knight/shared/KeVector.h
author Kyle Sanderson <kyle.leet@gmail.com>
Wed Jul 31 22:03:59 2013 -0400 (2013-07-31)
changeset 3963 39fc1ce67130
parent 2226 d10b38524be3
permissions -rw-r--r--
Fixed crash in SDKHooks when throwing bad ent type error on logical ent (r=psychonic).
     1 #ifndef _INCLUDE_KNIGHT_KE_VECTOR_H_
     2 #define _INCLUDE_KNIGHT_KE_VECTOR_H_
     3 
     4 #include <new>
     5 
     6 namespace Knight
     7 {
     8 	template <class T>
     9 	class KeVector
    10 	{
    11 	public:
    12 		KeVector<T>() : m_Data(NULL), m_Size(0), m_CurrentUsedSize(0)
    13 		{
    14 		}
    15 
    16 		KeVector<T>(const KeVector<T> & other)
    17 		{
    18 			m_Size = other.m_CurrentUsedSize;
    19 			m_CurrentUsedSize = other.m_CurrentUsedSize;
    20 
    21 			if (m_Size > 0)
    22 			{
    23 				m_Data = new T[other.m_CurrentUsedSize];
    24 
    25 				for (size_t i = 0; i < m_Size; i++)
    26 				{
    27 					m_Data[i] = other.m_Data[i];
    28 				}
    29 			}
    30 			else
    31 			{
    32 				m_Data = NULL;
    33 			}
    34 		}
    35 
    36 		~KeVector<T>()
    37 		{
    38 			clear();
    39 		}
    40 
    41 		KeVector & operator =(const KeVector<T> & other)
    42 		{
    43 			clear();
    44 
    45 			if (other.m_CurrentUsedSize)
    46 			{
    47 				m_Data = new T[other.m_CurrentUsedSize];
    48 				m_Size = other.m_CurrentUsedSize;
    49 				m_CurrentUsedSize = other.m_CurrentUsedSize;
    50 
    51 				for (size_t i = 0; i < m_Size; i++)
    52 				{
    53 					m_Data[i] = other.m_Data[i];
    54 				}
    55 			}
    56 		}
    57 
    58 		size_t size() const
    59 		{
    60 			return m_CurrentUsedSize;
    61 		}
    62 
    63 		void push_back(const T & elem)
    64 		{
    65 			GrowIfNeeded(1);
    66 
    67 			new (&m_Data[m_CurrentUsedSize]) T(elem);
    68 
    69 			m_CurrentUsedSize++;
    70 		}
    71 
    72 		void pop_back(const T & elem)
    73 		{
    74 			if (m_CurrentUsedSize == 0)
    75 			{
    76 				return;
    77 			}
    78 
    79 			m_CurrentUsedSize--;
    80 			m_Data[m_CurrentUsedSize].~T();
    81 		}
    82 
    83 		bool is_empty()
    84 		{
    85 			return (m_CurrentUsedSize == 0);
    86 		}
    87 
    88 		T & operator [](size_t pos)
    89 		{
    90 			return m_Data[pos];
    91 		}
    92 
    93 		const T & operator [](size_t pos) const
    94 		{
    95 			return m_Data[pos];
    96 		}
    97 
    98 		void clear()
    99 		{
   100 			for (size_t i = 0; i < m_CurrentUsedSize; i++)
   101 			{
   102 				m_Data[i].~T();
   103 			}
   104 
   105 			free(m_Data);
   106 			
   107 			m_Data = NULL;
   108 			m_Size = 0;
   109 			m_CurrentUsedSize = 0;
   110 		}
   111 	private:
   112 		void Grow(size_t amount)
   113 		{
   114 			T *new_data;
   115 			size_t new_size;
   116 
   117 			if (m_Size == 0)
   118 			{
   119 				new_size = 8;
   120 			}
   121 			else
   122 			{
   123 				new_size = m_Size * 2;
   124 			}
   125 
   126 			while (m_CurrentUsedSize + amount > new_size)
   127 			{
   128 				new_size *= 2;
   129 			}
   130 
   131 			new_data = (T *)malloc(sizeof(T) * new_size);
   132 
   133 			for (size_t i = 0; i < m_CurrentUsedSize; i++)
   134 			{
   135 				new (&new_data[i]) T(m_Data[i]);
   136 				m_Data[i].~T();
   137 			}
   138 
   139 			free(m_Data);
   140 			m_Data = new_data;
   141 			m_Size = new_size;
   142 		}
   143 
   144 		void GrowIfNeeded(size_t amount)
   145 		{
   146 			if (m_CurrentUsedSize + amount >= m_Size)
   147 			{
   148 				Grow(amount);
   149 			}
   150 		}
   151 	private:
   152 		T *m_Data;
   153 		size_t m_Size;
   154 		size_t m_CurrentUsedSize;
   155 	};
   156 }
   157 
   158 #endif //_INCLUDE_KNIGHT_KE_VECTOR_H_