#ifndef _INCLUDE_KNIGHT_KE_VECTOR_H_ #define _INCLUDE_KNIGHT_KE_VECTOR_H_ #include namespace Knight { template class KeVector { public: KeVector() : m_Data(NULL), m_Size(0), m_CurrentUsedSize(0) { } KeVector(const KeVector & 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() { clear(); } KeVector & operator =(const KeVector & 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_