Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

qmap.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** $Id: qmap.h,v 1.2 2003/07/10 02:40:11 llornkcor Exp $
00003 **
00004 ** Definition of QMap class
00005 **
00006 ** Created : 990406
00007 **
00008 ** Copyright (C) 1992-2002 Trolltech AS.  All rights reserved.
00009 **
00010 ** This file is part of the tools module of the Qt GUI Toolkit.
00011 **
00012 ** This file may be distributed under the terms of the Q Public License
00013 ** as defined by Trolltech AS of Norway and appearing in the file
00014 ** LICENSE.QPL included in the packaging of this file.
00015 **
00016 ** This file may be distributed and/or modified under the terms of the
00017 ** GNU General Public License version 2 as published by the Free Software
00018 ** Foundation and appearing in the file LICENSE.GPL included in the
00019 ** packaging of this file.
00020 **
00021 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00022 ** licenses may use this file in accordance with the Qt Commercial License
00023 ** Agreement provided with the Software.
00024 **
00025 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00026 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00027 **
00028 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00029 **   information about Qt Commercial License Agreements.
00030 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00031 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00032 **
00033 ** Contact info@trolltech.com if any conditions of this licensing are
00034 ** not clear to you.
00035 **
00036 **********************************************************************/
00037 
00038 #ifndef QMAP_H
00039 #define QMAP_H
00040 
00041 #ifndef QT_H
00042 #include "qglobal.h"
00043 #include "qshared.h"
00044 #include "qdatastream.h"
00045 #include "qpair.h"
00046 #include "qvaluelist.h"
00047 #endif // QT_H
00048 
00049 #ifndef QT_NO_STL
00050 #include <iterator>
00051 #include <map>
00052 #endif
00053 
00054 //#define QT_CHECK_MAP_RANGE
00055 
00056 struct Q_EXPORT QMapNodeBase
00057 {
00058     enum Color { Red, Black };
00059 
00060     QMapNodeBase* left;
00061     QMapNodeBase* right;
00062     QMapNodeBase* parent;
00063 
00064     Color color;
00065 
00066     QMapNodeBase* minimum() {
00067         QMapNodeBase* x = this;
00068         while ( x->left )
00069             x = x->left;
00070         return x;
00071     }
00072 
00073     QMapNodeBase* maximum() {
00074         QMapNodeBase* x = this;
00075         while ( x->right )
00076             x = x->right;
00077         return x;
00078     }
00079 };
00080 
00081 
00082 template <class K, class T>
00083 struct QMapNode : public QMapNodeBase
00084 {
00085     QMapNode( const K& _key, const T& _data ) { data = _data; key = _key; }
00086     QMapNode( const K& _key )      { key = _key; }
00087     QMapNode( const QMapNode<K,T>& _n ) { key = _n.key; data = _n.data; }
00088     QMapNode() { }
00089     T data;
00090     K key;
00091 };
00092 
00093 
00094 template<class K, class T>
00095 class QMapIterator
00096 {
00097  public:
00101     typedef QMapNode< K, T >* NodePtr;
00102 #ifndef QT_NO_STL
00103     typedef std::bidirectional_iterator_tag  iterator_category;
00104 #endif
00105     typedef T          value_type;
00106 #ifndef QT_NO_STL
00107     typedef ptrdiff_t  difference_type;
00108 #else
00109     typedef int difference_type;
00110 #endif
00111     typedef T*         pointer;
00112     typedef T&         reference;
00113 
00117     QMapNode<K,T>* node;
00118 
00122     QMapIterator() : node( 0 ) {}
00123     QMapIterator( QMapNode<K,T>* p ) : node( p ) {}
00124     QMapIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
00125 
00126     bool operator==( const QMapIterator<K,T>& it ) const { return node == it.node; }
00127     bool operator!=( const QMapIterator<K,T>& it ) const { return node != it.node; }
00128     T& operator*() { return node->data; }
00129     const T& operator*() const { return node->data; }
00130     // UDT for T = x*
00131     // T* operator->() const { return &node->data; }
00132 
00133     const K& key() const { return node->key; }
00134     T& data() { return node->data; }
00135     const T& data() const { return node->data; }
00136 
00137 private:
00138     int inc();
00139     int dec();
00140 
00141 public:
00142     QMapIterator<K,T>& operator++() {
00143         inc();
00144         return *this;
00145     }
00146 
00147     QMapIterator<K,T> operator++(int) {
00148         QMapIterator<K,T> tmp = *this;
00149         inc();
00150         return tmp;
00151     }
00152 
00153     QMapIterator<K,T>& operator--() {
00154         dec();
00155         return *this;
00156     }
00157 
00158     QMapIterator<K,T> operator--(int) {
00159         QMapIterator<K,T> tmp = *this;
00160         dec();
00161         return tmp;
00162     }
00163 };
00164 
00165 template <class K, class T>
00166 Q_INLINE_TEMPLATES int QMapIterator<K,T>::inc()
00167 {
00168     QMapNodeBase* tmp = node;
00169     if ( tmp->right ) {
00170         tmp = tmp->right;
00171         while ( tmp->left )
00172             tmp = tmp->left;
00173     } else {
00174         QMapNodeBase* y = tmp->parent;
00175         while (tmp == y->right) {
00176             tmp = y;
00177             y = y->parent;
00178         }
00179         if (tmp->right != y)
00180             tmp = y;
00181     }
00182     node = (NodePtr)tmp;
00183     return 0;
00184 }
00185 
00186 template <class K, class T>
00187 Q_INLINE_TEMPLATES int QMapIterator<K,T>::dec()
00188 {
00189     QMapNodeBase* tmp = node;
00190     if (tmp->color == QMapNodeBase::Red &&
00191         tmp->parent->parent == tmp ) {
00192         tmp = tmp->right;
00193     } else if (tmp->left != 0) {
00194         QMapNodeBase* y = tmp->left;
00195         while ( y->right )
00196             y = y->right;
00197         tmp = y;
00198     } else {
00199         QMapNodeBase* y = tmp->parent;
00200         while (tmp == y->left) {
00201             tmp = y;
00202             y = y->parent;
00203         }
00204         tmp = y;
00205     }
00206     node = (NodePtr)tmp;
00207     return 0;
00208 }
00209 
00210 template<class K, class T>
00211 class QMapConstIterator
00212 {
00213  public:
00217     typedef QMapNode< K, T >* NodePtr;
00218 #ifndef QT_NO_STL
00219     typedef std::bidirectional_iterator_tag  iterator_category;
00220 #endif
00221     typedef T          value_type;
00222 #ifndef QT_NO_STL
00223     typedef ptrdiff_t  difference_type;
00224 #else
00225     typedef int difference_type;
00226 #endif
00227     typedef const T*   pointer;
00228     typedef const T&   reference;
00229 
00230 
00234     QMapNode<K,T>* node;
00235 
00239     QMapConstIterator() : node( 0 ) {}
00240     QMapConstIterator( QMapNode<K,T>* p ) : node( p ) {}
00241     QMapConstIterator( const QMapConstIterator<K,T>& it ) : node( it.node ) {}
00242     QMapConstIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
00243 
00244     bool operator==( const QMapConstIterator<K,T>& it ) const { return node == it.node; }
00245     bool operator!=( const QMapConstIterator<K,T>& it ) const { return node != it.node; }
00246     const T& operator*()  const { return node->data; }
00247     // UDT for T = x*
00248     // const T* operator->() const { return &node->data; }
00249 
00250     const K& key() const { return node->key; }
00251     const T& data() const { return node->data; }
00252 
00253 private:
00254     int inc();
00255     int dec();
00256 
00257 public:
00258     QMapConstIterator<K,T>& operator++() {
00259         inc();
00260         return *this;
00261     }
00262 
00263     QMapConstIterator<K,T> operator++(int) {
00264         QMapConstIterator<K,T> tmp = *this;
00265         inc();
00266         return tmp;
00267     }
00268 
00269     QMapConstIterator<K,T>& operator--() {
00270         dec();
00271         return *this;
00272     }
00273 
00274     QMapConstIterator<K,T> operator--(int) {
00275         QMapConstIterator<K,T> tmp = *this;
00276         dec();
00277         return tmp;
00278     }
00279 };
00280 
00281 template <class K, class T>
00282 Q_INLINE_TEMPLATES int QMapConstIterator<K,T>::inc()
00283 {
00284     QMapNodeBase* tmp = node;
00285     if ( tmp->right ) {
00286         tmp = tmp->right;
00287         while ( tmp->left )
00288             tmp = tmp->left;
00289     } else {
00290         QMapNodeBase* y = tmp->parent;
00291         while (tmp == y->right) {
00292             tmp = y;
00293             y = y->parent;
00294         }
00295         if (tmp->right != y)
00296             tmp = y;
00297     }
00298     node = (NodePtr)tmp;
00299     return 0;
00300 }
00301 
00302 template <class K, class T>
00303 Q_INLINE_TEMPLATES int QMapConstIterator<K,T>::dec()
00304 {
00305     QMapNodeBase* tmp = node;
00306     if (tmp->color == QMapNodeBase::Red &&
00307         tmp->parent->parent == tmp ) {
00308         tmp = tmp->right;
00309     } else if (tmp->left != 0) {
00310         QMapNodeBase* y = tmp->left;
00311         while ( y->right )
00312             y = y->right;
00313         tmp = y;
00314     } else {
00315         QMapNodeBase* y = tmp->parent;
00316         while (tmp == y->left) {
00317             tmp = y;
00318             y = y->parent;
00319         }
00320         tmp = y;
00321     }
00322     node = (NodePtr)tmp;
00323     return 0;
00324 }
00325 
00326 class Q_EXPORT QMapPrivateBase : public QShared
00327 {
00328 public:
00329     QMapPrivateBase() {
00330         node_count = 0;
00331     }
00332     QMapPrivateBase( const QMapPrivateBase* _map) {
00333         node_count = _map->node_count;
00334     }
00335 
00339     void rotateLeft( QMapNodeBase* x, QMapNodeBase*& root);
00340     void rotateRight( QMapNodeBase* x, QMapNodeBase*& root );
00341     void rebalance( QMapNodeBase* x, QMapNodeBase*& root );
00342     QMapNodeBase* removeAndRebalance( QMapNodeBase* z, QMapNodeBase*& root,
00343                                       QMapNodeBase*& leftmost,
00344                                       QMapNodeBase*& rightmost );
00345 
00349     int node_count;
00350 };
00351 
00352 
00353 template <class Key, class T>
00354 class QMapPrivate : public QMapPrivateBase
00355 {
00356 public:
00360     typedef QMapIterator< Key, T > Iterator;
00361     typedef QMapConstIterator< Key, T > ConstIterator;
00362     typedef QMapNode< Key, T > Node;
00363     typedef QMapNode< Key, T >* NodePtr;
00364 
00368     QMapPrivate();
00369     QMapPrivate( const QMapPrivate< Key, T >* _map );
00370     ~QMapPrivate() { clear(); delete header; }
00371 
00372     NodePtr copy( NodePtr p );
00373     void clear();
00374     void clear( NodePtr p );
00375 
00376     Iterator begin()    { return Iterator( (NodePtr)(header->left ) ); }
00377     Iterator end()      { return Iterator( header ); }
00378     ConstIterator begin() const { return ConstIterator( (NodePtr)(header->left ) ); }
00379     ConstIterator end() const { return ConstIterator( header ); }
00380 
00381     ConstIterator find(const Key& k) const;
00382 
00383     void remove( Iterator it ) {
00384         NodePtr del = (NodePtr) removeAndRebalance( it.node, header->parent, header->left, header->right );
00385         delete del;
00386         --node_count;
00387     }
00388 
00389 #ifdef QT_QMAP_DEBUG
00390     void inorder( QMapNodeBase* x = 0, int level = 0 ){
00391         if ( !x )
00392             x = header->parent;
00393         if ( x->left )
00394             inorder( x->left, level + 1 );
00395     //cout << level << " Key=" << key(x) << " Value=" << ((NodePtr)x)->data << endl;
00396         if ( x->right )
00397             inorder( x->right, level + 1 );
00398     }
00399 #endif
00400 
00401 #if 0
00402     Iterator insertMulti(const Key& v){
00403         QMapNodeBase* y = header;
00404         QMapNodeBase* x = header->parent;
00405         while (x != 0){
00406             y = x;
00407             x = ( v < key(x) ) ? x->left : x->right;
00408         }
00409         return insert(x, y, v);
00410     }
00411 #endif
00412 
00413     Iterator insertSingle( const Key& k );
00414     Iterator insert( QMapNodeBase* x, QMapNodeBase* y, const Key& k );
00415 
00416 protected:
00420     const Key& key( QMapNodeBase* b ) const { return ((NodePtr)b)->key; }
00421 
00425     NodePtr header;
00426 };
00427 
00428 
00429 template <class Key, class T>
00430 Q_INLINE_TEMPLATES QMapPrivate<Key,T>::QMapPrivate() {
00431     header = new Node;
00432     header->color = QMapNodeBase::Red; // Mark the header
00433     header->parent = 0;
00434     header->left = header->right = header;
00435 }
00436 template <class Key, class T>
00437 Q_INLINE_TEMPLATES QMapPrivate<Key,T>::QMapPrivate( const QMapPrivate< Key, T >* _map ) : QMapPrivateBase( _map ) {
00438     header = new Node;
00439     header->color = QMapNodeBase::Red; // Mark the header
00440     if ( _map->header->parent == 0 ) {
00441         header->parent = 0;
00442         header->left = header->right = header;
00443     } else {
00444         header->parent = copy( (NodePtr)(_map->header->parent) );
00445         header->parent->parent = header;
00446         header->left = header->parent->minimum();
00447         header->right = header->parent->maximum();
00448     }
00449 }
00450 
00451 template <class Key, class T>
00452 Q_INLINE_TEMPLATES Q_TYPENAME QMapPrivate<Key,T>::NodePtr QMapPrivate<Key,T>::copy( Q_TYPENAME QMapPrivate<Key,T>::NodePtr p )
00453 {
00454     if ( !p )
00455         return 0;
00456     NodePtr n = new Node( *p );
00457     n->color = p->color;
00458     if ( p->left ) {
00459         n->left = copy( (NodePtr)(p->left) );
00460         n->left->parent = n;
00461     } else {
00462         n->left = 0;
00463     }
00464     if ( p->right ) {
00465         n->right = copy( (NodePtr)(p->right) );
00466         n->right->parent = n;
00467     } else {
00468         n->right = 0;
00469     }
00470     return n;
00471 }
00472 
00473 template <class Key, class T>
00474 Q_INLINE_TEMPLATES void QMapPrivate<Key,T>::clear()
00475 {
00476     clear( (NodePtr)(header->parent) );
00477     header->color = QMapNodeBase::Red;
00478     header->parent = 0;
00479     header->left = header->right = header;
00480     node_count = 0;
00481 }
00482 
00483 template <class Key, class T>
00484 Q_INLINE_TEMPLATES void QMapPrivate<Key,T>::clear( Q_TYPENAME QMapPrivate<Key,T>::NodePtr p )
00485 {
00486     while ( p != 0 ) {
00487         clear( (NodePtr)p->right );
00488         NodePtr y = (NodePtr)p->left;
00489         delete p;
00490         p = y;
00491     }
00492 }
00493 
00494 template <class Key, class T>
00495 Q_INLINE_TEMPLATES Q_TYPENAME QMapPrivate<Key,T>::ConstIterator QMapPrivate<Key,T>::find(const Key& k) const
00496 {
00497     QMapNodeBase* y = header;        // Last node
00498     QMapNodeBase* x = header->parent; // Root node.
00499 
00500     while ( x != 0 ) {
00501         // If as k <= key(x) go left
00502         if ( !( key(x) < k ) ) {
00503             y = x;
00504             x = x->left;
00505         } else {
00506             x = x->right;
00507         }
00508     }
00509 
00510     // Was k bigger/smaller then the biggest/smallest
00511     // element of the tree ? Return end()
00512     if ( y == header || k < key(y) )
00513         return ConstIterator( header );
00514     return ConstIterator( (NodePtr)y );
00515 }
00516 
00517 template <class Key, class T>
00518 Q_INLINE_TEMPLATES Q_TYPENAME QMapPrivate<Key,T>::Iterator QMapPrivate<Key,T>::insertSingle( const Key& k )
00519 {
00520     // Search correct position in the tree
00521     QMapNodeBase* y = header;
00522     QMapNodeBase* x = header->parent;
00523     bool result = TRUE;
00524     while ( x != 0 ) {
00525         result = ( k < key(x) );
00526         y = x;
00527         x = result ? x->left : x->right;
00528     }
00529     // Get iterator on the last not empty one
00530     Iterator j( (NodePtr)y );
00531     if ( result ) {
00532         // Smaller then the leftmost one ?
00533         if ( j == begin() ) {
00534             return insert(x, y, k );
00535         } else {
00536             // Perhaps daddy is the right one ?
00537             --j;
00538         }
00539     }
00540     // Really bigger ?
00541     if ( (j.node->key) < k )
00542         return insert(x, y, k );
00543     // We are going to replace a node
00544     return j;
00545 }
00546 
00547 
00548 template <class Key, class T>
00549 Q_INLINE_TEMPLATES Q_TYPENAME QMapPrivate<Key,T>::Iterator QMapPrivate<Key,T>::insert( QMapNodeBase* x, QMapNodeBase* y, const Key& k )
00550 {
00551     NodePtr z = new Node( k );
00552     if (y == header || x != 0 || k < key(y) ) {
00553         y->left = z;                // also makes leftmost = z when y == header
00554         if ( y == header ) {
00555             header->parent = z;
00556             header->right = z;
00557         } else if ( y == header->left )
00558             header->left = z;           // maintain leftmost pointing to min node
00559     } else {
00560         y->right = z;
00561         if ( y == header->right )
00562             header->right = z;          // maintain rightmost pointing to max node
00563     }
00564     z->parent = y;
00565     z->left = 0;
00566     z->right = 0;
00567     rebalance( z, header->parent );
00568     ++node_count;
00569     return Iterator(z);
00570 }
00571 
00572 
00573 #ifdef QT_CHECK_RANGE
00574 # if !defined( QT_NO_DEBUG ) && defined( QT_CHECK_MAP_RANGE )
00575 #  define QT_CHECK_INVALID_MAP_ELEMENT if ( empty() ) qWarning( "QMap: Warning invalid element" )
00576 #  define QT_CHECK_INVALID_MAP_ELEMENT_FATAL Q_ASSERT( !empty() );
00577 # else
00578 #  define QT_CHECK_INVALID_MAP_ELEMENT
00579 #  define QT_CHECK_INVALID_MAP_ELEMENT_FATAL
00580 # endif
00581 #else
00582 # define QT_CHECK_INVALID_MAP_ELEMENT
00583 # define QT_CHECK_INVALID_MAP_ELEMENT_FATAL
00584 #endif
00585 
00586 template <class T> class QDeepCopy;
00587 
00588 template<class Key, class T>
00589 class QMap
00590 {
00591 public:
00595     typedef Key key_type;
00596     typedef T mapped_type;
00597     typedef QPair<const key_type, mapped_type> value_type;
00598     typedef value_type* pointer;
00599     typedef const value_type* const_pointer;
00600     typedef value_type& reference;
00601     typedef const value_type& const_reference;
00602 #ifndef QT_NO_STL
00603     typedef ptrdiff_t  difference_type;
00604 #else
00605     typedef int difference_type;
00606 #endif
00607     typedef size_t      size_type;
00608     typedef QMapIterator<Key,T> iterator;
00609     typedef QMapConstIterator<Key,T> const_iterator;
00610     typedef QPair<iterator,bool> insert_pair;
00611 
00612     typedef QMapIterator< Key, T > Iterator;
00613     typedef QMapConstIterator< Key, T > ConstIterator;
00614     typedef T ValueType;
00615     typedef QMapPrivate< Key, T > Priv;
00616 
00620     QMap()
00621     {
00622         sh = new QMapPrivate< Key, T >;
00623     }
00624     QMap( const QMap<Key,T>& m )
00625     {
00626         sh = m.sh; sh->ref();
00627     }
00628 
00629 #ifndef QT_NO_STL
00630 #  ifdef Q_CC_HPACC    // HP-UX aCC does require typename in some place
00631 #    undef Q_TYPENAME  // but not accept them at others.
00632 #    define Q_TYPENAME // also doesn't like re-defines ...
00633 #  endif
00634     QMap( const Q_TYPENAME std::map<Key,T>& m )
00635     {
00636         sh = new QMapPrivate<Key,T>;
00637 #if defined(Q_OS_WIN32)
00638         std::map<Key,T>::const_iterator it = m.begin();
00639 #else
00640         QMapConstIterator<Key,T> it = m.begin();
00641 #endif
00642         for ( ; it != m.end(); ++it ) {
00643             value_type p( (*it).first, (*it).second );
00644             insert( p );
00645         }
00646     }
00647 #endif
00648     ~QMap()
00649     {
00650         if ( sh->deref() )
00651             delete sh;
00652     }
00653     QMap<Key,T>& operator= ( const QMap<Key,T>& m );
00654 #ifndef QT_NO_STL
00655     QMap<Key,T>& operator= ( const Q_TYPENAME std::map<Key,T>& m )
00656     {
00657         clear();
00658 #if defined(Q_OS_WIN32)
00659         std::map<Key,T>::const_iterator it = m.begin();
00660 #else
00661         QMapConstIterator<Key,T> it = m.begin();
00662 #endif
00663         for ( ; it != m.end(); ++it ) {
00664             value_type p( (*it).first, (*it).second );
00665             insert( p );
00666         }
00667         return *this;
00668     }
00669 #  ifdef Q_CC_HPACC    // undo the HP-UX aCC hackery done above
00670 #    undef Q_TYPENAME 
00671 #    define Q_TYPENAME typename
00672 #  endif
00673 #endif
00674 
00675     iterator begin() { detach(); return sh->begin(); }
00676     iterator end() { detach(); return sh->end(); }
00677     const_iterator begin() const { return ((const Priv*)sh)->begin(); }
00678     const_iterator end() const { return ((const Priv*)sh)->end(); }
00679     iterator replace( const Key& k, const T& v )
00680     {
00681         remove( k );
00682         return insert( k, v );
00683     }
00684 
00685     size_type size() const
00686     {
00687         return sh->node_count;
00688     }
00689     bool empty() const
00690     {
00691         return sh->node_count == 0;
00692     }
00693     QPair<iterator,bool> insert( const value_type& x );
00694 
00695     void erase( iterator it )
00696     {
00697         detach();
00698         sh->remove( it );
00699     }
00700     void erase( const key_type& k );
00701     size_type count( const key_type& k ) const;
00702     T& operator[] ( const Key& k );
00703     void clear();
00704 
00705     iterator find ( const Key& k )
00706     {
00707         detach();
00708         return iterator( sh->find( k ).node );
00709     }
00710     const_iterator find ( const Key& k ) const {        return sh->find( k ); }
00711 
00712     const T& operator[] ( const Key& k ) const
00713         { QT_CHECK_INVALID_MAP_ELEMENT; return sh->find( k ).data(); }
00714     bool contains ( const Key& k ) const
00715         { return find( k ) != end(); }
00716         //{ return sh->find( k ) != ((const Priv*)sh)->end(); }
00717 
00718     size_type count() const { return sh->node_count; }
00719 
00720     QValueList<Key> keys() const {
00721         QValueList<Key> r;
00722         for (const_iterator i=begin(); i!=end(); ++i)
00723             r.append(i.key());
00724         return r;
00725     }
00726 
00727     QValueList<T> values() const {
00728         QValueList<T> r;
00729         for (const_iterator i=begin(); i!=end(); ++i)
00730             r.append(*i);
00731         return r;
00732     }
00733 
00734     bool isEmpty() const { return sh->node_count == 0; }
00735 
00736     iterator insert( const Key& key, const T& value, bool overwrite = TRUE );
00737     void remove( iterator it ) { detach(); sh->remove( it ); }
00738     void remove( const Key& k );
00739 
00740 #if defined(Q_FULL_TEMPLATE_INSTANTIATION)
00741     bool operator==( const QMap<Key,T>& ) const { return FALSE; }
00742 #ifndef QT_NO_STL
00743     bool operator==( const Q_TYPENAME std::map<Key,T>& ) const { return FALSE; }
00744 #endif
00745 #endif
00746 
00747 protected:
00751     void detach() {  if ( sh->count > 1 ) detachInternal(); }
00752 
00753     Priv* sh;
00754 private:
00755     void detachInternal();
00756 
00757     friend class QDeepCopy< QMap<Key,T> >;
00758 };
00759 
00760 template<class Key, class T>
00761 Q_INLINE_TEMPLATES QMap<Key,T>& QMap<Key,T>::operator= ( const QMap<Key,T>& m )
00762 {
00763     m.sh->ref();
00764     if ( sh->deref() )
00765         delete sh;
00766     sh = m.sh;
00767     return *this;
00768 }
00769 
00770 template<class Key, class T>
00771 Q_INLINE_TEMPLATES Q_TYPENAME QMap<Key,T>::insert_pair QMap<Key,T>::insert( const Q_TYPENAME QMap<Key,T>::value_type& x )
00772 {
00773     detach();
00774     size_type n = size();
00775     iterator it = sh->insertSingle( x.first );
00776     bool inserted = FALSE;
00777     if ( n < size() ) {
00778         inserted = TRUE;
00779         it.data() = x.second;
00780     }
00781     return QPair<iterator,bool>( it, inserted );
00782 }
00783 
00784 template<class Key, class T>
00785 Q_INLINE_TEMPLATES void QMap<Key,T>::erase( const Key& k )
00786 {
00787     detach();
00788     iterator it( sh->find( k ).node );
00789     if ( it != end() )
00790         sh->remove( it );
00791 }
00792 
00793 template<class Key, class T>
00794 Q_INLINE_TEMPLATES Q_TYPENAME QMap<Key,T>::size_type QMap<Key,T>::count( const Key& k ) const
00795 {
00796     const_iterator it( sh->find( k ).node );
00797     if ( it != end() ) {
00798         size_type c = 0;
00799         while ( it != end() ) {
00800             ++it;
00801             ++c;
00802         }
00803         return c;
00804     }
00805     return 0;
00806 }
00807 
00808 template<class Key, class T>
00809 Q_INLINE_TEMPLATES T& QMap<Key,T>::operator[] ( const Key& k )
00810 {
00811     detach();
00812     QMapNode<Key,T>* p = sh->find( k ).node;
00813     if ( p != sh->end().node )
00814         return p->data;
00815     return insert( k, T() ).data();
00816 }
00817 
00818 template<class Key, class T>
00819 Q_INLINE_TEMPLATES void QMap<Key,T>::clear()
00820 {
00821     if ( sh->count == 1 )
00822         sh->clear();
00823     else {
00824         sh->deref();
00825         sh = new QMapPrivate<Key,T>;
00826     }
00827 }
00828 
00829 template<class Key, class T>
00830 Q_INLINE_TEMPLATES Q_TYPENAME QMap<Key,T>::iterator QMap<Key,T>::insert( const Key& key, const T& value, bool overwrite )
00831 {
00832     detach();
00833     size_type n = size();
00834     iterator it = sh->insertSingle( key );
00835     if ( overwrite || n < size() )
00836         it.data() = value;
00837     return it;
00838 }
00839 
00840 template<class Key, class T>
00841 Q_INLINE_TEMPLATES void QMap<Key,T>::remove( const Key& k )
00842 {
00843     detach();
00844     iterator it( sh->find( k ).node );
00845     if ( it != end() )
00846         sh->remove( it );
00847 }
00848 
00849 template<class Key, class T>
00850 Q_INLINE_TEMPLATES void QMap<Key,T>::detachInternal()
00851 {
00852     sh->deref(); sh = new QMapPrivate<Key,T>( sh );
00853 }
00854 
00855 
00856 #ifndef QT_NO_DATASTREAM
00857 template<class Key, class T>
00858 Q_INLINE_TEMPLATES QDataStream& operator>>( QDataStream& s, QMap<Key,T>& m ) {
00859     m.clear();
00860     Q_UINT32 c;
00861     s >> c;
00862     for( Q_UINT32 i = 0; i < c; ++i ) {
00863         Key k; T t;
00864         s >> k >> t;
00865         m.insert( k, t );
00866         if ( s.atEnd() )
00867             break;
00868     }
00869     return s;
00870 }
00871 
00872 
00873 template<class Key, class T>
00874 Q_INLINE_TEMPLATES QDataStream& operator<<( QDataStream& s, const QMap<Key,T>& m ) {
00875     s << (Q_UINT32)m.size();
00876     QMapConstIterator<Key,T> it = m.begin();
00877     for( ; it != m.end(); ++it )
00878         s << it.key() << it.data();
00879     return s;
00880 }
00881 #endif
00882 
00883 #ifdef QT_QWINEXPORT
00884 #define Q_DEFINED_QMAP
00885 #include "qwinexport.h"
00886 #endif /* QT_QWINEXPORT */
00887 #endif // QMAP_H

Generated on Sat Nov 5 16:18:25 2005 for OPIE by  doxygen 1.4.2