[Lemon-commits] [lemon_svn] deba: r1626 - hugo/trunk/src/lemon
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:46:40 CET 2006
Author: deba
Date: Wed Mar 9 15:13:01 2005
New Revision: 1626
Modified:
hugo/trunk/src/lemon/error.h
Log:
ExceptionMember helper class.
Modified DataFormatError
IOLogicError
Modified: hugo/trunk/src/lemon/error.h
==============================================================================
--- hugo/trunk/src/lemon/error.h (original)
+++ hugo/trunk/src/lemon/error.h Wed Mar 9 15:13:01 2005
@@ -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 <typename _Type>
+ 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<std::string> _message;
+ ExceptionMember<std::string> _file;
int _line;
- ///\todo Much better solution is boost::shared_ptr
- mutable
- std::auto_ptr<std::string> _file;
-
+ mutable ExceptionMember<std::string> _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 { return _message; }
+ const char* message() const {
+ if (_message.valid() && !_message.get().empty()) {
+ return _message.get().c_str();
+ } else {
+ return 0;
+ }
+ }
/// \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<std::string> _message;
+ ExceptionMember<std::string> _file;
+ int _line;
+
+ mutable ExceptionMember<std::string> _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;
More information about the Lemon-commits
mailing list