Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

util_list.h

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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 idList<type>::idList( int )
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 idList<type>::~idList<type>
00074 ================
00075 */
00076 template< class type >
00077 inline idList<type>::~idList() {
00078     Clear();
00079 }
00080 
00081 /*
00082 ================
00083 idList<type>::Clear
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 idList<type>::Num
00100 ================
00101 */
00102 template< class type >
00103 inline int idList<type>::Num( void ) {
00104     return m_num;
00105 }
00106 
00107 /*
00108 ================
00109 idList<type>::SetNum
00110 ================
00111 */
00112 template< class type >
00113 inline void idList<type>::SetNum( int num ) {
00114     assert( num >= 0 );
00115     if ( num > m_size ) {
00116         // resize it up to the closest level of granularity
00117         Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity );
00118     }
00119     m_num = num;
00120 }
00121 
00122 /*
00123 ================
00124 idList<type>::SetGranularity
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         // resize it to the closest level of granularity
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 idList<type>::Condense
00146 
00147 Resizes the array to exactly the number of elements it contains
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 idList<type>::Size
00164 ================
00165 */
00166 template< class type >
00167 inline int idList<type>::Size( void ) {
00168     return m_size;
00169 }
00170 
00171 /*
00172 ================
00173 idList<type>::Resize
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 idList<type>::operator[] const
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 idList<type>::operator[]
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 idList<type>::Append
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 idList<type>::AddUnique
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 idList<type>::Find
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 idList<type>::RemoveIndex
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 idList<type>::Remove
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 idList<type>::Sort
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 /* !__UTIL_LIST_H__ */

Generated on Thu Aug 25 12:38:00 2005 for Quake III Arena by  doxygen 1.3.9.1