Update contrib.
2 * Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #ifndef UNIQUEINSTANCE_H_
20 #define UNIQUEINSTANCE_H_
22 #include "UniqueInstanceBase.h"
24 // A user may only create and destroy the repository. All access is through the
25 // RUniqueInstance class.
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.
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
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.
48 // The operation of the repository and its clients is not thread safe.
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
55 Store of objects that coalesces repeated instances.
57 @since App-frameworks6.1
60 template <typename T> class CUniqueInstanceRepository
61 : public UniqueInstance::CUniqueInstanceRepositoryBase
66 // typical implementation might be:
67 // void CompareT(const T* aL, const T* aR)
75 typedef TInt TCompareFnType(const T*, const T*);
77 // typical implementation might be:
78 // void DeleteT(T* aDestroy)
82 typedef void TDeleteFnType(T* aObjectToBeDestroyed);
84 // typical implementation might be:
85 // T* CopyT(const T* aSrc, TInt aOffset, TInt)
87 // return new(ELeave) T(*aSrc);
89 typedef T* TCopyFnTypeL(const T* aTToBeCopied, TInt aSizeOfT);
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.
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);
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
113 static inline CUniqueInstanceRepository<T>* NewL(TCompareFnType* aCompare,
114 TInt aMaxLinks = 10);
115 static inline CUniqueInstanceRepository<T>* NewLC(TCompareFnType* aCompare,
116 TInt aMaxLinks = 10);
118 CUniqueInstanceRepository() {}
122 Specialization for the odd semantics of TDes. Copy/Delete/Compare functions
125 @since App-frameworks6.1
128 template <> class CUniqueInstanceRepository<TDes>
129 : public UniqueInstance::CUniqueInstanceRepositoryBase
132 CUniqueInstanceRepository() {}
133 static void* DesCopyL(void*, TInt);
134 static TInt DesCompare(void*, void*);
135 static void DesDelete(void*);
137 static inline CUniqueInstanceRepository<TDes>* NewL(TInt aMaxLinks = 10);
138 static inline CUniqueInstanceRepository<TDes>* NewLC(TInt aMaxLinks = 10);
142 Client of a CUniqueInstanceRepository.
143 Holds a single object, which may be shared.
145 @since App-frameworks6.1
148 template <typename T> class RUniqueInstance
152 inline explicit RUniqueInstance(CUniqueInstanceRepository<T>& aRepository)
153 : iImpl(aRepository) {}
155 * Destructor. In debug builds this asserts that no object is owned.
157 inline ~RUniqueInstance() {}
160 * Registers the argument as a unique instance, to be referenced by this
161 * RUniqueInstance. Any previously owned object is destroyed.
163 inline void TakeL(T* aToAdd);
165 * Makes a copy of the argument, as a unique instance. The argument is
166 * still owned by the caller
168 inline void TakeCopyL(const T* aToCopy);
170 * Returns a pointer to the referenced object without passing ownership
172 inline const T* Peek() const;
174 * Makes another instance of the same object: both have ownership
176 inline void CopyTo(RUniqueInstance<T>& aOther) const;
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.
182 inline void MoveTo(RUniqueInstance<T>& aOther);
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()
191 * Releases the owned object.
196 UniqueInstance::RInstanceImpl iImpl;
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.
206 @since App-frameworks6.1
209 TEMPLATE_SPECIALIZATION class RUniqueInstance<TDes>
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();
225 UniqueInstance::RInstanceImpl iImpl;
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)
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,
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)
249 CUniqueInstanceRepository<T>* that = NewLC(aComp, aDel, aCopyL, aMaxLinks);
250 CleanupStack::Pop(that);
254 template <typename T>
255 inline CUniqueInstanceRepository<T>* CUniqueInstanceRepository<T>::NewLC(
256 typename CUniqueInstanceRepository<T>::TCompareFnType* aCompare, TInt aMaxLinks)
258 CUniqueInstanceRepository<T>* that = new(ELeave) CUniqueInstanceRepository<T>;
259 CleanupStack::PushL(that);
260 that->ConstructL(reinterpret_cast<UniqueInstance::TCompareFn*>(aCompare),
261 DumbDelete, DumbCopyL, aMaxLinks,
266 template <typename T>
267 inline CUniqueInstanceRepository<T>* CUniqueInstanceRepository<T>::NewL(
268 typename CUniqueInstanceRepository<T>::TCompareFnType* aComp, TInt aMaxLinks)
270 CUniqueInstanceRepository<T>* that = NewLC(aComp, aMaxLinks);
271 CleanupStack::Pop(that);
275 inline CUniqueInstanceRepository<TDes>* CUniqueInstanceRepository<TDes>::NewLC(
278 CUniqueInstanceRepository<TDes>* that = new(ELeave) CUniqueInstanceRepository<TDes>;
279 CleanupStack::PushL(that);
280 that->ConstructL(DesCompare, DesDelete, DesCopyL, aMaxLinks, 1);
284 inline CUniqueInstanceRepository<TDes>* CUniqueInstanceRepository<TDes>::NewL(
287 CUniqueInstanceRepository<TDes>* that = NewLC(aMaxLinks);
288 CleanupStack::Pop(that);
292 ///////////////////////////////
294 // RUniqueInstance inlines //
296 ///////////////////////////////
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()
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()
335 #endif // UNIQUEINSTANCE_H_