diff -r 000000000000 -r e4d67989cc36 lowlevellibsandfws/genericusabilitylib/inc/emanaged.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lowlevellibsandfws/genericusabilitylib/inc/emanaged.h Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,3207 @@ +// Copyright (c) 2008-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 EMANAGED_H +#define EMANAGED_H + +#include + +#include +#include + + + + +/** + @file + @brief Utility class templates that provide RAII-based automatic + resource management. + + @publishedAll + @released +*/ + + + /** + Implementation function.In order to override the default cleanup + strategy for a particular type, use the provided + DEFINE_CLEANUP_FUNCTION utility macro + @internalComponent + */ +// Not for Client Use , Only to be used Internally. +template +inline void CallCleanupFunction(T* aObjPtr) + { + aObjPtr->Close(); + } + + +/** +Utility macro that can be used for defining the cleanup member +function for a class (typically a R-class). + +This macro can be used in the same namespace in which the R-class is +defined or in a namespace in which the R-class is used. + +Example: + +class RDestroyableClass + { + public: + // ... + void Destroy(); // member function used for cleanup and releasing the resources owned by a RDestroyableClass object + // ... + }; + +DEFINE_CLEANUP_FUNCTION(RDestroyableClass, Destroy) + +@param AClass the name of the class +@param CleanupMemFun the name of the cleanup member function of the class + */ +#define DEFINE_CLEANUP_FUNCTION(AClass, CleanupMemFun) \ + inline void CallCleanupFunction(AClass* aObjPtr) \ + { \ + aObjPtr->CleanupMemFun(); \ + } + +/** +Utility macro that can be used for specializing the default cleanup +strategy class template TResourceCleanupStrategy for a particular +class (typically a R-class). The default cleanup strategy for a class +specified using DEFINE_CLEANUP_STRATEGY overrides any other cleanup +strategy specified using DEFINE_CLEANUP_FUNCTION for that class. + +This macro must be used in the same namespace in which the R-class is +defined. + + + Utility macro that can be used for enabling single phase + construction for CBase-derived classes. This is necessary because + Symbian OS currently lacks the placement delete operator + counterparts corresponding to the placement new operators that take + a TLeave parameter (new(ELeave)), which will result in memory leaks + if a class constructor leaves. + + This macro must be used within a public section of a class + definition, if the single phase construction is part of the public + interface of the class. + + Current Limitation CONSTRUCTORS_MAY_LEAVE is an unfortunate blight on the + usability of single-phase construction, but we have yet to come up + with a better alternative in the face of the legacy handling of + ELeave. +*/ +#define CONSTRUCTORS_MAY_LEAVE \ + static void operator delete(TAny* aPtr) __NO_THROW \ + { \ + ::operator delete(aPtr); \ + } \ + \ + static void operator delete(TAny*, TAny*) __NO_THROW \ + { \ + } \ + \ + static void operator delete(TAny* aPtr, TLeave) __NO_THROW \ + { \ + ::operator delete(aPtr); \ + } \ + \ + static void operator delete(TAny* aPtr, TUint) __NO_THROW \ + { \ + ::operator delete(aPtr); \ + } \ + \ + static void operator delete(TAny* aPtr, TLeave, TUint) __NO_THROW \ + { \ + ::operator delete(aPtr); \ + } \ + \ + static void operator delete[](TAny* aPtr) __NO_THROW \ + { \ + ::operator delete[](aPtr); \ + } \ + \ + static void operator delete[](TAny* aPtr, TLeave) __NO_THROW \ + { \ + ::operator delete[](aPtr); \ + } + + +// Implementation function. +template +void ManagedPopCleanupStackItem(T aIsManaged) + { +// CleanupStack-based cleanup is automatically triggered by a Leave, +// so, in the case when __LEAVE_EQUALS_THROW__, +// CleanupStack::PopAndDestroy must not be called again here +#ifndef __GCCXML__ +// for gccxml builds the std::uncaught_exception function is not listed in std name space +// to supress GCCXML error + if (!std::uncaught_exception()) + { + if (aIsManaged) + { + CleanupStack::PopAndDestroy(); + } + else + { + CleanupStack::Pop(); + } + } +#endif + } + +/** + Strategy (policy) class that defines the default cleanup strategy + for managed resource class objects. + + The default cleanup strategy is to call the cleanup member function + of the managed class, which is the Close() member function of the + managed class, unless explicitly defined otherwise, for example by + using the provided DEFINE_CLEANUP_FUNCTION macro. + + @internalComponent +*/ +// Not for Client Use , Only to be used Internally. +class TResourceCleanupStrategy + { + public: + template + static void Cleanup(T* aObjPtr) + { + CallCleanupFunction(aObjPtr); + } + }; + +/** + Strategy (policy) class that defines a cleanup strategy for managed + resource class objects. This cleanup strategy calls the Close() + member function of the managed class. + + @see LCleanedupHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TClose + { + public: + template + static void Cleanup(T* aObjPtr) + { + aObjPtr->Close(); + } + }; + +/** + Strategy (policy) class that defines a cleanup strategy for managed + resource class objects. This cleanup strategy calls the Release() + member function of the managed class. + + @see LCleanedupHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TRelease + { + public: + template + static void Cleanup(T* aObjPtr) + { + aObjPtr->Release(); + } + }; + +/** + Strategy (policy) class that defines a cleanup strategy for managed + resource class objects. This cleanup strategy calls the Destroy() + member function of the managed class. + + @see LCleanedupHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TDestroy + { + public: + template + static void Cleanup(T* aObjPtr) + { + aObjPtr->Destroy(); + } + }; + +/** + Strategy (policy) class that defines a cleanup strategy for managed + resource class objects. This cleanup strategy calls the Free() + member function of the managed class. + + @see LCleanedupHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TFree + { + public: + template + static void Cleanup(T* aObjPtr) + { + aObjPtr->Free(); + } + }; + +/** + Strategy (policy) class that defines a cleanup strategy for managed + resource class objects. This cleanup strategy calls the + ResetAndDestroy() member function of the managed class. + + @see LCleanedupHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedHandle to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TResetAndDestroy + { + public: + template + static void Cleanup(T* aObjPtr) + { + aObjPtr->ResetAndDestroy(); + } + }; + + +/** + Strategy (policy) class that defines the default cleanup strategy + for pointer types. For pointers to CBase-derived types, the + default cleanup strategy is to call CBase::Delete with the managed + pointer. For pointers to types that are not derived from CBase, + the default cleanup strategy is to delete the managed pointer using + non-array delete. + + @see LCleanedupPtr to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedPtr to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TPtrCleanupStrategy + { + public: + template + static void Cleanup(T* aPtr) + { + delete aPtr; + } + + static void Cleanup(CBase* aPtr) + { + CBase::Delete(aPtr); + } + }; + + +/** + Strategy (policy) class that defines a cleanup strategy for pointer + types. This cleanup strategy deletes the managed pointer by using + non-array delete. + + @see LCleanedupPtr to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedPtr to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TPointerDeleteStrategy + { + public: + template + static void Cleanup(T* aPtr) + { + delete aPtr; + } + }; + + +/** + Strategy (policy) class that defines a cleanup strategy for + pointers to CBase-derived types. This cleanup strategy calls + CBase::Delete with the managed pointer. + + @see LCleanedupPtr to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedPtr to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TCBaseDeleteStrategy + { + public: + static void Cleanup(CBase* aPtr) + { + CBase::Delete(aPtr); + } + }; + + +/** + Strategy (policy) class that defines a cleanup strategy for pointer + types. This cleanup strategy calls User::Free with the managed + pointer. + + @see LCleanedupPtr to which this strategy type may be supplied as + an (optional) second tamplate parameter + @see LManagedPtr to which this strategy type may be supplied as + an (optional) second tamplate parameter +*/ +class TPointerFree + { + public: + static void Cleanup(TAny* aPtr) + { + User::Free(aPtr); + } + }; + + +/** + Strategy (policy) class that defines the default cleanup strategy + for heap-allocated arrays. This cleanup strategy deallocates the + managed array by using array delete. +*/ +class TArrayDelete + { + public: + template + static void Cleanup(T* aPtr) + { + delete[] aPtr; + } + }; + + +// enum type used for identifying the categories of managed pointer types +enum TManagedPtrType +{ + EPtrNonSpecial, + EPtrCBaseDerived +}; + + +// macro used for determining whether a pointer is special +#define IS_PTR_SPECIAL(T) IS_BASE_OF(CBase, T) + + +// enum type used for identifying the categories of resource handle types +enum TAutoHandleType +{ + EAutoHandleNonSpecial, + EAutoRHandleBaseDerived, + EAutoHandleRBuf +}; + + +// macro used for determining whether a resource handle type is special +#define IS_HANDLE_SPECIAL(T) IS_BASE_OF(RHandleBase, T) ? EAutoRHandleBaseDerived : ( (IS_SAME(RBuf8, T) || IS_SAME(RBuf16, T)) ? EAutoHandleRBuf : EAutoHandleNonSpecial ) + + +/** + Implementation base class - not designed for public inheritance or + direct use. + + @internalComponent +*/ +// Not for Client Use , Only to be used Internally. +template +class LAutoHandleBase + { + protected: + LAutoHandleBase() + : iEnabled(ETrue) + { + } + + template + explicit LAutoHandleBase(const Param1& aParam1) + : iHandle(aParam1), + iEnabled(ETrue) + { + } + + template + explicit LAutoHandleBase(Param1& aParam1) + : iHandle(aParam1), + iEnabled(ETrue) + { + } + + template + LAutoHandleBase(const Param1& aParam1, + const Param2& aParam2) + : iHandle(aParam1, + aParam2), + iEnabled(ETrue) + { + } + + template + LAutoHandleBase(Param1& aParam1, + const Param2& aParam2) + : iHandle(aParam1, + aParam2), + iEnabled(ETrue) + { + } + + template + LAutoHandleBase(const Param1& aParam1, + Param2& aParam2) + : iHandle(aParam1, + aParam2), + iEnabled(ETrue) + { + } + + template + LAutoHandleBase(Param1& aParam1, + Param2& aParam2) + : iHandle(aParam1, + aParam2), + iEnabled(ETrue) + { + } + + template + LAutoHandleBase& operator=(const U& aHandle) + { + iHandle = aHandle; + iEnabled = ETrue; + return *this; + } + + T& Get() + { + return iHandle; + } + + const T& Get() const + { + return iHandle; + } + + T& operator*() + { + return iHandle; + } + + const T& operator*() const + { + return iHandle; + } + + T* operator->() + { + return &iHandle; + } + + const T* operator->() const + { + return &iHandle; + } + + T Unmanage() + { + iEnabled = EFalse; + return iHandle; + } + + TBool IsEnabled() const + { + return iEnabled; + } + + void Disable() + { + iEnabled = EFalse; + } + + void Swap(LAutoHandleBase& aAutoHandle) + { + ::Swap(iHandle, aAutoHandle.iHandle); + ::Swap(iEnabled, aAutoHandle.iEnabled); + } + + protected: + T iHandle; + TBool iEnabled; + + private: + LAutoHandleBase(const LAutoHandleBase&); + LAutoHandleBase& operator=(const LAutoHandleBase&); + }; + + +/** + Implementation base class - not designed for public inheritance or + direct use. Specialization for types derived from RHandleBase. +*/ +template +class LAutoHandleBase + { + protected: + LAutoHandleBase() + { + } + + template + explicit LAutoHandleBase(const Param1& aParam1) + : iHandle(aParam1) + { + } + + template + explicit LAutoHandleBase(Param1& aParam1) + : iHandle(aParam1) + { + } + + template + LAutoHandleBase(const Param1& aParam1, + const Param2& aParam2) + : iHandle(aParam1, + aParam2) + { + } + + template + LAutoHandleBase(Param1& aParam1, + const Param2& aParam2) + : iHandle(aParam1, + aParam2) + { + } + + template + LAutoHandleBase(const Param1& aParam1, + Param2& aParam2) + : iHandle(aParam1, + aParam2) + { + } + + template + LAutoHandleBase(Param1& aParam1, + Param2& aParam2) + : iHandle(aParam1, + aParam2) + { + } + + template + LAutoHandleBase& operator=(const U& aHandle) + { + iHandle = aHandle; + return *this; + } + + T& Get() + { + return iHandle; + } + + const T& Get() const + { + return iHandle; + } + + T& operator*() + { + return iHandle; + } + + const T& operator*() const + { + return iHandle; + } + + T* operator->() + { + return &iHandle; + } + + const T* operator->() const + { + return &iHandle; + } + + T Unmanage() + { + T handle = iHandle; + iHandle.SetHandle(KNullHandle); + return handle; + } + + TBool IsEnabled() const + { + return iHandle.Handle() != KNullHandle; + } + + void Disable() + { + iHandle.SetHandle(KNullHandle); + } + + void Swap(LAutoHandleBase& aAutoHandle) + { + ::Swap(iHandle, aAutoHandle.iHandle); + } + + protected: + T iHandle; + + private: + LAutoHandleBase(const LAutoHandleBase&); + LAutoHandleBase& operator=(const LAutoHandleBase&); + }; + + +// N.B. RBuf8, RBuf16 and RBuf cannot be used with LManagedHandle and +// LCleanedupHandle. Use LString or managed references instead. +// The following specialization must not be used. +template +class LAutoHandleBase: protected T + { + private: + LAutoHandleBase() + { + } + + ~LAutoHandleBase() + { + } + }; + + +/** + A class template for the creation and automatic management of + resource handles (typically R-class instances) held in the data + members of objects. + + @note This class should not used to define locals. See below for + an explanation and links to management classes suitable for use in + that context. + + This class template can be used to protect a resource handle of + type T (typically an R-class instance) such that the instance of T + protected is automatically cleaned up when the management object is + destroyed; typically when the object containing it is deleted. + + By default, the cleanup action is to call the Close() member + function of the managed handle. An alternative cleanup strategy may + be selected by specifying a cleanup strategy template class in the + optional second template parameter position. The most common + alternative cleanup strategies are predefined. It is also possible + to specialize the default cleanup action for a given class using + the DEFINE_CLEANUP_FUNCTION macro. + + The constructors of this class never leave (unless construction of + the underlying T instance can leave, which is rare), so data + members defined with this type may be initialized safely during any + phase of construction of the owning class. + + Any arguments supplied when initializing an instance of this class + are automatically passed through to T's constructors. + + As a convenience, the methods of the managed pointer may be + accessed via "->" notation directly on the management object, while + "." notation is used to access the interface of the management + object itself. Using "*" to dereference the management object + yields a T&, and is often useful when passing the managed object as + an argument. + + Automatic cleanup may be disabled at any time by calling + Unmanage(), while cleanup may be forced at any time by calling + ReleaseResource(). + + Example: + @code + class CComposite : public CBase + { + public: + CONSTRUCTORS_MAY_LEAVE + + CComposite() + { + iFileServ->Connect() OR_LEAVE; + iFile->Open(*iFileServ, ...); + } + + ~CComposite() + { + // the handles are automatically closed + } + + private: + + LManagedHandle iFileServ; + LManagedHandle iFile; + }; + @endcode + + Behind the scenes, this class template simply relies on reliable + execution of its destructor. If used for a local variable rather + than a data member, cleanup will occur but out-of-order compared to + objects protected using the LCleanupXxx variants or the + CleanupStack directly. Therefore it is not recommended for use in + that context. + + These management classes may be used as the basis for implementing + leave-safe single-phase construction, since fully initialized + data members protected in this way will get destroyed (so reliably + triggering cleanup) if their containing classes leave during + execution of their constructors. Note, however, that single-phase + construction must be explicitly enabled in the containing class + using the CONSTRUCTORS_MAY_LEAVE macro. + + This class template together with the cleanup strategy class + templates provide a template-based implementation of the Strategy + design pattern (See also: Policy-based design). + + @see TClose which implements the default Close() calling cleanup strategy + @see TResetAndDestroy which implements an alternative + ResetAndDestroy() calling cleanup strategy + @see TFree which implements an alternative Free() calling cleanup + strategy + @see TDestroy which implements an alternative Destroy() calling + cleanup strategy + @see TRelease which implements an alternative Release() calling cleanup strategy + @see LCleanedupHandle which has the same interface, but uses the cleanup + stack and is suitable for protecting locals + @see CONSTRUCTORS_MAY_LEAVE +*/ +template +class LManagedHandle: protected LAutoHandleBase + { + typedef LAutoHandleBase LAutoHandleBase; + + public: + typedef T ManagedType; + typedef CleanupStrategyType CleanupStrategy; + +/** + Default constructor. +*/ + LManagedHandle() + { + } + + template + explicit LManagedHandle(const Param1& aParam1) + : LAutoHandleBase(aParam1) + { + } + + template + explicit LManagedHandle(Param1& aParam1) + : LAutoHandleBase(aParam1) + { + } + + template + LManagedHandle(const Param1& aParam1, + const Param2& aParam2) + : LAutoHandleBase(aParam1, + aParam2) + { + } + + template + LManagedHandle(const Param1& aParam1, + Param2& aParam2) + : LAutoHandleBase(aParam1, + aParam2) + { + } + + template + LManagedHandle(Param1& aParam1, + const Param2& aParam2) + : LAutoHandleBase(aParam1, + aParam2) + { + } + + template + LManagedHandle(Param1& aParam1, + Param2& aParam2) + : LAutoHandleBase(aParam1, + aParam2) + { + } + +/** + Assigns a new resource to be managed. If the LManagedHandle object + already contains a managed resource handle, then the managed + resource is released using the specified cleanup strategy before + assigning the new managed resource. + + @param aHandle a reference to a handle object of a type that can be assigned to a handle object of type T + */ + template + LManagedHandle& operator=(const U& aHandle) + { + ReleaseResource(); + LAutoHandleBase::operator=(aHandle); + return *this; + } + +/** + Destructor. When automatic resource management is enabled, the + destructor calls the cleanup function defined by the cleanup + strategy with the contained resource handle object. + */ + ~LManagedHandle() + { + if (IsEnabled()) + { + CleanupStrategy::Cleanup(&Get()); + } + } + +/** + If automatic resource management is enabled, calls the cleanup + function defined by the cleanup strategy with the managed resource + handle object and then disables the automatic resource management + for this object. The cleanup strategy is specified by the + CleanupStrategy template template parameter. The default cleanup + strategy is to call the cleanup member function on the contained + resource handle object. which is a member function named Close(), + unless explicitly defined otherwise for the class of the object, + for example by using the provided DEFINE_CLEANUP_FUNCTION macro. +*/ + void ReleaseResource() + { + if (!IsEnabled()) + return; + + CleanupStrategy::Cleanup(&Get()); + LAutoHandleBase::Disable(); + } + +/** + Disables the automatic resource management for this object and + returns a copy of the resource handle. + + @return A copy of the resource handle. +*/ + using LAutoHandleBase::Unmanage; + +/** + Returns ETrue if automatic resource management is enabled; EFalse + otherwise. + + @return ETrue if automatic resource management is enabled; EFalse + otherwise. +*/ + using LAutoHandleBase::IsEnabled; + +/** + Returns a reference to the resource handle. + + @return A reference to the resource handle. +*/ + using LAutoHandleBase::Get; + +/** + Overloaded indirection operator function. + + @return A reference to the resource handle. +*/ + using LAutoHandleBase::operator*; + +/** + Overloaded class member access operator function. + + @return A pointer to the resource handle. +*/ + using LAutoHandleBase::operator->; + + using LAutoHandleBase::Disable; + + void Swap(LManagedHandle& aManagedHandle) + { + LAutoHandleBase::Swap(aManagedHandle); + } + }; + + +/** + Implementation base class - not designed for public inheritance or + direct use. + + @internalComponent +*/ +// Not for Client Use , Only to be used Internally. +template +class LAutoPtrBase + { + protected: + LAutoPtrBase() + : iPtr(NULL) + { + } + + explicit LAutoPtrBase(T* aPtr) + : iPtr(aPtr) + { + } + + LAutoPtrBase& operator=(T* aPtr) + { + iPtr = aPtr; + return *this; + } + + T* Unmanage() + { + T* ptr = iPtr; + iPtr = NULL; + return ptr; + } + + TBool IsEnabled() const + { + return iPtr != NULL; + } + + T* Get() const + { + return iPtr; + } + + T* operator->() const + { + return iPtr; + } + + void Disable() + { + iPtr = NULL; + } + + void Swap(LAutoPtrBase& aAutoPtr) + { + ::Swap(iPtr, aAutoPtr.iPtr); + } + + protected: + T* iPtr; + + private: + LAutoPtrBase(const LAutoPtrBase&); + LAutoPtrBase& operator=(const LAutoPtrBase&); + }; + + +// Cleanup traits class template +template +struct TPtrCleanupTraits + { + }; + + +// Cleanup traits class template specialization for pointers to types +// that are not derived from CBase +template +struct TPtrCleanupTraits + { + typedef T ManagedType; + typedef T BaseManagedType; + typedef CleanupStrategyType CleanupStrategy; + }; + +// Cleanup traits class template specialization for pointers to types +// that are derived from CBase +template +struct TPtrCleanupTraits + { + typedef T ManagedType; + typedef CBase BaseManagedType; + typedef CleanupStrategyType CleanupStrategy; + }; + +// Cleanup traits class template specialization for pointers to types +// that are derived from CBase and the default pointer cleanup +// strategy (TPtrCleanupStrategy) +template +struct TPtrCleanupTraits + { + typedef CBase ManagedType; + typedef CBase BaseManagedType; + typedef TPtrCleanupStrategy CleanupStrategy; + }; + + +/** + Implementation base class - not designed for public inheritance or + direct use. +*/ +template +class LManagedPtrBase: protected LAutoPtrBase::BaseManagedType> + { + typedef LAutoPtrBase::BaseManagedType> LAutoPtrBase; + + protected: + typedef typename TPtrCleanupTraits::ManagedType ManagedType; + typedef typename TPtrCleanupTraits::BaseManagedType BaseManagedType; + typedef typename TPtrCleanupTraits::CleanupStrategy CleanupStrategy; + + LManagedPtrBase() + { + } + + template + explicit LManagedPtrBase(U* aPtr) + : LAutoPtrBase(aPtr) + { + } + +/** + Destructor. When automatic resource management is enabled, the + destructor invokes the specified cleanup strategy for the managed + pointer. + */ + ~LManagedPtrBase() + { + if (IsEnabled()) + { + CleanupStrategy::Cleanup(static_cast(iPtr)); + } + } + + template + LManagedPtrBase& operator=(U* aPtr) + { + ReleaseResource(); + LAutoPtrBase::operator=(aPtr); + return *this; + } + +/** + If automatic resource management is enabled, the specified cleanup + strategy is invoked for the managed pointer and the automatic + resource management is then disabled. The underlying pointer is + reset to NULL. + + @post Get() == NULL +*/ + void ReleaseResource() + { + if (!IsEnabled()) + return; + + CleanupStrategy::Cleanup(static_cast(iPtr)); + LAutoPtrBase::Disable(); + } + + using LAutoPtrBase::Unmanage; + + using LAutoPtrBase::IsEnabled; + + using LAutoPtrBase::Get; + + using LAutoPtrBase::operator->; + + using LAutoPtrBase::Disable; + + using LAutoPtrBase::iPtr; + + void Swap(LManagedPtrBase& aManagedPtr) + { + LAutoPtrBase::Swap(aManagedPtr); + } + }; + + +/** + A class template that provides automatic management of pointers + held in the data members of objects. + + @note This class should not used to define locals. See below for + an explanation and links to management classes suitable for use in + that context. + + This class template can be used to protect a pointer to type T such + that the instance of T referred to is automatically cleaned up when + the management object is destroyed; typically when the object + containing it is deleted. + + By default, the cleanup action is to delete the managed pointer + using a (non-array) delete operation. An alternative cleanup + strategy can be specified using the optional CleanupStrategy class + template parameter of the LManagedPtr class template. The most + common alternative cleanup strategies are predefined + (e.g. TPointerFree). + + The constructors of this class never leave, so data members defined with + this type may be initialized safely during any phase of + construction of the owning class. + + As a convenience, the methods of the managed pointer may be + accessed via "->" notation directly on the management object, while + "." notation is used to access the interface of the management + object itself. Using "*" to dereference the management object + yields a T&, and is often useful when passing the managed object as + an argument. + + Automatic cleanup may be disabled at any time by calling + Unmanage(), while cleanup may be forced at any time by calling + ReleaseResource(). + + Example: + @code + class CComposite : public CBase + { + public: + CONSTRUCTORS_MAY_LEAVE + + CComposite() + : iComponent(CComponent::NewL()) + { + //... + } + + ~CComposite() + { + // the pointer to the CComponent object is automatically + // deleted + } + + private: + LManagedPtr iComponent; + }; + @endcode + + Behind the scenes, this class template simply relies on reliable + execution of its destructor. If used for a local variable rather + than a data member, cleanup will occur but out-of-order compared to + objects protected using the LCleanupXxx variants or the + CleanupStack directly. Therefore it is not recommended for use in + that context. + + These management classes may be used as the basis for implementing + leave-safe single-phase construction, since fully initialized + data members protected in this way will get destroyed (so reliably + triggering cleanup) if their containing classes leave during + execution of their constructors. Note, however, that single-phase + construction must be explicitly enabled in the containing class + using the CONSTRUCTORS_MAY_LEAVE macro. + + This class template together with the cleanup strategy class + templates provide a template-based implementation of the Strategy + design pattern (See also: Policy-based design). + + @see TPointerDelete which implements the default deleting cleanup strategy + @see TPointerFree which implements the alternative User::Free() cleanup strategy + @see LCleanedupPtr which has the same interface, but uses the cleanup + stack and is suitable for protecting locals + @see CONSTRUCTORS_MAY_LEAVE +*/ +template +class LManagedPtr: protected LManagedPtrBase + { + typedef LManagedPtrBase LManagedPtrBase; + + public: + typedef T ManagedType; + typedef CleanupStrategyType CleanupStrategy; + + +/** + Default constructor. Constructs an empty LManagedPtr object. + + @post Get() == NULL + */ + LManagedPtr() + { + } + +/** + Explicit constructor template. Constructs a LManagedPtr object + that manages the pointer aPtr of a type convertible to T* that can + be cleaned up using the cleanup strategy of the LManagedPtr class. + The default cleanup strategy is to delete the pointer to a + heap-allocated object by using non-array delete. Alternative + cleanup strategies can be specified by using the CleanupStrategy + template parameter of the LManagedPtr class template. + + @param aPtr A pointer of a type that is convertible to T* that can + be cleaned up using the cleanup strategy. + + @pre aPtr is of a type convertible to T* and can be cleaned up + using the cleanup strategy. + + @post Get() == aPtr + */ + explicit LManagedPtr(T* aPtr) + : LManagedPtrBase(aPtr) + { + } + +/** + Destructor. When automatic resource management is enabled, the + destructor invokes the specified cleanup strategy for the managed + pointer. + */ + + +/** + Assigns a new pointer to be managed. The new pointer must be of a + type convertible to T* and it must be possible to use the cleanup + strategy of the LManagedPtr object for the cleanup of the new + managed pointer. If the LManagedPtr object already contains a + managed pointer, then the cleanup strategy is invoked with the + managed pointer before assigning the new managed pointer. + + @param aPtr A pointer of a type that is convertible to T* that can + be cleaned up using the cleanup strategy. + + @pre aPtr is a pointer of a type that is convertible to T* and can + be cleaned up using the cleanup strategy. + + @post Get() == aPtr + */ + LManagedPtr& operator=(T* aPtr) + { + LManagedPtrBase::operator=(aPtr); + return *this; + } + +/** + Assigns a new pointer to be managed. The new pointer must be of a + type convertible to T* and it must be possible to use the cleanup + strategy of the LManagedPtr object for the cleanup of the new + managed pointer. If the LManagedPtr object already contains a + managed pointer, then the cleanup strategy is invoked with the + managed pointer before assigning the new managed pointer. + + @param aPtr A pointer of a type that is convertible to T* that can + be cleaned up using the cleanup strategy. + + @pre aPtr is a pointer of a type that is convertible to T* and can + be cleaned up using the cleanup strategy. + + @post Get() == aPtr + */ + template + LManagedPtr& operator=(U* aPtr) + { + LManagedPtrBase::operator=(aPtr); + return *this; + } + + using LManagedPtrBase::ReleaseResource; + +/** + Disables the automatic resource management for this object and + returns a pointer to the object of type T. + + @return A pointer to the object of type T. +*/ + T* Unmanage() + { + return static_cast(LManagedPtrBase::Unmanage()); + } + +/** + Returns ETrue if automatic resource management is enabled; EFalse + otherwise. + + @return ETrue if automatic resource management is enabled; EFalse + otherwise. +*/ + using LManagedPtrBase::IsEnabled; + +/** + Returns a pointer to the managed object of type T. + + @return A pointer to the managed object of type T. +*/ + T* Get() const + { + return static_cast(iPtr); + } + +/** + Overloaded indirection operator function. + + @return A reference to the managed object of type T. +*/ + T& operator*() const + { + return *(static_cast(iPtr)); + } + +/** + Overloaded class member access operator function. + + @return A pointer to the managed object of type T. +*/ + T* operator->() const + { + return static_cast(iPtr); + } + + +// Implementation type - do not use + typedef typename LManagedPtrBase::BaseManagedType* LManagedPtr::*TUnspecifiedBoolType; + +/** + Conversion operator that enables LCleanedupPtr objects to be used + in boolean contexts. + + @return An unspecified value of an unspecified type convertible to + boolean, which has a boolean value equal to Get() != NULL + */ + operator TUnspecifiedBoolType() + { + return iPtr ? &LManagedPtr::iPtr : NULL; + } + + + using LManagedPtrBase::Disable; + + void Swap(LManagedPtr& aManagedPtr) + { + LManagedPtrBase::Swap(aManagedPtr); + } + + private: + using LManagedPtrBase::iPtr; + }; + + +// function template used for comparing two LManagedPtr-managed +// pointers for equality +template +TBool operator==(const LManagedPtr& aPtr1, const LManagedPtr& aPtr2) + { + return aPtr1.Get() == aPtr2.Get(); + } + +// function template used for comparing two LManagedPtr-managed +// pointers for inequality +template +TBool operator!=(const LManagedPtr& aPtr1, const LManagedPtr& aPtr2) + { + return aPtr1.Get() != aPtr2.Get(); + } + +// function template used for testing the ordering of two +// LManagedPtr-managed pointers +template +TBool operator<(const LManagedPtr& aPtr1, const LManagedPtr& aPtr2) + { + return aPtr1.Get() < aPtr2.Get(); + } + + +/** + A class template that provides automatic management of arrays. Such + managed arrays can be data members of composite classes. + + @note This class should not used to define locals. See below for + an explanation and links to management classes suitable for use in + that context. + + @par + + @note This class can only be used with raw arrays, which are used + only rarely on Symbian OS. Instances of Symbian array container + classes (e.g. RArray, RPointerArray) should be managed using the + automatic management template classes appropriate for the array's + type (LManagedHandle template classes for Symbian R arrays or + LManagedPtr template classes for Symbian C arrays). + + This class template can be used to protect a heap-allocated array + of objects of type T such that the managed array is automatically + deallocated when the management object is destroyed. + + The default cleanup strategy is to deallocate the managed array + using arrray delete (delete[]), assuming that the array is + heap-allocated. An alternative cleanup strategy can be selected by + specifying a cleanup strategy template class as the optional second + template argument (corresponding to the CleanupStrategy template + parameter). + + The constructors of this class never leave, so data members defined with + this type may be initialized safely during any phase of + construction of the owning class. + + As a convenience, the elements of the managed array may be accessed + via "[]" notation directly on the management object. + + Automatic cleanup may be disabled at any time by calling + Unmanage(), while cleanup may be forced at any time by calling + ReleaseResource(). + + + Example: + @code + class CComposite : public CBase + { + public: + CONSTRUCTORS_MAY_LEAVE + + CComposite() + : iComponents(new(ELeave) CComponent[KNumComponents]) + { + //... + } + + ~CComposite() + { + // the array is automatically deleted + } + + private: + LManagedArray iComponents; + }; + @endcode + + + Behind the scenes, this class template simply relies on reliable + execution of its destructor. If used for a local variable rather + than a data member, cleanup will occur but out-of-order compared to + objects protected using the LCleanupXxx variants or the + CleanupStack directly. Therefore it is not recommended for use in + that context. + + These management classes may be used as the basis for implementing + leave-safe single-phase construction, since fully initialized + data members protected in this way will get destroyed (so reliably + triggering cleanup) if their containing classes leave during + execution of their constructors. Note, however, that single-phase + construction must be explicitly enabled in the containing class + using the CONSTRUCTORS_MAY_LEAVE macro. + + This class template together with the cleanup strategy class + templates provide a template-based implementation of the Strategy + design pattern (See also: Policy-based design). + + @see LCleanedupArray which has the same interface, but uses the cleanup + stack and is suitable for protecting locals + @see CONSTRUCTORS_MAY_LEAVE +*/ +template +class LManagedArray: protected LAutoPtrBase + { + typedef LAutoPtrBase LAutoPtrBase; + + public: + typedef T ManagedType; + typedef CleanupStrategyType CleanupStrategy; + +/** + Default constructor. Constructs an empty LManagedArray object. + + @post Get() == NULL + */ + LManagedArray() + { + } + +/** + Explicit constructor. Constructs a LManagedArray object that + manages an array of objects of type T that can be cleaned up using + the cleanup strategy of the LManagedArray class. The default + cleanup strategy is to deallocate the managed array by using array + delete (delete[]), assuming that the array is heap-allocated. + Alternative cleanup strategies can be specified by using the + CleanupStrategy template parameter of the LManagedArray class + template. + + @param aPtr A pointer to the first element of an array of objects + of type T - array that can be cleaned up using the cleanup strategy + of the the LManagedArray class. + + @pre The array can be cleaned up using the cleanup strategy. + + @post Get() == aPtr + */ + explicit LManagedArray(T* aPtr) + : LAutoPtrBase(aPtr) + { + } + +/** + Destructor. When automatic resource management is enabled, the + destructor invokes the specified cleanup strategy for the managed + pointer. + */ + ~LManagedArray() + { + if (LAutoPtrBase::IsEnabled()) + { + CleanupStrategy::Cleanup(iPtr); + } + } + +/** + Assigns a new array of objects of type T to be managed. It needs + to be possible use the cleanup strategy of the LManagedArray object + for the cleanup of the new managed array. The default cleanup + strategy is to delete the heap-allocated array by using array + delete (delete[]). If the LManagedArray object already manages an + array, then the cleanup strategy is invoked with the managed array + before assigning the new managed array. + + @param aPtr A pointer to the first element of the array of objects + of type T - array that can be cleaned up using the cleanup + strategy. + + @pre The new array to be managed can be cleaned up using the + cleanup strategy. + + @post Get() == aPtr + */ + LManagedArray& operator=(T* aPtr) + { + ReleaseResource(); + LAutoPtrBase::operator=(aPtr); + return *this; + } + +/** + If automatic resource management is enabled, the specified cleanup + strategy is invoked for the managed pointer and the automatic + resource management is then disabled. The underlying pointer is + reset to NULL. + + @post Get() == NULL +*/ + void ReleaseResource() + { + if (!LAutoPtrBase::IsEnabled()) + return; + + CleanupStrategy::Cleanup(iPtr); + LAutoPtrBase::Disable(); + } + +/** + Disables the automatic resource management for this object and + returns a pointer to the first element of the array of objects of + type T. + + @return A pointer to the first element of the array of objects of + type T. +*/ + T* Unmanage() + { + return static_cast(LAutoPtrBase::Unmanage()); + } + +/** + Returns ETrue if automatic resource management is enabled; EFalse + otherwise. + + @return ETrue if automatic resource management is enabled; EFalse + otherwise. +*/ + using LAutoPtrBase::IsEnabled; + +/** + Returns a pointer to the first element of the managed array of + objects of type T. + + @return A pointer to the first element of the managed array of + objects of type T. +*/ + using LAutoPtrBase::Get; + +/** + Overloaded subscript operator. + + @return A reference to the object of type T at the position aIndex. + */ + T& operator[](TInt aIndex) const + { + return iPtr[aIndex]; + } + + using LAutoPtrBase::Disable; + + void Swap(LManagedArray& aArray) + { + LAutoPtrBase::Swap(aArray); + } + + private: + using LAutoPtrBase::iPtr; + }; + + +/** + Implementation base class - not designed for public inheritance or + direct use. + + @internalComponent +*/ +// Not for Client Use , Only to be used Internally. +template +class LAutoRefBase + { + protected: + template + explicit LAutoRefBase(U& aRef) + : iPtr(&aRef) + { + } + + template + LAutoRefBase& operator=(U& aRef) + { + iPtr = &aRef; + return *this; + } + + T& Unmanage() + { + T* ptr = iPtr; + iPtr = NULL; + return *ptr; + } + + TBool IsEnabled() const + { + return iPtr != NULL; + } + + T& Get() const + { + return *iPtr; + } + + T& operator*() const + { + return *iPtr; + } + + T* operator->() const + { + return iPtr; + } + + void Disable() + { + iPtr = NULL; + } + + void Swap(LAutoRefBase& aAutoRef) + { + ::Swap(iPtr, aAutoRef.iPtr); + } + + protected: + T* iPtr; + + private: + LAutoRefBase(const LAutoRefBase&); + LAutoRefBase& operator=(const LAutoRefBase&); + }; + + +/** + A class template that provides automatic management of references + to resource handles (often R-class instances) held in the data + members of objects. + + @note This class should not used to define locals. See below for + an explanation and links to management classes suitable for use in + that context. + + Unlike LManagedHandle which creates a fresh instance of its managed + type, this class template can be used to protect an existing + resource handle of type T (typically an R-class instance). The + instance of T referred to has a cleanup operation run on it + automatically when the management object is destroyed; typically + when the object containing it is deleted. + + By default, the cleanup action is to call the Close() member + function of the referenced handle. An alternative cleanup strategy may + be selected by specifying a cleanup strategy template class in the + optional second template parameter position. The most common + alternative cleanup strategies are predefined. It is also possible + to specialize the default cleanup action for a given class using + the DEFINE_CLEANUP_FUNCTION macro. + + The constructors of this class never leave, so data members defined with + this type may be initialized safely during any phase of + construction of the owning class. + + As a convenience, the methods of the managed pointer may be + accessed via "->" notation directly on the management object, while + "." notation is used to access the interface of the management + object itself. Using "*" to dereference the management object + yields a T&, and is often useful when passing the managed object as + an argument. + + Automatic cleanup may be disabled at any time by calling + Unmanage(), while cleanup may be forced at any time by calling + ReleaseResource(). + + Example: + @code + class CComposite : public CBase + { + public: + CONSTRUCTORS_MAY_LEAVE + + // An existing RFs instance is given to us to reuse, but + // we are responsible for calling Close() when we're done + CComposite(RFs& aFs) + : iFileServ(aFs) + { + iFileServ->Connect() OR_LEAVE; + iFile->Open(*iFileServ, ...); + } + + ~CComposite() + { + // the handles are automatically closed + } + + private: + + LManagedRef iFileServ; + LManagedHandle iFile; + }; + @endcode + + Behind the scenes, this class template simply relies on reliable + execution of its destructor. If used for a local variable rather + than a data member, cleanup will occur but out-of-order compared to + objects protected using the LCleanupXxx variants or the + CleanupStack directly. Therefore it is not recommended for use in + that context. + + These management classes may be used as the basis for implementing + leave-safe single-phase construction, since fully initialized + data members protected in this way will get destroyed (so reliably + triggering cleanup) if their containing classes leave during + execution of their constructors. Note, however, that single-phase + construction must be explicitly enabled in the containing class + using the CONSTRUCTORS_MAY_LEAVE macro. + + This class template together with the cleanup strategy class + templates provide a template-based implementation of the Strategy + design pattern (See also: Policy-based design). + + @see TClose which implements the default Close() calling cleanup strategy + @see TResetAndDestroy which implements an alternative + ResetAndDestroy() calling cleanup strategy + @see TFree which implements an alternative Free() calling cleanup + strategy + @see TDestroy which implements an alternative Destroy() calling + cleanup strategy + @see TRelease which implements an alternative Release() calling + cleanup strategy + @see LCleanedupRef which has the same interface, but uses the cleanup + stack and is suitable for protecting locals + @see LManagedHandle which has a similar interface but creates a fresh + local instance of T + @see CONSTRUCTORS_MAY_LEAVE +*/ +template +class LManagedRef: protected LAutoRefBase + { + typedef LAutoRefBase LAutoRefBase; + + public: + typedef T ManagedType; + typedef CleanupStrategyType CleanupStrategy; + +/** + Explicit constructor. + */ + template + explicit LManagedRef(U& aRef) + : LAutoRefBase(aRef) + { + } + +/** + Destructor. When automatic resource management is enabled, the + destructor invokes the specified cleanup strategy for the managed + reference. + */ + ~LManagedRef() + { + if (LAutoRefBase::IsEnabled()) + { + CleanupStrategy::Cleanup(iPtr); + } + } + +/** + Assigns a new reference to be managed. If the LManagedRef + object already contains a managed reference, then the specified + cleanup strategy is invoked for the managed reference before + assigning the new managed reference. + */ + template + LManagedRef& operator=(U& aRef) + { + ReleaseResource(); + LAutoRefBase::operator=(aRef); + return *this; + } + +/** + If automatic resource management is enabled, the specified cleanup + strategy is invoked for the managed reference and the automatic + resource management is then disabled for this object. +*/ + void ReleaseResource() + { + if (!LAutoRefBase::IsEnabled()) + return; + + CleanupStrategy::Cleanup(iPtr); + LAutoRefBase::Disable(); + } + +/** + Disables the automatic resource management for this object and + returns a reference to the object of type T. + + @return A reference to the object of type T. +*/ + using LAutoRefBase::Unmanage; + +/** + Returns ETrue if automatic resource management is enabled; EFalse + otherwise. + + @return ETrue if automatic resource management is enabled; EFalse + otherwise. +*/ + using LAutoRefBase::IsEnabled; + +/** + Returns a reference to the managed object of type T. + + @return A reference to the managed object of type T. +*/ + using LAutoRefBase::Get; + +/** + Overloaded indirection operator function. + + @return A reference to the managed object of type T. +*/ + using LAutoRefBase::operator*; + +/** + Overloaded class member access operator function. + + @return A pointer to the managed object of type T. +*/ + using LAutoRefBase::operator->; + + using LAutoRefBase::Disable; + + void Swap(LManagedRef& aRef) + { + LAutoRefBase::Swap(aRef); + } + + private: + using LAutoRefBase::iPtr; + }; + + +/** + A class template for the creation and CleanupStack-based + local-scope automatic management of resource handles (typically + instances of R-classes). + + @note This class can only be used to define locals, never + data members. See below for an explanation and links to management + classes suitable for use in different contexts. It should never be + used in the same function as code that uses the CleanupStack API + directly. + + This class template can be used to create and protect a resource + handle of type T (typically a R-class) such that the instance of T + referred to is automatically cleaned up when either of the + following occur: + + - The referring local variable goes out of scope normally + - The referring local variable goes out of scope due to an + untrapped leave causing the scope to be exited non-locally + + By default, the cleanup action is to call the Close() member + function of the managed handle. An alternative cleanup strategy may + be selected by specifying a cleanup strategy template class in the + optional second template parameter position. The most common + alternative cleanup strategies are predefined. It is also possible + to specialize the default cleanup action for a given class using + the DEFINE_CLEANUP_FUNCTION macro. + + The constructors of this class may leave. + + Any arguments supplied when initializing an instance of this class + are automatically passed through to T's constructors. + + As a convenience, the methods of the managed handle may be + accessed via "->" notation directly on the management object, while + "." notation is used to access the interface of the management + object itself. Using "*" to dereference the management object + yields a T&, and is often useful when passing the managed object as + an argument. + + Automatic cleanup may be disabled at any time by calling + Unmanage(), while cleanup may be forced at any time by calling + ReleaseResource(). + + Example: + @code + // block scope example + { + LCleanedupHandle obj; + obj->DoSomethingL(); // leave-safe + if (obj->Finished()) + return; // RClosable::Close is invoked automatically + obj->DoSomethingElseL(); // leave-safe + // RClosable::Close is invoked automatically + } + @endcode + + Behind the scenes, this class template is implemented in terms of + the thread-local CleanupStack, restricting its use to locals on the + stack. This use of the CleanupStack ensures a consistent cleanup + order between functions that call one another, even if they use + different cleanup idioms. + + This class template together with the cleanup strategy class + templates provide a template-based implementation of the Strategy + design pattern (See also: Policy-based design). + + @see TClose which implements the default Close() calling cleanup strategy + @see TResetAndDestroy which implements an alternative + ResetAndDestroy() calling cleanup strategy + @see TFree which implements an alternative Free() calling cleanup + strategy + @see TDestroy which implements an alternative Destroy() calling + cleanup strategy + @see TRelease which implements an alternative Release() calling cleanup strategy + @see LManagedHandle which has the same interface, but does not use the cleanup + stack and is suitable for protecting the data members of classes +*/ +template +class LCleanedupHandle: protected LAutoHandleBase + { + typedef LAutoHandleBase LAutoHandleBase; + + public: + typedef T ManagedType; + typedef CleanupStrategyType CleanupStrategy; + + +/** + Default constructor. +*/ + LCleanedupHandle() + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + template + explicit LCleanedupHandle(const Param1& aParam1) + : LAutoHandleBase(aParam1) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + template + explicit LCleanedupHandle(Param1& aParam1) + : LAutoHandleBase(aParam1) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + template + LCleanedupHandle(const Param1& aParam1, + const Param2& aParam2) + : LAutoHandleBase(aParam1, + aParam2) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + template + LCleanedupHandle(const Param1& aParam1, + Param2& aParam2) + : LAutoHandleBase(aParam1, + aParam2) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + template + LCleanedupHandle(Param1& aParam1, + const Param2& aParam2) + : LAutoHandleBase(aParam1, + aParam2) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + template + LCleanedupHandle(Param1& aParam1, + Param2& aParam2) + : LAutoHandleBase(aParam1, + aParam2) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + + ~LCleanedupHandle() + { + ManagedPopCleanupStackItem(IsEnabled()); + } + +/** + Assigns a new resource to be managed. If the LCleanedupHandle + object already contains a managed resource handle, then the managed + resource is released using the specified cleanup strategy before + assigning the new managed resource. + */ + template + LCleanedupHandle& operator=(const U& aHandle) + { + ReleaseResource(); + LAutoHandleBase::operator=(aHandle); + return *this; + } + + +/** + If automatic resource management is enabled, calls the cleanup + function defined by the cleanup strategy with the managed resource + handle object and then disables the automatic resource management + for this object. The cleanup strategy is specified by the + CleanupStrategy template template parameter. The default cleanup + strategy is to call the cleanup member function on the contained + resource handle object. which is a member function named Close(), + unless explicitly defined otherwise for the class of the object, + for example by using the provided DEFINE_CLEANUP_FUNCTION macro. +*/ + void ReleaseResource() + { + if (!IsEnabled()) + return; + + CleanupStrategy::Cleanup(&Get()); + LAutoHandleBase::Disable(); + } + +/** + Disables the automatic resource management for this obkect and + returns a copy of the resource handle. + + @return A copy of the resource handle. +*/ + using LAutoHandleBase::Unmanage; + +/** + Returns ETrue if automatic resource management is enabled; EFalse + otherwise. + + @return ETrue if automatic resource management is enabled; EFalse + otherwise. +*/ + using LAutoHandleBase::IsEnabled; + + +/** + Returns a reference to the resource handle. + + @return A reference to the resource handle. +*/ + using LAutoHandleBase::Get; + + +/** + Overloaded indirection operator function. + + @return A reference to the resource handle. +*/ + using LAutoHandleBase::operator*; + +/** + Overloaded class member access operator function. + + @return A pointer to the resource handle. +*/ + using LAutoHandleBase::operator->; + + static void Cleanup(TAny* aPtr) + { + LCleanedupHandle* autoh = static_cast(aPtr); + + if (autoh->IsEnabled()) + { + CleanupStrategy::Cleanup(&autoh->Get()); + } + } + + using LAutoHandleBase::Disable; + + void Swap(LCleanedupHandle& aCleanedupHandle) + { + LAutoHandleBase::Swap(aCleanedupHandle); + } + }; + + +/** + Implementation base class - not designed for public inheritance or + direct use. + + @internalComponent +*/ +// Not for Client Use , Only to be used Internally. +template +class LCleanedupPtrBase: protected LAutoPtrBase::BaseManagedType> + { + typedef LAutoPtrBase::BaseManagedType> LAutoPtrBase; + + protected: + typedef typename TPtrCleanupTraits::ManagedType ManagedType; + typedef typename TPtrCleanupTraits::BaseManagedType BaseManagedType; + typedef typename TPtrCleanupTraits::CleanupStrategy CleanupStrategy; + + LCleanedupPtrBase() + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + template + explicit LCleanedupPtrBase(U* aPtr) + : LAutoPtrBase(aPtr) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + ~LCleanedupPtrBase() + { + ManagedPopCleanupStackItem(LAutoPtrBase::IsEnabled()); + } + + template + LCleanedupPtrBase& operator=(U* aPtr) + { + ReleaseResource(); + LAutoPtrBase::operator=(aPtr); + return *this; + } + + void ReleaseResource() + { + if (!LAutoPtrBase::IsEnabled()) + return; + + CleanupStrategy::Cleanup(static_cast(iPtr)); + LAutoPtrBase::Disable(); + } + + using LAutoPtrBase::Unmanage; + + using LAutoPtrBase::IsEnabled; + + using LAutoPtrBase::Get; + + using LAutoPtrBase::operator->; + + static void Cleanup(TAny* aPtr) + { + LCleanedupPtrBase* cleanupPtr = static_cast(aPtr); + + if (cleanupPtr->IsEnabled()) + { + CleanupStrategy::Cleanup(static_cast(cleanupPtr->iPtr)); + } + } + + using LAutoPtrBase::iPtr; + + void Swap(LCleanedupPtrBase& aCleanedupPtr) + { + LAutoPtrBase::Swap(aCleanedupPtr); + } + }; + + +/** + A class template that provides CleanupStack-based local-scope + automatic management of pointers. + + @note This class can only be used to define locals, never + data members. See below for an explanation and links to management + classes suitable for use in different contexts. It should never be + used in the same function as code that uses the CleanupStack API + directly + + This class template can be used to protect a pointer to type T such + that the instance of T referred to is automatically cleaned up + when either of the following occur: + + - The referring local variable goes out of scope normally + - The referring local variable goes out of scope due to an + untrapped leave causing the scope to be exited non-locally + + By default, the cleanup action is to delete the managed pointer + using non-array delete. An alternative cleanup strategy may be + selected by specifying a cleanup strategy template class in the + optional second template parameter position. The most common + alternative cleanup strategies are predefined. + + The constructors of this class may leave. + + As a convenience, the methods of the managed pointer may be + accessed via "->" notation directly on the management object, while + "." notation is used to access the interface of the management + object itself. Using "*" to dereference the management object + yields a T&, and is often useful when passing the managed object as + an argument. + + Automatic cleanup may be disabled at any time by calling + Unmanage(), while cleanup may be forced at any time by calling + ReleaseResource(). + + Example: + @code + // block scope example + { + LCleanedupPtr autop(new(ELeave) CDynamic); + autop->DoSomethingL(); // leave-safe + if (autop->Finished()) + return; // the pointer is deleted automatically when exiting from scope + autop->DoSomethingElseL(); // leave-safe + // the pointer is deleted automatically when exiting from scope + } + @endcode + + Behind the scenes, this class template is implemented in terms of + the thread-local CleanupStack, restricting its use to locals on the + stack. This use of the CleanupStack ensures a consistent cleanup + order between functions that call one another, even if they use + different cleanup idioms. + + This class template together with the cleanup strategy class + templates provide a template-based implementation of the Strategy + design pattern (See also: Policy-based design). + + @see TPointerDelete which implements the default deleting cleanup strategy + @see TPointerFree which implements the alternative User::Free() cleanup strategy + @see LManagedPtr which has the same interface, but does not use the cleanup + stack and is suitable for protecting the data members of classes +*/ +template +class LCleanedupPtr: protected LCleanedupPtrBase + { + typedef LCleanedupPtrBase LCleanedupPtrBase; + + public: + typedef T ManagedType; + typedef CleanupStrategyType CleanupStrategy; + + +/** + Default constructor. Constructs an empty LCleanedupPtr object. + + @post Get() == NULL +*/ + LCleanedupPtr() + { + } + +/** + Explicit constructor template. Constructs a LCleanedupPtr object + that manages the pointer aPtr of a type convertible to T* that can + be cleaned up using the cleanup strategy of the LCleanedupPtr + class. The default cleanup strategy is to delete the pointer to a + heap-allocated object by using non-array delete. Alternative + cleanup strategies can be specified by using the CleanupStrategy + template parameter of the LCleanedupPtr class template. + + @param aPtr A pointer of a type that is convertible to T* that can + be cleaned up using the cleanup strategy. + + @pre aPtr is of a type convertible to T* and can be cleaned up + using the cleanup strategy. + + @post Get() == aPtr +*/ + explicit LCleanedupPtr(T* aPtr) + : LCleanedupPtrBase(aPtr) + { + } + +/** + Assigns a new pointer to be managed. The new pointer must be of a + type convertible to T* and it must be possible to use the cleanup + strategy of the LCleanedupPtr object for the cleanup of the new + managed pointer. If the LCleanedupPtr object already contains a + managed pointer, then the cleanup strategy is invoked with the + managed pointer before assigning the new managed pointer. + + @param aPtr A pointer of a type that is convertible to T* that can + be cleaned up using the cleanup strategy. + + @pre aPtr is a pointer of a type that is convertible to T* and can + be cleaned up using the cleanup strategy. + + @post Get() == aPtr + */ + LCleanedupPtr& operator=(T* aPtr) + { + LCleanedupPtrBase::operator=(aPtr); + return *this; + } + +/** + Assigns a new pointer to be managed. The new pointer must be of a + type convertible to T* and it must be possible to use the cleanup + strategy of the LCleanedupPtr object for the cleanup of the new + managed pointer. If the LCleanedupPtr object already contains a + managed pointer, then the cleanup strategy is invoked with the + managed pointer before assigning the new managed pointer. + + @param aPtr A pointer of a type that is convertible to T* that can + be cleaned up using the cleanup strategy. + + @pre aPtr is a pointer of a type that is convertible to T* and can + be cleaned up using the cleanup strategy. + + @post Get() == aPtr + */ + template + LCleanedupPtr& operator=(U* aPtr) + { + LCleanedupPtrBase::operator=(aPtr); + return *this; + } + + +/** + If automatic resource management is enabled, the specified cleanup + strategy is invoked with the managed pointer and the automatic + resource management is then disabled. The underlying pointer is + reset to NULL. + + @post Get() == NULL +*/ + using LCleanedupPtrBase::ReleaseResource; + +/** + Disables the automatic resource management for this object and + returns a pointer to the object of type T. + + @return A pointer to the object of type T. +*/ + T* Unmanage() + { + return static_cast(LCleanedupPtrBase::Unmanage()); + } + +/** + Returns ETrue if automatic resource management is enabled; EFalse + otherwise. + + @return ETrue if automatic resource management is enabled; EFalse + otherwise. +*/ + using LCleanedupPtrBase::IsEnabled; + +/** + Returns a pointer to the managed object of type T. + + @return A pointer to the managed object of type T. +*/ + T* Get() const + { + return static_cast(iPtr); + } + +/** + Overloaded indirection operator function. + + @return A reference to the managed object of type T. +*/ + T& operator*() const + { + return *(static_cast(iPtr)); + } + +/** + Overloaded class member access operator function. + + @return A pointer to the managed object of type T. +*/ + T* operator->() const + { + return static_cast(iPtr); + } + +// Implementation type - do not use + typedef typename LCleanedupPtrBase::BaseManagedType* LCleanedupPtr::*TUnspecifiedBoolType; + +/** + Conversion operator that enables LCleanedupPtr objects to be used + in boolean contexts. + + @return An unspecified value of an unspecified type convertible to + boolean, which has a boolean value equal to Get() != NULL + */ + operator TUnspecifiedBoolType() + { + return iPtr ? &LCleanedupPtr::iPtr : NULL; + } + + using LCleanedupPtrBase::Disable; + + void Swap(LCleanedupPtr& aCleanedupPtr) + { + LCleanedupPtrBase::Swap(aCleanedupPtr); + } + + private: + using LCleanedupPtrBase::iPtr; + }; + + +// function template used for comparing two LCleanedupPtr-managed +// pointers for equality +template +TBool operator==(const LCleanedupPtr& aPtr1, const LCleanedupPtr& aPtr2) + { + return aPtr1.Get() == aPtr2.Get(); + } + +// function template used for comparing two LCleanedupPtr-managed +// pointers for inequality +template +TBool operator!=(const LCleanedupPtr& aPtr1, const LCleanedupPtr& aPtr2) + { + return aPtr1.Get() != aPtr2.Get(); + } + +// function template used for testing the ordering of two +// LCleanedupPtr-managed pointers +template +TBool operator<(const LCleanedupPtr& aPtr1, const LCleanedupPtr& aPtr2) + { + return aPtr1.Get() < aPtr2.Get(); + } + + +/** + A class template that provides CleanupStack-based local-scope + automatic management of arrays. + + @note This class can only be used to define locals, never + data members. See below for an explanation and links to management + classes suitable for use in different contexts. It should never be + used in the same function as code that uses the CleanupStack API + directly + + @par + + @note This class can only be used with raw arrays, which are used + only rarely on Symbian OS. Instances of Symbian array container + classes (e.g. RArray, RPointerArray) should be managed using the + automatic management template classes appropriate for the array's + type (LCleanedupHandle template classes for Symbian R arrays or + LCleanedupPtr template classes for Symbian C arrays). + + This class template can be used to protect a heap-allocated array + of objects of type T such that the array of T referred to is + automatically cleaned up when either of the following occur: + + - The referring local variable goes out of scope normally + - The referring local variable goes out of scope due to an + untrapped leave causing the scope to be exited non-locally + + The default cleanup strategy is to deallocate the managed array + using arrray delete (delete[]), assuming that the array is + heap-allocated. An alternative cleanup strategy can be selected by + specifying a cleanup strategy template class as the optional second + template argument (corresponding to the CleanupStrategy template + parameter). + + The constructors of this class may leave. + + As a convenience, the elements of the managed array may be accessed + via "[]" notation directly on the management object. + + Automatic cleanup may be disabled at any time by calling + Unmanage(), while cleanup may be forced at any time by calling + ReleaseResource(). + + @code + // block scope example + { + LCleanedupArray arrayp(new(ELeave) TValue[KArraySize]); + arrayp[0].DoSomethingL(); // leave-safe + if (arrayp[0].Finished()) + return; // the array is deleted automatically when exiting from scope + arrayp[1].DoSomethingElseL(); // leave-safe + // the array is deleted automatically when exiting from scope + } + @endcode + + Behind the scenes, this class template is implemented in terms of + the thread-local CleanupStack, restricting its use to locals on the + stack. This use of the CleanupStack ensures a consistent cleanup + order between functions that call one another, even if they use + different cleanup idioms. + + This class template together with the cleanup strategy class + templates provide a template-based implementation of the Strategy + design pattern (See also: Policy-based design). + + @see LManagedArray which has the same interface, but does not use + the cleanup stack and is suitable for protecting the data members + of classes +*/ +template +class LCleanedupArray: protected LAutoPtrBase + { + typedef LAutoPtrBase LAutoPtrBase; + + public: + typedef T ManagedType; + typedef CleanupStrategyType CleanupStrategy; + +/** + Default constructor. Constructs an empty LCleanedupArray object. + + @post Get() == NULL + */ + LCleanedupArray() + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + +/** + Explicit constructor. Constructs a LCleanedupArray object that + manages an array of objects of type T that can be cleaned up using + the cleanup strategy of the LCleanedupArray class. The default + cleanup strategy is to deallocate the heap-allocated array by using + array delete. An alternative cleanup strategy can be selected by + specifying a cleanup strategy template class as the optional second + template argument (corresponding to the CleanupStrategy template + parameter). + + @param aPtr A pointer to the first element of an array of objects + of type T, array that can be cleaned up using the cleanup strategy + of the the LCleanedupArray class. + + @pre The array can be cleaned up using the cleanup strategy. + + @post Get() == aPtr + */ + explicit LCleanedupArray(T* aPtr) + : LAutoPtrBase(aPtr) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + + +/** + Destructor. When automatic resource management is enabled, the + destructor invokes the specified cleanup strategy for the managed + pointer. + */ + ~LCleanedupArray() + { + ManagedPopCleanupStackItem(LAutoPtrBase::IsEnabled()); + } + +/** + Assigns a new array of objects of type T to be managed. It needs + to be be possible to use the cleanup strategy of the + LCleanedupArray object for the cleanup of the new managed array. + The default cleanup strategy is to delete the heap-allocated array + by using array delete (delete[]). If the LCleanedupArray object + already manages an array, then the cleanup strategy is invoked with + the managed array before assigning the new managed array. + + @param aPtr A pointer to the first element of the array of objects + of type T - array that can be cleaned up using the cleanup + strategy. + + @pre The new array to be managed can be cleaned up using the + cleanup strategy. + + @post Get() == aPtr + */ + LCleanedupArray& operator=(T* aPtr) + { + ReleaseResource(); + LAutoPtrBase::operator=(aPtr); + return *this; + } + +/** + If automatic resource management is enabled, the specified cleanup + strategy is invoked for the managed pointer and the automatic + resource management is then disabled. The underlying pointer is + reset to NULL. + + @post Get() == NULL +*/ + void ReleaseResource() + { + if (!LAutoPtrBase::IsEnabled()) + return; + + CleanupStrategy::Cleanup(iPtr); + iPtr = NULL; + } + + +/** + Disables the automatic resource management for this object and + returns a pointer to the first element of the array of objects of + type T. + + @return A pointer to the first element of the array of objects of + type T. +*/ + using LAutoPtrBase::Unmanage; + +/** + Returns ETrue if automatic resource management is enabled; EFalse + otherwise. + + @return ETrue if automatic resource management is enabled; EFalse + otherwise. +*/ + using LAutoPtrBase::IsEnabled; + +/** + Returns a pointer to the first element of the managed array of + objects of type T. + + @return A pointer to the first element of the managed array of + objects of type T. +*/ + using LAutoPtrBase::Get; + +/** + Overloaded subscript operator. + + @return A reference to the object of type T at the position aIndex. + */ + T& operator[](TInt aIndex) const + { + return iPtr[aIndex]; + } + + static void Cleanup(TAny* aPtr) + { + LCleanedupArray* cleanupPtr = static_cast(aPtr); + + if (cleanupPtr->IsEnabled()) + { + CleanupStrategy::Cleanup(cleanupPtr->iPtr); + } + } + + using LAutoPtrBase::Disable; + + void Swap(LCleanedupArray& aArray) + { + LAutoPtrBase::Swap(aArray); + } + + private: + using LAutoPtrBase::iPtr; + }; + + +/** + A class template that provides CleanupStack-based local-scope + automatic management of references to resource handles (often + instances of R-classes). + + @note This class can only be used to define locals, never + data members. See below for an explanation and links to management + classes suitable for use in different contexts. It should never be + used in the same function as code that uses the CleanupStack API + directly. + + Unlike LCleanedupHandle which creates a fresh instance of its + managed type, this class template can be used to reference and + protect an existing resource handle of type T (typically an + R-class). The instance of T referred to has a cleanup operation run + on it automatically when either of the following occur: + + - The referring local variable goes out of scope normally + - The referring local variable goes out of scope due to an + untrapped leave causing the scope to be exited non-locally + + By default, the cleanup action is to call the Close() member + function of the referenced handle. An alternative cleanup strategy + may be selected by specifying a cleanup strategy template class in + the optional second template parameter position. The most common + alternative cleanup strategies are predefined. It is also possible + to specialize the default cleanup action for a given class using + the DEFINE_CLEANUP_FUNCTION macro. + + The constructors of this class may leave. + + As a convenience, the methods of the managed handle may be + accessed via "->" notation directly on the management object, while + "." notation is used to access the interface of the management + object itself. Using "*" to dereference the management object + yields a T&, and is often useful when passing the managed object as + an argument. + + Automatic cleanup may be disabled at any time by calling + Unmanage(), while cleanup may be forced at any time by calling + ReleaseResource(). + + Example: + @code + // block scope example + void DoWithClosable(RClosable& aObj) + { + LCleanedupRef obj(aObj); + obj->DoSomethingL(); // leave-safe + if (obj->Finished()) + return; // RClosable::Close is invoked automatically + obj->DoSomethingElseL(); // leave-safe + // RClosable::Close is invoked automatically + } + @endcode + + Behind the scenes, this class template is implemented in terms of + the thread-local CleanupStack, restricting its use to locals on the + stack. This use of the CleanupStack ensures a consistent cleanup + order between functions that call one another, even if they use + different cleanup idioms. + + This class template together with the cleanup strategy class + templates provide a template-based implementation of the Strategy + design pattern (See also: Policy-based design). + + @see TClose which implements the default Close() calling cleanup strategy + @see TResetAndDestroy which implements an alternative + ResetAndDestroy() calling cleanup strategy + @see TFree which implements an alternative Free() calling cleanup + strategy + @see TDestroy which implements an alternative Destroy() calling + cleanup strategy + @see TRelease which implements an alternative Release() calling + cleanup strategy + @see LManagedRef which has the same interface, but does not use + the cleanup stack and is suitable for protecting the data members of + classes + @see LCleanedupHandle which has a similar interface but creates a + fresh local instance of T +*/ +template +class LCleanedupRef: protected LAutoRefBase + { + typedef LAutoRefBase LAutoRefBase; + + public: + typedef T ManagedType; + typedef CleanupStrategyType CleanupStrategy; + +/** + Explicit constructor. + */ + template + explicit LCleanedupRef(U& aRef) + : LAutoRefBase(aRef) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + +/** + Destructor. When automatic resource management is enabled, the + destructor invokes the specified cleanup strategy for the managed + reference. + */ + ~LCleanedupRef() + { + ManagedPopCleanupStackItem(LAutoRefBase::IsEnabled()); + } + +/** + Assigns a new reference to be managed. If the LCleanedupRef + object already contains a managed reference, then the specified + cleanup strategy is invoked for the managed reference before + assigning the new managed reference. + */ + template + LCleanedupRef& operator=(U& aRef) + { + ReleaseResource(); + LAutoRefBase::operator=(aRef); + return *this; + } + +/** + If automatic resource management is enabled, the specified cleanup + strategy is invoked for the managed reference and the automatic + resource management is then disabled. +*/ + void ReleaseResource() + { + if (!LAutoRefBase::IsEnabled()) + return; + + CleanupStrategy::Cleanup(iPtr); + iPtr = NULL; + } + +/** + Disables the automatic resource management for this object and + returns a reference to the object of type T. + + @return A reference to the object of type T. +*/ + using LAutoRefBase::Unmanage; + +/** + Returns ETrue if automatic resource management is enabled; EFalse + otherwise. + + @return ETrue if automatic resource management is enabled; EFalse + otherwise. +*/ + using LAutoRefBase::IsEnabled; + +/** + Returns a reference to the managed object of type T. + + @return A reference to the managed object of type T. +*/ + using LAutoRefBase::Get; + +/** + Overloaded indirection operator function. + + @return A reference to the managed object of type T. +*/ + using LAutoRefBase::operator*; + +/** + Overloaded class member access operator function. + + @return A pointer to the managed object of type T. +*/ + using LAutoRefBase::operator->; + + + static void Cleanup(TAny* aPtr) + { + LCleanedupRef* cleanupRef = static_cast(aPtr); + + if (cleanupRef->IsEnabled()) + { + CleanupStrategy::Cleanup(cleanupRef->iPtr); + } + } + + using LAutoRefBase::Disable; + + void Swap(LCleanedupRef& aRef) + { + LAutoRefBase::Swap(aRef); + } + + private: + using LAutoRefBase::iPtr; + }; + + +/** + A class that provides automatic cleanup using a TCleanupOperation + on the destruction of the LManagedGuard object. + + @note This class can only be used to define object scoped cleanup + to guard object destruction, never local stack scoped cleanup. See + below for an explanation and links to management classes suitable + for use in different contexts. + + This class can be used to manage a TCleanupOperation in such a way + that the specified cleanup operation is guaranteed to be called + when the guarding object is destroyed; typically when the object + containing it is deleted. + + The constructors of this class never leave, so data members defined with + this type may be initialized safely during any phase of + construction of the owning class. + + Automatic cleanup may be disabled at any time by calling + Dismiss(), while cleanup may be forced at any time by calling + Execute(). + + @code + class CComposite : public CBase + { + public: + CONSTRUCTORS_MAY_LEAVE + + CComposite(RCleanable* aObj) + : iObj(RCleanable::Cleanup, aObj) + { + } + + ~CComposite() + { + // RCleanable::Cleanup(iObj) is automatically invoked + } + + private: + LManagedGuard iObj; + }; + @endcode + + Behind the scenes, this class template simply relies on reliable + execution of its destructor. If used for a local variable rather + than a data member, cleanup will occur but out-of-order compared to + objects protected using the LCleanupXxx variants or the + CleanupStack directly. Therefore it is not recommended for use in + that context. + + These management classes may be used as the basis for implementing + leave-safe single-phase construction, since fully initialized + data members protected in this way will get destroyed (so reliably + triggering cleanup) if their containing classes leave during + execution of their constructors. Note, however, that single-phase + construction must be explicitly enabled in the containing class + using the CONSTRUCTORS_MAY_LEAVE macro. + + @see LCleanedupGuard which has the same interface, but uses the cleanup + stack and is suitable for use as a local to guard local scope exit + @see CONSTRUCTORS_MAY_LEAVE +*/ +class LManagedGuard + { + public: +/** + Constructor. Creates a LCleanedupGuard object that, when enabled, + automatically invokes upon destruction a cleanup operation + specified by the aCleanupOperation parameter with the pointer to + data specified by the aData parameter. + + @param aCleanupOperation A cleanup operation. + @param aData Pointer to data to be passed to the cleanup operation + */ + LManagedGuard(TCleanupOperation aCleanupOperation, TAny* aData = 0) + : iCleanupOperation(aCleanupOperation), + iData(aData) + { + } + +/** + Destructor. + */ + ~LManagedGuard() + { + Execute(); + } + +/** + Executes the guard cleanup operation. +*/ + void Execute() + { + if (iCleanupOperation) + { + iCleanupOperation(iData); + } + } + +/** + Disables the guard. +*/ + void Dismiss() + { + iCleanupOperation = NULL; + } + + private: + LManagedGuard(const LManagedGuard&); + LManagedGuard& operator=(const LManagedGuard&); + + TCleanupOperation iCleanupOperation; + TAny* iData; + }; + + +/** + A class that provides CleanupStack-based local-scope automatic + cleanup using a TCleanupOperation on the destruction of the + LManagedGuard object. + + @note This class can only be used to define a local stack scoped + cleanup, never an object scoped cleanup to guard object + destruction. See below for an explanation and links to management + classes suitable for use in different contexts. + + This class can be used to manage a TCleanupOperation in such a way + that the specified cleanup operation is guaranteed to be called + when either of the following occur: + + - The guarding local variable goes out of scope normally + - The guarding local variable goes out of scope due to an + untrapped leave causing the scope to be exited non-locally + + The constructors of this class may leave. + + Automatic cleanup may be disabled at any time by calling + Dismiss(), while cleanup may be forced at any time by calling + Execute(). + + @code + // block scope example + { + RCleanable obj; + LCleanedupGuard cleanGuard(RCleanable::Cleanup, &obj); + + obj.DoSomethingL(); // leave-safe + if (Finished()) + return; // RCleanable::Cleanup is invoked automatically when exiting from scope + obj.DoSomethingElseL(); // leave-safe + // RCleanable::Cleanup is invoked automatically when exiting from scope + } + @endcode + + Behind the scenes, this class template is implemented in terms of + the thread-local CleanupStack, restricting its use to local stack + scope. This use of the CleanupStack ensures a consistent cleanup + order between functions that call one another, even if they use + different cleanup idioms. + + @see LManagedGuard which has the same interface, but does not use the cleanup + stack and is suitable for use as the data member of a class to guard + object destruction. +*/ +class LCleanedupGuard + { + public: +/** + Constructor. Creates a LCleanedupGuard object that, when enabled, + automatically invokes upon destruction a cleanup operation + specified by the aCleanupOperation parameter with the pointer to + data specified by the aData parameter. + + @param aCleanupOperation A cleanup operation. + @param aData Pointer to data to be passed to the cleanup operation + */ + LCleanedupGuard(TCleanupOperation aCleanupOperation, TAny* aData = 0) + : iCleanupOperation(aCleanupOperation), + iData(aData) + { + CleanupStack::PushL(TCleanupItem(Cleanup, this)); + } + +/** + Destructor. + */ + ~LCleanedupGuard() + { + ManagedPopCleanupStackItem(iCleanupOperation); + } + +/** + Executes the guard cleanup operation. +*/ + void Execute() + { + if (iCleanupOperation) + { + iCleanupOperation(iData); + } + } + +/** + Disables the guard. +*/ + void Dismiss() + { + iCleanupOperation = NULL; + } + + static void Cleanup(TAny* aPtr) + { + LCleanedupGuard* guard = static_cast(aPtr); + guard->Execute(); + } + + private: + LCleanedupGuard(const LCleanedupGuard&); + LCleanedupGuard& operator=(const LCleanedupGuard&); + + + TCleanupOperation iCleanupOperation; + TAny* iData; + }; + +#endif // !EMANAGED_H +