Common/Util/Validate.h

Go to the documentation of this file.
00001 //-------------------------------------------------------------------
00004 //  Copyright (c) 2004 Evan Sherbrooke and Michael Lauer
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License, or (at your option) any later version.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00019 //
00020 //-------------------------------------------------------------------
00021 #pragma once
00022 
00023 #ifndef VOLUMILL_VALIDATE_H
00024 #define VOLUMILL_VALIDATE_H
00025 
00026 //
00027 // A validate mechanism, a la Alexandrescu's Enforce
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             // Here we have time; an exception will be thrown
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

Generated on Tue Jan 29 21:37:57 2008 for VoluMill Universal Client by  doxygen 1.4.6