--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/epoc32/include/emanaged.h Wed Mar 31 12:33:34 2010 +0100
@@ -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 <e32base.h>
+
+#include <typerel.h>
+#include <swap.h>
+
+
+
+
+/**
+ @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<class T>
+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<typename T>
+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<typename T>
+ 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<class T>
+ 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<class T>
+ 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<class T>
+ 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<class T>
+ 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<class T>
+ 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<typename T>
+ 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<typename T>
+ 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<typename T>
+ 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<typename T,
+ TInt isHandleSpecial = IS_HANDLE_SPECIAL(T)>
+class LAutoHandleBase
+ {
+ protected:
+ LAutoHandleBase()
+ : iEnabled(ETrue)
+ {
+ }
+
+ template<typename Param1>
+ explicit LAutoHandleBase(const Param1& aParam1)
+ : iHandle(aParam1),
+ iEnabled(ETrue)
+ {
+ }
+
+ template<typename Param1>
+ explicit LAutoHandleBase(Param1& aParam1)
+ : iHandle(aParam1),
+ iEnabled(ETrue)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LAutoHandleBase(const Param1& aParam1,
+ const Param2& aParam2)
+ : iHandle(aParam1,
+ aParam2),
+ iEnabled(ETrue)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LAutoHandleBase(Param1& aParam1,
+ const Param2& aParam2)
+ : iHandle(aParam1,
+ aParam2),
+ iEnabled(ETrue)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LAutoHandleBase(const Param1& aParam1,
+ Param2& aParam2)
+ : iHandle(aParam1,
+ aParam2),
+ iEnabled(ETrue)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LAutoHandleBase(Param1& aParam1,
+ Param2& aParam2)
+ : iHandle(aParam1,
+ aParam2),
+ iEnabled(ETrue)
+ {
+ }
+
+ template<typename U>
+ 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<typename T>
+class LAutoHandleBase<T, EAutoRHandleBaseDerived>
+ {
+ protected:
+ LAutoHandleBase()
+ {
+ }
+
+ template<typename Param1>
+ explicit LAutoHandleBase(const Param1& aParam1)
+ : iHandle(aParam1)
+ {
+ }
+
+ template<typename Param1>
+ explicit LAutoHandleBase(Param1& aParam1)
+ : iHandle(aParam1)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LAutoHandleBase(const Param1& aParam1,
+ const Param2& aParam2)
+ : iHandle(aParam1,
+ aParam2)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LAutoHandleBase(Param1& aParam1,
+ const Param2& aParam2)
+ : iHandle(aParam1,
+ aParam2)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LAutoHandleBase(const Param1& aParam1,
+ Param2& aParam2)
+ : iHandle(aParam1,
+ aParam2)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LAutoHandleBase(Param1& aParam1,
+ Param2& aParam2)
+ : iHandle(aParam1,
+ aParam2)
+ {
+ }
+
+ template<typename U>
+ 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<typename T>
+class LAutoHandleBase<T, EAutoHandleRBuf>: 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<RFs> iFileServ;
+ LManagedHandle<RFile> 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<typename T,
+ class CleanupStrategyType = TResourceCleanupStrategy>
+class LManagedHandle: protected LAutoHandleBase<T, IS_HANDLE_SPECIAL(T)>
+ {
+ typedef LAutoHandleBase<T, IS_HANDLE_SPECIAL(T)> LAutoHandleBase;
+
+ public:
+ typedef T ManagedType;
+ typedef CleanupStrategyType CleanupStrategy;
+
+/**
+ Default constructor.
+*/
+ LManagedHandle()
+ {
+ }
+
+ template<typename Param1>
+ explicit LManagedHandle(const Param1& aParam1)
+ : LAutoHandleBase(aParam1)
+ {
+ }
+
+ template<typename Param1>
+ explicit LManagedHandle(Param1& aParam1)
+ : LAutoHandleBase(aParam1)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LManagedHandle(const Param1& aParam1,
+ const Param2& aParam2)
+ : LAutoHandleBase(aParam1,
+ aParam2)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LManagedHandle(const Param1& aParam1,
+ Param2& aParam2)
+ : LAutoHandleBase(aParam1,
+ aParam2)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LManagedHandle(Param1& aParam1,
+ const Param2& aParam2)
+ : LAutoHandleBase(aParam1,
+ aParam2)
+ {
+ }
+
+ template<typename Param1,
+ typename Param2>
+ 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<typename U>
+ 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<typename T>
+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<typename T,
+ class CleanupStrategyType,
+ TInt isPtrSpecial = IS_PTR_SPECIAL(T)>
+struct TPtrCleanupTraits
+ {
+ };
+
+
+// Cleanup traits class template specialization for pointers to types
+// that are not derived from CBase
+template<typename T,
+ class CleanupStrategyType>
+struct TPtrCleanupTraits<T, CleanupStrategyType, EPtrNonSpecial>
+ {
+ typedef T ManagedType;
+ typedef T BaseManagedType;
+ typedef CleanupStrategyType CleanupStrategy;
+ };
+
+// Cleanup traits class template specialization for pointers to types
+// that are derived from CBase
+template<typename T,
+ class CleanupStrategyType>
+struct TPtrCleanupTraits<T, CleanupStrategyType, EPtrCBaseDerived>
+ {
+ 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<typename T>
+struct TPtrCleanupTraits<T, TPtrCleanupStrategy, EPtrCBaseDerived>
+ {
+ typedef CBase ManagedType;
+ typedef CBase BaseManagedType;
+ typedef TPtrCleanupStrategy CleanupStrategy;
+ };
+
+
+/**
+ Implementation base class - not designed for public inheritance or
+ direct use.
+*/
+template<typename T,
+ class CleanupStrategyType>
+class LManagedPtrBase: protected LAutoPtrBase<typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType>
+ {
+ typedef LAutoPtrBase<typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType> LAutoPtrBase;
+
+ protected:
+ typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::ManagedType ManagedType;
+ typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType BaseManagedType;
+ typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::CleanupStrategy CleanupStrategy;
+
+ LManagedPtrBase()
+ {
+ }
+
+ template<typename U>
+ 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<ManagedType*>(iPtr));
+ }
+ }
+
+ template<typename U>
+ 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<ManagedType*>(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<CComponent> 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<typename T,
+ class CleanupStrategyType = TPtrCleanupStrategy>
+class LManagedPtr: protected LManagedPtrBase<T, CleanupStrategyType>
+ {
+ typedef LManagedPtrBase<T, CleanupStrategyType> 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<typename U>
+ 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<T*>(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<T*>(iPtr);
+ }
+
+/**
+ Overloaded indirection operator function.
+
+ @return A reference to the managed object of type T.
+*/
+ T& operator*() const
+ {
+ return *(static_cast<T*>(iPtr));
+ }
+
+/**
+ Overloaded class member access operator function.
+
+ @return A pointer to the managed object of type T.
+*/
+ T* operator->() const
+ {
+ return static_cast<T*>(iPtr);
+ }
+
+
+// Implementation type - do not use
+ typedef typename LManagedPtrBase::BaseManagedType* LManagedPtr<T, CleanupStrategy>::*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<typename T, typename U>
+TBool operator==(const LManagedPtr<T>& aPtr1, const LManagedPtr<U>& aPtr2)
+ {
+ return aPtr1.Get() == aPtr2.Get();
+ }
+
+// function template used for comparing two LManagedPtr-managed
+// pointers for inequality
+template<typename T, typename U>
+TBool operator!=(const LManagedPtr<T>& aPtr1, const LManagedPtr<U>& aPtr2)
+ {
+ return aPtr1.Get() != aPtr2.Get();
+ }
+
+// function template used for testing the ordering of two
+// LManagedPtr-managed pointers
+template<typename T, typename U>
+TBool operator<(const LManagedPtr<T>& aPtr1, const LManagedPtr<U>& 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<CComponent> 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<typename T,
+ class CleanupStrategyType = TArrayDelete>
+class LManagedArray: protected LAutoPtrBase<T>
+ {
+ typedef LAutoPtrBase<T> 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<T*>(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<typename T>
+class LAutoRefBase
+ {
+ protected:
+ template<typename U>
+ explicit LAutoRefBase(U& aRef)
+ : iPtr(&aRef)
+ {
+ }
+
+ template<typename U>
+ 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<RFs> iFileServ;
+ LManagedHandle<RFile> 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<typename T,
+ class CleanupStrategyType = TResourceCleanupStrategy>
+class LManagedRef: protected LAutoRefBase<T>
+ {
+ typedef LAutoRefBase<T> LAutoRefBase;
+
+ public:
+ typedef T ManagedType;
+ typedef CleanupStrategyType CleanupStrategy;
+
+/**
+ Explicit constructor.
+ */
+ template<typename U>
+ 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<typename U>
+ 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<RClosable> 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<typename T,
+ class CleanupStrategyType = TResourceCleanupStrategy>
+class LCleanedupHandle: protected LAutoHandleBase<T, IS_HANDLE_SPECIAL(T)>
+ {
+ typedef LAutoHandleBase<T, IS_HANDLE_SPECIAL(T)> LAutoHandleBase;
+
+ public:
+ typedef T ManagedType;
+ typedef CleanupStrategyType CleanupStrategy;
+
+
+/**
+ Default constructor.
+*/
+ LCleanedupHandle()
+ {
+ CleanupStack::PushL(TCleanupItem(Cleanup, this));
+ }
+
+ template<typename Param1>
+ explicit LCleanedupHandle(const Param1& aParam1)
+ : LAutoHandleBase(aParam1)
+ {
+ CleanupStack::PushL(TCleanupItem(Cleanup, this));
+ }
+
+ template<typename Param1>
+ explicit LCleanedupHandle(Param1& aParam1)
+ : LAutoHandleBase(aParam1)
+ {
+ CleanupStack::PushL(TCleanupItem(Cleanup, this));
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LCleanedupHandle(const Param1& aParam1,
+ const Param2& aParam2)
+ : LAutoHandleBase(aParam1,
+ aParam2)
+ {
+ CleanupStack::PushL(TCleanupItem(Cleanup, this));
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LCleanedupHandle(const Param1& aParam1,
+ Param2& aParam2)
+ : LAutoHandleBase(aParam1,
+ aParam2)
+ {
+ CleanupStack::PushL(TCleanupItem(Cleanup, this));
+ }
+
+ template<typename Param1,
+ typename Param2>
+ LCleanedupHandle(Param1& aParam1,
+ const Param2& aParam2)
+ : LAutoHandleBase(aParam1,
+ aParam2)
+ {
+ CleanupStack::PushL(TCleanupItem(Cleanup, this));
+ }
+
+ template<typename Param1,
+ typename Param2>
+ 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<typename U>
+ 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<LCleanedupHandle*>(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<typename T,
+ class CleanupStrategyType>
+class LCleanedupPtrBase: protected LAutoPtrBase<typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType>
+ {
+ typedef LAutoPtrBase<typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType> LAutoPtrBase;
+
+ protected:
+ typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::ManagedType ManagedType;
+ typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType BaseManagedType;
+ typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::CleanupStrategy CleanupStrategy;
+
+ LCleanedupPtrBase()
+ {
+ CleanupStack::PushL(TCleanupItem(Cleanup, this));
+ }
+
+ template<typename U>
+ explicit LCleanedupPtrBase(U* aPtr)
+ : LAutoPtrBase(aPtr)
+ {
+ CleanupStack::PushL(TCleanupItem(Cleanup, this));
+ }
+
+ ~LCleanedupPtrBase()
+ {
+ ManagedPopCleanupStackItem(LAutoPtrBase::IsEnabled());
+ }
+
+ template<typename U>
+ LCleanedupPtrBase& operator=(U* aPtr)
+ {
+ ReleaseResource();
+ LAutoPtrBase::operator=(aPtr);
+ return *this;
+ }
+
+ void ReleaseResource()
+ {
+ if (!LAutoPtrBase::IsEnabled())
+ return;
+
+ CleanupStrategy::Cleanup(static_cast<ManagedType*>(iPtr));
+ LAutoPtrBase::Disable();
+ }
+
+ using LAutoPtrBase::Unmanage;
+
+ using LAutoPtrBase::IsEnabled;
+
+ using LAutoPtrBase::Get;
+
+ using LAutoPtrBase::operator->;
+
+ static void Cleanup(TAny* aPtr)
+ {
+ LCleanedupPtrBase* cleanupPtr = static_cast<LCleanedupPtrBase*>(aPtr);
+
+ if (cleanupPtr->IsEnabled())
+ {
+ CleanupStrategy::Cleanup(static_cast<ManagedType*>(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<CDynamic> 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<typename T,
+ class CleanupStrategyType = TPtrCleanupStrategy>
+class LCleanedupPtr: protected LCleanedupPtrBase<T, CleanupStrategyType>
+ {
+ typedef LCleanedupPtrBase<T, CleanupStrategyType> 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<typename U>
+ 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<T*>(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<T*>(iPtr);
+ }
+
+/**
+ Overloaded indirection operator function.
+
+ @return A reference to the managed object of type T.
+*/
+ T& operator*() const
+ {
+ return *(static_cast<T*>(iPtr));
+ }
+
+/**
+ Overloaded class member access operator function.
+
+ @return A pointer to the managed object of type T.
+*/
+ T* operator->() const
+ {
+ return static_cast<T*>(iPtr);
+ }
+
+// Implementation type - do not use
+ typedef typename LCleanedupPtrBase::BaseManagedType* LCleanedupPtr<T, CleanupStrategy>::*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<typename T, typename U>
+TBool operator==(const LCleanedupPtr<T>& aPtr1, const LCleanedupPtr<U>& aPtr2)
+ {
+ return aPtr1.Get() == aPtr2.Get();
+ }
+
+// function template used for comparing two LCleanedupPtr-managed
+// pointers for inequality
+template<typename T, typename U>
+TBool operator!=(const LCleanedupPtr<T>& aPtr1, const LCleanedupPtr<U>& aPtr2)
+ {
+ return aPtr1.Get() != aPtr2.Get();
+ }
+
+// function template used for testing the ordering of two
+// LCleanedupPtr-managed pointers
+template<typename T, typename U>
+TBool operator<(const LCleanedupPtr<T>& aPtr1, const LCleanedupPtr<U>& 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<TValue> 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<typename T,
+ class CleanupStrategyType = TArrayDelete>
+class LCleanedupArray: protected LAutoPtrBase<T>
+ {
+ typedef LAutoPtrBase<T> 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<LCleanedupArray*>(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<RClosable> 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<typename T,
+ class CleanupStrategyType = TResourceCleanupStrategy>
+class LCleanedupRef: protected LAutoRefBase<T>
+ {
+ typedef LAutoRefBase<T> LAutoRefBase;
+
+ public:
+ typedef T ManagedType;
+ typedef CleanupStrategyType CleanupStrategy;
+
+/**
+ Explicit constructor.
+ */
+ template<typename U>
+ 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<typename U>
+ 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<LCleanedupRef*>(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<RCleanable> 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<LCleanedupGuard*>(aPtr);
+ guard->Execute();
+ }
+
+ private:
+ LCleanedupGuard(const LCleanedupGuard&);
+ LCleanedupGuard& operator=(const LCleanedupGuard&);
+
+
+ TCleanupOperation iCleanupOperation;
+ TAny* iData;
+ };
+
+#endif // !EMANAGED_H
+