Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
8.4 KiB

  1. //
  2. // file: scopeguard.h
  3. // Used with permission from
  4. // Andrei Alexandrescu and Petru Marginean
  5. //
  6. #ifndef SCOPEGUARD_H_
  7. #define SCOPEGUARD_H_
  8. template <class T>
  9. class RefHolder
  10. {
  11. T& ref_;
  12. public:
  13. RefHolder(T& ref) : ref_(ref) {}
  14. operator T& () const
  15. {
  16. return ref_;
  17. }
  18. };
  19. template <class T>
  20. inline RefHolder<T> ByRef(T& t)
  21. {
  22. return RefHolder<T>(t);
  23. }
  24. class ScopeGuardImplBase
  25. {
  26. ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
  27. protected:
  28. ~ScopeGuardImplBase()
  29. {
  30. }
  31. ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
  32. : dismissed_(other.dismissed_)
  33. {
  34. other.Dismiss();
  35. }
  36. template <typename J>
  37. static void SafeExecute(J& j) throw()
  38. {
  39. if (!j.dismissed_)
  40. try
  41. {
  42. j.Execute();
  43. }
  44. catch(...)
  45. {
  46. }
  47. }
  48. mutable bool dismissed_;
  49. public:
  50. ScopeGuardImplBase(bool active) throw() : dismissed_(!active)
  51. {
  52. }
  53. void Dismiss() const throw()
  54. {
  55. dismissed_ = true;
  56. }
  57. };
  58. typedef const ScopeGuardImplBase& ScopeGuard;
  59. template <typename F>
  60. class ScopeGuardImpl0 : public ScopeGuardImplBase
  61. {
  62. public:
  63. static ScopeGuardImpl0<F> MakeGuard(bool active, F fun)
  64. {
  65. return ScopeGuardImpl0<F>(active, fun);
  66. }
  67. ~ScopeGuardImpl0() throw()
  68. {
  69. SafeExecute(*this);
  70. }
  71. void Execute()
  72. {
  73. fun_();
  74. }
  75. protected:
  76. ScopeGuardImpl0(bool active, F fun) : ScopeGuardImplBase(active), fun_(fun)
  77. {
  78. }
  79. F fun_;
  80. };
  81. template <typename F>
  82. inline ScopeGuardImpl0<F> MakeGuard(F fun)
  83. {
  84. return ScopeGuardImpl0<F>::MakeGuard(true, fun);
  85. }
  86. template <typename F>
  87. inline ScopeGuardImpl0<F> MakeGuardIF(bool active, F fun)
  88. {
  89. return ScopeGuardImpl0<F>::MakeGuard(active, fun);
  90. }
  91. template <typename F, typename P1>
  92. class ScopeGuardImpl1 : public ScopeGuardImplBase
  93. {
  94. public:
  95. static ScopeGuardImpl1<F, P1> MakeGuard(bool active, F fun, P1 p1)
  96. {
  97. return ScopeGuardImpl1<F, P1>(active, fun, p1);
  98. }
  99. ~ScopeGuardImpl1() throw()
  100. {
  101. SafeExecute(*this);
  102. }
  103. void Execute()
  104. {
  105. fun_(p1_);
  106. }
  107. protected:
  108. ScopeGuardImpl1(bool active, F fun, P1 p1) : ScopeGuardImplBase(active), fun_(fun), p1_(p1)
  109. {
  110. }
  111. F fun_;
  112. const P1 p1_;
  113. };
  114. template <typename F, typename P1>
  115. inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
  116. {
  117. return ScopeGuardImpl1<F, P1>::MakeGuard(true, fun, p1);
  118. }
  119. template <typename F, typename P1>
  120. inline ScopeGuardImpl1<F, P1> MakeGuardIF(bool active, F fun, P1 p1)
  121. {
  122. return ScopeGuardImpl1<F, P1>::MakeGuard(active, fun, p1);
  123. }
  124. template <typename F, typename P1, typename P2>
  125. class ScopeGuardImpl2: public ScopeGuardImplBase
  126. {
  127. public:
  128. static ScopeGuardImpl2<F, P1, P2> MakeGuard(bool active, F fun, P1 p1, P2 p2)
  129. {
  130. return ScopeGuardImpl2<F, P1, P2>(active, fun, p1, p2);
  131. }
  132. ~ScopeGuardImpl2() throw()
  133. {
  134. SafeExecute(*this);
  135. }
  136. void Execute()
  137. {
  138. fun_(p1_, p2_);
  139. }
  140. protected:
  141. ScopeGuardImpl2(bool active, F fun, P1 p1, P2 p2) : ScopeGuardImplBase(active), fun_(fun), p1_(p1), p2_(p2)
  142. {
  143. }
  144. F fun_;
  145. const P1 p1_;
  146. const P2 p2_;
  147. };
  148. template <typename F, typename P1, typename P2>
  149. inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
  150. {
  151. return ScopeGuardImpl2<F, P1, P2>::MakeGuard(true, fun, p1, p2);
  152. }
  153. template <typename F, typename P1, typename P2>
  154. inline ScopeGuardImpl2<F, P1, P2> MakeGuardIF(bool active, F fun, P1 p1, P2 p2)
  155. {
  156. return ScopeGuardImpl2<F, P1, P2>::MakeGuard(active, fun, p1, p2);
  157. }
  158. template <typename F, typename P1, typename P2, typename P3>
  159. class ScopeGuardImpl3 : public ScopeGuardImplBase
  160. {
  161. public:
  162. static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(bool active, F fun, P1 p1, P2 p2, P3 p3)
  163. {
  164. return ScopeGuardImpl3<F, P1, P2, P3>(active, fun, p1, p2, p3);
  165. }
  166. ~ScopeGuardImpl3() throw()
  167. {
  168. SafeExecute(*this);
  169. }
  170. void Execute()
  171. {
  172. fun_(p1_, p2_, p3_);
  173. }
  174. protected:
  175. ScopeGuardImpl3(bool active, F fun, P1 p1, P2 p2, P3 p3) : ScopeGuardImplBase(active), fun_(fun), p1_(p1), p2_(p2), p3_(p3)
  176. {
  177. }
  178. F fun_;
  179. const P1 p1_;
  180. const P2 p2_;
  181. const P3 p3_;
  182. };
  183. template <typename F, typename P1, typename P2, typename P3>
  184. inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
  185. {
  186. return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(true, fun, p1, p2, p3);
  187. }
  188. template <typename F, typename P1, typename P2, typename P3>
  189. inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuardIF(bool active, F fun, P1 p1, P2 p2, P3 p3)
  190. {
  191. return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(active, fun, p1, p2, p3);
  192. }
  193. //************************************************************
  194. template <class Obj, typename MemFun>
  195. class ObjScopeGuardImpl0 : public ScopeGuardImplBase
  196. {
  197. public:
  198. static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(bool active, Obj& obj, MemFun memFun)
  199. {
  200. return ObjScopeGuardImpl0<Obj, MemFun>(active, obj, memFun);
  201. }
  202. ~ObjScopeGuardImpl0() throw()
  203. {
  204. SafeExecute(*this);
  205. }
  206. void Execute()
  207. {
  208. (obj_.*memFun_)();
  209. }
  210. protected:
  211. ObjScopeGuardImpl0(bool active, Obj& obj, MemFun memFun)
  212. : ScopeGuardImplBase(active), obj_(obj), memFun_(memFun) {}
  213. Obj& obj_;
  214. MemFun memFun_;
  215. };
  216. template <class Obj, typename MemFun>
  217. inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
  218. {
  219. return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(true, obj, memFun);
  220. }
  221. template <class Obj, typename MemFun>
  222. inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuardIF(bool active, Obj& obj, MemFun memFun)
  223. {
  224. return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(active, obj, memFun);
  225. }
  226. template <class Obj, typename MemFun, typename P1>
  227. class ObjScopeGuardImpl1 : public ScopeGuardImplBase
  228. {
  229. public:
  230. static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(bool active, Obj& obj, MemFun memFun, P1 p1)
  231. {
  232. return ObjScopeGuardImpl1<Obj, MemFun, P1>(active, obj, memFun, p1);
  233. }
  234. ~ObjScopeGuardImpl1() throw()
  235. {
  236. SafeExecute(*this);
  237. }
  238. void Execute()
  239. {
  240. (obj_.*memFun_)(p1_);
  241. }
  242. protected:
  243. ObjScopeGuardImpl1(bool active, Obj& obj, MemFun memFun, P1 p1)
  244. : ScopeGuardImplBase(active), obj_(obj), memFun_(memFun), p1_(p1) {}
  245. Obj& obj_;
  246. MemFun memFun_;
  247. const P1 p1_;
  248. };
  249. template <class Obj, typename MemFun, typename P1>
  250. inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
  251. {
  252. return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(true, obj, memFun, p1);
  253. }
  254. template <class Obj, typename MemFun, typename P1>
  255. inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuardIF(bool active, Obj& obj, MemFun memFun, P1 p1)
  256. {
  257. return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(active, obj, memFun, p1);
  258. }
  259. template <class Obj, typename MemFun, typename P1, typename P2>
  260. class ObjScopeGuardImpl2 : public ScopeGuardImplBase
  261. {
  262. public:
  263. static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(bool active, Obj& obj, MemFun memFun, P1 p1, P2 p2)
  264. {
  265. return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(active, obj, memFun, p1, p2);
  266. }
  267. ~ObjScopeGuardImpl2() throw()
  268. {
  269. SafeExecute(*this);
  270. }
  271. void Execute()
  272. {
  273. (obj_.*memFun_)(p1_, p2_);
  274. }
  275. protected:
  276. ObjScopeGuardImpl2(bool active, Obj& obj, MemFun memFun, P1 p1, P2 p2)
  277. : ScopeGuardImplBase(active), obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {}
  278. Obj& obj_;
  279. MemFun memFun_;
  280. const P1 p1_;
  281. const P2 p2_;
  282. };
  283. template <class Obj, typename MemFun, typename P1, typename P2>
  284. inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
  285. {
  286. return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(true, obj, memFun, p1, p2);
  287. }
  288. template <class Obj, typename MemFun, typename P1, typename P2>
  289. inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuardIF(bool active, Obj& obj, MemFun memFun, P1 p1, P2 p2)
  290. {
  291. return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(active, obj, memFun, p1, p2);
  292. }
  293. // Rollback helper functions
  294. template<typename T>
  295. void deletePtr(const T* p)
  296. {
  297. delete p;
  298. }
  299. template<typename T>
  300. void deleteArray(T* p)
  301. {
  302. delete[] p;
  303. }
  304. #define CONCATENATE_DIRECT(s1, s2) s1##s2
  305. #define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
  306. #define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
  307. #define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
  308. #define ON_BLOCK_EXIT_OBJ ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard
  309. #define ON_BLOCK_EXIT_IF ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuardIF
  310. #define ON_BLOCK_EXIT_OBJ_IF ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuardIF
  311. #endif //SCOPEGUARD_H_