source: trunk/src/tools/qglist.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 27.4 KB
Line 
1/****************************************************************************
2** $Id: qglist.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QGList and QGListIterator classes
5**
6** Created : 920624
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
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.
15**
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.
20**
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.
24**
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.
27**
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.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qglist.h"
39#include "qgvector.h"
40#include "qdatastream.h"
41#include "qvaluelist.h"
42
43/*!
44 \class QLNode qglist.h
45 \reentrant
46 \ingroup collection
47 \brief The QLNode class is an internal class for the QPtrList template collection.
48
49 \internal
50
51 QLNode is a doubly-linked list node. It has three pointers:
52 \list 1
53 \i Pointer to the previous node.
54 \i Pointer to the next node.
55 \i Pointer to the actual data.
56 \endlist
57
58 It might sometimes be practical to have direct access to the list nodes
59 in a QPtrList, but it is seldom required.
60
61 Be very careful if you want to access the list nodes. The heap can
62 easily get corrupted if you make a mistake.
63
64 \sa QPtrList::currentNode(), QPtrList::removeNode(), QPtrList::takeNode()
65*/
66
67/*!
68 \fn QPtrCollection::Item QLNode::getData()
69 Returns a pointer (\c void*) to the actual data in the list node.
70*/
71
72
73/*!
74 \class QGList qglist.h
75 \reentrant
76 \ingroup collection
77 \brief The QGList class is an internal class for implementing Qt collection classes.
78
79 \internal
80
81 QGList is a strictly internal class that acts as a base class for
82 several collection classes; QPtrList, QPtrQueue and QPtrStack.
83
84 QGList has some virtual functions that can be reimplemented to
85 customize the subclasses, namely compareItems(), read() and
86 write. Normally, you do not have to reimplement any of these
87 functions. If you still want to reimplement them, see the QStrList
88 class (qstrlist.h) for an example.
89*/
90
91
92/* Internal helper class for QGList. Contains some optimization for
93 the typically case where only one iterators is activre on the list.
94 */
95class QGListIteratorList
96{
97public:
98 QGListIteratorList()
99 : list(0), iterator(0) {
100 }
101 ~QGListIteratorList() {
102 notifyClear( TRUE );
103 delete list;
104 }
105
106 void add( QGListIterator* i ) {
107 if ( !iterator ) {
108 iterator = i;
109 } else if ( list ) {
110 list->push_front( i );
111 } else {
112 list = new QValueList<QGListIterator*>;
113 list->push_front( i );
114 }
115 }
116
117 void remove( QGListIterator* i ) {
118 if ( iterator == i ) {
119 iterator = 0;
120 } else if ( list ) {
121 list->remove( i );
122 if ( list->isEmpty() ) {
123 delete list;
124 list = 0;
125 }
126 }
127 }
128
129 void notifyClear( bool zeroList ) {
130 if ( iterator ) {
131 if ( zeroList )
132 iterator->list = 0;
133 iterator->curNode = 0;
134 }
135 if ( list ) {
136 for ( QValueList<QGListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) {
137 if ( zeroList )
138 (*i)->list = 0;
139 (*i)->curNode = 0;
140 }
141 }
142 }
143
144 void notifyRemove( QLNode* n, QLNode* curNode ) {
145 if ( iterator ) {
146 if ( iterator->curNode == n )
147 iterator->curNode = curNode;
148 }
149 if ( list ) {
150 for ( QValueList<QGListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) {
151 if ( (*i)->curNode == n )
152 (*i)->curNode = curNode;
153 }
154 }
155 }
156
157private:
158 QValueList<QGListIterator*>* list;
159 QGListIterator* iterator;
160};
161
162
163
164/*****************************************************************************
165 Default implementation of virtual functions
166 *****************************************************************************/
167
168/*!
169 Documented as QPtrList::compareItems().
170
171 Compares \a item1 with \a item2.
172*/
173int QGList::compareItems( QPtrCollection::Item item1, QPtrCollection::Item item2 )
174{
175 return item1 != item2; // compare pointers
176}
177
178#ifndef QT_NO_DATASTREAM
179/*!
180 \overload
181 Reads a collection/list item from the stream \a s and returns a reference
182 to the stream.
183
184 The default implementation sets \a item to 0.
185
186 \sa write()
187*/
188
189QDataStream &QGList::read( QDataStream &s, QPtrCollection::Item &item )
190{
191 item = 0;
192 return s;
193}
194
195/*!
196 \overload
197 Writes a collection/list item to the stream \a s and
198 returns a reference to the stream.
199
200 The default implementation does nothing.
201
202 \sa read()
203*/
204
205QDataStream &QGList::write( QDataStream &s, QPtrCollection::Item ) const
206{
207 return s;
208}
209#endif // QT_NO_DATASTREAM
210
211/*****************************************************************************
212 QGList member functions
213 *****************************************************************************/
214
215/*!
216 Constructs an empty list.
217*/
218
219QGList::QGList()
220{
221 firstNode = lastNode = curNode = 0; // initialize list
222 numNodes = 0;
223 curIndex = -1;
224 iterators = 0; // initialize iterator list
225}
226
227/*!
228 Constructs a copy of \a list.
229*/
230
231QGList::QGList( const QGList & list )
232 : QPtrCollection( list )
233{
234 firstNode = lastNode = curNode = 0; // initialize list
235 numNodes = 0;
236 curIndex = -1;
237 iterators = 0; // initialize iterator list
238 QLNode *n = list.firstNode;
239 while ( n ) { // copy all items from list
240 append( n->data );
241 n = n->next;
242 }
243}
244
245/*!
246 Removes all items from the list and destroys the list.
247*/
248
249QGList::~QGList()
250{
251 clear();
252 delete iterators;
253 // Workaround for GCC 2.7.* bug. Compiler constructs 'static' QGList
254 // instances twice on the same address and therefore tries to destruct
255 // twice on the same address! This is insane but let's try not to crash
256 // here.
257 iterators = 0;
258}
259
260
261/*!
262 Assigns \a list to this list.
263*/
264
265QGList& QGList::operator=( const QGList &list )
266{
267 if ( &list == this )
268 return *this;
269
270 clear();
271 if ( list.count() > 0 ) {
272 QLNode *n = list.firstNode;
273 while ( n ) { // copy all items from list
274 append( n->data );
275 n = n->next;
276 }
277 curNode = firstNode;
278 curIndex = 0;
279 }
280 return *this;
281}
282
283/*!
284 Compares this list with \a list. Returns TRUE if the lists
285 contain the same data, otherwise FALSE.
286*/
287
288bool QGList::operator==( const QGList &list ) const
289{
290 if ( count() != list.count() )
291 return FALSE;
292
293 if ( count() == 0 )
294 return TRUE;
295
296 QLNode *n1 = firstNode;
297 QLNode *n2 = list.firstNode;
298 while ( n1 && n2 ) {
299 // should be mutable
300 if ( ( (QGList*)this )->compareItems( n1->data, n2->data ) != 0 )
301 return FALSE;
302 n1 = n1->next;
303 n2 = n2->next;
304 }
305
306 return TRUE;
307}
308
309/*!
310 \fn uint QGList::count() const
311
312 Returns the number of items in the list.
313*/
314
315
316/*!
317 Returns the node at position \a index. Sets this node to current.
318*/
319
320QLNode *QGList::locate( uint index )
321{
322 if ( index == (uint)curIndex ) // current node ?
323 return curNode;
324 if ( !curNode && firstNode ) { // set current node
325 curNode = firstNode;
326 curIndex = 0;
327 }
328 register QLNode *node;
329 int distance = index - curIndex; // node distance to cur node
330 bool forward; // direction to traverse
331
332 if ( index >= numNodes )
333 return 0;
334
335 if ( distance < 0 )
336 distance = -distance;
337 if ( (uint)distance < index && (uint)distance < numNodes - index ) {
338 node = curNode; // start from current node
339 forward = index > (uint)curIndex;
340 } else if ( index < numNodes - index ) { // start from first node
341 node = firstNode;
342 distance = index;
343 forward = TRUE;
344 } else { // start from last node
345 node = lastNode;
346 distance = numNodes - index - 1;
347 if ( distance < 0 )
348 distance = 0;
349 forward = FALSE;
350 }
351 if ( forward ) { // now run through nodes
352 while ( distance-- )
353 node = node->next;
354 } else {
355 while ( distance-- )
356 node = node->prev;
357 }
358 curIndex = index; // must update index
359 return curNode = node;
360}
361
362
363/*!
364 Inserts item \a d at its sorted position in the list.
365*/
366
367void QGList::inSort( QPtrCollection::Item d )
368{
369 int index = 0;
370 register QLNode *n = firstNode;
371 while ( n && compareItems(n->data,d) < 0 ){ // find position in list
372 n = n->next;
373 index++;
374 }
375 insertAt( index, d );
376}
377
378
379/*!
380 Inserts item \a d at the start of the list.
381*/
382
383void QGList::prepend( QPtrCollection::Item d )
384{
385 register QLNode *n = new QLNode( newItem(d) );
386 Q_CHECK_PTR( n );
387 n->prev = 0;
388 if ( (n->next = firstNode) ) // list is not empty
389 firstNode->prev = n;
390 else // initialize list
391 lastNode = n;
392 firstNode = curNode = n; // curNode affected
393 numNodes++;
394 curIndex = 0;
395}
396
397
398/*!
399 Inserts item \a d at the end of the list.
400*/
401
402void QGList::append( QPtrCollection::Item d )
403{
404 register QLNode *n = new QLNode( newItem(d) );
405 Q_CHECK_PTR( n );
406 n->next = 0;
407 if ( (n->prev = lastNode) ) // list is not empty
408 lastNode->next = n;
409 else // initialize list
410 firstNode = n;
411 lastNode = curNode = n; // curNode affected
412 curIndex = numNodes;
413 numNodes++;
414}
415
416
417/*!
418 Inserts item \a d at position \a index in the list.
419*/
420
421bool QGList::insertAt( uint index, QPtrCollection::Item d )
422{
423 if ( index == 0 ) {
424 prepend( d );
425 return TRUE;
426 } else if ( index == numNodes ) {
427 append( d );
428 return TRUE;
429 }
430 QLNode *nextNode = locate( index );
431 if ( !nextNode )
432 return FALSE;
433 QLNode *prevNode = nextNode->prev;
434 register QLNode *n = new QLNode( newItem(d) );
435 Q_CHECK_PTR( n );
436 nextNode->prev = n;
437 prevNode->next = n;
438 n->prev = prevNode; // link new node into list
439 n->next = nextNode;
440 curNode = n; // curIndex set by locate()
441 numNodes++;
442 return TRUE;
443}
444
445
446/*!
447 Relinks node \a n and makes it the first node in the list.
448*/
449
450void QGList::relinkNode( QLNode *n )
451{
452 if ( n == firstNode ) // already first
453 return;
454 curNode = n;
455 unlink();
456 n->prev = 0;
457 if ( (n->next = firstNode) ) // list is not empty
458 firstNode->prev = n;
459 else // initialize list
460 lastNode = n;
461 firstNode = curNode = n; // curNode affected
462 numNodes++;
463 curIndex = 0;
464}
465
466
467/*!
468 Unlinks the current list node and returns a pointer to this node.
469*/
470
471QLNode *QGList::unlink()
472{
473 if ( curNode == 0 ) // null current node
474 return 0;
475 register QLNode *n = curNode; // unlink this node
476 if ( n == firstNode ) { // removing first node ?
477 if ( (firstNode = n->next) ) {
478 firstNode->prev = 0;
479 } else {
480 lastNode = curNode = 0; // list becomes empty
481 curIndex = -1;
482 }
483 } else {
484 if ( n == lastNode ) { // removing last node ?
485 lastNode = n->prev;
486 lastNode->next = 0;
487 } else { // neither last nor first node
488 n->prev->next = n->next;
489 n->next->prev = n->prev;
490 }
491 }
492
493 if ( n->next ) { // change current node
494 curNode = n->next;
495 } else if ( n->prev ) {
496 curNode = n->prev;
497 curIndex--;
498 }
499
500 if ( iterators )
501 iterators->notifyRemove( n, curNode );
502 numNodes--;
503 return n;
504}
505
506
507/*!
508 Removes the node \a n from the list.
509*/
510
511bool QGList::removeNode( QLNode *n )
512{
513#if defined(QT_CHECK_NULL)
514 if ( n == 0 || (n->prev && n->prev->next != n) ||
515 (n->next && n->next->prev != n) ) {
516 qWarning( "QGList::removeNode: Corrupted node" );
517 return FALSE;
518 }
519#endif
520 curNode = n;
521 unlink(); // unlink node
522 deleteItem( n->data ); // deallocate this node
523 delete n;
524 curNode = firstNode;
525 curIndex = curNode ? 0 : -1;
526 return TRUE;
527}
528
529/*!
530 Removes the item \a d from the list. Uses compareItems() to find the item.
531
532 If \a d is 0, removes the current item.
533*/
534
535bool QGList::remove( QPtrCollection::Item d )
536{
537 if ( d && find(d) == -1 )
538 return FALSE;
539 QLNode *n = unlink();
540 if ( !n )
541 return FALSE;
542 deleteItem( n->data );
543 delete n;
544 return TRUE;
545}
546
547/*!
548 Removes the item \a d from the list.
549*/
550
551bool QGList::removeRef( QPtrCollection::Item d )
552{
553 if ( findRef(d) == -1 )
554 return FALSE;
555 QLNode *n = unlink();
556 if ( !n )
557 return FALSE;
558 deleteItem( n->data );
559 delete n;
560 return TRUE;
561}
562
563/*!
564 \fn bool QGList::removeFirst()
565
566 Removes the first item in the list.
567*/
568
569/*!
570 \fn bool QGList::removeLast()
571
572 Removes the last item in the list.
573*/
574
575/*!
576 Removes the item at position \a index from the list.
577*/
578
579bool QGList::removeAt( uint index )
580{
581 if ( !locate(index) )
582 return FALSE;
583 QLNode *n = unlink();
584 if ( !n )
585 return FALSE;
586 deleteItem( n->data );
587 delete n;
588 return TRUE;
589}
590
591
592/*!
593 Replaces the item at index \a index with \a d.
594*/
595bool QGList::replaceAt( uint index, QPtrCollection::Item d )
596{
597 QLNode *n = locate( index );
598 if ( !n )
599 return FALSE;
600 if ( n->data != d ) {
601 deleteItem( n->data );
602 n->data = newItem( d );
603 }
604 return TRUE;
605}
606
607
608
609/*!
610 Takes the node \a n out of the list.
611*/
612
613QPtrCollection::Item QGList::takeNode( QLNode *n )
614{
615#if defined(QT_CHECK_NULL)
616 if ( n == 0 || (n->prev && n->prev->next != n) ||
617 (n->next && n->next->prev != n) ) {
618 qWarning( "QGList::takeNode: Corrupted node" );
619 return 0;
620 }
621#endif
622 curNode = n;
623 unlink(); // unlink node
624 Item d = n->data;
625 delete n; // delete the node, not data
626 curNode = firstNode;
627 curIndex = curNode ? 0 : -1;
628 return d;
629}
630
631/*!
632 Takes the current item out of the list.
633*/
634
635QPtrCollection::Item QGList::take()
636{
637 QLNode *n = unlink(); // unlink node
638 Item d = n ? n->data : 0;
639 delete n; // delete node, keep contents
640 return d;
641}
642
643/*!
644 Takes the item at position \a index out of the list.
645*/
646
647QPtrCollection::Item QGList::takeAt( uint index )
648{
649 if ( !locate(index) )
650 return 0;
651 QLNode *n = unlink(); // unlink node
652 Item d = n ? n->data : 0;
653 delete n; // delete node, keep contents
654 return d;
655}
656
657/*!
658 Takes the first item out of the list.
659*/
660
661QPtrCollection::Item QGList::takeFirst()
662{
663 first();
664 QLNode *n = unlink(); // unlink node
665 Item d = n ? n->data : 0;
666 delete n;
667 return d;
668}
669
670/*!
671 Takes the last item out of the list.
672*/
673
674QPtrCollection::Item QGList::takeLast()
675{
676 last();
677 QLNode *n = unlink(); // unlink node
678 Item d = n ? n->data : 0;
679 delete n;
680 return d;
681}
682
683
684/*!
685 Removes all items from the list.
686*/
687
688void QGList::clear()
689{
690 register QLNode *n = firstNode;
691
692 firstNode = lastNode = curNode = 0; // initialize list
693 numNodes = 0;
694 curIndex = -1;
695
696 if ( iterators )
697 iterators->notifyClear( FALSE );
698
699 QLNode *prevNode;
700 while ( n ) { // for all nodes ...
701 deleteItem( n->data ); // deallocate data
702 prevNode = n;
703 n = n->next;
704 delete prevNode; // deallocate node
705 }
706}
707
708
709/*!
710 Finds item \a d in the list. If \a fromStart is TRUE the search
711 begins at the first node; otherwise it begins at the current node.
712*/
713
714int QGList::findRef( QPtrCollection::Item d, bool fromStart )
715{
716 register QLNode *n;
717 int index;
718 if ( fromStart ) { // start from first node
719 n = firstNode;
720 index = 0;
721 } else { // start from current node
722 n = curNode;
723 index = curIndex;
724 }
725 while ( n && n->data != d ) { // find exact match
726 n = n->next;
727 index++;
728 }
729 curNode = n;
730 curIndex = n ? index : -1;
731 return curIndex; // return position of item
732}
733
734/*!
735 Finds item \a d in the list using compareItems(). If \a fromStart is
736 TRUE the search begins at the first node; otherwise it begins at the
737 current node.
738*/
739
740int QGList::find( QPtrCollection::Item d, bool fromStart )
741{
742 register QLNode *n;
743 int index;
744 if ( fromStart ) { // start from first node
745 n = firstNode;
746 index = 0;
747 } else { // start from current node
748 n = curNode;
749 index = curIndex;
750 }
751 while ( n && compareItems(n->data,d) ){ // find equal match
752 n = n->next;
753 index++;
754 }
755 curNode = n;
756 curIndex = n ? index : -1;
757 return curIndex; // return position of item
758}
759
760
761/*!
762 Counts the number item \a d occurs in the list.
763*/
764
765uint QGList::containsRef( QPtrCollection::Item d ) const
766{
767 register QLNode *n = firstNode;
768 uint count = 0;
769 while ( n ) { // for all nodes...
770 if ( n->data == d ) // count # exact matches
771 count++;
772 n = n->next;
773 }
774 return count;
775}
776
777/*!
778 Counts the number of times item \a d occurs in the list. Uses
779 compareItems().
780*/
781
782uint QGList::contains( QPtrCollection::Item d ) const
783{
784 register QLNode *n = firstNode;
785 uint count = 0;
786 QGList *that = (QGList*)this; // mutable for compareItems()
787 while ( n ) { // for all nodes...
788 if ( !that->compareItems(n->data,d) ) // count # equal matches
789 count++;
790 n = n->next;
791 }
792 return count;
793}
794
795
796/*!
797 \overload QPtrCollection::Item QGList::at( uint index )
798
799 Sets the item at position \a index to the current item.
800*/
801
802/*!
803 \fn int QGList::at() const
804
805 Returns the current index.
806*/
807
808/*!
809 \fn QLNode *QGList::currentNode() const
810
811 Returns the current node.
812*/
813
814/*!
815 \fn QPtrCollection::Item QGList::get() const
816
817 Returns the current item.
818*/
819
820/*!
821 \fn QPtrCollection::Item QGList::cfirst() const
822
823 Returns the first item in the list.
824*/
825
826/*!
827 \fn QPtrCollection::Item QGList::clast() const
828
829 Returns the last item in the list.
830*/
831
832
833/*!
834 Returns the first list item. Sets this to current.
835*/
836
837QPtrCollection::Item QGList::first()
838{
839 if ( firstNode ) {
840 curIndex = 0;
841 return (curNode=firstNode)->data;
842 }
843 return 0;
844}
845
846/*!
847 Returns the last list item. Sets this to current.
848*/
849
850QPtrCollection::Item QGList::last()
851{
852 if ( lastNode ) {
853 curIndex = numNodes-1;
854 return (curNode=lastNode)->data;
855 }
856 return 0;
857}
858
859/*!
860 Returns the next list item (after current). Sets this to current.
861*/
862
863QPtrCollection::Item QGList::next()
864{
865 if ( curNode ) {
866 if ( curNode->next ) {
867 curIndex++;
868 curNode = curNode->next;
869 return curNode->data;
870 }
871 curIndex = -1;
872 curNode = 0;
873 }
874 return 0;
875}
876
877/*!
878 Returns the previous list item (before current). Sets this to current.
879*/
880
881QPtrCollection::Item QGList::prev()
882{
883 if ( curNode ) {
884 if ( curNode->prev ) {
885 curIndex--;
886 curNode = curNode->prev;
887 return curNode->data;
888 }
889 curIndex = -1;
890 curNode = 0;
891 }
892 return 0;
893}
894
895
896/*!
897 Converts the list to a vector, \a vector.
898*/
899
900void QGList::toVector( QGVector *vector ) const
901{
902 vector->clear();
903 if ( !vector->resize( count() ) )
904 return;
905 register QLNode *n = firstNode;
906 uint i = 0;
907 while ( n ) {
908 vector->insert( i, n->data );
909 n = n->next;
910 i++;
911 }
912}
913
914void QGList::heapSortPushDown( QPtrCollection::Item* heap, int first, int last )
915{
916 int r = first;
917 while( r <= last/2 ) {
918 // Node r has only one child ?
919 if ( last == 2*r ) {
920 // Need for swapping ?
921 if ( compareItems( heap[r], heap[ 2*r ] ) > 0 ) {
922 QPtrCollection::Item tmp = heap[r];
923 heap[ r ] = heap[ 2*r ];
924 heap[ 2*r ] = tmp;
925 }
926 // That's it ...
927 r = last;
928 } else {
929 // Node has two children
930 if ( compareItems( heap[r], heap[ 2*r ] ) > 0 &&
931 compareItems( heap[ 2*r ], heap[ 2*r+1 ] ) <= 0 ) {
932 // Swap with left child
933 QPtrCollection::Item tmp = heap[r];
934 heap[ r ] = heap[ 2*r ];
935 heap[ 2*r ] = tmp;
936 r *= 2;
937 } else if ( compareItems( heap[r], heap[ 2*r+1 ] ) > 0 &&
938 compareItems( heap[ 2*r+1 ], heap[ 2*r ] ) < 0 ) {
939 // Swap with right child
940 QPtrCollection::Item tmp = heap[r];
941 heap[ r ] = heap[ 2*r+1 ];
942 heap[ 2*r+1 ] = tmp;
943 r = 2*r+1;
944 } else {
945 // We are done
946 r = last;
947 }
948 }
949 }
950}
951
952
953/*! Sorts the list by the result of the virtual compareItems() function.
954
955 The Heap-Sort algorithm is used for sorting. It sorts n items with
956 O(n*log n) compares. This is the asymptotic optimal solution of the
957 sorting problem.
958*/
959
960void QGList::sort()
961{
962 uint n = count();
963 if ( n < 2 )
964 return;
965
966 // Create the heap
967 QPtrCollection::Item* realheap = new QPtrCollection::Item[ n ];
968 // Wow, what a fake. But I want the heap to be indexed as 1...n
969 QPtrCollection::Item* heap = realheap - 1;
970 int size = 0;
971 QLNode* insert = firstNode;
972 for( ; insert != 0; insert = insert->next ) {
973 heap[++size] = insert->data;
974 int i = size;
975 while( i > 1 && compareItems( heap[i], heap[ i / 2 ] ) < 0 ) {
976 QPtrCollection::Item tmp = heap[ i ];
977 heap[ i ] = heap[ i/2 ];
978 heap[ i/2 ] = tmp;
979 i /= 2;
980 }
981 }
982
983 insert = firstNode;
984 // Now do the sorting
985 for ( int i = n; i > 0; i-- ) {
986 insert->data = heap[1];
987 insert = insert->next;
988 if ( i > 1 ) {
989 heap[1] = heap[i];
990 heapSortPushDown( heap, 1, i - 1 );
991 }
992 }
993
994 delete [] realheap;
995}
996
997
998/*****************************************************************************
999 QGList stream functions
1000 *****************************************************************************/
1001
1002#ifndef QT_NO_DATASTREAM
1003QDataStream &operator>>( QDataStream &s, QGList &list )
1004{ // read list
1005 return list.read( s );
1006}
1007
1008QDataStream &operator<<( QDataStream &s, const QGList &list )
1009{ // write list
1010 return list.write( s );
1011}
1012
1013/*!
1014 Reads a list from the stream \a s.
1015*/
1016
1017QDataStream &QGList::read( QDataStream &s )
1018{
1019 uint num;
1020 s >> num; // read number of items
1021 clear(); // clear list
1022 while ( num-- ) { // read all items
1023 Item d;
1024 read( s, d );
1025 Q_CHECK_PTR( d );
1026 if ( !d ) // no memory
1027 break;
1028 QLNode *n = new QLNode( d );
1029 Q_CHECK_PTR( n );
1030 if ( !n ) // no memory
1031 break;
1032 n->next = 0;
1033 if ( (n->prev = lastNode) ) // list is not empty
1034 lastNode->next = n;
1035 else // initialize list
1036 firstNode = n;
1037 lastNode = n;
1038 numNodes++;
1039 }
1040 curNode = firstNode;
1041 curIndex = curNode ? 0 : -1;
1042 return s;
1043}
1044
1045/*!
1046 Writes the list to the stream \a s.
1047*/
1048
1049QDataStream &QGList::write( QDataStream &s ) const
1050{
1051 s << count(); // write number of items
1052 QLNode *n = firstNode;
1053 while ( n ) { // write all items
1054 write( s, n->data );
1055 n = n->next;
1056 }
1057 return s;
1058}
1059
1060#endif // QT_NO_DATASTREAM
1061
1062
1063
1064/*! \internal
1065 */
1066QLNode* QGList::erase( QLNode* it )
1067{
1068 QLNode* n = it;
1069 it = it->next;
1070 removeNode( n );
1071 return it;
1072}
1073
1074
1075/*****************************************************************************
1076 QGListIterator member functions
1077 *****************************************************************************/
1078
1079/*!
1080 \class QGListIterator qglist.h
1081 \reentrant
1082 \ingroup collection
1083 \brief The QGListIterator class is an internal class for implementing QPtrListIterator.
1084
1085 \internal
1086
1087 QGListIterator is a strictly internal class that does the heavy work for
1088 QPtrListIterator.
1089*/
1090
1091/*!
1092 \internal
1093 Constructs an iterator that operates on the list \a l.
1094*/
1095
1096QGListIterator::QGListIterator( const QGList &l )
1097{
1098 list = (QGList *)&l; // get reference to list
1099 curNode = list->firstNode; // set to first node
1100 if ( !list->iterators ) {
1101 list->iterators = new QGListIteratorList; // create iterator list
1102 Q_CHECK_PTR( list->iterators );
1103 }
1104 list->iterators->add( this ); // attach iterator to list
1105}
1106
1107/*!
1108 \internal
1109 Constructs a copy of the iterator \a it.
1110*/
1111
1112QGListIterator::QGListIterator( const QGListIterator &it )
1113{
1114 list = it.list;
1115 curNode = it.curNode;
1116 if ( list )
1117 list->iterators->add( this ); // attach iterator to list
1118}
1119
1120/*!
1121 \internal
1122 Assigns a copy of the iterator \a it and returns a reference to this
1123 iterator.
1124*/
1125
1126QGListIterator &QGListIterator::operator=( const QGListIterator &it )
1127{
1128 if ( list ) // detach from old list
1129 list->iterators->remove( this );
1130 list = it.list;
1131 curNode = it.curNode;
1132 if ( list )
1133 list->iterators->add( this ); // attach to new list
1134 return *this;
1135}
1136
1137/*!
1138 \internal
1139 Destroys the iterator.
1140*/
1141
1142QGListIterator::~QGListIterator()
1143{
1144 if ( list ) // detach iterator from list
1145 list->iterators->remove(this);
1146}
1147
1148
1149/*!
1150 \fn bool QGListIterator::atFirst() const
1151 \internal
1152 Returns TRUE if the iterator points to the first item, otherwise FALSE.
1153*/
1154
1155/*!
1156 \fn bool QGListIterator::atLast() const
1157 \internal
1158 Returns TRUE if the iterator points to the last item, otherwise FALSE.
1159*/
1160
1161
1162/*!
1163 \internal
1164 Sets the list iterator to point to the first item in the list.
1165*/
1166
1167QPtrCollection::Item QGListIterator::toFirst()
1168{
1169 if ( !list ) {
1170#if defined(QT_CHECK_NULL)
1171 qWarning( "QGListIterator::toFirst: List has been deleted" );
1172#endif
1173 return 0;
1174 }
1175 return list->firstNode ? (curNode = list->firstNode)->getData() : 0;
1176}
1177
1178/*!
1179 \internal
1180 Sets the list iterator to point to the last item in the list.
1181*/
1182
1183QPtrCollection::Item QGListIterator::toLast()
1184{
1185 if ( !list ) {
1186#if defined(QT_CHECK_NULL)
1187 qWarning( "QGListIterator::toLast: List has been deleted" );
1188#endif
1189 return 0;
1190 }
1191 return list->lastNode ? (curNode = list->lastNode)->getData() : 0;
1192}
1193
1194
1195/*!
1196 \fn QPtrCollection::Item QGListIterator::get() const
1197 \internal
1198 Returns the iterator item.
1199*/
1200
1201
1202/*!
1203 \internal
1204 Moves to the next item (postfix).
1205*/
1206
1207QPtrCollection::Item QGListIterator::operator()()
1208{
1209 if ( !curNode )
1210 return 0;
1211 QPtrCollection::Item d = curNode->getData();
1212 curNode = curNode->next;
1213 return d;
1214}
1215
1216/*!
1217 \internal
1218 Moves to the next item (prefix).
1219*/
1220
1221QPtrCollection::Item QGListIterator::operator++()
1222{
1223 if ( !curNode )
1224 return 0;
1225 curNode = curNode->next;
1226 return curNode ? curNode->getData() : 0;
1227}
1228
1229/*!
1230 \internal
1231 Moves \a jumps positions forward.
1232*/
1233
1234QPtrCollection::Item QGListIterator::operator+=( uint jumps )
1235{
1236 while ( curNode && jumps-- )
1237 curNode = curNode->next;
1238 return curNode ? curNode->getData() : 0;
1239}
1240
1241/*!
1242 \internal
1243 Moves to the previous item (prefix).
1244*/
1245
1246QPtrCollection::Item QGListIterator::operator--()
1247{
1248 if ( !curNode )
1249 return 0;
1250 curNode = curNode->prev;
1251 return curNode ? curNode->getData() : 0;
1252}
1253
1254/*!
1255 \internal
1256 Moves \a jumps positions backward.
1257*/
1258
1259QPtrCollection::Item QGListIterator::operator-=( uint jumps )
1260{
1261 while ( curNode && jumps-- )
1262 curNode = curNode->prev;
1263 return curNode ? curNode->getData() : 0;
1264}
Note: See TracBrowser for help on using the repository browser.