Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |
qvaluevector.h
This is the verbatim text of the qvaluevector.h include file. It is provided only for illustration; the copyright remains with Trolltech.
/**************************************************************************** ** ** Definition of QValueVector class ** ** ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. ** ** This file is part of the tools module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition ** 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 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email [email protected] for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact [email protected] if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef QVALUEVECTOR_H #define QVALUEVECTOR_H #ifndef QT_H #include "qtl.h" #include "qshared.h" #include "qdatastream.h" #endif // QT_H #ifndef QT_NO_STL #include <vector> #endif template <class T> class QValueVectorPrivate : public QShared { public: typedef T value_type; typedef T* pointer; QValueVectorPrivate() : start( 0 ), finish( 0 ), end( 0 ) { } QValueVectorPrivate( const QValueVectorPrivate<T>& x ); QValueVectorPrivate( size_t size ); void derefAndDelete() // ### hack to get around hp-cc brain damage { if ( deref() ) delete this; } #if defined(Q_TEMPLATEDLL) // Workaround MS bug in memory de/allocation in DLL vs. EXE virtual #endif ~QValueVectorPrivate() { delete[] start; } size_t size() const { return finish - start; } bool empty() const { return start == finish; } size_t capacity() const { return end - start; } void insert( pointer pos, const T& x ); void insert( pointer pos, size_t n, const T& x ); void reserve( size_t n ); void clear() { delete[] start; start = 0; finish = 0; end = 0; } pointer start; pointer finish; pointer end; private: pointer growAndCopy( size_t n, pointer s, pointer f ); QValueVectorPrivate& operator=( const QValueVectorPrivate<T>& x ); }; template <class T> Q_INLINE_TEMPLATES QValueVectorPrivate<T>::QValueVectorPrivate( const QValueVectorPrivate<T>& x ) : QShared() { if ( x.size() > 0 ) { start = new T[ x.size() ]; finish = start + x.size(); end = start + x.size(); qCopy( x.start, x.finish, start ); } else { start = 0; finish = 0; end = 0; } } template <class T> Q_INLINE_TEMPLATES QValueVectorPrivate<T>::QValueVectorPrivate( size_t size ) { if ( size > 0 ) { start = new T[size]; finish = start + size; end = start + size; } else { start = 0; finish = 0; end = 0; } } template <class T> Q_INLINE_TEMPLATES void QValueVectorPrivate<T>::insert( pointer pos, const T& x ) { const size_t lastSize = size(); const size_t n = lastSize !=0 ? 2*lastSize : 1; const size_t offset = pos - start; pointer newStart = new T[n]; pointer newFinish = newStart + offset; qCopy( start, pos, newStart ); *newFinish = x; qCopy( pos, finish, ++newFinish ); delete[] start; start = newStart; finish = newStart + lastSize + 1; end = newStart + n; } template <class T> Q_INLINE_TEMPLATES void QValueVectorPrivate<T>::insert( pointer pos, size_t n, const T& x ) { if ( size_t( end - finish ) >= n ) { // enough room const size_t elems_after = finish - pos; pointer old_finish = finish; if ( elems_after > n ) { qCopy( finish - n, finish, finish ); finish += n; qCopyBackward( pos, old_finish - n, old_finish ); qFill( pos, pos + n, x ); } else { pointer filler = finish; size_t i = n - elems_after; for ( ; i > 0; --i, ++filler ) *filler = x; finish += n - elems_after; qCopy( pos, old_finish, finish ); finish += elems_after; qFill( pos, old_finish, x ); } } else { // not enough room const size_t lastSize = size(); const size_t len = lastSize + QMAX( lastSize, n ); pointer newStart = new T[len]; pointer newFinish = qCopy( start, pos, newStart ); // fill up inserted space size_t i = n; for ( ; i > 0; --i, ++newFinish ) *newFinish = x; newFinish = qCopy( pos, finish, newFinish ); delete[] start; start = newStart; finish = newFinish; end = newStart + len; } } template <class T> Q_INLINE_TEMPLATES void QValueVectorPrivate<T>::reserve( size_t n ) { const size_t lastSize = size(); pointer tmp = growAndCopy( n, start, finish ); start = tmp; finish = tmp + lastSize; end = start + n; } template <class T> Q_INLINE_TEMPLATES Q_TYPENAME QValueVectorPrivate<T>::pointer QValueVectorPrivate<T>::growAndCopy( size_t n, pointer s, pointer f ) { pointer newStart = new T[n]; qCopy( s, f, newStart ); delete[] start; return newStart; } template <class T> class QValueVector { public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type* iterator; typedef const value_type* const_iterator; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; #ifndef QT_NO_STL typedef ptrdiff_t difference_type; #else typedef int difference_type; #endif QValueVector() { sh = new QValueVectorPrivate<T>; } QValueVector( const QValueVector<T>& v ) { sh = v.sh; sh->ref(); } QValueVector( size_type n, const T& val = T() ); #ifndef QT_NO_STL QValueVector( std::vector<T>& v ) { sh = new QValueVectorPrivate<T>( v.size() ); qCopy( v.begin(), v.end(), begin() ); } #endif ~QValueVector() { sh->derefAndDelete(); } QValueVector<T>& operator= ( const QValueVector<T>& v ) { v.sh->ref(); sh->derefAndDelete(); sh = v.sh; return *this; } #ifndef QT_NO_STL QValueVector<T>& operator= ( const std::vector<T>& v ) { clear(); resize( v.size() ); qCopy( v.begin(), v.end(), begin() ); return *this; } #endif size_type size() const { return sh->size(); } bool empty() const { return sh->empty(); } size_type capacity() const { return size_type( sh->capacity() ); } iterator begin() { detach(); return sh->start; } const_iterator begin() const { return sh->start; } iterator end() { detach(); return sh->finish; } const_iterator end() const { return sh->finish; } reference at( size_type i, bool* ok = 0 ) { detach(); if ( ok ) { if ( i < size() ) *ok = TRUE; else *ok = FALSE; } return *( begin() + i ); } const_reference at( size_type i, bool* ok = 0 ) const { if ( ok ) { if ( i < size() ) *ok = TRUE; else *ok = FALSE; } return *( begin() + i ); } reference operator[]( size_type i ) { detach(); return *( begin() + i ); } const_reference operator[]( size_type i ) const { return *( begin() + i ); } reference front() { Q_ASSERT( !empty() ); detach(); return *begin(); } const_reference front() const { Q_ASSERT( !empty() ); return *begin(); } reference back() { Q_ASSERT( !empty() ); detach(); return *( end() - 1 ); } const_reference back() const { Q_ASSERT( !empty() ); return *( end() - 1 ); } void push_back( const T& x ) { detach(); if ( sh->finish == sh->end ) { sh->reserve( size()+1 ); } *sh->finish = x; ++sh->finish; } void pop_back() { detach(); if ( empty() ) return; --sh->finish; } iterator insert( iterator pos, const T& x ); iterator insert( iterator pos, size_type n, const T& x ); void reserve( size_type n ) { if ( capacity() < n ) { detach(); sh->reserve( n ); } } void resize( size_type n, const T& val = T() ) { if ( n < size() ) erase( begin() + n, end() ); else insert( end(), n - size(), val ); } void clear() { detach(); sh->clear(); } iterator erase( iterator pos ) { detach(); if ( pos + 1 != end() ) qCopy( pos + 1, sh->finish, pos ); --sh->finish; return pos; } iterator erase( iterator first, iterator last ) { detach(); qCopy( last, sh->finish, first ); sh->finish = sh->finish - ( last - first ); return first; } bool operator==( const QValueVector<T>& x ) { return qEqual( begin(), end(), x.begin() ); } bool operator==( const QValueVector<T>& x ) const { return qEqual( begin(), end(), x.begin() ); } protected: void detach() { if ( sh->count > 1 ) { detachInternal(); } } void detachInternal(); QValueVectorPrivate<T>* sh; }; template <class T> Q_INLINE_TEMPLATES QValueVector<T>::QValueVector( size_type n, const T& val ) { sh = new QValueVectorPrivate<T>( n ); qFill( begin(), end(), val ); } template <class T> Q_INLINE_TEMPLATES void QValueVector<T>::detachInternal() { sh->deref(); sh = new QValueVectorPrivate<T>( *sh ); } template <class T> Q_INLINE_TEMPLATES Q_TYPENAME QValueVector<T>::iterator QValueVector<T>::insert( iterator pos, const T& x ) { size_type offset = pos - sh->start; detach(); if ( pos == end() ) { if ( sh->finish == sh->end ) push_back( x ); else { *sh->finish = x; ++sh->finish; } } else { if ( sh->finish == sh->end ) { sh->insert( pos, x ); } else { *sh->finish = *(sh->finish - 1); ++sh->finish; qCopyBackward( pos, sh->finish - 2, sh->finish - 1 ); *pos = x; } } return begin() + offset; } template <class T> Q_INLINE_TEMPLATES Q_TYPENAME QValueVector<T>::iterator QValueVector<T>::insert( iterator pos, size_type n, const T& x ) { if ( n != 0 ) { size_type offset = pos - sh->start; detach(); pos = begin() + offset; sh->insert( pos, n, x ); } return pos; } #ifndef QT_NO_DATASTREAM template<class T> Q_INLINE_TEMPLATES QDataStream& operator>>( QDataStream& s, QValueVector<T>& v ) { v.clear(); Q_UINT32 c; s >> c; v.resize( c ); for( Q_UINT32 i = 0; i < c; ++i ) { T t; s >> t; v[i] = t; } return s; } template<class T> Q_INLINE_TEMPLATES QDataStream& operator<<( QDataStream& s, const QValueVector<T>& v ) { s << (Q_UINT32)v.size(); // ### use typename QValueVector<T>::const_iterator once all supported // ### compilers know about the 'typename' keyword. const T* it = v.begin(); for( ; it != v.end(); ++it ) s << *it; return s; } #endif // QT_NO_DATASTREAM #endif
Copyright © 2002 Trolltech | Trademarks | Qt version 3.0.5
|