2013-12-18 13:07:10 +01:00
|
|
|
//////////////////////////////
|
|
|
|
// Dennis Andersen 2013 //
|
|
|
|
//////////////////////////////
|
|
|
|
#ifndef MISC_DYNAMIC_ARRAY_H
|
|
|
|
#define MISC_DYNAMIC_ARRAY_H
|
|
|
|
|
2014-01-28 09:00:02 +01:00
|
|
|
#include <assert.h>
|
|
|
|
|
2013-12-18 13:07:10 +01:00
|
|
|
namespace Utility
|
|
|
|
{
|
|
|
|
namespace DynamicMemory
|
|
|
|
{
|
|
|
|
template <typename T>
|
|
|
|
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();
|
|
|
|
|
2014-01-07 10:26:09 +01:00
|
|
|
void Resize(unsigned int size);
|
|
|
|
|
2014-01-21 09:52:48 +01:00
|
|
|
void Reserve(unsigned int size);
|
|
|
|
|
2014-01-07 10:26:09 +01:00
|
|
|
void Swap(unsigned int a, unsigned int b);
|
2013-12-18 13:07:10 +01:00
|
|
|
|
|
|
|
unsigned int Size() const;
|
|
|
|
unsigned int Capacity() const;
|
|
|
|
|
2014-02-04 16:07:10 +01:00
|
|
|
bool IsEmpty() const;
|
|
|
|
|
|
|
|
T* begin();
|
|
|
|
T* end();
|
|
|
|
|
2014-01-07 10:26:09 +01:00
|
|
|
private:
|
|
|
|
void Expand(int elements = 0);
|
|
|
|
|
2013-12-18 13:07:10 +01:00
|
|
|
private:
|
|
|
|
T* data;
|
|
|
|
int size;
|
|
|
|
int capacity;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#pragma region Implementation
|
|
|
|
template <typename T> DynamicArray<T>::DynamicArray()
|
|
|
|
: data(0)
|
|
|
|
, size(0)
|
|
|
|
, capacity(0)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
template <typename T> DynamicArray<T>::DynamicArray(unsigned int capacity)
|
|
|
|
: size(capacity)
|
|
|
|
, capacity(capacity)
|
|
|
|
, data(new T[capacity])
|
|
|
|
{ }
|
|
|
|
|
|
|
|
template <typename T> DynamicArray<T>::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 <typename T> const DynamicArray<T>& DynamicArray<T>::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 <typename T> DynamicArray<T>::~DynamicArray()
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> T& DynamicArray<T>::operator[](unsigned int index)
|
|
|
|
{
|
|
|
|
assert((int)index < this->size);
|
|
|
|
|
|
|
|
return this->data[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> const T& DynamicArray<T>::operator[](unsigned int index) const
|
|
|
|
{
|
2014-02-09 16:42:26 +01:00
|
|
|
assert((int)index < this->size);
|
2013-12-18 13:07:10 +01:00
|
|
|
|
|
|
|
return this->data[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> void DynamicArray<T>::Push(const T& value)
|
|
|
|
{
|
|
|
|
Expand(1);
|
|
|
|
|
|
|
|
this->data[this->size] = value;
|
|
|
|
this->size ++;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> void DynamicArray<T>::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 <typename T> T& DynamicArray<T>::PopFront()
|
|
|
|
{
|
|
|
|
return Pop(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> T& DynamicArray<T>::PopBack()
|
|
|
|
{
|
|
|
|
return Pop(this->size-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> T& DynamicArray<T>::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 <typename T> void DynamicArray<T>::Remove(unsigned int index)
|
|
|
|
{
|
2014-02-04 16:07:10 +01:00
|
|
|
assert(index > (unsigned int) this->size);
|
2013-12-18 13:07:10 +01:00
|
|
|
|
|
|
|
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 <typename T> void DynamicArray<T>::Clear()
|
|
|
|
{
|
2014-02-04 16:07:10 +01:00
|
|
|
if(this->data)
|
|
|
|
delete [] this->data;
|
2013-12-18 13:07:10 +01:00
|
|
|
|
|
|
|
this->data = 0;
|
|
|
|
this->size = 0;
|
|
|
|
this->capacity = 0;
|
|
|
|
}
|
|
|
|
|
2014-01-07 10:26:09 +01:00
|
|
|
template <typename T> void DynamicArray<T>::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;
|
|
|
|
}
|
|
|
|
|
2014-01-21 09:52:48 +01:00
|
|
|
template <typename T> void DynamicArray<T>::Reserve(unsigned int size)
|
|
|
|
{
|
|
|
|
Expand(size);
|
|
|
|
}
|
|
|
|
|
2014-01-07 10:26:09 +01:00
|
|
|
template <typename T> void DynamicArray<T>::Swap(unsigned int a, unsigned int b)
|
|
|
|
{
|
|
|
|
T temp = this->data[a];
|
|
|
|
this->data[a] = this->data[b];
|
|
|
|
this->data[b] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> unsigned int DynamicArray<T>::Size() const
|
|
|
|
{
|
|
|
|
return (unsigned int)this->size;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> unsigned int DynamicArray<T>::Capacity() const
|
|
|
|
{
|
|
|
|
return (unsigned int)this->capacity;
|
|
|
|
}
|
|
|
|
|
2014-02-04 16:07:10 +01:00
|
|
|
template <typename T> bool DynamicArray<T>::IsEmpty() const
|
|
|
|
{
|
|
|
|
return (this->size == 0);
|
|
|
|
}
|
|
|
|
|
2013-12-18 13:07:10 +01:00
|
|
|
template <typename T> void DynamicArray<T>::Expand(int elements)
|
|
|
|
{
|
2014-01-07 10:26:09 +01:00
|
|
|
if(elements < 1) return;
|
|
|
|
|
2013-12-18 13:07:10 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-04 16:07:10 +01:00
|
|
|
template <typename T> T* DynamicArray<T>::begin()
|
|
|
|
{
|
|
|
|
if(this->size == 0) return 0;
|
|
|
|
return &this->data[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T> T* DynamicArray<T>::end()
|
|
|
|
{
|
|
|
|
if(this->size == 0) return 0;
|
|
|
|
return ((&this->data[this->size - 1]) + 1);
|
|
|
|
}
|
|
|
|
|
2013-12-18 13:07:10 +01:00
|
|
|
#pragma endregion
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|