1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
// Represents a dynamic array, similar to the standard library's "vector" class.
template<typename T, typename A>
class DynamicArray
{
public:
DynamicArray() :
data(nullptr),
elements(0),
capacity(0)
{
}
void Push(const T &val)
{
if(elements + 1 < capacity)
{
data[elements] = val;
elements++;
}
else
{
// Get more memory
Reserve(capacity + 1);
// Call the function again
Push(val);
}
}
void Pop()
{
// Call the destructor on the last element
allocator.destroy(&data[elements - 1]);
MemorySet(&data[elements - 1], 0, sizeof(T));
elements--;
}
T &operator[](size_t i)
{
// Check if the dynamic array is out of range.
Debug::CheckAssertion(!(i < 0 || i >= elements), "Index is out of dynamic array range.");
return data[i];
}
void Reserve(size_t size)
{
// Only change if the capacity is less
if(capacity < size)
{
T* newData = nullptr;
newData = allocator.allocate(size);
Debug::CheckAssertion((newData != nullptr), "Failed to allocate memory for dynamic array reservation.");
// Zero out memory
MemorySet(newData, 0, capacity * sizeof(T));
// Copy previous memory over
if(data != nullptr)
MemoryCopy(newData, data, elements * sizeof(T));
allocator.deallocate(data, capacity);
data = newData;
capacity = size;
}
}
void Resize(size_t size, const T &val = T())
{
size_t newElements = size;
size_t newCapacity = size;
T* newData = nullptr;
newData = allocator.allocate(size);
Debug::CheckAssertion((newData != nullptr), "Failed to allocate memory for dynamic array resize.");
MemoryCopy(newData, data, newElements);
if(newCapacity > capacity)
{
for(size_t i = 0; i < (newCapacity - capacity); i++)
{
allocator.construct(data[(newElements) + i], val);
}
}
}
void Clear()
{
for(size_t i = 0; i < capacity; i++)
{
allocator.deallocate(&data[i]);
}
elements = 0;
}
T* GetData() const{return data;}
size_t GetSize() const{return elements;}
size_t GetCapacity() const{return capacity;}
inline bool IsEmpty() const{return (elements == 0);}
private:
T* data;
size_t elements;
size_t capacity;
A allocator;
};
|