epoc32/include/emanaged.h
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
williamr@4
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
williamr@4
     2
// All rights reserved.
williamr@4
     3
// This component and the accompanying materials are made available
williamr@4
     4
// under the terms of "Eclipse Public License v1.0"
williamr@4
     5
// which accompanies this distribution, and is available
williamr@4
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
williamr@4
     7
//
williamr@4
     8
// Initial Contributors:
williamr@4
     9
// Nokia Corporation - initial contribution.
williamr@4
    10
//
williamr@4
    11
// Contributors:
williamr@4
    12
//
williamr@4
    13
// Description:
williamr@4
    14
//
williamr@4
    15
williamr@4
    16
#ifndef EMANAGED_H
williamr@4
    17
#define EMANAGED_H
williamr@4
    18
williamr@4
    19
#include <e32base.h>
williamr@4
    20
williamr@4
    21
#include <typerel.h>
williamr@4
    22
#include <swap.h>
williamr@4
    23
williamr@4
    24
williamr@4
    25
williamr@4
    26
williamr@4
    27
/**
williamr@4
    28
   @file
williamr@4
    29
   @brief Utility class templates that provide RAII-based automatic
williamr@4
    30
   resource management.
williamr@4
    31
williamr@4
    32
	 @publishedAll
williamr@4
    33
	 @released
williamr@4
    34
*/
williamr@4
    35
williamr@4
    36
williamr@4
    37
  /**
williamr@4
    38
     Implementation function.In order to override the default cleanup
williamr@4
    39
     strategy for a particular type, use the provided
williamr@4
    40
     DEFINE_CLEANUP_FUNCTION utility macro
williamr@4
    41
     @internalComponent
williamr@4
    42
  */
williamr@4
    43
// Not for Client Use , Only to be used Internally.
williamr@4
    44
template<class T>
williamr@4
    45
inline void CallCleanupFunction(T* aObjPtr)
williamr@4
    46
	{
williamr@4
    47
	aObjPtr->Close();
williamr@4
    48
	}
williamr@4
    49
williamr@4
    50
williamr@4
    51
/**
williamr@4
    52
Utility macro that can be used for defining the cleanup member
williamr@4
    53
function for a class (typically a R-class).
williamr@4
    54
williamr@4
    55
This macro can be used in the same namespace in which the R-class is
williamr@4
    56
defined or in a namespace in which the R-class is used.
williamr@4
    57
williamr@4
    58
Example:
williamr@4
    59
williamr@4
    60
class RDestroyableClass
williamr@4
    61
	{
williamr@4
    62
  public:
williamr@4
    63
	// ...
williamr@4
    64
	void Destroy(); // member function used for cleanup and releasing the resources owned by a RDestroyableClass object
williamr@4
    65
	// ...
williamr@4
    66
	};
williamr@4
    67
williamr@4
    68
DEFINE_CLEANUP_FUNCTION(RDestroyableClass, Destroy)
williamr@4
    69
williamr@4
    70
@param AClass the name of the class
williamr@4
    71
@param CleanupMemFun the name of the cleanup member function of the class
williamr@4
    72
 */
williamr@4
    73
#define DEFINE_CLEANUP_FUNCTION(AClass, CleanupMemFun)	\
williamr@4
    74
	inline void CallCleanupFunction(AClass* aObjPtr)	\
williamr@4
    75
		{												\
williamr@4
    76
		aObjPtr->CleanupMemFun();						\
williamr@4
    77
		}
williamr@4
    78
williamr@4
    79
/**
williamr@4
    80
Utility macro that can be used for specializing the default cleanup
williamr@4
    81
strategy class template TResourceCleanupStrategy for a particular
williamr@4
    82
class (typically a R-class).  The default cleanup strategy for a class
williamr@4
    83
specified using DEFINE_CLEANUP_STRATEGY overrides any other cleanup
williamr@4
    84
strategy specified using DEFINE_CLEANUP_FUNCTION for that class.
williamr@4
    85
williamr@4
    86
This macro must be used in the same namespace in which the R-class is
williamr@4
    87
defined.
williamr@4
    88
williamr@4
    89
williamr@4
    90
   Utility macro that can be used for enabling single phase
williamr@4
    91
   construction for CBase-derived classes. This is necessary because
williamr@4
    92
   Symbian OS currently lacks the placement delete operator
williamr@4
    93
   counterparts corresponding to the placement new operators that take
williamr@4
    94
   a TLeave parameter (new(ELeave)), which will result in memory leaks
williamr@4
    95
   if a class constructor leaves.
williamr@4
    96
williamr@4
    97
   This macro must be used within a public section of a class
williamr@4
    98
   definition, if the single phase construction is part of the public
williamr@4
    99
   interface of the class.
williamr@4
   100
williamr@4
   101
   Current Limitation CONSTRUCTORS_MAY_LEAVE is an unfortunate blight on the
williamr@4
   102
   usability of single-phase construction, but we have yet to come up
williamr@4
   103
   with a better alternative in the face of the legacy handling of
williamr@4
   104
   ELeave.
williamr@4
   105
*/
williamr@4
   106
#define CONSTRUCTORS_MAY_LEAVE											\
williamr@4
   107
	static void operator delete(TAny* aPtr) __NO_THROW					\
williamr@4
   108
		{																\
williamr@4
   109
		::operator delete(aPtr);										\
williamr@4
   110
		}																\
williamr@4
   111
																		\
williamr@4
   112
	static void operator delete(TAny*, TAny*) __NO_THROW				\
williamr@4
   113
		{																\
williamr@4
   114
		}																\
williamr@4
   115
																		\
williamr@4
   116
	static void operator delete(TAny* aPtr, TLeave) __NO_THROW			\
williamr@4
   117
		{																\
williamr@4
   118
		::operator delete(aPtr);										\
williamr@4
   119
		}																\
williamr@4
   120
																		\
williamr@4
   121
	static void operator delete(TAny* aPtr, TUint) __NO_THROW			\
williamr@4
   122
		{																\
williamr@4
   123
		::operator delete(aPtr);										\
williamr@4
   124
		}																\
williamr@4
   125
																		\
williamr@4
   126
	static void operator delete(TAny* aPtr, TLeave, TUint) __NO_THROW	\
williamr@4
   127
		{																\
williamr@4
   128
		::operator delete(aPtr);										\
williamr@4
   129
		}																\
williamr@4
   130
																		\
williamr@4
   131
	static void operator delete[](TAny* aPtr) __NO_THROW				\
williamr@4
   132
		{																\
williamr@4
   133
		::operator delete[](aPtr);										\
williamr@4
   134
		}																\
williamr@4
   135
																		\
williamr@4
   136
	static void operator delete[](TAny* aPtr, TLeave) __NO_THROW		\
williamr@4
   137
		{																\
williamr@4
   138
		::operator delete[](aPtr);										\
williamr@4
   139
		}
williamr@4
   140
williamr@4
   141
williamr@4
   142
// Implementation function.
williamr@4
   143
template<typename T>
williamr@4
   144
void ManagedPopCleanupStackItem(T aIsManaged)
williamr@4
   145
	{
williamr@4
   146
// CleanupStack-based cleanup is automatically triggered by a Leave,
williamr@4
   147
// so, in the case when __LEAVE_EQUALS_THROW__,
williamr@4
   148
// CleanupStack::PopAndDestroy must not be called again here
williamr@4
   149
#ifndef __GCCXML__
williamr@4
   150
// for gccxml builds the std::uncaught_exception function is not listed in std name space
williamr@4
   151
// to supress GCCXML error
williamr@4
   152
	if (!std::uncaught_exception())
williamr@4
   153
		{
williamr@4
   154
		if (aIsManaged)
williamr@4
   155
			{
williamr@4
   156
			CleanupStack::PopAndDestroy();
williamr@4
   157
			}
williamr@4
   158
		else
williamr@4
   159
			{
williamr@4
   160
			CleanupStack::Pop();
williamr@4
   161
			}
williamr@4
   162
		}
williamr@4
   163
#endif		
williamr@4
   164
	}
williamr@4
   165
williamr@4
   166
/**
williamr@4
   167
   Strategy (policy) class that defines the default cleanup strategy
williamr@4
   168
   for managed resource class objects.
williamr@4
   169
williamr@4
   170
   The default cleanup strategy is to call the cleanup member function
williamr@4
   171
   of the managed class, which is the Close() member function of the
williamr@4
   172
   managed class, unless explicitly defined otherwise, for example by
williamr@4
   173
   using the provided DEFINE_CLEANUP_FUNCTION macro.
williamr@4
   174
   
williamr@4
   175
   @internalComponent
williamr@4
   176
*/
williamr@4
   177
// Not for Client Use , Only to be used Internally.
williamr@4
   178
class TResourceCleanupStrategy
williamr@4
   179
	{
williamr@4
   180
  public:
williamr@4
   181
	template<typename T>
williamr@4
   182
	static void Cleanup(T* aObjPtr)
williamr@4
   183
		{
williamr@4
   184
		CallCleanupFunction(aObjPtr);
williamr@4
   185
		}
williamr@4
   186
	};
williamr@4
   187
williamr@4
   188
/**
williamr@4
   189
   Strategy (policy) class that defines a cleanup strategy for managed
williamr@4
   190
   resource class objects.  This cleanup strategy calls the Close()
williamr@4
   191
   member function of the managed class.
williamr@4
   192
williamr@4
   193
   @see LCleanedupHandle to which this strategy type may be supplied as
williamr@4
   194
   an (optional) second tamplate parameter
williamr@4
   195
   @see LManagedHandle to which this strategy type may be supplied as
williamr@4
   196
   an (optional) second tamplate parameter
williamr@4
   197
*/
williamr@4
   198
class TClose
williamr@4
   199
	{
williamr@4
   200
  public:
williamr@4
   201
	template<class T>
williamr@4
   202
	static void Cleanup(T* aObjPtr)
williamr@4
   203
		{
williamr@4
   204
		aObjPtr->Close();
williamr@4
   205
		}
williamr@4
   206
	};
williamr@4
   207
williamr@4
   208
/**
williamr@4
   209
   Strategy (policy) class that defines a cleanup strategy for managed
williamr@4
   210
   resource class objects.  This cleanup strategy calls the Release()
williamr@4
   211
   member function of the managed class.
williamr@4
   212
williamr@4
   213
   @see LCleanedupHandle to which this strategy type may be supplied as
williamr@4
   214
   an (optional) second tamplate parameter
williamr@4
   215
   @see LManagedHandle to which this strategy type may be supplied as
williamr@4
   216
   an (optional) second tamplate parameter
williamr@4
   217
*/
williamr@4
   218
class TRelease
williamr@4
   219
	{
williamr@4
   220
  public:
williamr@4
   221
	template<class T>
williamr@4
   222
	static void Cleanup(T* aObjPtr)
williamr@4
   223
		{
williamr@4
   224
		aObjPtr->Release();
williamr@4
   225
		}
williamr@4
   226
	};
williamr@4
   227
williamr@4
   228
/**
williamr@4
   229
   Strategy (policy) class that defines a cleanup strategy for managed
williamr@4
   230
   resource class objects.  This cleanup strategy calls the Destroy()
williamr@4
   231
   member function of the managed class.
williamr@4
   232
williamr@4
   233
   @see LCleanedupHandle to which this strategy type may be supplied as
williamr@4
   234
   an (optional) second tamplate parameter
williamr@4
   235
   @see LManagedHandle to which this strategy type may be supplied as
williamr@4
   236
   an (optional) second tamplate parameter
williamr@4
   237
*/
williamr@4
   238
class TDestroy
williamr@4
   239
	{
williamr@4
   240
  public:
williamr@4
   241
	template<class T>
williamr@4
   242
	static void Cleanup(T* aObjPtr)
williamr@4
   243
		{
williamr@4
   244
		aObjPtr->Destroy();
williamr@4
   245
		}
williamr@4
   246
	};
williamr@4
   247
williamr@4
   248
/**
williamr@4
   249
   Strategy (policy) class that defines a cleanup strategy for managed
williamr@4
   250
   resource class objects.  This cleanup strategy calls the Free()
williamr@4
   251
   member function of the managed class.
williamr@4
   252
williamr@4
   253
   @see LCleanedupHandle to which this strategy type may be supplied as
williamr@4
   254
   an (optional) second tamplate parameter
williamr@4
   255
   @see LManagedHandle to which this strategy type may be supplied as
williamr@4
   256
   an (optional) second tamplate parameter
williamr@4
   257
*/
williamr@4
   258
class TFree
williamr@4
   259
	{
williamr@4
   260
  public:
williamr@4
   261
	template<class T>
williamr@4
   262
	static void Cleanup(T* aObjPtr)
williamr@4
   263
		{
williamr@4
   264
		aObjPtr->Free();
williamr@4
   265
		}
williamr@4
   266
	};
williamr@4
   267
williamr@4
   268
/**
williamr@4
   269
   Strategy (policy) class that defines a cleanup strategy for managed
williamr@4
   270
   resource class objects.  This cleanup strategy calls the
williamr@4
   271
   ResetAndDestroy() member function of the managed class.
williamr@4
   272
williamr@4
   273
   @see LCleanedupHandle to which this strategy type may be supplied as
williamr@4
   274
   an (optional) second tamplate parameter
williamr@4
   275
   @see LManagedHandle to which this strategy type may be supplied as
williamr@4
   276
   an (optional) second tamplate parameter
williamr@4
   277
*/
williamr@4
   278
class TResetAndDestroy
williamr@4
   279
	{
williamr@4
   280
  public:
williamr@4
   281
	template<class T>
williamr@4
   282
	static void Cleanup(T* aObjPtr)
williamr@4
   283
		{
williamr@4
   284
		aObjPtr->ResetAndDestroy();
williamr@4
   285
		}
williamr@4
   286
	};
williamr@4
   287
williamr@4
   288
williamr@4
   289
/**
williamr@4
   290
   Strategy (policy) class that defines the default cleanup strategy
williamr@4
   291
   for pointer types.  For pointers to CBase-derived types, the
williamr@4
   292
   default cleanup strategy is to call CBase::Delete with the managed
williamr@4
   293
   pointer.  For pointers to types that are not derived from CBase,
williamr@4
   294
   the default cleanup strategy is to delete the managed pointer using
williamr@4
   295
   non-array delete.
williamr@4
   296
williamr@4
   297
   @see LCleanedupPtr to which this strategy type may be supplied as
williamr@4
   298
   an (optional) second tamplate parameter
williamr@4
   299
   @see LManagedPtr to which this strategy type may be supplied as
williamr@4
   300
   an (optional) second tamplate parameter
williamr@4
   301
*/
williamr@4
   302
class TPtrCleanupStrategy
williamr@4
   303
	{
williamr@4
   304
  public:
williamr@4
   305
	template<typename T>
williamr@4
   306
	static void Cleanup(T* aPtr)
williamr@4
   307
		{
williamr@4
   308
		delete aPtr;
williamr@4
   309
		}
williamr@4
   310
williamr@4
   311
	static void Cleanup(CBase* aPtr)
williamr@4
   312
		{
williamr@4
   313
		CBase::Delete(aPtr);
williamr@4
   314
		}
williamr@4
   315
	};
williamr@4
   316
williamr@4
   317
williamr@4
   318
/**
williamr@4
   319
   Strategy (policy) class that defines a cleanup strategy for pointer
williamr@4
   320
   types.  This cleanup strategy deletes the managed pointer by using
williamr@4
   321
   non-array delete.
williamr@4
   322
williamr@4
   323
   @see LCleanedupPtr to which this strategy type may be supplied as
williamr@4
   324
   an (optional) second tamplate parameter
williamr@4
   325
   @see LManagedPtr to which this strategy type may be supplied as
williamr@4
   326
   an (optional) second tamplate parameter
williamr@4
   327
*/
williamr@4
   328
class TPointerDeleteStrategy
williamr@4
   329
	{
williamr@4
   330
  public:
williamr@4
   331
	template<typename T>
williamr@4
   332
	static void Cleanup(T* aPtr)
williamr@4
   333
		{
williamr@4
   334
		delete aPtr;
williamr@4
   335
		}
williamr@4
   336
	};
williamr@4
   337
williamr@4
   338
williamr@4
   339
/**
williamr@4
   340
   Strategy (policy) class that defines a cleanup strategy for
williamr@4
   341
   pointers to CBase-derived types.  This cleanup strategy calls
williamr@4
   342
   CBase::Delete with the managed pointer.
williamr@4
   343
williamr@4
   344
   @see LCleanedupPtr to which this strategy type may be supplied as
williamr@4
   345
   an (optional) second tamplate parameter
williamr@4
   346
   @see LManagedPtr to which this strategy type may be supplied as
williamr@4
   347
   an (optional) second tamplate parameter
williamr@4
   348
*/
williamr@4
   349
class TCBaseDeleteStrategy
williamr@4
   350
	{
williamr@4
   351
  public:
williamr@4
   352
	static void Cleanup(CBase* aPtr)
williamr@4
   353
		{
williamr@4
   354
		CBase::Delete(aPtr);
williamr@4
   355
		}
williamr@4
   356
	};
williamr@4
   357
williamr@4
   358
williamr@4
   359
/**
williamr@4
   360
   Strategy (policy) class that defines a cleanup strategy for pointer
williamr@4
   361
   types.  This cleanup strategy calls User::Free with the managed
williamr@4
   362
   pointer.
williamr@4
   363
williamr@4
   364
   @see LCleanedupPtr to which this strategy type may be supplied as
williamr@4
   365
   an (optional) second tamplate parameter
williamr@4
   366
   @see LManagedPtr to which this strategy type may be supplied as
williamr@4
   367
   an (optional) second tamplate parameter
williamr@4
   368
*/
williamr@4
   369
class TPointerFree
williamr@4
   370
	{
williamr@4
   371
  public:
williamr@4
   372
	static void Cleanup(TAny* aPtr)
williamr@4
   373
		{
williamr@4
   374
		User::Free(aPtr);
williamr@4
   375
		}
williamr@4
   376
	};
williamr@4
   377
williamr@4
   378
williamr@4
   379
/**
williamr@4
   380
   Strategy (policy) class that defines the default cleanup strategy
williamr@4
   381
   for heap-allocated arrays.  This cleanup strategy deallocates the
williamr@4
   382
   managed array by using array delete.
williamr@4
   383
*/
williamr@4
   384
class TArrayDelete
williamr@4
   385
	{
williamr@4
   386
  public:
williamr@4
   387
	template<typename T>
williamr@4
   388
	static void Cleanup(T* aPtr)
williamr@4
   389
		{
williamr@4
   390
		delete[] aPtr;
williamr@4
   391
		}
williamr@4
   392
	};
williamr@4
   393
williamr@4
   394
williamr@4
   395
// enum type used for identifying the categories of managed pointer types
williamr@4
   396
enum TManagedPtrType
williamr@4
   397
{
williamr@4
   398
	EPtrNonSpecial,
williamr@4
   399
	EPtrCBaseDerived
williamr@4
   400
};
williamr@4
   401
williamr@4
   402
williamr@4
   403
// macro used for determining whether a pointer is special
williamr@4
   404
#define IS_PTR_SPECIAL(T) IS_BASE_OF(CBase, T)
williamr@4
   405
williamr@4
   406
williamr@4
   407
// enum type used for identifying the categories of resource handle types
williamr@4
   408
enum TAutoHandleType
williamr@4
   409
{
williamr@4
   410
	EAutoHandleNonSpecial,
williamr@4
   411
	EAutoRHandleBaseDerived,
williamr@4
   412
	EAutoHandleRBuf
williamr@4
   413
};
williamr@4
   414
williamr@4
   415
williamr@4
   416
// macro used for determining whether a resource handle type is special
williamr@4
   417
