1 /*
2 ===========================================================================
3
4 Return to Castle Wolfenstein single player GPL Source Code
5 Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
6
7 This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
8
9 RTCW SP Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 RTCW SP Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the RTCW SP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW SP Source Code. If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #ifndef __UTIL_LIST_H__
30 #define __UTIL_LIST_H__
31
32 #include <stdlib.h>
33 #include <assert.h>
34
35 template< class type >
36 class idList {
37 private:
38 int m_num;
39 int m_size;
40 int m_granularity;
41 type *m_list;
42
43 public:
44 idList( int granularity = 16 );
45 ~idList<type>();
46 void Clear( void );
47 int Num( void );
48 void SetNum( int num );
49 void SetGranularity( int granularity );
50 void Condense( void );
51 int Size( void );
52 void Resize( int size );
53 type operator[]( int index ) const;
54 type &operator[]( int index );
55 int Append( type const & obj );
56 int AddUnique( type const & obj );
57 type *Find( type const & obj, int *index = NULL );
58 bool RemoveIndex( int index );
59 bool Remove( type const & obj );
60 typedef int cmp_t ( const void *, const void * );
61 void Sort( cmp_t *compare );
62 };
63
64 /*
65 ================
66 idList<type>::idList( int )
67 ================
68 */
69 template< class type >
idList(int granularity)70 inline idList<type>::idList( int granularity ) {
71 assert( granularity > 0 );
72
73 m_list = NULL;
74 m_granularity = granularity;
75 Clear();
76 }
77
78 /*
79 ================
80 idList<type>::~idList<type>
81 ================
82 */
83 template< class type >
~idList()84 inline idList<type>::~idList() {
85 Clear();
86 }
87
88 /*
89 ================
90 idList<type>::Clear
91 ================
92 */
93 template< class type >
Clear(void)94 inline void idList<type>::Clear( void ) {
95 if ( m_list ) {
96 delete[] m_list;
97 }
98
99 m_list = NULL;
100 m_num = 0;
101 m_size = 0;
102 }
103
104 /*
105 ================
106 idList<type>::Num
107 ================
108 */
109 template< class type >
Num(void)110 inline int idList<type>::Num( void ) {
111 return m_num;
112 }
113
114 /*
115 ================
116 idList<type>::SetNum
117 ================
118 */
119 template< class type >
SetNum(int num)120 inline void idList<type>::SetNum( int num ) {
121 assert( num >= 0 );
122 if ( num > m_size ) {
123 // resize it up to the closest level of granularity
124 Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity );
125 }
126 m_num = num;
127 }
128
129 /*
130 ================
131 idList<type>::SetGranularity
132 ================
133 */
134 template< class type >
SetGranularity(int granularity)135 inline void idList<type>::SetGranularity( int granularity ) {
136 int newsize;
137
138 assert( granularity > 0 );
139 m_granularity = granularity;
140
141 if ( m_list ) {
142 // resize it to the closest level of granularity
143 newsize = ( ( m_num + m_granularity - 1 ) / m_granularity ) * m_granularity;
144 if ( newsize != m_size ) {
145 Resize( newsize );
146 }
147 }
148 }
149
150 /*
151 ================
152 idList<type>::Condense
153
154 Resizes the array to exactly the number of elements it contains
155 ================
156 */
157 template< class type >
Condense(void)158 inline void idList<type>::Condense( void ) {
159 if ( m_list ) {
160 if ( m_num ) {
161 Resize( m_num );
162 } else {
163 Clear();
164 }
165 }
166 }
167
168 /*
169 ================
170 idList<type>::Size
171 ================
172 */
173 template< class type >
Size(void)174 inline int idList<type>::Size( void ) {
175 return m_size;
176 }
177
178 /*
179 ================
180 idList<type>::Resize
181 ================
182 */
183 template< class type >
Resize(int size)184 inline void idList<type>::Resize( int size ) {
185 type *temp;
186 int i;
187
188 assert( size > 0 );
189
190 if ( size <= 0 ) {
191 Clear();
192 return;
193 }
194
195 temp = m_list;
196 m_size = size;
197 if ( m_size < m_num ) {
198 m_num = m_size;
199 }
200
201 m_list = new type[ m_size ];
202 for ( i = 0; i < m_num; i++ ) {
203 m_list[ i ] = temp[ i ];
204 }
205
206 if ( temp ) {
207 delete[] temp;
208 }
209 }
210
211 /*
212 ================
213 idList<type>::operator[] const
214 ================
215 */
216 template< class type >
217 inline type idList<type>::operator[]( int index ) const {
218 assert( index >= 0 );
219 assert( index < m_num );
220
221 return m_list[ index ];
222 }
223
224 /*
225 ================
226 idList<type>::operator[]
227 ================
228 */
229 template< class type >
230 inline type &idList<type>::operator[]( int index ) {
231 assert( index >= 0 );
232 assert( index < m_num );
233
234 return m_list[ index ];
235 }
236
237 /*
238 ================
239 idList<type>::Append
240 ================
241 */
242 template< class type >
Append(type const & obj)243 inline int idList<type>::Append( type const & obj ) {
244 if ( !m_list ) {
245 Resize( m_granularity );
246 }
247
248 if ( m_num == m_size ) {
249 Resize( m_size + m_granularity );
250 }
251
252 m_list[ m_num ] = obj;
253 m_num++;
254
255 return m_num - 1;
256 }
257
258 /*
259 ================
260 idList<type>::AddUnique
261 ================
262 */
263 template< class type >
AddUnique(type const & obj)264 inline int idList<type>::AddUnique( type const & obj ) {
265 int index;
266
267 if ( !Find( obj, &index ) ) {
268 index = Append( obj );
269 }
270
271 return index;
272 }
273
274 /*
275 ================
276 idList<type>::Find
277 ================
278 */
279 template< class type >
Find(type const & obj,int * index)280 inline type *idList<type>::Find( type const & obj, int *index ) {
281 int i;
282
283 for ( i = 0; i < m_num; i++ ) {
284 if ( m_list[ i ] == obj ) {
285 if ( index ) {
286 *index = i;
287 }
288 return &m_list[ i ];
289 }
290 }
291
292 return NULL;
293 }
294
295 /*
296 ================
297 idList<type>::RemoveIndex
298 ================
299 */
300 template< class type >
RemoveIndex(int index)301 inline bool idList<type>::RemoveIndex( int index ) {
302 int i;
303
304 if ( !m_list || !m_num ) {
305 return false;
306 }
307
308 assert( index >= 0 );
309 assert( index < m_num );
310
311 if ( ( index < 0 ) || ( index >= m_num ) ) {
312 return false;
313 }
314
315 m_num--;
316 for ( i = index; i < m_num; i++ ) {
317 m_list[ i ] = m_list[ i + 1 ];
318 }
319
320 return true;
321 }
322
323 /*
324 ================
325 idList<type>::Remove
326 ================
327 */
328 template< class type >
Remove(type const & obj)329 inline bool idList<type>::Remove( type const & obj ) {
330 int index;
331
332 if ( Find( obj, &index ) ) {
333 return RemoveIndex( index );
334 }
335
336 return false;
337 }
338
339 /*
340 ================
341 idList<type>::Sort
342 ================
343 */
344 template< class type >
Sort(cmp_t * compare)345 inline void idList<type>::Sort( cmp_t *compare ) {
346 if ( !m_list ) {
347 return;
348 }
349
350 qsort( ( void * )m_list, ( size_t )m_num, sizeof( type ), compare );
351 }
352
353 #endif /* !__UTIL_LIST_H__ */
354