Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

basics/exceptions.hh
Go to the documentation of this file.
00001 /* exceptions
00002  *
00003  * Assert
00004  * an exeption should be thrown with information about: file, line, function,
00005  * violated condition, exception name. This exception can be handled in the
00006  * main program.
00007  */
00008 
00009 #ifndef exceptions_hh
00010 #define exceptions_hh
00011 
00012 #include <exception>
00013 #include <iostream>
00014 #include <string>
00015 #include <cstdlib>
00016 #include <sstream>
00017 #include <new>
00018 
00019 #include "outputOperator.hh"
00020 
00021 namespace concepts {
00022 
00023   // ************************************************************ Stacktrace **
00024 
00031   class Stacktrace {
00032   public:
00034     static void print();
00036     static bool& doit() { return doit_; }
00037   private:
00038     static bool doit_;
00039   };
00040 
00041   // ********************************************************* ExceptionBase **
00042 
00080   class ExceptionBase : public std::exception,
00081       public OutputOperator 
00082   {
00083   public:
00085     ExceptionBase() throw();
00086     
00087     ExceptionBase(const std::string& message) throw()
00088     {
00089       new(this) ExceptionBase("(undefined)", -1, "(undefined)", message);
00090     }
00091 
00099     ExceptionBase(const std::string& file, const unsigned int line, 
00100    const std::string& function, const std::string& excName) throw();
00101 
00102     virtual ~ExceptionBase() throw();
00103 
00111     void setFields(const std::string& file, const unsigned int line, 
00112        const std::string& function, 
00113        const std::string& excName) throw();
00114 
00115   protected:
00116     virtual std::ostream& info(std::ostream& os) const throw();
00117 
00119     std::string file_;
00120 
00122     unsigned int line_;
00123 
00125     std::string function_;
00126 
00128     std::string excName_;
00129   };
00130 
00131   // ***************************************************** DimensionMismatch **
00132 
00137   class DimensionMismatch : public ExceptionBase {};
00138 
00139   // ****************************************************** IndexNotExisting **
00140 
00146   class IndexNotExisting : public ExceptionBase {};
00147 
00148   // ******************************************************** MissingFeature **
00149 
00161   class MissingFeature : public ExceptionBase {
00162   public:
00167     MissingFeature(const std::string& feature) throw();
00168 
00177     MissingFeature(const std::string& file, const unsigned int line, 
00178        const std::string& function, const std::string& excName, 
00179        const std::string& feature = std::string("")) throw();
00180 
00181     virtual ~MissingFeature() throw();
00182   protected:
00183     virtual std::ostream& info(std::ostream& os) const throw();
00184 
00186     std::string feature_;
00187   };
00188 
00189   // ************************************************************* Assertion **
00190 
00213   class Assertion : public MissingFeature {
00214   public:
00216     Assertion() throw();
00217 
00226     Assertion(const std::string& file, const unsigned int line, 
00227         const std::string& function, const std::string& excName, 
00228         const std::string& cond) throw();
00229 
00230     virtual ~Assertion() throw();
00231 
00240     void setFieldsAssert(const std::string& file, const unsigned int line, 
00241        const std::string& function, 
00242        const std::string& excName, 
00243        const std::string& cond = std::string("")) throw();
00244   protected:
00245     virtual std::ostream& info(std::ostream& os) const throw();
00246   };
00247 
00248   // ************************************************** exception_set_fields **
00249 
00250 #ifndef __GNUC__
00251 #  define __PRETTY_FUNCTION__ "(unknown)"
00252 #endif
00253 
00270   template<class exc>
00271   exc exception_set_fields(exc e, const std::string& file, 
00272          const unsigned int line,
00273          const std::string& function, 
00274          const std::string& excName) {
00275     e.setFields(file, line, function, excName);
00276 #ifdef DEBUG
00277     Stacktrace::print();
00278 #endif
00279 #ifdef __SUNPRO_CC
00280     std::cout << e << std::endl;
00281     std::exit(0);
00282 #endif
00283     return e;
00284   }
00285 
00286   // ***************************************************** conceptsException **
00287 
00299 #define conceptsException(exc) \
00300   exception_set_fields(exc, std::string(__FILE__), __LINE__, \
00301            std::string(__PRETTY_FUNCTION__), std::string(#exc))
00302 
00303 #define CONCEPTS_SIMPLE_EXC(msg) \
00304   exception_set_fields(ExceptionBase(), std::string(__FILE__), __LINE__, \
00305            std::string(__PRETTY_FUNCTION__), std::string(msg))
00306 
00307   // ************************************************ exception_throw_assert **
00308 
00318   template<class exc>
00319   void exception_throw_assert(const std::string& file, int line, 
00320             const std::string& function,
00321             const std::string& exc_name, 
00322             const std::string& cond, exc e) {
00323     e.setFieldsAssert(file, line, function, exc_name, cond);
00324     Stacktrace::print();
00325 #ifdef __SUNPRO_CC
00326     std::cout << e << std::endl;
00327     std::exit(0);
00328 #else
00329     throw e;
00330 #endif
00331   }
00332 
00333   // ******************************************************** conceptsAssert **
00334 
00335 #ifndef DEBUG
00336 
00349 #define conceptsAssert(cond, exc) { }
00350 #else
00351 #define conceptsAssert(cond, exc) { \
00352     if (!(cond)) { \
00353       std::stringstream errorMsg; \
00354       errorMsg << "by violating condition <" << #cond << ">"; \
00355       exception_throw_assert(std::string(__FILE__), __LINE__, \
00356            std::string(__PRETTY_FUNCTION__), \
00357                              std::string(#exc), errorMsg.str(), exc); \
00358     } \
00359   }
00360 #endif // DEBUG
00361 
00366 #define conceptsThrowSimpleE(msg) { \
00367       std::stringstream errorMsg; \
00368       errorMsg << msg; \
00369       exception_throw_assert(std::string(__FILE__), __LINE__, \
00370            std::string(__PRETTY_FUNCTION__), \
00371            std::string("SimpleException"), errorMsg.str(), concepts::Assertion()); \
00372   }
00373 
00374 
00375   // ******************************************************* conceptsAssert3 **
00376 
00377 #ifndef DEBUG
00378 
00397 #define conceptsAssert3(cond, exc, msg) { }
00398 #else
00399 #define conceptsAssert3(cond, exc, msg) { \
00400     if (!(cond)) { \
00401       std::stringstream errorMsg; \
00402       errorMsg << "by violating condition <" << #cond << ">, " << msg; \
00403       exception_throw_assert(std::string(__FILE__), __LINE__, \
00404            std::string(__PRETTY_FUNCTION__), \
00405                              std::string(#exc), errorMsg.str(), exc); \
00406     } \
00407   }
00408 #endif // DEBUG
00409 
00410 } // namespace
00411 
00412 #endif // exceptions_hh

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)