#define IS_HANDLE_SPECIAL(T) IS_BASE_OF(RHandleBase, T) ? EAutoRHandleBaseDerived : ( (IS_SAME(RBuf8, T) || IS_SAME(RBuf16, T)) ? EAutoHandleRBuf : EAutoHandleNonSpecial )
williamr@4
   418
williamr@4
   419
williamr@4
   420
/**
williamr@4
   421
   Implementation base class - not designed for public inheritance or
williamr@4
   422
   direct use.
williamr@4
   423
   
williamr@4
   424
   @internalComponent
williamr@4
   425
*/
williamr@4
   426
// Not for Client Use , Only to be used Internally.
williamr@4
   427
template<typename T,
williamr@4
   428
		 TInt isHandleSpecial = IS_HANDLE_SPECIAL(T)>
williamr@4
   429
class LAutoHandleBase
williamr@4
   430
	{
williamr@4
   431
  protected:
williamr@4
   432
	LAutoHandleBase()
williamr@4
   433
		: iEnabled(ETrue)
williamr@4
   434
		{
williamr@4
   435
		}
williamr@4
   436
williamr@4
   437
	template<typename Param1>
williamr@4
   438
	explicit LAutoHandleBase(const Param1& aParam1)
williamr@4
   439
		: iHandle(aParam1),
williamr@4
   440
		  iEnabled(ETrue)
williamr@4
   441
		{
williamr@4
   442
		}
williamr@4
   443
williamr@4
   444
	template<typename Param1>
williamr@4
   445
	explicit LAutoHandleBase(Param1& aParam1)
williamr@4
   446
		: iHandle(aParam1),
williamr@4
   447
		  iEnabled(ETrue)
williamr@4
   448
		{
williamr@4
   449
		}
williamr@4
   450
williamr@4
   451
	template<typename Param1,
williamr@4
   452
			 typename Param2>
williamr@4
   453
	LAutoHandleBase(const Param1& aParam1,
williamr@4
   454
					const Param2& aParam2)
williamr@4
   455
		: iHandle(aParam1,
williamr@4
   456
				  aParam2),
williamr@4
   457
		  iEnabled(ETrue)
williamr@4
   458
		{
williamr@4
   459
		}
williamr@4
   460
williamr@4
   461
	template<typename Param1,
williamr@4
   462
			 typename Param2>
williamr@4
   463
	LAutoHandleBase(Param1& aParam1,
williamr@4
   464
					const Param2& aParam2)
williamr@4
   465
		: iHandle(aParam1,
williamr@4
   466
				  aParam2),
williamr@4
   467
		  iEnabled(ETrue)
williamr@4
   468
		{
williamr@4
   469
		}
williamr@4
   470
williamr@4
   471
	template<typename Param1,
williamr@4
   472
			 typename Param2>
williamr@4
   473
	LAutoHandleBase(const Param1& aParam1,
williamr@4
   474
					Param2& aParam2)
williamr@4
   475
		: iHandle(aParam1,
williamr@4
   476
				  aParam2),
williamr@4
   477
		  iEnabled(ETrue)
williamr@4
   478
		{
williamr@4
   479
		}
williamr@4
   480
williamr@4
   481
	template<typename Param1,
williamr@4
   482
			 typename Param2>
williamr@4
   483
	LAutoHandleBase(Param1& aParam1,
williamr@4
   484
					Param2& aParam2)
williamr@4
   485
		: iHandle(aParam1,
williamr@4
   486
				  aParam2),
williamr@4
   487
		  iEnabled(ETrue)
williamr@4
   488
		{
williamr@4
   489
		}
williamr@4
   490
williamr@4
   491
	template<typename U>
williamr@4
   492
	LAutoHandleBase& operator=(const U& aHandle)
williamr@4
   493
		{
williamr@4
   494
		iHandle = aHandle;
williamr@4
   495
		iEnabled = ETrue;
williamr@4
   496
		return *this;
williamr@4
   497
		}
williamr@4
   498
williamr@4
   499
	T& Get()
williamr@4
   500
		{
williamr@4
   501
		return iHandle;
williamr@4
   502
		}
williamr@4
   503
williamr@4
   504
	const T& Get() const
williamr@4
   505
		{
williamr@4
   506
		return iHandle;
williamr@4
   507
		}
williamr@4
   508
williamr@4
   509
	T& operator*()
williamr@4
   510
		{
williamr@4
   511
		return iHandle;
williamr@4
   512
		}
williamr@4
   513
williamr@4
   514
	const T& operator*() const
williamr@4
   515
		{
williamr@4
   516
		return iHandle;
williamr@4
   517
		}
williamr@4
   518
williamr@4
   519
	T* operator->()
williamr@4
   520
		{
williamr@4
   521
		return &iHandle;
williamr@4
   522
		}
williamr@4
   523
williamr@4
   524
	const T* operator->() const
williamr@4
   525
		{
williamr@4
   526
		return &iHandle;
williamr@4
   527
		}
williamr@4
   528
williamr@4
   529
	T Unmanage()
williamr@4
   530
		{
williamr@4
   531
		iEnabled = EFalse;
williamr@4
   532
		return iHandle;
williamr@4
   533
		}
williamr@4
   534
williamr@4
   535
	TBool IsEnabled() const
williamr@4
   536
		{
williamr@4
   537
		return iEnabled;
williamr@4
   538
		}
williamr@4
   539
williamr@4
   540
	void Disable()
williamr@4
   541
		{
williamr@4
   542
		iEnabled = EFalse;
williamr@4
   543
		}
williamr@4
   544
williamr@4
   545
	void Swap(LAutoHandleBase& aAutoHandle)
williamr@4
   546
		{
williamr@4
   547
		::Swap(iHandle, aAutoHandle.iHandle);
williamr@4
   548
		::Swap(iEnabled, aAutoHandle.iEnabled);
williamr@4
   549
		}
williamr@4
   550
williamr@4
   551
  protected:
williamr@4
   552
	T iHandle;
williamr@4
   553
	TBool iEnabled;
williamr@4
   554
williamr@4
   555
  private:
williamr@4
   556
	LAutoHandleBase(const LAutoHandleBase&);
williamr@4
   557
	LAutoHandleBase& operator=(const LAutoHandleBase&);
williamr@4
   558
	};
williamr@4
   559
williamr@4
   560
williamr@4
   561
/**
williamr@4
   562
   Implementation base class - not designed for public inheritance or
williamr@4
   563
   direct use.  Specialization for types derived from RHandleBase.
williamr@4
   564
*/
williamr@4
   565
template<typename T>
williamr@4
   566
class LAutoHandleBase<T, EAutoRHandleBaseDerived>
williamr@4
   567
	{
williamr@4
   568
  protected:
williamr@4
   569
	LAutoHandleBase()
williamr@4
   570
		{
williamr@4
   571
		}
williamr@4
   572
williamr@4
   573
	template<typename Param1>
williamr@4
   574
	explicit LAutoHandleBase(const Param1& aParam1)
williamr@4
   575
		: iHandle(aParam1)
williamr@4
   576
		{
williamr@4
   577
		}
williamr@4
   578
williamr@4
   579
	template<typename Param1>
williamr@4
   580
	explicit LAutoHandleBase(Param1& aParam1)
williamr@4
   581
		: iHandle(aParam1)
williamr@4
   582
		{
williamr@4
   583
		}
williamr@4
   584
williamr@4
   585
	template<typename Param1,
williamr@4
   586
			 typename Param2>
williamr@4
   587
	LAutoHandleBase(const Param1& aParam1,
williamr@4
   588
					const Param2& aParam2)
williamr@4
   589
		: iHandle(aParam1,
williamr@4
   590
				  aParam2)
williamr@4
   591
		{
williamr@4
   592
		}
williamr@4
   593
williamr@4
   594
	template<typename Param1,
williamr@4
   595
			 typename Param2>
williamr@4
   596
	LAutoHandleBase(Param1& aParam1,
williamr@4
   597
					const Param2& aParam2)
williamr@4
   598
		: iHandle(aParam1,
williamr@4
   599
				  aParam2)
williamr@4
   600
		{
williamr@4
   601
		}
williamr@4
   602
williamr@4
   603
	template<typename Param1,
williamr@4
   604
			 typename Param2>
williamr@4
   605
	LAutoHandleBase(const Param1& aParam1,
williamr@4
   606
					Param2& aParam2)
williamr@4
   607
		: iHandle(aParam1,
williamr@4
   608
				  aParam2)
williamr@4
   609
		{
williamr@4
   610
		}
williamr@4
   611
williamr@4
   612
	template<typename Param1,
williamr@4
   613
			 typename Param2>
williamr@4
   614
	LAutoHandleBase(Param1& aParam1,
williamr@4
   615
					Param2& aParam2)
williamr@4
   616
		: iHandle(aParam1,
williamr@4
   617
				  aParam2)
williamr@4
   618
		{
williamr@4
   619
		}
williamr@4
   620
williamr@4
   621
	template<typename U>
williamr@4
   622
	LAutoHandleBase& operator=(const U& aHandle)
williamr@4
   623
		{
williamr@4
   624
		iHandle = aHandle;
williamr@4
   625
		return *this;
williamr@4
   626
		}
williamr@4
   627
williamr@4
   628
	T& Get()
williamr@4
   629
		{
williamr@4
   630
		return iHandle;
williamr@4
   631
		}
williamr@4
   632
williamr@4
   633
	const T& Get() const
williamr@4
   634
		{
williamr@4
   635
		return iHandle;
williamr@4
   636
		}
williamr@4
   637
williamr@4
   638
	T& operator*()
williamr@4
   639
		{
williamr@4
   640
		return iHandle;
williamr@4
   641
		}
williamr@4
   642
williamr@4
   643
	const T& operator*() const
williamr@4
   644
		{
williamr@4
   645
		return iHandle;
williamr@4
   646
		}
williamr@4
   647
williamr@4
   648
	T* operator->()
williamr@4
   649
		{
williamr@4
   650
		return &iHandle;
williamr@4
   651
		}
williamr@4
   652
williamr@4
   653
	const T* operator->() const
williamr@4
   654
		{
williamr@4
   655
		return &iHandle;
williamr@4
   656
		}
williamr@4
   657
williamr@4
   658
	T Unmanage()
williamr@4
   659
		{
williamr@4
   660
		T handle = iHandle;
williamr@4
   661
		iHandle.SetHandle(KNullHandle);
williamr@4
   662
		return handle;
williamr@4
   663
		}
williamr@4
   664
williamr@4
   665
	TBool IsEnabled() const
williamr@4
   666
		{
williamr@4
   667
		return iHandle.Handle() != KNullHandle;
williamr@4
   668
		}
williamr@4
   669
williamr@4
   670
	void Disable()
williamr@4
   671
		{
williamr@4
   672
		iHandle.SetHandle(KNullHandle);
williamr@4
   673
		}
williamr@4
   674
williamr@4
   675
	void Swap(LAutoHandleBase& aAutoHandle)
williamr@4
   676
		{
williamr@4
   677
		::Swap(iHandle, aAutoHandle.iHandle);
williamr@4
   678
		}
williamr@4
   679
williamr@4
   680
  protected:
williamr@4
   681
	T iHandle;
williamr@4
   682
williamr@4
   683
  private:
williamr@4
   684
	LAutoHandleBase(const LAutoHandleBase&);
williamr@4
   685
	LAutoHandleBase& operator=(const LAutoHandleBase&);
williamr@4
   686
	};
williamr@4
   687
williamr@4
   688
williamr@4
   689
// N.B. RBuf8, RBuf16 and RBuf cannot be used with LManagedHandle and
williamr@4
   690
// LCleanedupHandle.  Use LString or managed references instead.
williamr@4
   691
// The following specialization must not be used.
williamr@4
   692
template<typename T>
williamr@4
   693
class LAutoHandleBase<T, EAutoHandleRBuf>: protected T
williamr@4
   694
	{
williamr@4
   695
  private:
williamr@4
   696
	LAutoHandleBase()
williamr@4
   697
		{
williamr@4
   698
		}
williamr@4
   699
williamr@4
   700
	~LAutoHandleBase()
williamr@4
   701
		{
williamr@4
   702
		}
williamr@4
   703
	};
williamr@4
   704
williamr@4
   705
williamr@4
   706
/**
williamr@4
   707
   A class template for the creation and automatic management of
williamr@4
   708
   resource handles (typically R-class instances) held in the data
williamr@4
   709
   members of objects.
williamr@4
   710
williamr@4
   711
   @note This class should not used to define locals. See below for
williamr@4
   712
   an explanation and links to management classes suitable for use in
williamr@4
   713
   that context.
williamr@4
   714
williamr@4
   715
   This class template can be used to protect a resource handle of
williamr@4
   716
   type T (typically an R-class instance) such that the instance of T
williamr@4
   717
   protected is automatically cleaned up when the management object is
williamr@4
   718
   destroyed; typically when the object containing it is deleted.
williamr@4
   719
williamr@4
   720
   By default, the cleanup action is to call the Close() member
williamr@4
   721
   function of the managed handle. An alternative cleanup strategy may
williamr@4
   722
   be selected by specifying a cleanup strategy template class in the
williamr@4
   723
   optional second template parameter position. The most common
williamr@4
   724
   alternative cleanup strategies are predefined. It is also possible
williamr@4
   725
   to specialize the default cleanup action for a given class using
williamr@4
   726
   the DEFINE_CLEANUP_FUNCTION macro.
williamr@4
   727
williamr@4
   728
   The constructors of this class never leave (unless construction of
williamr@4
   729
   the underlying T instance can leave, which is rare), so data
williamr@4
   730
   members defined with this type may be initialized safely during any
williamr@4
   731
   phase of construction of the owning class.
williamr@4
   732
williamr@4
   733
   Any arguments supplied when initializing an instance of this class
williamr@4
   734
   are automatically passed through to T's constructors.
williamr@4
   735
williamr@4
   736
   As a convenience, the methods of the managed pointer may be
williamr@4
   737
   accessed via "->" notation directly on the management object, while
williamr@4
   738
   "." notation is used to access the interface of the management
williamr@4
   739
   object itself. Using "*" to dereference the management object
williamr@4
   740
   yields a T&, and is often useful when passing the managed object as
williamr@4
   741
   an argument.
williamr@4
   742
williamr@4
   743
   Automatic cleanup may be disabled at any time by calling
williamr@4
   744
   Unmanage(), while cleanup may be forced at any time by calling
williamr@4
   745
   ReleaseResource().
williamr@4
   746
williamr@4
   747
   Example:
williamr@4
   748
   @code
williamr@4
   749
   class CComposite : public CBase
williamr@4
   750
	   {
williamr@4
   751
	 public:
williamr@4
   752
	   CONSTRUCTORS_MAY_LEAVE
williamr@4
   753
williamr@4
   754
	   CComposite()
williamr@4
   755
		   {
williamr@4
   756
		   iFileServ->Connect() OR_LEAVE;
williamr@4
   757
		   iFile->Open(*iFileServ, ...);
williamr@4
   758
		   }
williamr@4
   759
williamr@4
   760
	   ~CComposite()
williamr@4
   761
		   {
williamr@4
   762
		   // the handles are automatically closed
williamr@4
   763
		   }
williamr@4
   764
williamr@4
   765
	 private:
williamr@4
   766
williamr@4
   767
	   LManagedHandle<RFs> iFileServ;
williamr@4
   768
	   LManagedHandle<RFile> iFile;
williamr@4
   769
	   };
williamr@4
   770
   @endcode
williamr@4
   771
williamr@4
   772
   Behind the scenes, this class template simply relies on reliable
williamr@4
   773
   execution of its destructor. If used for a local variable rather
williamr@4
   774
   than a data member, cleanup will occur but out-of-order compared to
williamr@4
   775
   objects protected using the LCleanupXxx variants or the
williamr@4
   776
   CleanupStack directly. Therefore it is not recommended for use in
williamr@4
   777
   that context.
williamr@4
   778
williamr@4
   779
   These management classes may be used as the basis for implementing
williamr@4
   780
   leave-safe single-phase construction, since fully initialized
williamr@4
   781
   data members protected in this way will get destroyed (so reliably
williamr@4
   782
   triggering cleanup) if their containing classes leave during
williamr@4
   783
   execution of their constructors. Note, however, that single-phase
williamr@4
   784
   construction must be explicitly enabled in the containing class
williamr@4
   785
   using the CONSTRUCTORS_MAY_LEAVE macro.
williamr@4
   786
williamr@4
   787
   This class template together with the cleanup strategy class
williamr@4
   788
   templates provide a template-based implementation of the Strategy
williamr@4
   789
   design pattern (See also: Policy-based design).
williamr@4
   790
williamr@4
   791
   @see TClose which implements the default Close() calling cleanup strategy
williamr@4
   792
   @see TResetAndDestroy which implements an alternative
williamr@4
   793
   ResetAndDestroy() calling cleanup strategy
williamr@4
   794
   @see TFree which implements an alternative Free() calling cleanup
williamr@4
   795
   strategy
williamr@4
   796
   @see TDestroy which implements an alternative Destroy() calling
williamr@4
   797
   cleanup strategy
williamr@4
   798
   @see TRelease which implements an alternative Release() calling cleanup strategy
williamr@4
   799
   @see LCleanedupHandle which has the same interface, but uses the cleanup
williamr@4
   800
   stack and is suitable for protecting locals
williamr@4
   801
   @see CONSTRUCTORS_MAY_LEAVE
williamr@4
   802
*/
williamr@4
   803
template<typename T,
williamr@4
   804
		 class CleanupStrategyType = TResourceCleanupStrategy>
williamr@4
   805
