List.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 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 Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. 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.
  18. ===========================================================================
  19. */
  20. #ifndef __LIST_H__
  21. #define __LIST_H__
  22. /*
  23. ===============================================================================
  24. List template
  25. Does not allocate memory until the first item is added.
  26. ===============================================================================
  27. */
  28. /*
  29. ================
  30. idListSortCompare<type>
  31. ================
  32. */
  33. #ifdef __INTEL_COMPILER
  34. // the intel compiler doesn't do the right thing here
  35. template< class type >
  36. ID_INLINE int idListSortCompare( const type *a, const type *b ) {
  37. assert( 0 );
  38. return 0;
  39. }
  40. #else
  41. template< class type >
  42. ID_INLINE int idListSortCompare( const type *a, const type *b ) {
  43. return *a - *b;
  44. }
  45. #endif
  46. /*
  47. ================
  48. idListNewElement<type>
  49. ================
  50. */
  51. template< class type >
  52. ID_INLINE type *idListNewElement( void ) {
  53. return new type;
  54. }
  55. /*
  56. ================
  57. idSwap<type>
  58. ================
  59. */
  60. template< class type >
  61. ID_INLINE void idSwap( type &a, type &b ) {
  62. type c = a;
  63. a = b;
  64. b = c;
  65. }
  66. template< class type >
  67. class idList {
  68. public:
  69. typedef int cmp_t( const type *, const type * );
  70. typedef type new_t( void );
  71. idList( int newgranularity = 16 );
  72. idList( const idList<type> &other );
  73. ~idList<type>( void );
  74. void Clear( void ); // clear the list
  75. int Num( void ) const; // returns number of elements in list
  76. int NumAllocated( void ) const; // returns number of elements allocated for
  77. void SetGranularity( int newgranularity ); // set new granularity
  78. int GetGranularity( void ) const; // get the current granularity
  79. size_t Allocated( void ) const; // returns total size of allocated memory
  80. size_t Size( void ) const; // returns total size of allocated memory including size of list type
  81. size_t MemoryUsed( void ) const; // returns size of the used elements in the list
  82. idList<type> & operator=( const idList<type> &other );
  83. const type & operator[]( int index ) const;
  84. type & operator[]( int index );
  85. void Condense( void ); // resizes list to exactly the number of elements it contains
  86. void Resize( int newsize ); // resizes list to the given number of elements
  87. void Resize( int newsize, int newgranularity ); // resizes list and sets new granularity
  88. void SetNum( int newnum, bool resize = true ); // set number of elements in list and resize to exactly this number if necessary
  89. void AssureSize( int newSize); // assure list has given number of elements, but leave them uninitialized
  90. void AssureSize( int newSize, const type &initValue ); // assure list has given number of elements and initialize any new elements
  91. void AssureSizeAlloc( int newSize, new_t *allocator ); // assure the pointer list has the given number of elements and allocate any new elements
  92. type * Ptr( void ); // returns a pointer to the list
  93. const type * Ptr( void ) const; // returns a pointer to the list
  94. type & Alloc( void ); // returns reference to a new data element at the end of the list
  95. int Append( const type & obj ); // append element
  96. int Append( const idList<type> &other ); // append list
  97. int AddUnique( const type & obj ); // add unique element
  98. int Insert( const type & obj, int index = 0 ); // insert the element at the given index
  99. int FindIndex( const type & obj ) const; // find the index for the given element
  100. type * Find( type const & obj ) const; // find pointer to the given element
  101. int FindNull( void ) const; // find the index for the first NULL pointer in the list
  102. int IndexOf( const type *obj ) const; // returns the index for the pointer to an element in the list
  103. bool RemoveIndex( int index ); // remove the element at the given index
  104. bool Remove( const type & obj ); // remove the element
  105. void Sort( cmp_t *compare = ( cmp_t * )&idListSortCompare<type> );
  106. void SortSubSection( int startIndex, int endIndex, cmp_t *compare = ( cmp_t * )&idListSortCompare<type> );
  107. void Swap( idList<type> &other ); // swap the contents of the lists
  108. void DeleteContents( bool clear ); // delete the contents of the list
  109. private:
  110. int num;
  111. int size;
  112. int granularity;
  113. type * list;
  114. };
  115. /*
  116. ================
  117. idList<type>::idList( int )
  118. ================
  119. */
  120. template< class type >
  121. ID_INLINE idList<type>::idList( int newgranularity ) {
  122. assert( newgranularity > 0 );
  123. list = NULL;
  124. granularity = newgranularity;
  125. Clear();
  126. }
  127. /*
  128. ================
  129. idList<type>::idList( const idList<type> &other )
  130. ================
  131. */
  132. template< class type >
  133. ID_INLINE idList<type>::idList( const idList<type> &other ) {
  134. list = NULL;
  135. *this = other;
  136. }
  137. /*
  138. ================
  139. idList<type>::~idList<type>
  140. ================
  141. */
  142. template< class type >
  143. ID_INLINE idList<type>::~idList( void ) {
  144. Clear();
  145. }
  146. /*
  147. ================
  148. idList<type>::Clear
  149. Frees up the memory allocated by the list. Assumes that type automatically handles freeing up memory.
  150. ================
  151. */
  152. template< class type >
  153. ID_INLINE void idList<type>::Clear( void ) {
  154. if ( list ) {
  155. delete[] list;
  156. }
  157. list = NULL;
  158. num = 0;
  159. size = 0;
  160. }
  161. /*
  162. ================
  163. idList<type>::DeleteContents
  164. Calls the destructor of all elements in the list. Conditionally frees up memory used by the list.
  165. Note that this only works on lists containing pointers to objects and will cause a compiler error
  166. if called with non-pointers. Since the list was not responsible for allocating the object, it has
  167. no information on whether the object still exists or not, so care must be taken to ensure that
  168. the pointers are still valid when this function is called. Function will set all pointers in the
  169. list to NULL.
  170. ================
  171. */
  172. template< class type >
  173. ID_INLINE void idList<type>::DeleteContents( bool clear ) {
  174. int i;
  175. for( i = 0; i < num; i++ ) {
  176. delete list[ i ];
  177. list[ i ] = NULL;
  178. }
  179. if ( clear ) {
  180. Clear();
  181. } else {
  182. memset( list, 0, size * sizeof( type ) );
  183. }
  184. }
  185. /*
  186. ================
  187. idList<type>::Allocated
  188. return total memory allocated for the list in bytes, but doesn't take into account additional memory allocated by type
  189. ================
  190. */
  191. template< class type >
  192. ID_INLINE size_t idList<type>::Allocated( void ) const {
  193. return size * sizeof( type );
  194. }
  195. /*
  196. ================
  197. idList<type>::Size
  198. return total size of list in bytes, but doesn't take into account additional memory allocated by type
  199. ================
  200. */
  201. template< class type >
  202. ID_INLINE size_t idList<type>::Size( void ) const {
  203. return sizeof( idList<type> ) + Allocated();
  204. }
  205. /*
  206. ================
  207. idList<type>::MemoryUsed
  208. ================
  209. */
  210. template< class type >
  211. ID_INLINE size_t idList<type>::MemoryUsed( void ) const {
  212. return num * sizeof( *list );
  213. }
  214. /*
  215. ================
  216. idList<type>::Num
  217. Returns the number of elements currently contained in the list.
  218. Note that this is NOT an indication of the memory allocated.
  219. ================
  220. */
  221. template< class type >
  222. ID_INLINE int idList<type>::Num( void ) const {
  223. return num;
  224. }
  225. /*
  226. ================
  227. idList<type>::NumAllocated
  228. Returns the number of elements currently allocated for.
  229. ================
  230. */
  231. template< class type >
  232. ID_INLINE int idList<type>::NumAllocated( void ) const {
  233. return size;
  234. }
  235. /*
  236. ================
  237. idList<type>::SetNum
  238. Resize to the exact size specified irregardless of granularity
  239. ================
  240. */
  241. template< class type >
  242. ID_INLINE void idList<type>::SetNum( int newnum, bool resize ) {
  243. assert( newnum >= 0 );
  244. if ( resize || newnum > size ) {
  245. Resize( newnum );
  246. }
  247. num = newnum;
  248. }
  249. /*
  250. ================
  251. idList<type>::SetGranularity
  252. Sets the base size of the array and resizes the array to match.
  253. ================
  254. */
  255. template< class type >
  256. ID_INLINE void idList<type>::SetGranularity( int newgranularity ) {
  257. int newsize;
  258. assert( newgranularity > 0 );
  259. granularity = newgranularity;
  260. if ( list ) {
  261. // resize it to the closest level of granularity
  262. newsize = num + granularity - 1;
  263. newsize -= newsize % granularity;
  264. if ( newsize != size ) {
  265. Resize( newsize );
  266. }
  267. }
  268. }
  269. /*
  270. ================
  271. idList<type>::GetGranularity
  272. Get the current granularity.
  273. ================
  274. */
  275. template< class type >
  276. ID_INLINE int idList<type>::GetGranularity( void ) const {
  277. return granularity;
  278. }
  279. /*
  280. ================
  281. idList<type>::Condense
  282. Resizes the array to exactly the number of elements it contains or frees up memory if empty.
  283. ================
  284. */
  285. template< class type >
  286. ID_INLINE void idList<type>::Condense( void ) {
  287. if ( list ) {
  288. if ( num ) {
  289. Resize( num );
  290. } else {
  291. Clear();
  292. }
  293. }
  294. }
  295. /*
  296. ================
  297. idList<type>::Resize
  298. Allocates memory for the amount of elements requested while keeping the contents intact.
  299. Contents are copied using their = operator so that data is correnctly instantiated.
  300. ================
  301. */
  302. template< class type >
  303. ID_INLINE void idList<type>::Resize( int newsize ) {
  304. type *temp;
  305. int i;
  306. assert( newsize >= 0 );
  307. // free up the list if no data is being reserved
  308. if ( newsize <= 0 ) {
  309. Clear();
  310. return;
  311. }
  312. if ( newsize == size ) {
  313. // not changing the size, so just exit
  314. return;
  315. }
  316. temp = list;
  317. size = newsize;
  318. if ( size < num ) {
  319. num = size;
  320. }
  321. // copy the old list into our new one
  322. list = new type[ size ];
  323. for( i = 0; i < num; i++ ) {
  324. list[ i ] = temp[ i ];
  325. }
  326. // delete the old list if it exists
  327. if ( temp ) {
  328. delete[] temp;
  329. }
  330. }
  331. /*
  332. ================
  333. idList<type>::Resize
  334. Allocates memory for the amount of elements requested while keeping the contents intact.
  335. Contents are copied using their = operator so that data is correnctly instantiated.
  336. ================
  337. */
  338. template< class type >
  339. ID_INLINE void idList<type>::Resize( int newsize, int newgranularity ) {
  340. type *temp;
  341. int i;
  342. assert( newsize >= 0 );
  343. assert( newgranularity > 0 );
  344. granularity = newgranularity;
  345. // free up the list if no data is being reserved
  346. if ( newsize <= 0 ) {
  347. Clear();
  348. return;
  349. }
  350. temp = list;
  351. size = newsize;
  352. if ( size < num ) {
  353. num = size;
  354. }
  355. // copy the old list into our new one
  356. list = new type[ size ];
  357. for( i = 0; i < num; i++ ) {
  358. list[ i ] = temp[ i ];
  359. }
  360. // delete the old list if it exists
  361. if ( temp ) {
  362. delete[] temp;
  363. }
  364. }
  365. /*
  366. ================
  367. idList<type>::AssureSize
  368. Makes sure the list has at least the given number of elements.
  369. ================
  370. */
  371. template< class type >
  372. ID_INLINE void idList<type>::AssureSize( int newSize ) {
  373. int newNum = newSize;
  374. if ( newSize > size ) {
  375. if ( granularity == 0 ) { // this is a hack to fix our memset classes
  376. granularity = 16;
  377. }
  378. newSize += granularity - 1;
  379. newSize -= newSize % granularity;
  380. Resize( newSize );
  381. }
  382. num = newNum;
  383. }
  384. /*
  385. ================
  386. idList<type>::AssureSize
  387. Makes sure the list has at least the given number of elements and initialize any elements not yet initialized.
  388. ================
  389. */
  390. template< class type >
  391. ID_INLINE void idList<type>::AssureSize( int newSize, const type &initValue ) {
  392. int newNum = newSize;
  393. if ( newSize > size ) {
  394. if ( granularity == 0 ) { // this is a hack to fix our memset classes
  395. granularity = 16;
  396. }
  397. newSize += granularity - 1;
  398. newSize -= newSize % granularity;
  399. num = size;
  400. Resize( newSize );
  401. for ( int i = num; i < newSize; i++ ) {
  402. list[i] = initValue;
  403. }
  404. }
  405. num = newNum;
  406. }
  407. /*
  408. ================
  409. idList<type>::AssureSizeAlloc
  410. Makes sure the list has at least the given number of elements and allocates any elements using the allocator.
  411. NOTE: This function can only be called on lists containing pointers. Calling it
  412. on non-pointer lists will cause a compiler error.
  413. ================
  414. */
  415. template< class type >
  416. ID_INLINE void idList<type>::AssureSizeAlloc( int newSize, new_t *allocator ) {
  417. int newNum = newSize;
  418. if ( newSize > size ) {
  419. if ( granularity == 0 ) { // this is a hack to fix our memset classes
  420. granularity = 16;
  421. }
  422. newSize += granularity - 1;
  423. newSize -= newSize % granularity;
  424. num = size;
  425. Resize( newSize );
  426. for ( int i = num; i < newSize; i++ ) {
  427. list[i] = (*allocator)();
  428. }
  429. }
  430. num = newNum;
  431. }
  432. /*
  433. ================
  434. idList<type>::operator=
  435. Copies the contents and size attributes of another list.
  436. ================
  437. */
  438. template< class type >
  439. ID_INLINE idList<type> &idList<type>::operator=( const idList<type> &other ) {
  440. int i;
  441. Clear();
  442. num = other.num;
  443. size = other.size;
  444. granularity = other.granularity;
  445. if ( size ) {
  446. list = new type[ size ];
  447. for( i = 0; i < num; i++ ) {
  448. list[ i ] = other.list[ i ];
  449. }
  450. }
  451. return *this;
  452. }
  453. /*
  454. ================
  455. idList<type>::operator[] const
  456. Access operator. Index must be within range or an assert will be issued in debug builds.
  457. Release builds do no range checking.
  458. ================
  459. */
  460. template< class type >
  461. ID_INLINE const type &idList<type>::operator[]( int index ) const {
  462. assert( index >= 0 );
  463. assert( index < num );
  464. return list[ index ];
  465. }
  466. /*
  467. ================
  468. idList<type>::operator[]
  469. Access operator. Index must be within range or an assert will be issued in debug builds.
  470. Release builds do no range checking.
  471. ================
  472. */
  473. template< class type >
  474. ID_INLINE type &idList<type>::operator[]( int index ) {
  475. assert( index >= 0 );
  476. assert( index < num );
  477. return list[ index ];
  478. }
  479. /*
  480. ================
  481. idList<type>::Ptr
  482. Returns a pointer to the begining of the array. Useful for iterating through the list in loops.
  483. Note: may return NULL if the list is empty.
  484. FIXME: Create an iterator template for this kind of thing.
  485. ================
  486. */
  487. template< class type >
  488. ID_INLINE type *idList<type>::Ptr( void ) {
  489. return list;
  490. }
  491. /*
  492. ================
  493. idList<type>::Ptr
  494. Returns a pointer to the begining of the array. Useful for iterating through the list in loops.
  495. Note: may return NULL if the list is empty.
  496. FIXME: Create an iterator template for this kind of thing.
  497. ================
  498. */
  499. template< class type >
  500. const ID_INLINE type *idList<type>::Ptr( void ) const {
  501. return list;
  502. }
  503. /*
  504. ================
  505. idList<type>::Alloc
  506. Returns a reference to a new data element at the end of the list.
  507. ================
  508. */
  509. template< class type >
  510. ID_INLINE type &idList<type>::Alloc( void ) {
  511. if ( !list ) {
  512. Resize( granularity );
  513. }
  514. if ( num == size ) {
  515. Resize( size + granularity );
  516. }
  517. return list[ num++ ];
  518. }
  519. /*
  520. ================
  521. idList<type>::Append
  522. Increases the size of the list by one element and copies the supplied data into it.
  523. Returns the index of the new element.
  524. ================
  525. */
  526. template< class type >
  527. ID_INLINE int idList<type>::Append( type const & obj ) {
  528. if ( !list ) {
  529. Resize( granularity );
  530. }
  531. if ( num == size ) {
  532. int newsize;
  533. if ( granularity == 0 ) { // this is a hack to fix our memset classes
  534. granularity = 16;
  535. }
  536. newsize = size + granularity;
  537. Resize( newsize - newsize % granularity );
  538. }
  539. list[ num ] = obj;
  540. num++;
  541. return num - 1;
  542. }
  543. /*
  544. ================
  545. idList<type>::Insert
  546. Increases the size of the list by at leat one element if necessary
  547. and inserts the supplied data into it.
  548. Returns the index of the new element.
  549. ================
  550. */
  551. template< class type >
  552. ID_INLINE int idList<type>::Insert( type const & obj, int index ) {
  553. if ( !list ) {
  554. Resize( granularity );
  555. }
  556. if ( num == size ) {
  557. int newsize;
  558. if ( granularity == 0 ) { // this is a hack to fix our memset classes
  559. granularity = 16;
  560. }
  561. newsize = size + granularity;
  562. Resize( newsize - newsize % granularity );
  563. }
  564. if ( index < 0 ) {
  565. index = 0;
  566. }
  567. else if ( index > num ) {
  568. index = num;
  569. }
  570. for ( int i = num; i > index; --i ) {
  571. list[i] = list[i-1];
  572. }
  573. num++;
  574. list[index] = obj;
  575. return index;
  576. }
  577. /*
  578. ================
  579. idList<type>::Append
  580. adds the other list to this one
  581. Returns the size of the new combined list
  582. ================
  583. */
  584. template< class type >
  585. ID_INLINE int idList<type>::Append( const idList<type> &other ) {
  586. if ( !list ) {
  587. if ( granularity == 0 ) { // this is a hack to fix our memset classes
  588. granularity = 16;
  589. }
  590. Resize( granularity );
  591. }
  592. int n = other.Num();
  593. for (int i = 0; i < n; i++) {
  594. Append(other[i]);
  595. }
  596. return Num();
  597. }
  598. /*
  599. ================
  600. idList<type>::AddUnique
  601. Adds the data to the list if it doesn't already exist. Returns the index of the data in the list.
  602. ================
  603. */
  604. template< class type >
  605. ID_INLINE int idList<type>::AddUnique( type const & obj ) {
  606. int index;
  607. index = FindIndex( obj );
  608. if ( index < 0 ) {
  609. index = Append( obj );
  610. }
  611. return index;
  612. }
  613. /*
  614. ================
  615. idList<type>::FindIndex
  616. Searches for the specified data in the list and returns it's index. Returns -1 if the data is not found.
  617. ================
  618. */
  619. template< class type >
  620. ID_INLINE int idList<type>::FindIndex( type const & obj ) const {
  621. int i;
  622. for( i = 0; i < num; i++ ) {
  623. if ( list[ i ] == obj ) {
  624. return i;
  625. }
  626. }
  627. // Not found
  628. return -1;
  629. }
  630. /*
  631. ================
  632. idList<type>::Find
  633. Searches for the specified data in the list and returns it's address. Returns NULL if the data is not found.
  634. ================
  635. */
  636. template< class type >
  637. ID_INLINE type *idList<type>::Find( type const & obj ) const {
  638. int i;
  639. i = FindIndex( obj );
  640. if ( i >= 0 ) {
  641. return &list[ i ];
  642. }
  643. return NULL;
  644. }
  645. /*
  646. ================
  647. idList<type>::FindNull
  648. Searches for a NULL pointer in the list. Returns -1 if NULL is not found.
  649. NOTE: This function can only be called on lists containing pointers. Calling it
  650. on non-pointer lists will cause a compiler error.
  651. ================
  652. */
  653. template< class type >
  654. ID_INLINE int idList<type>::FindNull( void ) const {
  655. int i;
  656. for( i = 0; i < num; i++ ) {
  657. if ( list[ i ] == NULL ) {
  658. return i;
  659. }
  660. }
  661. // Not found
  662. return -1;
  663. }
  664. /*
  665. ================
  666. idList<type>::IndexOf
  667. Takes a pointer to an element in the list and returns the index of the element.
  668. This is NOT a guarantee that the object is really in the list.
  669. Function will assert in debug builds if pointer is outside the bounds of the list,
  670. but remains silent in release builds.
  671. ================
  672. */
  673. template< class type >
  674. ID_INLINE int idList<type>::IndexOf( type const *objptr ) const {
  675. int index;
  676. index = objptr - list;
  677. assert( index >= 0 );
  678. assert( index < num );
  679. return index;
  680. }
  681. /*
  682. ================
  683. idList<type>::RemoveIndex
  684. Removes the element at the specified index and moves all data following the element down to fill in the gap.
  685. The number of elements in the list is reduced by one. Returns false if the index is outside the bounds of the list.
  686. Note that the element is not destroyed, so any memory used by it may not be freed until the destruction of the list.
  687. ================
  688. */
  689. template< class type >
  690. ID_INLINE bool idList<type>::RemoveIndex( int index ) {
  691. int i;
  692. assert( list != NULL );
  693. assert( index >= 0 );
  694. assert( index < num );
  695. if ( ( index < 0 ) || ( index >= num ) ) {
  696. return false;
  697. }
  698. num--;
  699. for( i = index; i < num; i++ ) {
  700. list[ i ] = list[ i + 1 ];
  701. }
  702. return true;
  703. }
  704. /*
  705. ================
  706. idList<type>::Remove
  707. Removes the element if it is found within the list and moves all data following the element down to fill in the gap.
  708. The number of elements in the list is reduced by one. Returns false if the data is not found in the list. Note that
  709. the element is not destroyed, so any memory used by it may not be freed until the destruction of the list.
  710. ================
  711. */
  712. template< class type >
  713. ID_INLINE bool idList<type>::Remove( type const & obj ) {
  714. int index;
  715. index = FindIndex( obj );
  716. if ( index >= 0 ) {
  717. return RemoveIndex( index );
  718. }
  719. return false;
  720. }
  721. /*
  722. ================
  723. idList<type>::Sort
  724. Performs a qsort on the list using the supplied comparison function. Note that the data is merely moved around the
  725. list, so any pointers to data within the list may no longer be valid.
  726. ================
  727. */
  728. template< class type >
  729. ID_INLINE void idList<type>::Sort( cmp_t *compare ) {
  730. if ( !list ) {
  731. return;
  732. }
  733. typedef int cmp_c(const void *, const void *);
  734. cmp_c *vCompare = (cmp_c *)compare;
  735. qsort( ( void * )list, ( size_t )num, sizeof( type ), vCompare );
  736. }
  737. /*
  738. ================
  739. idList<type>::SortSubSection
  740. Sorts a subsection of the list.
  741. ================
  742. */
  743. template< class type >
  744. ID_INLINE void idList<type>::SortSubSection( int startIndex, int endIndex, cmp_t *compare ) {
  745. if ( !list ) {
  746. return;
  747. }
  748. if ( startIndex < 0 ) {
  749. startIndex = 0;
  750. }
  751. if ( endIndex >= num ) {
  752. endIndex = num - 1;
  753. }
  754. if ( startIndex >= endIndex ) {
  755. return;
  756. }
  757. typedef int cmp_c(const void *, const void *);
  758. cmp_c *vCompare = (cmp_c *)compare;
  759. qsort( ( void * )( &list[startIndex] ), ( size_t )( endIndex - startIndex + 1 ), sizeof( type ), vCompare );
  760. }
  761. /*
  762. ================
  763. idList<type>::Swap
  764. Swaps the contents of two lists
  765. ================
  766. */
  767. template< class type >
  768. ID_INLINE void idList<type>::Swap( idList<type> &other ) {
  769. idSwap( num, other.num );
  770. idSwap( size, other.size );
  771. idSwap( granularity, other.granularity );
  772. idSwap( list, other.list );
  773. }
  774. #endif /* !__LIST_H__ */