From bcffb4d1a9edaa539770382e14129ac902da68d8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 9 Oct 2008 11:26:50 +0000 Subject: [PATCH] add 3 parameter scope guard; improve its documentation git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56194 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/scopeguard.h | 84 +++++++++++++++++++++++++++++++++++++++ interface/wx/scopeguard.h | 63 ++++++++++++++++++++++++++--- 2 files changed, 141 insertions(+), 6 deletions(-) diff --git a/include/wx/scopeguard.h b/include/wx/scopeguard.h index 45fe82f5bf..a3a4fffa7e 100644 --- a/include/wx/scopeguard.h +++ b/include/wx/scopeguard.h @@ -226,6 +226,41 @@ inline wxScopeGuardImpl2 wxMakeGuard(F fun, P1 p1, P2 p2) return wxScopeGuardImpl2::MakeGuard(fun, p1, p2); } +// ---------------------------------------------------------------------------- +// wxScopeGuardImpl3: scope guard for actions with 3 parameters +// ---------------------------------------------------------------------------- + +template +class wxScopeGuardImpl3 : public wxScopeGuardImplBase +{ +public: + static wxScopeGuardImpl3 MakeGuard(F fun, P1 p1, P2 p2, P3 p3) + { + return wxScopeGuardImpl3(fun, p1, p2, p3); + } + + ~wxScopeGuardImpl3() { wxPrivateOnScopeExit(*this); } + + void Execute() { m_fun(m_p1, m_p2, m_p3); } + +protected: + wxScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) + : m_fun(fun), m_p1(p1), m_p2(p2), m_p3(p3) { } + + F m_fun; + const P1 m_p1; + const P2 m_p2; + const P3 m_p3; + + wxScopeGuardImpl3& operator=(const wxScopeGuardImpl3&); +}; + +template +inline wxScopeGuardImpl3 wxMakeGuard(F fun, P1 p1, P2 p2, P3 p3) +{ + return wxScopeGuardImpl3::MakeGuard(fun, p1, p2, p3); +} + // ============================================================================ // wxScopeGuards for object methods // ============================================================================ @@ -324,6 +359,39 @@ wxMakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2) MakeObjGuard(obj, memFun, p1, p2); } +template +class wxObjScopeGuardImpl3 : public wxScopeGuardImplBase +{ +public: + static wxObjScopeGuardImpl3 + MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2, P3 p3) + { + return wxObjScopeGuardImpl3(obj, memFun, p1, p2, p3); + } + + ~wxObjScopeGuardImpl3() { wxPrivateOnScopeExit(*this); } + + void Execute() { (m_obj.*m_memfun)(m_p1, m_p2, m_p3); } + +protected: + wxObjScopeGuardImpl3(Obj& obj, MemFun memFun, P1 p1, P2 p2, P3 p3) + : m_obj(obj), m_memfun(memFun), m_p1(p1), m_p2(p2), m_p3(p3) { } + + Obj& m_obj; + MemFun m_memfun; + const P1 m_p1; + const P2 m_p2; + const P3 m_p3; +}; + +template +inline wxObjScopeGuardImpl3 +wxMakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2, P3 p3) +{ + return wxObjScopeGuardImpl3:: + MakeObjGuard(obj, memFun, p1, p2, p3); +} + // ---------------------------------------------------------------------------- // wxVariableSetter: use the same technique as for wxScopeGuard to allow // setting a variable to some value on block exit @@ -465,6 +533,22 @@ wxPrivate::VariableNullerImpl wxMakeVarNuller(T& var) wxON_BLOCK_EXIT_OBJ2(*this, m, p1, p2) +#define wxON_BLOCK_EXIT3_IMPL(n, f, p1, p2, p3) \ + wxScopeGuard n = wxMakeGuard(f, p1, p2, p3); \ + wxPrivateUse(n) +#define wxON_BLOCK_EXIT3(f, p1, p2, p3) \ + wxON_BLOCK_EXIT3_IMPL(wxGuardName, f, p1, p2, p3) + +#define wxON_BLOCK_EXIT_OBJ3_IMPL(n, o, m, p1, p2, p3) \ + wxScopeGuard n = wxMakeObjGuard(o, m, p1, p2, p3); \ + wxPrivateUse(n) +#define wxON_BLOCK_EXIT_OBJ3(o, m, p1, p2, p3) \ + wxON_BLOCK_EXIT_OBJ3_IMPL(wxGuardName, o, &m, p1, p2, p3) + +#define wxON_BLOCK_EXIT_THIS3(m, p1, p2, p3) \ + wxON_BLOCK_EXIT_OBJ3(*this, m, p1, p2, p3) + + #define wxSetterName wxMAKE_UNIQUE_NAME(wxVarSetter) #define wxON_BLOCK_EXIT_SET_IMPL(n, var, value) \ diff --git a/interface/wx/scopeguard.h b/interface/wx/scopeguard.h index e8c88a7989..c0a14ec137 100644 --- a/interface/wx/scopeguard.h +++ b/interface/wx/scopeguard.h @@ -6,13 +6,58 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +/** + Scope guard is an object which allows executing an action on scope exit. + + The objects of this class must be constructed using wxMakeGuard() function. + */ +class wxScopeGuard +{ +public: + /** + Call this method to dismiss the execution of the action on scope exit. + + A typical example: + @code + Update1(); + + // ensure that changes done so far are rolled back if the next + // operation throws + wxScopeGuard guard = wxMakeGuard(RollBack); + Update2(); + + // it didn't throw so commit the changes, i.e. avoid rolling back + guard.Dismiss(); + @endcode + */ + void Dismiss(); +}; + +/** @ingroup group_funcmacro_misc */ +//@{ +/** + Returns a scope guard object which will call the specified function with + the given parameters on scope exit. + + This function is overloaded to take several parameters up to some + implementation-defined (but relatively low) limit. + + The @a func should be a functor taking parameters of the types P1, ..., PN, + i.e. the expression @c func(p1, ..., pN) should be valid. + */ +template +wxScopeGuard wxMakeGuard(F func, P1 p1, ..., PN pN); + +//@} + /** @ingroup group_funcmacro_misc */ //@{ /** - This macro ensures that the global @a function with 0, 1, 2 or more - parameters (up to some implementation-defined limit) is executed on scope - exit, whether due to a normal function return or because an exception has - been thrown. A typical example of its usage: + Ensure that the global @a function with a few (up to some + implementation-defined limit) is executed on scope exit, whether due to a + normal function return or because an exception has been thrown. + + A typical example of its usage: @code void *buf = malloc(size); @@ -26,35 +71,41 @@ @header{wx/scopeguard.h} */ +#define wxON_BLOCK_EXIT(function, ...) #define wxON_BLOCK_EXIT0(function) #define wxON_BLOCK_EXIT1(function, p1) #define wxON_BLOCK_EXIT2(function, p1, p2) +#define wxON_BLOCK_EXIT3(function, p1, p2, p3) //@} /** @ingroup group_funcmacro_misc */ //@{ /** - This family of macros is similar to wxON_BLOCK_EXIT0(), but calls a method + This family of macros is similar to wxON_BLOCK_EXIT(), but calls a method of the given object instead of a free function. @header{wx/scopeguard.h} */ +#define wxON_BLOCK_EXIT_OBJ(object, method, ...) #define wxON_BLOCK_EXIT_OBJ0(object, method) #define wxON_BLOCK_EXIT_OBJ1(object, method, p1) #define wxON_BLOCK_EXIT_OBJ2(object, method, p1, p2) +#define wxON_BLOCK_EXIT_OBJ3(object, method, p1, p2, p3) //@} /** @ingroup group_funcmacro_misc */ //@{ /** - This family of macros is similar to wxON_BLOCK_OBJ0(), but calls a method + This family of macros is similar to wxON_BLOCK_OBJ(), but calls a method of @c this object instead of a method of the specified object. @header{wx/scopeguard.h} */ +#define wxON_BLOCK_EXIT_THIS(method, ...) #define wxON_BLOCK_EXIT_THIS0(method) #define wxON_BLOCK_EXIT_THIS1(method, p1) #define wxON_BLOCK_EXIT_THIS2(method, p1, p2) +#define wxON_BLOCK_EXIT_THIS3(method, p1, p2, p3) //@} /** @ingroup group_funcmacro_misc */ -- 2.45.2