source: trunk/src/qt3support/tools/q3glist.cpp@ 595

Last change on this file since 595 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 26.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the Qt3Support module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "q3glist.h"
43#include "q3gvector.h"
44#include "qdatastream.h"
45#include "q3valuelist.h"
46
47QT_BEGIN_NAMESPACE
48
49/*!
50 \class Q3LNode
51 \reentrant
52 \brief The Q3LNode class is an internal class for the Q3PtrList template collection.
53
54 \internal
55
56 Q3LNode is a doubly-linked list node. It has three pointers:
57 \list 1
58 \i Pointer to the previous node.
59 \i Pointer to the next node.
60 \i Pointer to the actual data.
61 \endlist
62
63 It might sometimes be practical to have direct access to the list nodes
64 in a Q3PtrList, but it is seldom required.
65
66 Be very careful if you want to access the list nodes. The heap can
67 easily get corrupted if you make a mistake.
68
69 \sa Q3PtrList::currentNode(), Q3PtrList::removeNode(), Q3PtrList::takeNode()
70*/
71
72/*!
73 \fn Q3PtrCollection::Item Q3LNode::getData()
74 Returns a pointer (\c void*) to the actual data in the list node.
75*/
76
77
78/*!
79 \class Q3GList
80 \reentrant
81 \brief The Q3GList class is an internal class for implementing Qt collection classes.
82
83 \internal
84
85 Q3GList is a strictly internal class that acts as a base class for
86 several collection classes; Q3PtrList, Q3PtrQueue and Q3PtrStack.
87
88 Q3GList has some virtual functions that can be reimplemented to
89 customize the subclasses, namely compareItems(), read() and
90 write. Normally, you do not have to reimplement any of these
91 functions. If you still want to reimplement them, see the QStrList
92 class (qstrlist.h) for an example.
93*/
94
95
96/* Internal helper class for Q3GList. Contains some optimization for
97 the typically case where only one iterators is activre on the list.
98 */
99class Q3GListIteratorList
100{
101public:
102 Q3GListIteratorList()
103 : list(0), iterator(0) {
104 }
105 ~Q3GListIteratorList() {
106 notifyClear( true );
107 delete list;
108 }
109
110 void add( Q3GListIterator* i ) {
111 if ( !iterator ) {
112 iterator = i;
113 } else if ( list ) {
114 list->push_front( i );
115 } else {
116 list = new Q3ValueList<Q3GListIterator*>;
117 list->push_front( i );
118 }
119 }
120
121 void remove( Q3GListIterator* i ) {
122 if ( iterator == i ) {
123 iterator = 0;
124 } else if ( list ) {
125 list->remove( i );
126 if ( list->isEmpty() ) {
127 delete list;
128 list = 0;
129 }
130 }
131 }
132
133 void notifyClear( bool zeroList ) {
134 if ( iterator ) {
135 if ( zeroList )
136 iterator->list = 0;
137 iterator->curNode = 0;
138 }
139 if ( list ) {
140 for ( Q3ValueList<Q3GListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) {
141 if ( zeroList )
142 (*i)->list = 0;
143 (*i)->curNode = 0;
144 }
145 }
146 }
147
148 void notifyRemove( Q3LNode* n, Q3LNode* curNode ) {
149 if ( iterator ) {
150 if ( iterator->curNode == n )
151 iterator->curNode = curNode;
152 }
153 if ( list ) {
154 for ( Q3ValueList<Q3GListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) {
155 if ( (*i)->curNode == n )
156 (*i)->curNode = curNode;
157 }
158 }
159 }
160
161private:
162 Q3ValueList<Q3GListIterator*>* list;
163 Q3GListIterator* iterator;
164};
165
166
167
168/*****************************************************************************
169 Default implementation of virtual functions
170 *****************************************************************************/
171
172/*!
173 Documented as Q3PtrList::compareItems().
174
175 Compares \a item1 with \a item2.
176*/
177int Q3GList::compareItems( Q3PtrCollection::Item item1, Q3PtrCollection::Item item2 )
178{
179 return item1 != item2; // compare pointers
180}
181
182#ifndef QT_NO_DATASTREAM
183/*!
184 \overload
185 Reads a collection/list item from the stream \a s and returns a reference
186 to the stream.
187
188 The default implementation sets \a item to 0.
189
190 \sa write()
191*/
192
193QDataStream &Q3GList::read( QDataStream &s, Q3PtrCollection::Item &item )
194{
195 item = 0;
196 return s;
197}
198
199/*!
200 \overload
201 Writes a collection/list item to the stream \a s and
202 returns a reference to the stream.
203
204 The default implementation does nothing.
205
206 \sa read()
207*/
208
209QDataStream &Q3GList::write( QDataStream &s, Q3PtrCollection::Item ) const
210{
211 return s;
212}
213#endif // QT_NO_DATASTREAM
214
215/*****************************************************************************
216 Q3GList member functions
217 *****************************************************************************/
218
219/*!
220 Constructs an empty list.
221*/
222
223Q3GList::Q3GList()
224{
225 firstNode = lastNode = curNode = 0; // initialize list
226 numNodes = 0;
227 curIndex = -1;
228 iterators = 0; // initialize iterator list
229}
230
231/*!
232 Constructs a copy of \a list.
233*/
234
235Q3GList::Q3GList( const Q3GList & list )
236 : Q3PtrCollection( list )
237{
238 firstNode = lastNode = curNode = 0; // initialize list
239 numNodes = 0;
240 curIndex = -1;
241 iterators = 0; // initialize iterator list
242 Q3LNode *n = list.firstNode;
243 while ( n ) { // copy all items from list
244 append( n->data );
245 n = n->next;
246 }
247}
248
249/*!
250 Removes all items from the list and destroys the list.
251*/
252
253Q3GList::~Q3GList()
254{
255 clear();
256 delete iterators;
257 // Workaround for GCC 2.7.* bug. Compiler constructs 'static' Q3GList
258 // instances twice on the same address and therefore tries to destruct
259 // twice on the same address! This is insane but let's try not to crash
260 // here.
261 iterators = 0;
262}
263
264
265/*!
266 Assigns \a list to this list.
267*/
268
269Q3GList& Q3GList::operator=( const Q3GList &list )
270{
271 if ( &list == this )
272 return *this;
273
274 clear();
275 if ( list.count() > 0 ) {
276 Q3LNode *n = list.firstNode;
277 while ( n ) { // copy all items from list
278 append( n->data );
279 n = n->next;
280 }
281 curNode = firstNode;
282 curIndex = 0;
283 }
284 return *this;
285}
286
287/*!
288 Compares this list with \a list. Returns true if the lists
289 contain the same data, otherwise false.
290*/
291
292bool Q3GList::operator==( const Q3GList &list ) const
293{
294 if ( count() != list.count() )
295 return false;
296
297 if ( count() == 0 )
298 return true;
299
300 Q3LNode *n1 = firstNode;
301 Q3LNode *n2 = list.firstNode;
302 while ( n1 && n2 ) {
303 // should be mutable
304 if ( ( (Q3GList*)this )->compareItems( n1->data, n2->data ) != 0 )
305 return false;
306 n1 = n1->next;
307 n2 = n2->next;
308 }
309
310 return true;
311}
312
313/*!
314 \fn uint Q3GList::count() const
315
316 Returns the number of items in the list.
317*/
318
319
320/*!
321 Returns the node at position \a index. Sets this node to current.
322*/
323
324Q3LNode *Q3GList::locate( uint index )
325{
326 if ( index == (uint)curIndex ) // current node ?
327 return curNode;
328 if ( !curNode && firstNode ) { // set current node
329 curNode = firstNode;
330 curIndex = 0;
331 }
332 register Q3LNode *node;
333 int distance = index - curIndex; // node distance to cur node
334 bool forward; // direction to traverse
335
336 if ( index >= numNodes )
337 return 0;
338
339 if ( distance < 0 )
340 distance = -distance;
341 if ( (uint)distance < index && (uint)distance < numNodes - index ) {
342 node = curNode; // start from current node
343 forward = index > (uint)curIndex;
344 } else if ( index < numNodes - index ) { // start from first node