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