Advertisement
Guest User

Untitled

a guest
Jun 19th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.88 KB | None | 0 0
  1. #ifndef AMVECTOR_H
  2. #define AMVECTOR_H
  3.  
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <algorithm>
  8. #include <initializer_list>
  9.  
  10. template < typename T >
  11. class AMVector
  12. {
  13. public:
  14. AMVector()
  15. {
  16. m_pElementList = nullptr;
  17. m_iElementCount = 0;
  18. m_iVectorCapacity = 0;
  19.  
  20. // Size of element type shouldn't change, so we store it.
  21. m_iElementSize = sizeof( T );
  22. }
  23.  
  24. AMVector( int32_t iVectorCapacity ) : AMVector()
  25. {
  26. Reserve( iVectorCapacity );
  27. }
  28.  
  29. AMVector( const AMVector &other )
  30. {
  31. m_iElementCount = other.m_iElementCount;
  32. m_iElementSize = other.m_iElementSize;
  33. m_iVectorCapacity = other.m_iVectorCapacity;
  34.  
  35. m_pElementList = new T[ m_iVectorCapacity ];
  36. memcpy( m_pElementList, other.m_pElementList, GetElementSize() * Count() );
  37. }
  38.  
  39. AMVector( std::initializer_list< T > elements )
  40. {
  41. m_iElementSize = sizeof ( T );
  42. m_iElementCount = ( int32_t )elements.size();
  43. m_iVectorCapacity = ( int32_t )elements.size();
  44. m_pElementList = new T[ m_iElementCount ];
  45.  
  46. // Should maybe use std::begin( elements ) + m_iElementCount as we're casting size() which is size_t to int32_t
  47. std::copy( std::begin( elements ), std::end( elements ), m_pElementList );
  48. }
  49.  
  50. ~AMVector()
  51. {
  52. if ( m_pElementList )
  53. delete[] m_pElementList;
  54. }
  55.  
  56. int32_t AddToTail( const T &element )
  57. {
  58. return InsertBefore( InvalidIndex(), element );
  59. }
  60.  
  61. void AddMultipleToTail( T *pElements, int32_t numElements )
  62. {
  63. if ( pElements == nullptr )
  64. return;
  65.  
  66. for ( int32_t i = 0; i < numElements; i++ )
  67. InsertBefore( InvalidIndex(), pElements[ i ] );
  68. }
  69.  
  70. int32_t AddToHead( const T &element )
  71. {
  72. return InsertBefore( 0, element );
  73. }
  74.  
  75. void AddMultipleToHead( T *pElements, int32_t numElements )
  76. {
  77. if ( pElements == nullptr )
  78. return;
  79.  
  80. for ( int32_t i = 0; i < numElements; i++ )
  81. InsertBefore( 0, pElements[ i ] );
  82. }
  83.  
  84. AMVector& operator = ( AMVector other )
  85. {
  86. std::swap( m_iElementCount, other.m_iElementCount );
  87. std::swap( m_iVectorCapacity, other.m_iVectorCapacity );
  88. std::swap( m_iElementSize, other.m_iElementSize );
  89. std::swap( m_pElementList, other.m_pElementList );
  90.  
  91. return *this;
  92. }
  93. T& operator [] ( const int32_t &elem )
  94. {
  95. return m_pElementList[ elem ];
  96. }
  97.  
  98. const T& operator [] ( const int32_t &elem ) const
  99. {
  100. return m_pElementList[ elem ];
  101. }
  102.  
  103. bool IsValidIndex( int32_t index )
  104. {
  105. return ( index < Count() && Count() > 0 && index >= 0 );
  106. }
  107.  
  108. T *Data() { return m_pElementList; }
  109.  
  110. inline const int32_t &Count() { return m_iElementCount; }
  111. inline const int32_t &Capacity() { return m_iVectorCapacity; }
  112.  
  113. void Purge()
  114. {
  115. if ( m_pElementList )
  116. {
  117. delete[] m_pElementList;
  118. m_pElementList = nullptr;
  119. }
  120.  
  121. m_iElementCount = 0;
  122. m_iVectorCapacity = 0;
  123. }
  124.  
  125. void PurgeAndDeleteElements()
  126. {
  127. for ( int32_t i = 0; i < Count(); i++ )
  128. if ( m_pElementList[i] )
  129. delete m_pElementList[i];
  130.  
  131. Purge();
  132. }
  133.  
  134. void Remove( int32_t index )
  135. {
  136. if ( !IsValidIndex( index ) ) // This also checks if element count is 0
  137. return;
  138. else if ( Count() == 1 )
  139. {
  140. Purge();
  141. return;
  142. }
  143.  
  144. ShiftElementsLeft( index );
  145.  
  146. int32_t iNewElementCount = Count() - 1;
  147. int32_t iNewVectorCapacity = Capacity() - 1;
  148.  
  149. T *pTempElements = new T[ iNewVectorCapacity ];
  150. memcpy( pTempElements, m_pElementList, GetElementSize() * ( iNewElementCount ) );
  151. delete[] m_pElementList;
  152.  
  153. m_pElementList = pTempElements;
  154. m_iElementCount = iNewElementCount;
  155. m_iVectorCapacity = iNewVectorCapacity;
  156. }
  157.  
  158. void Resize( int32_t newSize )
  159. {
  160. if ( newSize == Capacity() )
  161. return;
  162. else if ( newSize > Capacity() )
  163. {
  164. Reserve( newSize - Capacity() );
  165. return;
  166. }
  167. else if ( newSize < Capacity() )
  168. {
  169. T *pTempElements = new T[ newSize ];
  170. memcpy( pTempElements, m_pElementList, GetElementSize() * ( newSize ) );
  171. delete[] m_pElementList;
  172. m_pElementList = pTempElements;
  173.  
  174. if ( newSize < Count() )
  175. m_iElementCount = newSize;
  176.  
  177. m_iVectorCapacity = newSize;
  178.  
  179. return;
  180. }
  181. }
  182.  
  183. void Reserve( int32_t numElements )
  184. {
  185. if ( m_pElementList == nullptr )
  186. {
  187. m_pElementList = new T[ numElements ];
  188. m_iVectorCapacity = numElements;
  189. return;
  190. }
  191.  
  192. int32_t iNewCapacity = Capacity() + numElements;
  193. T *pTempElements = new T[ iNewCapacity ];
  194. memcpy( pTempElements, m_pElementList, GetElementSize() * ( m_iElementCount ) );
  195. delete[] m_pElementList;
  196. m_pElementList = pTempElements;
  197. m_iVectorCapacity = iNewCapacity;
  198. }
  199.  
  200. const size_t &GetElementSize() { return m_iElementSize; }
  201.  
  202. bool IsEmpty()
  203. {
  204. return ( Count() == 0 );
  205. }
  206.  
  207. inline int32_t InvalidIndex() { return -1; }
  208.  
  209. protected:
  210.  
  211. // Note: Inserting before the specified index, means that the new element will be at that index because of element shifting
  212. // It may be better to rename this to InsertAt
  213. int32_t InsertBefore( int32_t index, const T &element )
  214. {
  215. // We should probably do some checking to make sure we're not hitting the max value for our element count's type
  216. // However I don't have 17 GB of spare RAM to test this...
  217.  
  218. // Something bad happened
  219. if ( index >= Capacity() )
  220. return InvalidIndex();
  221.  
  222. T *pTempElements = nullptr;
  223. int32_t iNewElementCount = Count() + 1;
  224.  
  225. if ( iNewElementCount > Capacity() )
  226. {
  227. pTempElements = new T[ iNewElementCount ];
  228. m_iVectorCapacity = iNewElementCount;
  229.  
  230. if ( m_pElementList == nullptr )
  231. {
  232. m_pElementList = pTempElements;
  233. m_pElementList[ m_iElementCount ] = element;
  234. m_iElementCount = iNewElementCount;
  235. return Count() - 1;
  236. }
  237.  
  238. memcpy( pTempElements, m_pElementList, GetElementSize() * ( m_iElementCount ) );
  239. delete[] m_pElementList;
  240.  
  241. m_pElementList = pTempElements;
  242.  
  243. if ( index == InvalidIndex() )
  244. {
  245. m_pElementList[ m_iElementCount ] = element;
  246. m_iElementCount = iNewElementCount;
  247. return Count() - 1;
  248. }
  249.  
  250. m_iElementCount = iNewElementCount;
  251. ShiftElementsRight( index );
  252.  
  253. m_pElementList[index] = element;
  254. return index;
  255. }
  256.  
  257. if ( index == InvalidIndex() )
  258. {
  259. m_pElementList[ m_iElementCount ] = element;
  260. m_iElementCount = iNewElementCount;
  261. return Count() - 1;
  262. }
  263.  
  264. m_iElementCount = iNewElementCount;
  265.  
  266. ShiftElementsRight( index );
  267. m_pElementList[ index ] = element;
  268. return index;
  269. }
  270.  
  271. void ShiftElementsRight( int32_t index )
  272. {
  273. for ( int32_t i = Count() - 1; ( i >= index && i != 0 ); i-- )
  274. m_pElementList[ i ] = m_pElementList[ i - 1 ];
  275. }
  276.  
  277. void ShiftElementsLeft( int32_t index )
  278. {
  279. for ( int32_t i = index; i < Count() - 1; i++ )
  280. m_pElementList[i] = m_pElementList[ i + 1 ];
  281. }
  282.  
  283. int32_t m_iElementCount; // Number of elements in vector
  284. int32_t m_iVectorCapacity; // Number of allocated slots in vector
  285. size_t m_iElementSize; // Size of an individual element in vector
  286. T *m_pElementList; // Actual vector/element list
  287. };
  288.  
  289. #endif // AMVECTOR_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement