Qore Programming Language  1.12.0
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 
20 // make sure manual warnings don't get escalated to errors
21 #ifdef __clang__
22 #pragma clang diagnostic warning "-W#warnings"
23 #else
24 #ifdef __GNUC__
25 #if __GNUC__ >= 7
26 #pragma GCC diagnostic warning "-Wcpp"
27 #pragma GCC diagnostic ignored "-Wnoexcept-type"
28 #endif
29 #endif
30 #endif
31 
33 template <class T>
34 class RefHolder
35 {
36  T& ref_;
37 public:
38  RefHolder(T& ref) : ref_(ref) {}
39  operator T& () const
40  {
41  return ref_;
42  }
43 private:
44  // Disable assignment - not implemented
45  RefHolder& operator=(const RefHolder&);
46 };
47 
48 template <class T>
49 inline RefHolder<T> ByRef(T& t)
50 {
51  return RefHolder<T>(t);
52 }
53 
56 {
57  ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
58 protected:
60  {
61  }
62 public:
63  ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
64  : dismissed_(other.dismissed_)
65  {
66  other.Dismiss();
67  }
68 protected:
69  template <typename J>
70  static void SafeExecute(J& j) throw()
71  {
72  if (!j.dismissed_)
73  try
74  {
75  j.Execute();
76  }
77  catch(...)
78  {
79  }
80  }
81 
82  mutable bool dismissed_;
83 public:
84  ScopeGuardImplBase() throw() : dismissed_(false)
85  {
86  }
87  void Dismiss() const throw()
88  {
89  dismissed_ = true;
90  }
91 };
92 
93 typedef const ScopeGuardImplBase& ScopeGuard;
94 
96 template <typename F>
98 {
99 public:
100  static ScopeGuardImpl0<F> MakeGuard(F fun)
101  {
102  return ScopeGuardImpl0<F>(fun);
103  }
104  ~ScopeGuardImpl0() throw()
105  {
106  SafeExecute(*this);
107  }
108  void Execute()
109  {
110  fun_();
111  }
112 protected:
113  ScopeGuardImpl0(F fun) : fun_(fun)
114  {
115  }
116  F fun_;
117 };
118 
120 template <typename F>
121 inline ScopeGuardImpl0<F> MakeGuard(F fun)
122 {
123  return ScopeGuardImpl0<F>::MakeGuard(fun);
124 }
125 
127 template <typename F, typename P1>
129 {
130 public:
131  static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
132  {
133  return ScopeGuardImpl1<F, P1>(fun, p1);
134  }
135  ~ScopeGuardImpl1() throw()
136  {
137  SafeExecute(*this);
138  }
139  void Execute()
140  {
141  fun_(p1_);
142  }
143 protected:
144  ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
145  {
146  }
147  F fun_;
148  const P1 p1_;
149 };
150 
152 template <typename F, typename P1>
153 inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
154 {
155  return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
156 }
157 
159 template <typename F, typename P1, typename P2>
161 {
162 public:
163  static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
164  {
165  return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
166  }
167  ~ScopeGuardImpl2() throw()
168  {
169  SafeExecute(*this);
170  }
171  void Execute()
172  {
173  fun_(p1_, p2_);
174  }
175 protected:
176  ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
177  {
178  }
179  F fun_;
180  const P1 p1_;
181  const P2 p2_;
182 };
183 
185 template <typename F, typename P1, typename P2>
186 inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
187 {
188  return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
189 }
190 
192 template <typename F, typename P1, typename P2, typename P3>
194 {
195 public:
196  static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
197  {
198  return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
199  }
200  ~ScopeGuardImpl3() throw()
201  {
202  SafeExecute(*this);
203  }
204  void Execute()
205  {
206  fun_(p1_, p2_, p3_);
207  }
208 protected:
209  ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
210  {
211  }
212  F fun_;
213  const P1 p1_;
214  const P2 p2_;
215  const P3 p3_;
216 };
217 
218 template <typename F, typename P1, typename P2, typename P3>
219 inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
220 {
221  return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
222 }
223 
224 //************************************************************
225 
227 template <class Obj, typename MemFun>
229 {
230 public:
231  static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
232  {
233  return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
234  }
235  ~ObjScopeGuardImpl0() throw()
236  {
237  SafeExecute(*this);
238  }
239  void Execute()
240  {
241  (obj_.*memFun_)();
242  }
243 protected:
244  ObjScopeGuardImpl0(Obj& obj, MemFun memFun)
245  : obj_(obj), memFun_(memFun) {}
246  Obj& obj_;
247  MemFun memFun_;
248 };
249 
250 template <class Obj, typename MemFun>
251 inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
252 {
254 }
255 
257 template <class Obj, typename MemFun, typename P1>
259 {
260 public:
261  static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
262  {
263  return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
264  }
265  ~ObjScopeGuardImpl1() throw()
266  {
267  SafeExecute(*this);
268  }
269  void Execute()
270  {
271  (obj_.*memFun_)(p1_);
272  }
273 protected:
274  ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1)
275  : obj_(obj), memFun_(memFun), p1_(p1) {}
276  Obj& obj_;
277  MemFun memFun_;
278  const P1 p1_;
279 };
280 
281 template <class Obj, typename MemFun, typename P1>
282 inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
283 {
285 }
286 
288 template <class Obj, typename MemFun, typename P1, typename P2>
290 {
291 public:
292  static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
293  {
294  return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
295  }
296  ~ObjScopeGuardImpl2() throw()
297  {
298  SafeExecute(*this);
299  }
300  void Execute()
301  {
302  (obj_.*memFun_)(p1_, p2_);
303  }
304 protected:
305  ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2)
306  : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) {}
307  Obj& obj_;
308  MemFun memFun_;
309  const P1 p1_;
310  const P2 p2_;
311 };
312 
313 template <class Obj, typename MemFun, typename P1, typename P2>
314 inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
315 {
316  return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
317 }
318 
319 #define CONCATENATE_DIRECT(s1, s2) s1##s2
320 #define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
321 #define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
322 
323 #ifdef __GNUC__
324 # define UNUSED_VARIABLE __attribute__((unused))
325 #else
326 # define UNUSED_VARIABLE
327 #endif
328 
329 #define ON_BLOCK_EXIT ScopeGuard UNUSED_VARIABLE ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
330 #define ON_BLOCK_EXIT_OBJ ScopeGuard UNUSED_VARIABLE ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard
331 
332 #endif //SCOPEGUARD_H_
333 
334 
scope guard class
Definition: ScopeGuard.h:229
scope guard class
Definition: ScopeGuard.h:259
scope guard class
Definition: ScopeGuard.h:290
templated class for ScopeGuard to hold a c++ reference
Definition: ScopeGuard.h:35
scope guard class
Definition: ScopeGuard.h:98
scope guard class
Definition: ScopeGuard.h:129
scope guard class
Definition: ScopeGuard.h:161
scope guard class
Definition: ScopeGuard.h:194
scope guard class
Definition: ScopeGuard.h:56