Newer
Older
invertedlogic / InvertedLogic / iLFramework / toolkit / src / Containers.cpp
@John Ryland John Ryland on 10 Nov 2019 3 KB rename
#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