Leaked source code of windows server 2003
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.

214 lines
5.8 KiB

  1. #ifndef __TMAP_H
  2. #define __TMAP_H
  3. #include "srtarray.h"
  4. //--------------------------------------------------------------------------
  5. // TPair
  6. //--------------------------------------------------------------------------
  7. template<class TKey, class TValue>
  8. class TPair
  9. {
  10. public:
  11. TPair(const TKey& key, const TValue& value) :
  12. m_key(key),
  13. m_value(value)
  14. { }
  15. TPair(const TKey& key) :
  16. m_key(key),
  17. m_value()
  18. { }
  19. const TKey m_key;
  20. TValue m_value;
  21. };
  22. //--------------------------------------------------------------------------
  23. // class TMap
  24. //--------------------------------------------------------------------------
  25. template<class TKey, class TValue>
  26. class TMap
  27. {
  28. typedef int (__cdecl *PFNKEYYCOMPARE)(const TKey& first, const TKey& second);
  29. typedef void (__cdecl *PFNFREEPAIR)(TPair<TKey, TValue> *pair);
  30. public:
  31. TMap(PFNKEYYCOMPARE pfnCompare = NULL);
  32. ~TMap(void);
  33. long GetLength(void) const { return m_pArray ? m_pArray->GetLength() : 0; }
  34. // find the entry in the map whose key matches item->m_key
  35. TPair<TKey, TValue>* Find(TPair<TKey, TValue> *pPair) const;
  36. TPair<TKey, TValue>* Find(const TKey& key) const;
  37. // find the entry in the map whose key matches key
  38. HRESULT Add(const TPair<TKey, TValue> *pPair);
  39. // add newItem to the map
  40. HRESULT Add(const TKey& key, const TValue& value);
  41. // Create a pair and add it to the map
  42. BOOL Remove(TPair<TKey, TValue> *pPair);
  43. // Remove entry in the map whose key matches item->key
  44. BOOL Remove(const TKey& key);
  45. // Remove entry in the map whose key matches key
  46. public:
  47. // install a custom pair free function. it is the
  48. // responsibility of this function to free any data
  49. // associated with the pair, and to then call
  50. // "delete" on the pair
  51. void SetPairFreeFunction(PFNFREEPAIR pfnFreePair) { m_pfnFreePair = pfnFreePair; }
  52. TPair<TKey, TValue>* GetItemAt(long lIndex) const;
  53. // Return the entry at ulIndex. This method should only be
  54. // used as a low-level accessor (e.g., for iterating across
  55. // all entries in the map). Note that adding a new entry
  56. // invalidates any previous index:entry associations
  57. private:
  58. HRESULT _HrCreateArray(void)
  59. {
  60. Assert(NULL == m_pArray);
  61. return CSortedArray::Create(_Compare, _FreeItem, &m_pArray);
  62. }
  63. static int __cdecl _Compare(const void* pPair1, const void* pPair2)
  64. {
  65. const TKey& key1 = (*((TPair<TKey, TValue>**)pPair1))->m_key;
  66. const TKey& key2 = (*((TPair<TKey, TValue>**)pPair2))->m_key;
  67. // if (m_pfnCompare)
  68. // return (*m_pfnCompare)(key1, key2);
  69. // else
  70. // {
  71. if (key1 < key2)
  72. return -1;
  73. else if (key2 < key1)
  74. return 1;
  75. else
  76. return 0;
  77. // }
  78. }
  79. static void __cdecl _FreeItem(void* pPair)
  80. {
  81. delete (static_cast<TPair<TKey, TValue>*>(pPair));
  82. }
  83. private:
  84. PFNFREEPAIR m_pfnFreePair;
  85. PFNKEYYCOMPARE m_pfnCompare;
  86. CSortedArray *m_pArray;
  87. };
  88. template <class TKey, class TValue>
  89. inline TMap<TKey, TValue>::TMap(PFNKEYYCOMPARE pfnCompare) :
  90. m_pfnFreePair(NULL),
  91. m_pfnCompare(pfnCompare),
  92. m_pArray(NULL)
  93. {
  94. // nothing to do
  95. }
  96. template <class TKey, class TValue>
  97. TMap<TKey, TValue>::~TMap(void)
  98. {
  99. if (NULL != m_pfnFreePair)
  100. {
  101. long lLength = GetLength();
  102. TPair<TKey, TValue> *pPair;
  103. if (lLength > 0)
  104. {
  105. for (long i = lLength - 1; i >= 0; i--)
  106. {
  107. pPair = GetItemAt(i);
  108. m_pArray->Remove(i);
  109. if (pPair)
  110. (*m_pfnFreePair)(pPair);
  111. }
  112. }
  113. }
  114. delete m_pArray;
  115. }
  116. template<class TKey, class TValue>
  117. TPair<TKey, TValue>* TMap<TKey, TValue>::Find(TPair<TKey, TValue> *pPair) const
  118. {
  119. long lIndex;
  120. if (NULL != m_pArray && m_pArray->Find(pPair, &lIndex))
  121. return static_cast<TPair<TKey, TValue>*>(m_pArray->GetItemAt(lIndex));
  122. else
  123. return NULL;
  124. }
  125. template<class TKey, class TValue>
  126. inline TPair<TKey, TValue>* TMap<TKey, TValue>::Find(const TKey& key) const
  127. {
  128. return Find(&TPair<TKey, TValue>(key));
  129. }
  130. template<class TKey, class TValue>
  131. HRESULT TMap<TKey, TValue>::Add(const TPair<TKey, TValue> *pPair)
  132. {
  133. if (NULL == m_pArray)
  134. {
  135. HRESULT hr;
  136. if (FAILED(hr = _HrCreateArray()))
  137. return hr;
  138. }
  139. return m_pArray->Add(const_cast<TPair<TKey, TValue>*>(pPair));
  140. }
  141. template<class TKey, class TValue>
  142. inline HRESULT TMap<TKey, TValue>::Add(const TKey& key, const TValue& value)
  143. {
  144. TPair<TKey, TValue> *pPair = new TPair<TKey, TValue>(key, value);
  145. if (NULL == pPair)
  146. return E_OUTOFMEMORY;
  147. return Add(pPair);
  148. }
  149. template<class TKey, class TValue>
  150. BOOL TMap<TKey, TValue>::Remove(TPair<TKey, TValue> *pPair)
  151. {
  152. long lIndex;
  153. BOOL fFound = m_pArray->Find(pPair, &lIndex);
  154. if (fFound)
  155. {
  156. TPair<TKey, TValue> *pFoundPair = static_cast<TPair<TKey, TValue>*>(m_pArray->GetItemAt(lIndex));
  157. m_pArray->Remove(lIndex);
  158. if (m_pfnFreePair)
  159. (*m_pfnFreePair)(pFoundPair);
  160. else
  161. delete pFoundPair;
  162. }
  163. return fFound;
  164. }
  165. template<class TKey, class TValue>
  166. inline BOOL TMap<TKey, TValue>::Remove(const TKey& key)
  167. {
  168. return Remove(&TPair<TKey, TValue>(key));
  169. }
  170. template<class TKey, class TValue>
  171. inline TPair<TKey, TValue>* TMap<TKey, TValue>::GetItemAt(long lIndex) const
  172. {
  173. return m_pArray ? static_cast<TPair<TKey, TValue>*>(m_pArray->GetItemAt(lIndex)) : NULL;
  174. }
  175. #endif // __TMAP_H