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.

444 lines
8.7 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-2001 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLSIMPCOLL_H__
  11. #define __ATLSIMPCOLL_H__
  12. #pragma once
  13. #include <atldef.h>
  14. #include <wtypes.h>
  15. #ifndef _ATL_NO_DEBUG_CRT
  16. // Warning: if you define the above symbol, you will have
  17. // to provide your own definition of the ATLASSERT(x) macro
  18. // in order to compile ATL
  19. #include <crtdbg.h>
  20. #endif
  21. #pragma warning(push)
  22. #pragma warning(disable: 4800) // forcing 'int' value to bool
  23. namespace ATL
  24. {
  25. #pragma push_macro("new")
  26. #undef new
  27. /////////////////////////////////////////////////////////////////////////////
  28. // Collection helpers - CSimpleArray & CSimpleMap
  29. // template class helpers with functions for comparing elements
  30. // override if using complex types without operator==
  31. //REVIEW: Do we really need to disable warning 4800?
  32. template <class T>
  33. class CSimpleArrayEqualHelper
  34. {
  35. public:
  36. static bool IsEqual(const T& t1, const T& t2)
  37. {
  38. return (t1 == t2);
  39. }
  40. };
  41. template <class T>
  42. class CSimpleArrayEqualHelperFalse
  43. {
  44. public:
  45. static bool IsEqual(const T&, const T&)
  46. {
  47. ATLASSERT(false);
  48. return false;
  49. }
  50. };
  51. template <class TKey, class TVal>
  52. class CSimpleMapEqualHelper
  53. {
  54. public:
  55. static bool IsEqualKey(const TKey& k1, const TKey& k2)
  56. {
  57. return CSimpleArrayEqualHelper<TKey>::IsEqual(k1, k2);
  58. }
  59. static bool IsEqualValue(const TVal& v1, const TVal& v2)
  60. {
  61. return CSimpleArrayEqualHelper<TVal>::IsEqual(v1, v2);
  62. }
  63. };
  64. template <class TKey, class TVal>
  65. class CSimpleMapEqualHelperFalse
  66. {
  67. public:
  68. static bool IsEqualKey(const TKey& k1, const TKey& k2)
  69. {
  70. return CSimpleArrayEqualHelper<TKey>::IsEqual(k1, k2);
  71. }
  72. static bool IsEqualValue(const TVal&, const TVal&)
  73. {
  74. ATLASSERT(FALSE);
  75. return false;
  76. }
  77. };
  78. template <class T, class TEqual = CSimpleArrayEqualHelper< T > >
  79. class CSimpleArray
  80. {
  81. public:
  82. // Construction/destruction
  83. CSimpleArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
  84. { }
  85. ~CSimpleArray()
  86. {
  87. RemoveAll();
  88. }
  89. CSimpleArray(const CSimpleArray< T, TEqual >& src) : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
  90. {
  91. m_aT = (T*)malloc(src.GetSize() * sizeof(T));
  92. if (m_aT != NULL)
  93. {
  94. m_nAllocSize = src.GetSize();
  95. for (int i=0; i<src.GetSize(); i++)
  96. Add(src[i]);
  97. }
  98. }
  99. CSimpleArray< T, TEqual >& operator=(const CSimpleArray< T, TEqual >& src)
  100. {
  101. if (GetSize() != src.GetSize())
  102. {
  103. RemoveAll();
  104. m_aT = (T*)malloc(src.GetSize() * sizeof(T));
  105. if (m_aT != NULL)
  106. m_nAllocSize = src.GetSize();
  107. }
  108. else
  109. {
  110. for (int i = GetSize(); i > 0; i--)
  111. RemoveAt(i - 1);
  112. }
  113. for (int i=0; i<src.GetSize(); i++)
  114. Add(src[i]);
  115. return *this;
  116. }
  117. // Operations
  118. int GetSize() const
  119. {
  120. return m_nSize;
  121. }
  122. BOOL Add(const T& t)
  123. {
  124. if(m_nSize == m_nAllocSize)
  125. {
  126. T* aT;
  127. int nNewAllocSize = (m_nAllocSize == 0) ? 1 : (m_nSize * 2);
  128. aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T));
  129. if(aT == NULL)
  130. return FALSE;
  131. m_nAllocSize = nNewAllocSize;
  132. m_aT = aT;
  133. }
  134. m_nSize++;
  135. InternalSetAtIndex(m_nSize - 1, t);
  136. return TRUE;
  137. }
  138. BOOL Remove(const T& t)
  139. {
  140. int nIndex = Find(t);
  141. if(nIndex == -1)
  142. return FALSE;
  143. return RemoveAt(nIndex);
  144. }
  145. BOOL RemoveAt(int nIndex)
  146. {
  147. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  148. if (nIndex < 0 || nIndex >= m_nSize)
  149. return FALSE;
  150. m_aT[nIndex].~T();
  151. if(nIndex != (m_nSize - 1))
  152. memmove((void*)(m_aT + nIndex), (void*)(m_aT + nIndex + 1), (m_nSize - (nIndex + 1)) * sizeof(T));
  153. m_nSize--;
  154. return TRUE;
  155. }
  156. void RemoveAll()
  157. {
  158. if(m_aT != NULL)
  159. {
  160. for(int i = 0; i < m_nSize; i++)
  161. m_aT[i].~T();
  162. free(m_aT);
  163. m_aT = NULL;
  164. }
  165. m_nSize = 0;
  166. m_nAllocSize = 0;
  167. }
  168. const T& operator[] (int nIndex) const
  169. {
  170. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  171. return m_aT[nIndex];
  172. }
  173. T& operator[] (int nIndex)
  174. {
  175. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  176. return m_aT[nIndex];
  177. }
  178. T* GetData() const
  179. {
  180. return m_aT;
  181. }
  182. int Find(const T& t) const
  183. {
  184. for(int i = 0; i < m_nSize; i++)
  185. {
  186. if(TEqual::IsEqual(m_aT[i], t))
  187. return i;
  188. }
  189. return -1; // not found
  190. }
  191. BOOL SetAtIndex(int nIndex, const T& t)
  192. {
  193. if (nIndex < 0 || nIndex >= m_nSize)
  194. return FALSE;
  195. InternalSetAtIndex(nIndex, t);
  196. return TRUE;
  197. }
  198. // Implementation
  199. class Wrapper
  200. {
  201. public:
  202. Wrapper(const T& _t) : t(_t)
  203. {
  204. }
  205. template <class _Ty>
  206. void *operator new(size_t, _Ty* p)
  207. {
  208. return p;
  209. }
  210. template <class _Ty>
  211. void operator delete(void* /* pv */, _Ty* /* p */)
  212. {
  213. }
  214. T t;
  215. };
  216. // Implementation
  217. void InternalSetAtIndex(int nIndex, const T& t)
  218. {
  219. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  220. new(m_aT + nIndex) Wrapper(t);
  221. }
  222. typedef T _ArrayElementType;
  223. T* m_aT;
  224. int m_nSize;
  225. int m_nAllocSize;
  226. };
  227. #define CSimpleValArray CSimpleArray
  228. // intended for small number of simple types or pointers
  229. template <class TKey, class TVal, class TEqual = CSimpleMapEqualHelper< TKey, TVal > >
  230. class CSimpleMap
  231. {
  232. public:
  233. TKey* m_aKey;
  234. TVal* m_aVal;
  235. int m_nSize;
  236. typedef TKey _ArrayKeyType;
  237. typedef TVal _ArrayElementType;
  238. // Construction/destruction
  239. CSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
  240. { }
  241. ~CSimpleMap()
  242. {
  243. RemoveAll();
  244. }
  245. // Operations
  246. int GetSize() const
  247. {
  248. return m_nSize;
  249. }
  250. BOOL Add(const TKey& key, const TVal& val)
  251. {
  252. TKey* pKey;
  253. pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));
  254. if(pKey == NULL)
  255. return FALSE;
  256. m_aKey = pKey;
  257. TVal* pVal;
  258. pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));
  259. if(pVal == NULL)
  260. return FALSE;
  261. m_aVal = pVal;
  262. m_nSize++;
  263. InternalSetAtIndex(m_nSize - 1, key, val);
  264. return TRUE;
  265. }
  266. BOOL Remove(const TKey& key)
  267. {
  268. int nIndex = FindKey(key);
  269. if(nIndex == -1)
  270. return FALSE;
  271. return RemoveAt(nIndex);
  272. }
  273. BOOL RemoveAt(int nIndex)
  274. {
  275. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  276. if (nIndex < 0 || nIndex >= m_nSize)
  277. return FALSE;
  278. m_aKey[nIndex].~TKey();
  279. m_aVal[nIndex].~TVal();
  280. if(nIndex != (m_nSize - 1))
  281. {
  282. memmove((void*)(m_aKey + nIndex), (void*)(m_aKey + nIndex + 1), (m_nSize - (nIndex + 1)) * sizeof(TKey));
  283. memmove((void*)(m_aVal + nIndex), (void*)(m_aVal + nIndex + 1), (m_nSize - (nIndex + 1)) * sizeof(TVal));
  284. }
  285. TKey* pKey;
  286. pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  287. if(pKey != NULL || m_nSize == 1)
  288. m_aKey = pKey;
  289. TVal* pVal;
  290. pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  291. if(pVal != NULL || m_nSize == 1)
  292. m_aVal = pVal;
  293. m_nSize--;
  294. return TRUE;
  295. }
  296. void RemoveAll()
  297. {
  298. if(m_aKey != NULL)
  299. {
  300. for(int i = 0; i < m_nSize; i++)
  301. {
  302. m_aKey[i].~TKey();
  303. m_aVal[i].~TVal();
  304. }
  305. free(m_aKey);
  306. m_aKey = NULL;
  307. }
  308. if(m_aVal != NULL)
  309. {
  310. free(m_aVal);
  311. m_aVal = NULL;
  312. }
  313. m_nSize = 0;
  314. }
  315. BOOL SetAt(const TKey& key, const TVal& val)
  316. {
  317. int nIndex = FindKey(key);
  318. if(nIndex == -1)
  319. return FALSE;
  320. m_aKey[nIndex].~TKey();
  321. m_aVal[nIndex].~TVal();
  322. InternalSetAtIndex(nIndex, key, val);
  323. return TRUE;
  324. }
  325. TVal Lookup(const TKey& key) const
  326. {
  327. int nIndex = FindKey(key);
  328. if(nIndex == -1)
  329. return NULL; // must be able to convert
  330. return GetValueAt(nIndex);
  331. }
  332. TKey ReverseLookup(const TVal& val) const
  333. {
  334. int nIndex = FindVal(val);
  335. if(nIndex == -1)
  336. return NULL; // must be able to convert
  337. return GetKeyAt(nIndex);
  338. }
  339. TKey& GetKeyAt(int nIndex) const
  340. {
  341. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  342. return m_aKey[nIndex];
  343. }
  344. TVal& GetValueAt(int nIndex) const
  345. {
  346. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  347. return m_aVal[nIndex];
  348. }
  349. int FindKey(const TKey& key) const
  350. {
  351. for(int i = 0; i < m_nSize; i++)
  352. {
  353. if(TEqual::IsEqualKey(m_aKey[i], key))
  354. return i;
  355. }
  356. return -1; // not found
  357. }
  358. int FindVal(const TVal& val) const
  359. {
  360. for(int i = 0; i < m_nSize; i++)
  361. {
  362. if(TEqual::IsEqualValue(m_aVal[i], val))
  363. return i;
  364. }
  365. return -1; // not found
  366. }
  367. BOOL SetAtIndex(int nIndex, const TKey& key, const TVal& val)
  368. {
  369. if (nIndex < 0 || nIndex >= m_nSize)
  370. return FALSE;
  371. InternalSetAtIndex(nIndex, key, val);
  372. return TRUE;
  373. }
  374. // Implementation
  375. template <typename T>
  376. class Wrapper
  377. {
  378. public:
  379. Wrapper(const T& _t) : t(_t)
  380. {
  381. }
  382. template <class _Ty>
  383. void *operator new(size_t, _Ty* p)
  384. {
  385. return p;
  386. }
  387. template <class _Ty>
  388. void operator delete(void* /* pv */, _Ty* /* p */)
  389. {
  390. }
  391. T t;
  392. };
  393. void InternalSetAtIndex(int nIndex, const TKey& key, const TVal& val)
  394. {
  395. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  396. new(m_aKey + nIndex) Wrapper<TKey>(key);
  397. new(m_aVal + nIndex) Wrapper<TVal>(val);
  398. }
  399. };
  400. #pragma pop_macro("new")
  401. }; // namespace ATL
  402. #pragma warning(pop)
  403. #endif // __ATLSIMPCOLL_H__