00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __UTIL_LIST_H__
00023 #define __UTIL_LIST_H__
00024
00025 #include <stdlib.h>
00026 #include <assert.h>
00027
00028 template< class type >
00029 class idList {
00030 private:
00031 int m_num;
00032 int m_size;
00033 int m_granularity;
00034 type *m_list;
00035
00036 public:
00037 idList( int granularity = 16 );
00038 ~idList<type>();
00039 void Clear( void );
00040 int Num( void );
00041 void SetNum( int num );
00042 void SetGranularity( int granularity );
00043 void Condense( void );
00044 int Size( void );
00045 void Resize( int size );
00046 type operator[]( int index ) const;
00047 type &operator[]( int index );
00048 int Append( type const & obj );
00049 int AddUnique( type const & obj );
00050 type *Find( type const & obj, int *index = NULL );
00051 bool RemoveIndex( int index );
00052 bool Remove( type const & obj );
00053 typedef int cmp_t(const void *, const void *);
00054 void Sort( cmp_t *compare );
00055 };
00056
00057
00058
00059
00060
00061
00062 template< class type >
00063 inline idList<type>::idList( int granularity ) {
00064 assert( granularity > 0 );
00065
00066 m_list = NULL;
00067 m_granularity = granularity;
00068 Clear();
00069 }
00070
00071
00072
00073
00074
00075
00076 template< class type >
00077 inline idList<type>::~idList() {
00078 Clear();
00079 }
00080
00081
00082
00083
00084
00085
00086 template< class type >
00087 inline void idList<type>::Clear( void ) {
00088 if ( m_list ) {
00089 delete[] m_list;
00090 }
00091
00092 m_list = NULL;
00093 m_num = 0;
00094 m_size = 0;
00095 }
00096
00097
00098
00099
00100
00101
00102 template< class type >
00103 inline int idList<type>::Num( void ) {
00104 return m_num;
00105 }
00106
00107
00108
00109
00110
00111
00112 template< class type >
00113 inline void idList<type>::SetNum( int num ) {
00114 assert( num >= 0 );
00115 if ( num > m_size ) {
00116
00117 Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity );
00118 }
00119 m_num = num;
00120 }
00121
00122
00123
00124
00125
00126
00127 template< class type >
00128 inline void idList<type>::SetGranularity( int granularity ) {
00129 int newsize;
00130
00131 assert( granularity > 0 );
00132 m_granularity = granularity;
00133
00134 if ( m_list ) {
00135
00136 newsize = ( ( m_num + m_granularity - 1 ) / m_granularity ) * m_granularity;
00137 if ( newsize != m_size ) {
00138 Resize( newsize );
00139 }
00140 }
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150 template< class type >
00151 inline void idList<type>::Condense( void ) {
00152 if ( m_list ) {
00153 if ( m_num ) {
00154 Resize( m_num );
00155 } else {
00156 Clear();
00157 }
00158 }
00159 }
00160
00161
00162
00163
00164
00165
00166 template< class type >
00167 inline int idList<type>::Size( void ) {
00168 return m_size;
00169 }
00170
00171
00172
00173
00174
00175
00176 template< class type >
00177 inline void idList<type>::Resize( int size ) {
00178 type *temp;
00179 int i;
00180
00181 assert( size > 0 );
00182
00183 if ( size <= 0 ) {
00184 Clear();
00185 return;
00186 }
00187
00188 temp = m_list;
00189 m_size = size;
00190 if ( m_size < m_num ) {
00191 m_num = m_size;
00192 }
00193
00194 m_list = new type[ m_size ];
00195 for( i = 0; i < m_num; i++ ) {
00196 m_list[ i ] = temp[ i ];
00197 }
00198
00199 if ( temp ) {
00200 delete[] temp;
00201 }
00202 }
00203
00204
00205
00206
00207
00208
00209 template< class type >
00210 inline type idList<type>::operator[]( int index ) const {
00211 assert( index >= 0 );
00212 assert( index < m_num );
00213
00214 return m_list[ index ];
00215 }
00216
00217
00218
00219
00220
00221
00222 template< class type >
00223 inline type &idList<type>::operator[]( int index ) {
00224 assert( index >= 0 );
00225 assert( index < m_num );
00226
00227 return m_list[ index ];
00228 }
00229
00230
00231
00232
00233
00234
00235 template< class type >
00236 inline int idList<type>::Append( type const & obj ) {
00237 if ( !m_list ) {
00238 Resize( m_granularity );
00239 }
00240
00241 if ( m_num == m_size ) {
00242 Resize( m_size + m_granularity );
00243 }
00244
00245 m_list[ m_num ] = obj;
00246 m_num++;
00247
00248 return m_num - 1;
00249 }
00250
00251
00252
00253
00254
00255
00256 template< class type >
00257 inline int idList<type>::AddUnique( type const & obj ) {
00258 int index;
00259
00260 if ( !Find( obj, &index ) ) {
00261 index = Append( obj );
00262 }
00263
00264 return index;
00265 }
00266
00267
00268
00269
00270
00271
00272 template< class type >
00273 inline type *idList<type>::Find( type const & obj, int *index ) {
00274 int i;
00275
00276 for( i = 0; i < m_num; i++ ) {
00277 if ( m_list[ i ] == obj ) {
00278 if ( index ) {
00279 *index = i;
00280 }
00281 return &m_list[ i ];
00282 }
00283 }
00284
00285 return NULL;
00286 }
00287
00288
00289
00290
00291
00292
00293 template< class type >
00294 inline bool idList<type>::RemoveIndex( int index ) {
00295 int i;
00296
00297 if ( !m_list || !m_num ) {
00298 return false;
00299 }
00300
00301 assert( index >= 0 );
00302 assert( index < m_num );
00303
00304 if ( ( index < 0 ) || ( index >= m_num ) ) {
00305 return false;
00306 }
00307
00308 m_num--;
00309 for( i = index; i < m_num; i++ ) {
00310 m_list[ i ] = m_list[ i + 1 ];
00311 }
00312
00313 return true;
00314 }
00315
00316
00317
00318
00319
00320
00321 template< class type >
00322 inline bool idList<type>::Remove( type const & obj ) {
00323 int index;
00324
00325 if ( Find( obj, &index ) ) {
00326 return RemoveIndex( index );
00327 }
00328
00329 return false;
00330 }
00331
00332
00333
00334
00335
00336
00337 template< class type >
00338 inline void idList<type>::Sort( cmp_t *compare ) {
00339 if ( !m_list ) {
00340 return;
00341 }
00342
00343 qsort( ( void * )m_list, ( size_t )m_num, sizeof( type ), compare );
00344 }
00345
00346 #endif