MongoDB C++ Driver  legacy-1.1.2
scopeguard.h
1 // 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 
20 namespace mongo {
21 
28 
29 template <class T>
30 class RefToValue {
31 public:
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 
40 private:
41  // Disable - not implemented
42  RefToValue();
43  RefToValue& operator=(const RefToValue&);
44 
45  T& ref_;
46 };
47 
48 
52 
53 template <class T>
54 inline 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 
88 protected:
89  ~ScopeGuardImplBase() {}
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 
106 public:
107  ScopeGuardImplBase() throw() : dismissed_(false) {}
108 
109  void Dismiss() const throw() {
110  dismissed_ = true;
111  }
112 };
113 
124 
126 
127 template <typename F>
129 public:
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 
142 protected:
143  ScopeGuardImpl0(F fun) : fun_(fun) {}
144 
145  F fun_;
146 };
147 
148 template <typename F>
149 inline ScopeGuardImpl0<F> MakeGuard(F fun) {
150  return ScopeGuardImpl0<F>::MakeGuard(fun);
151 }
152 
153 template <typename F, typename P1>
155 public:
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 
168 protected:
169  ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) {}
170 
171  F fun_;
172  const P1 p1_;
173 };
174 
175 template <typename F, typename P1>
176 inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) {
177  return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
178 }
179 
180 template <typename F, typename P1, typename P2>
182 public:
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 
195 protected:
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 
203 template <typename F, typename P1, typename P2>
204 inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2) {
205  return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
206 }
207 
208 template <typename F, typename P1, typename P2, typename P3>
210 public:
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 
223 protected:
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 
232 template <typename F, typename P1, typename P2, typename P3>
233 inline 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 
239 template <class Obj, typename MemFun>
241 public:
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 
254 protected:
255  ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun) {}
256 
257  Obj& obj_;
258  MemFun memFun_;
259 };
260 
261 template <class Obj, typename MemFun>
262 inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) {
264 }
265 
266 template <typename Ret, class Obj1, class Obj2>
267 inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()> MakeGuard(Ret (Obj2::*memFun)(), Obj1& obj) {
268  return ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>::MakeObjGuard(obj, memFun);
269 }
270 
271 template <typename Ret, class Obj1, class Obj2>
272 inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()> MakeGuard(Ret (Obj2::*memFun)(), Obj1* obj) {
273  return ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()>::MakeObjGuard(*obj, memFun);
274 }
275 
276 template <class Obj, typename MemFun, typename P1>
278 public:
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 
291 protected:
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 
299 template <class Obj, typename MemFun, typename P1>
300 inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1) {
302 }
303 
304 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
305 inline 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 
311 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
312 inline 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 
318 template <class Obj, typename MemFun, typename P1, typename P2>
320 public:
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 
336 protected:
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 
346 template <class Obj, typename MemFun, typename P1, typename P2>
347 inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2) {
348  return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
349 }
350 
351 template <typename Ret,
352  class Obj1,
353  class Obj2,
354  typename P1a,
355  typename P1b,
356  typename P2a,
357  typename P2b>
358 inline 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 
364 template <typename Ret,
365  class Obj1,
366  class Obj2,
367  typename P1a,
368  typename P1b,
369  typename P2a,
370  typename P2b>
371 inline 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:277
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
Definition: scopeguard.h:128
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
Transports a reference as a value Serves to implement the Colvin/Gibbons trick for SmartPtr/ScopeGuar...
Definition: scopeguard.h:30
Definition: scopeguard.h:240
Definition: scopeguard.h:181
ScopeGuard.
Definition: scopeguard.h:85
Definition: scopeguard.h:209
Definition: scopeguard.h:154
Definition: scopeguard.h:319