]> git.saurik.com Git - wxWidgets.git/commitdiff
add 3 parameter scope guard; improve its documentation
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 9 Oct 2008 11:26:50 +0000 (11:26 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 9 Oct 2008 11:26:50 +0000 (11:26 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56194 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/scopeguard.h
interface/wx/scopeguard.h

index 45fe82f5bf5d21adcc8a695a5cded0f3eb245f6d..a3a4fffa7e2ed3902a0dd6466b450e5d9b969eab 100644 (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) \
index e8c88a7989e95af1c31467fe034632de83a26742..c0a14ec1374194c1041d1cce4435f92226b2d07c 100644 (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 */
+//@{
+/**
+    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 */
 //@{
 /**
-    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);
 
     @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 */