00001
00002
00003
00004
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
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