[Lemon-commits] [lemon_svn] klao: r1452 - hugo/trunk/src/work/klao

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:45:33 CET 2006


Author: klao
Date: Fri Jan  7 01:43:54 2005
New Revision: 1452

Added:
   hugo/trunk/src/work/klao/error.h
      - copied, changed from r1449, /hugo/trunk/src/lemon/error.h

Log:
Exception hierarchy sketch.
Exception safe exception classes.


Copied: hugo/trunk/src/work/klao/error.h (from r1449, /hugo/trunk/src/lemon/error.h)
==============================================================================
--- /hugo/trunk/src/lemon/error.h	(original)
+++ hugo/trunk/src/work/klao/error.h	Fri Jan  7 01:43:54 2005
@@ -25,45 +25,155 @@
 #include <string>
 #include <sstream>
 
+#include <boost/shared_ptr.hpp>
 
 namespace lemon {
 
+  /// Exception-safe convenient "error message" class.
+  class ErrorMessage {
+  protected:
+    boost::shared_ptr<std::ostringstream> buf;
+    
+    bool init() throw() {
+      try {
+	buf.reset(new std::ostringstream);
+      }
+      catch(...) {
+	buf.reset();
+      }
+      return buf;
+    }
+
+  public:
+
+    ErrorMessage() throw() { init(); }
+
+    ErrorMessage(const char *message) throw() {
+      init();
+      *this << message;
+    }
+
+    ErrorMessage(const std::string &message) throw() {
+      init();
+      *this << message;
+    }
+
+    template <typename T>
+    ErrorMessage& operator<<(const T &t) throw() {
+      if( !buf ) return *this;
+
+      try {
+	*buf << t;
+      }
+      catch(...) {
+	buf.reset();
+      }
+    }
+
+    const char* message() throw() {
+      if( !buf ) return 0;
+
+      const char* mes = 0;
+      try {
+	mes = buf->str().c_str();
+      }
+      catch(...) {}
+      return mes;
+    }
+    
+  };
+
   /**
    * \brief Generic exception class.
    *
-   * \todo Do we need this?
-   *
-   * \todo Don't we need different kind of exceptions for different kind
-   * of errors?
-   * Shouldn't we use \<stdexcept\> instead?
+   * Base class for exceptions used in LEMON.
    */
-  class Exception : public std::exception {
-  protected:
-    std::ostringstream buf;
+  class Exception : public std::exception, public ErrorMessage {
   public:
-    Exception() {}
-    explicit Exception(const std::string &s) { buf << s; }
-    Exception(const Exception &e) : std::exception() {
-      buf << e.buf.str();
-    }
+    Exception() throw() {}
+    explicit Exception(const std::string &s) throw()
+      : ErrorMessage(s) {}
     virtual ~Exception() throw() {}
     
     virtual const char* what() const throw() {
-      return buf.str().c_str();
+      const char *mes = message();
+      if( mes ) return mes;
+      return "lemon::Exception";
     }
+  };
 
-    template <typename T>
-    Exception& operator<<(T const& t) { buf << t; return *this; }
+
+  class LogicError : public Exception {
+    explicit LogicError(const std::string &s)
+      : Exception(s) {}
+  };
+
+  class RuntimeError : public Exception {
+    explicit RuntimeError(const std::string &s)
+      : Exception(s) {}
+  };
+
+  class RangeError : public RuntimeError {
+    explicit RangeError(const std::string &s)
+      : RuntimeError(s) {}
+  };
+
+  class IOError : public RuntimeError {
+    explicit IOError(const std::string &s)
+      : RuntimeError(s) {}
+  };
+
+  class DataFormatError : public IOError {
+    explicit DataFormatError(const std::string &message)
+      : IOError(message) : line(0) {}
+    DataFormatError(const std::string &file_name, int line_num,
+		    sconst std::string &message)
+      : IOError(message), line(line_num) { set_file(file_name); }
+
+    void set_line(int line_num) { line=line_num; }
+    void set_file(const std::string &file_name) {
+      try {
+	file.reset(new std::string);
+	*file = file_name;
+      }
+      catch(...) {
+	file.reset();
+      }
+    }
+
+    virtual const char* what() const {
+      const char *mes = 0;
+      try {
+	std::ostringstream ostr;
+	ostr << IOError::what();
+	if( file || line ) {
+	  ostr << " (";
+	  if( file ) ostr << "in file" << *file;
+	  if( line ) ostr << " at line" << line;
+	}
+	mes = ostr.str().c_str();
+      }
+      catch(...) {}
+      if( mes ) return mes;
+      return "lemon::DataFormatError";
+    }
   };
 
+
+
+  /****************  Macros  ****************/
+
+
   /**
-   * \brief Generic error signaling function.
-   *
-   * \todo Do we really need this? Is it helpful?
+   * \brief Macro for assertions with customizable message
    */
-  inline void fault(const std::string &msg) {
-    throw Exception(msg);
-  }
+
+# define lemon_assert(exp, msg) \
+    if(!(exp)) { \
+      std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \
+      abort; \
+    }
+
 
   /**
    * \brief Macro for mark not yet implemented features.
@@ -72,10 +182,7 @@
    * modules under development.
    */
 
-# define FIXME(msg) \
-    do { throw ::lemon::Exception() << "FIXME: " msg " (in: "    \
-      __FILE__ ", " << __LINE__ << ")";                          \
-    } while(false)
+# define FIXME(msg) lemon_assert(0, "FIXME: " msg)
 
 }
 #endif // LEMON_ERROR_H



More information about the Lemon-commits mailing list