class LManagedHandle: protected LAutoHandleBase<T, IS_HANDLE_SPECIAL(T)>
williamr@4
   806
	{
williamr@4
   807
	typedef LAutoHandleBase<T, IS_HANDLE_SPECIAL(T)> LAutoHandleBase;
williamr@4
   808
williamr@4
   809
  public:
williamr@4
   810
	typedef T ManagedType;
williamr@4
   811
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
   812
williamr@4
   813
/**
williamr@4
   814
   Default constructor.
williamr@4
   815
*/
williamr@4
   816
	LManagedHandle()
williamr@4
   817
		{
williamr@4
   818
		}
williamr@4
   819
williamr@4
   820
	template<typename Param1>
williamr@4
   821
	explicit LManagedHandle(const Param1& aParam1)
williamr@4
   822
		: LAutoHandleBase(aParam1)
williamr@4
   823
		{
williamr@4
   824
		}
williamr@4
   825
williamr@4
   826
	template<typename Param1>
williamr@4
   827
	explicit LManagedHandle(Param1& aParam1)
williamr@4
   828
		: LAutoHandleBase(aParam1)
williamr@4
   829
		{
williamr@4
   830
		}
williamr@4
   831
williamr@4
   832
	template<typename Param1,
williamr@4
   833
			 typename Param2>
williamr@4
   834
	LManagedHandle(const Param1& aParam1,
williamr@4
   835
				   const Param2& aParam2)
williamr@4
   836
		: LAutoHandleBase(aParam1,
williamr@4
   837
					   aParam2)
williamr@4
   838
		{
williamr@4
   839
		}
williamr@4
   840
williamr@4
   841
	template<typename Param1,
williamr@4
   842
			 typename Param2>
williamr@4
   843
	LManagedHandle(const Param1& aParam1,
williamr@4
   844
				   Param2& aParam2)
williamr@4
   845
		: LAutoHandleBase(aParam1,
williamr@4
   846
					   aParam2)
williamr@4
   847
		{
williamr@4
   848
		}
williamr@4
   849
williamr@4
   850
	template<typename Param1,
williamr@4
   851
			 typename Param2>
williamr@4
   852
	LManagedHandle(Param1& aParam1,
williamr@4
   853
				   const Param2& aParam2)
williamr@4
   854
		: LAutoHandleBase(aParam1,
williamr@4
   855
					   aParam2)
williamr@4
   856
		{
williamr@4
   857
		}
williamr@4
   858
williamr@4
   859
	template<typename Param1,
williamr@4
   860
			 typename Param2>
williamr@4
   861
	LManagedHandle(Param1& aParam1,
williamr@4
   862
				   Param2& aParam2)
williamr@4
   863
		: LAutoHandleBase(aParam1,
williamr@4
   864
					   aParam2)
williamr@4
   865
		{
williamr@4
   866
		}
williamr@4
   867
williamr@4
   868
/**
williamr@4
   869
   Assigns a new resource to be managed.  If the LManagedHandle object
williamr@4
   870
   already contains a managed resource handle, then the managed
williamr@4
   871
   resource is released using the specified cleanup strategy before
williamr@4
   872
   assigning the new managed resource.
williamr@4
   873
williamr@4
   874
   @param aHandle a reference to a handle object of a type that can be assigned to a handle object of type T
williamr@4
   875
 */
williamr@4
   876
	template<typename U>
williamr@4
   877
	LManagedHandle& operator=(const U& aHandle)
williamr@4
   878
		{
williamr@4
   879
		ReleaseResource();
williamr@4
   880
		LAutoHandleBase::operator=(aHandle);
williamr@4
   881
		return *this;
williamr@4
   882
		}
williamr@4
   883
williamr@4
   884
/**
williamr@4
   885
   Destructor.	When automatic resource management is enabled, the
williamr@4
   886
   destructor calls the cleanup function defined by the cleanup
williamr@4
   887
   strategy with the contained resource handle object.
williamr@4
   888
 */
williamr@4
   889
	~LManagedHandle()
williamr@4
   890
		{
williamr@4
   891
		if (IsEnabled())
williamr@4
   892
			{
williamr@4
   893
			CleanupStrategy::Cleanup(&Get());
williamr@4
   894
			}
williamr@4
   895
		}
williamr@4
   896
williamr@4
   897
/**
williamr@4
   898
   If automatic resource management is enabled, calls the cleanup
williamr@4
   899
   function defined by the cleanup strategy with the managed resource
williamr@4
   900
   handle object and then disables the automatic resource management
williamr@4
   901
   for this object.	 The cleanup strategy is specified by the
williamr@4
   902
   CleanupStrategy template template parameter.	 The default cleanup
williamr@4
   903
   strategy is to call the cleanup member function on the contained
williamr@4
   904
   resource handle object. which is a member function named Close(),
williamr@4
   905
   unless explicitly defined otherwise for the class of the object,
williamr@4
   906
   for example by using the provided DEFINE_CLEANUP_FUNCTION macro.
williamr@4
   907
*/
williamr@4
   908
	void ReleaseResource()
williamr@4
   909
		{
williamr@4
   910
		if (!IsEnabled())
williamr@4
   911
			return;
williamr@4
   912
williamr@4
   913
		CleanupStrategy::Cleanup(&Get());
williamr@4
   914
		LAutoHandleBase::Disable();
williamr@4
   915
		}
williamr@4
   916
williamr@4
   917
/**
williamr@4
   918
   Disables the automatic resource management for this object and
williamr@4
   919
   returns a copy of the resource handle.
williamr@4
   920
williamr@4
   921
   @return A copy of the resource handle.
williamr@4
   922
*/
williamr@4
   923
	using LAutoHandleBase::Unmanage;
williamr@4
   924
williamr@4
   925
/**
williamr@4
   926
   Returns ETrue if automatic resource management is enabled; EFalse
williamr@4
   927
   otherwise.
williamr@4
   928
williamr@4
   929
   @return ETrue if automatic resource management is enabled; EFalse
williamr@4
   930
   otherwise.
williamr@4
   931
*/
williamr@4
   932
	using LAutoHandleBase::IsEnabled;
williamr@4
   933
williamr@4
   934
/**
williamr@4
   935
   Returns a reference to the resource handle.
williamr@4
   936
williamr@4
   937
   @return A reference to the resource handle.
williamr@4
   938
*/
williamr@4
   939
	using LAutoHandleBase::Get;
williamr@4
   940
williamr@4
   941
/**
williamr@4
   942
   Overloaded indirection operator function.
williamr@4
   943
williamr@4
   944
   @return A reference to the resource handle.
williamr@4
   945
*/
williamr@4
   946
	using LAutoHandleBase::operator*;
williamr@4
   947
williamr@4
   948
/**
williamr@4
   949
   Overloaded class member access operator function.
williamr@4
   950
williamr@4
   951
   @return A pointer to the resource handle.
williamr@4
   952
*/
williamr@4
   953
	using LAutoHandleBase::operator->;
williamr@4
   954
williamr@4
   955
	using LAutoHandleBase::Disable;
williamr@4
   956
williamr@4
   957
	void Swap(LManagedHandle& aManagedHandle)
williamr@4
   958
		{
williamr@4
   959
		LAutoHandleBase::Swap(aManagedHandle);
williamr@4
   960
		}
williamr@4
   961
	};
williamr@4
   962
williamr@4
   963
williamr@4
   964
/**
williamr@4
   965
   Implementation base class - not designed for public inheritance or
williamr@4
   966
   direct use.
williamr@4
   967
   
williamr@4
   968
   @internalComponent
williamr@4
   969
*/
williamr@4
   970
// Not for Client Use , Only to be used Internally.
williamr@4
   971
template<typename T>
williamr@4
   972
class LAutoPtrBase
williamr@4
   973
	{
williamr@4
   974
  protected:
williamr@4
   975
	LAutoPtrBase()
williamr@4
   976
		: iPtr(NULL)
williamr@4
   977
		{
williamr@4
   978
		}
williamr@4
   979
williamr@4
   980
	explicit LAutoPtrBase(T* aPtr)
williamr@4
   981
		: iPtr(aPtr)
williamr@4
   982
		{
williamr@4
   983
		}
williamr@4
   984
williamr@4
   985
	LAutoPtrBase& operator=(T* aPtr)
williamr@4
   986
		{
williamr@4
   987
		iPtr = aPtr;
williamr@4
   988
		return *this;
williamr@4
   989
		}
williamr@4
   990
williamr@4
   991
	T* Unmanage()
williamr@4
   992
		{
williamr@4
   993
		T* ptr = iPtr;
williamr@4
   994
		iPtr = NULL;
williamr@4
   995
		return ptr;
williamr@4
   996
		}
williamr@4
   997
williamr@4
   998
	TBool IsEnabled() const
williamr@4
   999
		{
williamr@4
  1000
		return iPtr != NULL;
williamr@4
  1001
		}
williamr@4
  1002
williamr@4
  1003
	T* Get() const
williamr@4
  1004
		{
williamr@4
  1005
		return iPtr;
williamr@4
  1006
		}
williamr@4
  1007
williamr@4
  1008
	T* operator->() const
williamr@4
  1009
		{
williamr@4
  1010
		return iPtr;
williamr@4
  1011
		}
williamr@4
  1012
williamr@4
  1013
	void Disable()
williamr@4
  1014
		{
williamr@4
  1015
		iPtr = NULL;
williamr@4
  1016
		}
williamr@4
  1017
williamr@4
  1018
	void Swap(LAutoPtrBase& aAutoPtr)
williamr@4
  1019
		{
williamr@4
  1020
		::Swap(iPtr, aAutoPtr.iPtr);
williamr@4
  1021
		}
williamr@4
  1022
williamr@4
  1023
  protected:
williamr@4
  1024
	T* iPtr;
williamr@4
  1025
williamr@4
  1026
  private:
williamr@4
  1027
	LAutoPtrBase(const LAutoPtrBase&);
williamr@4
  1028
	LAutoPtrBase& operator=(const LAutoPtrBase&);
williamr@4
  1029
	};
williamr@4
  1030
williamr@4
  1031
williamr@4
  1032
// Cleanup traits class template
williamr@4
  1033
template<typename T,
williamr@4
  1034
		 class CleanupStrategyType,
williamr@4
  1035
		 TInt isPtrSpecial = IS_PTR_SPECIAL(T)>
williamr@4
  1036
struct TPtrCleanupTraits
williamr@4
  1037
	{
williamr@4
  1038
	};
williamr@4
  1039
williamr@4
  1040
williamr@4
  1041
// Cleanup traits class template specialization for pointers to types
williamr@4
  1042
// that are not derived from CBase
williamr@4
  1043
template<typename T,
williamr@4
  1044
		 class CleanupStrategyType>
williamr@4
  1045
struct TPtrCleanupTraits<T, CleanupStrategyType, EPtrNonSpecial>
williamr@4
  1046
	{
williamr@4
  1047
	typedef T ManagedType;
williamr@4
  1048
	typedef T BaseManagedType;
williamr@4
  1049
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  1050
	};
williamr@4
  1051
williamr@4
  1052
// Cleanup traits class template specialization for pointers to types
williamr@4
  1053
// that are derived from CBase
williamr@4
  1054
template<typename T,
williamr@4
  1055
		 class CleanupStrategyType>
williamr@4
  1056
struct TPtrCleanupTraits<T, CleanupStrategyType, EPtrCBaseDerived>
williamr@4
  1057
	{
williamr@4
  1058
	typedef T ManagedType;
williamr@4
  1059
	typedef CBase BaseManagedType;
williamr@4
  1060
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  1061
	};
williamr@4
  1062
williamr@4
  1063
// Cleanup traits class template specialization for pointers to types
williamr@4
  1064
// that are derived from CBase and the default pointer cleanup
williamr@4
  1065
// strategy (TPtrCleanupStrategy)
williamr@4
  1066
template<typename T>
williamr@4
  1067
struct TPtrCleanupTraits<T, TPtrCleanupStrategy, EPtrCBaseDerived>
williamr@4
  1068
	{
williamr@4
  1069
	typedef CBase ManagedType;
williamr@4
  1070
	typedef CBase BaseManagedType;
williamr@4
  1071
	typedef TPtrCleanupStrategy CleanupStrategy;
williamr@4
  1072
	};
williamr@4
  1073
williamr@4
  1074
williamr@4
  1075
/**
williamr@4
  1076
   Implementation base class - not designed for public inheritance or
williamr@4
  1077
   direct use.
williamr@4
  1078
*/
williamr@4
  1079
template<typename T,
williamr@4
  1080
		 class CleanupStrategyType>
williamr@4
  1081
class LManagedPtrBase: protected LAutoPtrBase<typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType>
williamr@4
  1082
	{
williamr@4
  1083
	typedef LAutoPtrBase<typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType> LAutoPtrBase;
williamr@4
  1084
williamr@4
  1085
  protected:
williamr@4
  1086
	typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::ManagedType ManagedType;
williamr@4
  1087
	typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType BaseManagedType;
williamr@4
  1088
	typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::CleanupStrategy CleanupStrategy;
williamr@4
  1089
williamr@4
  1090
	LManagedPtrBase()
williamr@4
  1091
		{
williamr@4
  1092
		}
williamr@4
  1093
williamr@4
  1094
	template<typename U>
williamr@4
  1095
	explicit LManagedPtrBase(U* aPtr)
williamr@4
  1096
		: LAutoPtrBase(aPtr)
williamr@4
  1097
		{
williamr@4
  1098
		}
williamr@4
  1099
williamr@4
  1100
/**
williamr@4
  1101
   Destructor.	When automatic resource management is enabled, the
williamr@4
  1102
   destructor invokes the specified cleanup strategy for the managed
williamr@4
  1103
   pointer.
williamr@4
  1104
 */
williamr@4
  1105
	~LManagedPtrBase()
williamr@4
  1106
		{
williamr@4
  1107
		if (IsEnabled())
williamr@4
  1108
			{
williamr@4
  1109
			CleanupStrategy::Cleanup(static_cast<ManagedType*>(iPtr));
williamr@4
  1110
			}
williamr@4
  1111
		}
williamr@4
  1112
williamr@4
  1113
	template<typename U>
williamr@4
  1114
	LManagedPtrBase& operator=(U* aPtr)
williamr@4
  1115
		{
williamr@4
  1116
		ReleaseResource();
williamr@4
  1117
		LAutoPtrBase::operator=(aPtr);
williamr@4
  1118
		return *this;
williamr@4
  1119
		}
williamr@4
  1120
williamr@4
  1121
/**
williamr@4
  1122
   If automatic resource management is enabled, the specified cleanup
williamr@4
  1123
   strategy is invoked for the managed pointer and the automatic
williamr@4
  1124
   resource management is then disabled.  The underlying pointer is
williamr@4
  1125
   reset to NULL.
williamr@4
  1126
williamr@4
  1127
   @post Get() == NULL
williamr@4
  1128
*/
williamr@4
  1129
	void ReleaseResource()
williamr@4
  1130
		{
williamr@4
  1131
		if (!IsEnabled())
williamr@4
  1132
			return;
williamr@4
  1133
williamr@4
  1134
		CleanupStrategy::Cleanup(static_cast<ManagedType*>(iPtr));
williamr@4
  1135
		LAutoPtrBase::Disable();
williamr@4
  1136
		}
williamr@4
  1137
williamr@4
  1138
	using LAutoPtrBase::Unmanage;
williamr@4
  1139
williamr@4
  1140
	using LAutoPtrBase::IsEnabled;
williamr@4
  1141
williamr@4
  1142
	using LAutoPtrBase::Get;
williamr@4
  1143
williamr@4
  1144
	using LAutoPtrBase::operator->;
williamr@4
  1145
williamr@4
  1146
	using LAutoPtrBase::Disable;
williamr@4
  1147
williamr@4
  1148
	using LAutoPtrBase::iPtr;
williamr@4
  1149
williamr@4
  1150
	void Swap(LManagedPtrBase& aManagedPtr)
williamr@4
  1151
		{
williamr@4
  1152
		LAutoPtrBase::Swap(aManagedPtr);
williamr@4
  1153
		}
williamr@4
  1154
	};
williamr@4
  1155
williamr@4
  1156
williamr@4
  1157
/**
williamr@4
  1158
   A class template that provides automatic management of pointers
williamr@4
  1159
   held in the data members of objects.
williamr@4
  1160
williamr@4
  1161
   @note This class should not used to define locals. See below for
williamr@4
  1162
   an explanation and links to management classes suitable for use in
williamr@4
  1163
   that context.
williamr@4
  1164
williamr@4
  1165
   This class template can be used to protect a pointer to type T such
williamr@4
  1166
   that the instance of T referred to is automatically cleaned up when
williamr@4
  1167
   the management object is destroyed; typically when the object
williamr@4
  1168
   containing it is deleted.
williamr@4
  1169
williamr@4
  1170
   By default, the cleanup action is to delete the managed pointer
williamr@4
  1171
   using a (non-array) delete operation. An alternative cleanup
williamr@4
  1172
   strategy can be specified using the optional CleanupStrategy class
williamr@4
  1173
   template parameter of the LManagedPtr class template. The most
williamr@4
  1174
   common alternative cleanup strategies are predefined
williamr@4
  1175
   (e.g. TPointerFree).
williamr@4
  1176
williamr@4
  1177
   The constructors of this class never leave, so data members defined with
williamr@4
  1178
   this type may be initialized safely during any phase of
williamr@4
  1179
   construction of the owning class.
williamr@4
  1180
williamr@4
  1181
   As a convenience, the methods of the managed pointer may be
williamr@4
  1182
   accessed via "->" notation directly on the management object, while
williamr@4
  1183
   "." notation is used to access the interface of the management
williamr@4
  1184
   object itself. Using "*" to dereference the management object
williamr@4
  1185
   yields a T&, and is often useful when passing the managed object as
williamr@4
  1186
   an argument.
williamr@4
  1187
williamr@4
  1188
   Automatic cleanup may be disabled at any time by calling
williamr@4
  1189
   Unmanage(), while cleanup may be forced at any time by calling
williamr@4
  1190
   ReleaseResource().
williamr@4
  1191
williamr@4
  1192
   Example:
williamr@4
  1193
   @code
williamr@4
  1194
   class CComposite : public CBase
williamr@4
  1195
	   {
williamr@4
  1196
	 public:
williamr@4
  1197
	   CONSTRUCTORS_MAY_LEAVE
williamr@4
  1198
williamr@4
  1199
	   CComposite()
williamr@4
  1200
		   : iComponent(CComponent::NewL())
williamr@4
  1201
		   {
williamr@4
  1202
		   //...
williamr@4
  1203
		   }
williamr@4
  1204
williamr@4
  1205
	   ~CComposite()
williamr@4
  1206
		   {
williamr@4
  1207
		   // the pointer to the CComponent object is automatically
williamr@4
  1208
		   // deleted
williamr@4
  1209
		   }
williamr@4
  1210
williamr@4
  1211
	 private:
williamr@4
  1212
	   LManagedPtr<CComponent> iComponent;
williamr@4
  1213
	   };
williamr@4
  1214
	@endcode
williamr@4
  1215
williamr@4
  1216
   Behind the scenes, this class template simply relies on reliable
williamr@4
  1217
   execution of its destructor. If used for a local variable rather
williamr@4
  1218
   than a data member, cleanup will occur but out-of-order compared to
williamr@4
  1219
   objects protected using the LCleanupXxx variants or the
williamr@4
  1220
   CleanupStack directly. Therefore it is not recommended for use in
williamr@4
  1221
   that context.
williamr@4
  1222
williamr@4
  1223
   These management classes may be used as the basis for implementing
williamr@4
  1224
   leave-safe single-phase construction, since fully initialized
williamr@4
  1225
   data members protected in this way will get destroyed (so reliably
williamr@4
  1226
   triggering cleanup) if their containing classes leave during
williamr@4
  1227
   execution of their constructors. Note, however, that single-phase
williamr@4
  1228
   construction must be explicitly enabled in the containing class
williamr@4
  1229
   using the CONSTRUCTORS_MAY_LEAVE macro.
williamr@4
  1230
williamr@4
  1231
   This class template together with the cleanup strategy class
williamr@4
  1232
   templates provide a template-based implementation of the Strategy
williamr@4
  1233
   design pattern (See also: Policy-based design).
williamr@4
  1234
williamr@4
  1235
   @see TPointerDelete which implements the default deleting cleanup strategy
williamr@4
  1236
   @see TPointerFree which implements the alternative User::Free() cleanup strategy
williamr@4
  1237
   @see LCleanedupPtr which has the same interface, but uses the cleanup
williamr@4
  1238
   stack and is suitable for protecting locals
williamr@4
  1239
   @see CONSTRUCTORS_MAY_LEAVE
williamr@4
  1240
*/
williamr@4
  1241
template<typename T,
williamr@4
  1242
		 class CleanupStrategyType = TPtrCleanupStrategy>
williamr@4
  1243
