Enforce.h

Go to the documentation of this file.
00001 /* ex: set tabstop=4 expandtab: */
00002 /*                                                             */
00003 /*  (c) 2004-2006 Iowa State University                        */
00004 /*      see the LICENSE file in the top level directory        */
00005 /*                                                             */
00012 
00013 #ifndef ENFORCE_H_
00014 #define ENFORCE_H_
00015 
00016 #include "FountainErrors.h"
00017 #include <bamboo/define.h>
00018 #include <string>
00019 #include <sstream>
00020 #include <stdexcept>
00021 
00024 struct DefaultPredicate {
00025         template <class T>
00026         static bool Wrong(const T& obj){
00027                 return !obj;
00028         }
00029 };
00030 
00033 struct DefaultRaiser {
00034     template <class T>
00035     static void Throw(const T&, const std::string& message, const char* locus) {
00036         throw FountainException(message + '\n' + locus);
00037     }
00038 };
00039 
00042 struct ErrorPredicate {
00043         static bool Wrong(int obj) {
00044                 return obj == FAILURE;
00045         }
00046 };
00047 
00050 template<typename Ref, typename P, typename R>
00051 class Enforcer {
00052 public:
00056     Enforcer(Ref t, const char* locus) : t_(t), msg_(), locus_(P::Wrong(t) ? locus : 0) {}
00057         
00059     Ref operator*() const {
00060         if (locus_) R::Throw(t_, msg_, locus_);
00061         return t_;
00062     }
00063         
00066     template <class MsgType>
00067     Enforcer& operator()(const MsgType& msg) {
00068         if (locus_) {
00069             // Here we have time; an exception will be thrown
00070             std::ostringstream ss;
00071             ss << msg;
00072             msg_ += ss.str();
00073         }
00074         return *this;
00075     }
00076     
00079     Enforcer(const Enforcer& rhs) : t_(rhs.t_), msg_(rhs.msg_), locus_(rhs.locus_) {}
00080         
00081 private:
00082         Enforcer& operator=(const Enforcer& rhs);
00083     Ref t_;
00084     std::string msg_;
00085     const char* const locus_;
00086 };
00087 
00092 template <class P, class R, typename T>
00093 inline Enforcer<const T&, P, R> MakeEnforcer(const T& t, const char* locus) {
00094     return Enforcer<const T&, P, R>(t, locus);
00095 }
00096 
00099 template <class P, class R, typename T>
00100 inline Enforcer<T&, P, R> MakeEnforcer(T& t, const char* locus) {
00101     return Enforcer<T&, P, R>(t, locus);
00102 }
00103 
00106 #define STRINGIZE(expr) STRINGIZE_HELPER(expr)
00107 
00110 #define STRINGIZE_HELPER(expr) #expr
00111 
00114 #define ENFORCE(exp) *MakeEnforcer<DefaultPredicate, DefaultRaiser>((exp), "Expression '" #exp "' failed in '" __FILE__ "', line: " STRINGIZE(__LINE__))
00115 
00118 #define ENFORCE_SUCCESS(exp) *MakeEnforcer<ErrorPredicate, DefaultRaiser>((exp), "Expression '" #exp "' failed in '" __FILE__ "', line: " STRINGIZE(__LINE__))
00119 
00120 #endif

Generated on Wed Mar 8 14:43:30 2006 for Fountain by  doxygen 1.4.6