os/textandloc/textrendering/textformatting/undo/UniqueInstance.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#ifndef UNIQUEINSTANCE_H_
sl@0
    20
#define UNIQUEINSTANCE_H_
sl@0
    21
sl@0
    22
#include "UniqueInstanceBase.h"
sl@0
    23
sl@0
    24
// A user may only create and destroy the repository. All access is through the
sl@0
    25
// RUniqueInstance class.
sl@0
    26
//
sl@0
    27
// Please note : Deleting the repository is unsafe unless all of its owned
sl@0
    28
// objects have been destroyed or relinquished. If objects exist in the repository
sl@0
    29
// (and provided that no RUniqueInstance objects have leaked) it follows that
sl@0
    30
// there must be RUniqueInstance objects around that still reference these objects.
sl@0
    31
// These RUniqueInstances will at some point try to access the repository to
sl@0
    32
// relinquish or destroy these objects, but it will have been deleted! Therefore
sl@0
    33
// the destructor panics if there are any objects in the repository.
sl@0
    34
//
sl@0
    35
// The compare function and copy function must co-operate like this:
sl@0
    36
// A) aCompare is a total order. That is, for all valid objects of type T t, u and v:
sl@0
    37
//	i)	aCompare(t, t) == 0									(idempotency)
sl@0
    38
//	ii)	if aCompare(t, u) < 0 then aCompare(u, t) > 0		(associativity)
sl@0
    39
//	iii)if aCompare(t, u) < 0 and aCompare(u, v) < 0 then aCompare(t, v) < 0
sl@0
    40
//															(transitivity)
sl@0
    41
// B) aCopyL always produces objects that compare equal to the arguments that
sl@0
    42
//		produced them, that is for all valid objects of type T t:
sl@0
    43
//	aCompare(t, aCopyL(t, sizeof(T))) == 0			(ignoring the memory leak!)
sl@0
    44
// If these conditions are not met, the behaviour of the repository is undefined.
sl@0
    45
// If the type does not own anything and does not have variable length, the
sl@0
    46
// copy and delete functions can be omitted.
sl@0
    47
//
sl@0
    48
// The operation of the repository and its clients is not thread safe.
sl@0
    49
//
sl@0
    50
// For aMaxLinks give half the log(base 2) of the expected maximum size of the
sl@0
    51
// repository. So for a repository of size 256, use 4. For size 65535 use 8. For
sl@0
    52
// 16777216 use 12.
sl@0
    53
sl@0
    54
/**
sl@0
    55
Store of objects that coalesces repeated instances.
sl@0
    56
sl@0
    57
@since App-frameworks6.1
sl@0
    58
@internalComponent
sl@0
    59
*/
sl@0
    60
template <typename T> class CUniqueInstanceRepository
sl@0
    61
	: public UniqueInstance::CUniqueInstanceRepositoryBase
sl@0
    62
