util_list.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #ifndef __UTIL_LIST_H__
  19. #define __UTIL_LIST_H__
  20. #include <stdlib.h>
  21. #include <assert.h>
  22. template< class type >
  23. class idList {
  24. private:
  25. int m_num;
  26. int m_size;
  27. int m_granularity;
  28. type *m_list;
  29. public:
  30. idList( int granularity = 16 );
  31. ~idList<type>();
  32. void Clear( void );
  33. int Num( void );
  34. void SetNum( int num );
  35. void SetGranularity( int granularity );
  36. void Condense( void );
  37. int Size( void );
  38. void Resize( int size );
  39. type operator[]( int index ) const;
  40. type &operator[]( int index );
  41. int Append( type const & obj );
  42. int AddUnique( type const & obj );
  43. type *Find( type const & obj, int *index = NULL );
  44. bool RemoveIndex( int index );
  45. bool Remove( type const & obj );
  46. typedef int cmp_t(const void *, const void *);
  47. void Sort( cmp_t *compare );
  48. };
  49. /*
  50. ================
  51. idList<type>::idList( int )
  52. ================
  53. */
  54. template< class type >
  55. inline idList<type>::idList( int granularity ) {
  56. assert( granularity > 0 );
  57. m_list = NULL;
  58. m_granularity = granularity;
  59. Clear();
  60. }
  61. /*
  62. ================
  63. idList<type>::~idList<type>
  64. ================
  65. */
  66. template< class type >
  67. inline idList<type>::~idList() {
  68. Clear();
  69. }
  70. /*
  71. ================
  72. idList<type>::Clear
  73. ================
  74. */
  75. template< class type >
  76. inline void idList<type>::Clear( void ) {
  77. if ( m_list ) {
  78. delete[] m_list;
  79. }
  80. m_list = NULL;
  81. m_num = 0;
  82. m_size = 0;
  83. }
  84. /*
  85. ================
  86. idList<type>::Num
  87. ================
  88. */
  89. template< class type >
  90. inline int idList<type>::Num( void ) {
  91. return m_num;
  92. }
  93. /*
  94. ================
  95. idList<type>::SetNum
  96. ================
  97. */
  98. template< class type >
  99. inline void idList<type>::SetNum( int num ) {
  100. assert( num >= 0 );
  101. if ( num > m_size ) {
  102. // resize it up to the closest level of granularity
  103. Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity );
  104. }
  105. m_num = num;
  106. }
  107. /*
  108. ================
  109. idList<type>::SetGranularity
  110. ================
  111. */
  112. template< class type >
  113. inline void idList<type>::SetGranularity( int granularity ) {
  114. int newsize;
  115. assert( granularity > 0 );
  116. m_granularity = granularity;
  117. if ( m_list ) {
  118. // resize it to the closest level of granularity
  119. newsize = ( ( m_num + m_granularity - 1 ) / m_granularity ) * m_granularity;
  120. if ( newsize != m_size ) {
  121. Resize( newsize );
  122. }
  123. }
  124. }
  125. /*
  126. ================
  127. idList<type>::Condense
  128. Resizes the array to exactly the number of elements it contains
  129. ================
  130. */
  131. template< class type >
  132. inline void idList<type>::Condense( void ) {
  133. if ( m_list ) {
  134. if ( m_num ) {
  135. Resize( m_num );
  136. } else {
  137. Clear();
  138. }
  139. }
  140. }
  141. /*
  142. ================
  143. idList<type>::Size
  144. ================
  145. */
  146. template< class type >
  147. inline int idList<type>::Size( void ) {
  148. return m_size;
  149. }
  150. /*
  151. ================
  152. idList<type>::Resize
  153. ================
  154. */
  155. template< class type >
  156. inline void idList<type>::Resize( int size ) {
  157. type *temp;
  158. int i;
  159. assert( size > 0 );
  160. if ( size <= 0 ) {
  161. Clear();
  162. return;
  163. }
  164. temp = m_list;
  165. m_size = size;
  166. if ( m_size < m_num ) {
  167. m_num = m_size;
  168. }
  169. m_list = new type[ m_size ];
  170. for( i = 0; i < m_num; i++ ) {
  171. m_list[ i ] = temp[ i ];
  172. }
  173. if ( temp ) {
  174. delete[] temp;
  175. }
  176. }
  177. /*
  178. ================
  179. idList<type>::operator[] const
  180. ================
  181. */
  182. template< class type >
  183. inline type idList<type>::operator[]( int index ) const {
  184. assert( index >= 0 );
  185. assert( index < m_num );
  186. return m_list[ index ];
  187. }
  188. /*
  189. ================
  190. idList<type>::operator[]
  191. ================
  192. */
  193. template< class type >
  194. inline type &idList<type>::operator[]( int index ) {
  195. assert( index >= 0 );
  196. assert( index < m_num );
  197. return m_list[ index ];
  198. }
  199. /*
  200. ================
  201. idList<type>::Append
  202. ================
  203. */
  204. template< class type >
  205. inline int idList<type>::Append( type const & obj ) {
  206. if ( !m_list ) {
  207. Resize( m_granularity );
  208. }
  209. if ( m_num == m_size ) {
  210. Resize( m_size + m_granularity );
  211. }
  212. m_list[ m_num ] = obj;
  213. m_num++;
  214. return m_num - 1;
  215. }
  216. /*
  217. ================
  218. idList<type>::AddUnique
  219. ================
  220. */
  221. template< class type >
  222. inline int idList<type>::AddUnique( type const & obj ) {
  223. int index;
  224. if ( !Find( obj, &index ) ) {
  225. index = Append( obj );
  226. }
  227. return index;
  228. }
  229. /*
  230. ================
  231. idList<type>::Find
  232. ================
  233. */
  234. template< class type >
  235. inline type *idList<type>::Find( type const & obj, int *index ) {
  236. int i;
  237. for( i = 0; i < m_num; i++ ) {
  238. if ( m_list[ i ] == obj ) {
  239. if ( index ) {
  240. *index = i;
  241. }
  242. return &m_list[ i ];
  243. }
  244. }
  245. return NULL;
  246. }
  247. /*
  248. ================
  249. idList<type>::RemoveIndex
  250. ================
  251. */
  252. template< class type >
  253. inline bool idList<type>::RemoveIndex( int index ) {
  254. int i;
  255. if ( !m_list || !m_num ) {
  256. return false;
  257. }
  258. assert( index >= 0 );
  259. assert( index < m_num );
  260. if ( ( index < 0 ) || ( index >= m_num ) ) {
  261. return false;
  262. }
  263. m_num--;
  264. for( i = index; i < m_num; i++ ) {
  265. m_list[ i ] = m_list[ i + 1 ];
  266. }
  267. return true;
  268. }
  269. /*
  270. ================
  271. idList<type>::Remove
  272. ================
  273. */
  274. template< class type >
  275. inline bool idList<type>::Remove( type const & obj ) {
  276. int index;
  277. if ( Find( obj, &index ) ) {
  278. return RemoveIndex( index );
  279. }
  280. return false;
  281. }
  282. /*
  283. ================
  284. idList<type>::Sort
  285. ================
  286. */
  287. template< class type >
  288. inline void idList<type>::Sort( cmp_t *compare ) {
  289. if ( !m_list ) {
  290. return;
  291. }
  292. qsort( ( void * )m_list, ( size_t )m_num, sizeof( type ), compare );
  293. }
  294. #endif /* !__UTIL_LIST_H__ */