598 lines
7.8 KiB
C++
598 lines
7.8 KiB
C++
#pragma once
|
|
|
|
#include <assert.h>
|
|
#include "MachineTypes.h"
|
|
|
|
template <class T>
|
|
class DynamicArray
|
|
{
|
|
protected:
|
|
int size, range;
|
|
T* array;
|
|
|
|
void Grow(int by)
|
|
{
|
|
T* a2;
|
|
int i;
|
|
|
|
if (size + by > range)
|
|
{
|
|
range = (size + by) * 2;
|
|
a2 = new T[range];
|
|
for (i = 0; i < size; i++) a2[i] = array[i];
|
|
delete[] array;
|
|
array = a2;
|
|
}
|
|
|
|
size += by;
|
|
|
|
}
|
|
public:
|
|
DynamicArray(void)
|
|
{
|
|
size = 0;
|
|
range = 4;
|
|
array = new T[range];
|
|
}
|
|
|
|
~DynamicArray(void)
|
|
{
|
|
delete[] array;
|
|
}
|
|
|
|
T* GetAndReleaseArray(void)
|
|
{
|
|
T* a2 = array;
|
|
|
|
size = 0;
|
|
range = 4;
|
|
array = new T[range];
|
|
|
|
return a2;
|
|
}
|
|
|
|
int Size(void) { return size; }
|
|
|
|
bool Insert(T t)
|
|
{
|
|
Grow(1);
|
|
array[size - 1] = t;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Insert(int n, T t)
|
|
{
|
|
int m;
|
|
|
|
if (n >= 0 && n <= size)
|
|
{
|
|
Grow(1);
|
|
m = size - 1;
|
|
while (m > n)
|
|
{
|
|
array[m] = array[m - 1];
|
|
m--;
|
|
}
|
|
|
|
array[n] = t;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Lookup(int n, T& t)
|
|
{
|
|
if (n >= 0 && n < size)
|
|
{
|
|
t = array[n];
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool Replace(int n, T t, T& old)
|
|
{
|
|
if (n >= 0 && n < size)
|
|
{
|
|
old = array[n];
|
|
array[n] = t;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool Swap(int n, int m)
|
|
{
|
|
T t;
|
|
|
|
if (n >= 0 && n < size && m >= 0 && m < size)
|
|
{
|
|
t = array[n]; array[n] = array[m]; array[m] = t;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool Remove(int n)
|
|
{
|
|
if (n >= 0 && n < size)
|
|
{
|
|
while (n < size - 1)
|
|
{
|
|
array[n] = array[n + 1];
|
|
n++;
|
|
}
|
|
size--;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
int Find(T t)
|
|
{
|
|
int n;
|
|
|
|
n = size - 1;
|
|
while (n >= 0 && t != array[n])
|
|
n--;
|
|
|
|
return n;
|
|
}
|
|
};
|
|
|
|
|
|
template <class T>
|
|
class GrowingArray
|
|
{
|
|
protected:
|
|
int size, range;
|
|
T* array;
|
|
T empty;
|
|
|
|
void Grow(int to, bool clear)
|
|
{
|
|
T* a2;
|
|
int i;
|
|
|
|
if (clear) size = 0;
|
|
|
|
if (to > range)
|
|
{
|
|
if (to > range * 2)
|
|
range = to;
|
|
else
|
|
range = range * 2;
|
|
|
|
a2 = new T[range];
|
|
if (to > size)
|
|
for (i = 0; i < size; i++) a2[i] = array[i];
|
|
else
|
|
for (i = 0; i < to; i++) a2[i] = array[i];
|
|
|
|
delete[] array;
|
|
array = a2;
|
|
}
|
|
|
|
for (i = size; i < to; i++) array[i] = empty;
|
|
|
|
size = to;
|
|
}
|
|
|
|
public:
|
|
GrowingArray(T empty_)
|
|
: empty(empty_)
|
|
{
|
|
size = 0;
|
|
range = 4;
|
|
array = new T[range];
|
|
}
|
|
|
|
GrowingArray(const GrowingArray& a)
|
|
: empty(a.empty)
|
|
{
|
|
size = a.size;
|
|
range = a.range;
|
|
array = new T[range];
|
|
|
|
int lsize = size;
|
|
const T* sap = a.array;
|
|
T* dap = array;
|
|
for (int i = 0; i < lsize; i++) dap[i] = sap[i];
|
|
}
|
|
|
|
GrowingArray & operator=(const GrowingArray& a)
|
|
{
|
|
if (a.size != size)
|
|
Grow(a.size, true);
|
|
|
|
int lsize = size;
|
|
const T* sap = a.array;
|
|
T* dap = array;
|
|
for (int i = 0; i < lsize; i++) dap[i] = sap[i];
|
|
|
|
return *this;
|
|
}
|
|
|
|
~GrowingArray(void)
|
|
{
|
|
delete[] array;
|
|
}
|
|
|
|
T& operator[](int n)
|
|
{
|
|
assert(n >= 0);
|
|
if (n >= size) Grow(n + 1, false);
|
|
return array[n];
|
|
}
|
|
|
|
const T & operator[](int n) const
|
|
{
|
|
assert(n >= 0);
|
|
if (n >= size) return empty;
|
|
else return array[n];
|
|
}
|
|
|
|
const T getAt(int n) const
|
|
{
|
|
if (n >= size) return empty;
|
|
else return array[n];
|
|
}
|
|
|
|
void destroyAt(int n)
|
|
{
|
|
if (n < size)
|
|
array[n] = empty;
|
|
}
|
|
|
|
void Push(T t)
|
|
{
|
|
(*this)[size] = t;
|
|
}
|
|
|
|
T Pop(void)
|
|
{
|
|
assert(size > 0);
|
|
return array[--size];
|
|
}
|
|
|
|
void Insert(int at, T t)
|
|
{
|
|
Grow(size + 1, false);
|
|
int j = size - 1;
|
|
while (j > at)
|
|
{
|
|
array[j] = array[j - 1];
|
|
j--;
|
|
}
|
|
array[at] = t;
|
|
}
|
|
|
|
void Remove(int at)
|
|
{
|
|
while (at + 1 < size)
|
|
{
|
|
array[at] = array[at + 1];
|
|
at++;
|
|
}
|
|
Grow(at, false);
|
|
}
|
|
|
|
void Remove(int at, int n)
|
|
{
|
|
while (at + n < size)
|
|
{
|
|
array[at] = array[at + n];
|
|
at++;
|
|
}
|
|
Grow(at, false);
|
|
}
|
|
|
|
int RemoveAll(const T & t)
|
|
{
|
|
int j = 0, i = 0;
|
|
while (i < size)
|
|
{
|
|
if (array[i] != t)
|
|
{
|
|
if (i != j)
|
|
array[j] = array[i];
|
|
j++;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
Grow(j, false);
|
|
|
|
return i - j;
|
|
}
|
|
|
|
|
|
T Top(void) const
|
|
{
|
|
return array[size - 1];
|
|
}
|
|
|
|
bool IsEmpty(void) const { return size == 0; }
|
|
|
|
int Size(void) const { return size; }
|
|
|
|
T Last() const
|
|
{
|
|
assert(size > 0);
|
|
return array[size - 1];
|
|
}
|
|
|
|
void SetSize(int size, bool clear = false)
|
|
{
|
|
Grow(size, clear);
|
|
}
|
|
|
|
void Reserve(int to)
|
|
{
|
|
if (to > range)
|
|
{
|
|
range = to;
|
|
|
|
T* a2 = new T[range];
|
|
if (to > size)
|
|
for (int i = 0; i < size; i++) a2[i] = array[i];
|
|
else
|
|
for (int i = 0; i < to; i++) a2[i] = array[i];
|
|
|
|
delete[] array;
|
|
array = a2;
|
|
|
|
for (int i = size; i < range; i++) array[i] = empty;
|
|
}
|
|
}
|
|
|
|
void Clear(void)
|
|
{
|
|
Grow(size, true);
|
|
}
|
|
|
|
int IndexOf(const T& t) const
|
|
{
|
|
for (int i = 0; i < size; i++)
|
|
if (array[i] == t)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
bool Contains(const T& t) const
|
|
{
|
|
for (int i = 0; i < size; i++)
|
|
if (array[i] == t)
|
|
return true;
|
|
return false;
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
class ExpandingArray
|
|
{
|
|
public:
|
|
protected:
|
|
int size, range;
|
|
T * array;
|
|
|
|
void Grow(int to, bool clear)
|
|
{
|
|
T* a2;
|
|
int i;
|
|
|
|
if (clear) size = 0;
|
|
|
|
if (to > range)
|
|
{
|
|
if (to > range * 2)
|
|
range = to;
|
|
else
|
|
range = range * 2;
|
|
|
|
a2 = new T[range];
|
|
if (to > size)
|
|
for (i = 0; i < size; i++) a2[i] = array[i];
|
|
else
|
|
for (i = 0; i < to; i++) a2[i] = array[i];
|
|
|
|
delete[] array;
|
|
array = a2;
|
|
}
|
|
|
|
size = to;
|
|
}
|
|
|
|
public:
|
|
ExpandingArray(void)
|
|
{
|
|
size = 0;
|
|
range = 4;
|
|
array = new T[range];
|
|
}
|
|
|
|
ExpandingArray(const ExpandingArray& a)
|
|
{
|
|
size = a.size;
|
|
range = a.range;
|
|
array = new T[range];
|
|
|
|
int lsize = size;
|
|
const T* sap = a.array;
|
|
T* dap = array;
|
|
for (int i = 0; i < lsize; i++) dap[i] = sap[i];
|
|
}
|
|
|
|
ExpandingArray& operator=(const ExpandingArray& a)
|
|
{
|
|
if (a.size != size)
|
|
Grow(a.size, true);
|
|
|
|
int lsize = size;
|
|
const T* sap = a.array;
|
|
T* dap = array;
|
|
for (int i = 0; i < lsize; i++) dap[i] = sap[i];
|
|
|
|
return *this;
|
|
}
|
|
|
|
~ExpandingArray(void)
|
|
{
|
|
delete[] array;
|
|
}
|
|
|
|
void Push(const T & t)
|
|
{
|
|
int s = size;
|
|
Grow(size + 1, false);
|
|
array[s] = t;
|
|
}
|
|
|
|
T Pop(void)
|
|
{
|
|
assert(size > 0);
|
|
return array[--size];
|
|
}
|
|
|
|
void Insert(int at, T t)
|
|
{
|
|
Grow(size + 1, false);
|
|
assert(at >= 0 && at < size);
|
|
int j = size - 1;
|
|
while (j > at)
|
|
{
|
|
array[j] = array[j - 1];
|
|
j--;
|
|
}
|
|
array[at] = t;
|
|
}
|
|
|
|
void Remove(int at)
|
|
{
|
|
assert(at >= 0 && at < size);
|
|
while (at + 1 < size)
|
|
{
|
|
array[at] = array[at + 1];
|
|
at++;
|
|
}
|
|
Grow(at, false);
|
|
}
|
|
|
|
void Remove(int at, int n)
|
|
{
|
|
assert(at >= 0 && at + n <= size);
|
|
while (at + n < size)
|
|
{
|
|
array[at] = array[at + n];
|
|
at++;
|
|
}
|
|
Grow(at, false);
|
|
}
|
|
|
|
int RemoveAll(const T& t)
|
|
{
|
|
int j = 0, i = 0;
|
|
while (i < size)
|
|
{
|
|
if (array[i] != t)
|
|
{
|
|
if (i != j)
|
|
array[j] = array[i];
|
|
j++;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
Grow(j, false);
|
|
|
|
return i - j;
|
|
}
|
|
|
|
|
|
T Top(void) const
|
|
{
|
|
assert(size > 0);
|
|
return array[size - 1];
|
|
}
|
|
|
|
bool IsEmpty(void) const { return size == 0; }
|
|
|
|
int Size(void) const { return size; }
|
|
|
|
T Last() const
|
|
{
|
|
assert(size > 0);
|
|
return array[size - 1];
|
|
}
|
|
|
|
void SetSize(int size, bool clear = false)
|
|
{
|
|
assert(size >= 0);
|
|
Grow(size, clear);
|
|
}
|
|
|
|
void Reserve(int to)
|
|
{
|
|
if (to > range)
|
|
{
|
|
range = to;
|
|
|
|
T* a2 = new T[range];
|
|
if (to > size)
|
|
for (int i = 0; i < size; i++) a2[i] = array[i];
|
|
else
|
|
for (int i = 0; i < to; i++) a2[i] = array[i];
|
|
|
|
delete[] array;
|
|
array = a2;
|
|
}
|
|
}
|
|
|
|
int IndexOf(const T& t) const
|
|
{
|
|
for (int i = 0; i < size; i++)
|
|
if (array[i] == t)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
int IndexOrPush(const T& t)
|
|
{
|
|
for (int i = 0; i < size; i++)
|
|
if (array[i] == t)
|
|
return i;
|
|
int s = size;
|
|
Grow(size + 1, false);
|
|
array[s] = t;
|
|
return s;
|
|
}
|
|
|
|
bool Contains(const T& t) const
|
|
{
|
|
for (int i = 0; i < size; i++)
|
|
if (array[i] == t)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
__forceinline T& operator[](int n)
|
|
{
|
|
assert(n >= 0 && n < size);
|
|
return array[n];
|
|
}
|
|
|
|
__forceinline const T& operator[](int n) const
|
|
{
|
|
assert(n >= 0 && n < size);
|
|
return array[n];
|
|
}
|
|
};
|