00001
00002
00003
00004
00005
00012
00013 #ifndef ASSERTER_H__
00014 #define ASSERTER_H__
00015
00016 #include <cstdlib>
00017
00025 #ifndef NDEBUG
00026 # define ASSERT if (false); \
00027 else \
00028 struct Local {\
00029 Local(const Asserter& info) { info.Handle(__FILE__, __LINE__); }\
00030 } localAsserter = Asserter::Make
00031 #else
00032 # define ASSERT if (true); \
00033 else \
00034 struct Local {\
00035 Local(const Asserter& info) { info.Handle(__FILE__, __LINE__); }\
00036 } localAsserter = Asserter::Make
00037 #endif
00038
00041 enum AsserterAction {
00042 giveUp,
00043 ignore,
00044 throwUp
00045 };
00046
00053 AsserterAction AskUser(const char* file, int line, const char* msg=NULL);
00054
00055
00056 template <class E>
00057 class AsserterEx;
00058
00060 class Asserter {
00061 protected:
00062 const bool holds_;
00063
00064 virtual void doHandle(const char* file, int line) const;
00065
00066 public:
00067 Asserter(bool holds) : holds_(holds) {}
00068 virtual ~Asserter() {}
00069 void Handle(const char* file, int line) const;
00070 static Asserter Make(bool flag) {
00071 return Asserter(flag);
00072 }
00073 template <class E>
00074 static AsserterEx<E> Make(bool flag, const char* msg) {
00075 return AsserterEx<E>(flag, msg);
00076 }
00077 };
00078
00081 template <class E>
00082 class AsserterEx : public Asserter {
00083 private:
00084 const char* const msg_;
00085 virtual void doHandle(const char* file, int line) const {
00086 const AsserterAction action = AskUser(file, line, msg_);
00087 if (action == throwUp) {
00088 throw E(msg_);
00089 }
00090 return Asserter::doHandle(file, line);
00091 }
00092
00093 public:
00094 AsserterEx(bool holds, const char* msg) : Asserter(holds), msg_(msg) {}
00095 };
00096
00097 #endif