ExceptionMember helper class.
Modified DataFormatError
IOLogicError
1.1 --- a/src/lemon/error.h Wed Mar 09 14:10:21 2005 +0000
1.2 +++ b/src/lemon/error.h Wed Mar 09 14:13:01 2005 +0000
1.3 @@ -32,8 +32,66 @@
1.4
1.5 namespace lemon {
1.6
1.7 -/// \addtogroup exceptions
1.8 -/// @{
1.9 + /// \addtogroup exceptions
1.10 + /// @{
1.11 +
1.12 + /// \brief Exception safe wrapper class.
1.13 + ///
1.14 + /// Exception safe wrapper class to implement the members of exceptions.
1.15 + template <typename _Type>
1.16 + class ExceptionMember {
1.17 + public:
1.18 + typedef _Type Type;
1.19 +
1.20 + ExceptionMember() throw () {
1.21 + try {
1.22 + ptr.reset(new Type());
1.23 + } catch (...) {}
1.24 + }
1.25 +
1.26 + ExceptionMember(const Type& type) throw () {
1.27 + try {
1.28 + ptr.reset(new Type());
1.29 + if (ptr.get() == 0) return;
1.30 + *ptr = type;
1.31 + } catch (...) {}
1.32 + }
1.33 +
1.34 + ExceptionMember(const ExceptionMember& copy) throw() {
1.35 + try {
1.36 + if (!copy.valid()) return;
1.37 + ptr.reset(new Type());
1.38 + if (ptr.get() == 0) return;
1.39 + *ptr = copy.get();
1.40 + } catch (...) {}
1.41 + }
1.42 +
1.43 + ExceptionMember& operator=(const ExceptionMember& copy) {
1.44 + if (ptr.get() == 0) return;
1.45 + try {
1.46 + if (!copy.valid()) return;
1.47 + *ptr = copy.get();
1.48 + } catch (...) {}
1.49 + }
1.50 +
1.51 + void set(const Type& type) {
1.52 + if (ptr.get() == 0) return;
1.53 + try {
1.54 + *ptr = type;
1.55 + } catch (...) {}
1.56 + }
1.57 +
1.58 + const Type& get() const {
1.59 + return *ptr;
1.60 + }
1.61 +
1.62 + bool valid() const {
1.63 + return ptr.get() != 0;
1.64 + }
1.65 +
1.66 + private:
1.67 + std::auto_ptr<_Type> ptr;
1.68 + };
1.69
1.70 /// Exception-safe convenient "error message" class.
1.71
1.72 @@ -88,6 +146,7 @@
1.73 catch(...) {
1.74 buf.reset();
1.75 }
1.76 + return *this;
1.77 }
1.78
1.79 ///\e
1.80 @@ -190,74 +249,71 @@
1.81 ///\e
1.82 class DataFormatError : public IOError {
1.83 protected:
1.84 - const char *_message;
1.85 + ExceptionMember<std::string> _message;
1.86 + ExceptionMember<std::string> _file;
1.87 int _line;
1.88
1.89 - ///\todo Much better solution is boost::shared_ptr
1.90 - mutable
1.91 - std::auto_ptr<std::string> _file;
1.92 -
1.93 + mutable ExceptionMember<std::string> _message_holder;
1.94 public:
1.95
1.96 DataFormatError(const DataFormatError &dfe) :
1.97 - IOError(dfe), _message(dfe._message), _line(dfe._line),
1.98 - _file(dfe._file) {}
1.99 + IOError(dfe), _message(dfe._message), _file(dfe._file),
1.100 + _line(dfe._line) {}
1.101
1.102 ///\e
1.103 explicit DataFormatError(const char *the_message)
1.104 : _message(the_message), _line(0) {}
1.105 +
1.106 ///\e
1.107 DataFormatError(const std::string &file_name, int line_num,
1.108 const char *the_message)
1.109 : _message(the_message), _line(line_num) { file(file_name); }
1.110
1.111 ///\e
1.112 - void line(int line_num) { _line=line_num; }
1.113 + void line(int line) { _line = line; }
1.114 ///\e
1.115 - void message(char *the_message) { _message=the_message; }
1.116 + void message(const std::string& message) { _message.set(message); }
1.117 ///\e
1.118 - void file(const std::string &file_name) {
1.119 - try {
1.120 - _file.reset(new std::string);
1.121 - *_file = file_name;
1.122 - }
1.123 - catch(...) {
1.124 - _file.reset();
1.125 + void file(const std::string &file) { _file.set(file); }
1.126 +
1.127 + ///\e
1.128 + int line() const { return _line; }
1.129 + ///\e
1.130 + const char* message() const {
1.131 + if (_message.valid() && !_message.get().empty()) {
1.132 + return _message.get().c_str();
1.133 + } else {
1.134 + return 0;
1.135 }
1.136 }
1.137
1.138 - ///\e
1.139 - int line() const { return _line; }
1.140 - ///\e
1.141 - const char* message() const { return _message; }
1.142 -
1.143 /// \brief Returns the filename.
1.144 ///
1.145 - /// Returns \e "(unknown)" if the filename was not specified.
1.146 + /// Returns \e null if the filename was not specified.
1.147 const char* file() const {
1.148 - if( _file.get() )
1.149 - return _file->c_str();
1.150 - else
1.151 - return "(unknown)";
1.152 + if (_file.valid() && !_file.get().empty()) {
1.153 + return _file.get().c_str();
1.154 + } else {
1.155 + return 0;
1.156 + }
1.157 }
1.158
1.159 ///\e
1.160 virtual const char* what() const throw() {
1.161 - const char *mes = 0;
1.162 try {
1.163 std::ostringstream ostr;
1.164 - ostr << _message;
1.165 - if( _file.get() || _line ) {
1.166 + if (message()) ostr << message();
1.167 + if( file() || line() != 0 ) {
1.168 ostr << " (";
1.169 - if( _file.get() ) ostr << "in file '" << *_file << "'";
1.170 - if( _file.get() && _line ) ostr << " ";
1.171 - if( _line ) ostr << "at line " << _line;
1.172 + if( file() ) ostr << "in file '" << file() << "'";
1.173 + if( file() && line() != 0 ) ostr << " ";
1.174 + if( line() != 0 ) ostr << "at line " << line();
1.175 ostr << ")";
1.176 }
1.177 - mes = ostr.str().c_str();
1.178 + _message_holder.set(ostr.str());
1.179 }
1.180 - catch(...) {}
1.181 - if( mes ) return mes;
1.182 + catch (...) {}
1.183 + if( _message_holder.valid()) return _message_holder.get().c_str();
1.184 return exceptionName();
1.185 }
1.186
1.187 @@ -268,6 +324,72 @@
1.188 virtual ~DataFormatError() throw() {}
1.189 };
1.190
1.191 + class IOLogicError : public IOError, public LogicError {
1.192 + protected:
1.193 + ExceptionMember<std::string> _message;
1.194 + ExceptionMember<std::string> _file;
1.195 + int _line;
1.196 +
1.197 + mutable ExceptionMember<std::string> _message_holder;
1.198 + public:
1.199 +
1.200 + IOLogicError(const IOLogicError &ile) :
1.201 + IOError(ile), LogicError(ile),
1.202 + _message(ile._message), _file(ile._file) {}
1.203 +
1.204 + ///\e
1.205 + explicit IOLogicError(const char *the_message)
1.206 + : _message(the_message), _line(0) {}
1.207 +
1.208 + ///\e
1.209 + IOLogicError(const char *file_name, const char *the_message)
1.210 + : _message(file_name), _file(file_name) {}
1.211 +
1.212 + ///\e
1.213 + void message(const std::string& message) { _message.set(message); }
1.214 + ///\e
1.215 + void file(const std::string &file) { _file.set(file); }
1.216 +
1.217 + ///\e
1.218 + const char* message() const {
1.219 + if (_message.valid()) {
1.220 + return _message.get().c_str();
1.221 + } else {
1.222 + return 0;
1.223 + }
1.224 + }
1.225 +
1.226 + /// \brief Returns the filename.
1.227 + ///
1.228 + /// Returns \e null if the filename was not specified.
1.229 + const char* file() const {
1.230 + if (_file.valid()) {
1.231 + return _file.get().c_str();
1.232 + } else {
1.233 + return 0;
1.234 + }
1.235 + }
1.236 +
1.237 + ///\e
1.238 + virtual const char* what() const throw() {
1.239 + try {
1.240 + std::ostringstream ostr;
1.241 + if (message()) ostr << message();
1.242 + if (file()) ostr << "(when reading file '" << file() << "')";
1.243 + _message_holder.set(ostr.str());
1.244 + }
1.245 + catch (...) {}
1.246 + if( _message_holder.valid() ) return _message_holder.get().c_str();
1.247 + return exceptionName();
1.248 + }
1.249 +
1.250 + virtual const char* exceptionName() const {
1.251 + return "lemon::IOLogicError";
1.252 + }
1.253 +
1.254 + virtual ~IOLogicError() throw() {}
1.255 + };
1.256 +
1.257
1.258 ///\e
1.259 class AssertionFailedError : public LogicError {
1.260 @@ -307,6 +429,8 @@
1.261 if( assertion )
1.262 ostr << " (assertion '" << assertion << "' failed)";
1.263 mes = ostr.str().c_str();
1.264 + /// \bug Szerintem a 'mes'-re nem szabad hivatkozni, mert
1.265 + /// az elobb felszabadul.
1.266 }
1.267 catch(...) {}
1.268 if( mes ) return mes;