00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef XBASE_H
00020 #define XBASE_H
00021
00022 #include "CString.h"
00023
00025
00028 class XBase {
00029 public:
00031 XBase();
00033 XBase(const CString& msg);
00034 virtual ~XBase();
00035
00037 virtual const char* what() const;
00038
00039 protected:
00041 virtual CString getWhat() const throw() = 0;
00042
00044
00049 virtual CString format(const char* id,
00050 const char* defaultFormat, ...) const throw();
00051
00052 private:
00053 mutable CString m_what;
00054 };
00055
00062 #define XBASE_SUBCLASS(name_, super_) \
00063 class name_ : public super_ { \
00064 public: \
00065 name_() : super_() { } \
00066 name_(const CString& msg) : super_(msg) { } \
00067 }
00068
00075 #define XBASE_SUBCLASS_WHAT(name_, super_) \
00076 class name_ : public super_ { \
00077 public: \
00078 name_() : super_() { } \
00079 name_(const CString& msg) : super_(msg) { } \
00080 \
00081 protected: \
00082 virtual CString getWhat() const throw(); \
00083 }
00084
00093 #define XBASE_SUBCLASS_FORMAT(name_, super_) \
00094 class name_ : public super_ { \
00095 private: \
00096 enum EState { kFirst, kFormat, kDone }; \
00097 \
00098 public: \
00099 name_() : super_(), m_state(kDone) { } \
00100 name_(const CString& msg) : super_(msg), m_state(kFirst) { } \
00101 \
00102 virtual const char* what() const \
00103 { \
00104 if (m_state == kFirst) { \
00105 m_state = kFormat; \
00106 m_formatted = getWhat(); \
00107 m_state = kDone; \
00108 } \
00109 if (m_state == kDone) { \
00110 return m_formatted.c_str(); \
00111 } \
00112 else { \
00113 return super_::what(); \
00114 } \
00115 } \
00116 \
00117 protected: \
00118 virtual CString getWhat() const throw(); \
00119 \
00120 private: \
00121 mutable EState m_state; \
00122 mutable std::string m_formatted; \
00123 }
00124
00125 #endif