home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / XenonSource.exe / gamesystem / includes / gs_list.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-26  |  5.9 KB  |  299 lines

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    gsCList Template
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    12/03/00
  8. //
  9. // Base:    None
  10. //
  11. // Derived:    None
  12. //
  13. //-------------------------------------------------------------
  14.  
  15. #ifndef _INCLUDE_GS_LIST_H
  16. #define _INCLUDE_GS_LIST_H
  17.  
  18. #include <string.h>
  19. #include "gs_error.h"
  20.  
  21. //-------------------------------------------------------------
  22. // Initial allocation
  23.  
  24. const int gsLIST_DEFAULT_ALLOCATION = 1;
  25.  
  26. //-------------------------------------------------------------
  27. // Re-allocation strategy
  28. //
  29. // new_size = old_size * T + P
  30.  
  31. const int gsLIST_ALLOCATION_TIMES = 1;
  32. const int gsLIST_ALLOCATION_PLUS = 1;
  33.  
  34. //-------------------------------------------------------------
  35. // List Class Template
  36.  
  37. template<class Type> class gsCList
  38. {
  39.     private:
  40.     
  41.         Type *m_array;
  42.         int m_count;
  43.         int m_allocated_size;
  44.  
  45.         void allocate(int new_size);
  46.         
  47.     public:
  48.         gsCList(int size = 0);
  49.  
  50.         void clear();
  51.  
  52.         void addItem(Type data);
  53.         void removeItem(const Type data);
  54.         void removeIndex(int index);
  55.         void insertItem(int index,const Type data);
  56.         int findItem(const Type data);
  57.         void setItem(int index,Type data);
  58.         void removeEmptyItems();
  59.  
  60.         inline Type operator [] (int index) const;
  61.  
  62.         inline int getSize();
  63.         void setSize(int size);
  64.  
  65.         inline bool isEmpty();
  66.  
  67.         virtual ~gsCList();
  68. };
  69.  
  70. //-------------------------------------------------------------
  71. // Constructor
  72.  
  73. template<class Type>
  74. gsCList<Type>::gsCList(int size)
  75. {
  76.     m_array = 0;
  77.     m_count = 0;
  78.     m_allocated_size = 0;
  79.     if (size)
  80.         setSize(size);
  81. }
  82.  
  83. //-------------------------------------------------------------
  84. // Clear list
  85.  
  86. template<class Type>
  87. void gsCList<Type>::clear()
  88. {
  89.     m_count = 0;
  90.  
  91.     if (m_array) {
  92.         delete [] m_array;
  93.         m_array = 0;
  94.         }
  95.  
  96.     m_allocated_size = 0;
  97. }
  98.  
  99. //-------------------------------------------------------------
  100. // Allocate/Re-allocate space
  101.  
  102. template<class Type>
  103. void gsCList<Type>::allocate(int new_size)
  104. {
  105.     if (new_size <= 0 || new_size < m_count)
  106.         return;
  107.     Type *old_array = m_array;
  108.     m_allocated_size = new_size;
  109.     m_array = new Type[m_allocated_size];
  110.     if (m_count > 0)
  111.         memcpy(m_array,old_array,m_count * sizeof(Type));
  112.     if (old_array)
  113.         delete [] old_array;
  114. }
  115.  
  116. //-------------------------------------------------------------
  117. // Add item to list
  118.  
  119. template<class Type>
  120. void gsCList<Type>::addItem(Type data)
  121. {
  122.     if (m_count == m_allocated_size) {
  123.         if (m_allocated_size == 0)
  124.             allocate(gsLIST_DEFAULT_ALLOCATION);
  125.         else
  126.             allocate(m_allocated_size * gsLIST_ALLOCATION_TIMES + gsLIST_ALLOCATION_PLUS);
  127.         }
  128.  
  129.     m_array[m_count++] = data;
  130. }
  131.  
  132. //-------------------------------------------------------------
  133. // Set the value of an existing item
  134.  
  135. template<class Type>
  136. void gsCList<Type>::setItem(int index,Type data)
  137. {
  138.     if (index >= 0 || index < m_count)
  139.         m_array[index] = data;
  140. }
  141.         
  142. //-------------------------------------------------------------
  143. // Remove all references to an item from list
  144.  
  145. template<class Type>
  146. void gsCList<Type>::removeItem(const Type data)
  147. {
  148.     int index = findItem(data);
  149.  
  150.     while (index != -1) {
  151.         removeIndex(index);
  152.         index = findItem(data);
  153.         }
  154. }
  155.  
  156. //-------------------------------------------------------------
  157. // Remove item at given index
  158.  
  159. template<class Type>
  160. void gsCList<Type>::removeIndex(int index)
  161. {
  162.     if (index < 0 || index >= m_count)
  163.         return;
  164.  
  165.     if (index < m_count - 1)
  166.         memmove(&m_array[index],&m_array[index + 1],(m_count - 1 - index) * sizeof(Type));
  167.  
  168.     m_count--;
  169. }
  170.  
  171. //-------------------------------------------------------------
  172. // Insert item into list
  173.  
  174. template<class Type>
  175. void gsCList<Type>::insertItem(int index,Type data)
  176. {
  177.     if (index < 0 || index > m_count)
  178.         return;
  179.  
  180.     if (m_count == 0 ||
  181.         index == m_count)
  182.         addItem(data);
  183.     else {
  184.         Type last = m_array[m_count - 1];
  185.  
  186.         for (int i = m_count - 1; i > index; i--)
  187.             m_array[i] = m_array[i - 1];
  188.  
  189.         m_array[index] = data;
  190.         addItem(last);
  191.         }
  192. }
  193.  
  194. //-------------------------------------------------------------
  195. // Find item in list
  196. //
  197. // Returns:
  198. //
  199. // position of item (range 0...size of list - 1)
  200. // -1 if item not found
  201.  
  202. template<class Type>
  203. int gsCList<Type>::findItem(const Type data)
  204. {
  205.     for (int i = 0; i < m_count; i++) {
  206.         if (m_array[i] == data)
  207.             return i;
  208.         }
  209.  
  210.     return -1;
  211. }
  212.  
  213. //-------------------------------------------------------------
  214. // Remove any empty items (i.e. == 0)
  215.  
  216. template<class Type>
  217. void gsCList<Type>::removeEmptyItems()
  218. {
  219.     int i = m_count;
  220.  
  221.     while (--i >= 0) {
  222.         if (m_array[i] == 0)
  223.             removeIndex(i);
  224.         }
  225. }
  226.  
  227. //-------------------------------------------------------------
  228. // Index item in list
  229. //
  230. // Returns:
  231. //
  232. // pointer to item (0 if index out of range)
  233.  
  234. template<class Type>
  235. inline Type gsCList<Type>::operator [] (int index) const
  236. {
  237.     gsASSERT(index >= 0 && index < m_count);
  238.  
  239.     return m_array[index];
  240. }
  241.  
  242. //-------------------------------------------------------------
  243. // Get size of list
  244. //
  245. // Returns:
  246. //
  247. // number of items in list (0 if empty)
  248.  
  249. template<class Type>
  250. inline int gsCList<Type>::getSize()
  251. {
  252.     return m_count;
  253. }
  254.  
  255. //-------------------------------------------------------------
  256. // Set size of list
  257.  
  258. template<class Type>
  259. void gsCList<Type>::setSize(int size)
  260. {
  261.     if (size == 0) {
  262.         if (m_array) {
  263.             delete [] m_array;
  264.             m_array = 0;
  265.             }
  266.         }
  267.     else
  268.         allocate(size);
  269.     m_count = size;
  270. }
  271.  
  272. //-------------------------------------------------------------
  273. // Is list empty ?
  274. //
  275. // Returns:
  276. //
  277. // true/false
  278.  
  279. template<class Type>
  280. inline bool gsCList<Type>::isEmpty()
  281. {
  282.     return m_count == 0;
  283. }
  284.  
  285. //-------------------------------------------------------------
  286. // Destructor
  287.  
  288. template<class Type>
  289. gsCList<Type>::~gsCList()
  290. {
  291.     if (m_array)
  292.         delete [] m_array;
  293. }
  294.  
  295. //-------------------------------------------------------------
  296.  
  297. #endif
  298.  
  299.