class LManagedPtr: protected LManagedPtrBase<T, CleanupStrategyType>
williamr@4
  1244
	{
williamr@4
  1245
	typedef LManagedPtrBase<T, CleanupStrategyType> LManagedPtrBase;
williamr@4
  1246
williamr@4
  1247
  public:
williamr@4
  1248
	typedef T ManagedType;
williamr@4
  1249
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  1250
williamr@4
  1251
williamr@4
  1252
/**
williamr@4
  1253
   Default constructor.	 Constructs an empty LManagedPtr object.
williamr@4
  1254
williamr@4
  1255
   @post Get() == NULL
williamr@4
  1256
 */
williamr@4
  1257
	LManagedPtr()
williamr@4
  1258
		{
williamr@4
  1259
		}
williamr@4
  1260
williamr@4
  1261
/**
williamr@4
  1262
   Explicit constructor template.  Constructs a LManagedPtr object
williamr@4
  1263
   that manages the pointer aPtr of a type convertible to T* that can
williamr@4
  1264
   be cleaned up using the cleanup strategy of the LManagedPtr class.
williamr@4
  1265
   The default cleanup strategy is to delete the pointer to a
williamr@4
  1266
   heap-allocated object by using non-array delete.	 Alternative
williamr@4
  1267
   cleanup strategies can be specified by using the CleanupStrategy
williamr@4
  1268
   template parameter of the LManagedPtr class template.
williamr@4
  1269
williamr@4
  1270
   @param aPtr A pointer of a type that is convertible to T* that can
williamr@4
  1271
   be cleaned up using the cleanup strategy.
williamr@4
  1272
williamr@4
  1273
   @pre aPtr is of a type convertible to T* and can be cleaned up
williamr@4
  1274
   using the cleanup strategy.
williamr@4
  1275
williamr@4
  1276
   @post Get() == aPtr
williamr@4
  1277
 */
williamr@4
  1278
	explicit LManagedPtr(T* aPtr)
williamr@4
  1279
		: LManagedPtrBase(aPtr)
williamr@4
  1280
		{
williamr@4
  1281
		}
williamr@4
  1282
williamr@4
  1283
/**
williamr@4
  1284
   Destructor.	When automatic resource management is enabled, the
williamr@4
  1285
   destructor invokes the specified cleanup strategy for the managed
williamr@4
  1286
   pointer.
williamr@4
  1287
 */
williamr@4
  1288
williamr@4
  1289
williamr@4
  1290
/**
williamr@4
  1291
   Assigns a new pointer to be managed.	 The new pointer must be of a
williamr@4
  1292
   type convertible to T* and it must be possible to use the cleanup
williamr@4
  1293
   strategy of the LManagedPtr object for the cleanup of the new
williamr@4
  1294
   managed pointer.	 If the LManagedPtr object already contains a
williamr@4
  1295
   managed pointer, then the cleanup strategy is invoked with the
williamr@4
  1296
   managed pointer before assigning the new managed pointer.
williamr@4
  1297
williamr@4
  1298
   @param aPtr A pointer of a type that is convertible to T* that can
williamr@4
  1299
   be cleaned up using the cleanup strategy.
williamr@4
  1300
williamr@4
  1301
   @pre aPtr is a pointer of a type that is convertible to T* and can
williamr@4
  1302
   be cleaned up using the cleanup strategy.
williamr@4
  1303
williamr@4
  1304
   @post Get() == aPtr
williamr@4
  1305
 */
williamr@4
  1306
	LManagedPtr& operator=(T* aPtr)
williamr@4
  1307
		{
williamr@4
  1308
		LManagedPtrBase::operator=(aPtr);
williamr@4
  1309
		return *this;
williamr@4
  1310
		}
williamr@4
  1311
williamr@4
  1312
/**
williamr@4
  1313
   Assigns a new pointer to be managed.	 The new pointer must be of a
williamr@4
  1314
   type convertible to T* and it must be possible to use the cleanup
williamr@4
  1315
   strategy of the LManagedPtr object for the cleanup of the new
williamr@4
  1316
   managed pointer.	 If the LManagedPtr object already contains a
williamr@4
  1317
   managed pointer, then the cleanup strategy is invoked with the
williamr@4
  1318
   managed pointer before assigning the new managed pointer.
williamr@4
  1319
williamr@4
  1320
   @param aPtr A pointer of a type that is convertible to T* that can
williamr@4
  1321
   be cleaned up using the cleanup strategy.
williamr@4
  1322
williamr@4
  1323
   @pre aPtr is a pointer of a type that is convertible to T* and can
williamr@4
  1324
   be cleaned up using the cleanup strategy.
williamr@4
  1325
williamr@4
  1326
   @post Get() == aPtr
williamr@4
  1327
 */
williamr@4
  1328
	template<typename U>
williamr@4
  1329
	LManagedPtr& operator=(U* aPtr)
williamr@4
  1330
		{
williamr@4
  1331
		LManagedPtrBase::operator=(aPtr);
williamr@4
  1332
		return *this;
williamr@4
  1333
		}
williamr@4
  1334
williamr@4
  1335
	using LManagedPtrBase::ReleaseResource;
williamr@4
  1336
williamr@4
  1337
/**
williamr@4
  1338
   Disables the automatic resource management for this object and
williamr@4
  1339
   returns a pointer to the object of type T.
williamr@4
  1340
williamr@4
  1341
   @return A pointer to the object of type T.
williamr@4
  1342
*/
williamr@4
  1343
	T* Unmanage()
williamr@4
  1344
		{
williamr@4
  1345
		return static_cast<T*>(LManagedPtrBase::Unmanage());
williamr@4
  1346
		}
williamr@4
  1347
williamr@4
  1348
/**
williamr@4
  1349
   Returns ETrue if automatic resource management is enabled; EFalse
williamr@4
  1350
   otherwise.
williamr@4
  1351
williamr@4
  1352
   @return ETrue if automatic resource management is enabled; EFalse
williamr@4
  1353
   otherwise.
williamr@4
  1354
*/
williamr@4
  1355
	using LManagedPtrBase::IsEnabled;
williamr@4
  1356
williamr@4
  1357
/**
williamr@4
  1358
   Returns a pointer to the managed object of type T.
williamr@4
  1359
williamr@4
  1360
   @return A pointer to the managed object of type T.
williamr@4
  1361
*/
williamr@4
  1362
	T* Get() const
williamr@4
  1363
		{
williamr@4
  1364
		return static_cast<T*>(iPtr);
williamr@4
  1365
		}
williamr@4
  1366
williamr@4
  1367
/**
williamr@4
  1368
   Overloaded indirection operator function.
williamr@4
  1369
williamr@4
  1370
   @return A reference to the managed object of type T.
williamr@4
  1371
*/
williamr@4
  1372
	T& operator*() const
williamr@4
  1373
		{
williamr@4
  1374
		return *(static_cast<T*>(iPtr));
williamr@4
  1375
		}
williamr@4
  1376
williamr@4
  1377
/**
williamr@4
  1378
   Overloaded class member access operator function.
williamr@4
  1379
williamr@4
  1380
   @return A pointer to the managed object of type T.
williamr@4
  1381
*/
williamr@4
  1382
	T* operator->() const
williamr@4
  1383
		{
williamr@4
  1384
		return static_cast<T*>(iPtr);
williamr@4
  1385
		}
williamr@4
  1386
williamr@4
  1387
williamr@4
  1388
// Implementation type - do not use
williamr@4
  1389
	typedef typename LManagedPtrBase::BaseManagedType* LManagedPtr<T, CleanupStrategy>::*TUnspecifiedBoolType;
williamr@4
  1390
williamr@4
  1391
/**
williamr@4
  1392
   Conversion operator that enables LCleanedupPtr objects to be used
williamr@4
  1393
   in boolean contexts.
williamr@4
  1394
williamr@4
  1395
   @return An unspecified value of an unspecified type convertible to
williamr@4
  1396
   boolean, which has a boolean value equal to Get() != NULL
williamr@4
  1397
 */
williamr@4
  1398
	operator TUnspecifiedBoolType()
williamr@4
  1399
		{
williamr@4
  1400
		return iPtr ? &LManagedPtr::iPtr : NULL;
williamr@4
  1401
		}
williamr@4
  1402
williamr@4
  1403
williamr@4
  1404
	using LManagedPtrBase::Disable;
williamr@4
  1405
williamr@4
  1406
	void Swap(LManagedPtr& aManagedPtr)
williamr@4
  1407
		{
williamr@4
  1408
		LManagedPtrBase::Swap(aManagedPtr);
williamr@4
  1409
		}
williamr@4
  1410
williamr@4
  1411
  private:
williamr@4
  1412
	using LManagedPtrBase::iPtr;
williamr@4
  1413
	};
williamr@4
  1414
williamr@4
  1415
williamr@4
  1416
// function template used for comparing two LManagedPtr-managed
williamr@4
  1417
// pointers for equality
williamr@4
  1418
template<typename T, typename U>
williamr@4
  1419
TBool operator==(const LManagedPtr<T>& aPtr1, const LManagedPtr<U>& aPtr2)
williamr@4
  1420
	{
williamr@4
  1421
	return aPtr1.Get() == aPtr2.Get();
williamr@4
  1422
	}
williamr@4
  1423
williamr@4
  1424
// function template used for comparing two LManagedPtr-managed
williamr@4
  1425
// pointers for inequality
williamr@4
  1426
template<typename T, typename U>
williamr@4
  1427
TBool operator!=(const LManagedPtr<T>& aPtr1, const LManagedPtr<U>& aPtr2)
williamr@4
  1428
	{
williamr@4
  1429
	return aPtr1.Get() != aPtr2.Get();
williamr@4
  1430
	}
williamr@4
  1431
williamr@4
  1432
// function template used for testing the ordering of two
williamr@4
  1433
// LManagedPtr-managed pointers
williamr@4
  1434
template<typename T, typename U>
williamr@4
  1435
TBool operator<(const LManagedPtr<T>& aPtr1, const LManagedPtr<U>& aPtr2)
williamr@4
  1436
	{
williamr@4
  1437
	return aPtr1.Get() < aPtr2.Get();
williamr@4
  1438
	}
williamr@4
  1439
williamr@4
  1440
williamr@4
  1441
/**
williamr@4
  1442
   A class template that provides automatic management of arrays. Such
williamr@4
  1443
   managed arrays can be data members of composite classes.
williamr@4
  1444
williamr@4
  1445
   @note This class should not used to define locals. See below for
williamr@4
  1446
   an explanation and links to management classes suitable for use in
williamr@4
  1447
   that context.
williamr@4
  1448
williamr@4
  1449
   @par
williamr@4
  1450
williamr@4
  1451
   @note This class can only be used with raw arrays, which are used
williamr@4
  1452
   only rarely on Symbian OS.  Instances of Symbian array container
williamr@4
  1453
   classes (e.g. RArray, RPointerArray) should be managed using the
williamr@4
  1454
   automatic management template classes appropriate for the array's
williamr@4
  1455
   type (LManagedHandle template classes for Symbian R arrays or
williamr@4
  1456
   LManagedPtr template classes for Symbian C arrays).
williamr@4
  1457
williamr@4
  1458
   This class template can be used to protect a heap-allocated array
williamr@4
  1459
   of objects of type T such that the managed array is automatically
williamr@4
  1460
   deallocated when the management object is destroyed.
williamr@4
  1461
williamr@4
  1462
   The default cleanup strategy is to deallocate the managed array
williamr@4
  1463
   using arrray delete (delete[]), assuming that the array is
williamr@4
  1464
   heap-allocated.	An alternative cleanup strategy can be selected by
williamr@4
  1465
   specifying a cleanup strategy template class as the optional second
williamr@4
  1466
   template argument (corresponding to the CleanupStrategy template
williamr@4
  1467
   parameter).
williamr@4
  1468
williamr@4
  1469
   The constructors of this class never leave, so data members defined with
williamr@4
  1470
   this type may be initialized safely during any phase of
williamr@4
  1471
   construction of the owning class.
williamr@4
  1472
williamr@4
  1473
   As a convenience, the elements of the managed array may be accessed
williamr@4
  1474
   via "[]" notation directly on the management object.
williamr@4
  1475
williamr@4
  1476
   Automatic cleanup may be disabled at any time by calling
williamr@4
  1477
   Unmanage(), while cleanup may be forced at any time by calling
williamr@4
  1478
   ReleaseResource().
williamr@4
  1479
williamr@4
  1480
williamr@4
  1481
   Example:
williamr@4
  1482
   @code
williamr@4
  1483
   class CComposite : public CBase
williamr@4
  1484
	   {
williamr@4
  1485
	 public:
williamr@4
  1486
	   CONSTRUCTORS_MAY_LEAVE
williamr@4
  1487
williamr@4
  1488
	   CComposite()
williamr@4
  1489
		   : iComponents(new(ELeave) CComponent[KNumComponents])
williamr@4
  1490
		   {
williamr@4
  1491
		   //...
williamr@4
  1492
		   }
williamr@4
  1493
williamr@4
  1494
	   ~CComposite()
williamr@4
  1495
		   {
williamr@4
  1496
		   // the array is automatically deleted
williamr@4
  1497
		   }
williamr@4
  1498
williamr@4
  1499
	 private:
williamr@4
  1500
	   LManagedArray<CComponent> iComponents;
williamr@4
  1501
	   };
williamr@4
  1502
   @endcode
williamr@4
  1503
williamr@4
  1504
williamr@4
  1505
   Behind the scenes, this class template simply relies on reliable
williamr@4
  1506
   execution of its destructor. If used for a local variable rather
williamr@4
  1507
   than a data member, cleanup will occur but out-of-order compared to
williamr@4
  1508
   objects protected using the LCleanupXxx variants or the
williamr@4
  1509
   CleanupStack directly. Therefore it is not recommended for use in
williamr@4
  1510
   that context.
williamr@4
  1511
williamr@4
  1512
   These management classes may be used as the basis for implementing
williamr@4
  1513
   leave-safe single-phase construction, since fully initialized
williamr@4
  1514
   data members protected in this way will get destroyed (so reliably
williamr@4
  1515
   triggering cleanup) if their containing classes leave during
williamr@4
  1516
   execution of their constructors. Note, however, that single-phase
williamr@4
  1517
   construction must be explicitly enabled in the containing class
williamr@4
  1518
   using the CONSTRUCTORS_MAY_LEAVE macro.
williamr@4
  1519
williamr@4
  1520
   This class template together with the cleanup strategy class
williamr@4
  1521
   templates provide a template-based implementation of the Strategy
williamr@4
  1522
   design pattern (See also: Policy-based design).
williamr@4
  1523
williamr@4
  1524
   @see LCleanedupArray which has the same interface, but uses the cleanup
williamr@4
  1525
   stack and is suitable for protecting locals
williamr@4
  1526
   @see CONSTRUCTORS_MAY_LEAVE
williamr@4
  1527
*/
williamr@4
  1528
template<typename T,
williamr@4
  1529
		 class CleanupStrategyType = TArrayDelete>
williamr@4
  1530
class LManagedArray: protected LAutoPtrBase<T>
williamr@4
  1531
	{
williamr@4
  1532
	typedef LAutoPtrBase<T> LAutoPtrBase;
williamr@4
  1533
williamr@4
  1534
  public:
williamr@4
  1535
	typedef T ManagedType;
williamr@4
  1536
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  1537
williamr@4
  1538
/**
williamr@4
  1539
   Default constructor.	 Constructs an empty LManagedArray object.
williamr@4
  1540
williamr@4
  1541
   @post Get() == NULL
williamr@4
  1542
 */
williamr@4
  1543
	LManagedArray()
williamr@4
  1544
		{
williamr@4
  1545
		}
williamr@4
  1546
williamr@4
  1547
/**
williamr@4
  1548
   Explicit constructor.  Constructs a LManagedArray object that
williamr@4
  1549
   manages an array of objects of type T that can be cleaned up using
williamr@4
  1550
   the cleanup strategy of the LManagedArray class.	 The default
williamr@4
  1551
   cleanup strategy is to deallocate the managed array by using array
williamr@4
  1552
   delete (delete[]), assuming that the array is heap-allocated.
williamr@4
  1553
   Alternative cleanup strategies can be specified by using the
williamr@4
  1554
   CleanupStrategy template parameter of the LManagedArray class
williamr@4
  1555
   template.
williamr@4
  1556
williamr@4
  1557
   @param aPtr A pointer to the first element of an array of objects
williamr@4
  1558
   of type T - array that can be cleaned up using the cleanup strategy
williamr@4
  1559
   of the the LManagedArray class.
williamr@4
  1560
williamr@4
  1561
   @pre The array can be cleaned up using the cleanup strategy.
williamr@4
  1562
williamr@4
  1563
   @post Get() == aPtr
williamr@4
  1564
 */
williamr@4
  1565
	explicit LManagedArray(T* aPtr)
williamr@4
  1566
		: LAutoPtrBase(aPtr)
williamr@4
  1567
		{
williamr@4
  1568
		}
williamr@4
  1569
williamr@4
  1570
/**
williamr@4
  1571
   Destructor.	When automatic resource management is enabled, the
williamr@4
  1572
   destructor invokes the specified cleanup strategy for the managed
williamr@4
  1573
   pointer.
williamr@4
  1574
 */
williamr@4
  1575
	~LManagedArray()
williamr@4
  1576
		{
williamr@4
  1577
		if (LAutoPtrBase::IsEnabled())
williamr@4
  1578
			{
williamr@4
  1579
			CleanupStrategy::Cleanup(iPtr);
williamr@4
  1580
			}
williamr@4
  1581
		}
williamr@4
  1582
williamr@4
  1583
/**
williamr@4
  1584
   Assigns a new array of objects of type T to be managed.	It needs
williamr@4
  1585
   to be possible use the cleanup strategy of the LManagedArray object
williamr@4
  1586
   for the cleanup of the new managed array.  The default cleanup
williamr@4
  1587
   strategy is to delete the heap-allocated array by using array
williamr@4
  1588
   delete (delete[]). If the LManagedArray object already manages an
williamr@4
  1589
   array, then the cleanup strategy is invoked with the managed array
williamr@4
  1590
   before assigning the new managed array.
williamr@4
  1591
williamr@4
  1592
   @param aPtr A pointer to the first element of the array of objects
williamr@4
  1593
   of type T - array that can be cleaned up using the cleanup
williamr@4
  1594
   strategy.
williamr@4
  1595
williamr@4
  1596
   @pre The new array to be managed can be cleaned up using the
williamr@4
  1597
   cleanup strategy.
williamr@4
  1598
williamr@4
  1599
   @post Get() == aPtr
williamr@4
  1600
 */
williamr@4
  1601
	LManagedArray& operator=(T* aPtr)
williamr@4
  1602
		{
williamr@4
  1603
		ReleaseResource();
williamr@4
  1604
		LAutoPtrBase::operator=(aPtr);
williamr@4
  1605
		return *this;
williamr@4
  1606
		}
williamr@4
  1607
williamr@4
  1608
/**
williamr@4
  1609
   If automatic resource management is enabled, the specified cleanup
williamr@4
  1610
   strategy is invoked for the managed pointer and the automatic
williamr@4
  1611
   resource management is then disabled.  The underlying pointer is
williamr@4
  1612
   reset to NULL.
williamr@4
  1613
williamr@4
  1614
   @post Get() == NULL
williamr@4
  1615
*/
williamr@4
  1616
	void ReleaseResource()
williamr@4
  1617
		{
williamr@4
  1618
		if (!LAutoPtrBase::IsEnabled())
williamr@4
  1619
			return;
williamr@4
  1620
williamr@4
  1621
		CleanupStrategy::Cleanup(iPtr);
williamr@4
  1622
		LAutoPtrBase::Disable();
williamr@4
  1623
		}
williamr@4
  1624
williamr@4
  1625
/**
williamr@4
  1626
   Disables the automatic resource management for this object and
williamr@4
  1627
   returns a pointer to the first element of the array of objects of
williamr@4
  1628
   type T.
williamr@4
  1629
williamr@4
  1630
   @return A pointer to the first element of the array of objects of
williamr@4
  1631
   type T.
williamr@4
  1632
*/
williamr@4
  1633
	T* Unmanage()
williamr@4
  1634
		{
williamr@4
  1635
		return static_cast<T*>(LAutoPtrBase::Unmanage());
williamr@4
  1636
		}
williamr@4
  1637
williamr@4
  1638
/**
williamr@4
  1639
   Returns ETrue if automatic resource management is enabled; EFalse
williamr@4
  1640
   otherwise.
williamr@4
  1641
williamr@4
  1642
   @return ETrue if automatic resource management is enabled; EFalse
williamr@4
  1643
   otherwise.
williamr@4
  1644
*/
williamr@4
  1645
	using LAutoPtrBase::IsEnabled;
williamr@4
  1646
williamr@4
  1647
/**
williamr@4
  1648
   Returns a pointer to the first element of the managed array of
williamr@4
  1649
   objects of type T.
williamr@4
  1650
williamr@4
  1651
   @return A pointer to the first element of the managed array of
williamr@4
  1652
   objects of type T.
williamr@4
  1653
*/
williamr@4
  1654
	using LAutoPtrBase::Get;
williamr@4
  1655
williamr@4
  1656
/**
williamr@4
  1657
   Overloaded subscript operator.
williamr@4
  1658
williamr@4
  1659
   @return A reference to the object of type T at the position aIndex.
williamr@4
  1660
 */
williamr@4
  1661
	T& operator[](TInt aIndex) const
williamr@4
  1662
		{
williamr@4
  1663
		return iPtr[aIndex];
williamr@4
  1664
		}
williamr@4
  1665
williamr@4
  1666
	using LAutoPtrBase::Disable;
williamr@4
  1667
williamr@4
  1668
	void Swap(LManagedArray& aArray)
williamr@4
  1669
		{
williamr@4
  1670
		LAutoPtrBase::Swap(aArray);
williamr@4
  1671
		}
williamr@4
  1672
williamr@4
  1673
  private:
williamr@4
  1674
	using LAutoPtrBase::iPtr;
williamr@4
  1675
	};
