~ubuntu-branches/ubuntu/precise/gmlive/precise

« back to all changes in this revision

Viewing changes to src/scope_gruard.h

  • Committer: Bazaar Package Importer
  • Author(s): Aron Xu
  • Date: 2010-01-28 10:02:52 UTC
  • Revision ID: james.westby@ubuntu.com-20100128100252-b0yb0n4zm7s85ce7
Tags: upstream-0.22.2
Import upstream version 0.22.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * =====================================================================================
 
3
 * 
 
4
 *       Filename:  scope_gruard.h
 
5
 * 
 
6
 *    Description: 资源自动释放,用于异常安全。
 
7
 * 
 
8
 *        Version:  1.0
 
9
 *        Created:  2007年08月21日 11时00分50秒 CST
 
10
 *       Revision:  none
 
11
 *       Compiler:  gcc
 
12
 * 
 
13
 *         Author:  wind (xihe), xihels@gmail.com
 
14
 *        Company:  cyclone
 
15
 * 
 
16
 * =====================================================================================
 
17
 */
 
18
#ifndef _SCOPE_GRUARD_H_
 
19
#define _SCOPE_GRUARD_H_
 
20
 
 
21
class ScopeGuardImplBase {
 
22
        public:
 
23
                void dismiss() const throw ()
 
24
                { dismissed = true; }
 
25
 
 
26
        protected:
 
27
                ScopeGuardImplBase() : dismissed (false) {}
 
28
                ScopeGuardImplBase(const ScopeGuardImplBase& other)
 
29
                        : dismissed (other.dismissed)
 
30
                { other.dismiss(); }
 
31
 
 
32
                ~ScopeGuardImplBase() {} // nonvirtual.
 
33
 
 
34
                mutable bool dismissed;
 
35
        private:
 
36
                // Disable assignment.
 
37
                ScopeGuardImplBase& operator = (const ScopeGuardImplBase&);
 
38
};
 
39
 
 
40
template <typename Fun>
 
41
class ScopeGuardImpl0 : public ScopeGuardImplBase {
 
42
        public:
 
43
                ScopeGuardImpl0(const Fun& _fun)
 
44
                        : fun(_fun) {}  
 
45
                ~ScopeGuardImpl0()
 
46
                {
 
47
                        try {
 
48
                                if (!dismissed) fun();
 
49
                        } catch (...) {}
 
50
                }
 
51
        private:
 
52
                Fun fun;
 
53
};
 
54
 
 
55
template <typename Fun>
 
56
        ScopeGuardImpl0<Fun>
 
57
MakeGuard(const Fun& fun)
 
58
{
 
59
        return ScopeGuardImpl0<Fun>(fun);
 
60
}
 
61
 
 
62
template <typename Fun, typename Parm>
 
63
class ScopeGuardImpl1 : public ScopeGuardImplBase {
 
64
        public:
 
65
                ScopeGuardImpl1(const Fun& _fun, const Parm& _parm)
 
66
                        : fun(_fun), parm(_parm) {}
 
67
 
 
68
                ~ScopeGuardImpl1()
 
69
                {
 
70
                        try {
 
71
                                if (!dismissed) fun(parm);
 
72
                        } catch (...) {}
 
73
                }
 
74
 
 
75
        private:
 
76
                Fun fun;
 
77
                const Parm parm;
 
78
};
 
79
 
 
80
template <typename Fun, typename Parm>
 
81
        ScopeGuardImpl1<Fun, Parm>
 
82
MakeGuard(const Fun& fun, const Parm& parm)
 
83
{
 
84
        return ScopeGuardImpl1<Fun, Parm>(fun, parm);
 
85
}
 
86
 
 
87
template <typename Fun, typename Parm1, typename Parm2>
 
