| @@ -25,8 +25,8 @@ template<typename K, typename V> class Map : protected Hash<K> | |||
| { | |||
| public: | |||
| /* 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 | |||
| * is usually suboptimal. */ | |||
| @@ -34,25 +34,19 @@ public: | |||
| inline V const& operator[] (E const &key) const | |||
| { | |||
| /* 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> | |||
| inline V & operator[] (E const &key) | |||
| { | |||
| /* 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. */ | |||
| m_array.Push(hash, key, V()); | |||
| return m_array.Last().m3; | |||
| @@ -61,45 +55,47 @@ public: | |||
| template <typename E> | |||
| 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> | |||
| 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> | |||
| 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; | |||
| } | |||
| inline int Count() const { return m_array.Count(); } | |||
| inline int Count() const | |||
| { | |||
| return m_array.Count(); | |||
| } | |||
| 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; | |||
| }; | |||