williamr@4
  1676
williamr@4
  1677
williamr@4
  1678
/**
williamr@4
  1679
   Implementation base class - not designed for public inheritance or
williamr@4
  1680
   direct use.
williamr@4
  1681
   
williamr@4
  1682
   @internalComponent
williamr@4
  1683
*/
williamr@4
  1684
// Not for Client Use , Only to be used Internally.
williamr@4
  1685
template<typename T>
williamr@4
  1686
class LAutoRefBase
williamr@4
  1687
	{
williamr@4
  1688
  protected:
williamr@4
  1689
	template<typename U>
williamr@4
  1690
	explicit LAutoRefBase(U& aRef)
williamr@4
  1691
		: iPtr(&aRef)
williamr@4
  1692
		{
williamr@4
  1693
		}
williamr@4
  1694
williamr@4
  1695
	template<typename U>
williamr@4
  1696
	LAutoRefBase& operator=(U& aRef)
williamr@4
  1697
		{
williamr@4
  1698
		iPtr = &aRef;
williamr@4
  1699
		return *this;
williamr@4
  1700
		}
williamr@4
  1701
williamr@4
  1702
	T& Unmanage()
williamr@4
  1703
		{
williamr@4
  1704
		T* ptr = iPtr;
williamr@4
  1705
		iPtr = NULL;
williamr@4
  1706
		return *ptr;
williamr@4
  1707
		}
williamr@4
  1708
williamr@4
  1709
	TBool IsEnabled() const
williamr@4
  1710
		{
williamr@4
  1711
		return iPtr != NULL;
williamr@4
  1712
		}
williamr@4
  1713
williamr@4
  1714
	T& Get() const
williamr@4
  1715
		{
williamr@4
  1716
		return *iPtr;
williamr@4
  1717
		}
williamr@4
  1718
williamr@4
  1719
	T& operator*() const
williamr@4
  1720
		{
williamr@4
  1721
		return *iPtr;
williamr@4
  1722
		}
williamr@4
  1723
williamr@4
  1724
	T* operator->() const
williamr@4
  1725
		{
williamr@4
  1726
		return iPtr;
williamr@4
  1727
		}
williamr@4
  1728
williamr@4
  1729
	void Disable()
williamr@4
  1730
		{
williamr@4
  1731
		iPtr = NULL;
williamr@4
  1732
		}
williamr@4
  1733
williamr@4
  1734
	void Swap(LAutoRefBase& aAutoRef)
williamr@4
  1735
		{
williamr@4
  1736
		::Swap(iPtr, aAutoRef.iPtr);
williamr@4
  1737
		}
williamr@4
  1738
williamr@4
  1739
  protected:
williamr@4
  1740
	T* iPtr;
williamr@4
  1741
williamr@4
  1742
  private:
williamr@4
  1743
	LAutoRefBase(const LAutoRefBase&);
williamr@4
  1744
	LAutoRefBase& operator=(const LAutoRefBase&);
williamr@4
  1745
	};
williamr@4
  1746
williamr@4
  1747
williamr@4
  1748
/**
williamr@4
  1749
   A class template that provides automatic management of references
williamr@4
  1750
   to resource handles (often R-class instances) held in the data
williamr@4
  1751
   members of objects.
williamr@4
  1752
williamr@4
  1753
   @note This class should not used to define locals. See below for
williamr@4
  1754
   an explanation and links to management classes suitable for use in
williamr@4
  1755
   that context.
williamr@4
  1756
williamr@4
  1757
   Unlike LManagedHandle which creates a fresh instance of its managed
williamr@4
  1758
   type, this class template can be used to protect an existing
williamr@4
  1759
   resource handle of type T (typically an R-class instance). The
williamr@4
  1760
   instance of T referred to has a cleanup operation run on it
williamr@4
  1761
   automatically when the management object is destroyed; typically
williamr@4
  1762
   when the object containing it is deleted.
williamr@4
  1763
williamr@4
  1764
   By default, the cleanup action is to call the Close() member
williamr@4
  1765
   function of the referenced handle. An alternative cleanup strategy may
williamr@4
  1766
   be selected by specifying a cleanup strategy template class in the
williamr@4
  1767
   optional second template parameter position. The most common
williamr@4
  1768
   alternative cleanup strategies are predefined. It is also possible
williamr@4
  1769
   to specialize the default cleanup action for a given class using
williamr@4
  1770
   the DEFINE_CLEANUP_FUNCTION macro.
williamr@4
  1771
williamr@4
  1772
   The constructors of this class never leave, so data members defined with
williamr@4
  1773
   this type may be initialized safely during any phase of
williamr@4
  1774
   construction of the owning class.
williamr@4
  1775
williamr@4
  1776
   As a convenience, the methods of the managed pointer may be
williamr@4
  1777
   accessed via "->" notation directly on the management object, while
williamr@4
  1778
   "." notation is used to access the interface of the management
williamr@4
  1779
   object itself. Using "*" to dereference the management object
williamr@4
  1780
   yields a T&, and is often useful when passing the managed object as
williamr@4
  1781
   an argument.
williamr@4
  1782
williamr@4
  1783
   Automatic cleanup may be disabled at any time by calling
williamr@4
  1784
   Unmanage(), while cleanup may be forced at any time by calling
williamr@4
  1785
   ReleaseResource().
williamr@4
  1786
williamr@4
  1787
   Example:
williamr@4
  1788
   @code
williamr@4
  1789
   class CComposite : public CBase
williamr@4
  1790
	   {
williamr@4
  1791
	 public:
williamr@4
  1792
	   CONSTRUCTORS_MAY_LEAVE
williamr@4
  1793
williamr@4
  1794
	   // An existing RFs instance is given to us to reuse, but
williamr@4
  1795
	   // we are responsible for calling Close() when we're done
williamr@4
  1796
	   CComposite(RFs& aFs)
williamr@4
  1797
		   : iFileServ(aFs)
williamr@4
  1798
		   {
williamr@4
  1799
		   iFileServ->Connect() OR_LEAVE;
williamr@4
  1800
		   iFile->Open(*iFileServ, ...);
williamr@4
  1801
		   }
williamr@4
  1802
williamr@4
  1803
	   ~CComposite()
williamr@4
  1804
		   {
williamr@4
  1805
		   // the handles are automatically closed
williamr@4
  1806
		   }
williamr@4
  1807
williamr@4
  1808
	 private:
williamr@4
  1809
williamr@4
  1810
	   LManagedRef<RFs> iFileServ;
williamr@4
  1811
	   LManagedHandle<RFile> iFile;
williamr@4
  1812
	   };
williamr@4
  1813
   @endcode
williamr@4
  1814
williamr@4
  1815
   Behind the scenes, this class template simply relies on reliable
williamr@4
  1816
   execution of its destructor. If used for a local variable rather
williamr@4
  1817
   than a data member, cleanup will occur but out-of-order compared to
williamr@4
  1818
   objects protected using the LCleanupXxx variants or the
williamr@4
  1819
   CleanupStack directly. Therefore it is not recommended for use in
williamr@4
  1820
   that context.
williamr@4
  1821
williamr@4
  1822
   These management classes may be used as the basis for implementing
williamr@4
  1823
   leave-safe single-phase construction, since fully initialized
williamr@4
  1824
   data members protected in this way will get destroyed (so reliably
williamr@4
  1825
   triggering cleanup) if their containing classes leave during
williamr@4
  1826
   execution of their constructors. Note, however, that single-phase
williamr@4
  1827
   construction must be explicitly enabled in the containing class
williamr@4
  1828
   using the CONSTRUCTORS_MAY_LEAVE macro.
williamr@4
  1829
williamr@4
  1830
   This class template together with the cleanup strategy class
williamr@4
  1831
   templates provide a template-based implementation of the Strategy
williamr@4
  1832
   design pattern (See also: Policy-based design).
williamr@4
  1833
williamr@4
  1834
   @see TClose which implements the default Close() calling cleanup strategy
williamr@4
  1835
   @see TResetAndDestroy which implements an alternative
williamr@4
  1836
   ResetAndDestroy() calling cleanup strategy
williamr@4
  1837
   @see TFree which implements an alternative Free() calling cleanup
williamr@4
  1838
   strategy
williamr@4
  1839
   @see TDestroy which implements an alternative Destroy() calling
williamr@4
  1840
   cleanup strategy
williamr@4
  1841
   @see TRelease which implements an alternative Release() calling
williamr@4
  1842
   cleanup strategy
williamr@4
  1843
   @see LCleanedupRef which has the same interface, but uses the cleanup
williamr@4
  1844
   stack and is suitable for protecting locals
williamr@4
  1845
   @see LManagedHandle which has a similar interface but creates a fresh
williamr@4
  1846
   local instance of T
williamr@4
  1847
   @see CONSTRUCTORS_MAY_LEAVE
williamr@4
  1848
*/
williamr@4
  1849
template<typename T,
williamr@4
  1850
		 class CleanupStrategyType = TResourceCleanupStrategy>
williamr@4
  1851
class LManagedRef: protected LAutoRefBase<T>
williamr@4
  1852
	{
williamr@4
  1853
	typedef LAutoRefBase<T> LAutoRefBase;
williamr@4
  1854
williamr@4
  1855
  public:
williamr@4
  1856
	typedef T ManagedType;
williamr@4
  1857
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  1858
williamr@4
  1859
/**
williamr@4
  1860
   Explicit constructor.
williamr@4
  1861
 */
williamr@4
  1862
	template<typename U>
williamr@4
  1863
	explicit LManagedRef(U& aRef)
williamr@4
  1864
		: LAutoRefBase(aRef)
williamr@4
  1865
		{
williamr@4
  1866
		}
williamr@4
  1867
williamr@4
  1868
/**
williamr@4
  1869
   Destructor.	When automatic resource management is enabled, the
williamr@4
  1870
   destructor invokes the specified cleanup strategy for the managed
williamr@4
  1871
   reference.
williamr@4
  1872
 */
williamr@4
  1873
	~LManagedRef()
williamr@4
  1874
		{
williamr@4
  1875
		if (LAutoRefBase::IsEnabled())
williamr@4
  1876
			{
williamr@4
  1877
			CleanupStrategy::Cleanup(iPtr);
williamr@4
  1878
			}
williamr@4
  1879
		}
williamr@4
  1880
williamr@4
  1881
/**
williamr@4
  1882
   Assigns a new reference to be managed.  If the LManagedRef
williamr@4
  1883
   object already contains a managed reference, then the specified
williamr@4
  1884
   cleanup strategy is invoked for the managed reference before
williamr@4
  1885
   assigning the new managed reference.
williamr@4
  1886
 */
williamr@4
  1887
	template<typename U>
williamr@4
  1888
	LManagedRef& operator=(U& aRef)
williamr@4
  1889
		{
williamr@4
  1890
		ReleaseResource();
williamr@4
  1891
		LAutoRefBase::operator=(aRef);
williamr@4
  1892
		return *this;
williamr@4
  1893
		}
williamr@4
  1894
williamr@4
  1895
/**
williamr@4
  1896
   If automatic resource management is enabled, the specified cleanup
williamr@4
  1897
   strategy is invoked for the managed reference and the automatic
williamr@4
  1898
   resource management is then disabled for this object.
williamr@4
  1899
*/
williamr@4
  1900
	void ReleaseResource()
williamr@4
  1901
		{
williamr@4
  1902
		if (!LAutoRefBase::IsEnabled())
williamr@4
  1903
			return;
williamr@4
  1904
williamr@4
  1905
		CleanupStrategy::Cleanup(iPtr);
williamr@4
  1906
		LAutoRefBase::Disable();
williamr@4
  1907
		}
williamr@4
  1908
williamr@4
  1909
/**
williamr@4
  1910
   Disables the automatic resource management for this object and
williamr@4
  1911
   returns a reference to the object of type T.
williamr@4
  1912
williamr@4
  1913
   @return A reference to the object of type T.
williamr@4
  1914
*/
williamr@4
  1915
	using LAutoRefBase::Unmanage;
williamr@4
  1916
williamr@4
  1917
/**
williamr@4
  1918
   Returns ETrue if automatic resource management is enabled; EFalse
williamr@4
  1919
   otherwise.
williamr@4
  1920
williamr@4
  1921
   @return ETrue if automatic resource management is enabled; EFalse
williamr@4
  1922
   otherwise.
williamr@4
  1923
*/
williamr@4
  1924
	using LAutoRefBase::IsEnabled;
williamr@4
  1925
williamr@4
  1926
/**
williamr@4
  1927
   Returns a reference to the managed object of type T.
williamr@4
  1928
williamr@4
  1929
   @return A reference to the managed object of type T.
williamr@4
  1930
*/
williamr@4
  1931
	using LAutoRefBase::Get;
williamr@4
  1932
williamr@4
  1933
/**
williamr@4
  1934
   Overloaded indirection operator function.
williamr@4
  1935
williamr@4
  1936
   @return A reference to the managed object of type T.
williamr@4
  1937
*/
williamr@4
  1938
	using LAutoRefBase::operator*;
williamr@4
  1939
williamr@4
  1940
/**
williamr@4
  1941
   Overloaded class member access operator function.
williamr@4
  1942
williamr@4
  1943
   @return A pointer to the managed object of type T.
williamr@4
  1944
*/
williamr@4
  1945
	using LAutoRefBase::operator->;
williamr@4
  1946
williamr@4
  1947
	using LAutoRefBase::Disable;
williamr@4
  1948
williamr@4
  1949
	void Swap(LManagedRef& aRef)
williamr@4
  1950
		{
williamr@4
  1951
		LAutoRefBase::Swap(aRef);
williamr@4
  1952
		}
williamr@4
  1953
williamr@4
  1954
  private:
williamr@4
  1955
	using LAutoRefBase::iPtr;
williamr@4
  1956
	};
williamr@4
  1957
williamr@4
  1958
williamr@4
  1959
/**
williamr@4
  1960
   A class template for the creation and CleanupStack-based
williamr@4
  1961
   local-scope automatic management of resource handles (typically
williamr@4
  1962
   instances of R-classes).
williamr@4
  1963
williamr@4
  1964
   @note This class can only be used to define locals, never
williamr@4
  1965
   data members. See below for an explanation and links to management
williamr@4
  1966
   classes suitable for use in different contexts. It should never be
williamr@4
  1967
   used in the same function as code that uses the CleanupStack API
williamr@4
  1968
   directly.
williamr@4
  1969
williamr@4
  1970
   This class template can be used to create and protect a resource
williamr@4
  1971
   handle of type T (typically a R-class) such that the instance of T
williamr@4
  1972
   referred to is automatically cleaned up when either of the
williamr@4
  1973
   following occur:
williamr@4
  1974
williamr@4
  1975
   - The referring local variable goes out of scope normally
williamr@4
  1976
   - The referring local variable goes out of scope due to an
williamr@4
  1977
	 untrapped leave causing the scope to be exited non-locally
williamr@4
  1978
williamr@4
  1979
   By default, the cleanup action is to call the Close() member
williamr@4
  1980
   function of the managed handle. An alternative cleanup strategy may
williamr@4
  1981
   be selected by specifying a cleanup strategy template class in the
williamr@4
  1982
   optional second template parameter position. The most common
williamr@4
  1983
   alternative cleanup strategies are predefined. It is also possible
williamr@4
  1984
   to specialize the default cleanup action for a given class using
williamr@4
  1985
   the DEFINE_CLEANUP_FUNCTION macro.
williamr@4
  1986
williamr@4
  1987
   The constructors of this class may leave.
williamr@4
  1988
williamr@4
  1989
   Any arguments supplied when initializing an instance of this class
williamr@4
  1990
   are automatically passed through to T's constructors.
williamr@4
  1991
williamr@4
  1992
   As a convenience, the methods of the managed handle may be
williamr@4
  1993
   accessed via "->" notation directly on the management object, while
williamr@4
  1994
   "." notation is used to access the interface of the management
williamr@4
  1995
   object itself. Using "*" to dereference the management object
williamr@4
  1996
   yields a T&, and is often useful when passing the managed object as
williamr@4
  1997
   an argument.
williamr@4
  1998
williamr@4
  1999
   Automatic cleanup may be disabled at any time by calling
williamr@4
  2000
   Unmanage(), while cleanup may be forced at any time by calling
williamr@4
  2001
   ReleaseResource().
williamr@4
  2002
williamr@4
  2003
   Example:
williamr@4
  2004
   @code
williamr@4
  2005
	// block scope example
williamr@4
  2006
	{
williamr@4
  2007
	LCleanedupHandle<RClosable> obj;
williamr@4
  2008
	obj->DoSomethingL(); // leave-safe
williamr@4
  2009
	if (obj->Finished())
williamr@4
  2010
		return; // RClosable::Close is invoked automatically
williamr@4
  2011
	obj->DoSomethingElseL(); // leave-safe
williamr@4
  2012
	// RClosable::Close is invoked automatically
williamr@4
  2013
	}
williamr@4
  2014
   @endcode
williamr@4
  2015
williamr@4
  2016
   Behind the scenes, this class template is implemented in terms of
williamr@4
  2017
   the thread-local CleanupStack, restricting its use to locals on the
williamr@4
  2018
   stack. This use of the CleanupStack ensures a consistent cleanup
williamr@4
  2019
   order between functions that call one another, even if they use
williamr@4
  2020
   different cleanup idioms.
williamr@4
  2021
williamr@4
  2022
   This class template together with the cleanup strategy class
williamr@4
  2023
   templates provide a template-based implementation of the Strategy
williamr@4
  2024
   design pattern (See also: Policy-based design).
williamr@4
  2025
williamr@4
  2026
   @see TClose which implements the default Close() calling cleanup strategy
williamr@4
  2027
   @see TResetAndDestroy which implements an alternative
williamr@4
  2028
   ResetAndDestroy() calling cleanup strategy
williamr@4
  2029
   @see TFree which implements an alternative Free() calling cleanup
williamr@4
  2030
   strategy
williamr@4
  2031
   @see TDestroy which implements an alternative Destroy() calling
williamr@4
  2032
   cleanup strategy
williamr@4
  2033
   @see TRelease which implements an alternative Release() calling cleanup strategy
williamr@4
  2034
   @see LManagedHandle which has the same interface, but does not use the cleanup
williamr@4
  2035
   stack and is suitable for protecting the data members of classes
williamr@4
  2036
*/
williamr@4
  2037
template<typename T,
williamr@4
  2038
		 class CleanupStrategyType = TResourceCleanupStrategy>
williamr@4
  2039
