Eneboo - Documentación para desarrolladores
src/qt/include/qvaluevector.h
Ir a la documentación de este archivo.
00001 /****************************************************************************
00002 ** $Id: qt/qvaluevector.h   3.3.8   edited Jan 11 14:38 $
00003 **
00004 ** Definition of QValueVector class
00005 **
00006 ** Copyright (C) 1992-2007 Trolltech ASA.  All rights reserved.
00007 **
00008 ** This file is part of the tools module of the Qt GUI Toolkit.
00009 **
00010 ** This file may be distributed under the terms of the Q Public License
00011 ** as defined by Trolltech ASA of Norway and appearing in the file
00012 ** LICENSE.QPL included in the packaging of this file.
00013 **
00014 ** This file may be distributed and/or modified under the terms of the
00015 ** GNU General Public License version 2 as published by the Free Software
00016 ** Foundation and appearing in the file LICENSE.GPL included in the
00017 ** packaging of this file.
00018 **
00019 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00020 ** licenses may use this file in accordance with the Qt Commercial License
00021 ** Agreement provided with the Software.
00022 **
00023 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00024 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00025 **
00026 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00027 **   information about Qt Commercial License Agreements.
00028 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00029 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00030 **
00031 ** Contact info@trolltech.com if any conditions of this licensing are
00032 ** not clear to you.
00033 **
00034 **********************************************************************/
00035 
00036 #ifndef QVALUEVECTOR_H
00037 #define QVALUEVECTOR_H
00038 
00039 #ifndef QT_H
00040 #include "qtl.h"
00041 #include "qshared.h"
00042 #include "qdatastream.h"
00043 #endif // QT_H
00044 
00045 #ifndef QT_NO_STL
00046 #include <vector>
00047 #endif
00048 
00049 template <class T>
00050 class QValueVectorPrivate : public QShared
00051 {
00052 public:
00053     typedef T value_type;
00054     typedef T* pointer;
00055 
00056     QValueVectorPrivate()
00057         : start( 0 ), finish( 0 ), end( 0 )
00058     {
00059     }
00060 
00061     QValueVectorPrivate( const QValueVectorPrivate<T>& x );
00062     QValueVectorPrivate( size_t size );
00063 
00064     void derefAndDelete() // work-around for hp-cc
00065     {
00066         if ( deref() )
00067             delete this;
00068     }
00069 
00070 #if defined(Q_TEMPLATEDLL)
00071     // Workaround MS bug in memory de/allocation in DLL vs. EXE
00072     virtual
00073 #endif
00074     ~QValueVectorPrivate()
00075     {
00076         delete[] start;
00077     }
00078 
00079     size_t size() const
00080     {
00081         return finish - start;
00082     }
00083 
00084     bool empty() const
00085     {
00086         return start == finish;
00087     }
00088 
00089     size_t capacity() const
00090     {
00091         return end - start;
00092     }
00093 
00094     void insert( pointer pos, const T& x );
00095     void insert( pointer pos, size_t n, const T& x );
00096     void reserve( size_t n );
00097 
00098     void clear()
00099     {
00100         delete[] start;
00101         start = 0;
00102         finish = 0;
00103         end = 0;
00104     }
00105 
00106 
00107     pointer start;
00108     pointer finish;
00109     pointer end;
00110 
00111 private:
00112     pointer growAndCopy( size_t n, pointer s, pointer f );
00113 
00114     QValueVectorPrivate<T>& operator=( const QValueVectorPrivate<T>& x );
00115 
00116 };
00117 
00118 template <class T>
00119 Q_INLINE_TEMPLATES QValueVectorPrivate<T>::QValueVectorPrivate( const QValueVectorPrivate<T>& x )
00120     : QShared()
00121 {
00122     size_t i = x.size();
00123     if ( i > 0 ) {
00124         start = new T[ i ];
00125         finish = start + i;
00126         end = start + i;
00127 #if defined(__xlC__) && __xlC__ < 0x400 // xlC 3.6 confused by const
00128         qCopy( (pointer)x.start, (pointer)x.finish, start );
00129 #else
00130         qCopy( x.start, x.finish, start );
00131 #endif
00132     } else {
00133         start = 0;
00134         finish = 0;
00135         end = 0;
00136     }
00137 }
00138 
00139 template <class T>
00140 Q_INLINE_TEMPLATES QValueVectorPrivate<T>::QValueVectorPrivate( size_t size )
00141 {
00142     if ( size > 0 ) {
00143         start = new T[size];
00144         finish = start + size;
00145         end = start + size;
00146     } else {
00147         start = 0;
00148         finish = 0;
00149         end = 0;
00150     }
00151 }
00152 
00153 template <class T>
00154 Q_INLINE_TEMPLATES void QValueVectorPrivate<T>::insert( pointer pos, const T& x )
00155 {
00156     const size_t lastSize = size();
00157     const size_t n = lastSize !=0 ? 2*lastSize : 1;
00158     const size_t offset = pos - start;
00159     pointer newStart = new T[n];
00160     pointer newFinish = newStart + offset;
00161     qCopy( start, pos, newStart );
00162     *newFinish = x;
00163     qCopy( pos, finish, ++newFinish );
00164     delete[] start;
00165     start = newStart;
00166     finish = newStart + lastSize + 1;
00167     end = newStart + n;
00168 }
00169 
00170 template <class T>
00171 Q_INLINE_TEMPLATES void QValueVectorPrivate<T>::insert( pointer pos, size_t n, const T& x )
00172 {
00173     if ( size_t( end - finish ) >= n ) {
00174         // enough room
00175         const size_t elems_after = finish - pos;
00176         pointer old_finish = finish;
00177         if ( elems_after > n ) {
00178             qCopy( finish - n, finish, finish );
00179             finish += n;
00180             qCopyBackward( pos, old_finish - n, old_finish );
00181             qFill( pos, pos + n, x );
00182         } else {
00183             pointer filler = finish;
00184             size_t i = n - elems_after;
00185             for ( ; i > 0; --i, ++filler )
00186                 *filler = x;
00187             finish += n - elems_after;
00188             qCopy( pos, old_finish, finish );
00189             finish += elems_after;
00190             qFill( pos, old_finish, x );
00191         }
00192     } else {
00193         // not enough room
00194         const size_t lastSize = size();
00195         const size_t len = lastSize + QMAX( lastSize, n );
00196         pointer newStart = new T[len];
00197         pointer newFinish = qCopy( start, pos, newStart );
00198         // fill up inserted space
00199         size_t i = n;
00200         for ( ; i > 0; --i, ++newFinish )
00201             *newFinish = x;
00202         newFinish = qCopy( pos, finish, newFinish );
00203         delete[] start;
00204         start = newStart;
00205         finish = newFinish;
00206         end = newStart + len;
00207     }
00208 }
00209 
00210 template <class T>
00211 Q_INLINE_TEMPLATES void QValueVectorPrivate<T>::reserve( size_t n )
00212 {
00213     const size_t lastSize = size();
00214     pointer tmp = growAndCopy( n, start, finish );
00215     start = tmp;
00216     finish = tmp + lastSize;
00217     end = start + n;
00218 }
00219 
00220 template <class T>
00221 Q_INLINE_TEMPLATES Q_TYPENAME QValueVectorPrivate<T>::pointer QValueVectorPrivate<T>::growAndCopy( size_t n, pointer s, pointer f )
00222 {
00223     pointer newStart = new T[n];
00224     qCopy( s, f, newStart );
00225     delete[] start;
00226     return newStart;
00227 }
00228 
00229 template <class T> class QDeepCopy;
00230 
00231 template <class T>
00232 class QValueVector
00233 {
00234 public:
00235     typedef T value_type;
00236     typedef value_type* pointer;
00237     typedef const value_type* const_pointer;
00238     typedef value_type* iterator;
00239     typedef const value_type* const_iterator;
00240     typedef value_type& reference;
00241     typedef const value_type& const_reference;
00242     typedef size_t size_type;
00243 #ifndef QT_NO_STL
00244     typedef ptrdiff_t difference_type;
00245 #else
00246     typedef int difference_type;
00247 #endif
00248 
00249     QValueVector()
00250     {
00251         sh = new QValueVectorPrivate<T>;
00252     }
00253 
00254     QValueVector( const QValueVector<T>& v )
00255     {
00256         sh = v.sh;
00257         sh->ref();
00258     }
00259 
00260     QValueVector( size_type n, const T& val = T() );
00261 
00262 #ifndef QT_NO_STL
00263     QValueVector( std::vector<T>& v ) // ### remove in 4.0
00264     {
00265         sh = new QValueVectorPrivate<T>( v.size() );
00266         qCopy( v.begin(), v.end(), begin() );
00267     }
00268 
00269     QValueVector( const std::vector<T>& v )
00270     {
00271         sh = new QValueVectorPrivate<T>( v.size() );
00272         qCopy( v.begin(), v.end(), begin() );
00273     }
00274 #endif
00275 
00276     ~QValueVector()
00277     {
00278         sh->derefAndDelete();
00279     }
00280 
00281     QValueVector<T>& operator= ( const QValueVector<T>& v )
00282     {
00283         v.sh->ref();
00284         sh->derefAndDelete();
00285         sh = v.sh;
00286         return *this;
00287     }
00288 
00289 #ifndef QT_NO_STL
00290     QValueVector<T>& operator= ( const std::vector<T>& v )
00291     {
00292         clear();
00293         resize( v.size() );
00294         qCopy( v.begin(), v.end(), begin() );
00295         return *this;
00296     }
00297 #endif
00298 
00299     size_type size() const { return sh->size(); }
00300 
00301     bool empty() const { return sh->empty(); }
00302 
00303     size_type capacity() const
00304     {
00305         return size_type( sh->capacity() );
00306     }
00307 
00308     iterator begin()
00309     {
00310         detach();
00311         return sh->start;
00312     }
00313 
00314     const_iterator begin() const
00315     {
00316         return sh->start;
00317     }
00318 
00319     const_iterator constBegin() const
00320     {
00321         return sh->start;
00322     }
00323 
00324     iterator end()
00325     {
00326         detach();
00327         return sh->finish;
00328     }
00329 
00330     const_iterator end() const
00331     {
00332         return sh->finish;
00333     }
00334 
00335     const_iterator constEnd() const
00336     {
00337         return sh->finish;
00338     }
00339 
00340     reference at( size_type i, bool* ok = 0 )
00341     {
00342         detach();
00343         if ( ok )
00344             *ok = ( i < size() );
00345         return *( begin() + i );
00346     }
00347 
00348     const_reference at( size_type i, bool* ok = 0 ) const
00349     {
00350         if ( ok )
00351             *ok = ( i < size() );
00352         return *( begin() + i );
00353     }
00354 
00355     reference operator[]( size_type i )
00356     {
00357         detach();
00358         return *( begin() + i );
00359     }
00360 
00361     const_reference operator[]( size_type i ) const
00362     {
00363         return *( begin() + i );
00364     }
00365 
00366     reference front()
00367     {
00368         Q_ASSERT( !empty() );
00369         detach();
00370         return *begin();
00371     }
00372 
00373     const_reference front() const
00374     {
00375         Q_ASSERT( !empty() );
00376         return *begin();
00377     }
00378 
00379     reference back()
00380     {
00381         Q_ASSERT( !empty() );
00382         detach();
00383         return *( end() - 1 );
00384     }
00385 
00386     const_reference back() const
00387     {
00388         Q_ASSERT( !empty() );
00389         return *( end() - 1 );
00390     }
00391 
00392     void push_back( const T& x )
00393     {
00394         detach();
00395         if ( sh->finish == sh->end ) {
00396             sh->reserve( size()+size()/2+1 );
00397         }
00398         *sh->finish = x;
00399         ++sh->finish;
00400     }
00401 
00402     void pop_back()
00403     {
00404         detach();
00405         if ( empty() )
00406             return;
00407         --sh->finish;
00408     }
00409 
00410     iterator insert( iterator pos, const T& x );
00411     iterator insert( iterator pos, size_type n, const T& x );
00412 
00413     void reserve( size_type n )
00414     {
00415         if ( capacity() < n ) {
00416             detach();
00417             sh->reserve( n );
00418         }
00419     }
00420 
00421     void resize( size_type n, const T& val = T() )
00422     {
00423         if ( n < size() )
00424             erase( begin() + n, end() );
00425         else
00426             insert( end(), n - size(), val );
00427     }
00428 
00429     void clear()
00430     {
00431         detach();
00432         sh->clear();
00433     }
00434 
00435     iterator erase( iterator pos )
00436     {
00437         detach();
00438         if ( pos + 1 != end() )
00439             qCopy( pos + 1, sh->finish, pos );
00440         --sh->finish;
00441         return pos;
00442     }
00443 
00444     iterator erase( iterator first, iterator last )
00445     {
00446         detach();
00447         qCopy( last, sh->finish, first );
00448         sh->finish = sh->finish - ( last - first );
00449         return first;
00450     }
00451 
00452     // ### remove in Qt 4.0
00453     bool operator==( const QValueVector<T>& x )
00454     {
00455         return size()==x.size() ? qEqual( constBegin(), constEnd(), x.begin()) : FALSE;
00456     }
00457 
00458     bool operator==( const QValueVector<T>& x ) const
00459     {
00460         return size()==x.size() ? qEqual( begin(), end(), x.begin() ) : FALSE;
00461     }
00462 
00463     typedef T ValueType;
00464     typedef ValueType *Iterator;
00465     typedef const ValueType *ConstIterator;
00466 
00467     size_type count() const { return size(); }
00468     bool isEmpty() const { return empty(); }
00469 
00470     reference first() { return front(); }
00471     const_reference first() const { return front(); }
00472     reference last() { return back(); }
00473     const_reference last() const { return back(); }
00474     void append( const T& x ) { push_back( x ); }
00475 
00476 protected:
00477     void detach()
00478     {
00479         if ( sh->count > 1 ) { detachInternal(); }
00480     }
00481     void detachInternal();
00482     QValueVectorPrivate<T>* sh;
00483 
00484 private:
00485     friend class QDeepCopy< QValueVector<T> >;
00486 };
00487 
00488 template <class T>
00489 Q_INLINE_TEMPLATES QValueVector<T>::QValueVector( size_type n, const T& val )
00490 {
00491     sh = new QValueVectorPrivate<T>( n );
00492     qFill( begin(), end(), val );
00493 }
00494 
00495 template <class T>
00496 Q_INLINE_TEMPLATES void QValueVector<T>::detachInternal()
00497 {
00498     sh->deref();
00499     sh = new QValueVectorPrivate<T>( *sh );
00500 }
00501 
00502 template <class T>
00503 Q_INLINE_TEMPLATES Q_TYPENAME QValueVector<T>::iterator QValueVector<T>::insert( iterator pos, const T& x )
00504 {
00505     size_type offset = pos - sh->start;
00506     detach();
00507     if ( pos == end() ) {
00508         if ( sh->finish == sh->end )
00509             push_back( x );
00510         else {
00511             *sh->finish = x;
00512             ++sh->finish;
00513         }
00514     } else {
00515         if ( sh->finish == sh->end ) {
00516             sh->insert( pos, x );
00517         } else {
00518             *sh->finish = *(sh->finish - 1);
00519             ++sh->finish;
00520             qCopyBackward( pos, sh->finish - 2, sh->finish - 1 );
00521             *pos = x;
00522         }
00523     }
00524     return begin() + offset;
00525 }
00526 
00527 template <class T>
00528 Q_INLINE_TEMPLATES Q_TYPENAME QValueVector<T>::iterator QValueVector<T>::insert( iterator pos, size_type n, const T& x )
00529 {
00530     if ( n != 0 ) {
00531         size_type offset = pos - sh->start;
00532         detach();
00533         pos = begin() + offset;
00534         sh->insert( pos, n, x );
00535     }
00536     return pos;
00537 }
00538 
00539 
00540 #ifndef QT_NO_DATASTREAM
00541 template<class T>
00542 Q_INLINE_TEMPLATES QDataStream& operator>>( QDataStream& s, QValueVector<T>& v )
00543 {
00544     v.clear();
00545     Q_UINT32 c;
00546     s >> c;
00547     v.resize( c );
00548     for( Q_UINT32 i = 0; i < c; ++i )
00549     {
00550         T t;
00551         s >> t;
00552         v[i] = t;
00553     }
00554     return s;
00555 }
00556 
00557 template<class T>
00558 Q_INLINE_TEMPLATES QDataStream& operator<<( QDataStream& s, const QValueVector<T>& v )
00559 {
00560     s << (Q_UINT32)v.size();
00561     // ### use typename QValueVector<T>::const_iterator once all supported
00562     // ### compilers know about the 'typename' keyword.
00563     const T* it = v.begin();
00564     for( ; it != v.end(); ++it )
00565         s << *it;
00566     return s;
00567 }
00568 #endif // QT_NO_DATASTREAM
00569 
00570 #define Q_DEFINED_QVALUEVECTOR
00571 #include "qwinexport.h"
00572 #endif // QVALUEVECTOR_H
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'