1 #ifndef MARISA_EXCEPTION_H_ 2 #define MARISA_EXCEPTION_H_ 3 4 #include <exception> 5 6 #include "marisa/base.h" 7 8 namespace marisa { 9 10 // An exception object keeps a filename, a line number, an error code and an 11 // error message. The message format is as follows: 12 // "__FILE__:__LINE__: error_code: error_message" 13 class Exception : public std::exception { 14 public: Exception(const char * filename,int line,ErrorCode error_code,const char * error_message)15 Exception(const char *filename, int line, 16 ErrorCode error_code, const char *error_message) 17 : std::exception(), filename_(filename), line_(line), 18 error_code_(error_code), error_message_(error_message) {} Exception(const Exception & ex)19 Exception(const Exception &ex) 20 : std::exception(), filename_(ex.filename_), line_(ex.line_), 21 error_code_(ex.error_code_), error_message_(ex.error_message_) {} ~Exception()22 virtual ~Exception() throw() {} 23 24 Exception &operator=(const Exception &rhs) { 25 filename_ = rhs.filename_; 26 line_ = rhs.line_; 27 error_code_ = rhs.error_code_; 28 error_message_ = rhs.error_message_; 29 return *this; 30 } 31 filename()32 const char *filename() const { 33 return filename_; 34 } line()35 int line() const { 36 return line_; 37 } error_code()38 ErrorCode error_code() const { 39 return error_code_; 40 } error_message()41 const char *error_message() const { 42 return error_message_; 43 } 44 what()45 virtual const char *what() const throw() { 46 return error_message_; 47 } 48 49 private: 50 const char *filename_; 51 int line_; 52 ErrorCode error_code_; 53 const char *error_message_; 54 }; 55 56 // These macros are used to convert a line number to a string constant. 57 #define MARISA_INT_TO_STR(value) #value 58 #define MARISA_LINE_TO_STR(line) MARISA_INT_TO_STR(line) 59 #define MARISA_LINE_STR MARISA_LINE_TO_STR(__LINE__) 60 61 // MARISA_THROW throws an exception with a filename, a line number, an error 62 // code and an error message. The message format is as follows: 63 // "__FILE__:__LINE__: error_code: error_message" 64 #define MARISA_THROW(error_code, error_message) \ 65 (throw marisa::Exception(__FILE__, __LINE__, error_code, \ 66 __FILE__ ":" MARISA_LINE_STR ": " #error_code ": " error_message)) 67 68 // MARISA_THROW_IF throws an exception if `condition' is true. 69 #define MARISA_THROW_IF(condition, error_code) \ 70 (void)((!(condition)) || (MARISA_THROW(error_code, #condition), 0)) 71 72 // MARISA_DEBUG_IF is ignored if _DEBUG is undefined. So, it is useful for 73 // debugging time-critical codes. 74 #ifdef _DEBUG 75 #define MARISA_DEBUG_IF(cond, error_code) MARISA_THROW_IF(cond, error_code) 76 #else 77 #define MARISA_DEBUG_IF(cond, error_code) 78 #endif 79 80 } // namespace marisa 81 82 #endif // MARISA_EXCEPTION_H_ 83