class LCleanedupHandle: protected LAutoHandleBase<T, IS_HANDLE_SPECIAL(T)>
williamr@4
  2040
	{
williamr@4
  2041
	typedef LAutoHandleBase<T, IS_HANDLE_SPECIAL(T)> LAutoHandleBase;
williamr@4
  2042
williamr@4
  2043
  public:
williamr@4
  2044
	typedef T ManagedType;
williamr@4
  2045
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  2046
williamr@4
  2047
williamr@4
  2048
/**
williamr@4
  2049
   Default constructor.
williamr@4
  2050
*/
williamr@4
  2051
	LCleanedupHandle()
williamr@4
  2052
		{
williamr@4
  2053
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2054
		}
williamr@4
  2055
williamr@4
  2056
	template<typename Param1>
williamr@4
  2057
	explicit LCleanedupHandle(const Param1& aParam1)
williamr@4
  2058
		: LAutoHandleBase(aParam1)
williamr@4
  2059
		{
williamr@4
  2060
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2061
		}
williamr@4
  2062
williamr@4
  2063
	template<typename Param1>
williamr@4
  2064
	explicit LCleanedupHandle(Param1& aParam1)
williamr@4
  2065
		: LAutoHandleBase(aParam1)
williamr@4
  2066
		{
williamr@4
  2067
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2068
		}
williamr@4
  2069
williamr@4
  2070
	template<typename Param1,
williamr@4
  2071
			 typename Param2>
williamr@4
  2072
	LCleanedupHandle(const Param1& aParam1,
williamr@4
  2073
					 const Param2& aParam2)
williamr@4
  2074
		: LAutoHandleBase(aParam1,
williamr@4
  2075
					   aParam2)
williamr@4
  2076
		{
williamr@4
  2077
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2078
		}
williamr@4
  2079
williamr@4
  2080
	template<typename Param1,
williamr@4
  2081
			 typename Param2>
williamr@4
  2082
	LCleanedupHandle(const Param1& aParam1,
williamr@4
  2083
					 Param2& aParam2)
williamr@4
  2084
		: LAutoHandleBase(aParam1,
williamr@4
  2085
					   aParam2)
williamr@4
  2086
		{
williamr@4
  2087
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2088
		}
williamr@4
  2089
williamr@4
  2090
	template<typename Param1,
williamr@4
  2091
			 typename Param2>
williamr@4
  2092
	LCleanedupHandle(Param1& aParam1,
williamr@4
  2093
					 const Param2& aParam2)
williamr@4
  2094
		: LAutoHandleBase(aParam1,
williamr@4
  2095
					   aParam2)
williamr@4
  2096
		{
williamr@4
  2097
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2098
		}
williamr@4
  2099
williamr@4
  2100
	template<typename Param1,
williamr@4
  2101
			 typename Param2>
williamr@4
  2102
	LCleanedupHandle(Param1& aParam1,
williamr@4
  2103
					 Param2& aParam2)
williamr@4
  2104
		: LAutoHandleBase(aParam1,
williamr@4
  2105
					   aParam2)
williamr@4
  2106
		{
williamr@4
  2107
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2108
		}
williamr@4
  2109
williamr@4
  2110
williamr@4
  2111
	~LCleanedupHandle()
williamr@4
  2112
		{
williamr@4
  2113
		ManagedPopCleanupStackItem(IsEnabled());
williamr@4
  2114
		}
williamr@4
  2115
williamr@4
  2116
/**
williamr@4
  2117
   Assigns a new resource to be managed.  If the LCleanedupHandle
williamr@4
  2118
   object already contains a managed resource handle, then the managed
williamr@4
  2119
   resource is released using the specified cleanup strategy before
williamr@4
  2120
   assigning the new managed resource.
williamr@4
  2121
 */
williamr@4
  2122
	template<typename U>
williamr@4
  2123
	LCleanedupHandle& operator=(const U& aHandle)
williamr@4
  2124
		{
williamr@4
  2125
		ReleaseResource();
williamr@4
  2126
		LAutoHandleBase::operator=(aHandle);
williamr@4
  2127
		return *this;
williamr@4
  2128
		}
williamr@4
  2129
williamr@4
  2130
williamr@4
  2131
/**
williamr@4
  2132
   If automatic resource management is enabled, calls the cleanup
williamr@4
  2133
   function defined by the cleanup strategy with the managed resource
williamr@4
  2134
   handle object and then disables the automatic resource management
williamr@4
  2135
   for this object.	 The cleanup strategy is specified by the
williamr@4
  2136
   CleanupStrategy template template parameter.	 The default cleanup
williamr@4
  2137
   strategy is to call the cleanup member function on the contained
williamr@4
  2138
   resource handle object. which is a member function named Close(),
williamr@4
  2139
   unless explicitly defined otherwise for the class of the object,
williamr@4
  2140
   for example by using the provided DEFINE_CLEANUP_FUNCTION macro.
williamr@4
  2141
*/
williamr@4
  2142
	void ReleaseResource()
williamr@4
  2143
		{
williamr@4
  2144
		if (!IsEnabled())
williamr@4
  2145
			return;
williamr@4
  2146
williamr@4
  2147
		CleanupStrategy::Cleanup(&Get());
williamr@4
  2148
		LAutoHandleBase::Disable();
williamr@4
  2149
		}
williamr@4
  2150
williamr@4
  2151
/**
williamr@4
  2152
   Disables the automatic resource management for this obkect and
williamr@4
  2153
   returns a copy of the resource handle.
williamr@4
  2154
williamr@4
  2155
   @return A copy of the resource handle.
williamr@4
  2156
*/
williamr@4
  2157
	using LAutoHandleBase::Unmanage;
williamr@4
  2158
williamr@4
  2159
/**
williamr@4
  2160
   Returns ETrue if automatic resource management is enabled; EFalse
williamr@4
  2161
   otherwise.
williamr@4
  2162
williamr@4
  2163
   @return ETrue if automatic resource management is enabled; EFalse
williamr@4
  2164
   otherwise.
williamr@4
  2165
*/
williamr@4
  2166
	using LAutoHandleBase::IsEnabled;
williamr@4
  2167
williamr@4
  2168
williamr@4
  2169
/**
williamr@4
  2170
   Returns a reference to the resource handle.
williamr@4
  2171
williamr@4
  2172
   @return A reference to the resource handle.
williamr@4
  2173
*/
williamr@4
  2174
	using LAutoHandleBase::Get;
williamr@4
  2175
williamr@4
  2176
williamr@4
  2177
/**
williamr@4
  2178
   Overloaded indirection operator function.
williamr@4
  2179
williamr@4
  2180
   @return A reference to the resource handle.
williamr@4
  2181
*/
williamr@4
  2182
	using LAutoHandleBase::operator*;
williamr@4
  2183
williamr@4
  2184
/**
williamr@4
  2185
   Overloaded class member access operator function.
williamr@4
  2186
williamr@4
  2187
   @return A pointer to the resource handle.
williamr@4
  2188
*/
williamr@4
  2189
	using LAutoHandleBase::operator->;
williamr@4
  2190
williamr@4
  2191
	static void Cleanup(TAny* aPtr)
williamr@4
  2192
		{
williamr@4
  2193
		LCleanedupHandle* autoh = static_cast<LCleanedupHandle*>(aPtr);
williamr@4
  2194
williamr@4
  2195
		if (autoh->IsEnabled())
williamr@4
  2196
			{
williamr@4
  2197
			CleanupStrategy::Cleanup(&autoh->Get());
williamr@4
  2198
			}
williamr@4
  2199
		}
williamr@4
  2200
williamr@4
  2201
	using LAutoHandleBase::Disable;
williamr@4
  2202
williamr@4
  2203
	void Swap(LCleanedupHandle& aCleanedupHandle)
williamr@4
  2204
		{
williamr@4
  2205
		LAutoHandleBase::Swap(aCleanedupHandle);
williamr@4
  2206
		}
williamr@4
  2207
	};
williamr@4
  2208
williamr@4
  2209
williamr@4
  2210
/**
williamr@4
  2211
   Implementation base class - not designed for public inheritance or
williamr@4
  2212
   direct use.
williamr@4
  2213
   
williamr@4
  2214
   @internalComponent
williamr@4
  2215
*/
williamr@4
  2216
// Not for Client Use , Only to be used Internally.
williamr@4
  2217
template<typename T,
williamr@4
  2218
		 class CleanupStrategyType>
williamr@4
  2219
class LCleanedupPtrBase: protected LAutoPtrBase<typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType>
williamr@4
  2220
	{
williamr@4
  2221
	typedef LAutoPtrBase<typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType> LAutoPtrBase;
williamr@4
  2222
williamr@4
  2223
  protected:
williamr@4
  2224
	typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::ManagedType ManagedType;
williamr@4
  2225
	typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::BaseManagedType BaseManagedType;
williamr@4
  2226
	typedef typename TPtrCleanupTraits<T, CleanupStrategyType>::CleanupStrategy CleanupStrategy;
williamr@4
  2227
williamr@4
  2228
	LCleanedupPtrBase()
williamr@4
  2229
		{
williamr@4
  2230
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2231
		}
williamr@4
  2232
williamr@4
  2233
	template<typename U>
williamr@4
  2234
	explicit LCleanedupPtrBase(U* aPtr)
williamr@4
  2235
		: LAutoPtrBase(aPtr)
williamr@4
  2236
		{
williamr@4
  2237
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2238
		}
williamr@4
  2239
williamr@4
  2240
	~LCleanedupPtrBase()
williamr@4
  2241
		{
williamr@4
  2242
		ManagedPopCleanupStackItem(LAutoPtrBase::IsEnabled());
williamr@4
  2243
		}
williamr@4
  2244
williamr@4
  2245
	template<typename U>
williamr@4
  2246
	LCleanedupPtrBase& operator=(U* aPtr)
williamr@4
  2247
		{
williamr@4
  2248
		ReleaseResource();
williamr@4
  2249
		LAutoPtrBase::operator=(aPtr);
williamr@4
  2250
		return *this;
williamr@4
  2251
		}
williamr@4
  2252
williamr@4
  2253
	void ReleaseResource()
williamr@4
  2254
		{
williamr@4
  2255
		if (!LAutoPtrBase::IsEnabled())
williamr@4
  2256
			return;
williamr@4
  2257
williamr@4
  2258
		CleanupStrategy::Cleanup(static_cast<ManagedType*>(iPtr));
williamr@4
  2259
		LAutoPtrBase::Disable();
williamr@4
  2260
		}
williamr@4
  2261
williamr@4
  2262
	using LAutoPtrBase::Unmanage;
williamr@4
  2263
williamr@4
  2264
	using LAutoPtrBase::IsEnabled;
williamr@4
  2265
williamr@4
  2266
	using LAutoPtrBase::Get;
williamr@4
  2267
williamr@4
  2268
	using LAutoPtrBase::operator->;
williamr@4
  2269
williamr@4
  2270
	static void Cleanup(TAny* aPtr)
williamr@4
  2271
		{
williamr@4
  2272
		LCleanedupPtrBase* cleanupPtr = static_cast<LCleanedupPtrBase*>(aPtr);
williamr@4
  2273
williamr@4
  2274
		if (cleanupPtr->IsEnabled())
williamr@4
  2275
			{
williamr@4
  2276
			CleanupStrategy::Cleanup(static_cast<ManagedType*>(cleanupPtr->iPtr));
williamr@4
  2277
			}
williamr@4
  2278
		}
williamr@4
  2279
williamr@4
  2280
	using LAutoPtrBase::iPtr;
williamr@4
  2281
williamr@4
  2282
	void Swap(LCleanedupPtrBase& aCleanedupPtr)
williamr@4
  2283
		{
williamr@4
  2284
		LAutoPtrBase::Swap(aCleanedupPtr);
williamr@4
  2285
		}
williamr@4
  2286
	};
williamr@4
  2287
williamr@4
  2288
williamr@4
  2289
/**
williamr@4
  2290
   A class template that provides CleanupStack-based local-scope
williamr@4
  2291
   automatic management of pointers.
williamr@4
  2292
williamr@4
  2293
   @note This class can only be used to define locals, never
williamr@4
  2294
   data members. See below for an explanation and links to management
williamr@4
  2295
   classes suitable for use in different contexts. It should never be
williamr@4
  2296
   used in the same function as code that uses the CleanupStack API
williamr@4
  2297
   directly
williamr@4
  2298
williamr@4
  2299
   This class template can be used to protect a pointer to type T such
williamr@4
  2300
   that the instance of T referred to is automatically cleaned up
williamr@4
  2301
   when either of the following occur:
williamr@4
  2302
williamr@4
  2303
   - The referring local variable goes out of scope normally
williamr@4
  2304
   - The referring local variable goes out of scope due to an
williamr@4
  2305
	 untrapped leave causing the scope to be exited non-locally
williamr@4
  2306
williamr@4
  2307
   By default, the cleanup action is to delete the managed pointer
williamr@4
  2308
   using non-array delete. An alternative cleanup strategy may be
williamr@4
  2309
   selected by specifying a cleanup strategy template class in the
williamr@4
  2310
   optional second template parameter position. The most common
williamr@4
  2311
   alternative cleanup strategies are predefined.
williamr@4
  2312
williamr@4
  2313
   The constructors of this class may leave.
williamr@4
  2314
williamr@4
  2315
   As a convenience, the methods of the managed pointer may be
williamr@4
  2316
   accessed via "->" notation directly on the management object, while
williamr@4
  2317
   "." notation is used to access the interface of the management
williamr@4
  2318
   object itself. Using "*" to dereference the management object
williamr@4
  2319
   yields a T&, and is often useful when passing the managed object as
williamr@4
  2320
   an argument.
williamr@4
  2321
williamr@4
  2322
   Automatic cleanup may be disabled at any time by calling
williamr@4
  2323
   Unmanage(), while cleanup may be forced at any time by calling
williamr@4
  2324
   ReleaseResource().
williamr@4
  2325
williamr@4
  2326
   Example:
williamr@4
  2327
   @code
williamr@4
  2328
	// block scope example
williamr@4
  2329
	{
williamr@4
  2330
	LCleanedupPtr<CDynamic> autop(new(ELeave) CDynamic);
williamr@4
  2331
	autop->DoSomethingL(); // leave-safe
williamr@4
  2332
	if (autop->Finished())
williamr@4
  2333
		return; //	the pointer is deleted automatically when exiting from scope
williamr@4
  2334
	autop->DoSomethingElseL(); // leave-safe
williamr@4
  2335
	//	the pointer is deleted automatically when exiting from scope
williamr@4
  2336
	}
williamr@4
  2337
   @endcode
williamr@4
  2338
williamr@4
  2339
   Behind the scenes, this class template is implemented in terms of
williamr@4
  2340
   the thread-local CleanupStack, restricting its use to locals on the
williamr@4
  2341
   stack. This use of the CleanupStack ensures a consistent cleanup
williamr@4
  2342
   order between functions that call one another, even if they use
williamr@4
  2343
   different cleanup idioms.
williamr@4
  2344
williamr@4
  2345
   This class template together with the cleanup strategy class
williamr@4
  2346
   templates provide a template-based implementation of the Strategy
williamr@4
  2347
   design pattern (See also: Policy-based design).
williamr@4
  2348
williamr@4
  2349
   @see TPointerDelete which implements the default deleting cleanup strategy
williamr@4
  2350
   @see TPointerFree which implements the alternative User::Free() cleanup strategy
williamr@4
  2351
   @see LManagedPtr which has the same interface, but does not use the cleanup
williamr@4
  2352
   stack and is suitable for protecting the data members of classes
williamr@4
  2353
*/
williamr@4
  2354
template<typename T,
williamr@4
  2355
		 class CleanupStrategyType = TPtrCleanupStrategy>
williamr@4
  2356
class LCleanedupPtr: protected LCleanedupPtrBase<T, CleanupStrategyType>
williamr@4
  2357
	{
williamr@4
  2358
	typedef LCleanedupPtrBase<T, CleanupStrategyType> LCleanedupPtrBase;
williamr@4
  2359
williamr@4
  2360
  public:
williamr@4
  2361
	typedef T ManagedType;
williamr@4
  2362
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  2363
williamr@4
  2364
williamr@4
  2365
/**
williamr@4
  2366
   Default constructor.	 Constructs an empty LCleanedupPtr object.
williamr@4
  2367
williamr@4
  2368
   @post Get() == NULL
williamr@4
  2369
*/
williamr@4
  2370
	LCleanedupPtr()
williamr@4
  2371
		{
williamr@4
  2372
		}
williamr@4
  2373
williamr@4
  2374
/**
williamr@4
  2375
   Explicit constructor template.  Constructs a LCleanedupPtr object
williamr@4
  2376
   that manages the pointer aPtr of a type convertible to T* that can
williamr@4
  2377
   be cleaned up using the cleanup strategy of the LCleanedupPtr
williamr@4
  2378
   class.  The default cleanup strategy is to delete the pointer to a
williamr@4
  2379
   heap-allocated object by using non-array delete.	 Alternative
williamr@4
  2380
   cleanup strategies can be specified by using the CleanupStrategy
williamr@4
  2381
   template parameter of the LCleanedupPtr class template.
williamr@4
  2382
williamr@4
  2383
   @param aPtr A pointer of a type that is convertible to T* that can
williamr@4
  2384
   be cleaned up using the cleanup strategy.
williamr@4
  2385
williamr@4
  2386
   @pre aPtr is of a type convertible to T* and can be cleaned up
williamr@4
  2387
   using the cleanup strategy.
williamr@4
  2388
williamr@4
  2389
   @post Get() == aPtr
williamr@4
  2390
*/
williamr@4
  2391
	explicit LCleanedupPtr(T* aPtr)
williamr@4
  2392
		: LCleanedupPtrBase(aPtr)
williamr@4
  2393
		{
williamr@4
  2394
		}
williamr@4
  2395
williamr@4
  2396
/**
williamr@4
  2397
   Assigns a new pointer to be managed.	 The new pointer must be of a
williamr@4
  2398
   type convertible to T* and it must be possible to use the cleanup
williamr@4
  2399
   strategy of the LCleanedupPtr object for the cleanup of the new
williamr@4
  2400
   managed pointer.	 If the LCleanedupPtr object already contains a
williamr@4
  2401
   managed pointer, then the cleanup strategy is invoked with the
williamr@4
  2402
   managed pointer before assigning the new managed pointer.
williamr@4
  2403
williamr@4
  2404
   @param aPtr A pointer of a type that is convertible to T* that can
williamr@4
  2405
   be cleaned up using the cleanup strategy.
williamr@4
  2406
williamr@4
  2407
   @pre aPtr is a pointer of a type that is convertible to T* and can
williamr@4
  2408
   be cleaned up using the cleanup strategy.
williamr@4
  2409
williamr@4
  2410
   @post Get() == aPtr
williamr@4
  2411
 */
williamr@4
  2412
	LCleanedupPtr& operator=(T* aPtr)
williamr@4
  2413
		{
williamr@4
  2414
		LCleanedupPtrBase::operator=(aPtr);
williamr@4
  2415
		return *this;
williamr@4
  2416
		}
williamr@4
  2417
williamr@4
  2418
/**
williamr@4
  2419
   Assigns a new pointer to be managed.	 The new pointer must be of a
williamr@4
  2420
   type convertible to T* and it must be possible to use the cleanup
williamr@4
  2421
   strategy of the LCleanedupPtr object for the cleanup of the new
williamr@4
  2422
   managed pointer.	 If the LCleanedupPtr object already contains a
williamr@4
  2423
   managed pointer, then the cleanup strategy is invoked with the
williamr@4
  2424
   managed pointer before assigning the new managed pointer.
williamr@4
  2425
williamr@4
  2426
   @param aPtr A pointer of a type that is convertible to T* that can
williamr@4
  2427
   be cleaned up using the cleanup strategy.
williamr@4
  2428
williamr@4
  2429
   @pre aPtr is a pointer of a type that is convertible to T* and can
williamr@4
  2430
   be cleaned up using the cleanup strategy.
williamr@4
  2431
williamr@4
  2432
   @post Get() == aPtr
williamr@4
  2433
 */
williamr@4
  2434
	template<typename U>
williamr@4
  2435
	LCleanedupPtr& operator=(U* aPtr)
williamr@4
  2436
		{
williamr@4
  2437
		LCleanedupPtrBase::operator=(aPtr);
williamr@4
  2438
		return *this;
williamr@4
  2439
		}
williamr@4
  2440
williamr@4
  2441
williamr@4
  2442
/**
williamr@4
  2443
   If automatic resource management is enabled, the specified cleanup
williamr@4
  2444
   strategy is invoked with the managed pointer and the automatic
williamr@4
  2445
   resource management is then disabled.  The underlying pointer is
williamr@4
  2446
   reset to NULL.
williamr@4
  2447
williamr@4
  2448
   @post Get() == NULL
williamr@4
  2449
*/
williamr@4
  2450
	using LCleanedupPtrBase::ReleaseResource;
williamr@4
  2451
williamr@4
  2452
/**
williamr@4
  2453
   Disables the automatic resource management for this object and
williamr@4
  2454
   returns a pointer to the object of type T.
williamr@4
  2455
williamr@4
  2456
   @return A pointer to the object of type T.
williamr@4
  2457
*/
williamr@4
  2458
	T* Unmanage()
williamr@4
  2459
		{
williamr@4
  2460
		return static_cast<T*>(LCleanedupPtrBase::Unmanage());
williamr@4
  2461
		}
williamr@4
  2462
williamr@4
  2463
/**
williamr@4
  2464
   Returns ETrue if automatic resource management is enabled; EFalse
williamr@4
  2465
   otherwise.
williamr@4
  2466
williamr@4
  2467
   @return ETrue if automatic resource management is enabled; EFalse
williamr@4
  2468
   otherwise.
williamr@4
  2469
*/
williamr@4
  2470
	using LCleanedupPtrBase::IsEnabled;
williamr@4
  2471
williamr@4
  2472
/**
williamr@4
  2473
   Returns a pointer to the managed object of type T.
williamr@4
  2474
williamr@4
  2475
   @return A pointer to the managed object of type T.
williamr@4
  2476
*/
williamr@4
  2477
	T* Get() const
williamr@4
  2478
		{
williamr@4
  2479
		return static_cast<T*>(iPtr);
williamr@4
  2480
		}
williamr@4
  2481
williamr@4
  2482
/**
williamr@4
  2483
   Overloaded indirection operator function.
williamr@4
  2484
williamr@4
  2485
   @return A reference to the managed object of type T.
williamr@4
  2486
*/
williamr@4
  2487
	T& operator*() const
williamr@4
  2488
		{
williamr@4
  2489
		return *(static_cast<T*>(iPtr));
williamr@4
  2490
		}
williamr@4
  2491
williamr@4
  2492
/**
williamr@4
  2493
   Overloaded class member access operator function.
williamr@4
  2494
williamr@4
  2495
   @return A pointer to the managed object of type T.
williamr@4
  2496
*/
williamr@4
  2497
	T* operator->() const
williamr@4
  2498
		{
williamr@4
  2499
		return static_cast<T*>(iPtr);
williamr@4
  2500
		}
williamr@4
  2501
williamr@4
  2502
// Implementation type - do not use
williamr@4
  2503
	typedef typename LCleanedupPtrBase::BaseManagedType* LCleanedupPtr<T, CleanupStrategy>::*TUnspecifiedBoolType;
williamr@4
  2504
williamr@4
  2505
/**
williamr@4
  2506
   Conversion operator that enables LCleanedupPtr objects to be used
williamr@4
  2507
   in boolean contexts.
williamr@4
  2508
williamr@4
  2509
   @return An unspecified value of an unspecified type convertible to
williamr@4
  2510
   boolean, which has a boolean value equal to Get() != NULL
williamr@4
  2511
 */
williamr@4
  2512
	operator TUnspecifiedBoolType()
williamr@4
  2513
		{
williamr@4
  2514
		return iPtr ? &LCleanedupPtr::iPtr : NULL;
williamr@4
  2515
		}
williamr@4
  2516
williamr@4
  2517
	using LCleanedupPtrBase::Disable;
williamr@4
  2518
williamr@4
  2519
	void Swap(LCleanedupPtr& aCleanedupPtr)
williamr@4
  2520
		{
williamr@4
  2521
		LCleanedupPtrBase::Swap(aCleanedupPtr);
williamr@4
  2522
		}
williamr@4
  2523
williamr@4
  2524
  private:
williamr@4
  2525
	using LCleanedupPtrBase::iPtr;
williamr@4
  2526
	};