88
class ScopeGuardImpl2 : public ScopeGuardImplBase {
 
89
        public:
 
90
                ScopeGuardImpl2(const Fun& _fun, 
 
91
                                const Parm1& _parm1, 
 
92
                                const Parm2& _parm2)
 
93
                        : fun(_fun),
 
94
                        parm1(_parm1),
 
95
                        parm2(_parm2) {}
 
96
 
 
97
                ~ScopeGuardImpl2()
 
98
                {
 
99
                        try {
 
100
                                if (!dismissed) fun(parm1, parm2);
 
101
                        } catch (...) {}
 
102
                }
 
103
        private:
 
104
                Fun fun;
 
105
                const Parm1 parm1;
 
106
                const Parm2 parm2; 
 
107
};
 
108
 
 
109
template <typename Fun, typename Parm1, typename Parm2>
 
110
        ScopeGuardImpl2<Fun, Parm1, Parm2>
 
111
MakeGuard(const Fun& fun, const Parm1& parm1, const Parm2& parm2)
 
112
{
 
113
        return ScopeGuardImpl2<Fun, Parm1, Parm2>(fun, parm1, parm2);
 
114
}
 
115
 
 
116
template <typename Fun, typename Parm1, typename Parm2, typename Parm3>
 
117
class ScopeGuardImpl3 : public ScopeGuardImplBase {
 
118
        public:
 
119
                ScopeGuardImpl3(const Fun& _fun, 
 
120
                                const Parm1& _parm1, 
 
121
                                const Parm2& _parm2,
 
122
                                const Parm3& _parm3)
 
123
                        : fun(_fun),
 
124
                        parm1(_parm1),
 
125
                        parm2(_parm2),
 
126
                        parm3(_parm3) {}
 
127
 
 
128
                ~ScopeGuardImpl3()
 
129
                {
 
130
                        try {
 
131
                                if (!dismissed) fun(parm1, parm2, parm3);
 
132
                        } catch (...) {}
 
133
                }
 
134
        private:
 
135
                Fun fun;
 
136
                const Parm1 parm1;
 
137
                const Parm2 parm2; 
 
138
                const Parm3 parm3; 
 
139
};
 
140
 
 
141
template <typename Fun, typename Parm1, typename Parm2, typename Parm3>
 
142
        ScopeGuardImpl3<Fun, Parm1, Parm2, Parm3>
 
143
MakeGuard(const Fun& fun,
 
144
                const Parm1& parm1,
 
145
                const Parm2& parm2, 
 
146
                const Parm3& parm3)
 
147
{
 
148
        return ScopeGuardImpl3<Fun, Parm1, Parm2, Parm3>(fun, parm1, parm2, parm3);
 
149
}
 
150
 
 
151
 
 
152
template <typename Fun, typename Parm1, typename Parm2,
 
153
         typename Parm3, typename Parm4>
 
154
         class ScopeGuardImpl4 : public ScopeGuardImplBase {
 
155
                 public:
 
156
                         ScopeGuardImpl4(const Fun& _fun, 
 
157
                                         const Parm1& _parm1, 
 
158
                                         const Parm2& _parm2,
 
159
                                         const Parm3& _parm3,
 
160
                                         const Parm4& _parm4)
 
161
                                 : fun(_fun),
 
162
                                 parm1(_parm1),
 
163
                                 parm2(_parm2),
 
164
                                 parm3(_parm3),
 
165
                                 parm4(_parm4) {}
 
166
 
 
167
                         ~ScopeGuardImpl4()
 
168
                         {
 
169
                                 try {
 
170
                                         if (!dismissed) fun(parm1, parm2, parm3, parm4);
 
171
                                 } catch (...) {}
 
172
                         }
 
173
                 private:
 
174
                         Fun fun;
 
175
                         const Parm1 parm1;
 
176
                         const Parm2 parm2; 
 
177
                         const Parm3 parm3; 
 
178
                         const Parm4 parm4;
 
179
         };
 
180
 
 
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,
 
185
                const Parm1& parm1,
 
186
                const Parm2& parm2, 
 
187
                const Parm3& parm3,
 
188
                const Parm4& parm4)
 
189
{
 
190
        return ScopeGuardImpl4<Fun, Parm1, Parm2, Parm3, Parm4>
 
191
                (fun, parm1, parm2, parm3, parm4);
 
192
}
 
193
 
 
194
 
 
195
 
 
196
 
 
197
template <typename Obj, typename Fun>
 
