00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00051 #ifndef SCYTHE_ERROR_H
00052 #define SCYTHE_ERROR_H
00053
00054 #include <exception>
00055 #include <string>
00056 #include <sstream>
00057 #include <iostream>
00058 #include <vector>
00059
00061 #ifdef SCYTHE_DEBUG_LIB
00062 #define SCYTHE_DEBUG_MSG(MSG) \
00063 { std::cout << "SCYTHE_DEBUG_LIB: " << MSG << std::endl; }
00064 #else
00065 #define SCYTHE_DEBUG_MSG(MSG)
00066 #endif
00067
00069 #define SCYTHE_THROW(EXCEP,MSG) \
00070 { \
00071 std::stringstream _SCYTHE_DEBUG_ss; \
00072 _SCYTHE_DEBUG_ss << MSG; \
00073 throw EXCEP(__FILE__, __func__, __LINE__, \
00074 _SCYTHE_DEBUG_ss.str()); \
00075 }
00076
00077 #define SCYTHE_CHECK(CHECK,EXCEP,MSG) \
00078 { \
00079 if (CHECK) \
00080 SCYTHE_THROW(EXCEP,MSG) \
00081 }
00082
00084 #ifndef SCYTHE_DEBUG
00085 #define SCYTHE_DEBUG 3
00086 #endif
00087
00089 #if SCYTHE_DEBUG > 0
00090 #define SCYTHE_CHECK_10(CHECK,EXCEP,MSG) SCYTHE_CHECK(CHECK,EXCEP,MSG)
00091 #else
00092 #define SCYTHE_CHECK_10(CHECK, EXCEP, MSG)
00093 #endif
00094
00095 #if SCYTHE_DEBUG > 1
00096 #define SCYTHE_CHECK_20(CHECK,EXCEP,MSG) SCYTHE_CHECK(CHECK,EXCEP,MSG)
00097 #else
00098 #define SCYTHE_CHECK_20(CHECK, EXCEP, MSG)
00099 #endif
00100
00101 #if SCYTHE_DEBUG > 2
00102 #define SCYTHE_CHECK_30(CHECK,EXCEP,MSG) SCYTHE_CHECK(CHECK,EXCEP,MSG)
00103 #else
00104 #define SCYTHE_CHECK_30(CHECK, EXCEP, MSG)
00105 #endif
00106
00107 #if SCYTHE_DEBUG > 0
00108 #define SCYTHE_THROW_10(EXCEP,MSG) SCYTHE_THROW(EXCEP,MSG)
00109 #else
00110 #define SCYTHE_THROW_10(EXCEP,MSG)
00111 #endif
00112
00113 #if SCYTHE_DEBUG > 1
00114 #define SCYTHE_THROW_20(EXCEP,MSG) SCYTHE_THROW(EXCEP,MSG)
00115 #else
00116 #define SCYTHE_THROW_20(EXCEP,MSG)
00117 #endif
00118
00119 #if SCYTHE_DEBUG > 2
00120 #define SCYTHE_THROW_30(EXCEP,MSG) SCYTHE_THROW(EXCEP,MSG)
00121 #else
00122 #define SCYTHE_THROW_30(EXCEP,MSG)
00123 #endif
00124
00125 #define SCYTHE_WARN(MSG) \
00126 { \
00127 std::cerr << "WARNING in " << __FILE__ << ", " \
00128 << __func__ << ", " << __LINE__ << ": " \
00129 << MSG << "\n"; \
00130 }
00131
00132 #define SCYTHE_CHECK_WARN(CHECK,MSG) \
00133 { \
00134 if (CHECK) \
00135 SCYTHE_WARN(MSG) \
00136 }
00137
00138
00139 namespace scythe
00140 {
00141
00142 class scythe_exception;
00143
00144
00145
00146
00147 #ifdef __MINGW32__
00148 static scythe_exception *serr;
00149 #else
00150 namespace
00151 {
00152 scythe_exception *serr;
00153 }
00154 #endif
00155
00156
00157
00158
00159
00160 inline void scythe_terminate ();
00161
00162
00171 class scythe_exception:public std::exception
00172 {
00173 public:
00174 scythe_exception (const std::string & head,
00175 const std::string & file,
00176 const std::string & function,
00177 const unsigned int &line,
00178 const std::string & message = "",
00179 const bool & halt = false) throw ()
00180 : exception (),
00181 head_ (head),
00182 file_ (file),
00183 function_ (function),
00184 line_ (line),
00185 message_ (message),
00186 call_files_ (),
00187 call_funcs_ (),
00188 call_lines_ ()
00189 {
00190 std::ostringstream os;
00191 os << head_ << " in " << file_ << ", " << function_ << ", "
00192 << line_ << ": " << message_ << "!\n\n";
00193
00194 serr = this;
00195 std::set_terminate (scythe_terminate);
00196 if (halt)
00197 std::terminate ();
00198 }
00199
00200 scythe_exception (const scythe_exception & e) throw ()
00201 : exception (),
00202 head_ (e.head_),
00203 file_ (e.file_),
00204 function_ (e.function_),
00205 line_ (e.line_),
00206 message_ (e.message_),
00207 call_files_ (e.call_files_),
00208 call_funcs_ (e.call_funcs_),
00209 call_lines_ (e.call_lines_)
00210 {
00211 }
00212
00213 scythe_exception & operator= (const scythe_exception & e) throw ()
00214 {
00215 head_ = e.head_;
00216 file_ = e.file_;
00217 function_ = e.function_;
00218 line_ = e.line_;
00219 message_ = e.message_;
00220
00221 return *this;
00222 }
00223
00224 virtual ~ scythe_exception () throw ()
00225 {
00226 }
00227
00228 virtual const char *what () const throw ()
00229 {
00230 std::ostringstream os;
00231 for (int i = call_files_.size() - 1; i > -1; ++i) {
00232 os << "Called from " << call_files_[i] << ", "
00233 << call_funcs_[i] << ", " << call_lines_[i] << std::endl;
00234 }
00235 os << head_ << " in " << file_ << ", " << function_ << ", "
00236 << line_ << ": " << message_ << "!";
00237 return os.str ().c_str ();
00238 }
00239
00240 virtual std::string message () const throw ()
00241 {
00242 return message_;
00243 }
00244
00245 virtual void add_caller (const std::string &file,
00246 const std::string &function, const unsigned int &line) throw ()
00247 {
00248
00249
00250
00251
00252
00253
00254 if (file != file_ && function != function_) {
00255 call_files_.push_back(file);
00256 call_funcs_.push_back(function);
00257 call_lines_.push_back(line);
00258 }
00259 }
00260
00261 private:
00262 std::string head_;
00263 std::string file_;
00264 std::string function_;
00265 unsigned int line_;
00266 std::string message_;
00267 std::vector<std::string> call_files_;
00268 std::vector<std::string> call_funcs_;
00269 std::vector<unsigned int> call_lines_;
00270 };
00271
00272
00273
00274
00282 class scythe_alloc_error:public scythe_exception
00283 {
00284 public:
00285 scythe_alloc_error (const std::string & file,
00286 const std::string & function,
00287 const unsigned int &line,
00288 const std::string & message = "",
00289 const bool & halt = false) throw ()
00290 : scythe_exception ("SCYTHE_ALLOCATION_ERROR", file, function,
00291 line, message, halt)
00292 {
00293 }
00294 };
00295
00303 class scythe_invalid_arg:public scythe_exception
00304 {
00305 public:
00306 scythe_invalid_arg (const std::string & file,
00307 const std::string & function,
00308 const unsigned int &line,
00309 const std::string & message = "",
00310 const bool & halt = false) throw ()
00311 : scythe_exception ("SCYTHE_INVALID ARGUMENT", file, function,
00312 line, message, halt)
00313 {
00314 }
00315 };
00316
00324 class scythe_file_error:public scythe_exception
00325 {
00326 public:
00327 scythe_file_error(const std::string & file,
00328 const std::string & function,
00329 const unsigned int &line,
00330 const std::string & message = "",
00331 const bool & halt = false) throw ()
00332 : scythe_exception ("SCYTHE FILE ERROR", file, function, line,
00333 message, halt)
00334 {
00335 }
00336 };
00337
00344 class scythe_conformation_error:public scythe_exception
00345 {
00346 public:
00347 scythe_conformation_error(const std::string & file,
00348 const std::string & function,
00349 const unsigned int &line,
00350 const std::string & message = "",
00351 const bool & halt = false) throw ()
00352 : scythe_exception ("SCYTHE CONFORMATION ERROR", file, function,
00353 line, message, halt)
00354 {
00355 }
00356 };
00357
00366 class scythe_dimension_error:public scythe_exception
00367 {
00368 public:
00369 scythe_dimension_error (const std::string & file,
00370 const std::string & function,
00371 const unsigned int &line,
00372 const std::string & message = "",
00373 const bool & halt = false) throw ()
00374 : scythe_exception ("SCYTHE DIMENSION ERROR", file, function,
00375 line, message, halt)
00376 {
00377 }
00378 };
00379
00387 class scythe_null_error:public scythe_exception
00388 {
00389 public:
00390 scythe_null_error(const std::string & file,
00391 const std::string & function,
00392 const unsigned int &line,
00393 const std::string & message = "",
00394 const bool & halt = false) throw ()
00395 : scythe_exception ("SCYTHE NULL ERROR", file, function, line,
00396 message, halt)
00397 {
00398 }
00399 };
00400
00410 class scythe_type_error:public scythe_exception
00411 {
00412 public:
00413 scythe_type_error(const std::string & file,
00414 const std::string & function,
00415 const unsigned int &line,
00416 const std::string & message = "",
00417 const bool & halt = false) throw ()
00418 : scythe_exception ("SCYTHE TYPE ERROR", file, function, line,
00419 message, halt)
00420 {
00421 }
00422 };
00423
00431 class scythe_bounds_error:public scythe_exception
00432 {
00433 public:
00434 scythe_bounds_error(const std::string & file,
00435 const std::string & function,
00436 const unsigned int &line,
00437 const std::string & message = "",
00438 const bool & halt = false) throw ()
00439 : scythe_exception ("SCYTHE BOUNDS ERROR", file, function,
00440 line, message, halt)
00441 {
00442 }
00443 };
00444
00452 class scythe_convergence_error:public scythe_exception
00453 {
00454 public:
00455 scythe_convergence_error (const std::string & file,
00456 const std::string & function,
00457 const unsigned int &line,
00458 const std::string & message = "",
00459 const bool & halt = false) throw ()
00460 : scythe_exception ("SCYTHE CONVERGENCE ERROR", file, function,
00461 line, message, halt)
00462 {
00463 }
00464 };
00465
00474 class scythe_range_error:public scythe_exception
00475 {
00476 public:
00477 scythe_range_error (const std::string & file,
00478 const std::string & function,
00479 const unsigned int &line,
00480 const std::string & message = "",
00481 const bool & halt = false) throw ()
00482 : scythe_exception ("SCYTHE RANGE ERROR", file, function, line,
00483 message, halt)
00484 {
00485 }
00486 };
00487
00497 class scythe_precision_error:public scythe_exception
00498 {
00499 public:
00500 scythe_precision_error (const std::string & file,
00501 const std::string & function,
00502 const unsigned int &line,
00503 const std::string & message = "",
00504 const bool & halt = false) throw ()
00505 : scythe_exception ("SCYTHE PRECISION ERROR", file, function,
00506 line, message, halt)
00507 {
00508 }
00509 };
00510
00519 class scythe_randseed_error:public scythe_exception
00520 {
00521 public:
00522 scythe_randseed_error(const std::string & file,
00523 const std::string & function,
00524 const unsigned int &line,
00525 const std::string & message = "",
00526 const bool & halt = false) throw ()
00527 : scythe_exception ("SCYTHE RANDOM SEED ERROR", file, function,
00528 line, message, halt)
00529 {
00530 }
00531 };
00532
00542 class scythe_style_error:public scythe_exception
00543 {
00544 public:
00545 scythe_style_error(const std::string& file,
00546 const std::string& function,
00547 const unsigned int& line,
00548 const std::string& message = "",
00549 const bool& halt = false) throw ()
00550 : scythe_exception("SCYTHE STYLE ERROR", file, function,
00551 line, message, halt)
00552 {}
00553 };
00554
00561 class scythe_lapack_internal_error:public scythe_exception
00562 {
00563 public:
00564 scythe_lapack_internal_error(const std::string& file,
00565 const std::string& function,
00566 const unsigned int& line,
00567 const std::string& message = "",
00568 const bool& halt = false) throw ()
00569 : scythe_exception("SCYTHE LAPACK/BLAS INTERNAL ERROR", file,
00570 function, line, message, halt)
00571 {}
00572 };
00573
00580 class scythe_unexpected_default_error:public scythe_exception
00581 {
00582 public:
00583 scythe_unexpected_default_error(const std::string& file,
00584 const std::string& function,
00585 const unsigned int& line,
00586 const std::string& message = "",
00587 const bool& halt = false) throw ()
00588 : scythe_exception("SCYTHE UNEXPECTED DEFAULT ERROR", file,
00589 function, line, message, halt)
00590 {}
00591 };
00592
00593
00594 inline void scythe_terminate ()
00595 {
00596 std::cerr << serr->what() << std::endl;
00597 std::cerr << std::endl;
00598 abort ();
00599 }
00600
00601 }
00602
00603 #endif