NoesisGUI

ScopeGuard

ScopeGuard is a useful mechanism to automatically invoke an "undo" operation of your choosing when it goes out of scope. As a RAII mechanism it can very handy to "rollback" to a previous state when an exception is thrown. Due to its simplicity it can be used in more scenarios, not only when exceptions can appear.

Usage

Basically, when you want to register an action that may need "rolling back" you create a ScopeGuard instance with the function in charge of the undo operation and all the needed parameter. ScopeGuard supports all type of functors: free functions and member functions. Whenever you arrive to a safe state that does not need the "undo" operation you invoke the Dismiss() method of ScopeGuard. This operation disables the "undo" operation.

class Manager
{
public:
    Manager()
    {
        mFile = File::Open("info.dat", "rb");
        ScopeGuard guard = MakeGuard(&File::Close, mFile);

        // This operation may raise an exception. If an exception is generated the scopeguard
        // will close the opened file handle
        ReadDatabase(fp);

        // Ok, we are now in a safe state. We do not need closing the handle because it is needed
        // by this instance
        guard.Dismiss();
    }

private:
    FILE* mFile;
};

When the Dismiss() operation is nos needed, that is, when you need the undo operation to be executed always, you can use the macro NS_ON_SCOPE_EXIT that simplifies the Scope guard usage.

void RegisterDirectory(const NsChar* directory)
{
    UINT errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
    NS_ON_SCOPE_EXIT(&SetErrorMode, errorMode);

    ///
    /// Rest of the function
    ///

    /// When leaving this function the ScopeGuard mechanism will restore the initial ErrorMode
}

Additional documentation

ScopeGuard implementation is based on the work by Andrei Alexandrescu and Petru Marginean.

© 2017 Noesis Technologies