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.
     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_