X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c66cca2af072daf7abe63f784038cbd9125ca4bd..c3c62822fdda9d340179dec663a806e905882cc9:/include/wx/scopeguard.h diff --git a/include/wx/scopeguard.h b/include/wx/scopeguard.h index 2b794dc43f..f1f5a8204c 100644 --- a/include/wx/scopeguard.h +++ b/include/wx/scopeguard.h @@ -5,14 +5,15 @@ // Modified by: // Created: 03.07.2003 // RCS-ID: $Id$ -// Copyright: (c) 2003 Vadim Zeitlin +// Copyright: (c) 2003 Vadim Zeitlin // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// /* Acknowledgements: this header is heavily based on (well, almost the exact - copy of) wxScopeGuard.h by Andrei Alexandrescu and Petru Marginean published + copy of) ScopeGuard.h by Andrei Alexandrescu and Petru Marginean published in December 2000 issue of C/C++ Users Journal. + http://www.cuj.com/documents/cujcexp1812alexandr/ */ #ifndef _WX_SCOPEGUARD_H_ @@ -20,42 +21,75 @@ #include "wx/defs.h" +#include "wx/except.h" + // ---------------------------------------------------------------------------- // helpers // ---------------------------------------------------------------------------- +#ifdef __WATCOMC__ + +// WATCOM-FIXME: C++ of Open Watcom 1.3 doesn't like OnScopeExit() created +// through template so it must be workarounded with dedicated inlined macro. +// For compatibility with Watcom compilers wxPrivate::OnScopeExit must be +// replaced with wxPrivateOnScopeExit but in user code (for everyone who +// doesn't care about OW compatibility) wxPrivate::OnScopeExit still works. + +#define wxPrivateOnScopeExit(guard) \ + { \ + if ( !(guard).WasDismissed() ) \ + { \ + wxTRY \ + { \ + (guard).Execute(); \ + } \ + wxCATCH_ALL(;) \ + } \ + } + +#define wxPrivateUse(n) wxUnusedVar(n) + +#else + +#if !defined(__GNUC__) || wxCHECK_GCC_VERSION(2, 95) +// namespace support was first implemented in gcc-2.95, +// so avoid using it for older versions. namespace wxPrivate { +#else +#define wxPrivate +#endif // in the original implementation this was a member template function of // ScopeGuardImplBase but gcc 2.8 which is still used for OS/2 doesn't // support member templates and so we must make it global - template - void OnScopeExit(ScopeGuardImpl& guard) + template + void OnScopeExit(ScopeGuardImpl& guard) { if ( !guard.WasDismissed() ) { // we're called from ScopeGuardImpl dtor and so we must not throw -#if wxUSE_EXCEPTIONS - try -#endif // wxUSE_EXCEPTIONS + wxTRY { guard.Execute(); } -#if wxUSE_EXCEPTIONS - catch ( ... ) - { - } -#endif // wxUSE_EXCEPTIONS + wxCATCH_ALL(;) // do nothing, just eat the exception } } // just to avoid the warning about unused variables - template + template void Use(const T& WXUNUSED(t)) { } +#if !defined(__GNUC__) || wxCHECK_GCC_VERSION(2, 95) } // namespace wxPrivate - +#endif + +#define wxPrivateOnScopeExit(n) wxPrivate::OnScopeExit(n) +#define wxPrivateUse(n) wxPrivate::Use(n) + +#endif + // ============================================================================ // wxScopeGuard for functions and functors // ============================================================================ @@ -69,20 +103,20 @@ class wxScopeGuardImplBase public: wxScopeGuardImplBase() : m_wasDismissed(false) { } + wxScopeGuardImplBase(const wxScopeGuardImplBase& other) + : m_wasDismissed(other.m_wasDismissed) + { + other.Dismiss(); + } + void Dismiss() const { m_wasDismissed = true; } - // for OnScopeExit() only we can't make it friend, unfortunately)! + // for OnScopeExit() only (we can't make it friend, unfortunately)! bool WasDismissed() const { return m_wasDismissed; } protected: ~wxScopeGuardImplBase() { } - wxScopeGuardImplBase(const wxScopeGuardImplBase& other) - : m_wasDismissed(other.m_wasDismissed) - { - other.Dismiss(); - } - // must be mutable for copy ctor to work mutable bool m_wasDismissed; @@ -94,7 +128,7 @@ private: // wxScopeGuardImpl0: scope guard for actions without parameters // ---------------------------------------------------------------------------- -template +template class wxScopeGuardImpl0 : public wxScopeGuardImplBase { public: @@ -103,7 +137,7 @@ public: return wxScopeGuardImpl0(fun); } - ~wxScopeGuardImpl0() { wxPrivate::OnScopeExit(*this); } + ~wxScopeGuardImpl0() { wxPrivateOnScopeExit(*this); } void Execute() { m_fun(); } @@ -115,7 +149,7 @@ protected: wxScopeGuardImpl0& operator=(const wxScopeGuardImpl0&); }; -template +template inline wxScopeGuardImpl0 wxMakeGuard(F fun) { return wxScopeGuardImpl0::MakeGuard(fun); @@ -125,7 +159,7 @@ inline wxScopeGuardImpl0 wxMakeGuard(F fun) // wxScopeGuardImpl1: scope guard for actions with 1 parameter // ---------------------------------------------------------------------------- -template +template class wxScopeGuardImpl1 : public wxScopeGuardImplBase { public: @@ -134,7 +168,7 @@ public: return wxScopeGuardImpl1(fun, p1); } - ~wxScopeGuardImpl1() { wxPrivate::OnScopeExit(*this); } + ~wxScopeGuardImpl1() { wxPrivateOnScopeExit(* this); } void Execute() { m_fun(m_p1); } @@ -147,7 +181,7 @@ protected: wxScopeGuardImpl1& operator=(const wxScopeGuardImpl1&); }; -template +template inline wxScopeGuardImpl1 wxMakeGuard(F fun, P1 p1) { return wxScopeGuardImpl1::MakeGuard(fun, p1); @@ -157,7 +191,7 @@ inline wxScopeGuardImpl1 wxMakeGuard(F fun, P1 p1) // wxScopeGuardImpl2: scope guard for actions with 2 parameters // ---------------------------------------------------------------------------- -template +template class wxScopeGuardImpl2 : public wxScopeGuardImplBase { public: @@ -166,7 +200,7 @@ public: return wxScopeGuardImpl2(fun, p1, p2); } - ~wxScopeGuardImpl2() { wxPrivate::OnScopeExit(*this); } + ~wxScopeGuardImpl2() { wxPrivateOnScopeExit(*this); } void Execute() { m_fun(m_p1, m_p2); } @@ -180,7 +214,7 @@ protected: wxScopeGuardImpl2& operator=(const wxScopeGuardImpl2&); }; -template +template inline wxScopeGuardImpl2 wxMakeGuard(F fun, P1 p1, P2 p2) { return wxScopeGuardImpl2::MakeGuard(fun, p1, p2); @@ -194,7 +228,7 @@ inline wxScopeGuardImpl2 wxMakeGuard(F fun, P1 p1, P2 p2) // wxObjScopeGuardImpl0 // ---------------------------------------------------------------------------- -template +template class wxObjScopeGuardImpl0 : public wxScopeGuardImplBase { public: @@ -204,7 +238,7 @@ public: return wxObjScopeGuardImpl0(obj, memFun); } - ~wxObjScopeGuardImpl0() { wxPrivate::OnScopeExit(*this); } + ~wxObjScopeGuardImpl0() { wxPrivateOnScopeExit(*this); } void Execute() { (m_obj.*m_memfun)(); } @@ -216,13 +250,13 @@ protected: MemFun m_memfun; }; -template +template inline wxObjScopeGuardImpl0 wxMakeObjGuard(Obj& obj, MemFun memFun) { return wxObjScopeGuardImpl0::MakeObjGuard(obj, memFun); } -template +template class wxObjScopeGuardImpl1 : public wxScopeGuardImplBase { public: @@ -232,12 +266,12 @@ public: return wxObjScopeGuardImpl1(obj, memFun, p1); } - ~wxObjScopeGuardImpl1() { wxPrivate::OnScopeExit(*this); } + ~wxObjScopeGuardImpl1() { wxPrivateOnScopeExit(*this); } void Execute() { (m_obj.*m_memfun)(m_p1); } protected: - wxObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) + wxObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : m_obj(obj), m_memfun(memFun), m_p1(p1) { } Obj& m_obj; @@ -245,14 +279,14 @@ protected: const P1 m_p1; }; -template +template inline wxObjScopeGuardImpl1 wxMakeObjGuard(Obj& obj, MemFun memFun, P1 p1) { return wxObjScopeGuardImpl1::MakeObjGuard(obj, memFun, p1); } -template +template class wxObjScopeGuardImpl2 : public wxScopeGuardImplBase { public: @@ -262,12 +296,12 @@ public: return wxObjScopeGuardImpl2(obj, memFun, p1, p2); } - ~wxObjScopeGuardImpl2() { wxPrivate::OnScopeExit(*this); } + ~wxObjScopeGuardImpl2() { wxPrivateOnScopeExit(*this); } void Execute() { (m_obj.*m_memfun)(m_p1, m_p2); } protected: - wxObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) + wxObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : m_obj(obj), m_memfun(memFun), m_p1(p1), m_p2(p2) { } Obj& m_obj; @@ -276,7 +310,7 @@ protected: const P2 m_p2; }; -template +template inline wxObjScopeGuardImpl2 wxMakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2) { @@ -297,29 +331,43 @@ typedef const wxScopeGuardImplBase& wxScopeGuard; // but this results in compiler warnings about unused variables and I // didn't find a way to work around this other than by having different // macros with different names -#define ON_BLOCK_EXIT0(f) \ - wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeGuard(f); \ - wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard)) - -#define ON_BLOCK_EXIT_OBJ0(o, m) \ - wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeObjGuard(o, m); \ - wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard)) - -#define ON_BLOCK_EXIT1(f, p1) \ - wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeGuard(f, p1); \ - wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard)) -#define ON_BLOCK_EXIT_OBJ1(o, m, p1) \ - wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeObjGuard(o, m, p1); \ - wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard)) - -#define ON_BLOCK_EXIT2(f, p1, p2) \ - wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeGuard(f, p1, p2); \ - wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard)) - -#define ON_BLOCK_EXIT_OBJ2(o, m, p1, p2) \ - wxScopeGuard wxMAKE_UNIQUE_NAME(scopeGuard) = wxMakeObjGuard(o, m, p1, p2); \ - wxPrivate::Use(wxMAKE_UNIQUE_NAME(scopeGuard)) +#define wxGuardName wxMAKE_UNIQUE_NAME(scopeGuard) + +#define wxON_BLOCK_EXIT0_IMPL(n, f) \ + wxScopeGuard n = wxMakeGuard(f); \ + wxPrivateUse(n) +#define wxON_BLOCK_EXIT0(f) \ + wxON_BLOCK_EXIT0_IMPL(wxGuardName, f) + +#define wxON_BLOCK_EXIT_OBJ0_IMPL(n, o, m) \ + wxScopeGuard n = wxMakeObjGuard(o, m); \ + wxPrivateUse(n) +#define wxON_BLOCK_EXIT_OBJ0(o, m) \ + wxON_BLOCK_EXIT_OBJ0_IMPL(wxGuardName, o, &m) + +#define wxON_BLOCK_EXIT1_IMPL(n, f, p1) \ + wxScopeGuard n = wxMakeGuard(f, p1); \ + wxPrivateUse(n) +#define wxON_BLOCK_EXIT1(f, p1) \ + wxON_BLOCK_EXIT1_IMPL(wxGuardName, f, p1) + +#define wxON_BLOCK_EXIT_OBJ1_IMPL(n, o, m, p1) \ + wxScopeGuard n = wxMakeObjGuard(o, m, p1); \ + wxPrivateUse(n) +#define wxON_BLOCK_EXIT_OBJ1(o, m, p1) \ + wxON_BLOCK_EXIT_OBJ1_IMPL(wxGuardName, o, &m, p1) + +#define wxON_BLOCK_EXIT2_IMPL(n, f, p1, p2) \ + wxScopeGuard n = wxMakeGuard(f, p1, p2); \ + wxPrivateUse(n) +#define wxON_BLOCK_EXIT2(f, p1, p2) \ + wxON_BLOCK_EXIT2_IMPL(wxGuardName, f, p1, p2) + +#define wxON_BLOCK_EXIT_OBJ2_IMPL(n, o, m, p1, p2) \ + wxScopeGuard n = wxMakeObjGuard(o, m, p1, p2); \ + wxPrivateUse(n) +#define wxON_BLOCK_EXIT_OBJ2(o, m, p1, p2) \ + wxON_BLOCK_EXIT_OBJ2_IMPL(wxGuardName, o, &m, p1, p2) #endif // _WX_SCOPEGUARD_H_ -