Created
December 6, 2016 15:04
-
-
Save DCubix/64a13a299fcaaa2dcdf1d9880430cc75 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* File: Collections.h | |
* Author: twisterge | |
* | |
* Created on December 5, 2016, 11:50 PM | |
*/ | |
#ifndef COLLECTIONS_H | |
#define COLLECTIONS_H | |
#define ARR_MAX_CAPACITY 100 | |
#include <iostream> | |
#include <stdexcept> | |
#include <functional> | |
#include <malloc.h> | |
template <typename T> | |
class ArrayList { | |
public: | |
ArrayList() { | |
m_data = nullptr; | |
m_capacity = ARR_MAX_CAPACITY; | |
m_length = 0; | |
} | |
T& At(int i) const { | |
return m_data[i]; | |
} | |
void Add(T value) { | |
if (m_data == nullptr) { | |
m_data = (T*) calloc(m_capacity, sizeof(T)); | |
} | |
if (m_length+1 > m_capacity) { | |
m_capacity *= 2; | |
m_data = (T*) realloc(m_data, sizeof(T) * m_capacity); | |
} | |
m_data[m_length++] = value; | |
} | |
void Remove(T value) { | |
int i = -1; | |
for (i = 0; i < m_length; i++) { | |
if (m_data[i] == value) { | |
break; | |
} | |
} | |
if (i != -1) { | |
RemoveAt(i); | |
} | |
} | |
void RemoveAt(int at) { | |
if (at < 0 || at >= m_length) { | |
return; | |
} | |
m_data[at].~T(); | |
for (int i = at; i < m_length; i++) { | |
T tmp = m_data[i]; | |
m_data[i] = m_data[i+1]; | |
m_data[i+1] = tmp; | |
} | |
m_length--; | |
} | |
void Insert(int at, T value) { | |
if (at >= m_length) { | |
Add(value); | |
return; | |
} | |
for (int i = m_length-1; i >= at; i--) { | |
T tmp = m_data[i]; | |
m_data[i] = m_data[i+1]; | |
m_data[i+1] = tmp; | |
} | |
m_data[at] = value; | |
m_length++; | |
} | |
void Sort(const std::function<bool(const T&, const T&)>& key={}, bool reverse=false) { | |
for (int x = 0; x < m_length; x++) { | |
int imin = x; | |
for (int y = x; y < m_length; y++) { | |
if (key) { | |
if (!reverse) { | |
if (key(m_data[imin], m_data[y])) { | |
imin = y; | |
} | |
} else { | |
if (!key(m_data[imin], m_data[y])) { | |
imin = y; | |
} | |
} | |
} else { | |
if (!reverse) { | |
if (m_data[imin] > m_data[y]) { | |
imin = y; | |
} | |
} else { | |
if (m_data[imin] < m_data[y]) { | |
imin = y; | |
} | |
} | |
} | |
} | |
T tmp = m_data[x]; | |
m_data[x] = m_data[imin]; | |
m_data[imin] = tmp; | |
} | |
} | |
void ForEach(const std::function<bool(T& item)>& cb) { | |
for (int i = 0; i < m_length; i++) { | |
if (cb) { | |
if (!cb(m_data[i])) { | |
break; | |
} | |
} | |
} | |
} | |
T& operator [](unsigned i) const { | |
return m_data[i]; | |
} | |
void Print() { | |
for (int i = 0; i < m_length; i++) | |
std::cout << m_data[i] << std::endl; | |
} | |
~ArrayList() { | |
delete[] m_data; | |
m_data = nullptr; | |
m_length = 0; | |
m_capacity = ARR_MAX_CAPACITY; | |
} | |
unsigned GetLength() const { | |
return m_length; | |
} | |
protected: | |
T* m_data; | |
unsigned m_length, m_capacity; | |
}; | |
// Map | |
template <typename K, typename V> | |
class Pair { | |
public: | |
K key; | |
V value; | |
Pair(K key, V value) : key(key), value(value) {} | |
bool operator ==(const Pair<K, V>& o) { | |
return key == o.key && value == o.value; | |
} | |
bool operator !=(const Pair<K, V>& o) { | |
return key != o.key || value != o.value; | |
} | |
}; | |
template <typename K, typename V> | |
class Map : private ArrayList<Pair<K, V>> { | |
public: | |
using ArrayList<Pair<K, V>>::RemoveAt; | |
using ArrayList<Pair<K, V>>::GetLength; | |
using ArrayList<Pair<K, V>>::ForEach; | |
using ArrayList<Pair<K, V>>::Add; | |
using ArrayList<Pair<K, V>>::At; | |
using ArrayList<Pair<K, V>>::operator []; | |
public: | |
void Add(K key, V value) { | |
Add(Pair<K, V>(key, value)); | |
} | |
void Remove(K key) { | |
int i = -1; | |
for (i = 0; i < GetLength(); i++) { | |
if ((*this)[i].key == key) { | |
break; | |
} | |
} | |
if (i != -1) { | |
RemoveAt(i); | |
} | |
} | |
bool ContainsKey(K key) { | |
bool ret = false; | |
ForEach([this, &key, &ret](Pair<K, V>& p) { | |
if (p.key == key) { | |
ret = true; | |
return false; | |
} | |
return true; | |
}); | |
return ret; | |
} | |
bool ContainsValue(V value) { | |
bool ret = false; | |
ForEach([this, &value, &ret](Pair<K, V>& p) { | |
if (p.value == value) { | |
ret = true; | |
return false; | |
} | |
return true; | |
}); | |
return ret; | |
} | |
V& At(K key) const { | |
int i = -1; | |
for (i = 0; i < GetLength(); i++) { | |
if (ArrayList<Pair<K, V>>::At(i).key == key) { | |
break; | |
} | |
} | |
if (i != -1) { | |
return ArrayList<Pair<K, V>>::At(i).value; | |
} else { | |
throw std::invalid_argument("KEY doesn't exist."); | |
} | |
} | |
V& operator [](K key) const { | |
return At(key); | |
} | |
void Print() { | |
ForEach([](Pair<K, V>& p) { | |
std::cout << p.key << " -> " << p.value << std::endl; | |
return true; | |
}); | |
} | |
}; | |
#endif /* COLLECTIONS_H */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment