Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

501 lines
12 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. ARRTEMPL.H
  5. Abstract:
  6. This file defines a simple template for an array of arbitrary pointers.
  7. Actual growing array functionality is provided by CFlexArray.
  8. Classes defined:
  9. template CPointerArray
  10. History:
  11. 11/27/96 a-levn Compiles.
  12. --*/
  13. #ifndef __ARRAY_TEMPLATE__H_
  14. #define __ARRAY_TEMPLATE__H_
  15. #pragma warning(disable:4786)
  16. #include <map>
  17. #include <strutils.h>
  18. using namespace std;
  19. class wcsless : public binary_function<LPWSTR, LPWSTR, bool>
  20. {
  21. public:
  22. bool operator()(const LPWSTR& wcs1, const LPWSTR& wcs2) const
  23. {return wcscmp(wcs1, wcs2) < 0;}
  24. };
  25. class wcsiless : public binary_function<LPWSTR, LPWSTR, bool>
  26. {
  27. public:
  28. bool operator()(const LPWSTR& wcs1, const LPWSTR& wcs2) const
  29. {return wbem_wcsicmp(wcs1, wcs2) < 0;}
  30. };
  31. class CReleaseMe
  32. {
  33. protected:
  34. IUnknown* m_pUnk;
  35. public:
  36. CReleaseMe(IUnknown* pUnk) : m_pUnk(pUnk){}
  37. ~CReleaseMe() { release();}
  38. void release() { if(m_pUnk) m_pUnk->Release(); m_pUnk=0;}
  39. };
  40. template<class T>
  41. class CTemplateReleaseMe
  42. {
  43. protected:
  44. T* m_p;
  45. public:
  46. CTemplateReleaseMe(T* p) : m_p(p){}
  47. ~CTemplateReleaseMe() { release();}
  48. void release(){ if(m_p) m_p->Release();m_p=0;}
  49. };
  50. template<class T>
  51. class CDeleteMe
  52. {
  53. protected:
  54. T* m_p;
  55. public:
  56. CDeleteMe(T* p = NULL) : m_p(p){}
  57. ~CDeleteMe() {delete m_p;}
  58. // overwrites the previous pointer, does NOT delete it
  59. void operator= (T* p) {m_p = p;}
  60. };
  61. class CCloseMe
  62. {
  63. protected:
  64. HANDLE m_h;
  65. public:
  66. CCloseMe(HANDLE hToClose){m_h = hToClose;};
  67. ~CCloseMe(){if(m_h && m_h != INVALID_HANDLE_VALUE)CloseHandle(m_h);};
  68. };
  69. class CfcloseMe
  70. {
  71. protected:
  72. FILE * m_h;
  73. public:
  74. CfcloseMe(FILE * ToClose){m_h = ToClose;};
  75. ~CfcloseMe(){if(m_h != NULL)fclose(m_h);};
  76. };
  77. typedef CCloseMe CCloseHandle;
  78. class CRegCloseMe
  79. {
  80. protected:
  81. HKEY m_h;
  82. public:
  83. CRegCloseMe(HKEY hToClose){m_h = hToClose;};
  84. ~CRegCloseMe(){if(m_h)RegCloseKey(m_h);};
  85. };
  86. template<class T>
  87. class CVectorDeleteMe
  88. {
  89. protected:
  90. T* m_p;
  91. T** m_pp;
  92. public:
  93. CVectorDeleteMe(T* p) : m_p(p), m_pp(NULL){}
  94. CVectorDeleteMe(T** pp) : m_p(NULL), m_pp(pp){}
  95. ~CVectorDeleteMe() {if(m_p) delete [] m_p; else if(m_pp) delete [] *m_pp;}
  96. };
  97. class CClearMe
  98. {
  99. protected:
  100. VARIANT* m_pv;
  101. public:
  102. CClearMe(VARIANT* pv) : m_pv(pv){}
  103. ~CClearMe() {VariantClear(m_pv);}
  104. };
  105. class CSysFreeMe
  106. {
  107. protected:
  108. BSTR m_str;
  109. public:
  110. CSysFreeMe(BSTR str) : m_str(str){}
  111. ~CSysFreeMe() { if ( NULL != m_str ) SysFreeString(m_str);}
  112. };
  113. class CUnaccessMe
  114. {
  115. protected:
  116. SAFEARRAY* m_psa;
  117. public:
  118. CUnaccessMe(SAFEARRAY* psa) : m_psa(psa){}
  119. ~CUnaccessMe() {SafeArrayUnaccessData(m_psa);}
  120. };
  121. class CMemFreeMe
  122. {
  123. protected:
  124. void* m_pMem;
  125. public:
  126. CMemFreeMe( void* pMem ) : m_pMem(pMem){}
  127. ~CMemFreeMe() { if ( NULL != m_pMem ) CoTaskMemFree(m_pMem);}
  128. };
  129. #include <arena.h>
  130. #include <flexarry.h>
  131. #include <flexq.h>
  132. #include <smallarr.h>
  133. //*****************************************************************************
  134. //
  135. // class CPointerArray
  136. //
  137. // Array of pointers to TMember, where TMember is any class. See CFlexArray
  138. // in coredll\flexarry.h/cpp for documentation.
  139. //
  140. //*****************************************************************************
  141. template <class TMember>
  142. class CNullManager
  143. {
  144. public:
  145. void AddRefElement(TMember*){}
  146. void ReleaseElement(TMember*){}
  147. };
  148. template <class TMember, class TManager = CNullManager<TMember>,
  149. class TArray = CFlexArray>
  150. class CPointerArray
  151. {
  152. protected:
  153. TArray m_Array;
  154. TManager m_Manager;
  155. public:
  156. CPointerArray(const TManager& Manager = TManager())
  157. : m_Manager(Manager){}
  158. ~CPointerArray();
  159. int GetSize() const
  160. {return m_Array.Size();}
  161. void SetSize(int nNewSize)
  162. {m_Array.SetSize(nNewSize);}
  163. const TMember* GetAt(int nIndex) const
  164. {return (TMember*)m_Array.GetAt(nIndex);}
  165. TMember* GetAt(int nIndex)
  166. {return (TMember*)m_Array.GetAt(nIndex);}
  167. const TMember* operator[](int nIndex) const
  168. {return (TMember*)m_Array.GetAt(nIndex);}
  169. TMember* operator[](int nIndex)
  170. {return (TMember*)m_Array.GetAt(nIndex);}
  171. void SetAt(int nIndex, TMember* pElement, TMember** ppOld = NULL);
  172. void Discard(int nIndex);
  173. bool RemoveAt(int nIndex, TMember** ppOld = NULL);
  174. bool InsertAt(int nIndex, TMember* pElement);
  175. int Add(TMember* pElement);
  176. TMember** GetArrayPtr();
  177. TMember** UnbindPtr();
  178. void RemoveAll();
  179. void Swap(int nIndex1, int nIndex2);
  180. void Trim() {m_Array.Trim();}
  181. protected:
  182. void AddRefElement(TMember* p){m_Manager.AddRefElement(p);}
  183. void ReleaseElement(TMember* p){m_Manager.ReleaseElement(p);}
  184. };
  185. template<class TMember>
  186. class CPointerSmallArray :
  187. public CPointerArray<TMember, CNullManager<TMember>, CSmallArray>
  188. {
  189. };
  190. //*****************************************************************************
  191. //
  192. // class CPointerQueue
  193. //
  194. // Queue of pointers to TMember, where TMember is any class. See CFlexQueue
  195. // in coredll\flexq.h/cpp for documentation.
  196. //
  197. //*****************************************************************************
  198. template <class TMember, class TManager = CNullManager<TMember> >
  199. class CPointerQueue
  200. {
  201. protected:
  202. CFlexQueue m_Queue;
  203. TManager m_Manager;
  204. public:
  205. CPointerQueue(int nInitialSize = 1, const TManager& Manager = TManager())
  206. : m_Manager(Manager), m_Queue(nInitialSize){}
  207. void Clear();
  208. ~CPointerQueue()
  209. {Clear();}
  210. inline int GetQueueSize() const
  211. {return m_Queue.GetQueueSize();}
  212. bool Enqueue(TMember* pNew)
  213. {
  214. AddRefElement(pNew);
  215. return m_Queue.Enqueue(pNew);
  216. }
  217. TMember* Dequeue()
  218. {
  219. TMember* p = (TMember*)m_Queue.Dequeue();
  220. return p;
  221. }
  222. bool Requeue(TMember* pNew)
  223. {
  224. AddRefElement(pNew);
  225. return m_Queue.Requeue(pNew);
  226. }
  227. TMember* Unqueue()
  228. {
  229. TMember* p = (TMember*)m_Queue.Unqueue();
  230. AddRefElement(p);
  231. return p;
  232. }
  233. protected:
  234. void AddRefElement(TMember* p){m_Manager.AddRefElement(p);}
  235. void ReleaseElement(TMember* p){m_Manager.ReleaseElement(p);}
  236. };
  237. //*****************************************************************************
  238. //
  239. // UNIQUE POINTER ARRAY
  240. //
  241. //*****************************************************************************
  242. template <class TMember>
  243. class CUniqueManager
  244. {
  245. public:
  246. void AddRefElement(TMember*){}
  247. void ReleaseElement(TMember* pMember) {delete pMember;}
  248. };
  249. template<class TMember>
  250. class CUniquePointerArray :
  251. public CPointerArray<TMember, CUniqueManager<TMember> >
  252. {
  253. };
  254. template<class TMember>
  255. class CUniquePointerSmallArray :
  256. public CPointerArray<TMember, CUniqueManager<TMember>, CSmallArray>
  257. {
  258. };
  259. template<class TMember>
  260. class CUniquePointerQueue :
  261. public CPointerQueue<TMember, CUniqueManager<TMember> >
  262. {
  263. public:
  264. CUniquePointerQueue<TMember>(int nInitialSize = 1)
  265. : CPointerQueue<TMember, CUniqueManager<TMember> >(nInitialSize)
  266. {}
  267. };
  268. //*****************************************************************************
  269. //
  270. // REFED POINTER ARRAY
  271. //
  272. //*****************************************************************************
  273. template <class TMember>
  274. class CReferenceManager
  275. {
  276. public:
  277. void AddRefElement(TMember* pMember) {if(pMember)pMember->AddRef();}
  278. void ReleaseElement(TMember* pMember) {if(pMember)pMember->Release();}
  279. };
  280. template<class TMember>
  281. class CRefedPointerArray :
  282. public CPointerArray<TMember, CReferenceManager<TMember> >
  283. {
  284. };
  285. template<class TMember>
  286. class CRefedPointerSmallArray :
  287. public CPointerArray<TMember, CReferenceManager<TMember>, CSmallArray>
  288. {
  289. };
  290. template<class TMember>
  291. class CRefedPointerQueue :
  292. public CPointerQueue<TMember, CReferenceManager<TMember> >
  293. {
  294. public:
  295. CRefedPointerQueue(int nInitialSize = 1)
  296. : CPointerQueue<TMember, CReferenceManager<TMember> >(nInitialSize)
  297. {}
  298. };
  299. //*****************************************************************************
  300. //
  301. // ARRAY OF UNIQUE ARRAYS
  302. //
  303. //*****************************************************************************
  304. template <class TMember>
  305. class CUniqueArrayManager
  306. {
  307. void AddRefElement(TMember**){}
  308. void ReleaseElement(TMember** pMember) {delete [] pMember;}
  309. };
  310. template<class TMember>
  311. class CUniqueArrayArray : public CPointerArray<TMember,
  312. CUniqueArrayManager<TMember> >
  313. {
  314. };
  315. //*****************************************************************************
  316. //
  317. // IMPLEMENTATION
  318. //
  319. //*****************************************************************************
  320. template <class TMember, class TManager, class TArray>
  321. CPointerArray<TMember, TManager, TArray>::~CPointerArray()
  322. {
  323. RemoveAll();
  324. }
  325. template <class TMember, class TManager, class TArray>
  326. void CPointerArray<TMember, TManager, TArray>::RemoveAll()
  327. {
  328. for(int i = 0; i < m_Array.Size(); i++)
  329. {
  330. //
  331. // Remove it from array before releasing --- otherwise for a moment
  332. // there we have a garbage pointer in array!
  333. //
  334. TMember* p = GetAt(i);
  335. m_Array.SetAt(i, NULL);
  336. ReleaseElement(p);
  337. }
  338. m_Array.Empty();
  339. }
  340. template <class TMember, class TManager, class TArray>
  341. void CPointerArray<TMember, TManager, TArray>::SetAt(int nIndex,
  342. TMember* pElement, TMember** ppOld)
  343. {
  344. AddRefElement(pElement);
  345. //
  346. // Remove it from array before releasing --- otherwise for a moment
  347. // there we have a garbage pointer in array!
  348. //
  349. TMember* pOld = GetAt(nIndex);
  350. m_Array.SetAt(nIndex, (void*)pElement);
  351. if(ppOld == NULL)
  352. ReleaseElement(pOld);
  353. else
  354. *ppOld = pOld;
  355. }
  356. template <class TMember, class TManager, class TArray>
  357. void CPointerArray<TMember, TManager, TArray>::Discard(int nIndex)
  358. {
  359. m_Array.SetAt(nIndex, NULL);
  360. }
  361. template <class TMember, class TManager, class TArray>
  362. bool CPointerArray<TMember, TManager, TArray>::RemoveAt(int nIndex,
  363. TMember** ppOld)
  364. {
  365. //
  366. // Remove it from array before releasing --- otherwise for a moment
  367. // there we have a garbage pointer in array!
  368. //
  369. TMember* pOld = GetAt(nIndex);
  370. if(m_Array.RemoveAt(nIndex) != CFlexArray::no_error)
  371. return false;
  372. if(ppOld == NULL)
  373. ReleaseElement(pOld);
  374. else
  375. *ppOld = pOld;
  376. return true;
  377. }
  378. template <class TMember, class TManager, class TArray>
  379. bool CPointerArray<TMember, TManager, TArray>::InsertAt(int nIndex,
  380. TMember* pElement)
  381. {
  382. if(m_Array.InsertAt(nIndex, (void*)pElement) != CFlexArray::no_error)
  383. return false;
  384. AddRefElement(pElement);
  385. return true;
  386. }
  387. template <class TMember, class TManager, class TArray>
  388. int CPointerArray<TMember, TManager, TArray>::Add(TMember* pElement)
  389. {
  390. if(m_Array.Add((void*)pElement) != CFlexArray::no_error)
  391. return -1;
  392. AddRefElement(pElement);
  393. return m_Array.Size()-1;
  394. }
  395. template <class TMember, class TManager, class TArray>
  396. TMember** CPointerArray<TMember, TManager, TArray>::GetArrayPtr()
  397. {
  398. return (TMember**)m_Array.GetArrayPtr();
  399. }
  400. template <class TMember, class TManager, class TArray>
  401. TMember** CPointerArray<TMember, TManager, TArray>::UnbindPtr()
  402. {
  403. return (TMember**)m_Array.UnbindPtr();
  404. }
  405. template <class TMember, class TManager, class TArray>
  406. void CPointerArray<TMember, TManager, TArray>::Swap(int nIndex1, int nIndex2)
  407. {
  408. void* pTemp = m_Array[nIndex1];
  409. m_Array.SetAt(nIndex1, m_Array[nIndex2]);
  410. m_Array.SetAt(nIndex2, pTemp);
  411. }
  412. template <class TMember, class TManager>
  413. void CPointerQueue<TMember, TManager>::Clear()
  414. {
  415. TMember* p;
  416. while(p = (TMember*)m_Queue.Dequeue())
  417. {
  418. ReleaseElement(p);
  419. }
  420. }
  421. #endif