1 /****************************************************************************
4 ** Implementation of QGVector class
8 ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
10 ** This file is part of the tools module of the Qt GUI Toolkit.
12 ** This file may be distributed under the terms of the Q Public License
13 ** as defined by Trolltech AS of Norway and appearing in the file
14 ** LICENSE.QPL included in the packaging of this file.
16 ** This file may be distributed and/or modified under the terms of the
17 ** GNU General Public License version 2 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.GPL included in the
19 ** packaging of this file.
21 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22 ** licenses may use this file in accordance with the Qt Commercial License
23 ** Agreement provided with the Software.
25 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
28 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29 ** information about Qt Commercial License Agreements.
30 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
31 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
33 ** Contact info@trolltech.com if any conditions of this licensing are
36 **********************************************************************/
42 #include "qdatastream.h"
45 #define USE_MALLOC // comment to use new/delete
50 #if defined(USE_MALLOC)
51 #define NEW(type,size) ((type*)malloc(size*sizeof(type)))
52 #define DELETE(array) (free((char*)array))
54 #define NEW(type,size) (new type[size])
55 #define DELETE(array) (delete[] array)
56 #define DONT_USE_REALLOC // comment to use realloc()
62 \class QGVector qgvector.h
64 \brief The QGVector class is an internal class for implementing Qt
67 QGVector is a strictly internal class that acts as a base class for
68 the QVector collection class.
70 QGVector has some virtual functions that may be reimplemented in
71 subclasses to to customize behavior.
74 <li> compareItems() compares two collection/vector items.
75 <li> read() reads a collection/vector item from a QDataStream.
76 <li> write() writes a collection/vector item to a QDataStream.
80 /*****************************************************************************
81 Default implementation of virtual functions
82 *****************************************************************************/
85 This virtual function compares two list items.
89 <li> 0 if \a item1 == \a item2
90 <li> non-zero if \a item1 != \a item2
93 This function returns \e int rather than \e bool so that
94 reimplementations can return one of three values and use it to sort
98 <li> 0 if \e item1 == \e item2
99 <li> \> 0 (positive integer) if \a item1 \> \a item2
100 <li> \< 0 (negative integer) if \a item1 \< \a item2
103 The QVector::sort() and QVector::bsearch() functions require that
104 compareItems() is implemented as described here.
106 This function should not modify the vector because some const
107 functions call compareItems().
110 int QGVector::compareItems( Item d1, Item d2 )
112 return d1 != d2; // compare pointers
115 #ifndef QT_NO_DATASTREAM
117 Reads a collection/vector item from the stream \a s and returns a reference
120 The default implementation sets \e item to 0.
125 QDataStream &QGVector::read( QDataStream &s, Item &d )
126 { // read item from stream
132 Writes a collection/vector item to the stream \a s and returns a reference
135 The default implementation does nothing.
140 QDataStream &QGVector::write( QDataStream &s, Item ) const
141 { // write item to stream
144 #endif // QT_NO_DATASTREAM
146 /*****************************************************************************
147 QGVector member functions
148 *****************************************************************************/
154 QGVector::QGVector() // create empty vector
163 QGVector::QGVector( uint size ) // create vectors with nullptrs
167 if ( len == 0 ) { // zero length
173 memset( (void*)vec, 0, len*sizeof(Item) ); // fill with nulls
180 QGVector::QGVector( const QGVector &a ) // make copy of other vector
184 numItems = a.numItems;
187 for ( uint i=0; i<len; i++ ) {
188 vec[i] = a.vec[i] ? newItem( a.vec[i] ) : 0;
197 QGVector::~QGVector()
207 QGVector& QGVector::operator=( const QGVector &v )
208 { // assign from other vector
209 clear(); // first delete old vector
211 numItems = v.numItems;
212 vec = NEW(Item,len); // create new vector
214 for ( uint i=0; i<len; i++ ) { // copy elements
215 vec[i] = v.vec[i] ? newItem( v.vec[i] ) : 0;
223 \fn Item *QGVector::data() const
228 \fn uint QGVector::size() const
233 \fn uint QGVector::count() const
238 \fn Item QGVector::at( uint index ) const
246 bool QGVector::insert( uint index, Item d ) // insert item at index
248 #if defined(CHECK_RANGE)
249 if ( index >= len ) { // range error
250 qWarning( "QGVector::insert: Index %d out of range", index );
254 if ( vec[index] ) { // remove old item
255 deleteItem( vec[index] );
259 vec[index] = newItem( d );
260 CHECK_PTR( vec[index] );
262 return vec[index] != 0;
264 vec[index] = 0; // reset item
273 bool QGVector::remove( uint index ) // remove item at index
275 #if defined(CHECK_RANGE)
276 if ( index >= len ) { // range error
277 qWarning( "QGVector::remove: Index %d out of range", index );
281 if ( vec[index] ) { // valid item
282 deleteItem( vec[index] ); // delete it
283 vec[index] = 0; // reset pointer
293 QCollection::Item QGVector::take( uint index ) // take out item
295 #if defined(CHECK_RANGE)
296 if ( index >= len ) { // range error
297 qWarning( "QGVector::take: Index %d out of range", index );
301 Item d = vec[index]; // don't delete item
313 void QGVector::clear() // clear vector
316 for ( uint i=0; i<len; i++ ) { // delete each item
318 deleteItem( vec[i] );
330 bool QGVector::resize( uint newsize ) // resize array
332 if ( newsize == len ) // nothing to do
334 if ( vec ) { // existing data
335 if ( newsize < len ) { // shrink vector
337 while ( i < len ) { // delete lost items
339 deleteItem( vec[i] );
345 if ( newsize == 0 ) { // vector becomes empty
351 #if defined(DONT_USE_REALLOC)
352 Item *newvec = NEW(Item,newsize); // manual realloc
353 memcpy( newvec, vec, (len < newsize ? len : newsize)*sizeof(Item) );
357 vec = (Item*)realloc( (char *)vec, newsize*sizeof(Item) );
359 } else { // create new vector
360 vec = NEW(Item,newsize);
364 if ( !vec ) // no memory
366 if ( newsize > len ) // init extra space added
367 memset( (void*)&vec[len], 0, (newsize-len)*sizeof(Item) );
377 bool QGVector::fill( Item d, int flen ) // resize and fill vector
380 flen = len; // default: use vector length
381 else if ( !resize( flen ) )
383 for ( uint i=0; i<(uint)flen; i++ ) // insert d at every index
389 static QGVector *sort_vec=0; // current sort vector
392 #if defined(Q_C_CALLBACKS)
396 static int cmp_vec( const void *n1, const void *n2 )
398 return sort_vec->compareItems( *((QCollection::Item*)n1), *((QCollection::Item*)n2) );
401 #if defined(Q_C_CALLBACKS)
410 void QGVector::sort() // sort vector
412 if ( count() == 0 ) // no elements
414 register Item *start = &vec[0];
415 register Item *end = &vec[len-1];
417 while ( TRUE ) { // put all zero elements behind
418 while ( start < end && *start != 0 )
420 while ( end > start && *end == 0 )
430 sort_vec = (QGVector*)this;
431 qsort( vec, count(), sizeof(Item), cmp_vec );
439 int QGVector::bsearch( Item d ) const // binary search; when sorted
444 #if defined(CHECK_NULL)
445 qWarning( "QGVector::bsearch: Cannot search for null object" );
456 if ( vec[mid] == 0 ) // null item greater
459 res = ((QGVector*)this)->compareItems( d, vec[mid] );
471 // search to first of equal items
472 while ( (mid - 1 >= 0) && !((QGVector*)this)->compareItems(d, vec[mid-1]) )
482 int QGVector::findRef( Item d, uint index) const // find exact item in vector
484 #if defined(CHECK_RANGE)
485 if ( index >= len ) { // range error
486 qWarning( "QGVector::findRef: Index %d out of range", index );
490 for ( uint i=index; i<len; i++ ) {
501 int QGVector::find( Item d, uint index ) const // find equal item in vector
503 #if defined(CHECK_RANGE)
504 if ( index >= len ) { // range error
505 qWarning( "QGVector::find: Index %d out of range", index );
509 for ( uint i=index; i<len; i++ ) {
510 if ( vec[i] == 0 && d == 0 ) // found null item
512 if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
522 uint QGVector::containsRef( Item d ) const // get number of exact matches
525 for ( uint i=0; i<len; i++ ) {
536 uint QGVector::contains( Item d ) const // get number of equal matches
539 for ( uint i=0; i<len; i++ ) {
540 if ( vec[i] == 0 && d == 0 ) // count null items
542 if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
553 bool QGVector::insertExpand( uint index, Item d )// insert and grow if necessary
555 if ( index >= len ) {
556 if ( !resize( index+1 ) ) // no memory
568 void QGVector::toList( QGList *list ) const // store items in list
571 for ( uint i=0; i<len; i++ ) {
573 list->append( vec[i] );
578 void QGVector::warningIndexRange( uint i )
580 #if defined(CHECK_RANGE)
581 qWarning( "QGVector::operator[]: Index %d out of range", i );
588 /*****************************************************************************
589 QGVector stream functions
590 *****************************************************************************/
591 #ifndef QT_NO_DATASTREAM
592 QDataStream &operator>>( QDataStream &s, QGVector &vec )
594 return vec.read( s );
597 QDataStream &operator<<( QDataStream &s, const QGVector &vec )
599 return vec.write( s );
606 QDataStream &QGVector::read( QDataStream &s ) // read vector from stream
609 s >> num; // read number of items
610 clear(); // clear vector
612 for (uint i=0; i<num; i++) { // read all items
616 if ( !d ) // no memory
627 QDataStream &QGVector::write( QDataStream &s ) const
628 { // write vector to stream
630 s << num; // number of items to write
632 for (uint i=0; i<num; i++) { // write non-null items
638 #endif // QT_NO_DATASTREAM