IOSS  2.0
Ioss_ScopeGuard.h
Go to the documentation of this file.
1 /*
2  * Copyright(C) 2009-2017 National Technology & Engineering Solutions
3  * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
4  * NTESS, the U.S. Government retains certain rights in this software.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of NTESS nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 #ifndef SCOPEGUARD_H_
34 #define SCOPEGUARD_H_
35 
36 /*
37  Scopeguard, by Andrei Alexandrescu and Petru Marginean, December 2000.
38  Modified by Joshua Lehrer, FactSet Research Systems, November 2005.
39 */
40 
41 template <class T> class RefHolder
42 {
43  T &ref_;
44 
45 public:
46  explicit RefHolder(T &ref) : ref_(ref) {}
47  operator T &() const { return ref_; }
48  RefHolder &operator=(const RefHolder &) = delete;
49 };
50 
51 template <class T> inline RefHolder<T> ByRef(T &t) { return RefHolder<T>(t); }
52 
54 {
56 
57 protected:
58  ~ScopeGuardImplBase() = default;
59  ScopeGuardImplBase(const ScopeGuardImplBase &other) throw() : dismissed_(other.dismissed_)
60  {
61  other.Dismiss();
62  }
63  template <typename J> static void SafeExecute(J &j) throw()
64  {
65  if (!j.dismissed_) {
66  try {
67  j.Execute();
68  }
69  catch (...) {
70  }
71  }
72  }
73 
74  mutable bool dismissed_;
75 
76 public:
77  ScopeGuardImplBase() throw() : dismissed_(false) {}
78  void Dismiss() const throw() { dismissed_ = true; }
79 };
80 
81 // typedef const ScopeGuardImplBase& ScopeGuard;
82 __attribute__((unused)) typedef const ScopeGuardImplBase &ScopeGuard;
83 
84 template <typename F> class ScopeGuardImpl0 : public ScopeGuardImplBase
85 {
86 public:
87  static ScopeGuardImpl0<F> MakeGuard(F fun) { return ScopeGuardImpl0<F>(fun); }
88  ~ScopeGuardImpl0() throw() { SafeExecute(*this); }
89  void Execute() { fun_(); }
90 
91 protected:
92  explicit ScopeGuardImpl0(F fun) : fun_(fun) {}
93  F fun_;
94 };
95 
96 template <typename F> inline ScopeGuardImpl0<F> MakeGuard(F fun)
97 {
99 }
100 
101 template <typename F, typename P1> class ScopeGuardImpl1 : public ScopeGuardImplBase
102 {
103 public:
104  static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) { return ScopeGuardImpl1<F, P1>(fun, p1); }
105  ~ScopeGuardImpl1() throw() { SafeExecute(*this); }
106  void Execute() { fun_(p1_); }
107 
108 protected:
109  ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) {}
110  F fun_;
111  const P1 p1_;
112 };
113 
114 template <typename F, typename P1> inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
115 {
116  return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
117 }
118 
119 template <typename F, typename P1, typename P2> class ScopeGuardImpl2 : public ScopeGuardImplBase
120 {
121 public:
122  static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
123  {
124  return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
125  }
126  ~ScopeGuardImpl2() throw() { SafeExecute(*this); }
127  void Execute() { fun_(p1_, p2_); }
128 
129 protected:
130  ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) {}
131  F fun_;
132  const P1 p1_;
133  const P2 p2_;
134 };
135 
136 template <typename F, typename P1, typename P2>
137 inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
138 {
139  return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
140 }
141 
142 template <typename F, typename P1, typename P2, typename P3>
144 {
145 public:
146  static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
147  {
148  return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
149  }
150  ~ScopeGuardImpl3() throw() { SafeExecute(*this); }
151  void Execute() { fun_(p1_, p2_, p3_); }
152 
153 protected:
154  ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3) {}
155  F fun_;
156  const P1 p1_;
157  const P2 p2_;
158  const P3 p3_;
159 };
160 
161 template <typename F, typename P1, typename P2, typename P3>
162 inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
163 {
164  return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
165 }
166 
167 //************************************************************
168 
169 template <class Obj, typename MemFun> class ObjScopeGuardImpl0 : public ScopeGuardImplBase
170 {
171 public:
172  static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj &obj, MemFun memFun)
173  {
174  return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
175  }
176  ~ObjScopeGuardImpl0() throw() { SafeExecute(*this); }
177  void Execute() { (obj_.*memFun_)(); }
178 
179 protected:
180  ObjScopeGuardImpl0(Obj &obj, MemFun memFun) : obj_(obj), memFun_(memFun) {}
181  Obj & obj_;
182  MemFun memFun_;
183 };
184 
185 template <class Obj, typename MemFun>
186 inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj &obj, MemFun memFun)
187 {
189 }
190 
191 template <typename Ret, class Obj1, class Obj2>
192 inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()> MakeGuard(Ret (Obj2::*memFun)(), Obj1 &obj)
193 {
195 }
196 
197 template <typename Ret, class Obj1, class Obj2>
198 inline ObjScopeGuardImpl0<Obj1, Ret (Obj2::*)()> MakeGuard(Ret (Obj2::*memFun)(), Obj1 *obj)
199 {
201 }
202 
203 template <class Obj, typename MemFun, typename P1>
205 {
206 public:
207  static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1)
208  {
209  return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
210  }
211  ~ObjScopeGuardImpl1() throw() { SafeExecute(*this); }
212  void Execute() { (obj_.*memFun_)(p1_); }
213 
214 protected:
215  ObjScopeGuardImpl1(Obj &obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1) {}
216  Obj & obj_;
217  MemFun memFun_;
218  const P1 p1_;
219 };
220 
221 template <class Obj, typename MemFun, typename P1>
222 inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1)
223 {
225 }
226 
227 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
229  Obj1 &obj, P1b p1)
230 {
232 }
233 
234 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
236  Obj1 *obj, P1b p1)
237 {
239 }
240 
241 template <class Obj, typename MemFun, typename P1, typename P2>
243 {
244 public:
245  static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2)
246  {
247  return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
248  }
249  ~ObjScopeGuardImpl2() throw() { SafeExecute(*this); }
250  void Execute() { (obj_.*memFun_)(p1_, p2_); }
251 
252 protected:
253  ObjScopeGuardImpl2(Obj &obj, MemFun memFun, P1 p1, P2 p2)
254  : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
255  {
256  }
257  Obj & obj_;
258  MemFun memFun_;
259  const P1 p1_;
260  const P2 p2_;
261 };
262 
263 template <class Obj, typename MemFun, typename P1, typename P2>
264 inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2)
265 {
266  return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
267 }
268 
269 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a,
270  typename P2b>
272 MakeGuard(Ret (Obj2::*memFun)(P1a, P2a), Obj1 &obj, P1b p1, P2b p2)
273 {
275  p2);
276 }
277 
278 template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a,
279  typename P2b>
281 MakeGuard(Ret (Obj2::*memFun)(P1a, P2a), Obj1 *obj, P1b p1, P2b p2)
282 {
284  p2);
285 }
286 
287 #define CONCATENATE_DIRECT(s1, s2) s1##s2
288 #define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
289 #define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
290 
291 #define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
292 #define ON_BLOCK_EXIT_OBJ ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard
293 
294 #endif // SCOPEGUARD_H_
Obj & obj_
Definition: Ioss_ScopeGuard.h:216
RefHolder< T > ByRef(T &t)
Definition: Ioss_ScopeGuard.h:51
F fun_
Definition: Ioss_ScopeGuard.h:155
static ObjScopeGuardImpl0< Obj, MemFun > MakeObjGuard(Obj &obj, MemFun memFun)
Definition: Ioss_ScopeGuard.h:172
void Execute()
Definition: Ioss_ScopeGuard.h:177
ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3)
Definition: Ioss_ScopeGuard.h:154
~ScopeGuardImpl0()
Definition: Ioss_ScopeGuard.h:88
Definition: Ioss_ScopeGuard.h:242
F fun_
Definition: Ioss_ScopeGuard.h:110
const P1 p1_
Definition: Ioss_ScopeGuard.h:156
ScopeGuardImplBase()
Definition: Ioss_ScopeGuard.h:77
const P1 p1_
Definition: Ioss_ScopeGuard.h:111
~ObjScopeGuardImpl2()
Definition: Ioss_ScopeGuard.h:249
~ScopeGuardImpl3()
Definition: Ioss_ScopeGuard.h:150
Definition: Ioss_ScopeGuard.h:53
Definition: Ioss_ScopeGuard.h:84
const P1 p1_
Definition: Ioss_ScopeGuard.h:218
ScopeGuardImpl1(F fun, P1 p1)
Definition: Ioss_ScopeGuard.h:109
static ScopeGuardImpl1< F, P1 > MakeGuard(F fun, P1 p1)
Definition: Ioss_ScopeGuard.h:104
F fun_
Definition: Ioss_ScopeGuard.h:93
~ScopeGuardImplBase()=default
T & ref_
Definition: Ioss_ScopeGuard.h:43
const P1 p1_
Definition: Ioss_ScopeGuard.h:259
Definition: Ioss_ScopeGuard.h:143
const P3 p3_
Definition: Ioss_ScopeGuard.h:158
Definition: Ioss_ScopeGuard.h:204
~ObjScopeGuardImpl1()
Definition: Ioss_ScopeGuard.h:211
Obj & obj_
Definition: Ioss_ScopeGuard.h:181
static void SafeExecute(J &j)
Definition: Ioss_ScopeGuard.h:63
ScopeGuardImpl0< F > MakeGuard(F fun)
Definition: Ioss_ScopeGuard.h:96
ObjScopeGuardImpl0< Obj, MemFun > MakeObjGuard(Obj &obj, MemFun memFun)
Definition: Ioss_ScopeGuard.h:186
void Execute()
Definition: Ioss_ScopeGuard.h:89
static ScopeGuardImpl2< F, P1, P2 > MakeGuard(F fun, P1 p1, P2 p2)
Definition: Ioss_ScopeGuard.h:122
MemFun memFun_
Definition: Ioss_ScopeGuard.h:217
static ScopeGuardImpl3< F, P1, P2, P3 > MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
Definition: Ioss_ScopeGuard.h:146
bool dismissed_
Definition: Ioss_ScopeGuard.h:74
ObjScopeGuardImpl0(Obj &obj, MemFun memFun)
Definition: Ioss_ScopeGuard.h:180
ScopeGuardImpl2(F fun, P1 p1, P2 p2)
Definition: Ioss_ScopeGuard.h:130
static ObjScopeGuardImpl1< Obj, MemFun, P1 > MakeObjGuard(Obj &obj, MemFun memFun, P1 p1)
Definition: Ioss_ScopeGuard.h:207
static ObjScopeGuardImpl2< Obj, MemFun, P1, P2 > MakeObjGuard(Obj &obj, MemFun memFun, P1 p1, P2 p2)
Definition: Ioss_ScopeGuard.h:245
Definition: Ioss_ScopeGuard.h:169
RefHolder(T &ref)
Definition: Ioss_ScopeGuard.h:46
const P2 p2_
Definition: Ioss_ScopeGuard.h:260
const P2 p2_
Definition: Ioss_ScopeGuard.h:157
void Execute()
Definition: Ioss_ScopeGuard.h:151
static ScopeGuardImpl0< F > MakeGuard(F fun)
Definition: Ioss_ScopeGuard.h:87
MemFun memFun_
Definition: Ioss_ScopeGuard.h:182
void Execute()
Definition: Ioss_ScopeGuard.h:250
const P1 p1_
Definition: Ioss_ScopeGuard.h:132
void Dismiss() const
Definition: Ioss_ScopeGuard.h:78
Definition: Ioss_ScopeGuard.h:119
ScopeGuardImpl0(F fun)
Definition: Ioss_ScopeGuard.h:92
ObjScopeGuardImpl2(Obj &obj, MemFun memFun, P1 p1, P2 p2)
Definition: Ioss_ScopeGuard.h:253
RefHolder & operator=(const RefHolder &)=delete
MemFun memFun_
Definition: Ioss_ScopeGuard.h:258
~ScopeGuardImpl2()
Definition: Ioss_ScopeGuard.h:126
__attribute__((unused)) typedef const ScopeGuardImplBase &ScopeGuard
void Execute()
Definition: Ioss_ScopeGuard.h:127
F fun_
Definition: Ioss_ScopeGuard.h:131
~ObjScopeGuardImpl0()
Definition: Ioss_ScopeGuard.h:176
ObjScopeGuardImpl1(Obj &obj, MemFun memFun, P1 p1)
Definition: Ioss_ScopeGuard.h:215
Obj & obj_
Definition: Ioss_ScopeGuard.h:257
const P2 p2_
Definition: Ioss_ScopeGuard.h:133
ScopeGuardImplBase & operator=(const ScopeGuardImplBase &)
~ScopeGuardImpl1()
Definition: Ioss_ScopeGuard.h:105
ScopeGuardImplBase(const ScopeGuardImplBase &other)
Definition: Ioss_ScopeGuard.h:59
void Execute()
Definition: Ioss_ScopeGuard.h:212
Definition: Ioss_ScopeGuard.h:101
Definition: Ioss_ScopeGuard.h:41
void Execute()
Definition: Ioss_ScopeGuard.h:106