198
class ObjScopeGuardImpl0 : public ScopeGuardImplBase {
 
199
        public:
 
200
                ObjScopeGuardImpl0(Obj& _obj, const Fun& _fun)
 
201
                        : obj(_obj), 
 
202
                        fun(_fun) {}    
 
203
                ~ObjScopeGuardImpl0()
 
204
                {
 
205
                        try {
 
206
                                if (!dismissed) (obj.*fun)();
 
207
                        } catch (...) {}
 
208
                }
 
209
        private:
 
210
                Obj& obj;
 
211
                Fun fun;
 
212
};
 
213
 
 
214
template <typename Obj, typename Fun>
 
215
        ObjScopeGuardImpl0<Obj, Fun>
 
216
MakeGuard(Obj& obj, const Fun& fun)
 
217
{
 
218
        return ObjScopeGuardImpl0<Obj, Fun>(obj, fun);
 
219
}
 
220
 
 
221
template <typename Obj, typename Fun, typename Parm>
 
222
class ObjScopeGuardImpl1 : public ScopeGuardImplBase {
 
223
        public:
 
224
                ObjScopeGuardImpl1(Obj& _obj, const Fun& _fun, const Parm& _parm)
 
225
                        : obj(_obj), fun(_fun), parm(_parm) {}
 
226
 
 
227
                ~ObjScopeGuardImpl1()
 
228
                {
 
229
                        try {
 
230
                                if (!dismissed) (obj.*fun)(parm);
 
231
                        } catch (...) {}
 
232
                }
 
233
 
 
234
        private:
 
235
                Obj& obj;
 
236
                Fun fun;
 
237
                const Parm parm;
 
238
};
 
239
 
 
240
template <typename Obj, typename Fun, typename Parm>
 
241
        ObjScopeGuardImpl1<Obj, Fun, Parm>
 
242
MakeGuard(Obj& obj, const Fun& fun, const Parm& parm)
 
243
{
 
244
        return ObjScopeGuardImpl1<Obj, Fun, Parm>(obj, fun, parm);
 
245
}
 
246
 
 
247
template <typename Obj, typename Fun, typename Parm1, typename Parm2>
 
248
class ObjScopeGuardImpl2 : public ScopeGuardImplBase {
 
249
        public:
 
250
                ObjScopeGuardImpl2(Obj& _obj,
 
251
                                const Fun& _fun, 
 
252
                                const Parm1& _parm1, 
 
253
                                const Parm2& _parm2)
 
254
                        : obj(_obj),
 
255
                        fun(_fun),
 
256
                        parm1(_parm1),
 
257
                        parm2(_parm2) {}
 
258
 
 
259
                ~ObjScopeGuardImpl2()
 
260
                {
 
261
                        try {
 
262
                                if (!dismissed) (obj.*fun)(parm1, parm2);
 
263
                        } catch (...) {}
 
264
                }
 
265
        private:
 
266
                Obj& obj;
 
267
                Fun fun;
 
268
                const Parm1 parm1;
 
269
                const Parm2 parm2; 
 
270
};
 
271
 
 
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)
 
275
{
 
276
        return ObjScopeGuardImpl2<Obj, Fun, Parm1, Parm2>
 
277
                (obj, fun, parm1, parm2);
 
278
}
 
279
 
 
280
template <typename Obj, typename Fun, typename Parm1, typename Parm2, typename Parm3>
 
281
class ObjScopeGuardImpl3 : public ScopeGuardImplBase {
 
282
        public:
 
283
                ObjScopeGuardImpl3(Obj& _obj, 
 
284
                                const Fun& _fun, 
 
285
                                const Parm1& _parm1, 
 
286
                                const Parm2& _parm2,
 
287
                                const Parm3& _parm3)
 
288
                        : obj(_obj),
 
289
                        fun(_fun),
 
290
                        parm1(_parm1),
 
291
                        parm2(_parm2),
 
292
                        parm3(_parm3) {}
 
293
 
 
294
                ~ObjScopeGuardImpl3()
 
295
                {
 
296
                        try {
 
297
                                if (!dismissed) (obj.*fun)(parm1, parm2, parm3);
 
298
                        } catch (...) {}
 
299
                }
 
300
        private:
 
301
                Obj& obj;
 
302
                Fun fun;
 
303
                const Parm1 parm1;
 
304
                const Parm2 parm2; 
 
305
                const Parm3 parm3; 
 
306
};
 