sl@0
    63
	{
sl@0
    64
public:
sl@0
    65
sl@0
    66
	// typical implementation might be:
sl@0
    67
	//	void CompareT(const T* aL, const T* aR)
sl@0
    68
	//		{
sl@0
    69
	//		if (*aL == *aR)
sl@0
    70
	//			return 0;
sl@0
    71
	//		if (*aL < *aR)
sl@0
    72
	//			return -1;
sl@0
    73
	//		return 1;
sl@0
    74
	//		}
sl@0
    75
	typedef TInt TCompareFnType(const T*, const T*);
sl@0
    76
sl@0
    77
	// typical implementation might be:
sl@0
    78
	//	void DeleteT(T* aDestroy)
sl@0
    79
	//		{
sl@0
    80
	//		delete aDestroy;
sl@0
    81
	//		}
sl@0
    82
	typedef void TDeleteFnType(T* aObjectToBeDestroyed);
sl@0
    83
sl@0
    84
	// typical implementation might be:
sl@0
    85
	//	T* CopyT(const T* aSrc, TInt aOffset, TInt)
sl@0
    86
	//		{
sl@0
    87
	//		return new(ELeave) T(*aSrc);
sl@0
    88
	//		}
sl@0
    89
	typedef T* TCopyFnTypeL(const T* aTToBeCopied, TInt aSizeOfT);
sl@0
    90
sl@0
    91
	/**
sl@0
    92
	 * Creates a new empty repository. aCompare must define a total order on
sl@0
    93
	 * objects that may be added to the repository. In other words
sl@0
    94
	 * aCompare(a,b) == 0 iff a and b are equivalent, aCompare(a,b) < 0
sl@0
    95
	 * iff aCompare(a,b) > 0, aCompare(a,b) < 0 iff aCompare(b,a) < 0 and
sl@0
    96
	 * aCompare(a,b) < 0 && aCompare(b,c) < 0 implies that aCompare(a,c) < 0.
sl@0
    97
	 * aDelete(a) deletes a and aCopyL(a) generates a new object such that
sl@0
    98
	 * aCompare(aCopyL(a),a) == 0.
sl@0
    99
	 * aMaxLinks concerns the space against speed tradeoff of the
sl@0
   100
	 * implementation. It should be a number greater than half log2 of the
sl@0
   101
	 * expected maximum size of the repository.
sl@0
   102
	 */
sl@0
   103
	static inline CUniqueInstanceRepository<T>* NewL(TCompareFnType* aCompare,
sl@0
   104
		TDeleteFnType* aDelete, TCopyFnTypeL* aCopyL, TInt aMaxLinks = 10);
sl@0
   105
	static inline CUniqueInstanceRepository<T>* NewLC(TCompareFnType* aCompare,
sl@0
   106
		TDeleteFnType* aDelete, TCopyFnTypeL* aCopyL, TInt aMaxLinks = 10);
sl@0
   107
	/**
sl@0
   108
	 * Creates a new empty repository with aDelete(a) simply freeing memory
sl@0
   109
	 * at a and aCopyL(a) simply bitwise copying the memory occupied by a.
sl@0
   110
	 * This is suitable only if T has no destructor and only the automatic
sl@0
   111
	 * copy constructor.
sl@0
   112
	 */
sl@0
   113
	static inline CUniqueInstanceRepository<T>* NewL(TCompareFnType* aCompare,
sl@0
   114
		TInt aMaxLinks = 10);
sl@0
   115
	static inline CUniqueInstanceRepository<T>* NewLC(TCompareFnType* aCompare,
sl@0
   116
		TInt aMaxLinks = 10);
sl@0
   117
private:
sl@0
   118
	CUniqueInstanceRepository() {}
sl@0
   119
	};
sl@0
   120
sl@0
   121
/**
sl@0
   122
Specialization for the odd semantics of TDes. Copy/Delete/Compare functions
sl@0
   123
are provided free.
sl@0
   124
sl@0
   125
@since App-frameworks6.1
sl@0
   126
@internalComponent
sl@0
   127
*/
sl@0
   128
template <> class CUniqueInstanceRepository<TDes>
sl@0
   129
	: public UniqueInstance::CUniqueInstanceRepositoryBase
sl@0
   130
sl@0
   131
	{
sl@0
   132
	CUniqueInstanceRepository() {}
sl@0
   133
	static void* DesCopyL(void*, TInt);
sl@0
   134
	static TInt DesCompare(void*, void*);
sl@0
   135
	static void DesDelete(void*);
sl@0
   136
public:
sl@0
   137
	static inline CUniqueInstanceRepository<TDes>* NewL(TInt aMaxLinks = 10);
sl@0
   138
	static inline CUniqueInstanceRepository<TDes>* NewLC(TInt aMaxLinks = 10);
sl@0
   139
	};
sl@0
   140
sl@0
   141
/**
sl@0
   142
Client of a CUniqueInstanceRepository.
sl@0
   143
Holds a single object, which may be shared.
sl@0
   144
sl@0
   145
@since App-frameworks6.1
sl@0
   146
@internalComponent
sl@0
   147
*/
sl@0
   148
template <typename T> class RUniqueInstance
sl@0
   149
sl@0
   150
	{
sl@0
   151
public:
sl@0
   152
	inline explicit RUniqueInstance(CUniqueInstanceRepository<T>& aRepository)
sl@0
   153
		: iImpl(aRepository) {}
sl@0
   154
	/**
sl@0
   155
	 * Destructor. In debug builds this asserts that no object is owned.
sl@0
   156
	 */
sl@0
   157
	inline ~RUniqueInstance() {}
sl@0
   158
sl@0
   159
	/**
sl@0
   160
	 * Registers the argument as a unique instance, to be referenced by this
sl@0
   161
	 * RUniqueInstance. Any previously owned object is destroyed.
sl@0
   162
	 */
sl@0
   163
	inline void TakeL(T* aToAdd);
sl@0
   164
	/**
sl@0
   165
	 * Makes a copy of the argument, as a unique instance. The argument is
sl@0
   166
	 * still owned by the caller
sl@0
   167
	 */
sl@0
   168
	inline void TakeCopyL(const T* aToCopy);
sl@0
   169
	/**
sl@0
   170
	 * Returns a pointer to the referenced object without passing ownership
sl@0
   171
	 */
sl@0
   172
	inline const T* Peek() const;
sl@0
   173
	/**
sl@0
   174
	 * Makes another instance of the same object: both have ownership
sl@0
   175
	 */
sl@0
   176
	inline void CopyTo(RUniqueInstance<T>& aOther) const;
sl@0
   177
	/**
sl@0
   178
	 * Pass ownership of the owned object to another RUniqueInstance.
sl@0
   179
	 * This object may not be referenced through this RUniqueInstance any
sl@0
   180
	 * more, only through aOther.
sl@0
   181
	 */
sl@0
   182
	inline void MoveTo(RUniqueInstance<T>& aOther);
sl@0
   183
	/**
sl@0
   184
	 * Relinquishes ownership of the object to the caller. The object is
sl@0
   185
	 * not destroyed. It may not be referenced through this RUniqueInstance
sl@0
   186
	 * any more. The pointer returned may be different from that passed
sl@0
   187
	 * to TakeL() or returned from Peek()
sl@0
   188
	 */
sl@0
   189
	inline T* DropL();
sl@0
   190
	/**
sl@0
   191
	 * Releases the owned object.
sl@0
   192
	 */
sl@0
   193
	inline void Close();
sl@0
   194
sl@0
   195
private:
sl@0
   196
	UniqueInstance::RInstanceImpl iImpl;
sl@0
   197
	};
sl@0
   198
sl@0
   199
/**
sl@0
   200
Specialization of RUniqueInstance for the odd semantics of TDes.
sl@0
   201
Any descriptor that needs ownership to be passed around is an HBufC.
sl@0
   202
Any time a copy or view over a descriptor is required, a const TDesC
sl@0
   203
is used. Please note the different signature of NewL and NewLC. This is
sl@0
   204
because copy, delete and compare functions are provided for free.
sl@0
   205
sl@0
   206
@since App-frameworks6.1
sl@0
   207
@internalComponent
sl@0
   208
*/
sl@0
   209
TEMPLATE_SPECIALIZATION class RUniqueInstance<TDes>
sl@0
   210
sl@0
   211
	{
sl@0
   212
public:
sl@0
   213
	inline explicit RUniqueInstance(CUniqueInstanceRepository<TDes>& aRepository)
sl@0
   214
		: iImpl(aRepository) {}
sl@0
   215
	inline ~RUniqueInstance() {}
sl@0
   216
	inline void TakeL(HBufC* aToAdd);
sl@0
   217
	inline void TakeCopyL(const TDesC* aToCopy);
sl@0
   218
	inline const TDesC* Peek() const;
sl@0
   219
	inline void CopyTo(RUniqueInstance<TDes>& aOther) const;
sl@0
   220
	inline void MoveTo(RUniqueInstance<TDes>& aOther);
sl@0
   221
	inline HBufC* DropL();
sl@0
   222
	inline void Close();
sl@0
   223
sl@0
   224
private:
sl@0
   225
	UniqueInstance::RInstanceImpl iImpl;
sl@0
   226
	};
sl@0
   227
sl@0
   228
template <typename T>
sl@0
   229
inline CUniqueInstanceRepository<T>* CUniqueInstanceRepository<T>::NewLC(
sl@0
   230
	typename CUniqueInstanceRepository<T>::TCompareFnType* aCompare,
sl@0
   231
	typename CUniqueInstanceRepository<T>::TDeleteFnType* aDelete,
sl@0
   232
	typename CUniqueInstanceRepository<T>::TCopyFnTypeL* aCopyL, TInt aMaxLinks)
sl@0
   233
	{
sl@0
   234
	CUniqueInstanceRepository<T>* that = new(ELeave) CUniqueInstanceRepository<T>;
sl@0
   235
	CleanupStack::PushL(that);
sl@0
   236
	that->ConstructL(reinterpret_cast<UniqueInstance::TCompareFn*>(aCompare),
sl@0
   237
		reinterpret_cast<UniqueInstance::TDeleteFn*>(aDelete),
sl@0
   238
		reinterpret_cast<UniqueInstance::TCopyFnL*>(aCopyL), aMaxLinks,
sl@0
   239
		sizeof(T));
sl@0
   240
	return that;
sl@0
   241
	}
sl@0
   242
sl@0
   243
template <typename T>
sl@0
   244
inline CUniqueInstanceRepository<T>* CUniqueInstanceRepository<T>::NewL(
sl@0
   245
	typename CUniqueInstanceRepository<T>::TCompareFnType* aComp,
sl@0
   246
	typename CUniqueInstanceRepository<T>::TDeleteFnType* aDel,
sl@0
   247
	typename CUniqueInstanceRepository<T>::TCopyFnTypeL* aCopyL, TInt aMaxLinks)
sl@0
   248
	{
sl@0
   249
	CUniqueInstanceRepository<T>* that = NewLC(aComp, aDel, aCopyL, aMaxLinks);
sl@0
   250
	CleanupStack::Pop(that);
sl@0
   251
	return that;
sl@0
   252
	}
sl@0
   253
sl@0
   254
template <typename T>
sl@0
   255
inline CUniqueInstanceRepository<T>* CUniqueInstanceRepository<T>::NewLC(
sl@0
   256
	typename CUniqueInstanceRepository<T>::TCompareFnType* aCompare, TInt aMaxLinks)
sl@0
   257
	{
sl@0
   258
	CUniqueInstanceRepository<T>* that = new(ELeave) CUniqueInstanceRepository<T>;
sl@0
   259
	CleanupStack::PushL(that);
sl@0
   260
	that->ConstructL(reinterpret_cast<UniqueInstance::TCompareFn*>(aCompare),
sl@0
   261
		DumbDelete, DumbCopyL, aMaxLinks,
sl@0
   262
		sizeof(T));
sl@0
   263
	return that;
sl@0
   264
	}
sl@0
   265
sl@0
   266
template <typename T>
sl@0
   267
inline CUniqueInstanceRepository<T>* CUniqueInstanceRepository<T>::NewL(
sl@0
   268
	typename CUniqueInstanceRepository<T>::TCompareFnType* aComp, TInt aMaxLinks)
sl@0
   269
	{
sl@0
   270
	CUniqueInstanceRepository<T>* that = NewLC(aComp, aMaxLinks);
sl@0
   271
	CleanupStack::Pop(that);
sl@0
   272
	return that;
sl@0
   273
	}
sl@0
   274
sl@0
   275
inline CUniqueInstanceRepository<TDes>* CUniqueInstanceRepository<TDes>::NewLC(
sl@0
   276
	TInt aMaxLinks)
sl@0
   277
	{
sl@0
   278
	CUniqueInstanceRepository<TDes>* that = new(ELeave) CUniqueInstanceRepository<TDes>;
sl@0
   279
	CleanupStack::PushL(that);
sl@0
   280
	that->ConstructL(DesCompare, DesDelete, DesCopyL, aMaxLinks, 1);
sl@0
   281
	return that;
sl@0
   282
	}
sl@0
   283
sl@0
   284
inline CUniqueInstanceRepository<TDes>* CUniqueInstanceRepository<TDes>::NewL(
sl@0
   285
	TInt aMaxLinks)
sl@0
   286
	{
sl@0
   287
	CUniqueInstanceRepository<TDes>* that = NewLC(aMaxLinks);
sl@0
   288
	CleanupStack::Pop(that);
sl@0
   289
	return that;
sl@0
   290
	}
sl@0
   291
sl@0
   292
///////////////////////////////
sl@0
   293
//							 //
sl@0
   294
//	RUniqueInstance inlines  //
sl@0
   295
//							 //
sl@0
   296
///////////////////////////////
sl@0
   297
sl@0
   298
template <typename T> inline
sl@0
   299
void RUniqueInstance<T>::TakeL(T* aToAdd)
sl@0
   300
	{ iImpl.TakeL(aToAdd); }
sl@0
   301
template <typename T> inline
sl@0
   302
void RUniqueInstance<T>::TakeCopyL(const T* aToCopy)
sl@0
   303
	{ iImpl.TakeCopyL(const_cast<T*>(aToCopy)); }
sl@0
   304
template <typename T> inline
sl@0
   305
const T* RUniqueInstance<T>::Peek() const
sl@0
   306
	{ return reinterpret_cast<const T*>(iImpl.Peek()); }
sl@0
   307
template <typename T> inline
sl@0
   308
void RUniqueInstance<T>::CopyTo(RUniqueInstance<T>& aOther) const
sl@0
   309
	{ iImpl.CopyTo(aOther.iImpl); }
sl@0
   310
template <typename T> inline
sl@0
   311
void RUniqueInstance<T>::MoveTo(RUniqueInstance<T>& aOther)
sl@0
   312
	{ iImpl.MoveTo(aOther.iImpl); }
sl@0
   313
template <typename T> inline
sl@0
   314
T* RUniqueInstance<T>::DropL()
sl@0
   315
	{ return reinterpret_cast<T*>(iImpl.DropL()); }
sl@0
   316
template <typename T> inline
sl@0
   317
void RUniqueInstance<T>::Close()
sl@0
   318
	{ iImpl.Close(); }
sl@0
   319
sl@0
   320
inline void RUniqueInstance<TDes>::TakeL(HBufC* aToAdd)
sl@0
   321
	{ iImpl.TakeL(aToAdd); }
sl@0
   322
inline void RUniqueInstance<TDes>::TakeCopyL(const TDesC* aToCopy)
sl@0
   323
	{ iImpl.TakeCopyL(const_cast<TDesC*>(aToCopy)); }
sl@0
   324
inline const TDesC* RUniqueInstance<TDes>::Peek() const
sl@0
   325
	{ return reinterpret_cast<HBufC*>(iImpl.Peek()); }
sl@0
   326
inline void RUniqueInstance<TDes>::CopyTo(RUniqueInstance<TDes>& aOther) const
sl@0
   327
	{ iImpl.CopyTo(aOther.iImpl); }
sl@0
   328
inline void RUniqueInstance<TDes>::MoveTo(RUniqueInstance<TDes>& aOther)
sl@0
   329
	{ iImpl.MoveTo(aOther.iImpl); }
sl@0
   330
inline HBufC* RUniqueInstance<TDes>::DropL()
sl@0
   331
	{ return reinterpret_cast<HBufC*>(iImpl.DropL()); }
sl@0
   332
inline void RUniqueInstance<TDes>::Close()
sl@0
   333
	{ iImpl.Close(); }
sl@0
   334
sl@0
   335
#endif	// UNIQUEINSTANCE_H_