00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "qglobal.h"
00039 #if defined(Q_CC_BOR)
00040
00041 #include "qplatformdefs.h"
00042 #endif
00043
00044 #define QGVECTOR_CPP
00045 #include "qgvector.h"
00046 #include "qglist.h"
00047 #include "qstring.h"
00048 #include "qdatastream.h"
00049 #include <stdlib.h>
00050
00051 #ifdef QT_THREAD_SUPPORT
00052 # include <private/qmutexpool_p.h>
00053 #endif // QT_THREAD_SUPPORT
00054
00055 #define USE_MALLOC // comment to use new/delete
00056
00057 #undef NEW
00058 #undef DELETE
00059
00060 #if defined(USE_MALLOC)
00061 #define NEW(type,size) ((type*)malloc(size*sizeof(type)))
00062 #define DELETE(array) (free((char*)array))
00063 #else
00064 #define NEW(type,size) (new type[size])
00065 #define DELETE(array) (delete[] array)
00066 #define DONT_USE_REALLOC // comment to use realloc()
00067 #endif
00068
00092
00093
00094
00095
00121 int QGVector::compareItems( Item d1, Item d2 )
00122 {
00123 return d1 != d2;
00124 }
00125
00126 #ifndef QT_NO_DATASTREAM
00127
00136 QDataStream &QGVector::read( QDataStream &s, Item &d )
00137 {
00138 d = 0;
00139 return s;
00140 }
00141
00151 QDataStream &QGVector::write( QDataStream &s, Item ) const
00152 {
00153 return s;
00154 }
00155 #endif // QT_NO_DATASTREAM
00156
00157
00158
00159
00160
00161 QGVector::QGVector()
00162 {
00163 vec = 0;
00164 len = numItems = 0;
00165 }
00166
00167 QGVector::QGVector( uint size )
00168 {
00169 len = size;
00170 numItems = 0;
00171 if ( len == 0 ) {
00172 vec = 0;
00173 return;
00174 }
00175 vec = NEW(Item,len);
00176 Q_CHECK_PTR( vec );
00177 memset( (void*)vec, 0, len*sizeof(Item) );
00178 }
00179
00180 QGVector::QGVector( const QGVector &a )
00181 : QPtrCollection( a )
00182 {
00183 len = a.len;
00184 numItems = a.numItems;
00185 if ( len == 0 ) {
00186 vec = 0;
00187 return;
00188 }
00189 vec = NEW( Item, len );
00190 Q_CHECK_PTR( vec );
00191 for ( uint i = 0; i < len; i++ ) {
00192 if ( a.vec[i] ) {
00193 vec[i] = newItem( a.vec[i] );
00194 Q_CHECK_PTR( vec[i] );
00195 } else {
00196 vec[i] = 0;
00197 }
00198 }
00199 }
00200
00201 QGVector::~QGVector()
00202 {
00203 clear();
00204 }
00205
00206 QGVector& QGVector::operator=( const QGVector &v )
00207 {
00208 if ( &v == this )
00209 return *this;
00210
00211 clear();
00212 len = v.len;
00213 numItems = v.numItems;
00214 if ( len == 0 ) {
00215 vec = 0;
00216 return *this;
00217 }
00218 vec = NEW( Item, len );
00219 Q_CHECK_PTR( vec );
00220 for ( uint i = 0; i < len; i++ ) {
00221 if ( v.vec[i] ) {
00222 vec[i] = newItem( v.vec[i] );
00223 Q_CHECK_PTR( vec[i] );
00224 } else {
00225 vec[i] = 0;
00226 }
00227 }
00228 return *this;
00229 }
00230
00231
00232 bool QGVector::insert( uint index, Item d )
00233 {
00234 #if defined(QT_CHECK_RANGE)
00235 if ( index >= len ) {
00236 qWarning( "QGVector::insert: Index %d out of range", index );
00237 return FALSE;
00238 }
00239 #endif
00240 if ( vec[index] ) {
00241 deleteItem( vec[index] );
00242 numItems--;
00243 }
00244 if ( d ) {
00245 vec[index] = newItem( d );
00246 Q_CHECK_PTR( vec[index] );
00247 numItems++;
00248 return vec[index] != 0;
00249 } else {
00250 vec[index] = 0;
00251 }
00252 return TRUE;
00253 }
00254
00255 bool QGVector::remove( uint index )
00256 {
00257 #if defined(QT_CHECK_RANGE)
00258 if ( index >= len ) {
00259 qWarning( "QGVector::remove: Index %d out of range", index );
00260 return FALSE;
00261 }
00262 #endif
00263 if ( vec[index] ) {
00264 deleteItem( vec[index] );
00265 vec[index] = 0;
00266 numItems--;
00267 }
00268 return TRUE;
00269 }
00270
00271 QPtrCollection::Item QGVector::take( uint index )
00272 {
00273 #if defined(QT_CHECK_RANGE)
00274 if ( index >= len ) {
00275 qWarning( "QGVector::take: Index %d out of range", index );
00276 return 0;
00277 }
00278 #endif
00279 Item d = vec[index];
00280 if ( d )
00281 numItems--;
00282 vec[index] = 0;
00283 return d;
00284 }
00285
00286 void QGVector::clear()
00287 {
00288 if ( vec ) {
00289 for ( uint i=0; i<len; i++ ) {
00290 if ( vec[i] )
00291 deleteItem( vec[i] );
00292 }
00293 DELETE(vec);
00294 vec = 0;
00295 len = numItems = 0;
00296 }
00297 }
00298
00299 bool QGVector::resize( uint newsize )
00300 {
00301 if ( newsize == len )
00302 return TRUE;
00303 if ( vec ) {
00304 if ( newsize < len ) {
00305 uint i = newsize;
00306 while ( i < len ) {
00307 if ( vec[i] ) {
00308 deleteItem( vec[i] );
00309 numItems--;
00310 }
00311 i++;
00312 }
00313 }
00314 if ( newsize == 0 ) {
00315 DELETE(vec);
00316 vec = 0;
00317 len = numItems = 0;
00318 return TRUE;
00319 }
00320 #if defined(DONT_USE_REALLOC)
00321 if ( newsize == 0 ) {
00322 DELETE(vec);
00323 vec = 0;
00324 return FALSE;
00325 }
00326 Item *newvec = NEW(Item,newsize);
00327 memcpy( newvec, vec, (len < newsize ? len : newsize)*sizeof(Item) );
00328 DELETE(vec);
00329 vec = newvec;
00330 #else
00331 vec = (Item*)realloc( (char *)vec, newsize*sizeof(Item) );
00332 #endif
00333 } else {
00334 vec = NEW(Item,newsize);
00335 len = numItems = 0;
00336 }
00337 Q_CHECK_PTR( vec );
00338 if ( !vec )
00339 return FALSE;
00340 if ( newsize > len )
00341 memset( (void*)&vec[len], 0, (newsize-len)*sizeof(Item) );
00342 len = newsize;
00343 return TRUE;
00344 }
00345
00346
00347 bool QGVector::fill( Item d, int flen )
00348 {
00349 if ( flen < 0 )
00350 flen = len;
00351 else if ( !resize( flen ) )
00352 return FALSE;
00353 for ( uint i=0; i<(uint)flen; i++ )
00354 insert( i, d );
00355 return TRUE;
00356 }
00357
00358
00359 static QGVector *sort_vec=0;
00360
00361
00362 #if defined(Q_C_CALLBACKS)
00363 extern "C" {
00364 #endif
00365
00366 #ifdef Q_OS_TEMP
00367 static int _cdecl cmp_vec( const void *n1, const void *n2 )
00368 #else
00369 static int cmp_vec( const void *n1, const void *n2 )
00370 #endif
00371 {
00372 return sort_vec->compareItems( *((QPtrCollection::Item*)n1), *((QPtrCollection::Item*)n2) );
00373 }
00374
00375 #if defined(Q_C_CALLBACKS)
00376 }
00377 #endif
00378
00379
00380 void QGVector::sort()
00381 {
00382 if ( count() == 0 )
00383 return;
00384 register Item *start = &vec[0];
00385 register Item *end = &vec[len-1];
00386 Item tmp;
00387 for (;;) {
00388 while ( start < end && *start != 0 )
00389 start++;
00390 while ( end > start && *end == 0 )
00391 end--;
00392 if ( start < end ) {
00393 tmp = *start;
00394 *start = *end;
00395 *end = tmp;
00396 } else {
00397 break;
00398 }
00399 }
00400
00401 #ifdef QT_THREAD_SUPPORT
00402 QMutexLocker locker( qt_global_mutexpool ?
00403 qt_global_mutexpool->get( &sort_vec ) : 0 );
00404 #endif // QT_THREAD_SUPPORT
00405
00406 sort_vec = (QGVector*)this;
00407 qsort( vec, count(), sizeof(Item), cmp_vec );
00408 sort_vec = 0;
00409 }
00410
00411 int QGVector::bsearch( Item d ) const
00412 {
00413 if ( !len )
00414 return -1;
00415 if ( !d ) {
00416 #if defined(QT_CHECK_NULL)
00417 qWarning( "QGVector::bsearch: Cannot search for null object" );
00418 #endif
00419 return -1;
00420 }
00421 int n1 = 0;
00422 int n2 = len - 1;
00423 int mid = 0;
00424 bool found = FALSE;
00425 while ( n1 <= n2 ) {
00426 int res;
00427 mid = (n1 + n2)/2;
00428 if ( vec[mid] == 0 )
00429 res = -1;
00430 else
00431 res = ((QGVector*)this)->compareItems( d, vec[mid] );
00432 if ( res < 0 )
00433 n2 = mid - 1;
00434 else if ( res > 0 )
00435 n1 = mid + 1;
00436 else {
00437 found = TRUE;
00438 break;
00439 }
00440 }
00441 if ( !found )
00442 return -1;
00443
00444 while ( (mid - 1 >= 0) && !((QGVector*)this)->compareItems(d, vec[mid-1]) )
00445 mid--;
00446 return mid;
00447 }
00448
00449 int QGVector::findRef( Item d, uint index) const
00450 {
00451 #if defined(QT_CHECK_RANGE)
00452 if ( index > len ) {
00453 qWarning( "QGVector::findRef: Index %d out of range", index );
00454 return -1;
00455 }
00456 #endif
00457 for ( uint i=index; i<len; i++ ) {
00458 if ( vec[i] == d )
00459 return i;
00460 }
00461 return -1;
00462 }
00463
00464 int QGVector::find( Item d, uint index ) const
00465 {
00466 #if defined(QT_CHECK_RANGE)
00467 if ( index >= len ) {
00468 qWarning( "QGVector::find: Index %d out of range", index );
00469 return -1;
00470 }
00471 #endif
00472 for ( uint i=index; i<len; i++ ) {
00473 if ( vec[i] == 0 && d == 0 )
00474 return i;
00475 if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
00476 return i;
00477 }
00478 return -1;
00479 }
00480
00481 uint QGVector::containsRef( Item d ) const
00482 {
00483 uint count = 0;
00484 for ( uint i=0; i<len; i++ ) {
00485 if ( vec[i] == d )
00486 count++;
00487 }
00488 return count;
00489 }
00490
00491 uint QGVector::contains( Item d ) const
00492 {
00493 uint count = 0;
00494 for ( uint i=0; i<len; i++ ) {
00495 if ( vec[i] == 0 && d == 0 )
00496 count++;
00497 if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
00498 count++;
00499 }
00500 return count;
00501 }
00502
00503 bool QGVector::insertExpand( uint index, Item d )
00504 {
00505 if ( index >= len ) {
00506 if ( !resize( index+1 ) )
00507 return FALSE;
00508 }
00509 insert( index, d );
00510 return TRUE;
00511 }
00512
00513 void QGVector::toList( QGList *list ) const
00514 {
00515 list->clear();
00516 for ( uint i=0; i<len; i++ ) {
00517 if ( vec[i] )
00518 list->append( vec[i] );
00519 }
00520 }
00521
00522
00523 void QGVector::warningIndexRange( uint i )
00524 {
00525 #if defined(QT_CHECK_RANGE)
00526 qWarning( "QGVector::operator[]: Index %d out of range", i );
00527 #else
00528 Q_UNUSED( i )
00529 #endif
00530 }
00531
00532
00533
00534
00535
00536 #ifndef QT_NO_DATASTREAM
00537 QDataStream &operator>>( QDataStream &s, QGVector &vec )
00538 {
00539 return vec.read( s );
00540 }
00541
00542 QDataStream &operator<<( QDataStream &s, const QGVector &vec )
00543 {
00544 return vec.write( s );
00545 }
00546
00547 QDataStream &QGVector::read( QDataStream &s )
00548 {
00549 uint num;
00550 s >> num;
00551 clear();
00552 resize( num );
00553 for (uint i=0; i<num; i++) {
00554 Item d;
00555 read( s, d );
00556 Q_CHECK_PTR( d );
00557 if ( !d )
00558 break;
00559 vec[i] = d;
00560 }
00561 return s;
00562 }
00563
00564 QDataStream &QGVector::write( QDataStream &s ) const
00565 {
00566 uint num = count();
00567 s << num;
00568 num = size();
00569 for (uint i=0; i<num; i++) {
00570 if ( vec[i] )
00571 write( s, vec[i] );
00572 }
00573 return s;
00574 }
00575
00576
00577
00578 bool QGVector::operator==( const QGVector &v ) const
00579 {
00580 if ( size() != v.size() )
00581 return FALSE;
00582 if ( count() != v.count() )
00583 return FALSE;
00584 for ( int i = 0; i < (int)size(); ++i ) {
00585 if ( ( (QGVector*)this )->compareItems( at( i ), v.at( i ) ) != 0 )
00586 return FALSE;
00587 }
00588 return TRUE;
00589 }
00590
00591 #endif // QT_NO_DATASTREAM