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 #ifndef QVALUELIST_H
00039 #define QVALUELIST_H
00040
00041 #ifndef QT_H
00042 #include "qtl.h"
00043 #include "qshared.h"
00044 #include "qdatastream.h"
00045 #endif // QT_H
00046
00047 #ifndef QT_NO_STL
00048 #include <iterator>
00049 #include <list>
00050 #endif
00051
00052
00053
00054 #if defined(Q_CC_MSVC)
00055 #pragma warning(disable:4284) // "return type for operator -> is not a UDT"
00056 #endif
00057
00058 template <class T>
00059 class QValueListNode
00060 {
00061 public:
00062 QValueListNode( const T& t ) : data( t ) { }
00063 QValueListNode() { }
00064 #if defined(Q_TEMPLATEDLL)
00065
00066 virtual ~QValueListNode() { }
00067 #endif
00068
00069 QValueListNode<T>* next;
00070 QValueListNode<T>* prev;
00071 T data;
00072 };
00073
00074 template<class T>
00075 class QValueListIterator
00076 {
00077 public:
00081 typedef QValueListNode<T>* NodePtr;
00082 #ifndef QT_NO_STL
00083 typedef std::bidirectional_iterator_tag iterator_category;
00084 #endif
00085 typedef T value_type;
00086 typedef size_t size_type;
00087 #ifndef QT_NO_STL
00088 typedef ptrdiff_t difference_type;
00089 #else
00090 typedef int difference_type;
00091 #endif
00092 typedef T* pointer;
00093 typedef T& reference;
00094
00098 NodePtr node;
00099
00103 QValueListIterator() : node( 0 ) {}
00104 QValueListIterator( NodePtr p ) : node( p ) {}
00105 QValueListIterator( const QValueListIterator<T>& it ) : node( it.node ) {}
00106
00107 bool operator==( const QValueListIterator<T>& it ) const { return node == it.node; }
00108 bool operator!=( const QValueListIterator<T>& it ) const { return node != it.node; }
00109 const T& operator*() const { return node->data; }
00110 T& operator*() { return node->data; }
00111
00112
00113
00114 QValueListIterator<T>& operator++() {
00115 node = node->next;
00116 return *this;
00117 }
00118
00119 QValueListIterator<T> operator++(int) {
00120 QValueListIterator<T> tmp = *this;
00121 node = node->next;
00122 return tmp;
00123 }
00124
00125 QValueListIterator<T>& operator--() {
00126 node = node->prev;
00127 return *this;
00128 }
00129
00130 QValueListIterator<T> operator--(int) {
00131 QValueListIterator<T> tmp = *this;
00132 node = node->prev;
00133 return tmp;
00134 }
00135
00136 QValueListIterator<T>& operator+=( int j ) {
00137 while ( j-- )
00138 node = node->next;
00139 return *this;
00140 }
00141
00142 QValueListIterator<T>& operator-=( int j ) {
00143 while ( j-- )
00144 node = node->prev;
00145 return *this;
00146 }
00147
00148 };
00149
00150 template<class T>
00151 class QValueListConstIterator
00152 {
00153 public:
00157 typedef QValueListNode<T>* NodePtr;
00158 #ifndef QT_NO_STL
00159 typedef std::bidirectional_iterator_tag iterator_category;
00160 #endif
00161 typedef T value_type;
00162 typedef size_t size_type;
00163 #ifndef QT_NO_STL
00164 typedef ptrdiff_t difference_type;
00165 #else
00166 typedef int difference_type;
00167 #endif
00168 typedef const T* pointer;
00169 typedef const T& reference;
00170
00174 NodePtr node;
00175
00179 QValueListConstIterator() : node( 0 ) {}
00180 QValueListConstIterator( NodePtr p ) : node( p ) {}
00181 QValueListConstIterator( const QValueListConstIterator<T>& it ) : node( it.node ) {}
00182 QValueListConstIterator( const QValueListIterator<T>& it ) : node( it.node ) {}
00183
00184 bool operator==( const QValueListConstIterator<T>& it ) const { return node == it.node; }
00185 bool operator!=( const QValueListConstIterator<T>& it ) const { return node != it.node; }
00186 const T& operator*() const { return node->data; }
00187
00188
00189
00190 QValueListConstIterator<T>& operator++() {
00191 node = node->next;
00192 return *this;
00193 }
00194
00195 QValueListConstIterator<T> operator++(int) {
00196 QValueListConstIterator<T> tmp = *this;
00197 node = node->next;
00198 return tmp;
00199 }
00200
00201 QValueListConstIterator<T>& operator--() {
00202 node = node->prev;
00203 return *this;
00204 }
00205
00206 QValueListConstIterator<T> operator--(int) {
00207 QValueListConstIterator<T> tmp = *this;
00208 node = node->prev;
00209 return tmp;
00210 }
00211 };
00212
00213 template <class T>
00214 class QValueListPrivate : public QShared
00215 {
00216 public:
00220 typedef QValueListIterator<T> Iterator;
00221 typedef QValueListConstIterator<T> ConstIterator;
00222 typedef QValueListNode<T> Node;
00223 typedef QValueListNode<T>* NodePtr;
00224 typedef size_t size_type;
00225
00229 QValueListPrivate();
00230 QValueListPrivate( const QValueListPrivate<T>& _p );
00231
00232 void derefAndDelete()
00233 {
00234 if ( deref() )
00235 delete this;
00236 }
00237
00238 #if defined(Q_TEMPLATEDLL)
00239
00240 virtual
00241 #endif
00242 ~QValueListPrivate();
00243
00244 Iterator insert( Iterator it, const T& x );
00245 Iterator remove( Iterator it );
00246 NodePtr find( NodePtr start, const T& x ) const;
00247 int findIndex( NodePtr start, const T& x ) const;
00248 uint contains( const T& x ) const;
00249 uint remove( const T& x );
00250 NodePtr at( size_type i ) const;
00251 void clear();
00252
00253 NodePtr node;
00254 size_type nodes;
00255 };
00256
00257 template <class T>
00258 Q_INLINE_TEMPLATES QValueListPrivate<T>::QValueListPrivate()
00259 {
00260 node = new Node; node->next = node->prev = node; nodes = 0;
00261 }
00262
00263 template <class T>
00264 Q_INLINE_TEMPLATES QValueListPrivate<T>::QValueListPrivate( const QValueListPrivate<T>& _p )
00265 : QShared()
00266 {
00267 node = new Node; node->next = node->prev = node; nodes = 0;
00268 Iterator b( _p.node->next );
00269 Iterator e( _p.node );
00270 Iterator i( node );
00271 while( b != e )
00272 insert( i, *b++ );
00273 }
00274
00275 template <class T>
00276 Q_INLINE_TEMPLATES QValueListPrivate<T>::~QValueListPrivate() {
00277 NodePtr p = node->next;
00278 while( p != node ) {
00279 NodePtr x = p->next;
00280 delete p;
00281 p = x;
00282 }
00283 delete node;
00284 }
00285
00286 template <class T>
00287 Q_INLINE_TEMPLATES Q_TYPENAME QValueListPrivate<T>::Iterator QValueListPrivate<T>::insert( Q_TYPENAME QValueListPrivate<T>::Iterator it, const T& x )
00288 {
00289 NodePtr p = new Node( x );
00290 p->next = it.node;
00291 p->prev = it.node->prev;
00292 it.node->prev->next = p;
00293 it.node->prev = p;
00294 nodes++;
00295 return p;
00296 }
00297
00298 template <class T>
00299 Q_INLINE_TEMPLATES Q_TYPENAME QValueListPrivate<T>::Iterator QValueListPrivate<T>::remove( Q_TYPENAME QValueListPrivate<T>::Iterator it )
00300 {
00301 Q_ASSERT ( it.node != node );
00302 NodePtr next = it.node->next;
00303 NodePtr prev = it.node->prev;
00304 prev->next = next;
00305 next->prev = prev;
00306 delete it.node;
00307 nodes--;
00308 return Iterator( next );
00309 }
00310
00311 template <class T>
00312 Q_INLINE_TEMPLATES Q_TYPENAME QValueListPrivate<T>::NodePtr QValueListPrivate<T>::find( Q_TYPENAME QValueListPrivate<T>::NodePtr start, const T& x ) const
00313 {
00314 ConstIterator first( start );
00315 ConstIterator last( node );
00316 while( first != last) {
00317 if ( *first == x )
00318 return first.node;
00319 ++first;
00320 }
00321 return last.node;
00322 }
00323
00324 template <class T>
00325 Q_INLINE_TEMPLATES int QValueListPrivate<T>::findIndex( Q_TYPENAME QValueListPrivate<T>::NodePtr start, const T& x ) const
00326 {
00327 ConstIterator first( start );
00328 ConstIterator last( node );
00329 int pos = 0;
00330 while( first != last) {
00331 if ( *first == x )
00332 return pos;
00333 ++first;
00334 ++pos;
00335 }
00336 return -1;
00337 }
00338
00339 template <class T>
00340 Q_INLINE_TEMPLATES uint QValueListPrivate<T>::contains( const T& x ) const
00341 {
00342 uint result = 0;
00343 Iterator first = Iterator( node->next );
00344 Iterator last = Iterator( node );
00345 while( first != last) {
00346 if ( *first == x )
00347 ++result;
00348 ++first;
00349 }
00350 return result;
00351 }
00352
00353 template <class T>
00354 Q_INLINE_TEMPLATES uint QValueListPrivate<T>::remove( const T& x )
00355 {
00356 uint result = 0;
00357 Iterator first = Iterator( node->next );
00358 Iterator last = Iterator( node );
00359 while( first != last) {
00360 if ( *first == x ) {
00361 first = remove( first );
00362 ++result;
00363 } else
00364 ++first;
00365 }
00366 return result;
00367 }
00368
00369 template <class T>
00370 Q_INLINE_TEMPLATES Q_TYPENAME QValueListPrivate<T>::NodePtr QValueListPrivate<T>::at( size_type i ) const
00371 {
00372 Q_ASSERT( i <= nodes );
00373 NodePtr p = node->next;
00374 for( size_type x = 0; x < i; ++x )
00375 p = p->next;
00376 return p;
00377 }
00378
00379 template <class T>
00380 Q_INLINE_TEMPLATES void QValueListPrivate<T>::clear()
00381 {
00382 nodes = 0;
00383 NodePtr p = node->next;
00384 while( p != node ) {
00385 NodePtr next = p->next;
00386 delete p;
00387 p = next;
00388 }
00389 node->next = node->prev = node;
00390 }
00391
00392 #ifdef QT_CHECK_RANGE
00393 # if !defined( QT_NO_DEBUG ) && defined( QT_CHECK_VALUELIST_RANGE )
00394 # define QT_CHECK_INVALID_LIST_ELEMENT if ( empty() ) qWarning( "QValueList: Warning invalid element" )
00395 # define QT_CHECK_INVALID_LIST_ELEMENT_FATAL Q_ASSERT( !empty() );
00396 # else
00397 # define QT_CHECK_INVALID_LIST_ELEMENT
00398 # define QT_CHECK_INVALID_LIST_ELEMENT_FATAL
00399 # endif
00400 #else
00401 # define QT_CHECK_INVALID_LIST_ELEMENT
00402 # define QT_CHECK_INVALID_LIST_ELEMENT_FATAL
00403 #endif
00404
00405 template <class T> class QDeepCopy;
00406
00407 template <class T>
00408 class QValueList
00409 {
00410 public:
00414 typedef QValueListIterator<T> iterator;
00415 typedef QValueListConstIterator<T> const_iterator;
00416 typedef T value_type;
00417 typedef value_type* pointer;
00418 typedef const value_type* const_pointer;
00419 typedef value_type& reference;
00420 typedef const value_type& const_reference;
00421 typedef size_t size_type;
00422 #ifndef QT_NO_STL
00423 typedef ptrdiff_t difference_type;
00424 #else
00425 typedef int difference_type;
00426 #endif
00427
00431 QValueList() { sh = new QValueListPrivate<T>; }
00432 QValueList( const QValueList<T>& l ) { sh = l.sh; sh->ref(); }
00433 #ifndef QT_NO_STL
00434 # ifdef Q_CC_HPACC // HP-UX aCC does require typename in some place
00435 # undef Q_TYPENAME // but not accept them at others.
00436 # define Q_TYPENAME // also doesn't like re-defines ...
00437 # endif
00438 QValueList( const Q_TYPENAME std::list<T>& l )
00439 {
00440 sh = new QValueListPrivate<T>;
00441 qCopy( l.begin(), l.end(), std::back_inserter( *this ) );
00442 }
00443 #endif
00444 ~QValueList() { sh->derefAndDelete(); }
00445
00446 QValueList<T>& operator= ( const QValueList<T>& l )
00447 {
00448 l.sh->ref();
00449 sh->derefAndDelete();
00450 sh = l.sh;
00451 return *this;
00452 }
00453 #ifndef QT_NO_STL
00454 QValueList<T>& operator= ( const Q_TYPENAME std::list<T>& l )
00455 {
00456 detach();
00457 qCopy( l.begin(), l.end(), std::back_inserter( *this ) );
00458 return *this;
00459 }
00460 bool operator== ( const Q_TYPENAME std::list<T>& l ) const
00461 {
00462 if ( size() != l.size() )
00463 return FALSE;
00464 const_iterator it2 = begin();
00465 #if !defined(Q_CC_MIPS)
00466 typename
00467 #endif
00468 std::list<T>::const_iterator it = l.begin();
00469 for ( ; it2 != end(); ++it2, ++it )
00470 if ( !((*it2) == (*it)) )
00471 return FALSE;
00472 return TRUE;
00473 }
00474 # ifdef Q_CC_HPACC // undo the HP-UX aCC hackery done above
00475 # undef Q_TYPENAME
00476 # define Q_TYPENAME typename
00477 # endif
00478 #endif
00479 bool operator== ( const QValueList<T>& l ) const;
00480 bool operator!= ( const QValueList<T>& l ) const { return !( *this == l ); }
00481 iterator begin() { detach(); return iterator( sh->node->next ); }
00482 const_iterator begin() const { return const_iterator( sh->node->next ); }
00483 iterator end() { detach(); return iterator( sh->node ); }
00484 const_iterator end() const { return const_iterator( sh->node ); }
00485 iterator insert( iterator it, const T& x ) { detach(); return sh->insert( it, x ); }
00486 uint remove( const T& x ) { detach(); return sh->remove( x ); }
00487 void clear();
00488
00489 QValueList<T>& operator<< ( const T& x )
00490 {
00491 append( x );
00492 return *this;
00493 }
00494
00495 size_type size() const { return sh->nodes; }
00496 bool empty() const { return sh->nodes == 0; }
00497 void push_front( const T& x ) { detach(); sh->insert( begin(), x ); }
00498 void push_back( const T& x ) { detach(); sh->insert( end(), x ); }
00499 iterator erase( iterator pos ) { detach(); return sh->remove( pos ); }
00500 iterator erase( iterator first, iterator last );
00501 reference front() { QT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *begin(); }
00502 const_reference front() const { QT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *begin(); }
00503 reference back() { QT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *(--end()); }
00504 const_reference back() const { QT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *(--end()); }
00505 void pop_front() { QT_CHECK_INVALID_LIST_ELEMENT; erase( begin() ); }
00506 void pop_back() {
00507 QT_CHECK_INVALID_LIST_ELEMENT;
00508 iterator tmp = end();
00509 erase( --tmp );
00510 }
00511 void insert( iterator pos, size_type n, const T& x );
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 QValueList<T> operator+ ( const QValueList<T>& l ) const;
00523 QValueList<T>& operator+= ( const QValueList<T>& l );
00524
00525 iterator fromLast() { detach(); return iterator( sh->node->prev ); }
00526 const_iterator fromLast() const { return const_iterator( sh->node->prev ); }
00527
00528 bool isEmpty() const { return ( sh->nodes == 0 ); }
00529
00530 iterator append( const T& x ) { detach(); return sh->insert( end(), x ); }
00531 iterator prepend( const T& x ) { detach(); return sh->insert( begin(), x ); }
00532
00533 iterator remove( iterator it ) { detach(); return sh->remove( it ); }
00534
00535 T& first() { QT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->node->next->data; }
00536 const T& first() const { QT_CHECK_INVALID_LIST_ELEMENT; return sh->node->next->data; }
00537 T& last() { QT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->node->prev->data; }
00538 const T& last() const { QT_CHECK_INVALID_LIST_ELEMENT; return sh->node->prev->data; }
00539
00540 T& operator[] ( size_type i ) { QT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->at(i)->data; }
00541 const T& operator[] ( size_type i ) const { QT_CHECK_INVALID_LIST_ELEMENT; return sh->at(i)->data; }
00542 iterator at( size_type i ) { QT_CHECK_INVALID_LIST_ELEMENT; detach(); return iterator( sh->at(i) ); }
00543 const_iterator at( size_type i ) const { QT_CHECK_INVALID_LIST_ELEMENT; return const_iterator( sh->at(i) ); }
00544 iterator find ( const T& x ) { detach(); return iterator( sh->find( sh->node->next, x) ); }
00545 const_iterator find ( const T& x ) const { return const_iterator( sh->find( sh->node->next, x) ); }
00546 iterator find ( iterator it, const T& x ) { detach(); return iterator( sh->find( it.node, x ) ); }
00547 const_iterator find ( const_iterator it, const T& x ) const { return const_iterator( sh->find( it.node, x ) ); }
00548 int findIndex( const T& x ) const { return sh->findIndex( sh->node->next, x) ; }
00549 size_type contains( const T& x ) const { return sh->contains( x ); }
00550
00551 size_type count() const { return sh->nodes; }
00552
00553 QValueList<T>& operator+= ( const T& x )
00554 {
00555 append( x );
00556 return *this;
00557 }
00558 typedef QValueListIterator<T> Iterator;
00559 typedef QValueListConstIterator<T> ConstIterator;
00560 typedef T ValueType;
00561
00562 protected:
00566 void detach() { if ( sh->count > 1 ) detachInternal(); }
00567
00571 QValueListPrivate<T>* sh;
00572
00573 private:
00574 void detachInternal();
00575
00576 friend class QDeepCopy< QValueList<T> >;
00577 };
00578
00579 template <class T>
00580 Q_INLINE_TEMPLATES bool QValueList<T>::operator== ( const QValueList<T>& l ) const
00581 {
00582 if ( size() != l.size() )
00583 return FALSE;
00584 const_iterator it2 = begin();
00585 const_iterator it = l.begin();
00586 for( ; it != l.end(); ++it, ++it2 )
00587 if ( !( *it == *it2 ) )
00588 return FALSE;
00589 return TRUE;
00590 }
00591
00592 template <class T>
00593 Q_INLINE_TEMPLATES void QValueList<T>::clear()
00594 {
00595 if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new QValueListPrivate<T>; }
00596 }
00597
00598 template <class T>
00599 Q_INLINE_TEMPLATES Q_TYPENAME QValueList<T>::iterator QValueList<T>::erase( Q_TYPENAME QValueList<T>::iterator first, Q_TYPENAME QValueList<T>::iterator last )
00600 {
00601 while ( first != last )
00602 erase( first++ );
00603 return last;
00604 }
00605
00606
00607 template <class T>
00608 Q_INLINE_TEMPLATES void QValueList<T>::insert( Q_TYPENAME QValueList<T>::iterator pos, size_type n, const T& x )
00609 {
00610 for ( ; n > 0; --n )
00611 insert( pos, x );
00612 }
00613
00614 template <class T>
00615 Q_INLINE_TEMPLATES QValueList<T> QValueList<T>::operator+ ( const QValueList<T>& l ) const
00616 {
00617 QValueList<T> l2( *this );
00618 for( const_iterator it = l.begin(); it != l.end(); ++it )
00619 l2.append( *it );
00620 return l2;
00621 }
00622
00623 template <class T>
00624 Q_INLINE_TEMPLATES QValueList<T>& QValueList<T>::operator+= ( const QValueList<T>& l )
00625 {
00626 for( const_iterator it = l.begin(); it != l.end(); ++it )
00627 append( *it );
00628 return *this;
00629 }
00630
00631 template <class T>
00632 Q_INLINE_TEMPLATES void QValueList<T>::detachInternal()
00633 {
00634 sh->deref(); sh = new QValueListPrivate<T>( *sh );
00635 }
00636
00637 #ifndef QT_NO_DATASTREAM
00638 template <class T>
00639 Q_INLINE_TEMPLATES QDataStream& operator>>( QDataStream& s, QValueList<T>& l )
00640 {
00641 l.clear();
00642 Q_UINT32 c;
00643 s >> c;
00644 for( Q_UINT32 i = 0; i < c; ++i )
00645 {
00646 T t;
00647 s >> t;
00648 l.append( t );
00649 if ( s.atEnd() )
00650 break;
00651 }
00652 return s;
00653 }
00654
00655 template <class T>
00656 Q_INLINE_TEMPLATES QDataStream& operator<<( QDataStream& s, const QValueList<T>& l )
00657 {
00658 s << (Q_UINT32)l.size();
00659 QValueListConstIterator<T> it = l.begin();
00660 for( ; it != l.end(); ++it )
00661 s << *it;
00662 return s;
00663 }
00664 #endif // QT_NO_DATASTREAM
00665 #ifdef QT_QWINEXPORT
00666 #define Q_DEFINED_QVALUELIST
00667 #include "qwinexport.h"
00668 #endif
00669 #endif // QVALUELIST_H