159 lines
2.5 KiB
C
159 lines
2.5 KiB
C
|
#ifndef _INCLUDE_KNIGHT_KE_VECTOR_H_
|
||
|
#define _INCLUDE_KNIGHT_KE_VECTOR_H_
|
||
|
|
||
|
#include <new>
|
||
|
|
||
|
namespace Knight
|
||
|
{
|
||
|
template <class T>
|
||
|
class KeVector
|
||
|
{
|
||
|
public:
|
||
|
KeVector<T>() : m_Data(NULL), m_Size(0), m_CurrentUsedSize(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
KeVector<T>(const KeVector<T> & other)
|
||
|
{
|
||
|
m_Size = other.m_CurrentUsedSize;
|
||
|
m_CurrentUsedSize = other.m_CurrentUsedSize;
|
||
|
|
||
|
if (m_Size > 0)
|
||
|
{
|
||
|
m_Data = new T[other.m_CurrentUsedSize];
|
||
|
|
||
|
for (size_t i = 0; i < m_Size; i++)
|
||
|
{
|
||
|
m_Data[i] = other.m_Data[i];
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_Data = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
~KeVector<T>()
|
||
|
{
|
||
|
clear();
|
||
|
}
|
||
|
|
||
|
KeVector & operator =(const KeVector<T> & other)
|
||
|
{
|
||
|
clear();
|
||
|
|
||
|
if (other.m_CurrentUsedSize)
|
||
|
{
|
||
|
m_Data = new T[other.m_CurrentUsedSize];
|
||
|
m_Size = other.m_CurrentUsedSize;
|
||
|
m_CurrentUsedSize = other.m_CurrentUsedSize;
|
||
|
|
||
|
for (size_t i = 0; i < m_Size; i++)
|
||
|
{
|
||
|
m_Data[i] = other.m_Data[i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
size_t size() const
|
||
|
{
|
||
|
return m_CurrentUsedSize;
|
||
|
}
|
||
|
|
||
|
void push_back(const T & elem)
|
||
|
{
|
||
|
GrowIfNeeded(1);
|
||
|
|
||
|
new (&m_Data[m_CurrentUsedSize]) T(elem);
|
||
|
|
||
|
m_CurrentUsedSize++;
|
||
|
}
|
||
|
|
||
|
void pop_back(const T & elem)
|
||
|
{
|
||
|
if (m_CurrentUsedSize == 0)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_CurrentUsedSize--;
|
||
|
m_Data[m_CurrentUsedSize].~T();
|
||
|
}
|
||
|
|
||
|
bool is_empty()
|
||
|
{
|
||
|
return (m_CurrentUsedSize == 0);
|
||
|
}
|
||
|
|
||
|
T & operator [](size_t pos)
|
||
|
{
|
||
|
return m_Data[pos];
|
||
|
}
|
||
|
|
||
|
const T & operator [](size_t pos) const
|
||
|
{
|
||
|
return m_Data[pos];
|
||
|
}
|
||
|
|
||
|
void clear()
|
||
|
{
|
||
|
for (size_t i = 0; i < m_CurrentUsedSize; i++)
|
||
|
{
|
||
|
m_Data[i].~T();
|
||
|
}
|
||
|
|
||
|
free(m_Data);
|
||
|
|
||
|
m_Data = NULL;
|
||
|
m_Size = 0;
|
||
|
m_CurrentUsedSize = 0;
|
||
|
}
|
||
|
private:
|
||
|
void Grow(size_t amount)
|
||
|
{
|
||
|
T *new_data;
|
||
|
size_t new_size;
|
||
|
|
||
|
if (m_Size == 0)
|
||
|
{
|
||
|
new_size = 8;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
new_size = m_Size * 2;
|
||
|
}
|
||
|
|
||
|
while (m_CurrentUsedSize + amount > new_size)
|
||
|
{
|
||
|
new_size *= 2;
|
||
|
}
|
||
|
|
||
|
new_data = (T *)malloc(sizeof(T) * new_size);
|
||
|
|
||
|
for (size_t i = 0; i < m_CurrentUsedSize; i++)
|
||
|
{
|
||
|
new (&new_data[i]) T(m_Data[i]);
|
||
|
m_Data[i].~T();
|
||
|
}
|
||
|
|
||
|
free(m_Data);
|
||
|
m_Data = new_data;
|
||
|
m_Size = new_size;
|
||
|
}
|
||
|
|
||
|
void GrowIfNeeded(size_t amount)
|
||
|
{
|
||
|
if (m_CurrentUsedSize + amount >= m_Size)
|
||
|
{
|
||
|
Grow(amount);
|
||
|
}
|
||
|
}
|
||
|
private:
|
||
|
T *m_Data;
|
||
|
size_t m_Size;
|
||
|
size_t m_CurrentUsedSize;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
#endif //_INCLUDE_KNIGHT_KE_VECTOR_H_
|