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.
 
 
 
 
 
 

215 lines
5.8 KiB

#ifndef __TMAP_H
#define __TMAP_H
#include "srtarray.h"
//--------------------------------------------------------------------------
// TPair
//--------------------------------------------------------------------------
template<class TKey, class TValue>
class TPair
{
public:
TPair(const TKey& key, const TValue& value) :
m_key(key),
m_value(value)
{ }
TPair(const TKey& key) :
m_key(key),
m_value()
{ }
const TKey m_key;
TValue m_value;
};
//--------------------------------------------------------------------------
// class TMap
//--------------------------------------------------------------------------
template<class TKey, class TValue>
class TMap
{
typedef int (__cdecl *PFNKEYYCOMPARE)(const TKey& first, const TKey& second);
typedef void (__cdecl *PFNFREEPAIR)(TPair<TKey, TValue> *pair);
public:
TMap(PFNKEYYCOMPARE pfnCompare = NULL);
~TMap(void);
long GetLength(void) const { return m_pArray ? m_pArray->GetLength() : 0; }
// find the entry in the map whose key matches item->m_key
TPair<TKey, TValue>* Find(TPair<TKey, TValue> *pPair) const;
TPair<TKey, TValue>* Find(const TKey& key) const;
// find the entry in the map whose key matches key
HRESULT Add(const TPair<TKey, TValue> *pPair);
// add newItem to the map
HRESULT Add(const TKey& key, const TValue& value);
// Create a pair and add it to the map
BOOL Remove(TPair<TKey, TValue> *pPair);
// Remove entry in the map whose key matches item->key
BOOL Remove(const TKey& key);
// Remove entry in the map whose key matches key
public:
// install a custom pair free function. it is the
// responsibility of this function to free any data
// associated with the pair, and to then call
// "delete" on the pair
void SetPairFreeFunction(PFNFREEPAIR pfnFreePair) { m_pfnFreePair = pfnFreePair; }
TPair<TKey, TValue>* GetItemAt(long lIndex) const;
// Return the entry at ulIndex. This method should only be
// used as a low-level accessor (e.g., for iterating across
// all entries in the map). Note that adding a new entry
// invalidates any previous index:entry associations
private:
HRESULT _HrCreateArray(void)
{
Assert(NULL == m_pArray);
return CSortedArray::Create(_Compare, _FreeItem, &m_pArray);
}
static int __cdecl _Compare(const void* pPair1, const void* pPair2)
{
const TKey& key1 = (*((TPair<TKey, TValue>**)pPair1))->m_key;
const TKey& key2 = (*((TPair<TKey, TValue>**)pPair2))->m_key;
// if (m_pfnCompare)
// return (*m_pfnCompare)(key1, key2);
// else
// {
if (key1 < key2)
return -1;
else if (key2 < key1)
return 1;
else
return 0;
// }
}
static void __cdecl _FreeItem(void* pPair)
{
delete (static_cast<TPair<TKey, TValue>*>(pPair));
}
private:
PFNFREEPAIR m_pfnFreePair;
PFNKEYYCOMPARE m_pfnCompare;
CSortedArray *m_pArray;
};
template <class TKey, class TValue>
inline TMap<TKey, TValue>::TMap(PFNKEYYCOMPARE pfnCompare) :
m_pfnFreePair(NULL),
m_pfnCompare(pfnCompare),
m_pArray(NULL)
{
// nothing to do
}
template <class TKey, class TValue>
TMap<TKey, TValue>::~TMap(void)
{
if (NULL != m_pfnFreePair)
{
long lLength = GetLength();
TPair<TKey, TValue> *pPair;
if (lLength > 0)
{
for (long i = lLength - 1; i >= 0; i--)
{
pPair = GetItemAt(i);
m_pArray->Remove(i);
if (pPair)
(*m_pfnFreePair)(pPair);
}
}
}
delete m_pArray;
}
template<class TKey, class TValue>
TPair<TKey, TValue>* TMap<TKey, TValue>::Find(TPair<TKey, TValue> *pPair) const
{
long lIndex;
if (NULL != m_pArray && m_pArray->Find(pPair, &lIndex))
return static_cast<TPair<TKey, TValue>*>(m_pArray->GetItemAt(lIndex));
else
return NULL;
}
template<class TKey, class TValue>
inline TPair<TKey, TValue>* TMap<TKey, TValue>::Find(const TKey& key) const
{
return Find(&TPair<TKey, TValue>(key));
}
template<class TKey, class TValue>
HRESULT TMap<TKey, TValue>::Add(const TPair<TKey, TValue> *pPair)
{
if (NULL == m_pArray)
{
HRESULT hr;
if (FAILED(hr = _HrCreateArray()))
return hr;
}
return m_pArray->Add(const_cast<TPair<TKey, TValue>*>(pPair));
}
template<class TKey, class TValue>
inline HRESULT TMap<TKey, TValue>::Add(const TKey& key, const TValue& value)
{
TPair<TKey, TValue> *pPair = new TPair<TKey, TValue>(key, value);
if (NULL == pPair)
return E_OUTOFMEMORY;
return Add(pPair);
}
template<class TKey, class TValue>
BOOL TMap<TKey, TValue>::Remove(TPair<TKey, TValue> *pPair)
{
long lIndex;
BOOL fFound = m_pArray->Find(pPair, &lIndex);
if (fFound)
{
TPair<TKey, TValue> *pFoundPair = static_cast<TPair<TKey, TValue>*>(m_pArray->GetItemAt(lIndex));
m_pArray->Remove(lIndex);
if (m_pfnFreePair)
(*m_pfnFreePair)(pFoundPair);
else
delete pFoundPair;
}
return fFound;
}
template<class TKey, class TValue>
inline BOOL TMap<TKey, TValue>::Remove(const TKey& key)
{
return Remove(&TPair<TKey, TValue>(key));
}
template<class TKey, class TValue>
inline TPair<TKey, TValue>* TMap<TKey, TValue>::GetItemAt(long lIndex) const
{
return m_pArray ? static_cast<TPair<TKey, TValue>*>(m_pArray->GetItemAt(lIndex)) : NULL;
}
#endif // __TMAP_H