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
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
|