148 lines
4.1 KiB
MQL5
148 lines
4.1 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| HashMap.mqh - Simple HashMap implementation for EscapeEA |
| |||
//+------------------------------------------------------------------+
| |||
#property copyright "Copyright 2025, EscapeEA"
| |||
#property link "https://www.escapeea.com"
| |||
#property version "1.00"
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Template class for key-value pairs |
| |||
//+------------------------------------------------------------------+
| |||
template<typename TKey,typename TValue>
| |||
class CKeyValuePair
| |||
{
| |||
public:
| |||
TKey key;
| |||
TValue value;
| |||
| |||
CKeyValuePair() {}
| |||
CKeyValuePair(TKey k, TValue v): key(k), value(v) {}
| |||
};
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| HashMap class |
| |||
//+------------------------------------------------------------------+
| |||
template<typename TKey,typename TValue>
| |||
class CHashMap
| |||
{
| |||
private:
| |||
CKeyValuePair<TKey,TValue> m_items[];
| |||
| |||
// Find the index of a key in the array
| |||
int FindIndex(TKey key) const
| |||
{
| |||
for(int i = 0; i < ArraySize(m_items); i++)
| |||
if(m_items[i].key == key)
| |||
return i;
| |||
return -1;
| |||
}
| |||
| |||
public:
| |||
// Constructor
| |||
CHashMap() { ArrayResize(m_items, 0); }
| |||
| |||
// Destructor
| |||
~CHashMap() { ArrayFree(m_items); }
| |||
| |||
// Add or update a key-value pair
| |||
void Add(TKey key, TValue value)
| |||
{
| |||
int index = FindIndex(key);
| |||
if(index >= 0)
| |||
m_items[index].value = value;
| |||
else
| |||
{
| |||
int size = ArraySize(m_items);
| |||
ArrayResize(m_items, size + 1);
| |||
m_items[size] = CKeyValuePair<TKey,TValue>(key, value);
| |||
}
| |||
}
| |||
| |||
// Check if a key exists
| |||
bool ContainsKey(TKey key) const
| |||
{
| |||
return (FindIndex(key) >= 0);
| |||
}
| |||
| |||
// Try to get a value by key
| |||
bool TryGetValue(TKey key, TValue &value) const
| |||
{
| |||
int index = FindIndex(key);
| |||
if(index >= 0)
| |||
{
| |||
value = m_items[index].value;
| |||
return true;
| |||
}
| |||
return false;
| |||
}
| |||
| |||
// Remove a key-value pair by key
| |||
bool Remove(TKey key)
| |||
{
| |||
int index = FindIndex(key);
| |||
if(index >= 0)
| |||
{
| |||
int size = ArraySize(m_items);
| |||
if(index < size - 1)
| |||
m_items[index] = m_items[size - 1];
| |||
ArrayResize(m_items, size - 1);
| |||
return true;
| |||
}
| |||
return false;
| |||
}
| |||
| |||
// Clear all items
| |||
void Clear()
| |||
{
| |||
ArrayFree(m_items);
| |||
ArrayResize(m_items, 0);
| |||
}
| |||
| |||
// Get the number of items
| |||
int Count() const
| |||
{
| |||
return ArraySize(m_items);
| |||
}
| |||
};
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Specialization for string keys |
| |||
//+------------------------------------------------------------------+
| |||
template<typename TValue>
| |||
class CHashMap<string,TValue> : public CHashMap<ulong,TValue>
| |||
{
| |||
private:
| |||
static ulong StringHash(const string str)
| |||
{
| |||
ulong hash = 5381;
| |||
int len = StringLen(str);
| |||
for(int i = 0; i < len; i++)
| |||
hash = ((hash << 5) + hash) + str[i];
| |||
return hash;
| |||
}
| |||
| |||
public:
| |||
// Add or update a key-value pair with string key
| |||
void Add(string key, TValue value)
| |||
{
| |||
CHashMap<ulong,TValue>::Add(StringHash(key), value);
| |||
}
| |||
| |||
// Check if a string key exists
| |||
bool ContainsKey(string key) const
| |||
{
| |||
return CHashMap<ulong,TValue>::ContainsKey(StringHash(key));
| |||
}
| |||
| |||
// Try to get a value by string key
| |||
bool TryGetValue(string key, TValue &value) const
| |||
{
| |||
return CHashMap<ulong,TValue>::TryGetValue(StringHash(key), value);
| |||
}
| |||
| |||
// Remove a key-value pair by string key
| |||
bool Remove(string key)
| |||
{
| |||
return CHashMap<ulong,TValue>::Remove(StringHash(key));
| |||
}
| |||
};
|