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
This commit is contained in:
Vadim Zeitlin 2008-10-09 11:26:50 +00:00
parent d8a16cc8c9
commit bcffb4d1a9
2 changed files with 141 additions and 6 deletions

View File

@ -226,6 +226,41 @@ inline wxScopeGuardImpl2<F, P1, P2> wxMakeGuard(F fun, P1 p1, P2 p2)
return wxScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
}
// ----------------------------------------------------------------------------
// wxScopeGuardImpl3: scope guard for actions with 3 parameters
// ----------------------------------------------------------------------------
template <class F, class P1, class P2, class P3>
class wxScopeGuardImpl3 : public wxScopeGuardImplBase
{
public:
static wxScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
{
return wxScopeGuardImpl3<F, P1, P2, P3>(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 <class F, class P1, class P2, class P3>
inline wxScopeGuardImpl3<F, P1, P2, P3> wxMakeGuard(F fun, P1 p1, P2 p2, P3 p3)
{
return wxScopeGuardImpl3<F, P1, P2, P3>::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 Obj, class MemFun, class P1, class P2, class P3>
class wxObjScopeGuardImpl3 : public wxScopeGuardImplBase
{
public:
static wxObjScopeGuardImpl3<Obj, MemFun, P1, P2, P3>
MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2, P3 p3)
{
return wxObjScopeGuardImpl3<Obj, MemFun, P1, P3>(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 <class Obj, class MemFun, class P1, class P2, class P3>
inline wxObjScopeGuardImpl3<Obj, MemFun, P1, P2, P3>
wxMakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2, P3 p3)
{
return wxObjScopeGuardImpl3<Obj, MemFun, P1, P2, P3>::
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<T> 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) \

View File

@ -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 */
//@{
/**
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:
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 <typename F, typename P1, ..., typename PN>
wxScopeGuard wxMakeGuard(F func, P1 p1, ..., PN pN);
//@}
/** @ingroup group_funcmacro_misc */
//@{
/**
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 */