123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- /*
- ===========================================================================
- Copyright (C) 1999-2005 Id Software, Inc.
- This file is part of Quake III Arena source code.
- Quake III Arena source code is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the License,
- or (at your option) any later version.
- Quake III Arena source code is distributed in the hope that it will be
- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Foobar; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- ===========================================================================
- */
- #ifndef __UTIL_LIST_H__
- #define __UTIL_LIST_H__
- #include <stdlib.h>
- #include <assert.h>
- template< class type >
- class idList {
- private:
- int m_num;
- int m_size;
- int m_granularity;
- type *m_list;
- public:
- idList( int granularity = 16 );
- ~idList<type>();
- void Clear( void );
- int Num( void );
- void SetNum( int num );
- void SetGranularity( int granularity );
- void Condense( void );
- int Size( void );
- void Resize( int size );
- type operator[]( int index ) const;
- type &operator[]( int index );
- int Append( type const & obj );
- int AddUnique( type const & obj );
- type *Find( type const & obj, int *index = NULL );
- bool RemoveIndex( int index );
- bool Remove( type const & obj );
- typedef int cmp_t(const void *, const void *);
- void Sort( cmp_t *compare );
- };
- /*
- ================
- idList<type>::idList( int )
- ================
- */
- template< class type >
- inline idList<type>::idList( int granularity ) {
- assert( granularity > 0 );
- m_list = NULL;
- m_granularity = granularity;
- Clear();
- }
- /*
- ================
- idList<type>::~idList<type>
- ================
- */
- template< class type >
- inline idList<type>::~idList() {
- Clear();
- }
- /*
- ================
- idList<type>::Clear
- ================
- */
- template< class type >
- inline void idList<type>::Clear( void ) {
- if ( m_list ) {
- delete[] m_list;
- }
- m_list = NULL;
- m_num = 0;
- m_size = 0;
- }
- /*
- ================
- idList<type>::Num
- ================
- */
- template< class type >
- inline int idList<type>::Num( void ) {
- return m_num;
- }
- /*
- ================
- idList<type>::SetNum
- ================
- */
- template< class type >
- inline void idList<type>::SetNum( int num ) {
- assert( num >= 0 );
- if ( num > m_size ) {
- // resize it up to the closest level of granularity
- Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity );
- }
- m_num = num;
- }
- /*
- ================
- idList<type>::SetGranularity
- ================
- */
- template< class type >
- inline void idList<type>::SetGranularity( int granularity ) {
- int newsize;
- assert( granularity > 0 );
- m_granularity = granularity;
- if ( m_list ) {
- // resize it to the closest level of granularity
- newsize = ( ( m_num + m_granularity - 1 ) / m_granularity ) * m_granularity;
- if ( newsize != m_size ) {
- Resize( newsize );
- }
- }
- }
- /*
- ================
- idList<type>::Condense
- Resizes the array to exactly the number of elements it contains
- ================
- */
- template< class type >
- inline void idList<type>::Condense( void ) {
- if ( m_list ) {
- if ( m_num ) {
- Resize( m_num );
- } else {
- Clear();
- }
- }
- }
- /*
- ================
- idList<type>::Size
- ================
- */
- template< class type >
- inline int idList<type>::Size( void ) {
- return m_size;
- }
- /*
- ================
- idList<type>::Resize
- ================
- */
- template< class type >
- inline void idList<type>::Resize( int size ) {
- type *temp;
- int i;
- assert( size > 0 );
- if ( size <= 0 ) {
- Clear();
- return;
- }
- temp = m_list;
- m_size = size;
- if ( m_size < m_num ) {
- m_num = m_size;
- }
- m_list = new type[ m_size ];
- for( i = 0; i < m_num; i++ ) {
- m_list[ i ] = temp[ i ];
- }
- if ( temp ) {
- delete[] temp;
- }
- }
- /*
- ================
- idList<type>::operator[] const
- ================
- */
- template< class type >
- inline type idList<type>::operator[]( int index ) const {
- assert( index >= 0 );
- assert( index < m_num );
- return m_list[ index ];
- }
- /*
- ================
- idList<type>::operator[]
- ================
- */
- template< class type >
- inline type &idList<type>::operator[]( int index ) {
- assert( index >= 0 );
- assert( index < m_num );
- return m_list[ index ];
- }
- /*
- ================
- idList<type>::Append
- ================
- */
- template< class type >
- inline int idList<type>::Append( type const & obj ) {
- if ( !m_list ) {
- Resize( m_granularity );
- }
- if ( m_num == m_size ) {
- Resize( m_size + m_granularity );
- }
- m_list[ m_num ] = obj;
- m_num++;
- return m_num - 1;
- }
- /*
- ================
- idList<type>::AddUnique
- ================
- */
- template< class type >
- inline int idList<type>::AddUnique( type const & obj ) {
- int index;
- if ( !Find( obj, &index ) ) {
- index = Append( obj );
- }
- return index;
- }
- /*
- ================
- idList<type>::Find
- ================
- */
- template< class type >
- inline type *idList<type>::Find( type const & obj, int *index ) {
- int i;
- for( i = 0; i < m_num; i++ ) {
- if ( m_list[ i ] == obj ) {
- if ( index ) {
- *index = i;
- }
- return &m_list[ i ];
- }
- }
- return NULL;
- }
- /*
- ================
- idList<type>::RemoveIndex
- ================
- */
- template< class type >
- inline bool idList<type>::RemoveIndex( int index ) {
- int i;
- if ( !m_list || !m_num ) {
- return false;
- }
- assert( index >= 0 );
- assert( index < m_num );
- if ( ( index < 0 ) || ( index >= m_num ) ) {
- return false;
- }
- m_num--;
- for( i = index; i < m_num; i++ ) {
- m_list[ i ] = m_list[ i + 1 ];
- }
- return true;
- }
- /*
- ================
- idList<type>::Remove
- ================
- */
- template< class type >
- inline bool idList<type>::Remove( type const & obj ) {
- int index;
- if ( Find( obj, &index ) ) {
- return RemoveIndex( index );
- }
-
- return false;
- }
- /*
- ================
- idList<type>::Sort
- ================
- */
- template< class type >
- inline void idList<type>::Sort( cmp_t *compare ) {
- if ( !m_list ) {
- return;
- }
- qsort( ( void * )m_list, ( size_t )m_num, sizeof( type ), compare );
- }
- #endif /* !__UTIL_LIST_H__ */
|