00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=4 sw=2 sts=2: 00003 00004 #ifndef DUNE_EXCEPTIONS_HH 00005 #define DUNE_EXCEPTIONS_HH 00006 00007 #include <exception> 00008 #include <string> 00009 #include <sstream> 00010 00011 namespace Dune { 00012 00071 /* forward declarations */ 00072 class Exception; 00073 struct ExceptionHook; 00074 00092 class Exception 00093 : public std::exception 00094 { 00095 public: 00096 Exception (); 00097 void message(const std::string &msg); 00098 virtual const char* what() const noexcept; 00099 static void registerHook (ExceptionHook * hook); 00100 static void clearHook (); 00101 private: 00102 std::string _message; 00103 static ExceptionHook * _hook; 00104 }; 00105 00171 struct ExceptionHook 00172 { 00173 virtual ~ExceptionHook() {} 00174 virtual void operator () () = 0; 00175 }; 00176 00177 inline std::ostream& operator<<(std::ostream &stream, const Exception &e) 00178 { 00179 return stream << e.what(); 00180 } 00181 00182 #ifndef DOXYGEN 00183 // the "format" the exception-type gets printed. __FILE__ and 00184 // __LINE__ are standard C-defines, the GNU cpp-infofile claims that 00185 // C99 defines __func__ as well. __FUNCTION__ is a GNU-extension 00186 #define THROWSPEC(E) # E << " [" << __func__ << ":" << __FILE__ << ":" << __LINE__ << "]: " 00187 #endif // DOXYGEN 00188 00214 // this is the magic: use the usual do { ... } while (0) trick, create 00215 // the full message via a string stream and throw the created object 00216 #define DUNE_THROW(E, m) do { E th__ex; std::ostringstream th__out; \ 00217 th__out << THROWSPEC(E) << m; th__ex.message(th__out.str()); throw th__ex; \ 00218 } while (0) 00219 00229 class IOError : public Exception {}; 00230 00239 class MathError : public Exception {}; 00240 00252 class RangeError : public Exception {}; 00253 00261 class NotImplemented : public Exception {}; 00262 00269 class SystemError : public Exception {}; 00270 00274 class OutOfMemoryError : public SystemError {}; 00275 00279 class InvalidStateException : public Exception {}; 00280 00285 class ParallelError : public Exception {}; 00286 00287 } // end namespace 00288 00289 #endif