home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / qt3_emx.zip / include / qvaluevector.h < prev    next >
C/C++ Source or Header  |  2001-10-02  |  10KB  |  517 lines

  1. /****************************************************************************
  2. **
  3. ** Definition of QValueVector class
  4. **
  5. **
  6. ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
  7. **
  8. ** This file is part of the tools module of the Qt GUI Toolkit.
  9. **
  10. ** This file may be distributed under the terms of the Q Public License
  11. ** as defined by Trolltech AS of Norway and appearing in the file
  12. ** LICENSE.QPL included in the packaging of this file.
  13. **
  14. ** This file may be distributed and/or modified under the terms of the
  15. ** GNU General Public License version 2 as published by the Free Software
  16. ** Foundation and appearing in the file LICENSE.GPL included in the
  17. ** packaging of this file.
  18. **
  19. ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
  20. ** licenses may use this file in accordance with the Qt Commercial License
  21. ** Agreement provided with the Software.
  22. **
  23. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  24. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25. **
  26. ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
  27. **   information about Qt Commercial License Agreements.
  28. ** See http://www.trolltech.com/qpl/ for QPL licensing information.
  29. ** See http://www.trolltech.com/gpl/ for GPL licensing information.
  30. **
  31. ** Contact info@trolltech.com if any conditions of this licensing are
  32. ** not clear to you.
  33. **
  34. **********************************************************************/
  35.  
  36. #ifndef QVALUEVECTOR_H
  37. #define QVALUEVECTOR_H
  38.  
  39. #ifndef QT_H
  40. #include "qtl.h"
  41. #include "qshared.h"
  42. #include "qdatastream.h"
  43. #endif // QT_H
  44.  
  45. #ifndef QT_NO_STL
  46. #include <vector>
  47. #endif
  48.  
  49. template <class T>
  50. class Q_EXPORT QValueVectorPrivate : public QShared
  51. {
  52. public:
  53.  
  54.     typedef T value_type;
  55.     typedef T* pointer;
  56.  
  57.     QValueVectorPrivate()
  58.     : start( 0 ), finish( 0 ), end( 0 )
  59.     {
  60.     }
  61.  
  62.     QValueVectorPrivate( const QValueVectorPrivate<T>& x )
  63.     : QShared()
  64.     {
  65.     if ( x.size() > 0 ) {
  66.         start = new T[ x.size() ];
  67.         finish = start + x.size();
  68.         end = start + x.size();
  69.         qCopy( x.start, x.finish, start );
  70.     } else {
  71.         start = 0;
  72.         finish = 0;
  73.         end = 0;
  74.     }
  75.     }
  76.  
  77.     QValueVectorPrivate( size_t size )
  78.     {
  79.     if ( size > 0 ) {
  80.         start = new T[size];
  81.         finish = start + size;
  82.         end = start + size;
  83.     } else {
  84.         start = 0;
  85.         finish = 0;
  86.         end = 0;
  87.     }
  88.     }
  89.  
  90.     void derefAndDelete() // ### hack to get around hp-cc brain damage
  91.     {
  92.     if ( deref() ) {
  93.         delete this;
  94.     }
  95.     }
  96.  
  97. #if defined(Q_TEMPLATEDLL)
  98.     // Workaround MS bug in memory de/allocation in DLL vs. EXE
  99.     virtual
  100. #endif
  101.     ~QValueVectorPrivate()
  102.     {
  103.     delete[] start;
  104.     }
  105.  
  106.     size_t size() const
  107.     {
  108.     return finish - start;
  109.     }
  110.  
  111.     bool empty() const
  112.     {
  113.     return start == finish;
  114.     }
  115.  
  116.     size_t capacity() const
  117.     {
  118.     return end - start;
  119.     }
  120.  
  121.     void insert( pointer pos, const T& x )
  122.     {
  123.     const size_t lastSize = size();
  124.     const size_t n = lastSize !=0 ? 2*lastSize : 1;
  125.     const size_t offset = pos - start;
  126.     pointer newStart = new T[n];
  127.     pointer newFinish = newStart + offset;
  128.     qCopy( start, pos, newStart );
  129.     *newFinish = x;
  130.     qCopy( pos, finish, ++newFinish );
  131.     delete[] start;
  132.     start = newStart;
  133.     finish = newStart + lastSize + 1;
  134.     end = newStart + n;
  135.     }
  136.  
  137.     void insert( pointer pos, size_t n, const T& x )
  138.     {
  139.     if ( size_t( end - finish ) >= n ) {
  140.         // enough room
  141.         const size_t elems_after = finish - pos;
  142.         pointer old_finish = finish;
  143.         if ( elems_after > n ) {
  144.         qCopy( finish - n, finish, finish );
  145.         finish += n;
  146.         qCopyBackward( pos, old_finish - n, old_finish );
  147.         qFill( pos, pos + n, x );
  148.         } else {
  149.         pointer filler = finish;
  150.         size_t i = n - elems_after;
  151.         for ( ; i > 0; --i, ++filler )
  152.             *filler = x;
  153.         finish += n - elems_after;
  154.         qCopy( pos, old_finish, finish );
  155.         finish += elems_after;
  156.         qFill( pos, old_finish, x );
  157.         }
  158.     } else {
  159.         // not enough room
  160.         const size_t lastSize = size();
  161.         const size_t len = lastSize + QMAX( lastSize, n );
  162.         pointer newStart = new T[len];
  163.         pointer newFinish = newStart;
  164.         newFinish = qCopy( start, pos, newStart );
  165.         pointer filler = newFinish;
  166.         size_t i = n;
  167.         for ( ; i > 0; --i, ++filler )
  168.         *filler = x;
  169.         newFinish = filler;
  170.         newFinish = qCopy( pos, finish, newFinish );
  171.         delete[] start;
  172.         start = newStart;
  173.         finish = newFinish;
  174.         end = newStart + len;
  175.     }
  176.     }
  177.  
  178.     void reserve( size_t n )
  179.     {
  180.     const size_t lastSize = size();
  181.     pointer tmp = growAndCopy( n, start, finish );
  182.     start = tmp;
  183.     finish = tmp + lastSize;
  184.     end = start + n;
  185.     }
  186.  
  187.     void clear()
  188.     {
  189.     delete[] start;
  190.     start = 0;
  191.     finish = 0;
  192.     end = 0;
  193.     }
  194.  
  195.     pointer start;
  196.     pointer finish;
  197.     pointer end;
  198.  
  199. private:
  200.     pointer growAndCopy( size_t n, pointer s, pointer f )
  201.     {
  202.     pointer newStart = new T[n];
  203.     qCopy( s, f, newStart );
  204.     delete[] start;
  205.     return newStart;
  206.     }
  207.  
  208.     QValueVectorPrivate& operator=( const QValueVectorPrivate<T>& x );
  209.  
  210. };
  211.  
  212. template <class T>
  213. class Q_EXPORT QValueVector
  214. {
  215. public:
  216.     typedef T value_type;
  217.     typedef value_type* pointer;
  218.     typedef const value_type* const_pointer;
  219.     typedef value_type* iterator;
  220.     typedef const value_type* const_iterator;
  221.     typedef value_type& reference;
  222.     typedef const value_type& const_reference;
  223.     typedef size_t size_type;
  224. #ifndef QT_NO_STL
  225.     typedef ptrdiff_t  difference_type;
  226. #else
  227.     typedef int difference_type;
  228. #endif
  229.  
  230.     QValueVector()
  231.     {
  232.     sh = new QValueVectorPrivate<T>;
  233.     }
  234.  
  235.     QValueVector( const QValueVector<T>& v )
  236.     {
  237.     sh = v.sh;
  238.     sh->ref();
  239.     }
  240.  
  241.     QValueVector( size_type n, const T& val = T() )
  242.     {
  243.     sh = new QValueVectorPrivate<T>( n );
  244.     qFill( begin(), end(), val );
  245.     }
  246.  
  247. #ifndef QT_NO_STL
  248.     QValueVector( std::vector<T>& v )
  249.     {
  250.     sh = new QValueVectorPrivate<T>( v.size() );
  251.     qCopy( v.begin(), v.end(), begin() );
  252.     }
  253. #endif
  254.  
  255.     ~QValueVector()
  256.     {
  257.     sh->derefAndDelete();
  258.     }
  259.  
  260.     QValueVector<T>& operator= ( const QValueVector<T>& v )
  261.     {
  262.     v.sh->ref();
  263.     sh->derefAndDelete();
  264.     sh = v.sh;
  265.     return *this;
  266.     }
  267.  
  268. #ifndef QT_NO_STL
  269.     QValueVector<T>& operator= ( const std::vector<T>& v )
  270.     {
  271.     clear();
  272.     resize( v.size() );
  273.     qCopy( v.begin(), v.end(), begin() );
  274.     return *this;
  275.     }
  276. #endif
  277.  
  278.     size_type size() const
  279.     {
  280.     return sh->size();
  281.     }
  282.  
  283.     bool empty() const
  284.     {
  285.     return sh->empty();
  286.     }
  287.  
  288.     size_type capacity() const
  289.     {
  290.     return size_type( sh->capacity() );
  291.     }
  292.  
  293.     iterator begin()
  294.     {
  295.     detach();
  296.     return sh->start;
  297.     }
  298.  
  299.     const_iterator begin() const
  300.     {
  301.     return sh->start;
  302.     }
  303.  
  304.     iterator end()
  305.     {
  306.     detach();
  307.     return sh->finish;
  308.     }
  309.  
  310.     const_iterator end() const
  311.     {
  312.     return sh->finish;
  313.     }
  314.  
  315.     reference at( size_type i, bool* ok = 0 )
  316.     {
  317.     detach();
  318.     if ( ok ) {
  319.         if ( i < size() )
  320.         *ok = TRUE;
  321.         else
  322.         *ok = FALSE;
  323.     }
  324.     return *( begin() + i );
  325.     }
  326.  
  327.     const_reference at( size_type i, bool* ok = 0 ) const
  328.     {
  329.     if ( ok ) {
  330.         if ( i < size() )
  331.         *ok = TRUE;
  332.         else
  333.         *ok = FALSE;
  334.     }
  335.     return *( begin() + i );
  336.     }
  337.  
  338.     reference operator[]( size_type i )
  339.     {
  340.     detach();
  341.     return *( begin() + i );
  342.     }
  343.  
  344.     const_reference operator[]( size_type i ) const
  345.     {
  346.     return *( begin() + i );
  347.     }
  348.  
  349.     reference front()
  350.     {
  351.     Q_ASSERT( !empty() );
  352.     detach();
  353.     return *begin();
  354.     }
  355.  
  356.     const_reference front() const
  357.     {
  358.     Q_ASSERT( !empty() );
  359.     return *begin();
  360.     }
  361.  
  362.     reference back()
  363.     {
  364.     Q_ASSERT( !empty() );
  365.     detach();
  366.     return *( end() - 1 );
  367.     }
  368.  
  369.     const_reference back() const
  370.     {
  371.     Q_ASSERT( !empty() );
  372.     return *( end() - 1 );
  373.     }
  374.  
  375.     void push_back( const T& x )
  376.     {
  377.     detach();
  378.     if ( sh->finish == sh->end ) {
  379.         sh->reserve( size()+1 );
  380.     }
  381.     *sh->finish = x;
  382.     ++sh->finish;
  383.     }
  384.  
  385.     void pop_back()
  386.     {
  387.     detach();
  388.     if ( empty() )
  389.         return;
  390.     --sh->finish;
  391.     }
  392.  
  393.     iterator insert( iterator pos, const T& x )
  394.     {
  395.     detach();
  396.     size_type offset = pos - begin();
  397.     if ( pos == end() ) {
  398.         if ( sh->finish == sh->end )
  399.         push_back( x );
  400.         else {
  401.         *sh->finish = x;
  402.         ++sh->finish;
  403.         }
  404.     } else {
  405.         if ( sh->finish == sh->end ) {
  406.         sh->insert( pos, x );
  407.         } else {
  408.         *sh->finish = *(sh->finish - 1);
  409.         ++sh->finish;
  410.         qCopyBackward( pos, sh->finish - 2, sh->finish - 1 );
  411.         *pos = x;
  412.         }
  413.     }
  414.     return begin() + offset;
  415.     }
  416.  
  417.     iterator insert( iterator pos, size_type n, const T& x )
  418.     {
  419.         size_type offset = pos - begin();
  420.         if ( n != 0 ) {
  421.             detach();
  422.             offset = pos - begin();
  423.             sh->insert( pos, n, x );
  424.         }
  425.         return begin() + offset;
  426.     }
  427.  
  428.     void reserve( size_type n )
  429.     {
  430.     if ( capacity() < n ) {
  431.         detach();
  432.         sh->reserve( n );
  433.     }
  434.     }
  435.  
  436.     void resize( size_type n, const T& val = T() )
  437.     {
  438.     if ( n < size() )
  439.         erase( begin() + n, end() );
  440.     else
  441.         insert( end(), n - size(), val );
  442.     }
  443.  
  444.     void clear()
  445.     {
  446.     detach();
  447.     sh->clear();
  448.     }
  449.  
  450.     iterator erase( iterator pos )
  451.     {
  452.     detach();
  453.     if ( pos + 1 != end() )
  454.         qCopy( pos + 1, sh->finish, pos );
  455.     --sh->finish;
  456.     return pos;
  457.     }
  458.  
  459.     iterator erase( iterator first, iterator last )
  460.     {
  461.     detach();
  462.     qCopy( last, sh->finish, first );
  463.     sh->finish = sh->finish - ( last - first );
  464.     return first;
  465.     }
  466.  
  467.     bool operator==( const QValueVector<T>& x )
  468.     {
  469.     return qEqual( begin(), end(), x.begin() );
  470.     }
  471.  
  472. protected:
  473.     void detach()
  474.     {
  475.     if ( sh->count > 1 ) {
  476.         sh->deref();
  477.         sh = new QValueVectorPrivate<T>( *sh );
  478.     }
  479.     }
  480.     QValueVectorPrivate<T>* sh;
  481. };
  482.  
  483.  
  484. #ifndef QT_NO_DATASTREAM
  485. template<class T>
  486. inline QDataStream& operator>>( QDataStream& s, QValueVector<T>& v )
  487. {
  488.     v.clear();
  489.     Q_UINT32 c;
  490.     s >> c;
  491.     v.resize( c );
  492.     for( Q_UINT32 i = 0; i < c; ++i )
  493.     {
  494.     T t;
  495.     s >> t;
  496.     v[i] = t;
  497.     }
  498.     return s;
  499. }
  500.  
  501. template<class T>
  502. inline QDataStream& operator<<( QDataStream& s, const QValueVector<T>& v )
  503. {
  504.     s << (Q_UINT32)v.size();
  505.     // ### use typename QValueVector<T>::const_iterator once all supported
  506.     // ### compilers know about the 'typename' keyword.
  507.     const T* it = v.begin();
  508.     for( ; it != v.end(); ++it )
  509.     s << *it;
  510.     return s;
  511. }
  512. #endif // QT_NO_DATASTREAM
  513.  
  514.  
  515.  
  516. #endif
  517.