237 lines
4.9 KiB
C++
237 lines
4.9 KiB
C++
/* $Id$
|
|
||
|
|
|| @author Alexander Brevig <abrevig@wiring.org.co>
|
|
|| @url http://wiring.org.co/
|
|
|| @url http://alexanderbrevig.com/
|
|
|| @contribution Brett Hagman <bhagman@wiring.org.co>
|
|
||
|
|
|| @description
|
|
|| | Implementation of a HashMap data structure.
|
|
|| |
|
|
|| | Wiring Cross-platform Library
|
|
|| #
|
|
||
|
|
|| @license Please see cores/Common/License.txt.
|
|
||
|
|
*/
|
|
|
|
#ifndef HASHMAP_H
|
|
#define HASHMAP_H
|
|
|
|
//for convenience
|
|
#define CreateHashMap(hashM, ktype, vtype, capacity) HashMap<ktype,vtype,capacity> hashM
|
|
#define CreateComplexHashMap(hashM, ktype, vtype, capacity, comparator) HashMap<ktype,vtype,capacity> hashM(comparator)
|
|
|
|
template<typename K, typename V, unsigned int capacity>
|
|
class HashMap
|
|
{
|
|
public:
|
|
typedef bool (*comparator)(K, K);
|
|
|
|
/*
|
|
|| @constructor
|
|
|| | Initialize this HashMap
|
|
|| #
|
|
||
|
|
|| @parameter compare optional function for comparing a key against another (for complex types)
|
|
*/
|
|
HashMap(comparator compare = 0)
|
|
{
|
|
cb_comparator = compare;
|
|
currentIndex = 0;
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | Get the size of this HashMap
|
|
|| #
|
|
||
|
|
|| @return The size of this HashMap
|
|
*/
|
|
unsigned int size() const
|
|
{
|
|
return currentIndex;
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | Get a key at a specified index
|
|
|| #
|
|
||
|
|
|| @parameter idx the index to get the key at
|
|
||
|
|
|| @return The key at index idx
|
|
*/
|
|
K keyAt(unsigned int idx)
|
|
{
|
|
return keys[idx];
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | Get a value at a specified index
|
|
|| #
|
|
||
|
|
|| @parameter idx the index to get the value at
|
|
||
|
|
|| @return The value at index idx
|
|
*/
|
|
V valueAt(unsigned int idx)
|
|
{
|
|
return values[idx];
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | Check if a new assignment will overflow this HashMap
|
|
|| #
|
|
||
|
|
|| @return true if next assignment will overflow this HashMap
|
|
*/
|
|
bool willOverflow()
|
|
{
|
|
return (currentIndex + 1 > capacity);
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | An indexer for accessing and assigning a value to a key
|
|
|| | If a key is used that exists, it returns the value for that key
|
|
|| | If there exists no value for that key, the key is added
|
|
|| #
|
|
||
|
|
|| @parameter key the key to get the value for
|
|
||
|
|
|| @return The const value for key
|
|
*/
|
|
const V& operator[](const K key) const
|
|
{
|
|
return operator[](key);
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | An indexer for accessing and assigning a value to a key
|
|
|| | If a key is used that exists, it returns the value for that key
|
|
|| | If there exists no value for that key, the key is added
|
|
|| #
|
|
||
|
|
|| @parameter key the key to get the value for
|
|
||
|
|
|| @return The value for key
|
|
*/
|
|
V& operator[](const K key)
|
|
{
|
|
if (contains(key))
|
|
{
|
|
return values[indexOf(key)];
|
|
}
|
|
else if (currentIndex < capacity)
|
|
{
|
|
keys[currentIndex] = key;
|
|
values[currentIndex] = nil;
|
|
currentIndex++;
|
|
return values[currentIndex - 1];
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | Get the index of a key
|
|
|| #
|
|
||
|
|
|| @parameter key the key to get the index for
|
|
||
|
|
|| @return The index of the key, or -1 if key does not exist
|
|
*/
|
|
unsigned int indexOf(K key)
|
|
{
|
|
for (int i = 0; i < currentIndex; i++)
|
|
{
|
|
if (cb_comparator)
|
|
{
|
|
if (cb_comparator(key, keys[i]))
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (key == keys[i])
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | Check if a key is contained within this HashMap
|
|
|| #
|
|
||
|
|
|| @parameter key the key to check if is contained within this HashMap
|
|
||
|
|
|| @return true if it is contained in this HashMap
|
|
*/
|
|
bool contains(K key)
|
|
{
|
|
for (int i = 0; i < currentIndex; i++)
|
|
{
|
|
if (cb_comparator)
|
|
{
|
|
if (cb_comparator(key, keys[i]))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (key == keys[i])
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
|| @description
|
|
|| | Check if a key is contained within this HashMap
|
|
|| #
|
|
||
|
|
|| @parameter key the key to remove from this HashMap
|
|
*/
|
|
void remove(K key)
|
|
{
|
|
int index = indexOf(key);
|
|
if (contains(key))
|
|
{
|
|
for (int i = index; i < capacity - 1; i++)
|
|
{
|
|
keys[i] = keys[i + 1];
|
|
values[i] = values[i + 1];
|
|
}
|
|
currentIndex--;
|
|
}
|
|
}
|
|
|
|
void setNullValue(V nullv)
|
|
{
|
|
nil = nullv;
|
|
}
|
|
|
|
protected:
|
|
K keys[capacity];
|
|
V values[capacity];
|
|
V nil;
|
|
int currentIndex;
|
|
comparator cb_comparator;
|
|
};
|
|
|
|
#endif
|
|
// HASHMAP_H
|