]>
git.saurik.com Git - wxWidgets.git/blob - include/wx/scopeguard.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/scopeguard.h
3 // Purpose: declares wxwxScopeGuard and related macros
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
13 Acknowledgements: this header is heavily based on (well, almost the exact
14 copy of) wxScopeGuard.h by Andrei Alexandrescu and Petru Marginean published
15 in December 2000 issue of C/C++ Users Journal.
18 #ifndef _WX_SCOPEGUARD_H_
19 #define _WX_SCOPEGUARD_H_
23 // ----------------------------------------------------------------------------
25 // ----------------------------------------------------------------------------
29 // in the original implementation this was a member template function of
30 // ScopeGuardImplBase but gcc 2.8 which is still used for OS/2 doesn't
31 // support member templates and so we must make it global
32 template <typename ScopeGuardImpl
>
33 void OnScopeExit(ScopeGuardImpl
& guard
)
35 if ( !guard
.WasDismissed() )
37 // we're called from ScopeGuardImpl dtor and so we must not throw
40 #endif // wxUSE_EXCEPTIONS
48 #endif // wxUSE_EXCEPTIONS
52 // just to avoid the warning about unused variables
54 void Use(const T
& WXUNUSED(t
))
57 } // namespace wxPrivate
59 // ============================================================================
60 // wxScopeGuard for functions and functors
61 // ============================================================================
63 // ----------------------------------------------------------------------------
64 // wxScopeGuardImplBase: used by wxScopeGuardImpl[0..N] below
65 // ----------------------------------------------------------------------------
67 class wxScopeGuardImplBase
70 wxScopeGuardImplBase() : m_wasDismissed(false) { }
72 void Dismiss() const { m_wasDismissed
= true; }
74 // for OnScopeExit() only we can't make it friend, unfortunately)!
75 bool WasDismissed() const { return m_wasDismissed
; }
78 ~wxScopeGuardImplBase() { }
80 wxScopeGuardImplBase(const wxScopeGuardImplBase
& other
)
81 : m_wasDismissed(other
.m_wasDismissed
)
86 // must be mutable for copy ctor to work
87 mutable bool m_wasDismissed
;
90 wxScopeGuardImplBase
& operator=(const wxScopeGuardImplBase
&);
93 // ----------------------------------------------------------------------------
94 // wxScopeGuardImpl0: scope guard for actions without parameters
95 // ----------------------------------------------------------------------------
98 class wxScopeGuardImpl0
: public wxScopeGuardImplBase
101 static wxScopeGuardImpl0
<F
> MakeGuard(F fun
)
103 return wxScopeGuardImpl0
<F
>(fun
);
106 ~wxScopeGuardImpl0() { wxPrivate::OnScopeExit(*this); }
108 void Execute() { m_fun(); }
111 wxScopeGuardImpl0(F fun
) : m_fun(fun
) { }
115 wxScopeGuardImpl0
& operator=(const wxScopeGuardImpl0
&);
118 template <typename F
>
119 inline wxScopeGuardImpl0
<F
> wxMakeGuard(F fun
)
121 return wxScopeGuardImpl0
<F
>::MakeGuard(fun
);
124 // ----------------------------------------------------------------------------
125 // wxScopeGuardImpl1: scope guard for actions with 1 parameter
126 // ----------------------------------------------------------------------------
128 template <typename F
, typename P1
>
129 class wxScopeGuardImpl1
: public wxScopeGuardImplBase
132 static wxScopeGuardImpl1
<F
, P1
> MakeGuard(F fun
, P1 p1
)
134 return wxScopeGuardImpl1
<F
, P1
>(fun
, p1
);
137 ~wxScopeGuardImpl1() { wxPrivate::OnScopeExit(*this); }
139 void Execute() { m_fun(m_p1
); }
142 wxScopeGuardImpl1(F fun
, P1 p1
) : m_fun(fun
), m_p1(p1
) { }
147 wxScopeGuardImpl1
& operator=(const wxScopeGuardImpl1
&);
150 template <typename F
, typename P1
>
151 inline wxScopeGuardImpl1
<F
, P1
> wxMakeGuard(F fun
, P1 p1
)
153 return wxScopeGuardImpl1
<F
, P1
>::MakeGuard(fun
, p1
);
156 // ----------------------------------------------------------------------------
157 // wxScopeGuardImpl2: scope guard for actions with 2 parameters
158 // ----------------------------------------------------------------------------
160 template <typename F
, typename P1
, typename P2
>
161 class wxScopeGuardImpl2
: public wxScopeGuardImplBase
164 static wxScopeGuardImpl2
<F
, P1
, P2
> MakeGuard(F fun
, P1 p1
, P2 p2
)
166 return wxScopeGuardImpl2
<F
, P1
, P2
>(fun
, p1
, p2
);
169 ~wxScopeGuardImpl2() { wxPrivate::OnScopeExit(*this); }
171 void Execute() { m_fun(m_p1
, m_p2
); }
174 wxScopeGuardImpl2(F fun
, P1 p1
, P2 p2
) : m_fun(fun
), m_p1(p1
), m_p2(p2
) { }
180 wxScopeGuardImpl2
& operator=(const wxScopeGuardImpl2
&);
183 template <typename F
, typename P1
, typename P2
>
184 inline wxScopeGuardImpl2
<F
, P1
, P2
> wxMakeGuard(F fun
, P1 p1
, P2 p2
)
186 return wxScopeGuardImpl2
<F
, P1
, P2
>::MakeGuard(fun
, p1
, p2
);
189 // ============================================================================
190 // wxScopeGuards for object methods
191 // ============================================================================
193 // ----------------------------------------------------------------------------
194 // wxObjScopeGuardImpl0
195 // ----------------------------------------------------------------------------
197 template <class Obj
, typename MemFun
>
198 class wxObjScopeGuardImpl0
: public wxScopeGuardImplBase
201 static wxObjScopeGuardImpl0
<Obj
, MemFun
>
202 MakeObjGuard(Obj
& obj
, MemFun memFun
)
204 return wxObjScopeGuardImpl0
<Obj
, MemFun
>(obj
, memFun
);
207 ~wxObjScopeGuardImpl0() { wxPrivate::OnScopeExit(*this); }
209 void Execute() { (m_obj
.*m_memfun
)(); }
212 wxObjScopeGuardImpl0(Obj
& obj
, MemFun memFun
)
213 : m_obj(obj
), m_memfun(memFun
) { }
219 template <class Obj
, typename MemFun
>
220 inline wxObjScopeGuardImpl0
<Obj
, MemFun
> wxMakeObjGuard(Obj
& obj
, MemFun memFun
)
222 return wxObjScopeGuardImpl0
<Obj
, MemFun
>::MakeObjGuard(obj
, memFun
);
225 template <class Obj
, typename MemFun
, typename P1
>
226 class wxObjScopeGuardImpl1
: public wxScopeGuardImplBase
229 static wxObjScopeGuardImpl1
<Obj
, MemFun
, P1
>
230 MakeObjGuard(Obj
& obj
, MemFun memFun
, P1 p1
)
232 return wxObjScopeGuardImpl1
<Obj
, MemFun
, P1
>(obj
, memFun
, p1
);
235 ~wxObjScopeGuardImpl1() { wxPrivate::OnScopeExit(*this); }
237 void Execute() { (m_obj
.*m_memfun
)(m_p1
); }
240 wxObjScopeGuardImpl1(Obj
& obj
, MemFun memFun
, P1 p1
)
241 : m_obj(obj
), m_memfun(memFun
), m_p1(p1
) { }
248 template <class Obj
, typename MemFun
, typename P1
>
249 inline wxObjScopeGuardImpl1
<Obj
, MemFun
, P1
>
250 wxMakeObjGuard(Obj
& obj
, MemFun memFun
, P1 p1
)
252 return wxObjScopeGuardImpl1
<Obj
, MemFun
, P1
>::MakeObjGuard(obj
, memFun
, p1
);
255 template <class Obj
, typename MemFun
, typename P1
, typename P2
>
256 class wxObjScopeGuardImpl2
: public wxScopeGuardImplBase
259 static wxObjScopeGuardImpl2
<Obj
, MemFun
, P1
, P2
>
260 MakeObjGuard(Obj
& obj
, MemFun memFun
, P1 p1
, P2 p2
)
262 return wxObjScopeGuardImpl2
<Obj
, MemFun
, P1
, P2
>(obj
, memFun
, p1
, p2
);
265 ~wxObjScopeGuardImpl2() { wxPrivate::OnScopeExit(*this); }
267 void Execute() { (m_obj
.*m_memfun
)(m_p1
, m_p2
); }
270 wxObjScopeGuardImpl2(Obj
& obj
, MemFun memFun
, P1 p1
, P2 p2
)
271 : m_obj(obj
), m_memfun(memFun
), m_p1(p1
), m_p2(p2
) { }
279 template <class Obj
, typename MemFun
, typename P1
, typename P2
>
280 inline wxObjScopeGuardImpl2
<Obj
, MemFun
, P1
, P2
>
281 wxMakeObjGuard(Obj
& obj
, MemFun memFun
, P1 p1
, P2 p2
)
283 return wxObjScopeGuardImpl2
<Obj
, MemFun
, P1
, P2
>::
284 MakeObjGuard(obj
, memFun
, p1
, p2
);
287 // ============================================================================
289 // ============================================================================
291 // wxScopeGuard is just a reference, see the explanation in CUJ article
292 typedef const wxScopeGuardImplBase
& wxScopeGuard
;
294 // when an unnamed scope guard is needed, the macros below may be used
296 // NB: the original code has a single (and much nicer) ON_BLOCK_EXIT macro
297 // but this results in compiler warnings about unused variables and I
298 // didn't find a way to work around this other than by having different
299 // macros with different names
300 #define ON_BLOCK_EXIT0(f) \
301 wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeGuard(f); \
302 wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard))
304 #define ON_BLOCK_EXIT_OBJ0(o, m) \
305 wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeObjGuard(o, m); \
306 wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard))
308 #define ON_BLOCK_EXIT1(f, p1) \
309 wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeGuard(f, p1); \
310 wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard))
312 #define ON_BLOCK_EXIT_OBJ1(o, m, p1) \
313 wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeObjGuard(o, m, p1); \
314 wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard))
316 #define ON_BLOCK_EXIT2(f, p1, p2) \
317 wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeGuard(f, p1, p2); \
318 wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard))
320 #define ON_BLOCK_EXIT_OBJ2(o, m, p1, p2) \
321 wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeObjGuard(o, m, p1, p2); \
322 wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard))
324 #endif // _WX_SCOPEGUARD_H_