From e5e5db14bf9a12b17fefe650fface82bb250aaec Mon Sep 17 00:00:00 2001 From: tpearson Date: Mon, 30 Aug 2010 23:26:07 +0000 Subject: * More TQt/Qt4 features * Various compilation fixes for Slackware git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/dependencies/tqtinterface@1170159 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- qtinterface/tqmap.h | 890 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 890 insertions(+) (limited to 'qtinterface/tqmap.h') diff --git a/qtinterface/tqmap.h b/qtinterface/tqmap.h index 5a445df..92f170d 100644 --- a/qtinterface/tqmap.h +++ b/qtinterface/tqmap.h @@ -39,6 +39,896 @@ Boston, MA 02110-1301, USA. // For Qt4, some changes are needed #include +#include +#include + +/**************************************************************************** +** +** Definition of TQMap class +** +** Created : 990406 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the tools module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +//#define QT_CHECK_MAP_RANGE + +struct TQMapNodeBase +{ + enum Color { Red, Black }; + + TQMapNodeBase* left; + TQMapNodeBase* right; + TQMapNodeBase* parent; + + Color color; + + TQMapNodeBase* minimum() { + TQMapNodeBase* x = this; + while ( x->left ) + x = x->left; + return x; + } + + TQMapNodeBase* maximum() { + TQMapNodeBase* x = this; + while ( x->right ) + x = x->right; + return x; + } +}; + + +template +struct TQMapNode : public TQMapNodeBase +{ + TQMapNode( const K& _key, const T& _data ) { data = _data; key = _key; } + TQMapNode( const K& _key ) { key = _key; } + TQMapNode( const TQMapNode& _n ) { key = _n.key; data = _n.data; } + TQMapNode() { } + T data; + K key; +}; + + +template +class TQMapIterator +{ + public: + /** + * Typedefs + */ + typedef TQMapNode< K, T >* NodePtr; +#ifndef QT_NO_STL + typedef std::bidirectional_iterator_tag iterator_category; +#endif + typedef T value_type; +#ifndef QT_NO_STL + typedef ptrdiff_t difference_type; +#else + typedef int difference_type; +#endif + typedef T* pointer; + typedef T& reference; + + /** + * Variables + */ + TQMapNode* node; + + /** + * Functions + */ + TQMapIterator() : node( 0 ) {} + TQMapIterator( TQMapNode* p ) : node( p ) {} + TQMapIterator( const TQMapIterator& it ) : node( it.node ) {} + + bool operator==( const TQMapIterator& it ) const { return node == it.node; } + bool operator!=( const TQMapIterator& it ) const { return node != it.node; } + T& operator*() { return node->data; } + const T& operator*() const { return node->data; } + // UDT for T = x* + // T* operator->() const { return &node->data; } + + const K& key() const { return node->key; } + T& data() { return node->data; } + const T& data() const { return node->data; } + +private: + int inc(); + int dec(); + +public: + TQMapIterator& operator++() { + inc(); + return *this; + } + + TQMapIterator operator++(int) { + TQMapIterator tmp = *this; + inc(); + return tmp; + } + + TQMapIterator& operator--() { + dec(); + return *this; + } + + TQMapIterator operator--(int) { + TQMapIterator tmp = *this; + dec(); + return tmp; + } +}; + +template +int TQMapIterator::inc() +{ + TQMapNodeBase* tmp = node; + if ( tmp->right ) { + tmp = tmp->right; + while ( tmp->left ) + tmp = tmp->left; + } else { + TQMapNodeBase* y = tmp->parent; + while (tmp == y->right) { + tmp = y; + y = y->parent; + } + if (tmp->right != y) + tmp = y; + } + node = (NodePtr)tmp; + return 0; +} + +template +int TQMapIterator::dec() +{ + TQMapNodeBase* tmp = node; + if (tmp->color == TQMapNodeBase::Red && + tmp->parent->parent == tmp ) { + tmp = tmp->right; + } else if (tmp->left != 0) { + TQMapNodeBase* y = tmp->left; + while ( y->right ) + y = y->right; + tmp = y; + } else { + TQMapNodeBase* y = tmp->parent; + while (tmp == y->left) { + tmp = y; + y = y->parent; + } + tmp = y; + } + node = (NodePtr)tmp; + return 0; +} + +template +class TQMapConstIterator +{ + public: + /** + * Typedefs + */ + typedef TQMapNode< K, T >* NodePtr; +#ifndef QT_NO_STL + typedef std::bidirectional_iterator_tag iterator_category; +#endif + typedef T value_type; +#ifndef QT_NO_STL + typedef ptrdiff_t difference_type; +#else + typedef int difference_type; +#endif + typedef const T* pointer; + typedef const T& reference; + + + /** + * Variables + */ + TQMapNode* node; + + /** + * Functions + */ + TQMapConstIterator() : node( 0 ) {} + TQMapConstIterator( TQMapNode* p ) : node( p ) {} + TQMapConstIterator( const TQMapConstIterator& it ) : node( it.node ) {} + TQMapConstIterator( const TQMapIterator& it ) : node( it.node ) {} + + bool operator==( const TQMapConstIterator& it ) const { return node == it.node; } + bool operator!=( const TQMapConstIterator& it ) const { return node != it.node; } + const T& operator*() const { return node->data; } + // UDT for T = x* + // const T* operator->() const { return &node->data; } + + const K& key() const { return node->key; } + const T& data() const { return node->data; } + +private: + int inc(); + int dec(); + +public: + TQMapConstIterator& operator++() { + inc(); + return *this; + } + + TQMapConstIterator operator++(int) { + TQMapConstIterator tmp = *this; + inc(); + return tmp; + } + + TQMapConstIterator& operator--() { + dec(); + return *this; + } + + TQMapConstIterator operator--(int) { + TQMapConstIterator tmp = *this; + dec(); + return tmp; + } +}; + +template +int TQMapConstIterator::inc() +{ + TQMapNodeBase* tmp = node; + if ( tmp->right ) { + tmp = tmp->right; + while ( tmp->left ) + tmp = tmp->left; + } else { + TQMapNodeBase* y = tmp->parent; + while (tmp == y->right) { + tmp = y; + y = y->parent; + } + if (tmp->right != y) + tmp = y; + } + node = (NodePtr)tmp; + return 0; +} + +template +int TQMapConstIterator::dec() +{ + TQMapNodeBase* tmp = node; + if (tmp->color == TQMapNodeBase::Red && + tmp->parent->parent == tmp ) { + tmp = tmp->right; + } else if (tmp->left != 0) { + TQMapNodeBase* y = tmp->left; + while ( y->right ) + y = y->right; + tmp = y; + } else { + TQMapNodeBase* y = tmp->parent; + while (tmp == y->left) { + tmp = y; + y = y->parent; + } + tmp = y; + } + node = (NodePtr)tmp; + return 0; +} + +// ### 4.0: rename to something without Private in it. Not really internal. +class TQMapPrivateBase : public Q3Shared +{ +public: + TQMapPrivateBase() { + node_count = 0; + } + TQMapPrivateBase( const TQMapPrivateBase* _map) { + node_count = _map->node_count; + } + + /** + * Implementations of basic tree algorithms + */ + void rotateLeft( TQMapNodeBase* x, TQMapNodeBase*& root); + void rotateRight( TQMapNodeBase* x, TQMapNodeBase*& root ); + void rebalance( TQMapNodeBase* x, TQMapNodeBase*& root ); + TQMapNodeBase* removeAndRebalance( TQMapNodeBase* z, TQMapNodeBase*& root, + TQMapNodeBase*& leftmost, + TQMapNodeBase*& rightmost ); + + /** + * Variables + */ + int node_count; +}; + + +template +class TQMapPrivate : public TQMapPrivateBase +{ +public: + /** + * Typedefs + */ + typedef TQMapIterator< Key, T > Iterator; + typedef TQMapConstIterator< Key, T > ConstIterator; + typedef TQMapNode< Key, T > Node; + typedef TQMapNode< Key, T >* NodePtr; + + /** + * Functions + */ + TQMapPrivate(); + TQMapPrivate( const TQMapPrivate< Key, T >* _map ); + ~TQMapPrivate() { clear(); delete header; } + + NodePtr copy( NodePtr p ); + void clear(); + void clear( NodePtr p ); + + Iterator begin() { return Iterator( (NodePtr)(header->left ) ); } + Iterator end() { return Iterator( header ); } + ConstIterator begin() const { return ConstIterator( (NodePtr)(header->left ) ); } + ConstIterator end() const { return ConstIterator( header ); } + + ConstIterator find(const Key& k) const; + + void remove( Iterator it ) { + NodePtr del = (NodePtr) removeAndRebalance( it.node, header->parent, header->left, header->right ); + delete del; + --node_count; + } + +#ifdef QT_QMAP_DEBUG + void inorder( TQMapNodeBase* x = 0, int level = 0 ){ + if ( !x ) + x = header->parent; + if ( x->left ) + inorder( x->left, level + 1 ); + //cout << level << " Key=" << key(x) << " Value=" << ((NodePtr)x)->data << endl; + if ( x->right ) + inorder( x->right, level + 1 ); + } +#endif + +#if 0 + Iterator insertMulti(const Key& v){ + TQMapNodeBase* y = header; + TQMapNodeBase* x = header->parent; + while (x != 0){ + y = x; + x = ( v < key(x) ) ? x->left : x->right; + } + return insert(x, y, v); + } +#endif + + Iterator insertSingle( const Key& k ); + Iterator insert( TQMapNodeBase* x, TQMapNodeBase* y, const Key& k ); + +protected: + /** + * Helpers + */ + const Key& key( TQMapNodeBase* b ) const { return ((NodePtr)b)->key; } + + /** + * Variables + */ + NodePtr header; +}; + + +template +TQMapPrivate::TQMapPrivate() { + header = new Node; + header->color = TQMapNodeBase::Red; // Mark the header + header->parent = 0; + header->left = header->right = header; +} +template +TQMapPrivate::TQMapPrivate( const TQMapPrivate< Key, T >* _map ) : TQMapPrivateBase( _map ) { + header = new Node; + header->color = TQMapNodeBase::Red; // Mark the header + if ( _map->header->parent == 0 ) { + header->parent = 0; + header->left = header->right = header; + } else { + header->parent = copy( (NodePtr)(_map->header->parent) ); + header->parent->parent = header; + header->left = header->parent->minimum(); + header->right = header->parent->maximum(); + } +} + +template +Q_TYPENAME TQMapPrivate::NodePtr TQMapPrivate::copy( Q_TYPENAME TQMapPrivate::NodePtr p ) +{ + if ( !p ) + return 0; + NodePtr n = new Node( *p ); + n->color = p->color; + if ( p->left ) { + n->left = copy( (NodePtr)(p->left) ); + n->left->parent = n; + } else { + n->left = 0; + } + if ( p->right ) { + n->right = copy( (NodePtr)(p->right) ); + n->right->parent = n; + } else { + n->right = 0; + } + return n; +} + +template +void TQMapPrivate::clear() +{ + clear( (NodePtr)(header->parent) ); + header->color = TQMapNodeBase::Red; + header->parent = 0; + header->left = header->right = header; + node_count = 0; +} + +template +void TQMapPrivate::clear( Q_TYPENAME TQMapPrivate::NodePtr p ) +{ + while ( p != 0 ) { + clear( (NodePtr)p->right ); + NodePtr y = (NodePtr)p->left; + delete p; + p = y; + } +} + +template +Q_TYPENAME TQMapPrivate::ConstIterator TQMapPrivate::find(const Key& k) const +{ + TQMapNodeBase* y = header; // Last node + TQMapNodeBase* x = header->parent; // Root node. + + while ( x != 0 ) { + // If as k <= key(x) go left + if ( !( key(x) < k ) ) { + y = x; + x = x->left; + } else { + x = x->right; + } + } + + // Was k bigger/smaller then the biggest/smallest + // element of the tree ? Return end() + if ( y == header || k < key(y) ) + return ConstIterator( header ); + return ConstIterator( (NodePtr)y ); +} + +template +Q_TYPENAME TQMapPrivate::Iterator TQMapPrivate::insertSingle( const Key& k ) +{ + // Search correct position in the tree + TQMapNodeBase* y = header; + TQMapNodeBase* x = header->parent; + bool result = TRUE; + while ( x != 0 ) { + result = ( k < key(x) ); + y = x; + x = result ? x->left : x->right; + } + // Get iterator on the last not empty one + Iterator j( (NodePtr)y ); + if ( result ) { + // Smaller then the leftmost one ? + if ( j == begin() ) { + return insert(x, y, k ); + } else { + // Perhaps daddy is the right one ? + --j; + } + } + // Really bigger ? + if ( (j.node->key) < k ) + return insert(x, y, k ); + // We are going to replace a node + return j; +} + + +template +Q_TYPENAME TQMapPrivate::Iterator TQMapPrivate::insert( TQMapNodeBase* x, TQMapNodeBase* y, const Key& k ) +{ + NodePtr z = new Node( k ); + if (y == header || x != 0 || k < key(y) ) { + y->left = z; // also makes leftmost = z when y == header + if ( y == header ) { + header->parent = z; + header->right = z; + } else if ( y == header->left ) + header->left = z; // maintain leftmost pointing to min node + } else { + y->right = z; + if ( y == header->right ) + header->right = z; // maintain rightmost pointing to max node + } + z->parent = y; + z->left = 0; + z->right = 0; + rebalance( z, header->parent ); + ++node_count; + return Iterator(z); +} + + +#ifdef QT_CHECK_RANGE +# if !defined( QT_NO_DEBUG ) && defined( QT_CHECK_MAP_RANGE ) +# define QT_CHECK_INVALID_MAP_ELEMENT if ( empty() ) qWarning( "TQMap: Warning invalid element" ) +# define QT_CHECK_INVALID_MAP_ELEMENT_FATAL Q_ASSERT( !empty() ); +# else +# define QT_CHECK_INVALID_MAP_ELEMENT +# define QT_CHECK_INVALID_MAP_ELEMENT_FATAL +# endif +#else +# define QT_CHECK_INVALID_MAP_ELEMENT +# define QT_CHECK_INVALID_MAP_ELEMENT_FATAL +#endif + +template class QDeepCopy; + +template +class TQMap +{ +public: + /** + * Typedefs + */ + typedef Key key_type; + typedef T mapped_type; + typedef QPair value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; +#ifndef QT_NO_STL + typedef ptrdiff_t difference_type; +#else + typedef int difference_type; +#endif + typedef size_t size_type; + typedef TQMapIterator iterator; + typedef TQMapConstIterator const_iterator; + typedef QPair insert_pair; + + typedef TQMapIterator< Key, T > Iterator; + typedef TQMapConstIterator< Key, T > ConstIterator; + typedef T ValueType; + typedef TQMapPrivate< Key, T > Priv; + + /** + * API + */ + TQMap() + { + sh = new TQMapPrivate< Key, T >; + } + TQMap( const TQMap& m ) + { + sh = m.sh; sh->ref(); + } + +#ifndef QT_NO_STL + TQMap( const std::map& m ) + { + sh = new TQMapPrivate; + Q_TYPENAME std::map::const_iterator it = m.begin(); + for ( ; it != m.end(); ++it ) { + value_type p( (*it).first, (*it).second ); + insert( p ); + } + } +#endif + ~TQMap() + { + if ( sh->deref() ) + delete sh; + } + TQMap& operator= ( const TQMap& m ); +#ifndef QT_NO_STL + TQMap& operator= ( const std::map& m ) + { + clear(); + Q_TYPENAME std::map::const_iterator it = m.begin(); + for ( ; it != m.end(); ++it ) { + value_type p( (*it).first, (*it).second ); + insert( p ); + } + return *this; + } +#endif + + // Interoperability + TQMap(const QMap& m) + { + QMapIterator i(m); + while (i.hasNext()) { + i.next(); + insert(i.key(), i.value()); + } + } + TQMap& operator= (const QMap& m) + { + this->clear(); + QMapIterator i(m); + while (i.hasNext()) { + i.next(); + insert(i.key(), i.value()); + } + return *this; + } + + operator QMap() const { + QMap map; + iterator it; + for ( it = this->begin(); it != this->end(); ++it) { + map.insert(it.key(), it.data()); + } + return map; + } + + iterator begin() { detach(); return sh->begin(); } + iterator end() { detach(); return sh->end(); } + const_iterator begin() const { return ((const Priv*)sh)->begin(); } + const_iterator end() const { return ((const Priv*)sh)->end(); } + const_iterator constBegin() const { return begin(); } + const_iterator constEnd() const { return end(); } + + iterator replace( const Key& k, const T& v ) + { + remove( k ); + return insert( k, v ); + } + + size_type size() const + { + return sh->node_count; + } + bool empty() const + { + return sh->node_count == 0; + } + QPair insert( const value_type& x ); + + void erase( iterator it ) + { + detach(); + sh->remove( it ); + } + void erase( const key_type& k ); + size_type count( const key_type& k ) const; + T& operator[] ( const Key& k ); + void clear(); + + iterator find ( const Key& k ) + { + detach(); + return iterator( sh->find( k ).node ); + } + const_iterator find ( const Key& k ) const { return sh->find( k ); } + + const T& operator[] ( const Key& k ) const + { QT_CHECK_INVALID_MAP_ELEMENT; return sh->find( k ).data(); } + bool contains ( const Key& k ) const + { return find( k ) != end(); } + //{ return sh->find( k ) != ((const Priv*)sh)->end(); } + + size_type count() const { return sh->node_count; } + + Q3ValueList keys() const { + Q3ValueList r; + for (const_iterator i=begin(); i!=end(); ++i) + r.append(i.key()); + return r; + } + + Q3ValueList values() const { + Q3ValueList r; + for (const_iterator i=begin(); i!=end(); ++i) + r.append(*i); + return r; + } + + bool isEmpty() const { return sh->node_count == 0; } + + iterator insert( const Key& key, const T& value, bool overwrite = TRUE ); + void remove( iterator it ) { detach(); sh->remove( it ); } + void remove( const Key& k ); + +#if defined(Q_FULL_TEMPLATE_INSTANTIATION) + bool operator==( const TQMap& ) const { return FALSE; } +#ifndef QT_NO_STL + bool operator==( const std::map& ) const { return FALSE; } +#endif +#endif + +protected: + /** + * Helpers + */ + void detach() { if ( sh->count > 1 ) detachInternal(); } + + Priv* sh; +private: + void detachInternal(); + + friend class QDeepCopy< TQMap >; +}; + +template +TQMap& TQMap::operator= ( const TQMap& m ) +{ + m.sh->ref(); + if ( sh->deref() ) + delete sh; + sh = m.sh; + return *this; +} + +template +Q_TYPENAME TQMap::insert_pair TQMap::insert( const Q_TYPENAME TQMap::value_type& x ) +{ + detach(); + size_type n = size(); + iterator it = sh->insertSingle( x.first ); + bool inserted = FALSE; + if ( n < size() ) { + inserted = TRUE; + it.data() = x.second; + } + return QPair( it, inserted ); +} + +template +void TQMap::erase( const Key& k ) +{ + detach(); + iterator it( sh->find( k ).node ); + if ( it != end() ) + sh->remove( it ); +} + +template +Q_TYPENAME TQMap::size_type TQMap::count( const Key& k ) const +{ + const_iterator it( sh->find( k ).node ); + if ( it != end() ) { + size_type c = 0; + while ( it != end() ) { + ++it; + ++c; + } + return c; + } + return 0; +} + +template +T& TQMap::operator[] ( const Key& k ) +{ + detach(); + TQMapNode* p = sh->find( k ).node; + if ( p != sh->end().node ) + return p->data; + return insert( k, T() ).data(); +} + +template +void TQMap::clear() +{ + if ( sh->count == 1 ) + sh->clear(); + else { + sh->deref(); + sh = new TQMapPrivate; + } +} + +template +Q_TYPENAME TQMap::iterator TQMap::insert( const Key& key, const T& value, bool overwrite ) +{ + detach(); + size_type n = size(); + iterator it = sh->insertSingle( key ); + if ( overwrite || n < size() ) + it.data() = value; + return it; +} + +template +void TQMap::remove( const Key& k ) +{ + detach(); + iterator it( sh->find( k ).node ); + if ( it != end() ) + sh->remove( it ); +} + +template +void TQMap::detachInternal() +{ + sh->deref(); sh = new TQMapPrivate( sh ); +} + + +#ifndef QT_NO_DATASTREAM +template +QDataStream& operator>>( QDataStream& s, TQMap& m ) { + m.clear(); + Q_UINT32 c; + s >> c; + for( Q_UINT32 i = 0; i < c; ++i ) { + Key k; T t; + s >> k >> t; + m.insert( k, t ); + if ( s.atEnd() ) + break; + } + return s; +} + + +template +QDataStream& operator<<( QDataStream& s, const TQMap& m ) { + s << (Q_UINT32)m.size(); + TQMapConstIterator it = m.begin(); + for( ; it != m.end(); ++it ) + s << it.key() << it.data(); + return s; +} +#endif + +/**********************************************************************/ #endif // USE_QT4 -- cgit v1.2.1