|
@@ -25,8 +25,8 @@ template<typename K, typename V> class Map : protected Hash<K> |
|
|
{ |
|
|
{ |
|
|
public: |
|
|
public: |
|
|
/* If E is different from K, Hash<K> must implement operator()(E const&) |
|
|
/* If E is different from K, Hash<K> must implement operator()(E const&) |
|
|
* and an equality operator between K and E must exist in order to use this method. |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
* and an equality operator between K and E must exist in order to use |
|
|
|
|
|
* this method. */ |
|
|
|
|
|
|
|
|
/* I choose to make this inline because passing the key by reference |
|
|
/* I choose to make this inline because passing the key by reference |
|
|
* is usually suboptimal. */ |
|
|
* is usually suboptimal. */ |
|
@@ -34,25 +34,19 @@ public: |
|
|
inline V const& operator[] (E const &key) const |
|
|
inline V const& operator[] (E const &key) const |
|
|
{ |
|
|
{ |
|
|
/* Look for the hash in our table and return the value. */ |
|
|
/* Look for the hash in our table and return the value. */ |
|
|
uint32_t hash = ((Hash<K> const &)*this)(key); |
|
|
|
|
|
for (int i = 0; i < m_array.Count(); ++i) |
|
|
|
|
|
if (m_array[i].m1 == hash) |
|
|
|
|
|
if (m_array[i].m2 == key) |
|
|
|
|
|
return m_array[i].m3; |
|
|
|
|
|
/* XXX: this in an error! */ |
|
|
|
|
|
ASSERT(0, "trying to read a nonexistent key in map"); |
|
|
|
|
|
return V(); |
|
|
|
|
|
|
|
|
int i = FindIndex(key); |
|
|
|
|
|
ASSERT(i >= 0, "trying to read a nonexistent key in map"); |
|
|
|
|
|
return m_array[i].m3; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <typename E> |
|
|
template <typename E> |
|
|
inline V & operator[] (E const &key) |
|
|
inline V & operator[] (E const &key) |
|
|
{ |
|
|
{ |
|
|
/* Look for the hash in our table and return the value if found. */ |
|
|
/* Look for the hash in our table and return the value if found. */ |
|
|
uint32_t hash = ((Hash<K> const &)*this)(key); |
|
|
|
|
|
for (int i = 0; i < m_array.Count(); ++i) |
|
|
|
|
|
if (m_array[i].m1 == hash) |
|
|
|
|
|
if (m_array[i].m2 == key) |
|
|
|
|
|
return m_array[i].m3; |
|
|
|
|
|
|
|
|
int i = FindIndex(key); |
|
|
|
|
|
if (i >= 0) |
|
|
|
|
|
return m_array[i].m3; |
|
|
|
|
|
|
|
|
/* If not found, insert a new value. */ |
|
|
/* If not found, insert a new value. */ |
|
|
m_array.Push(hash, key, V()); |
|
|
m_array.Push(hash, key, V()); |
|
|
return m_array.Last().m3; |
|
|
return m_array.Last().m3; |
|
@@ -61,45 +55,47 @@ public: |
|
|
template <typename E> |
|
|
template <typename E> |
|
|
inline void Remove(E const &key) |
|
|
inline void Remove(E const &key) |
|
|
{ |
|
|
{ |
|
|
uint32_t hash = ((Hash<K> const &)*this)(key); |
|
|
|
|
|
for (int i = 0; i < m_array.Count(); ++i) |
|
|
|
|
|
if (m_array[i].m1 == hash) |
|
|
|
|
|
if (m_array[i].m2 == key) |
|
|
|
|
|
{ |
|
|
|
|
|
m_array.Remove(i); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int i = FindIndex(key); |
|
|
|
|
|
if (i >= 0) |
|
|
|
|
|
m_array.Remove(i); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <typename E> |
|
|
template <typename E> |
|
|
inline bool HasKey(E const &key) |
|
|
inline bool HasKey(E const &key) |
|
|
{ |
|
|
{ |
|
|
uint32_t hash = ((Hash<K> const &)*this)(key); |
|
|
|
|
|
for (int i = 0; i < m_array.Count(); ++i) |
|
|
|
|
|
if (m_array[i].m1 == hash) |
|
|
|
|
|
if (m_array[i].m2 == key) |
|
|
|
|
|
return true; |
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
return FindIndex(key) >= 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <typename E> |
|
|
template <typename E> |
|
|
inline bool TryGetValue(E const &key, V& value) |
|
|
inline bool TryGetValue(E const &key, V& value) |
|
|
{ |
|
|
{ |
|
|
uint32_t hash = ((Hash<K> const &)*this)(key); |
|
|
|
|
|
for (int i = 0; i < m_array.Count(); ++i) |
|
|
|
|
|
if (m_array[i].m1 == hash) |
|
|
|
|
|
if (m_array[i].m2 == key) |
|
|
|
|
|
{ |
|
|
|
|
|
value = m_array[i].m3; |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int i = FindIndex(key); |
|
|
|
|
|
if (i >= 0) |
|
|
|
|
|
{ |
|
|
|
|
|
value = m_array[i].m3; |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
inline int Count() const { return m_array.Count(); } |
|
|
|
|
|
|
|
|
inline int Count() const |
|
|
|
|
|
{ |
|
|
|
|
|
return m_array.Count(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
|
|
|
template <typename E> |
|
|
|
|
|
int FindIndex(E const &key) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t hash = ((Hash<K> const &)*this)(key); |
|
|
|
|
|
for (int i = 0; i < m_array.Count(); ++i) |
|
|
|
|
|
if (m_array[i].m1 == hash) |
|
|
|
|
|
if (m_array[i].m2 == key) |
|
|
|
|
|
return i; |
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Array<uint32_t, K, V> m_array; |
|
|
Array<uint32_t, K, V> m_array; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|