|
Qore Programming Language
0.8.3
|
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