////////////////////////////// // Dennis Andersen 2013 // ////////////////////////////// #ifndef MISC_DYNAMIC_ARRAY_H #define MISC_DYNAMIC_ARRAY_H namespace Utility { namespace DynamicMemory { template class DynamicArray { public: DynamicArray(); DynamicArray(unsigned int capacity); DynamicArray(const DynamicArray& orig); const DynamicArray& operator=(const DynamicArray& orig); virtual~DynamicArray(); T& operator[](unsigned int index); const T& operator[](unsigned int index) const; void Push(const T& value); void Push(unsigned int index, const T& value); T& PopFront(); T& PopBack(); T& Pop(unsigned int index); void Remove(unsigned int index); void Remove(unsigned int first, unsigned int last); void Clear(); void Resize(unsigned int size); void Swap(unsigned int a, unsigned int b); unsigned int Size() const; unsigned int Capacity() const; private: void Expand(int elements = 0); private: T* data; int size; int capacity; }; #pragma region Implementation template DynamicArray::DynamicArray() : data(0) , size(0) , capacity(0) { } template DynamicArray::DynamicArray(unsigned int capacity) : size(capacity) , capacity(capacity) , data(new T[capacity]) { } template DynamicArray::DynamicArray(const DynamicArray& orig) : capacity(orig.capacity) , size(orig.size) { this->data = new T[orig.capacity]; for (int i = 0; i < orig.size; i++) { this->data[i] = orig.data[i]; } } template const DynamicArray& DynamicArray::operator=(const DynamicArray& orig) { if(this->data) { delete [] this->data; } this->capacity = orig.capacity; this->size = orig.size; if(orig.capacity > 0) { this->data = new T[orig.capacity]; for (int i = 0; i < orig.size; i++) { this->data[i] = orig.data[i]; } } return *this; } template DynamicArray::~DynamicArray() { Clear(); } template T& DynamicArray::operator[](unsigned int index) { assert((int)index < this->size); return this->data[index]; } template const T& DynamicArray::operator[](unsigned int index) const { assert(index < this->size); return this->data[index]; } template void DynamicArray::Push(const T& value) { Expand(1); this->data[this->size] = value; this->size ++; } template void DynamicArray::Push(unsigned int index, const T& value) { int newElem = 1; if((int)index >= this->size) newElem = (index + 1) - this->size; Expand(newElem); this->data[index] = value; this->size += newElem; } template T& DynamicArray::PopFront() { return Pop(0); } template T& DynamicArray::PopBack() { return Pop(this->size-1); } template T& DynamicArray::Pop(unsigned int index) { assert((int)index < this->size); T* temp = new T[this->capacity]; for (int i = 0; i < this->size; i++) { if(i != index) temp[i] = this->data[i]; } delete [] this->data; this->data = temp; this->size--; return this->data[index]; } template void DynamicArray::Remove(unsigned int index) { assert(index > this->size); T* temp = new T[this->capacity - 1]; for (int i = 0; i < this->size; i++) { if(i != index) temp[i] = this->data[i]; } delete [] this->data; this->data = temp; this->size--; } template void DynamicArray::Clear() { delete [] this->data; this->data = 0; this->size = 0; this->capacity = 0; } template void DynamicArray::Resize(unsigned int size) { if (size == this->capacity) return; //No need to resize T* temp = new T[size]; for (int i = 0; i < this->size; i++) { temp[i] = this->data[i]; } this->capacity = size; this->size = size; delete [] this->data; this->data = temp; } template void DynamicArray::Swap(unsigned int a, unsigned int b) { T temp = this->data[a]; this->data[a] = this->data[b]; this->data[b] = temp; } template unsigned int DynamicArray::Size() const { return (unsigned int)this->size; } template unsigned int DynamicArray::Capacity() const { return (unsigned int)this->capacity; } template void DynamicArray::Expand(int elements) { if(elements < 1) return; int newSize = this->size + elements; if(newSize >= this->capacity) { T* temp = new T[newSize]; for (int i = 0; i < this->size; i++) { temp[i] = this->data[i]; } this->capacity = newSize; delete [] this->data; this->data = temp; } } #pragma endregion } } #endif