1 /****************************************************************************
4 ** Definition of QMap 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 **********************************************************************/
43 #include "qdatastream.h"
49 enum Color { Red, Black };
57 QMapNodeBase* minimum() {
58 QMapNodeBase* x = this;
64 QMapNodeBase* maximum() {
65 QMapNodeBase* x = this;
73 template <class K, class T>
74 struct QMapNode : public QMapNodeBase
76 QMapNode( const K& _key, const T& _data ) { data = _data; key = _key; }
77 QMapNode( const K& _key ) { key = _key; }
78 QMapNode( const QMapNode<K,T>& _n ) { key = _n.key; data = _n.data; }
85 template<class K, class T>
86 class Q_EXPORT QMapIterator
92 typedef QMapNode< K, T >* NodePtr;
102 QMapIterator() : node( 0 ) {}
103 QMapIterator( QMapNode<K,T>* p ) : node( p ) {}
104 QMapIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
106 bool operator==( const QMapIterator<K,T>& it ) const { return node == it.node; }
107 bool operator!=( const QMapIterator<K,T>& it ) const { return node != it.node; }
108 T& operator*() { return node->data; }
109 const T& operator*() const { return node->data; }
111 // Cannot have this - some compilers are too stupid
112 //T* operator->() const { return &(node->data); }
114 const K& key() const { return node->key; }
115 T& data() { return node->data; }
116 const T& data() const { return node->data; }
120 QMapNodeBase* tmp = node;
126 QMapNodeBase* y = tmp->parent;
127 while (tmp == y->right) {
139 QMapNodeBase* tmp = node;
140 if (tmp->color == QMapNodeBase::Red &&
141 tmp->parent->parent == tmp ) {
143 } else if (tmp->left != 0) {
144 QMapNodeBase* y = tmp->left;
149 QMapNodeBase* y = tmp->parent;
150 while (tmp == y->left) {
161 QMapIterator<K,T>& operator++() {
166 QMapIterator<K,T> operator++(int) {
167 QMapIterator<K,T> tmp = *this;
172 QMapIterator<K,T>& operator--() {
177 QMapIterator<K,T> operator--(int) {
178 QMapIterator<K,T> tmp = *this;
184 template<class K, class T>
185 class Q_EXPORT QMapConstIterator
191 typedef QMapNode< K, T >* NodePtr;
201 QMapConstIterator() : node( 0 ) {}
202 QMapConstIterator( QMapNode<K,T>* p ) : node( p ) {}
203 QMapConstIterator( const QMapConstIterator<K,T>& it ) : node( it.node ) {}
204 QMapConstIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
206 bool operator==( const QMapConstIterator<K,T>& it ) const { return node == it.node; }
207 bool operator!=( const QMapConstIterator<K,T>& it ) const { return node != it.node; }
208 const T& operator*() const { return node->data; }
210 // Cannot have this - some compilers are too stupid
211 //const T* operator->() const { return &(node->data); }
213 const K& key() const { return node->key; }
214 const T& data() const { return node->data; }
218 QMapNodeBase* tmp = node;
224 QMapNodeBase* y = tmp->parent;
225 while (tmp == y->right) {
237 QMapNodeBase* tmp = node;
238 if (tmp->color == QMapNodeBase::Red &&
239 tmp->parent->parent == tmp ) {
241 } else if (tmp->left != 0) {
242 QMapNodeBase* y = tmp->left;
247 QMapNodeBase* y = tmp->parent;
248 while (tmp == y->left) {
259 QMapConstIterator<K,T>& operator++() {
264 QMapConstIterator<K,T> operator++(int) {
265 QMapConstIterator<K,T> tmp = *this;
270 QMapConstIterator<K,T>& operator--() {
275 QMapConstIterator<K,T> operator--(int) {
276 QMapConstIterator<K,T> tmp = *this;
283 class Q_EXPORT QMapPrivateBase : public QShared
289 QMapPrivateBase( const QMapPrivateBase* _map) {
290 node_count = _map->node_count;
294 * Implementations of basic tree algorithms
296 void rotateLeft( QMapNodeBase* x, QMapNodeBase*& root);
297 void rotateRight( QMapNodeBase* x, QMapNodeBase*& root );
298 void rebalance( QMapNodeBase* x, QMapNodeBase*& root );
299 QMapNodeBase* removeAndRebalance( QMapNodeBase* z, QMapNodeBase*& root,
300 QMapNodeBase*& leftmost,
301 QMapNodeBase*& rightmost );
310 template <class Key, class T>
311 class QMapPrivate : public QMapPrivateBase
317 typedef QMapIterator< Key, T > Iterator;
318 typedef QMapConstIterator< Key, T > ConstIterator;
319 typedef QMapNode< Key, T > Node;
320 typedef QMapNode< Key, T >* NodePtr;
327 header->color = QMapNodeBase::Red; // Mark the header
329 header->left = header->right = header;
331 QMapPrivate( const QMapPrivate< Key, T >* _map ) : QMapPrivateBase( _map ) {
333 header->color = QMapNodeBase::Red; // Mark the header
334 if ( _map->header->parent == 0 ) {
336 header->left = header->right = header;
338 header->parent = copy( (NodePtr)(_map->header->parent) );
339 header->parent->parent = header;
340 header->left = header->parent->minimum();
341 header->right = header->parent->maximum();
344 ~QMapPrivate() { clear(); delete header; }
346 NodePtr copy( NodePtr p ) {
349 NodePtr n = new Node( *p );
352 n->left = copy( (NodePtr)(p->left) );
358 n->right = copy( (NodePtr)(p->right) );
359 n->right->parent = n;
367 clear( (NodePtr)(header->parent) );
368 header->color = QMapNodeBase::Red;
370 header->left = header->right = header;
374 void clear( NodePtr p ) {
376 clear( (NodePtr)p->right );
377 NodePtr y = (NodePtr)p->left;
383 Iterator begin() { return Iterator( (NodePtr)(header->left ) ); }
384 Iterator end() { return Iterator( header ); }
385 ConstIterator begin() const { return ConstIterator( (NodePtr)(header->left ) ); }
386 ConstIterator end() const { return ConstIterator( header ); }
388 ConstIterator find(const Key& k) const {
389 QMapNodeBase* y = header; // Last node
390 QMapNodeBase* x = header->parent; // Root node.
393 // If as k <= key(x) go left
394 if ( !( key(x) < k ) ) {
402 // Was k bigger/smaller then the biggest/smallest
403 // element of the tree ? Return end()
404 if ( y == header || k < key(y) )
405 return ConstIterator( header );
406 return ConstIterator( (NodePtr)y );
409 void remove( Iterator it ) {
410 NodePtr del = (NodePtr) removeAndRebalance( it.node, header->parent, header->left, header->right );
416 void inorder( QMapNodeBase* x = 0, int level = 0 ){
420 inorder( x->left, level + 1 );
421 //cout << level << " Key=" << key(x) << " Value=" << ((NodePtr)x)->data << endl;
423 inorder( x->right, level + 1 );
427 Iterator insertMulti(const Key& v){
428 QMapNodeBase* y = header;
429 QMapNodeBase* x = header->parent;
432 x = ( v < key(x) ) ? x->left : x->right;
434 return insert(x, y, v);
437 Iterator insertSingle( const Key& k ) {
438 // Search correct position in the tree
439 QMapNodeBase* y = header;
440 QMapNodeBase* x = header->parent;
443 result = ( k < key(x) );
445 x = result ? x->left : x->right;
447 // Get iterator on the last not empty one
448 Iterator j( (NodePtr)y );
450 // Smaller then the leftmost one ?
451 if ( j == begin() ) {
452 return insert(x, y, k );
454 // Perhaps daddy is the right one ?
459 if ( (j.node->key) < k )
460 return insert(x, y, k );
461 // We are going to replace a node
465 Iterator insert( QMapNodeBase* x, QMapNodeBase* y, const Key& k ) {
466 NodePtr z = new Node( k );
467 if (y == header || x != 0 || k < key(y) ) {
468 y->left = z; // also makes leftmost = z when y == header
472 } else if ( y == header->left )
473 header->left = z; // maintain leftmost pointing to min node
476 if ( y == header->right )
477 header->right = z; // maintain rightmost pointing to max node
482 rebalance( z, header->parent );
491 const Key& key( QMapNodeBase* b ) const { return ((NodePtr)b)->key; }
500 template<class Key, class T>
507 typedef QMapIterator< Key, T > Iterator;
508 typedef QMapConstIterator< Key, T > ConstIterator;
510 typedef QMapPrivate< Key, T > Priv;
515 QMap() { sh = new QMapPrivate< Key, T >; }
516 QMap( const QMap<Key,T>& m ) { sh = m.sh; sh->ref(); }
517 ~QMap() { if ( sh->deref() ) delete sh; }
519 QMap<Key,T>& operator= ( const QMap<Key,T>& m )
520 { m.sh->ref(); if ( sh->deref() ) delete sh; sh = m.sh; return *this; }
522 Iterator begin() { detach(); return sh->begin(); }
523 Iterator end() { detach(); return sh->end(); }
524 ConstIterator begin() const { return ((const Priv*)sh)->begin(); }
525 ConstIterator end() const { return ((const Priv*)sh)->end(); }
527 Iterator find ( const Key& k )
528 { detach(); return Iterator( sh->find( k ).node ); }
529 ConstIterator find ( const Key& k ) const
530 { return sh->find( k ); }
531 T& operator[] ( const Key& k ) {
532 detach(); QMapNode<Key,T>* p = sh->find( k ).node;
533 if ( p != sh->end().node ) return p->data;
534 return insert( k, T() ).data(); }
535 const T& operator[] ( const Key& k ) const
536 { return sh->find( k ).data(); }
537 bool contains ( const Key& k ) const
538 { return find( k ) != end(); }
539 //{ return sh->find( k ) != ((const Priv*)sh)->end(); }
541 uint count() const { return sh->node_count; }
543 bool isEmpty() const { return sh->node_count == 0; }
545 Iterator insert( const Key& key, const T& value ) {
547 Iterator it = sh->insertSingle( key );
552 void remove( Iterator it ) { detach(); sh->remove( it ); }
553 void remove( const Key& k ) {
555 Iterator it( sh->find( k ).node );
560 Iterator replace( const Key& k, const T& v ) {
562 return insert( k, v );
565 void clear() { if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new QMapPrivate<Key,T>; } }
567 #if defined(Q_FULL_TEMPLATE_INSTANTIATION)
568 bool operator==( const QMap<Key,T>& ) const { return FALSE; }
575 void detach() { if ( sh->count > 1 ) { sh->deref(); sh = new QMapPrivate<Key,T>( sh ); } }
581 #ifndef QT_NO_DATASTREAM
582 template<class Key, class T>
583 inline QDataStream& operator>>( QDataStream& s, QMap<Key,T>& m ) {
587 for( Q_UINT32 i = 0; i < c; ++i ) {
596 template<class Key, class T>
597 inline QDataStream& operator<<( QDataStream& s, const QMap<Key,T>& m ) {
598 s << (Q_UINT32)m.count();
599 QMapConstIterator<Key,T> it = m.begin();
600 for( ; it != m.end(); ++it )
601 s << it.key() << it.data();