#include "Utils.h"
#include "Test.h"
#include "Containers.h"
#include <vector>
#include <cstdlib>
#include <cstring>
#include <malloc.h>
BEGIN_NAMESPACE
/*
template <typename T>
size_t hash(String a_str) { return a_str.hash(); }
template <typename T>
size_t hash(std::string a_str) { return std::hash<std::string>()(a_str); }
*/
UNIT_TEST(HashTests, 0)
{
HashMap<int,int> table;
table.insert(10, 20);
table.insert(20, 30);
table.insert(30, 40);
printf("%d:%d\n", 10, table[10]);
printf("%d:%d\n", 20, table[20]);
printf("%d:%d\n", 30, table[30]);
/*
table_t t = hnew();
hset(t, 10, 20);
hset(t, 20, 30);
hset(t, 30, 40);
pair_t *a = hget(t, 10);
pair_t *b = hget(t, 20);
pair_t *c = hget(t, 30);
printf("%d:%d\n", a->key, a->value);
printf("%d:%d\n", b->key, b->value);
printf("%d:%d\n", c->key, c->value);
hdel(t);
*/
}
struct DictionaryElement
{
String m_key;
void* m_value;
};
// It's a dumb implementation, but for relatively small counts of elements
// it is reasonably fast and cache coherent. Computationally probably if you
// add up the operations it on paper is less efficient, but for many normal
// uses, this is fine and might even be better.
class DictionaryData
{
public:
DictionaryData() : m_null(NULL) {}
// lookup
void** find(const String& a_lookup) {
for (unsigned i = 0; i < m_elements.size(); i++)
if (m_elements[i].m_key == a_lookup)
return &m_elements[i].m_value;
return NULL;// &m_null;
}
// Pure insert
void insert(const String& a_key, void* a_value) {
DictionaryElement elem = {a_key, a_value};
m_elements.push_back(elem);
}
/*
void insertOrReplace(const String& a_key, void* a_value, void* a_nullPtr) {
DictionaryElement elem = {a_key, a_value};
void** value = find(a_key, a_nullPtr);
if (*value == m_null)
m_elements.push_back(elem);
else
*value = a_value;
}
*/
void* m_null;
Vector<DictionaryElement> m_elements;
};
template <typename T>
class Dictionary
{
public:
Dictionary() { m_data = new DictionaryData; }
~Dictionary() { delete m_data; }
/*
T const& operator[](const String& a_lookup) const {
void** ptrptr = m_data->find(a_lookup);
ptr = *ptrptr;
if (ptr == NULL)
return m_nullT;
return *((T*)ptr);
}
*/
T*& operator[](const String& a_lookup) {
void** ptrptr = m_data->find(a_lookup);
if (ptrptr == NULL)
m_data->insert(a_lookup, NULL);
ptrptr = m_data->find(a_lookup);
return *((T**)ptrptr);
}
//Dictionary<T>& operator=(const String& a_lookup);
private:
T m_nullT;
class DictionaryData* m_data;
//BinaryTree m_btree;
};
struct Blah
{
int x;
};
UNIT_TEST(DictionaryTests, 0)
{
Dictionary<Blah> blahs;
Blah *testBlahRet;
Blah testBlah1 = { 5 };
blahs["foo"] = &testBlah1;
testBlahRet = blahs["foo"];
CHECK(testBlahRet->x == 5);
CHECK(testBlahRet == &testBlah1);
CHECK(blahs["bar"] == 0);
{
Dictionary<int> blahs;
int *testBlahRet;
int testBlah1 = 5;
blahs["foo"] = &testBlah1;
testBlahRet = blahs["foo"];
CHECK(*testBlahRet == 5);
CHECK(testBlahRet == &testBlah1);
CHECK(blahs["bar"] == 0);
}
}
END_NAMESPACE