Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

util_list.h (6304B)


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