mql5/Include/Escape/HashMap.mqh
2025-08-05 01:57:33 -04:00

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));
}
};