diff -r 000000000000 -r bde4ae8d615e os/textandloc/textrendering/textformatting/undo/UniqueInstance.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/textandloc/textrendering/textformatting/undo/UniqueInstance.h Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,335 @@ +/* +* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef UNIQUEINSTANCE_H_ +#define UNIQUEINSTANCE_H_ + +#include "UniqueInstanceBase.h" + +// A user may only create and destroy the repository. All access is through the +// RUniqueInstance class. +// +// Please note : Deleting the repository is unsafe unless all of its owned +// objects have been destroyed or relinquished. If objects exist in the repository +// (and provided that no RUniqueInstance objects have leaked) it follows that +// there must be RUniqueInstance objects around that still reference these objects. +// These RUniqueInstances will at some point try to access the repository to +// relinquish or destroy these objects, but it will have been deleted! Therefore +// the destructor panics if there are any objects in the repository. +// +// The compare function and copy function must co-operate like this: +// A) aCompare is a total order. That is, for all valid objects of type T t, u and v: +// i) aCompare(t, t) == 0 (idempotency) +// ii) if aCompare(t, u) < 0 then aCompare(u, t) > 0 (associativity) +// iii)if aCompare(t, u) < 0 and aCompare(u, v) < 0 then aCompare(t, v) < 0 +// (transitivity) +// B) aCopyL always produces objects that compare equal to the arguments that +// produced them, that is for all valid objects of type T t: +// aCompare(t, aCopyL(t, sizeof(T))) == 0 (ignoring the memory leak!) +// If these conditions are not met, the behaviour of the repository is undefined. +// If the type does not own anything and does not have variable length, the +// copy and delete functions can be omitted. +// +// The operation of the repository and its clients is not thread safe. +// +// For aMaxLinks give half the log(base 2) of the expected maximum size of the +// repository. So for a repository of size 256, use 4. For size 65535 use 8. For +// 16777216 use 12. + +/** +Store of objects that coalesces repeated instances. + +@since App-frameworks6.1 +@internalComponent +*/ +template class CUniqueInstanceRepository + : public UniqueInstance::CUniqueInstanceRepositoryBase + + { +public: + + // typical implementation might be: + // void CompareT(const T* aL, const T* aR) + // { + // if (*aL == *aR) + // return 0; + // if (*aL < *aR) + // return -1; + // return 1; + // } + typedef TInt TCompareFnType(const T*, const T*); + + // typical implementation might be: + // void DeleteT(T* aDestroy) + // { + // delete aDestroy; + // } + typedef void TDeleteFnType(T* aObjectToBeDestroyed); + + // typical implementation might be: + // T* CopyT(const T* aSrc, TInt aOffset, TInt) + // { + // return new(ELeave) T(*aSrc); + // } + typedef T* TCopyFnTypeL(const T* aTToBeCopied, TInt aSizeOfT); + + /** + * Creates a new empty repository. aCompare must define a total order on + * objects that may be added to the repository. In other words + * aCompare(a,b) == 0 iff a and b are equivalent, aCompare(a,b) < 0 + * iff aCompare(a,b) > 0, aCompare(a,b) < 0 iff aCompare(b,a) < 0 and + * aCompare(a,b) < 0 && aCompare(b,c) < 0 implies that aCompare(a,c) < 0. + * aDelete(a) deletes a and aCopyL(a) generates a new object such that + * aCompare(aCopyL(a),a) == 0. + * aMaxLinks concerns the space against speed tradeoff of the + * implementation. It should be a number greater than half log2 of the + * expected maximum size of the repository. + */ + static inline CUniqueInstanceRepository* NewL(TCompareFnType* aCompare, + TDeleteFnType* aDelete, TCopyFnTypeL* aCopyL, TInt aMaxLinks = 10); + static inline CUniqueInstanceRepository* NewLC(TCompareFnType* aCompare, + TDeleteFnType* aDelete, TCopyFnTypeL* aCopyL, TInt aMaxLinks = 10); + /** + * Creates a new empty repository with aDelete(a) simply freeing memory + * at a and aCopyL(a) simply bitwise copying the memory occupied by a. + * This is suitable only if T has no destructor and only the automatic + * copy constructor. + */ + static inline CUniqueInstanceRepository* NewL(TCompareFnType* aCompare, + TInt aMaxLinks = 10); + static inline CUniqueInstanceRepository* NewLC(TCompareFnType* aCompare, + TInt aMaxLinks = 10); +private: + CUniqueInstanceRepository() {} + }; + +/** +Specialization for the odd semantics of TDes. Copy/Delete/Compare functions +are provided free. + +@since App-frameworks6.1 +@internalComponent +*/ +template <> class CUniqueInstanceRepository + : public UniqueInstance::CUniqueInstanceRepositoryBase + + { + CUniqueInstanceRepository() {} + static void* DesCopyL(void*, TInt); + static TInt DesCompare(void*, void*); + static void DesDelete(void*); +public: + static inline CUniqueInstanceRepository* NewL(TInt aMaxLinks = 10); + static inline CUniqueInstanceRepository* NewLC(TInt aMaxLinks = 10); + }; + +/** +Client of a CUniqueInstanceRepository. +Holds a single object, which may be shared. + +@since App-frameworks6.1 +@internalComponent +*/ +template class RUniqueInstance + + { +public: + inline explicit RUniqueInstance(CUniqueInstanceRepository& aRepository) + : iImpl(aRepository) {} + /** + * Destructor. In debug builds this asserts that no object is owned. + */ + inline ~RUniqueInstance() {} + + /** + * Registers the argument as a unique instance, to be referenced by this + * RUniqueInstance. Any previously owned object is destroyed. + */ + inline void TakeL(T* aToAdd); + /** + * Makes a copy of the argument, as a unique instance. The argument is + * still owned by the caller + */ + inline void TakeCopyL(const T* aToCopy); + /** + * Returns a pointer to the referenced object without passing ownership + */ + inline const T* Peek() const; + /** + * Makes another instance of the same object: both have ownership + */ + inline void CopyTo(RUniqueInstance& aOther) const; + /** + * Pass ownership of the owned object to another RUniqueInstance. + * This object may not be referenced through this RUniqueInstance any + * more, only through aOther. + */ + inline void MoveTo(RUniqueInstance& aOther); + /** + * Relinquishes ownership of the object to the caller. The object is + * not destroyed. It may not be referenced through this RUniqueInstance + * any more. The pointer returned may be different from that passed + * to TakeL() or returned from Peek() + */ + inline T* DropL(); + /** + * Releases the owned object. + */ + inline void Close(); + +private: + UniqueInstance::RInstanceImpl iImpl; + }; + +/** +Specialization of RUniqueInstance for the odd semantics of TDes. +Any descriptor that needs ownership to be passed around is an HBufC. +Any time a copy or view over a descriptor is required, a const TDesC +is used. Please note the different signature of NewL and NewLC. This is +because copy, delete and compare functions are provided for free. + +@since App-frameworks6.1 +@internalComponent +*/ +TEMPLATE_SPECIALIZATION class RUniqueInstance + + { +public: + inline explicit RUniqueInstance(CUniqueInstanceRepository& aRepository) + : iImpl(aRepository) {} + inline ~RUniqueInstance() {} + inline void TakeL(HBufC* aToAdd); + inline void TakeCopyL(const TDesC* aToCopy); + inline const TDesC* Peek() const; + inline void CopyTo(RUniqueInstance& aOther) const; + inline void MoveTo(RUniqueInstance& aOther); + inline HBufC* DropL(); + inline void Close(); + +private: + UniqueInstance::RInstanceImpl iImpl; + }; + +template +inline CUniqueInstanceRepository* CUniqueInstanceRepository::NewLC( + typename CUniqueInstanceRepository::TCompareFnType* aCompare, + typename CUniqueInstanceRepository::TDeleteFnType* aDelete, + typename CUniqueInstanceRepository::TCopyFnTypeL* aCopyL, TInt aMaxLinks) + { + CUniqueInstanceRepository* that = new(ELeave) CUniqueInstanceRepository; + CleanupStack::PushL(that); + that->ConstructL(reinterpret_cast(aCompare), + reinterpret_cast(aDelete), + reinterpret_cast(aCopyL), aMaxLinks, + sizeof(T)); + return that; + } + +template +inline CUniqueInstanceRepository* CUniqueInstanceRepository::NewL( + typename CUniqueInstanceRepository::TCompareFnType* aComp, + typename CUniqueInstanceRepository::TDeleteFnType* aDel, + typename CUniqueInstanceRepository::TCopyFnTypeL* aCopyL, TInt aMaxLinks) + { + CUniqueInstanceRepository* that = NewLC(aComp, aDel, aCopyL, aMaxLinks); + CleanupStack::Pop(that); + return that; + } + +template +inline CUniqueInstanceRepository* CUniqueInstanceRepository::NewLC( + typename CUniqueInstanceRepository::TCompareFnType* aCompare, TInt aMaxLinks) + { + CUniqueInstanceRepository* that = new(ELeave) CUniqueInstanceRepository; + CleanupStack::PushL(that); + that->ConstructL(reinterpret_cast(aCompare), + DumbDelete, DumbCopyL, aMaxLinks, + sizeof(T)); + return that; + } + +template +inline CUniqueInstanceRepository* CUniqueInstanceRepository::NewL( + typename CUniqueInstanceRepository::TCompareFnType* aComp, TInt aMaxLinks) + { + CUniqueInstanceRepository* that = NewLC(aComp, aMaxLinks); + CleanupStack::Pop(that); + return that; + } + +inline CUniqueInstanceRepository* CUniqueInstanceRepository::NewLC( + TInt aMaxLinks) + { + CUniqueInstanceRepository* that = new(ELeave) CUniqueInstanceRepository; + CleanupStack::PushL(that); + that->ConstructL(DesCompare, DesDelete, DesCopyL, aMaxLinks, 1); + return that; + } + +inline CUniqueInstanceRepository* CUniqueInstanceRepository::NewL( + TInt aMaxLinks) + { + CUniqueInstanceRepository* that = NewLC(aMaxLinks); + CleanupStack::Pop(that); + return that; + } + +/////////////////////////////// +// // +// RUniqueInstance inlines // +// // +/////////////////////////////// + +template inline +void RUniqueInstance::TakeL(T* aToAdd) + { iImpl.TakeL(aToAdd); } +template inline +void RUniqueInstance::TakeCopyL(const T* aToCopy) + { iImpl.TakeCopyL(const_cast(aToCopy)); } +template inline +const T* RUniqueInstance::Peek() const + { return reinterpret_cast(iImpl.Peek()); } +template inline +void RUniqueInstance::CopyTo(RUniqueInstance& aOther) const + { iImpl.CopyTo(aOther.iImpl); } +template inline +void RUniqueInstance::MoveTo(RUniqueInstance& aOther) + { iImpl.MoveTo(aOther.iImpl); } +template inline +T* RUniqueInstance::DropL() + { return reinterpret_cast(iImpl.DropL()); } +template inline +void RUniqueInstance::Close() + { iImpl.Close(); } + +inline void RUniqueInstance::TakeL(HBufC* aToAdd) + { iImpl.TakeL(aToAdd); } +inline void RUniqueInstance::TakeCopyL(const TDesC* aToCopy) + { iImpl.TakeCopyL(const_cast(aToCopy)); } +inline const TDesC* RUniqueInstance::Peek() const + { return reinterpret_cast(iImpl.Peek()); } +inline void RUniqueInstance::CopyTo(RUniqueInstance& aOther) const + { iImpl.CopyTo(aOther.iImpl); } +inline void RUniqueInstance::MoveTo(RUniqueInstance& aOther) + { iImpl.MoveTo(aOther.iImpl); } +inline HBufC* RUniqueInstance::DropL() + { return reinterpret_cast(iImpl.DropL()); } +inline void RUniqueInstance::Close() + { iImpl.Close(); } + +#endif // UNIQUEINSTANCE_H_