MongoDB C++ Driver legacy-1.0.1
Loading...
Searching...
No Matches
scopeguard.h
1
2// The Loki Library
3// Copyright (c) 2000 Andrei Alexandrescu
4// Copyright (c) 2000 Petru Marginean
5// Copyright (c) 2005 Joshua Lehrer
6//
7// Permission to use, copy, modify, distribute and sell this software for any
8// purpose is hereby granted without fee, provided that the above copyright
9// notice appear in all copies and that both that copyright notice and this
10// permission notice appear in supporting documentation.
11// The author makes no representations about the
12// suitability of this software for any purpose. It is provided "as is"
13// without express or implied warranty.
15#ifndef LOKI_SCOPEGUARD_H_
16#define LOKI_SCOPEGUARD_H_
17
18#include "mongo/platform/compiler.h"
19
20namespace mongo
21{
22
29
30 template <class T>
32 {
33 public:
34
35 RefToValue(T& ref) : ref_(ref)
36 {}
37
38 RefToValue(const RefToValue& rhs) : ref_(rhs.ref_)
39 {}
40
41 operator T& () const
42 {
43 return ref_;
44 }
45
46 private:
47 // Disable - not implemented
48 RefToValue();
49 RefToValue& operator=(const RefToValue&);
50
51 T& ref_;
52 };
53
54
58
59 template <class T>
60 inline RefToValue<T> ByRef(T& t)
61 {
62 return RefToValue<T>(t);
63 }
64
65
66
67
70 /*
71 Trivial example for use:
72
73 FILE* f = fopen("myfile.txt", "w+");
74 if (!f)
75 return error;
76 ON_BLOCK_EXIT(fclose, f);
77
78
79 More complicated example:
80
81 ScopeGuard guard = MakeGuard(my_rollback_func, myparam);
82 ...
83 if (successful) {
84 guard.Dismiss();
85 return;
86 }
87 // guard is still active here and will fire at scope exit
88 ...
89
90
91 */
92
93
95 {
96 ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
97
98 protected:
99
101 {}
102
103 ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
104 : dismissed_(other.dismissed_)
105 {
106 other.Dismiss();
107 }
108
109 template <typename J>
110 static void SafeExecute(J& j) throw()
111 {
112 if (!j.dismissed_)
113 try
114 {
115 j.Execute();
116 }
117 catch(...)
118 {}
119 }
120
121 mutable bool dismissed_;
122
123 public:
124 ScopeGuardImplBase() throw() : dismissed_(false)
125 {}
126
127 void Dismiss() const throw()
128 {
129 dismissed_ = true;
130 }
131 };
132
143
145
146 template <typename F>
148 {
149 public:
150 static ScopeGuardImpl0<F> MakeGuard(F fun)
151 {
152 return ScopeGuardImpl0<F>(fun);
153 }
154
155 ~ScopeGuardImpl0() throw()
156 {
157 SafeExecute(*this);
158 }
159
160 void Execute()
161 {
162 fun_();
163 }
164
165 protected:
166 ScopeGuardImpl0(F fun) : fun_(fun)
167 {}
168
169 F fun_;
170 };
171
172 template <typename F>
173 inline ScopeGuardImpl0<F> MakeGuard(F fun)
174 {
176 }
177
178 template <typename F, typename P1>
180 {
181 public:
182 static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
183 {
184 return ScopeGuardImpl1<F, P1>(fun, p1);
185 }
186
187 ~ScopeGuardImpl1() throw()
188 {
189 SafeExecute(*this);
190 }
191
192 void Execute()
193 {
194 fun_(p1_);
195 }
196
197 protected:
198 ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
199 {}
200
201 F fun_;
202 const P1 p1_;
203 };
204
205 template <typename F, typename P1>
206 inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
207 {
208 return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
209 }
210
211 template <typename F, typename P1, typename P2>
213 {
214 public:
215 static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
216 {
217 return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
218 }
219
220 ~ScopeGuardImpl2() throw()
221 {
222 SafeExecute(*this);
223 }
224
225 void Execute()
226 {
227 fun_(p1_, p2_);
228 }
229
230 protected:
231 ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
232 {}
233
234 F fun_;
235 const P1 p1_;
236 const P2 p2_;
237 };
238
239 template <typename F, typename P1, typename P2>
240 inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
241 {
242 return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
243 }
244
245 template <typename F, typename P1, typename P2, typename P3>
247 {
248 public:
249 static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
250 {
251 return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
252 }
253
254 ~ScopeGuardImpl3() throw()
255 {
256 SafeExecute(*this);
257 }
258
259 void Execute()
260 {
261 fun_(p1_, p2_, p3_);
262 }
263
264 protected:
265 ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
266 {}
267
268 F fun_;
269 const P1 p1_;
270 const P2 p2_;
271 const P3 p3_;
272 };
273
274 template <typename F, typename P1, typename P2, typename P3>
275 inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
276 {
277 return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
278 }
279
280 //************************************************************
281
282 template <class Obj, typename MemFun>
284 {
285 public:
286 static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
287 {
288 return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
289 }
290
291 ~ObjScopeGuardImpl0() throw()
292 {
293 SafeExecute(*this);
294 }
295
296 void Execute()
297 {
298 (obj_.*memFun_)();
299 }
300
301 protected:
302 ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)
303 {}
304
305 Obj& obj_;
306 MemFun memFun_;
307 };
308
309 template <class Obj, typename MemFun>
310 inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
311 {
313 }
314
315 template <typename Ret, class Obj1, class Obj2>
316 inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 &obj)
317 {
318 return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(obj,memFun);
319 }
320
321 template <typename Ret, class Obj1, class Obj2>
322 inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 *obj)
323 {
324 return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(*obj,memFun);
325 }
326
327 template <class Obj, typename MemFun, typename P1>
329 {
330 public:
331 static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
332 {
333 return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
334 }
335
336 ~ObjScopeGuardImpl1() throw()
337 {
338 SafeExecute(*this);
339 }
340
341 void Execute()
342 {
343 (obj_.*memFun_)(p1_);
344 }
345
346 protected:
347 ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
348 {}
349
350 Obj& obj_;
351 MemFun memFun_;
352 const P1 p1_;
353 };
354
355 template <class Obj, typename MemFun, typename P1>
356 inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
357 {
359 }
360
361 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
362 inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 &obj, P1b p1)
363 {
364 return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(obj,memFun,p1);
365 }
366
367 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
368 inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 *obj, P1b p1)
369 {
370 return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(*obj,memFun,p1);
371 }
372
373 template <class Obj, typename MemFun, typename P1, typename P2>
375 {
376 public:
377 static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
378 {
379 return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
380 }
381
382 ~ObjScopeGuardImpl2() throw()
383 {
384 SafeExecute(*this);
385 }
386
387 void Execute()
388 {
389 (obj_.*memFun_)(p1_, p2_);
390 }
391
392 protected:
393 ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
394 {}
395
396 Obj& obj_;
397 MemFun memFun_;
398 const P1 p1_;
399 const P2 p2_;
400 };
401
402 template <class Obj, typename MemFun, typename P1, typename P2>
403 inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
404 {
406 }
407
408 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
409 inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 &obj, P1b p1, P2b p2)
410 {
411 return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(obj,memFun,p1,p2);
412 }
413
414 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
415 inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 *obj, P1b p1, P2b p2)
416 {
417 return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(*obj,memFun,p1,p2);
418 }
419
420} // namespace Loki
421
422#define LOKI_CONCATENATE_DIRECT(s1, s2) s1##s2
423#define LOKI_CONCATENATE(s1, s2) LOKI_CONCATENATE_DIRECT(s1, s2)
424#define LOKI_ANONYMOUS_VARIABLE(str) LOKI_CONCATENATE(str, __LINE__)
425
426#define ON_BLOCK_EXIT \
427 MONGO_COMPILER_VARIABLE_UNUSED ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
428#define ON_BLOCK_EXIT_OBJ \
429 MONGO_COMPILER_VARIABLE_UNUSED ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard
430
431#endif //LOKI_SCOPEGUARD_H_
Definition scopeguard.h:284
Definition scopeguard.h:329
Definition scopeguard.h:375
Transports a reference as a value Serves to implement the Colvin/Gibbons trick for SmartPtr/ScopeGuar...
Definition scopeguard.h:32
Definition scopeguard.h:148
Definition scopeguard.h:180
Definition scopeguard.h:213
Definition scopeguard.h:247
ScopeGuard.
Definition scopeguard.h:95
the main MongoDB namespace
Definition bulk_operation_builder.h:24
RefToValue< T > ByRef(T &t)
RefToValue creator.
Definition scopeguard.h:60
const ScopeGuardImplBase & ScopeGuard
See Andrei's and Petru Marginean's CUJ article http://www.cuj.com/documents/s=8000/cujcexp1812alexand...
Definition scopeguard.h:144