williamr@4
  2527
williamr@4
  2528
williamr@4
  2529
// function template used for comparing two LCleanedupPtr-managed
williamr@4
  2530
// pointers for equality
williamr@4
  2531
template<typename T, typename U>
williamr@4
  2532
TBool operator==(const LCleanedupPtr<T>& aPtr1, const LCleanedupPtr<U>& aPtr2)
williamr@4
  2533
	{
williamr@4
  2534
	return aPtr1.Get() == aPtr2.Get();
williamr@4
  2535
	}
williamr@4
  2536
williamr@4
  2537
// function template used for comparing two LCleanedupPtr-managed
williamr@4
  2538
// pointers for inequality
williamr@4
  2539
template<typename T, typename U>
williamr@4
  2540
TBool operator!=(const LCleanedupPtr<T>& aPtr1, const LCleanedupPtr<U>& aPtr2)
williamr@4
  2541
	{
williamr@4
  2542
	return aPtr1.Get() != aPtr2.Get();
williamr@4
  2543
	}
williamr@4
  2544
williamr@4
  2545
// function template used for testing the ordering of two
williamr@4
  2546
// LCleanedupPtr-managed pointers
williamr@4
  2547
template<typename T, typename U>
williamr@4
  2548
TBool operator<(const LCleanedupPtr<T>& aPtr1, const LCleanedupPtr<U>& aPtr2)
williamr@4
  2549
	{
williamr@4
  2550
	return aPtr1.Get() < aPtr2.Get();
williamr@4
  2551
	}
williamr@4
  2552
williamr@4
  2553
williamr@4
  2554
/**
williamr@4
  2555
   A class template that provides CleanupStack-based local-scope
williamr@4
  2556
   automatic management of arrays.
williamr@4
  2557
williamr@4
  2558
   @note This class can only be used to define locals, never
williamr@4
  2559
   data members. See below for an explanation and links to management
williamr@4
  2560
   classes suitable for use in different contexts. It should never be
williamr@4
  2561
   used in the same function as code that uses the CleanupStack API
williamr@4
  2562
   directly
williamr@4
  2563
williamr@4
  2564
   @par
williamr@4
  2565
williamr@4
  2566
   @note This class can only be used with raw arrays, which are used
williamr@4
  2567
   only rarely on Symbian OS.  Instances of Symbian array container
williamr@4
  2568
   classes (e.g. RArray, RPointerArray) should be managed using the
williamr@4
  2569
   automatic management template classes appropriate for the array's
williamr@4
  2570
   type (LCleanedupHandle template classes for Symbian R arrays or
williamr@4
  2571
   LCleanedupPtr template classes for Symbian C arrays).
williamr@4
  2572
williamr@4
  2573
   This class template can be used to protect a heap-allocated array
williamr@4
  2574
   of objects of type T such that the array of T referred to is
williamr@4
  2575
   automatically cleaned up when either of the following occur:
williamr@4
  2576
williamr@4
  2577
   - The referring local variable goes out of scope normally
williamr@4
  2578
   - The referring local variable goes out of scope due to an
williamr@4
  2579
	 untrapped leave causing the scope to be exited non-locally
williamr@4
  2580
williamr@4
  2581
   The default cleanup strategy is to deallocate the managed array
williamr@4
  2582
   using arrray delete (delete[]), assuming that the array is
williamr@4
  2583
   heap-allocated.	An alternative cleanup strategy can be selected by
williamr@4
  2584
   specifying a cleanup strategy template class as the optional second
williamr@4
  2585
   template argument (corresponding to the CleanupStrategy template
williamr@4
  2586
   parameter).
williamr@4
  2587
williamr@4
  2588
   The constructors of this class may leave.
williamr@4
  2589
williamr@4
  2590
   As a convenience, the elements of the managed array may be accessed
williamr@4
  2591
   via "[]" notation directly on the management object.
williamr@4
  2592
williamr@4
  2593
   Automatic cleanup may be disabled at any time by calling
williamr@4
  2594
   Unmanage(), while cleanup may be forced at any time by calling
williamr@4
  2595
   ReleaseResource().
williamr@4
  2596
williamr@4
  2597
   @code
williamr@4
  2598
	// block scope example
williamr@4
  2599
	{
williamr@4
  2600
	LCleanedupArray<TValue> arrayp(new(ELeave) TValue[KArraySize]);
williamr@4
  2601
	arrayp[0].DoSomethingL(); // leave-safe
williamr@4
  2602
	if (arrayp[0].Finished())
williamr@4
  2603
		return; //	the array is deleted automatically when exiting from scope
williamr@4
  2604
	arrayp[1].DoSomethingElseL(); // leave-safe
williamr@4
  2605
	//	the array is deleted automatically when exiting from scope
williamr@4
  2606
	}
williamr@4
  2607
   @endcode
williamr@4
  2608
williamr@4
  2609
   Behind the scenes, this class template is implemented in terms of
williamr@4
  2610
   the thread-local CleanupStack, restricting its use to locals on the
williamr@4
  2611
   stack. This use of the CleanupStack ensures a consistent cleanup
williamr@4
  2612
   order between functions that call one another, even if they use
williamr@4
  2613
   different cleanup idioms.
williamr@4
  2614
williamr@4
  2615
   This class template together with the cleanup strategy class
williamr@4
  2616
   templates provide a template-based implementation of the Strategy
williamr@4
  2617
   design pattern (See also: Policy-based design).
williamr@4
  2618
williamr@4
  2619
   @see LManagedArray which has the same interface, but does not use
williamr@4
  2620
   the cleanup stack and is suitable for protecting the data members
williamr@4
  2621
   of classes
williamr@4
  2622
*/
williamr@4
  2623
template<typename T,
williamr@4
  2624
		 class CleanupStrategyType = TArrayDelete>
williamr@4
  2625
class LCleanedupArray: protected LAutoPtrBase<T>
williamr@4
  2626
	{
williamr@4
  2627
	typedef LAutoPtrBase<T> LAutoPtrBase;
williamr@4
  2628
williamr@4
  2629
  public:
williamr@4
  2630
	typedef T ManagedType;
williamr@4
  2631
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  2632
williamr@4
  2633
/**
williamr@4
  2634
   Default constructor.	 Constructs an empty LCleanedupArray object.
williamr@4
  2635
williamr@4
  2636
   @post Get() == NULL
williamr@4
  2637
 */
williamr@4
  2638
	LCleanedupArray()
williamr@4
  2639
		{
williamr@4
  2640
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2641
		}
williamr@4
  2642
williamr@4
  2643
/**
williamr@4
  2644
   Explicit constructor.  Constructs a LCleanedupArray object that
williamr@4
  2645
   manages an array of objects of type T that can be cleaned up using
williamr@4
  2646
   the cleanup strategy of the LCleanedupArray class.  The default
williamr@4
  2647
   cleanup strategy is to deallocate the heap-allocated array by using
williamr@4
  2648
   array delete.  An alternative cleanup strategy can be selected by
williamr@4
  2649
   specifying a cleanup strategy template class as the optional second
williamr@4
  2650
   template argument (corresponding to the CleanupStrategy template
williamr@4
  2651
   parameter).
williamr@4
  2652
williamr@4
  2653
   @param aPtr A pointer to the first element of an array of objects
williamr@4
  2654
   of type T, array that can be cleaned up using the cleanup strategy
williamr@4
  2655
   of the the LCleanedupArray class.
williamr@4
  2656
williamr@4
  2657
   @pre The array can be cleaned up using the cleanup strategy.
williamr@4
  2658
williamr@4
  2659
   @post Get() == aPtr
williamr@4
  2660
 */
williamr@4
  2661
	explicit LCleanedupArray(T* aPtr)
williamr@4
  2662
		: LAutoPtrBase(aPtr)
williamr@4
  2663
		{
williamr@4
  2664
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2665
		}
williamr@4
  2666
williamr@4
  2667
williamr@4
  2668
/**
williamr@4
  2669
   Destructor.	When automatic resource management is enabled, the
williamr@4
  2670
   destructor invokes the specified cleanup strategy for the managed
williamr@4
  2671
   pointer.
williamr@4
  2672
 */
williamr@4
  2673
	~LCleanedupArray()
williamr@4
  2674
		{
williamr@4
  2675
		ManagedPopCleanupStackItem(LAutoPtrBase::IsEnabled());
williamr@4
  2676
		}
williamr@4
  2677
williamr@4
  2678
/**
williamr@4
  2679
   Assigns a new array of objects of type T to be managed.	It needs
williamr@4
  2680
   to be be possible to use the cleanup strategy of the
williamr@4
  2681
   LCleanedupArray object for the cleanup of the new managed array.
williamr@4
  2682
   The default cleanup strategy is to delete the heap-allocated array
williamr@4
  2683
   by using array delete (delete[]).  If the LCleanedupArray object
williamr@4
  2684
   already manages an array, then the cleanup strategy is invoked with
williamr@4
  2685
   the managed array before assigning the new managed array.
williamr@4
  2686
williamr@4
  2687
   @param aPtr A pointer to the first element of the array of objects
williamr@4
  2688
   of type T - array that can be cleaned up using the cleanup
williamr@4
  2689
   strategy.
williamr@4
  2690
williamr@4
  2691
   @pre The new array to be managed can be cleaned up using the
williamr@4
  2692
   cleanup strategy.
williamr@4
  2693
williamr@4
  2694
   @post Get() == aPtr
williamr@4
  2695
 */
williamr@4
  2696
	LCleanedupArray& operator=(T* aPtr)
williamr@4
  2697
		{
williamr@4
  2698
		ReleaseResource();
williamr@4
  2699
		LAutoPtrBase::operator=(aPtr);
williamr@4
  2700
		return *this;
williamr@4
  2701
		}
williamr@4
  2702
williamr@4
  2703
/**
williamr@4
  2704
   If automatic resource management is enabled, the specified cleanup
williamr@4
  2705
   strategy is invoked for the managed pointer and the automatic
williamr@4
  2706
   resource management is then disabled.  The underlying pointer is
williamr@4
  2707
   reset to NULL.
williamr@4
  2708
williamr@4
  2709
   @post Get() == NULL
williamr@4
  2710
*/
williamr@4
  2711
	void ReleaseResource()
williamr@4
  2712
		{
williamr@4
  2713
		if (!LAutoPtrBase::IsEnabled())
williamr@4
  2714
			return;
williamr@4
  2715
williamr@4
  2716
		CleanupStrategy::Cleanup(iPtr);
williamr@4
  2717
		iPtr = NULL;
williamr@4
  2718
		}
williamr@4
  2719
williamr@4
  2720
williamr@4
  2721
/**
williamr@4
  2722
   Disables the automatic resource management for this object and
williamr@4
  2723
   returns a pointer to the first element of the array of objects of
williamr@4
  2724
   type T.
williamr@4
  2725
williamr@4
  2726
   @return A pointer to the first element of the array of objects of
williamr@4
  2727
   type T.
williamr@4
  2728
*/
williamr@4
  2729
	using LAutoPtrBase::Unmanage;
williamr@4
  2730
williamr@4
  2731
/**
williamr@4
  2732
   Returns ETrue if automatic resource management is enabled; EFalse
williamr@4
  2733
   otherwise.
williamr@4
  2734
williamr@4
  2735
   @return ETrue if automatic resource management is enabled; EFalse
williamr@4
  2736
   otherwise.
williamr@4
  2737
*/
williamr@4
  2738
	using LAutoPtrBase::IsEnabled;
williamr@4
  2739
williamr@4
  2740
/**
williamr@4
  2741
   Returns a pointer to the first element of the managed array of
williamr@4
  2742
   objects of type T.
williamr@4
  2743
williamr@4
  2744
   @return A pointer to the first element of the managed array of
williamr@4
  2745
   objects of type T.
williamr@4
  2746
*/
williamr@4
  2747
	using LAutoPtrBase::Get;
williamr@4
  2748
williamr@4
  2749
/**
williamr@4
  2750
   Overloaded subscript operator.
williamr@4
  2751
williamr@4
  2752
   @return A reference to the object of type T at the position aIndex.
williamr@4
  2753
 */
williamr@4
  2754
	T& operator[](TInt aIndex) const
williamr@4
  2755
		{
williamr@4
  2756
		return iPtr[aIndex];
williamr@4
  2757
		}
williamr@4
  2758
williamr@4
  2759
	static void Cleanup(TAny* aPtr)
williamr@4
  2760
		{
williamr@4
  2761
		LCleanedupArray* cleanupPtr = static_cast<LCleanedupArray*>(aPtr);
williamr@4
  2762
williamr@4
  2763
		if (cleanupPtr->IsEnabled())
williamr@4
  2764
			{
williamr@4
  2765
			CleanupStrategy::Cleanup(cleanupPtr->iPtr);
williamr@4
  2766
			}
williamr@4
  2767
		}
williamr@4
  2768
williamr@4
  2769
	using LAutoPtrBase::Disable;
williamr@4
  2770
williamr@4
  2771
	void Swap(LCleanedupArray& aArray)
williamr@4
  2772
		{
williamr@4
  2773
		LAutoPtrBase::Swap(aArray);
williamr@4
  2774
		}
williamr@4
  2775
williamr@4
  2776
  private:
williamr@4
  2777
	using LAutoPtrBase::iPtr;
williamr@4
  2778
	};
williamr@4
  2779
williamr@4
  2780
williamr@4
  2781
