2
* =====================================================================================
4
* Filename: scope_gruard.h
6
* Description: 资源自动释放,用于异常安全。
9
* Created: 2007年08月21日 11时00分50秒 CST
13
* Author: wind (xihe), xihels@gmail.com
16
* =====================================================================================
18
#ifndef _SCOPE_GRUARD_H_
19
#define _SCOPE_GRUARD_H_
21
class ScopeGuardImplBase {
23
void dismiss() const throw ()
27
ScopeGuardImplBase() : dismissed (false) {}
28
ScopeGuardImplBase(const ScopeGuardImplBase& other)
29
: dismissed (other.dismissed)
32
~ScopeGuardImplBase() {} // nonvirtual.
34
mutable bool dismissed;
36
// Disable assignment.
37
ScopeGuardImplBase& operator = (const ScopeGuardImplBase&);
40
template <typename Fun>
41
class ScopeGuardImpl0 : public ScopeGuardImplBase {
43
ScopeGuardImpl0(const Fun& _fun)
48
if (!dismissed) fun();
55
template <typename Fun>
57
MakeGuard(const Fun& fun)
59
return ScopeGuardImpl0<Fun>(fun);
62
template <typename Fun, typename Parm>
63
class ScopeGuardImpl1 : public ScopeGuardImplBase {
65
ScopeGuardImpl1(const Fun& _fun, const Parm& _parm)
66
: fun(_fun), parm(_parm) {}
71
if (!dismissed) fun(parm);
80
template <typename Fun, typename Parm>
81
ScopeGuardImpl1<Fun, Parm>
82
MakeGuard(const Fun& fun, const Parm& parm)
84
return ScopeGuardImpl1<Fun, Parm>(fun, parm);
87
template <typename Fun, typename Parm1, typename Parm2>
88
class ScopeGuardImpl2 : public ScopeGuardImplBase {
90
ScopeGuardImpl2(const Fun& _fun,
100
if (!dismissed) fun(parm1, parm2);
109
template <typename Fun, typename Parm1, typename Parm2>
110
ScopeGuardImpl2<Fun, Parm1, Parm2>
111
MakeGuard(const Fun& fun, const Parm1& parm1, const Parm2& parm2)
113
return ScopeGuardImpl2<Fun, Parm1, Parm2>(fun, parm1, parm2);
116
template <typename Fun, typename Parm1, typename Parm2, typename Parm3>
117
class ScopeGuardImpl3 : public ScopeGuardImplBase {
119
ScopeGuardImpl3(const Fun& _fun,
131
if (!dismissed) fun(parm1, parm2, parm3);
141
template <typename Fun, typename Parm1, typename Parm2, typename Parm3>
142
ScopeGuardImpl3<Fun, Parm1, Parm2, Parm3>
143
MakeGuard(const Fun& fun,
148
return ScopeGuardImpl3<Fun, Parm1, Parm2, Parm3>(fun, parm1, parm2, parm3);
152
template <typename Fun, typename Parm1, typename Parm2,
153
typename Parm3, typename Parm4>
154
class ScopeGuardImpl4 : public ScopeGuardImplBase {
156
ScopeGuardImpl4(const Fun& _fun,
170
if (!dismissed) fun(parm1, parm2, parm3, parm4);
181
template <typename Fun, typename Parm1, typename Parm2,
182
typename Parm3, typename Parm4>
183
ScopeGuardImpl4<Fun, Parm1, Parm2, Parm3, Parm4>
184
MakeGuard(const Fun& fun,
190
return ScopeGuardImpl4<Fun, Parm1, Parm2, Parm3, Parm4>
191
(fun, parm1, parm2, parm3, parm4);
197
template <typename Obj, typename Fun>
198
class ObjScopeGuardImpl0 : public ScopeGuardImplBase {
200
ObjScopeGuardImpl0(Obj& _obj, const Fun& _fun)
203
~ObjScopeGuardImpl0()
206
if (!dismissed) (obj.*fun)();
214
template <typename Obj, typename Fun>
215
ObjScopeGuardImpl0<Obj, Fun>
216
MakeGuard(Obj& obj, const Fun& fun)
218
return ObjScopeGuardImpl0<Obj, Fun>(obj, fun);
221
template <typename Obj, typename Fun, typename Parm>
222
class ObjScopeGuardImpl1 : public ScopeGuardImplBase {
224
ObjScopeGuardImpl1(Obj& _obj, const Fun& _fun, const Parm& _parm)
225
: obj(_obj), fun(_fun), parm(_parm) {}
227
~ObjScopeGuardImpl1()
230
if (!dismissed) (obj.*fun)(parm);
240
template <typename Obj, typename Fun, typename Parm>
241
ObjScopeGuardImpl1<Obj, Fun, Parm>
242
MakeGuard(Obj& obj, const Fun& fun, const Parm& parm)
244
return ObjScopeGuardImpl1<Obj, Fun, Parm>(obj, fun, parm);
247
template <typename Obj, typename Fun, typename Parm1, typename Parm2>
248
class ObjScopeGuardImpl2 : public ScopeGuardImplBase {
250
ObjScopeGuardImpl2(Obj& _obj,
259
~ObjScopeGuardImpl2()
262
if (!dismissed) (obj.*fun)(parm1, parm2);
272
template <typename Obj, typename Fun, typename Parm1, typename Parm2>
273
ObjScopeGuardImpl2<Obj, Fun, Parm1, Parm2>
274
MakeGuard(Obj& obj, const Fun& fun, const Parm1& parm1, const Parm2& parm2)
276
return ObjScopeGuardImpl2<Obj, Fun, Parm1, Parm2>
277
(obj, fun, parm1, parm2);
280
template <typename Obj, typename Fun, typename Parm1, typename Parm2, typename Parm3>
281
class ObjScopeGuardImpl3 : public ScopeGuardImplBase {
283
ObjScopeGuardImpl3(Obj& _obj,
294
~ObjScopeGuardImpl3()
297
if (!dismissed) (obj.*fun)(parm1, parm2, parm3);
308
template <typename Obj, typename Fun, typename Parm1, typename Parm2, typename Parm3>
309
ObjScopeGuardImpl3<Obj, Fun, Parm1, Parm2, Parm3>
316
return ObjScopeGuardImpl3<Obj, Fun, Parm1, Parm2, Parm3>
317
(obj, fun, parm1, parm2, parm3);
321
template <typename Obj, typename Fun, typename Parm1, typename Parm2,
322
typename Parm3, typename Parm4>
323
class ObjScopeGuardImpl4 : public ScopeGuardImplBase {
325
ObjScopeGuardImpl4(Obj& _obj,
338
~ObjScopeGuardImpl4()
341
if (!dismissed) (obj.*fun)(parm1, parm2, parm3, parm4);
353
template <typename Obj, typename Fun, typename Parm1, typename Parm2,
354
typename Parm3, typename Parm4>
355
ObjScopeGuardImpl4<Obj, Fun, Parm1, Parm2, Parm3, Parm4>
363
return ObjScopeGuardImpl4<Obj, Fun, Parm1, Parm2, Parm3, Parm4>
364
(obj, fun, parm1, parm2, parm3, parm4);
367
// 使用一个辅助类,可以把引用转变为一个值,
369
template <typename T>
372
RefHolder(T& _ref) : ref(_ref) {}
381
template <typename T>
382
inline RefHolder<T> ByRef(T& t)
384
return RefHolder<T>(t);
388
// 根据C++标准,如果 const 的引用和被初始化为对一个临时变量的引用,
389
// 那么它会使这个临时变量的生命期变得和它自己一样。
390
typedef const ScopeGuardImplBase& ScopeGuard;
392
#endif //_SCOPE_GRUARD_H_