0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ScopeGuard.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Hypertable. If not, see <http://www.gnu.org/licenses/>
18  */
19 
26 #ifndef HT_SCOPEGUARD_H
27 #define HT_SCOPEGUARD_H
28 
29 namespace Hypertable {
30 
37 protected:
39  ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
40  : m_dismissed(other.m_dismissed) {
41  other.dismiss();
42  }
43 
44  template <typename GuardT>
45  static void safe_run(GuardT& guard) throw() {
46  if (!guard.m_dismissed) try {
47  guard.run();
48  }
49  catch(...) { }
50  }
51 
52 public:
53  ScopeGuardImplBase() throw() : m_dismissed(false) { }
54  void dismiss() const throw() { m_dismissed = true; }
55 
56 private:
57  ScopeGuardImplBase& operator=(const ScopeGuardImplBase&); // not assignable
58 
59  mutable bool m_dismissed;
60 };
61 
62 /*
63  * According to the C++ standard, a reference initialized with a temporary
64  * value makes that temporary value live for the lifetime of the reference
65  * itself. This can save us from having to explicitly instantiate the guards
66  * with long type parameters
67  */
69 
73 template <typename FunT>
75 public:
76  static ScopeGuardImpl0<FunT> make_guard(FunT fun) {
77  return ScopeGuardImpl0<FunT>(fun);
78  }
79  ~ScopeGuardImpl0() throw() { safe_run(*this); }
80  void run() { m_fun(); }
81 
82 private:
83  ScopeGuardImpl0(FunT fun) : m_fun(fun) { }
84 
85  FunT m_fun;
86 };
87 
88 template <typename FunT>
91 }
92 
96 template <typename FunT, typename P1T>
98 public:
99  static ScopeGuardImpl1<FunT, P1T> make_guard(FunT fun, P1T p1) {
100  return ScopeGuardImpl1<FunT, P1T>(fun, p1);
101  }
102  ~ScopeGuardImpl1() throw() { safe_run(*this); }
103 
104  void run() { m_fun(m_p1); }
105 
106 private:
107  ScopeGuardImpl1(FunT fun, P1T p1) : m_fun(fun), m_p1(p1) { }
108 
109  FunT m_fun;
110  const P1T m_p1;
111 };
112 
113 template <typename FunT, typename P1T>
114 inline ScopeGuardImpl1<FunT, P1T> make_guard(FunT fun, P1T p1) {
116 }
117 
121 template <typename FunT, typename P1T, typename P2T>
123 public:
124  static ScopeGuardImpl2<FunT, P1T, P2T> make_guard(FunT fun, P1T p1, P2T p2) {
125  return ScopeGuardImpl2<FunT, P1T, P2T>(fun, p1, p2);
126  }
127  ~ScopeGuardImpl2() throw() { safe_run(*this); }
128 
129  void run() { m_fun(m_p1, m_p2); }
130 
131 private:
132  ScopeGuardImpl2(FunT fun, P1T p1, P2T p2) : m_fun(fun), m_p1(p1), m_p2(p2) { }
133 
134  FunT m_fun;
135  const P1T m_p1;
136  const P2T m_p2;
137 };
138 
139 template <typename FunT, typename P1T, typename P2T>
140 inline ScopeGuardImpl2<FunT, P1T, P2T> make_guard(FunT fun, P1T p1, P2T p2) {
142 }
143 
147 template <typename FunT, typename P1T, typename P2T, typename P3T>
149 public:
151  make_guard(FunT fun, P1T p1, P2T p2, P3T p3) {
152  return ScopeGuardImpl3<FunT, P1T, P2T, P3T>(fun, p1, p2, p3);
153  }
154  ~ScopeGuardImpl3() throw() { safe_run(*this); }
155 
156  void run() { m_fun(m_p1, m_p2, m_p3); }
157 
158 private:
159  ScopeGuardImpl3(FunT fun, P1T p1, P2T p2, P3T p3)
160  : m_fun(fun), m_p1(p1), m_p2(p2), m_p3(p3) { }
161 
162  FunT m_fun;
163  const P1T m_p1;
164  const P2T m_p2;
165  const P3T m_p3;
166 };
167 
168 template <typename FunT, typename P1T, typename P2T, typename P3T>
170 make_guard(FunT fun, P1T p1, P2T p2, P3T p3) {
171  return ScopeGuardImpl3<FunT, P1T, P2T, P3T>::make_guard(fun, p1, p2, p3);
172 }
173 
177 template <class ObjT, typename MethodT>
179 public:
181  make_obj_guard(ObjT &obj, MethodT method) {
182  return ObjScopeGuardImpl0<ObjT, MethodT>(obj, method);
183  }
184  ~ObjScopeGuardImpl0() throw() { safe_run(*this); }
185 
186  void run() { (m_obj.*m_method)(); }
187 
188 private:
189  ObjScopeGuardImpl0(ObjT &obj, MethodT method)
190  : m_obj(obj), m_method(method) { }
191 
192  ObjT &m_obj;
193  MethodT m_method;
194 };
195 
196 template <class ObjT, typename MethodT>
198 make_obj_guard(ObjT &obj, MethodT method) {
200 }
201 
205 template <class ObjT, typename MethodT, typename P1T>
207 public:
209  make_obj_guard(ObjT &obj, MethodT method, P1T p1) {
210  return ObjScopeGuardImpl1<ObjT, MethodT, P1T>(obj, method, p1);
211  }
212  ~ObjScopeGuardImpl1() throw() { safe_run(*this); }
213 
214  void run() { (m_obj.*m_method)(m_p1); }
215 
216 protected:
217  ObjScopeGuardImpl1(ObjT &obj, MethodT method, P1T p1)
218  : m_obj(obj), m_method(method), m_p1(p1) { }
219 
220  ObjT &m_obj;
221  MethodT m_method;
222  const P1T m_p1;
223 };
224 
225 template <class ObjT, typename MethodT, typename P1T>
227 make_obj_guard(ObjT &obj, MethodT method, P1T p1) {
229 }
230 
234 template <class ObjT, typename MethodT, typename P1T, typename P2T>
236 public:
238  make_obj_guard(ObjT &obj, MethodT method, P1T p1, P2T p2) {
239  return ObjScopeGuardImpl2<ObjT, MethodT, P1T, P2T>(obj, method, p1, p2);
240  }
241  ~ObjScopeGuardImpl2() throw() { safe_run(*this); }
242 
243  void run() { (m_obj.*m_method)(m_p1, m_p2); }
244 
245 private:
246  ObjScopeGuardImpl2(ObjT &obj, MethodT method, P1T p1, P2T p2)
247  : m_obj(obj), m_method(method), m_p1(p1), m_p2(p2) { }
248 
249  ObjT &m_obj;
250  MethodT m_method;
251  const P1T m_p1;
252  const P2T m_p2;
253 };
254 
255 template <class ObjT, typename MethodT, typename P1T, typename P2T>
257 make_obj_guard(ObjT &obj, MethodT method, P1T p1, P2T p2) {
259  method, p1, p2);
260 }
261 
274 template <class T>
275 class RefHolder {
276 public:
277  RefHolder(T& ref) : m_ref(ref) {}
278  operator T& () const { return m_ref; }
279 
280 private:
281  RefHolder& operator=(const RefHolder&); // not assignable
282  T& m_ref;
283 };
284 
285 template <class T>
286 inline RefHolder<T> by_ref(T& t) {
287  return RefHolder<T>(t);
288 }
289 
292 } // namespace Hypertable
293 
294 
295 // The two level macros are needed for var<lineno>.
296 // Otherwise, it'd be literally var__LINE__
297 #define HT_CONCAT_(s1, s2) s1##s2
298 #define HT_CONCAT(s1, s2) HT_CONCAT_(s1, s2)
299 #define HT_AUTO_VAR(var) HT_CONCAT(var, __LINE__)
300 
301 #define HT_ON_SCOPE_EXIT(...) \
302  ScopeGuard HT_AUTO_VAR(guard) = make_guard(__VA_ARGS__); \
303  HT_UNUSED(HT_AUTO_VAR(guard))
304 
305 #define HT_ON_OBJ_SCOPE_EXIT(...) \
306  ScopeGuard HT_AUTO_VAR(guard) = make_obj_guard(__VA_ARGS__); \
307  HT_UNUSED(HT_AUTO_VAR(guard))
308 
309 #endif // HT_SCOPEGUARD_H
ScopeGuard implementation for free function with 2 parameters.
Definition: ScopeGuard.h:122
static ScopeGuardImpl3< FunT, P1T, P2T, P3T > make_guard(FunT fun, P1T p1, P2T p2, P3T p3)
Definition: ScopeGuard.h:151
static ObjScopeGuardImpl2< ObjT, MethodT, P1T, P2T > make_obj_guard(ObjT &obj, MethodT method, P1T p1, P2T p2)
Definition: ScopeGuard.h:238
ObjScopeGuardImpl0(ObjT &obj, MethodT method)
Definition: ScopeGuard.h:189
ScopeGuard implementation for free function with 3 parameters.
Definition: ScopeGuard.h:148
ScopeGuard implementation for method with 1 parameter.
Definition: ScopeGuard.h:206
ScopeGuardImplBase & operator=(const ScopeGuardImplBase &)
const ScopeGuardImplBase & ScopeGuard
Definition: ScopeGuard.h:68
ObjScopeGuardImpl0< ObjT, MethodT > make_obj_guard(ObjT &obj, MethodT method)
Definition: ScopeGuard.h:198
ObjScopeGuardImpl1(ObjT &obj, MethodT method, P1T p1)
Definition: ScopeGuard.h:217
static ObjScopeGuardImpl0< ObjT, MethodT > make_obj_guard(ObjT &obj, MethodT method)
Definition: ScopeGuard.h:181
ScopeGuard implementation for method with 2 parameters.
Definition: ScopeGuard.h:235
ScopeGuardImplBase(const ScopeGuardImplBase &other)
Definition: ScopeGuard.h:39
ObjScopeGuardImpl2(ObjT &obj, MethodT method, P1T p1, P2T p2)
Definition: ScopeGuard.h:246
ScopeGuard implementation for free function with no paramter.
Definition: ScopeGuard.h:74
RefHolder & operator=(const RefHolder &)
static ScopeGuardImpl1< FunT, P1T > make_guard(FunT fun, P1T p1)
Definition: ScopeGuard.h:99
ScopeGuardImpl2(FunT fun, P1T p1, P2T p2)
Definition: ScopeGuard.h:132
ScopeGuardImpl1(FunT fun, P1T p1)
Definition: ScopeGuard.h:107
Hypertable definitions
static ScopeGuardImpl2< FunT, P1T, P2T > make_guard(FunT fun, P1T p1, P2T p2)
Definition: ScopeGuard.h:124
static ScopeGuardImpl0< FunT > make_guard(FunT fun)
Definition: ScopeGuard.h:76
ScopeGuardImpl0< FunT > make_guard(FunT fun)
Definition: ScopeGuard.h:89
ScopeGuardImpl3(FunT fun, P1T p1, P2T p2, P3T p3)
Definition: ScopeGuard.h:159
Base class for the ScopeGuards.
Definition: ScopeGuard.h:36
ScopeGuard implementation for free function with 1 parameter.
Definition: ScopeGuard.h:97
RefHolder< T > by_ref(T &t)
Definition: ScopeGuard.h:286
static ObjScopeGuardImpl1< ObjT, MethodT, P1T > make_obj_guard(ObjT &obj, MethodT method, P1T p1)
Definition: ScopeGuard.h:209
Helper class used to pass a parameter to the ScopeGuard by reference.
Definition: ScopeGuard.h:275
static void safe_run(GuardT &guard)
Definition: ScopeGuard.h:45
ScopeGuard implementation for method with no parameter.
Definition: ScopeGuard.h:178