307
 
 
308
template <typename Obj, typename Fun, typename Parm1, typename Parm2, typename Parm3>
 
309
        ObjScopeGuardImpl3<Obj, Fun, Parm1, Parm2, Parm3>
 
310
MakeGuard(Obj& obj,
 
311
                const Fun& fun,
 
312
                const Parm1& parm1,
 
313
                const Parm2& parm2, 
 
314
                const Parm3& parm3)
 
315
{
 
316
        return ObjScopeGuardImpl3<Obj, Fun, Parm1, Parm2, Parm3>
 
317
                (obj, fun, parm1, parm2, parm3);
 
318
}
 
319
 
 
320
 
 
321
template <typename Obj, typename Fun, typename Parm1, typename Parm2,
 
322
         typename Parm3, typename Parm4>
 
323
         class ObjScopeGuardImpl4 : public ScopeGuardImplBase {
 
324
                 public:
 
325
                         ObjScopeGuardImpl4(Obj& _obj,
 
326
                                         const Fun& _fun, 
 
327
                                         const Parm1& _parm1, 
 
328
                                         const Parm2& _parm2,
 
329
                                         const Parm3& _parm3,
 
330
                                         const Parm4& _parm4)
 
331
                                 :obj(_obj),
 
332
                                 fun(_fun),
 
333
                                 parm1(_parm1),
 
334
                                 parm2(_parm2),
 
335
                                 parm3(_parm3),
 
336
                                 parm4(_parm4) {}
 
337
 
 
338
                         ~ObjScopeGuardImpl4()
 
339
                         {
 
340
                                 try {
 
341
                                         if (!dismissed) (obj.*fun)(parm1, parm2, parm3, parm4);
 
342
                                 } catch (...) {}
 
343
                         }
 
344
                 private:
 
345
                         Obj& obj;
 
346
                         Fun fun;
 
347
                         const Parm1 parm1;
 
348
                         const Parm2 parm2; 
 
349
                         const Parm3 parm3; 
 
350
                         const Parm4 parm4;
 
351
         };
 
352
 
 
353
template <typename Obj, typename Fun, typename Parm1, typename Parm2,
 
354
         typename Parm3, typename Parm4>
 
355
        ObjScopeGuardImpl4<Obj, Fun, Parm1, Parm2, Parm3, Parm4>
 
356
MakeGuard(Obj& obj, 
 
357
                const Fun& fun,
 
358
                const Parm1& parm1,
 
359
                const Parm2& parm2, 
 
360
                const Parm3& parm3,
 
361
                const Parm4& parm4)
 
362
{
 
363
        return ObjScopeGuardImpl4<Obj, Fun, Parm1, Parm2, Parm3, Parm4>
 
364
                (obj, fun, parm1, parm2, parm3, parm4);
 
365
}
 
366
 
 
367
// 使用一个辅助类,可以把引用转变为一个值,
 
368
// 以适应一些需要修改参数的函数调用。
 
369
template <typename T>
 
370
class RefHolder {
 
371
        public:
 
372
                RefHolder(T& _ref) : ref(_ref) {}
 
373
                operator T& () const
 
374
                {
 
375
                        return ref;
 
376
                }
 
377
        private:
 
378
                T& ref;
 
379
};
 
380
 
 
381
template <typename T>
 
382
inline RefHolder<T> ByRef(T& t)
 
383
{
 
384
        return RefHolder<T>(t);
 
385
}
 
386
 
 
387
 
 
388
// 根据C++标准,如果 const 的引用和被初始化为对一个临时变量的引用,
 
389
// 那么它会使这个临时变量的生命期变得和它自己一样。
 
390
typedef const ScopeGuardImplBase& ScopeGuard;
 
391
 
 
392
#endif //_SCOPE_GRUARD_H_
 
393