/**
williamr@4
  2782
   A class template that provides CleanupStack-based local-scope
williamr@4
  2783
   automatic management of references to resource handles (often
williamr@4
  2784
   instances of R-classes).
williamr@4
  2785
williamr@4
  2786
   @note This class can only be used to define locals, never
williamr@4
  2787
   data members. See below for an explanation and links to management
williamr@4
  2788
   classes suitable for use in different contexts. It should never be
williamr@4
  2789
   used in the same function as code that uses the CleanupStack API
williamr@4
  2790
   directly.
williamr@4
  2791
williamr@4
  2792
   Unlike LCleanedupHandle which creates a fresh instance of its
williamr@4
  2793
   managed type, this class template can be used to reference and
williamr@4
  2794
   protect an existing resource handle of type T (typically an
williamr@4
  2795
   R-class). The instance of T referred to has a cleanup operation run
williamr@4
  2796
   on it automatically when either of the following occur:
williamr@4
  2797
williamr@4
  2798
   - The referring local variable goes out of scope normally
williamr@4
  2799
   - The referring local variable goes out of scope due to an
williamr@4
  2800
	 untrapped leave causing the scope to be exited non-locally
williamr@4
  2801
williamr@4
  2802
   By default, the cleanup action is to call the Close() member
williamr@4
  2803
   function of the referenced handle. An alternative cleanup strategy
williamr@4
  2804
   may be selected by specifying a cleanup strategy template class in
williamr@4
  2805
   the optional second template parameter position. The most common
williamr@4
  2806
   alternative cleanup strategies are predefined. It is also possible
williamr@4
  2807
   to specialize the default cleanup action for a given class using
williamr@4
  2808
   the DEFINE_CLEANUP_FUNCTION macro.
williamr@4
  2809
williamr@4
  2810
   The constructors of this class may leave.
williamr@4
  2811
williamr@4
  2812
   As a convenience, the methods of the managed handle may be
williamr@4
  2813
   accessed via "->" notation directly on the management object, while
williamr@4
  2814
   "." notation is used to access the interface of the management
williamr@4
  2815
   object itself. Using "*" to dereference the management object
williamr@4
  2816
   yields a T&, and is often useful when passing the managed object as
williamr@4
  2817
   an argument.
williamr@4
  2818
williamr@4
  2819
   Automatic cleanup may be disabled at any time by calling
williamr@4
  2820
   Unmanage(), while cleanup may be forced at any time by calling
williamr@4
  2821
   ReleaseResource().
williamr@4
  2822
williamr@4
  2823
   Example:
williamr@4
  2824
   @code
williamr@4
  2825
	// block scope example
williamr@4
  2826
	void DoWithClosable(RClosable& aObj)
williamr@4
  2827
	  {
williamr@4
  2828
	  LCleanedupRef<RClosable> obj(aObj);
williamr@4
  2829
	  obj->DoSomethingL(); // leave-safe
williamr@4
  2830
	  if (obj->Finished())
williamr@4
  2831
		return; // RClosable::Close is invoked automatically
williamr@4
  2832
	  obj->DoSomethingElseL(); // leave-safe
williamr@4
  2833
	  // RClosable::Close is invoked automatically
williamr@4
  2834
	  }
williamr@4
  2835
   @endcode
williamr@4
  2836
williamr@4
  2837
   Behind the scenes, this class template is implemented in terms of
williamr@4
  2838
   the thread-local CleanupStack, restricting its use to locals on the
williamr@4
  2839
   stack. This use of the CleanupStack ensures a consistent cleanup
williamr@4
  2840
   order between functions that call one another, even if they use
williamr@4
  2841
   different cleanup idioms.
williamr@4
  2842
williamr@4
  2843
   This class template together with the cleanup strategy class
williamr@4
  2844
   templates provide a template-based implementation of the Strategy
williamr@4
  2845
   design pattern (See also: Policy-based design).
williamr@4
  2846
williamr@4
  2847
   @see TClose which implements the default Close() calling cleanup strategy
williamr@4
  2848
   @see TResetAndDestroy which implements an alternative
williamr@4
  2849
   ResetAndDestroy() calling cleanup strategy
williamr@4
  2850
   @see TFree which implements an alternative Free() calling cleanup
williamr@4
  2851
   strategy
williamr@4
  2852
   @see TDestroy which implements an alternative Destroy() calling
williamr@4
  2853
   cleanup strategy
williamr@4
  2854
   @see TRelease which implements an alternative Release() calling
williamr@4
  2855
   cleanup strategy
williamr@4
  2856
   @see LManagedRef which has the same interface, but does not use
williamr@4
  2857
   the cleanup stack and is suitable for protecting the data members of
williamr@4
  2858
   classes
williamr@4
  2859
   @see LCleanedupHandle which has a similar interface but creates a
williamr@4
  2860
   fresh local instance of T
williamr@4
  2861
*/
williamr@4
  2862
template<typename T,
williamr@4
  2863
		 class CleanupStrategyType = TResourceCleanupStrategy>
williamr@4
  2864
class LCleanedupRef: protected LAutoRefBase<T>
williamr@4
  2865
	{
williamr@4
  2866
	typedef LAutoRefBase<T> LAutoRefBase;
williamr@4
  2867
williamr@4
  2868
  public:
williamr@4
  2869
	typedef T ManagedType;
williamr@4
  2870
	typedef CleanupStrategyType CleanupStrategy;
williamr@4
  2871
williamr@4
  2872
/**
williamr@4
  2873
   Explicit constructor.
williamr@4
  2874
 */
williamr@4
  2875
	template<typename U>
williamr@4
  2876
	explicit LCleanedupRef(U& aRef)
williamr@4
  2877
		: LAutoRefBase(aRef)
williamr@4
  2878
		{
williamr@4
  2879
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  2880
		}
williamr@4
  2881
williamr@4
  2882
/**
williamr@4
  2883
   Destructor.	When automatic resource management is enabled, the
williamr@4
  2884
   destructor invokes the specified cleanup strategy for the managed
williamr@4
  2885
   reference.
williamr@4
  2886
 */
williamr@4
  2887
	~LCleanedupRef()
williamr@4
  2888
		{
williamr@4
  2889
		ManagedPopCleanupStackItem(LAutoRefBase::IsEnabled());
williamr@4
  2890
		}
williamr@4
  2891
williamr@4
  2892
/**
williamr@4
  2893
   Assigns a new reference to be managed.  If the LCleanedupRef
williamr@4
  2894
   object already contains a managed reference, then the specified
williamr@4
  2895
   cleanup strategy is invoked for the managed reference before
williamr@4
  2896
   assigning the new managed reference.
williamr@4
  2897
 */
williamr@4
  2898
	template<typename U>
williamr@4
  2899
	LCleanedupRef& operator=(U& aRef)
williamr@4
  2900
		{
williamr@4
  2901
		ReleaseResource();
williamr@4
  2902
		LAutoRefBase::operator=(aRef);
williamr@4
  2903
		return *this;
williamr@4
  2904
		}
williamr@4
  2905
williamr@4
  2906
/**
williamr@4
  2907
   If automatic resource management is enabled, the specified cleanup
williamr@4
  2908
   strategy is invoked for the managed reference and the automatic
williamr@4
  2909
   resource management is then disabled.
williamr@4
  2910
*/
williamr@4
  2911
	void ReleaseResource()
williamr@4
  2912
		{
williamr@4
  2913
		if (!LAutoRefBase::IsEnabled())
williamr@4
  2914
			return;
williamr@4
  2915
williamr@4
  2916
		CleanupStrategy::Cleanup(iPtr);
williamr@4
  2917
		iPtr = NULL;
williamr@4
  2918
		}
williamr@4
  2919
williamr@4
  2920
/**
williamr@4
  2921
   Disables the automatic resource management for this object and
williamr@4
  2922
   returns a reference to the object of type T.
williamr@4
  2923
williamr@4
  2924
   @return A reference to the object of type T.
williamr@4
  2925
*/
williamr@4
  2926
	using LAutoRefBase::Unmanage;
williamr@4
  2927
williamr@4
  2928
/**
williamr@4
  2929
   Returns ETrue if automatic resource management is enabled; EFalse
williamr@4
  2930
   otherwise.
williamr@4
  2931
williamr@4
  2932
   @return ETrue if automatic resource management is enabled; EFalse
williamr@4
  2933
   otherwise.
williamr@4
  2934
*/
williamr@4
  2935
	using LAutoRefBase::IsEnabled;
williamr@4
  2936
williamr@4
  2937
/**
williamr@4
  2938
   Returns a reference to the managed object of type T.
williamr@4
  2939
williamr@4
  2940
   @return A reference to the managed object of type T.
williamr@4
  2941
*/
williamr@4
  2942
	using LAutoRefBase::Get;
williamr@4
  2943
williamr@4
  2944
/**
williamr@4
  2945
   Overloaded indirection operator function.
williamr@4
  2946
williamr@4
  2947
   @return A reference to the managed object of type T.
williamr@4
  2948
*/
williamr@4
  2949
	using LAutoRefBase::operator*;
williamr@4
  2950
williamr@4
  2951
/**
williamr@4
  2952
   Overloaded class member access operator function.
williamr@4
  2953
williamr@4
  2954
   @return A pointer to the managed object of type T.
williamr@4
  2955
*/
williamr@4
  2956
	using LAutoRefBase::operator->;
williamr@4
  2957
williamr@4
  2958
williamr@4
  2959
	static void Cleanup(TAny* aPtr)
williamr@4
  2960
		{
williamr@4
  2961
		LCleanedupRef* cleanupRef = static_cast<LCleanedupRef*>(aPtr);
williamr@4
  2962
williamr@4
  2963
		if (cleanupRef->IsEnabled())
williamr@4
  2964
			{
williamr@4
  2965
			CleanupStrategy::Cleanup(cleanupRef->iPtr);
williamr@4
  2966
			}
williamr@4
  2967
		}
williamr@4
  2968
williamr@4
  2969
	using LAutoRefBase::Disable;
williamr@4
  2970
williamr@4
  2971
	void Swap(LCleanedupRef& aRef)
williamr@4
  2972
		{
williamr@4
  2973
		LAutoRefBase::Swap(aRef);
williamr@4
  2974
		}
williamr@4
  2975
williamr@4
  2976
  private:
williamr@4
  2977
	using LAutoRefBase::iPtr;
williamr@4
  2978
	};
williamr@4
  2979
williamr@4
  2980
williamr@4
  2981
/**
williamr@4
  2982
   A class that provides automatic cleanup using a TCleanupOperation
williamr@4
  2983
   on the destruction of the LManagedGuard object.
williamr@4
  2984
williamr@4
  2985
   @note This class can only be used to define object scoped cleanup
williamr@4
  2986
   to guard object destruction, never local stack scoped cleanup. See
williamr@4
  2987
   below for an explanation and links to management classes suitable
williamr@4
  2988
   for use in different contexts.
williamr@4
  2989
williamr@4
  2990
   This class can be used to manage a TCleanupOperation in such a way
williamr@4
  2991
   that the specified cleanup operation is guaranteed to be called
williamr@4
  2992
   when the guarding object is destroyed; typically when the object
williamr@4
  2993
   containing it is deleted.
williamr@4
  2994
williamr@4
  2995
   The constructors of this class never leave, so data members defined with
williamr@4
  2996
   this type may be initialized safely during any phase of
williamr@4
  2997
   construction of the owning class.
williamr@4
  2998
williamr@4
  2999
   Automatic cleanup may be disabled at any time by calling
williamr@4
  3000
   Dismiss(), while cleanup may be forced at any time by calling
williamr@4
  3001
   Execute().
williamr@4
  3002
williamr@4
  3003
   @code
williamr@4
  3004
   class CComposite : public CBase
williamr@4
  3005
	   {
williamr@4
  3006
	 public:
williamr@4
  3007
	   CONSTRUCTORS_MAY_LEAVE
williamr@4
  3008
williamr@4
  3009
	   CComposite(RCleanable* aObj)
williamr@4
  3010
		   : iObj(RCleanable::Cleanup, aObj)
williamr@4
  3011
		   {
williamr@4
  3012
		   }
williamr@4
  3013
williamr@4
  3014
	   ~CComposite()
williamr@4
  3015
		   {
williamr@4
  3016
		   // RCleanable::Cleanup(iObj) is automatically invoked
williamr@4
  3017
		   }
williamr@4
  3018
williamr@4
  3019
	 private:
williamr@4
  3020
	   LManagedGuard<RCleanable> iObj;
williamr@4
  3021
	   };
williamr@4
  3022
   @endcode
williamr@4
  3023
williamr@4
  3024
   Behind the scenes, this class template simply relies on reliable
williamr@4
  3025
   execution of its destructor. If used for a local variable rather
williamr@4
  3026
   than a data member, cleanup will occur but out-of-order compared to
williamr@4
  3027
   objects protected using the LCleanupXxx variants or the
williamr@4
  3028
   CleanupStack directly. Therefore it is not recommended for use in
williamr@4
  3029
   that context.
williamr@4
  3030
williamr@4
  3031
   These management classes may be used as the basis for implementing
williamr@4
  3032
   leave-safe single-phase construction, since fully initialized
williamr@4
  3033
   data members protected in this way will get destroyed (so reliably
williamr@4
  3034
   triggering cleanup) if their containing classes leave during
williamr@4
  3035
   execution of their constructors. Note, however, that single-phase
williamr@4
  3036
   construction must be explicitly enabled in the containing class
williamr@4
  3037
   using the CONSTRUCTORS_MAY_LEAVE macro.
williamr@4
  3038
williamr@4
  3039
   @see LCleanedupGuard which has the same interface, but uses the cleanup
williamr@4
  3040
   stack and is suitable for use as a local to guard local scope exit
williamr@4
  3041
   @see CONSTRUCTORS_MAY_LEAVE
williamr@4
  3042
*/
williamr@4
  3043
class LManagedGuard
williamr@4
  3044
	{
williamr@4
  3045
  public:
williamr@4
  3046
/**
williamr@4
  3047
   Constructor.	 Creates a LCleanedupGuard object that, when enabled,
williamr@4
  3048
   automatically invokes upon destruction a cleanup operation
williamr@4
  3049
   specified by the aCleanupOperation parameter with the pointer to
williamr@4
  3050
   data specified by the aData parameter.
williamr@4
  3051
williamr@4
  3052
   @param aCleanupOperation A cleanup operation.
williamr@4
  3053
   @param aData Pointer to data to be passed to the cleanup operation
williamr@4
  3054
 */
williamr@4
  3055
	LManagedGuard(TCleanupOperation aCleanupOperation, TAny* aData = 0)
williamr@4
  3056
		: iCleanupOperation(aCleanupOperation),
williamr@4
  3057
		  iData(aData)
williamr@4
  3058
		{
williamr@4
  3059
		}
williamr@4
  3060
williamr@4
  3061
/**
williamr@4
  3062
   Destructor.
williamr@4
  3063
 */
williamr@4
  3064
	~LManagedGuard()
williamr@4
  3065
		{
williamr@4
  3066
		Execute();
williamr@4
  3067
		}
williamr@4
  3068
williamr@4
  3069
/**
williamr@4
  3070
   Executes the guard cleanup operation.
williamr@4
  3071
*/
williamr@4
  3072
	void Execute()
williamr@4
  3073
		{
williamr@4
  3074
		if (iCleanupOperation)
williamr@4
  3075
			{
williamr@4
  3076
			iCleanupOperation(iData);
williamr@4
  3077
			}
williamr@4
  3078
		}
williamr@4
  3079
williamr@4
  3080
/**
williamr@4
  3081
   Disables the guard.
williamr@4
  3082
*/
williamr@4
  3083
	void Dismiss()
williamr@4
  3084
		{
williamr@4
  3085
		iCleanupOperation = NULL;
williamr@4
  3086
		}
williamr@4
  3087
williamr@4
  3088
  private:
williamr@4
  3089
	LManagedGuard(const LManagedGuard&);
williamr@4
  3090
	LManagedGuard& operator=(const LManagedGuard&);
williamr@4
  3091
williamr@4
  3092
	TCleanupOperation iCleanupOperation;
williamr@4
  3093
	TAny* iData;
williamr@4
  3094
	};
williamr@4
  3095
williamr@4
  3096
williamr@4
  3097
/**
williamr@4
  3098
   A class that provides CleanupStack-based local-scope automatic
williamr@4
  3099
   cleanup using a TCleanupOperation on the destruction of the
williamr@4
  3100
   LManagedGuard object.
williamr@4
  3101
williamr@4
  3102
   @note This class can only be used to define a local stack scoped
williamr@4
  3103
   cleanup, never an object scoped cleanup to guard object
williamr@4
  3104
   destruction. See below for an explanation and links to management
williamr@4
  3105
   classes suitable for use in different contexts.
williamr@4
  3106
williamr@4
  3107
   This class can be used to manage a TCleanupOperation in such a way
williamr@4
  3108
   that the specified cleanup operation is guaranteed to be called
williamr@4
  3109
   when either of the following occur:
williamr@4
  3110
williamr@4
  3111
   - The guarding local variable goes out of scope normally
williamr@4
  3112
   - The guarding local variable goes out of scope due to an
williamr@4
  3113
	 untrapped leave causing the scope to be exited non-locally
williamr@4
  3114
williamr@4
  3115
   The constructors of this class may leave.
williamr@4
  3116
williamr@4
  3117
   Automatic cleanup may be disabled at any time by calling
williamr@4
  3118
   Dismiss(), while cleanup may be forced at any time by calling
williamr@4
  3119
   Execute().
williamr@4
  3120
williamr@4
  3121
   @code
williamr@4
  3122
	// block scope example
williamr@4
  3123
	{
williamr@4
  3124
	RCleanable obj;
williamr@4
  3125
	LCleanedupGuard cleanGuard(RCleanable::Cleanup, &obj);
williamr@4
  3126
williamr@4
  3127
	obj.DoSomethingL(); // leave-safe
williamr@4
  3128
	if (Finished())
williamr@4
  3129
		return; // RCleanable::Cleanup is invoked automatically when exiting from scope
williamr@4
  3130
	obj.DoSomethingElseL(); // leave-safe
williamr@4
  3131
	//	RCleanable::Cleanup is invoked automatically when exiting from scope
williamr@4
  3132
	}
williamr@4
  3133
   @endcode
williamr@4
  3134
williamr@4
  3135
   Behind the scenes, this class template is implemented in terms of
williamr@4
  3136
   the thread-local CleanupStack, restricting its use to local stack
williamr@4
  3137
   scope. This use of the CleanupStack ensures a consistent cleanup
williamr@4
  3138
   order between functions that call one another, even if they use
williamr@4
  3139
   different cleanup idioms.
williamr@4
  3140
williamr@4
  3141
   @see LManagedGuard which has the same interface, but does not use the cleanup
williamr@4
  3142
   stack and is suitable for use as the data member of a class to guard
williamr@4
  3143
   object destruction.
williamr@4
  3144
*/
williamr@4
  3145
class LCleanedupGuard
williamr@4
  3146
	{
williamr@4
  3147
  public:
williamr@4
  3148
/**
williamr@4
  3149
   Constructor.	 Creates a LCleanedupGuard object that, when enabled,
williamr@4
  3150
   automatically invokes upon destruction a cleanup operation
williamr@4
  3151
   specified by the aCleanupOperation parameter with the pointer to
williamr@4
  3152
   data specified by the aData parameter.
williamr@4
  3153
williamr@4
  3154
   @param aCleanupOperation A cleanup operation.
williamr@4
  3155
   @param aData Pointer to data to be passed to the cleanup operation
williamr@4
  3156
 */
williamr@4
  3157
	LCleanedupGuard(TCleanupOperation aCleanupOperation, TAny* aData = 0)
williamr@4
  3158
		: iCleanupOperation(aCleanupOperation),
williamr@4
  3159
		  iData(aData)
williamr@4
  3160
		{
williamr@4
  3161
		CleanupStack::PushL(TCleanupItem(Cleanup, this));
williamr@4
  3162
		}
williamr@4
  3163
williamr@4
  3164
/**
williamr@4
  3165
   Destructor.
williamr@4
  3166
 */
williamr@4
  3167
	~LCleanedupGuard()
williamr@4
  3168
		{
williamr@4
  3169
		ManagedPopCleanupStackItem(iCleanupOperation);
williamr@4
  3170
		}
williamr@4
  3171
williamr@4
  3172
/**
williamr@4
  3173
   Executes the guard cleanup operation.
williamr@4
  3174
*/
williamr@4
  3175
	void Execute()
williamr@4
  3176
		{
williamr@4
  3177
		if (iCleanupOperation)
williamr@4
  3178
			{
williamr@4
  3179
			iCleanupOperation(iData);
williamr@4
  3180
			}
williamr@4
  3181
		}
williamr@4
  3182
williamr@4
  3183
/**
williamr@4
  3184
   Disables the guard.
williamr@4
  3185
*/
williamr@4
  3186
	void Dismiss()
williamr@4
  3187
		{
williamr@4
  3188
		iCleanupOperation = NULL;
williamr@4
  3189
		}
williamr@4
  3190
williamr@4
  3191
	static void Cleanup(TAny* aPtr)
williamr@4
  3192
		{
williamr@4
  3193
		LCleanedupGuard* guard = static_cast<LCleanedupGuard*>(aPtr);
williamr@4
  3194
		guard->Execute();
williamr@4
  3195
		}
williamr@4
  3196
williamr@4
  3197
  private:
williamr@4
  3198
	LCleanedupGuard(const LCleanedupGuard&);
williamr@4
  3199
	LCleanedupGuard& operator=(const LCleanedupGuard&);
williamr@4
  3200
williamr@4
  3201
williamr@4
  3202
	TCleanupOperation iCleanupOperation;
williamr@4
  3203
	TAny* iData;
williamr@4
  3204
	};
williamr@4
  3205
williamr@4
  3206
#endif // !EMANAGED_H
williamr@4
  3207