00001
00002
00003
00004
00005
00006
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
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
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
00132
00137 class DimensionMismatch : public ExceptionBase {};
00138
00139
00140
00146 class IndexNotExisting : public ExceptionBase {};
00147
00148
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
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
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
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
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
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
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 }
00411
00412 #endif // exceptions_hh