# HG changeset patch # User deba # Date 1110377581 0 # Node ID 8117169c904958233218df2daff29e8d2e116e17 # Parent 9c398137c2cb83367013259934b172a32f2d5c3b ExceptionMember helper class. Modified DataFormatError IOLogicError diff -r 9c398137c2cb -r 8117169c9049 src/lemon/error.h --- a/src/lemon/error.h Wed Mar 09 14:10:21 2005 +0000 +++ b/src/lemon/error.h Wed Mar 09 14:13:01 2005 +0000 @@ -32,8 +32,66 @@ namespace lemon { -/// \addtogroup exceptions -/// @{ + /// \addtogroup exceptions + /// @{ + + /// \brief Exception safe wrapper class. + /// + /// Exception safe wrapper class to implement the members of exceptions. + template + class ExceptionMember { + public: + typedef _Type Type; + + ExceptionMember() throw () { + try { + ptr.reset(new Type()); + } catch (...) {} + } + + ExceptionMember(const Type& type) throw () { + try { + ptr.reset(new Type()); + if (ptr.get() == 0) return; + *ptr = type; + } catch (...) {} + } + + ExceptionMember(const ExceptionMember& copy) throw() { + try { + if (!copy.valid()) return; + ptr.reset(new Type()); + if (ptr.get() == 0) return; + *ptr = copy.get(); + } catch (...) {} + } + + ExceptionMember& operator=(const ExceptionMember& copy) { + if (ptr.get() == 0) return; + try { + if (!copy.valid()) return; + *ptr = copy.get(); + } catch (...) {} + } + + void set(const Type& type) { + if (ptr.get() == 0) return; + try { + *ptr = type; + } catch (...) {} + } + + const Type& get() const { + return *ptr; + } + + bool valid() const { + return ptr.get() != 0; + } + + private: + std::auto_ptr<_Type> ptr; + }; /// Exception-safe convenient "error message" class. @@ -88,6 +146,7 @@ catch(...) { buf.reset(); } + return *this; } ///\e @@ -190,74 +249,71 @@ ///\e class DataFormatError : public IOError { protected: - const char *_message; + ExceptionMember _message; + ExceptionMember _file; int _line; - ///\todo Much better solution is boost::shared_ptr - mutable - std::auto_ptr _file; - + mutable ExceptionMember _message_holder; public: DataFormatError(const DataFormatError &dfe) : - IOError(dfe), _message(dfe._message), _line(dfe._line), - _file(dfe._file) {} + IOError(dfe), _message(dfe._message), _file(dfe._file), + _line(dfe._line) {} ///\e explicit DataFormatError(const char *the_message) : _message(the_message), _line(0) {} + ///\e DataFormatError(const std::string &file_name, int line_num, const char *the_message) : _message(the_message), _line(line_num) { file(file_name); } ///\e - void line(int line_num) { _line=line_num; } + void line(int line) { _line = line; } ///\e - void message(char *the_message) { _message=the_message; } + void message(const std::string& message) { _message.set(message); } ///\e - void file(const std::string &file_name) { - try { - _file.reset(new std::string); - *_file = file_name; - } - catch(...) { - _file.reset(); + void file(const std::string &file) { _file.set(file); } + + ///\e + int line() const { return _line; } + ///\e + const char* message() const { + if (_message.valid() && !_message.get().empty()) { + return _message.get().c_str(); + } else { + return 0; } } - ///\e - int line() const { return _line; } - ///\e - const char* message() const { return _message; } - /// \brief Returns the filename. /// - /// Returns \e "(unknown)" if the filename was not specified. + /// Returns \e null if the filename was not specified. const char* file() const { - if( _file.get() ) - return _file->c_str(); - else - return "(unknown)"; + if (_file.valid() && !_file.get().empty()) { + return _file.get().c_str(); + } else { + return 0; + } } ///\e virtual const char* what() const throw() { - const char *mes = 0; try { std::ostringstream ostr; - ostr << _message; - if( _file.get() || _line ) { + if (message()) ostr << message(); + if( file() || line() != 0 ) { ostr << " ("; - if( _file.get() ) ostr << "in file '" << *_file << "'"; - if( _file.get() && _line ) ostr << " "; - if( _line ) ostr << "at line " << _line; + if( file() ) ostr << "in file '" << file() << "'"; + if( file() && line() != 0 ) ostr << " "; + if( line() != 0 ) ostr << "at line " << line(); ostr << ")"; } - mes = ostr.str().c_str(); + _message_holder.set(ostr.str()); } - catch(...) {} - if( mes ) return mes; + catch (...) {} + if( _message_holder.valid()) return _message_holder.get().c_str(); return exceptionName(); } @@ -268,6 +324,72 @@ virtual ~DataFormatError() throw() {} }; + class IOLogicError : public IOError, public LogicError { + protected: + ExceptionMember _message; + ExceptionMember _file; + int _line; + + mutable ExceptionMember _message_holder; + public: + + IOLogicError(const IOLogicError &ile) : + IOError(ile), LogicError(ile), + _message(ile._message), _file(ile._file) {} + + ///\e + explicit IOLogicError(const char *the_message) + : _message(the_message), _line(0) {} + + ///\e + IOLogicError(const char *file_name, const char *the_message) + : _message(file_name), _file(file_name) {} + + ///\e + void message(const std::string& message) { _message.set(message); } + ///\e + void file(const std::string &file) { _file.set(file); } + + ///\e + const char* message() const { + if (_message.valid()) { + return _message.get().c_str(); + } else { + return 0; + } + } + + /// \brief Returns the filename. + /// + /// Returns \e null if the filename was not specified. + const char* file() const { + if (_file.valid()) { + return _file.get().c_str(); + } else { + return 0; + } + } + + ///\e + virtual const char* what() const throw() { + try { + std::ostringstream ostr; + if (message()) ostr << message(); + if (file()) ostr << "(when reading file '" << file() << "')"; + _message_holder.set(ostr.str()); + } + catch (...) {} + if( _message_holder.valid() ) return _message_holder.get().c_str(); + return exceptionName(); + } + + virtual const char* exceptionName() const { + return "lemon::IOLogicError"; + } + + virtual ~IOLogicError() throw() {} + }; + ///\e class AssertionFailedError : public LogicError { @@ -307,6 +429,8 @@ if( assertion ) ostr << " (assertion '" << assertion << "' failed)"; mes = ostr.str().c_str(); + /// \bug Szerintem a 'mes'-re nem szabad hivatkozni, mert + /// az elobb felszabadul. } catch(...) {} if( mes ) return mes;