00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #pragma once
00022
00023 #ifndef VOLUMILL_VALIDATE_H
00024 #define VOLUMILL_VALIDATE_H
00025
00026
00027
00028
00029
00030 #include <string>
00031 #include <sstream>
00032 #include <stdexcept>
00033
00034 namespace util
00035 {
00036
00037 class EnforcementHandlerInterface
00038 {
00039 public:
00040 enum { Warning=0, Error, Info };
00041 virtual ~EnforcementHandlerInterface();
00042 virtual void post (const std::string& message, const char* locus, int line, int level) = 0;
00043 static boost::shared_ptr<EnforcementHandlerInterface> getInstance();
00044 static void setInstance(boost::shared_ptr<EnforcementHandlerInterface> pEHI);
00045 private:
00046 static boost::shared_ptr<EnforcementHandlerInterface> m_pEHI;
00047 };
00048
00049 struct DefaultPredicate
00050 {
00051 template <class T>
00052 static bool Wrong(const T& obj)
00053 {
00054 return !obj;
00055 }
00056 };
00057
00058 struct DefaultRaiser
00059 {
00060 template <class T>
00061 static void Throw(const T&, const std::string& message, const char* locus, int line)
00062 {
00063 boost::shared_ptr<EnforcementHandlerInterface> pEHI = EnforcementHandlerInterface::getInstance();
00064 if (pEHI)
00065 {
00066 pEHI->post (message, locus, line, EnforcementHandlerInterface::Error);
00067 }
00068 throw std::runtime_error(message);
00069 }
00070 };
00071
00072 struct WarnRaiser
00073 {
00074 template<class T>
00075 static void Throw(const T&, const std::string& message, const char* locus, int line)
00076 {
00077 boost::shared_ptr<EnforcementHandlerInterface> pEHI = EnforcementHandlerInterface::getInstance();
00078 if (pEHI)
00079 {
00080 pEHI->post (message, locus, line, EnforcementHandlerInterface::Warning);
00081 }
00082 }
00083 };
00084
00085 struct InfoRaiser
00086 {
00087 template<class T>
00088 static void Throw(const T&, const std::string& message, const char* locus, int line)
00089 {
00090 boost::shared_ptr<EnforcementHandlerInterface> pEHI = EnforcementHandlerInterface::getInstance();
00091 if (pEHI)
00092 {
00093 pEHI->post (message, locus, line, EnforcementHandlerInterface::Info);
00094 }
00095 }
00096 };
00097
00098 template<typename Ref, typename P, typename R>
00099 class Enforcer
00100 {
00101 public:
00102 Enforcer(Ref t, const char* locus, int line) : t_(t), locus_(P::Wrong(t) ? locus : 0), line_ (line)
00103 {
00104 }
00105
00106 Ref operator*() const
00107 {
00108 if (locus_) R::Throw(t_, msg_, locus_, line_);
00109 return t_;
00110 }
00111
00112 template <class MsgType>
00113 Enforcer& operator()(const MsgType& msg)
00114 {
00115 if (locus_)
00116 {
00117
00118 std::ostringstream ss;
00119 ss << msg;
00120 msg_ += ss.str();
00121 }
00122 return *this;
00123 }
00124
00125 private:
00126 Ref t_;
00127 std::string msg_;
00128 const char* const locus_;
00129 int line_;
00130 };
00131
00132 template <class P, class R, typename T>
00133 inline Enforcer<const T&, P, R>
00134 MakeEnforcer(const T& t, const char* locus, int line)
00135 {
00136 return Enforcer<const T&, P, R>(t, locus, line);
00137 }
00138
00139 template <class P, class R, typename T>
00140 inline Enforcer<T&, P, R>
00141 MakeEnforcer(T& t, const char* locus, int line)
00142 {
00143 return Enforcer<T&, P, R>(t, locus, line);
00144 }
00145 }
00146
00147 #define VALIDATE(exp) \
00148 *::util::MakeEnforcer<util::DefaultPredicate, util::DefaultRaiser>((exp), "Expression '" #exp "' failed in '" \
00149 __FILE__ , __LINE__)
00150
00151 #define VALIDATE_ARG(exp) \
00152 *::util::MakeEnforcer<util::DefaultPredicate, util::DefaultRaiser>((exp), "Expression '" #exp "' failed in '" \
00153 __FILE__ , __LINE__)
00154
00155 #define WARN(exp) \
00156 *::util::MakeEnforcer<util::DefaultPredicate, util::WarnRaiser>((exp), "Expression '" #exp "' failed in '" \
00157 __FILE__ , __LINE__)
00158
00159 #define INFO(exp) \
00160 *::util::MakeEnforcer<util::DefaultPredicate, util::InfoRaiser>((0), "Message in '" __FILE__ , __LINE__)((exp))
00161
00162 #endif