Eneboo - Documentación para desarrolladores
|
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