Tuesday, December 3, 2013

C++ Exception Finally stand in

C++ has no equivalent of "finally" in the exception handling construct. So I wrote a class named Finally which can be used instead as "finally" in other languages. This only works in C++11 because this makes use of lambda.
#include <functional>
#include <array>
#include <assert.h>

template< std::size_t N >
class Finally
{
public:
    Finally() : m_uCount(0) {}

    typedef std::function<void()> deleter_type ;
    void operator += ( const deleter_type&& a_deleter )
    {
        assert( m_uCount < N ) ;
        if( m_uCount >= N ) return ;
        m_deleters[m_uCount++] = a_deleter ;
    }

    ~Finally()
    {
        for( int i=int(m_uCount)-1 ; i>=0 ; --i )
        {
            m_deleters[i]() ;
        }
    }

private:
    std::array<deleter_type,N> m_deleters ;
    size_t m_uCount ;

    Finally( const Finally& ) /* = delete */ ;
    Finally( Finally&& )  /* = delete */ ;
    void operator=( const Finally& ) /* & = delete */ ;
    void operator=( Finally&& ) /* & = delete */ ;
};
Following is a code snippet which my Finally class is applied to.
#include <stdlib.h>
#include "Finally.h"

void Test( int a_iException )
{
    Finally<3> finally ;
    FILE* pFile = ::fopen( "Test", "w" ) ;
    finally += [ pFile ]
    {
        if( NULL != pFile )
            ::fclose( pFile ) ;
    } ;

    try
    {
        if( 2 == a_iException )
            throw 2 ;
    }
    catch( std::logic_error& e )
    {
         throw ;
    }
}

int main()
{
    try
    {
        Test( 1 ) ;
        Test( 2 ) ;
    }
    catch( int iExc )
    {
        assert( 2 == iExc ) ;
    }
    return 0 ;
}