javauis/m2g_akn/inc/JcfAutoPtr.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 27 Apr 2010 16:30:29 +0300
branchRCL_3
changeset 19 04becd199f91
permissions -rw-r--r--
Revision: v2.1.22 Kit: 201017

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/

#ifndef JCFAUTOPTR_H
#define JCFAUTOPTR_H

#include <e32base.h>

/**
 * Functionality of this auto ptr class is same as stl's auto_ptr class
 * except this works with cleanup stack.
 * Implementation of the example operation with "traditional" way:
 * void bar()
 *   {
 *   CFoo* myFoo = CFoo::NewL();
 *   CleanupStack::PushL(myFoo);
 *   myFoo->DoSomeThingL();
 *   CleanupStack::PopAndDestroy(1); //myFoo
 *   }
 * Implementation of the same function with auto pointer class:
 * void bar()
 *   {
 *   jcfcommon::auto_ptr<CFoo> myFoo(CFoo::NewL());
 *   myFoo->DoSomeThingL();
 *   }
 *
 */
namespace jcfcommon
{

template<class X> class auto_ptr
{
public:
    typedef X element_type;

    auto_ptr(X* aPtr = 0): iPtr(aPtr),iCloseCalledFlag(EFalse)
    {
        CleanupStack::PushL(TCleanupItem(Close, (void*)this));
    }

    /**
     * Copy constructor was commented out because current
     * implementation doesn't support situation where auto_ptr
     * is returned as return value of the function. Problem is that
     * orig. auto_ptr is deleted when getBar() operation has been
     * executed and this deleted local reference has been stored to the
     * cleanup stack.
     * E.g:
     * void foo()
     *   {
     *   auto_ptr<bar> barObj = getBar();
     *       .
     *       .
     *       .
     *   User::Leave(KErrNotFound);
     *   }
     */
    /*auto_ptr(auto_ptr& aPtr): iPtr(aPtr.release())
    {
      CleanupStack::PushL(TCleanupItem(Close, (void*)this));
    }*/

    auto_ptr<X>& operator=(auto_ptr<X>& aRhs)
    {
        if (&aRhs != this)
        {
            delete iPtr;
            iPtr = aRhs.release();
        }
        return (*this);
    }

    ~auto_ptr()
    {
        if (!iCloseCalledFlag)
        {
            CleanupStack::Pop();
            delete iPtr;
        }
    }

    X& operator *() const
    {
        return *iPtr;
    }
    X* operator ->() const
    {
        return iPtr;
    }

    X* get() const
    {
        return iPtr;
    }

    X* release()
    {
        X* result = iPtr;
        iPtr = 0;
        return result;
    }

    void reset(X* aPtr = 0)
    {
        if (aPtr != iPtr)
        {
            delete iPtr;
            iPtr = aPtr;
        }
    }

private:
    static void Close(void* aPtr)
    {
        auto_ptr<X>* self = (auto_ptr<X>*)aPtr;
        delete self->iPtr;
        self->iPtr = 0;
        self->iCloseCalledFlag = ETrue;
    }

    //Not implemented.
    auto_ptr(auto_ptr& aPtr);

private:
    X* iPtr;
    TBool iCloseCalledFlag;
};

}//end jcfcommon

#endif // JCFAUTOPTR_H