Qore Programming Language  0.8.11.1
ScopeGuard.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 
3 /* The Loki Library
4  Copyright (c) 2000 Andrei Alexandrescu
5  Copyright (c) 2000 Petru Marginean
6  Copyright (c) 2005 Joshua Lehrer
7 
8  Permission to use, copy, modify, distribute and sell this software for any
9  purpose is hereby granted without fee, provided that the above copyright
10  notice appear in all copies and that both that copyright notice and this
11  permission notice appear in supporting documentation.
12  The author makes no representations about the
13  suitability of this software for any purpose. It is provided "as is"
14  without express or implied warranty.
15 */
16 
17 #ifndef SCOPEGUARD_H_
18 #define SCOPEGUARD_H_
19 
21 template <class T>
22 class RefHolder
23 {
24  T& ref_;
25 public:
26  RefHolder(T& ref) : ref_(ref) {}
27  operator T& () const
28  {
29  return ref_;
30  }
31 private:
32  // Disable assignment - not implemented
33  RefHolder& operator=(const RefHolder&);
34 };
35 
36 template <class T>
37 inline RefHolder<T> ByRef(T& t)
38 {
39  return RefHolder<T>(t);
40 }
41 
44 {
45  ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
46 protected:
48  {
49  }
50 public:
51  ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
52  : dismissed_(other.dismissed_)
53  {
54  other.Dismiss();
55  }
56 protected:
57  template <typename J>
58  static void SafeExecute(J& j) throw()
59  {
60  if (!j.dismissed_)
61  try
62  {
63  j.Execute();
64  }
65  catch(...)
66  {
67  }
68  }
69 
70  mutable bool dismissed_;
71 public:
72  ScopeGuardImplBase() throw() : dismissed_(false)
73  {
74  }
75  void Dismiss() const throw()
76  {
77  dismissed_ = true;
78  }
79 };
80 
81 typedef const ScopeGuardImplBase& ScopeGuard;
82 
84 template <typename F>
86 {
87 public:
88  static ScopeGuardImpl0<F> MakeGuard(F fun)
89  {
90  return ScopeGuardImpl0<F>(fun);
91  }
92  ~ScopeGuardImpl0() throw()
93  {
94  SafeExecute(*this);
95  }
96  void Execute()
97  {
98  fun_();
99  }
100 protected:
101  ScopeGuardImpl0(F fun) : fun_(fun)
102  {
103  }
104  F fun_;
105 };
106 
108 template <typename F>
109 inline ScopeGuardImpl0<F> MakeGuard(F fun)
110 {
111  return ScopeGuardImpl0<F>::MakeGuard(fun);
112 }
113 
115 template <typename F, typename P1>
117 {
118 public:
119  static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
120  {
121  return ScopeGuardImpl1<F, P1>(fun, p1);
122  }
123  ~ScopeGuardImpl1() throw()
124  {
125  SafeExecute(*this);
126  }
127  void Execute()
128  {
129  fun_(p1_);
130  }
131 protected:
132  ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
133  {
134  }
135  F fun_;
136  const P1 p1_;
137 };
138 
140 template <typename F, typename P1>
141 inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
142 {
143  return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
144 }
145 
147 template <typename F, typename P1, typename P2>
149 {
150 public:
151  static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
152  {
153  return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
154  }
155  ~ScopeGuardImpl2() throw()
156  {
157  SafeExecute(*this);
158  }
159  void Execute()
160  {
161  fun_(p1_, p2_);
162  }
163 protected:
164  ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
165  {
166  }
167  F fun_;
168  const P1 p1_;
169  const P2 p2_;
170 };
171 
173 template <typename F, typename P1, typename P2>
174 inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
175 {
176  return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
177 }
178 
180 template <typename F, typename P1, typename P2, typename P3>
182 {
183 public:
184  static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
185  {
186  return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
187  }
188  ~ScopeGuardImpl3() throw()
189  {
190  SafeExecute(*this);
191  }
192  void Execute()
193  {
194  fun_(p1_, p2_, p3_);
195  }
196 protected:
197  ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
198  {
199  }
200  F fun_;
201  const P1 p1_;
202  const P2 p2_;
203  const P3 p3_;
204 };
205 
206 template <typename F, typename P1, typename P2, typename P3>
207 inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
208 {
209  return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
210 }
211 
212 //************************************************************
213 
215 template <class Obj, typename MemFun>
217 {
218 public:
219  static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
220  {
221  return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
222  }
223  ~ObjScopeGuardImpl0() throw()
224  {
225  SafeExecute(*this);
226  }
227  void Execute()
228  {
229  (obj_.*memFun_)();
230  }
231 protected:
232  ObjScopeGuardImpl0(Obj& obj, MemFun memFun)
233  : obj_(obj), memFun_(memFun) {}
234  Obj& obj_;
235  MemFun memFun_;
236 };
237 
238 template <class Obj, typename MemFun>
239 inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
240 {
242 }
243 
245 template <class Obj, typename MemFun, typename P1>
247 {
248 public:
249  static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
250  {
251  return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
252  }
253  ~ObjScopeGuardImpl1() throw()
254  {
255  SafeExecute(*this);
256  }
257  void Execute()
258  {
259  (obj_.*memFun_)(p1_);
260  }
261 protected:
262  ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1)
263  : obj_(obj), memFun_(memFun), p1_(p1) {}
264  Obj& obj_;
265  MemFun memFun_;
266  const P1 p1_;
267 };
268 
269 template <class Obj, typename MemFun, typename P1>
270 inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
271 {
273 }
274 
276 template <class Obj, typename MemFun, typename P1, typename P2>
278 {
279 public:
280  static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
281  {
282  return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
283  }
284  ~ObjScopeGuardImpl2() throw()
285  {
286  SafeExecute(*this);
287  }
288  void Execute()
289  {
290  (obj_.*memFun_)(p1_, p2_);
291  }
292 protected:
293  ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2)
294  : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {}
295  Obj& obj_;
296  MemFun memFun_;
297  const P1 p1_;
298  const P2 p2_;
299 };
300 
301 template <class Obj, typename MemFun, typename P1, typename P2>
302 inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
303 {
304  return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
305 }
306 
307 #define CONCATENATE_DIRECT(s1, s2) s1##s2
308 #define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
309 #define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
310 
311 #ifdef __GNUC__
312 # define UNUSED_VARIABLE __attribute__((unused))
313 #else
314 # define UNUSED_VARIABLE
315 #endif
316 
317 #define ON_BLOCK_EXIT ScopeGuard UNUSED_VARIABLE ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
318 #define ON_BLOCK_EXIT_OBJ ScopeGuard UNUSED_VARIABLE ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard
319 
320 #endif //SCOPEGUARD_H_
321 
322 
scope guard class
Definition: ScopeGuard.h:116
scope guard class
Definition: ScopeGuard.h:43
scope guard class
Definition: ScopeGuard.h:85
scope guard class
Definition: ScopeGuard.h:216
scope guard class
Definition: ScopeGuard.h:181
templated class for ScopeGuard to hold a c++ reference
Definition: ScopeGuard.h:22
scope guard class
Definition: ScopeGuard.h:246
scope guard class
Definition: ScopeGuard.h:148
scope guard class
Definition: ScopeGuard.h:277