Qore Programming Language  0.8.3
include/qore/ScopeGuard.h (4311)
00001 /* -*- mode: c++; indent-tabs-mode: nil -*- */
00002 #ifndef SCOPEGUARD_H_
00003 #define SCOPEGUARD_H_
00004 
00006 template <class T>
00007 class RefHolder
00008 {
00009     T& ref_;
00010 public:
00011     RefHolder(T& ref) : ref_(ref) {}
00012     operator T& () const 
00013     {
00014         return ref_;
00015     }
00016 private:
00017     // Disable assignment - not implemented
00018     RefHolder& operator=(const RefHolder&);
00019 };
00020 
00021 template <class T>
00022 inline RefHolder<T> ByRef(T& t)
00023 {
00024     return RefHolder<T>(t);
00025 }
00026 
00028 class ScopeGuardImplBase
00029 {
00030     ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
00031 protected:
00032     ~ScopeGuardImplBase()
00033     {
00034     }
00035 public:
00036     ScopeGuardImplBase(const ScopeGuardImplBase& other) throw() 
00037         : dismissed_(other.dismissed_)
00038     {
00039         other.Dismiss();
00040     }
00041 protected:
00042     template <typename J>
00043     static void SafeExecute(J& j) throw() 
00044     {
00045         if (!j.dismissed_)
00046             try
00047             {
00048                 j.Execute();
00049             }
00050             catch(...)
00051             {
00052             }
00053     }
00054     
00055     mutable bool dismissed_;
00056 public:
00057     ScopeGuardImplBase() throw() : dismissed_(false) 
00058     {
00059     }
00060     void Dismiss() const throw() 
00061     {
00062         dismissed_ = true;
00063     }
00064 };
00065 
00066 typedef const ScopeGuardImplBase& ScopeGuard;
00067 
00069 template <typename F>
00070 class ScopeGuardImpl0 : public ScopeGuardImplBase
00071 {
00072 public:
00073     static ScopeGuardImpl0<F> MakeGuard(F fun)
00074     {
00075         return ScopeGuardImpl0<F>(fun);
00076     }
00077     ~ScopeGuardImpl0() throw() 
00078     {
00079         SafeExecute(*this);
00080     }
00081     void Execute() 
00082     {
00083         fun_();
00084     }
00085 protected:
00086     ScopeGuardImpl0(F fun) : fun_(fun) 
00087     {
00088     }
00089     F fun_;
00090 };
00091 
00093 template <typename F> 
00094 inline ScopeGuardImpl0<F> MakeGuard(F fun)
00095 {
00096     return ScopeGuardImpl0<F>::MakeGuard(fun);
00097 }
00098 
00100 template <typename F, typename P1>
00101 class ScopeGuardImpl1 : public ScopeGuardImplBase
00102 {
00103 public:
00104     static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
00105     {
00106         return ScopeGuardImpl1<F, P1>(fun, p1);
00107     }
00108     ~ScopeGuardImpl1() throw() 
00109     {
00110         SafeExecute(*this);
00111     }
00112     void Execute()
00113     {
00114         fun_(p1_);
00115     }
00116 protected:
00117     ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) 
00118     {
00119     }
00120     F fun_;
00121     const P1 p1_;
00122 };
00123 
00125 template <typename F, typename P1> 
00126 inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
00127 {
00128     return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
00129 }
00130 
00132 template <typename F, typename P1, typename P2>
00133 class ScopeGuardImpl2: public ScopeGuardImplBase
00134 {
00135 public:
00136     static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
00137     {
00138         return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
00139     }
00140     ~ScopeGuardImpl2() throw() 
00141     {
00142         SafeExecute(*this);
00143     }
00144     void Execute()
00145     {
00146         fun_(p1_, p2_);
00147     }
00148 protected:
00149     ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) 
00150     {
00151     }
00152     F fun_;
00153     const P1 p1_;
00154     const P2 p2_;
00155 };
00156 
00158 template <typename F, typename P1, typename P2>
00159 inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
00160 {
00161     return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
00162 }
00163 
00165 template <typename F, typename P1, typename P2, typename P3>
00166 class ScopeGuardImpl3 : public ScopeGuardImplBase
00167 {
00168 public:
00169     static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
00170     {
00171         return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
00172     }
00173     ~ScopeGuardImpl3() throw() 
00174     {
00175         SafeExecute(*this);
00176     }
00177     void Execute()
00178     {
00179         fun_(p1_, p2_, p3_);
00180     }
00181 protected:
00182     ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3) 
00183     {
00184     }
00185     F fun_;
00186     const P1 p1_;
00187     const P2 p2_;
00188     const P3 p3_;
00189 };
00190 
00191 template <typename F, typename P1, typename P2, typename P3>
00192 inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
00193 {
00194     return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
00195 }
00196 
00197 //************************************************************
00198 
00200 template <class Obj, typename MemFun>
00201 class ObjScopeGuardImpl0 : public ScopeGuardImplBase
00202 {
00203 public:
00204     static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
00205     {
00206         return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
00207     }
00208     ~ObjScopeGuardImpl0() throw() 
00209     {
00210         SafeExecute(*this);
00211     }
00212     void Execute() 
00213     {
00214         (obj_.*memFun_)();
00215     }
00216 protected:
00217     ObjScopeGuardImpl0(Obj& obj, MemFun memFun) 
00218         : obj_(obj), memFun_(memFun) {}
00219     Obj& obj_;
00220     MemFun memFun_;
00221 };
00222 
00223 template <class Obj, typename MemFun>
00224 inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
00225 {
00226     return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
00227 }
00228 
00230 template <class Obj, typename MemFun, typename P1>
00231 class ObjScopeGuardImpl1 : public ScopeGuardImplBase
00232 {
00233 public:
00234     static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
00235     {
00236         return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
00237     }
00238     ~ObjScopeGuardImpl1() throw() 
00239     {
00240         SafeExecute(*this);
00241     }
00242     void Execute() 
00243     {
00244         (obj_.*memFun_)(p1_);
00245     }
00246 protected:
00247     ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) 
00248         : obj_(obj), memFun_(memFun), p1_(p1) {}
00249     Obj& obj_;
00250     MemFun memFun_;
00251     const P1 p1_;
00252 };
00253 
00254 template <class Obj, typename MemFun, typename P1>
00255 inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
00256 {
00257     return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
00258 }
00259 
00261 template <class Obj, typename MemFun, typename P1, typename P2>
00262 class ObjScopeGuardImpl2 : public ScopeGuardImplBase
00263 {
00264 public:
00265     static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
00266     {
00267         return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
00268     }
00269     ~ObjScopeGuardImpl2() throw() 
00270     {
00271         SafeExecute(*this);
00272     }
00273     void Execute() 
00274     {
00275         (obj_.*memFun_)(p1_, p2_);
00276     }
00277 protected:
00278     ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) 
00279         : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {}
00280     Obj& obj_;
00281     MemFun memFun_;
00282     const P1 p1_;
00283     const P2 p2_;
00284 };
00285 
00286 template <class Obj, typename MemFun, typename P1, typename P2>
00287 inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
00288 {
00289     return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
00290 }
00291 
00292 #define CONCATENATE_DIRECT(s1, s2) s1##s2
00293 #define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
00294 #define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
00295 
00296 #ifdef __GNUC__
00297 #  define UNUSED_VARIABLE __attribute__((unused))
00298 #else
00299 #  define UNUSED_VARIABLE
00300 #endif
00301 
00302 #define ON_BLOCK_EXIT ScopeGuard UNUSED_VARIABLE ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
00303 #define ON_BLOCK_EXIT_OBJ ScopeGuard UNUSED_VARIABLE ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard
00304 
00305 #endif //SCOPEGUARD_H_
00306 
00307 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines