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