MongoDB C++ Driver legacy-1.1.2
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
28
29template <class T>
31public:
32 RefToValue(T& ref) : ref_(ref) {}
33
34 RefToValue(const RefToValue& rhs) : ref_(rhs.ref_) {}
35
36 operator T&() const {
37 return ref_;
38 }
39
40private:
41 // Disable - not implemented
42 RefToValue();
43 RefToValue& operator=(const RefToValue&);
44
45 T& ref_;
46};
47
48
52
53template <class T>
54inline RefToValue<T> ByRef(T& t) {
55 return RefToValue<T>(t);
56}
57
58
61/*
62 Trivial example for use:
63
64 FILE* f = fopen("myfile.txt", "w+");
65 if (!f)
66 return error;
67 ON_BLOCK_EXIT(fclose, f);
68
69
70 More complicated example:
71
72 ScopeGuard guard = MakeGuard(my_rollback_func, myparam);
73 ...
74 if (successful) {
75 guard.Dismiss();
76 return;
77 }
78 // guard is still active here and will fire at scope exit
79 ...
80
81
82*/
83
84
86 ScopeGuardImplBase& operator=(const ScopeGuardImplBase&);
87
88protected:
90
91 ScopeGuardImplBase(const ScopeGuardImplBase& other) throw() : dismissed_(other.dismissed_) {
92 other.Dismiss();
93 }
94
95 template <typename J>
96 static void SafeExecute(J& j) throw() {
97 if (!j.dismissed_)
98 try {
99 j.Execute();
100 } catch (...) {
101 }
102 }
103
104 mutable bool dismissed_;
105
106public:
107 ScopeGuardImplBase() throw() : dismissed_(false) {}
108
109 void Dismiss() const throw() {
110 dismissed_ = true;
111 }
112};
113
124
126
127template <typename F>
129public:
130 static ScopeGuardImpl0<F> MakeGuard(F fun) {
131 return ScopeGuardImpl0<F>(fun);
132 }
133
134 ~ScopeGuardImpl0() throw() {
135 SafeExecute(*this);
136 }
137
138 void Execute() {
139 fun_();
140 }
141
142protected:
143 ScopeGuardImpl0(F fun) : fun_(fun) {}
144
145 F fun_;
146};
147
148template <typename F>
149inline ScopeGuardImpl0<F> MakeGuard(F fun) {
151}
152
153template <typename F, typename P1>
155public:
156 static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) {
157 return ScopeGuardImpl1<F, P1>(fun, p1);
158 }
159
160 ~ScopeGuardImpl1() throw() {
161 SafeExecute(*this);
162 }
163
164 void Execute() {
165 fun_(p1_);
166 }
167
168protected:
169 ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) {}
170
171 F fun_;
172 const P1 p1_;
173};
174
175template <typename F, typename P1>
176inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) {
177 return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
178}
179
180template <typename F, typename P1, typename P2>
182public:
183 static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2) {
184 return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
185 }
186
187 ~ScopeGuardImpl2() throw() {
188 SafeExecute(*this);
189 }
190
191 void Execute() {
192 fun_(p1_, p2_);
193 }
194
195protected:
196 ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) {}
197
198 F fun_;
199 const P1 p1_;
200 const P2 p2_;
201};
202
203template <typename F, typename P1, typename P2>
204inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2) {
205 return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
206}
207
208template <typename F, typename P1, typename P2, typename P3>
210public:
211 static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3) {
212 return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
213 }
214
215 ~ScopeGuardImpl3() throw() {
216 SafeExecute(*this);
217 }
218
219 void Execute() {
220 fun_(p1_, p2_, p3_);
221 }
222
223protected:
224 ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3) {}
225
226 F fun_;
227 const P1 p1_;
228 const P2 p2_;
229 const P3 p3_;
230};
231
232template <typename F, typename P1, typename P2, typename P3>
233inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3) {
234 return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
235}
236
237//************************************************************
238
239template <class Obj, typename MemFun>
241public:
242 static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) {
243 return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
244 }
245
246 ~ObjScopeGuardImpl0() throw() {
247 SafeExecute(*this);
248 }
249
250 void Execute() {
251 (obj_.*memFun_)();
252 }
253
254protected:
255 ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun) {}
256
257 Obj& obj_;
258 MemFun memFun_;
259};
260
261template <class Obj, typename MemFun>
262inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) {
264}
265
266template <typename Ret, class Obj1, class Obj2>
267inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()> MakeGuard(Ret (Obj2::*memFun)(), Obj1& obj) {
268 return ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>::MakeObjGuard(obj, memFun);
269}
270
271template <typename Ret, class Obj1, class Obj2>
272inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()> MakeGuard(Ret (Obj2::*memFun)(), Obj1* obj) {
273 return ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>::MakeObjGuard(*obj, memFun);
274}
275
276template <class Obj, typename MemFun, typename P1>
278public:
279 static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1) {
280 return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
281 }
282
283 ~ObjScopeGuardImpl1() throw() {
284 SafeExecute(*this);
285 }
286
287 void Execute() {
288 (obj_.*memFun_)(p1_);
289 }
290
291protected:
292 ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1) {}
293
294 Obj& obj_;
295 MemFun memFun_;
296 const P1 p1_;
297};
298
299template <class Obj, typename MemFun, typename P1>
300inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1) {
302}
303
304template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
305inline ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b> MakeGuard(Ret (Obj2::*memFun)(P1a),
306 Obj1& obj,
307 P1b p1) {
308 return ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b>::MakeObjGuard(obj, memFun, p1);
309}
310
311template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
312inline ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b> MakeGuard(Ret (Obj2::*memFun)(P1a),
313 Obj1* obj,
314 P1b p1) {
315 return ObjScopeGuardImpl1<Obj1, Ret (Obj2::*)(P1a), P1b>::MakeObjGuard(*obj, memFun, p1);
316}
317
318template <class Obj, typename MemFun, typename P1, typename P2>
320public:
321 static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj,
322 MemFun memFun,
323 P1 p1,
324 P2 p2) {
325 return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
326 }
327
328 ~ObjScopeGuardImpl2() throw() {
329 SafeExecute(*this);
330 }
331
332 void Execute() {
333 (obj_.*memFun_)(p1_, p2_);
334 }
335
336protected:
337 ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2)
338 : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {}
339
340 Obj& obj_;
341 MemFun memFun_;
342 const P1 p1_;
343 const P2 p2_;
344};
345
346template <class Obj, typename MemFun, typename P1, typename P2>
347inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2) {
349}
350
351template <typename Ret,
352 class Obj1,
353 class Obj2,
354 typename P1a,
355 typename P1b,
356 typename P2a,
357 typename P2b>
358inline ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b> MakeGuard(
359 Ret (Obj2::*memFun)(P1a, P2a), Obj1& obj, P1b p1, P2b p2) {
360 return ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b>::MakeObjGuard(
361 obj, memFun, p1, p2);
362}
363
364template <typename Ret,
365 class Obj1,
366 class Obj2,
367 typename P1a,
368 typename P1b,
369 typename P2a,
370 typename P2b>
371inline ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b> MakeGuard(
372 Ret (Obj2::*memFun)(P1a, P2a), Obj1* obj, P1b p1, P2b p2) {
373 return ObjScopeGuardImpl2<Obj1, Ret (Obj2::*)(P1a, P2a), P1b, P2b>::MakeObjGuard(
374 *obj, memFun, p1, p2);
375}
376
377} // namespace Loki
378
379#define LOKI_CONCATENATE_DIRECT(s1, s2) s1##s2
380#define LOKI_CONCATENATE(s1, s2) LOKI_CONCATENATE_DIRECT(s1, s2)
381#define LOKI_ANONYMOUS_VARIABLE(str) LOKI_CONCATENATE(str, __LINE__)
382
383#define ON_BLOCK_EXIT \
384 MONGO_COMPILER_VARIABLE_UNUSED ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
385#define ON_BLOCK_EXIT_OBJ \
386 MONGO_COMPILER_VARIABLE_UNUSED ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard
387
388#endif // LOKI_SCOPEGUARD_H_
Definition scopeguard.h:240
Definition scopeguard.h:277
Definition scopeguard.h:319
Transports a reference as a value Serves to implement the Colvin/Gibbons trick for SmartPtr/ScopeGuar...
Definition scopeguard.h:30
Definition scopeguard.h:128
Definition scopeguard.h:154
Definition scopeguard.h:181
Definition scopeguard.h:209
ScopeGuard.
Definition scopeguard.h:85
Utility functions for parsing numbers from strings.
Definition compare_numbers.h:20
RefToValue< T > ByRef(T &t)
RefToValue creator.
Definition scopeguard.h:54
const ScopeGuardImplBase & ScopeGuard
See Andrei's and Petru Marginean's CUJ article http://www.cuj.com/documents/s=8000/cujcexp1812alexand...
Definition scopeguard.h:125