| Qore Programming Language - C/C++ Library 1.0.8

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
55 class ScopeGuardImplBase
56 {
57 ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
58 protected:
59 ~ScopeGuardImplBase()
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>
97 class ScopeGuardImpl0 : public ScopeGuardImplBase
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>
128 class ScopeGuardImpl1 : public ScopeGuardImplBase
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>
160 class ScopeGuardImpl2: public ScopeGuardImplBase
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>
193 class ScopeGuardImpl3 : public ScopeGuardImplBase
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>
228 class ObjScopeGuardImpl0 : public ScopeGuardImplBase
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 {
253 return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
254 }
255
257 template <class Obj, typename MemFun, typename P1>
258 class ObjScopeGuardImpl1 : public ScopeGuardImplBase
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 {
284 return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
285 }
286
288 template <class Obj, typename MemFun, typename P1, typename P2>
289 class ObjScopeGuardImpl2 : public ScopeGuardImplBase
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
ScopeGuardImpl1
scope guard class
Definition: ScopeGuard.h:128
ScopeGuardImplBase
scope guard class
Definition: ScopeGuard.h:55
ScopeGuardImpl0
scope guard class
Definition: ScopeGuard.h:97
ObjScopeGuardImpl0
scope guard class
Definition: ScopeGuard.h:228
ScopeGuardImpl3
scope guard class
Definition: ScopeGuard.h:193
RefHolder
templated class for ScopeGuard to hold a c++ reference
Definition: ScopeGuard.h:34
ObjScopeGuardImpl1
scope guard class
Definition: ScopeGuard.h:258
ScopeGuardImpl2
scope guard class
Definition: ScopeGuard.h:160
ObjScopeGuardImpl2
scope guard class
Definition: ScopeGuard.h:289