qvector.h
上传用户:detong
上传日期:2022-06-22
资源大小:20675k
文件大小:24k
源码类别:

系统编程

开发平台:

Unix_Linux

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  4. ** Contact: Qt Software Information (qt-info@nokia.com)
  5. **
  6. ** This file is part of the QtCore module of the Qt Toolkit.
  7. **
  8. ** Commercial Usage
  9. ** Licensees holding valid Qt Commercial licenses may use this file in
  10. ** accordance with the Qt Commercial License Agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Nokia.
  13. **
  14. **
  15. ** GNU General Public License Usage
  16. ** Alternatively, this file may be used under the terms of the GNU
  17. ** General Public License versions 2.0 or 3.0 as published by the Free
  18. ** Software Foundation and appearing in the file LICENSE.GPL included in
  19. ** the packaging of this file.  Please review the following information
  20. ** to ensure GNU General Public Licensing requirements will be met:
  21. ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
  22. ** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
  23. ** exception, Nokia gives you certain additional rights. These rights
  24. ** are described in the Nokia Qt GPL Exception version 1.3, included in
  25. ** the file GPL_EXCEPTION.txt in this package.
  26. **
  27. ** Qt for Windows(R) Licensees
  28. ** As a special exception, Nokia, as the sole copyright holder for Qt
  29. ** Designer, grants users of the Qt/Eclipse Integration plug-in the
  30. ** right for the Qt/Eclipse Integration to link to functionality
  31. ** provided by Qt Designer and its related libraries.
  32. **
  33. ** If you are unsure which license is appropriate for your use, please
  34. ** contact the sales department at qt-sales@nokia.com.
  35. **
  36. ****************************************************************************/
  37. #ifndef QVECTOR_H
  38. #define QVECTOR_H
  39. #include <QtCore/qiterator.h>
  40. #include <QtCore/qatomic.h>
  41. #include <QtCore/qalgorithms.h>
  42. #include <QtCore/qlist.h>
  43. #ifndef QT_NO_STL
  44. #include <iterator>
  45. #include <vector>
  46. #endif
  47. #include <stdlib.h>
  48. #include <string.h>
  49. QT_BEGIN_HEADER
  50. QT_BEGIN_NAMESPACE
  51. QT_MODULE(Core)
  52. struct Q_CORE_EXPORT QVectorData
  53. {
  54.     QBasicAtomicInt ref;
  55.     int alloc;
  56.     int size;
  57. #if defined(QT_ARCH_SPARC) && defined(Q_CC_GNU) && defined(__LP64__) && defined(QT_BOOTSTRAPPED)
  58.     // workaround for bug in gcc 3.4.2
  59.     uint sharable;
  60.     uint capacity;
  61. #else
  62.     uint sharable : 1;
  63.     uint capacity : 1;
  64. #endif
  65.     static QVectorData shared_null;
  66.     static QVectorData *malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init);
  67.     static int grow(int sizeofTypedData, int size, int sizeofT, bool excessive);
  68. };
  69. template <typename T>
  70. struct QVectorTypedData
  71. {
  72.     QBasicAtomicInt ref;
  73.     int alloc;
  74.     int size;
  75. #if defined(QT_ARCH_SPARC) && defined(Q_CC_GNU) && defined(__LP64__) && defined(QT_BOOTSTRAPPED)
  76.     // workaround for bug in gcc 3.4.2
  77.     uint sharable;
  78.     uint capacity;
  79. #else
  80.     uint sharable : 1;
  81.     uint capacity : 1;
  82. #endif
  83.     T array[1];
  84. };
  85. template <typename T>
  86. class QVector
  87. {
  88.     typedef QVectorTypedData<T> Data;
  89.     union { QVectorData *p; QVectorTypedData<T> *d; };
  90. public:
  91.     inline QVector() : p(&QVectorData::shared_null) { d->ref.ref(); }
  92.     explicit QVector(int size);
  93.     QVector(int size, const T &t);
  94.     inline QVector(const QVector<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
  95.     inline ~QVector() { if (!d) return; if (!d->ref.deref()) free(d); }
  96.     QVector<T> &operator=(const QVector<T> &v);
  97.     bool operator==(const QVector<T> &v) const;
  98.     inline bool operator!=(const QVector<T> &v) const { return !(*this == v); }
  99.     inline int size() const { return d->size; }
  100.     inline bool isEmpty() const { return d->size == 0; }
  101.     void resize(int size);
  102.     inline int capacity() const { return d->alloc; }
  103.     void reserve(int size);
  104.     inline void squeeze() { realloc(d->size, d->size); d->capacity = 0; }
  105.     inline void detach() { if (d->ref != 1) detach_helper(); }
  106.     inline bool isDetached() const { return d->ref == 1; }
  107.     inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
  108.     inline T *data() { detach(); return d->array; }
  109.     inline const T *data() const { return d->array; }
  110.     inline const T *constData() const { return d->array; }
  111.     void clear();
  112.     const T &at(int i) const;
  113.     T &operator[](int i);
  114.     const T &operator[](int i) const;
  115.     void append(const T &t);
  116.     void prepend(const T &t);
  117.     void insert(int i, const T &t);
  118.     void insert(int i, int n, const T &t);
  119.     void replace(int i, const T &t);
  120.     void remove(int i);
  121.     void remove(int i, int n);
  122.     QVector<T> &fill(const T &t, int size = -1);
  123.     int indexOf(const T &t, int from = 0) const;
  124.     int lastIndexOf(const T &t, int from = -1) const;
  125.     bool contains(const T &t) const;
  126.     int count(const T &t) const;
  127. #ifdef QT_STRICT_ITERATORS
  128.     class iterator {
  129.     public:
  130.         T *i;
  131.         typedef std::random_access_iterator_tag  iterator_category;
  132.         typedef ptrdiff_t difference_type;
  133.         typedef T value_type;
  134.         typedef T *pointer;
  135.         typedef T &reference;
  136.         inline iterator() : i(0) {}
  137.         inline iterator(T *n) : i(n) {}
  138.         inline iterator(const iterator &o): i(o.i){}
  139.         inline T &operator*() const { return *i; }
  140.         inline T *operator->() const { return i; }
  141.         inline T &operator[](int j) const { return *(i + j); }
  142.         inline bool operator==(const iterator &o) const { return i == o.i; }
  143.         inline bool operator!=(const iterator &o) const { return i != o.i; }
  144.         inline bool operator<(const iterator& other) const { return i < other.i; }
  145.         inline bool operator<=(const iterator& other) const { return i <= other.i; }
  146.         inline bool operator>(const iterator& other) const { return i > other.i; }
  147.         inline bool operator>=(const iterator& other) const { return i >= other.i; }
  148.         inline iterator &operator++() { ++i; return *this; }
  149.         inline iterator operator++(int) { T *n = i; ++i; return n; }
  150.         inline iterator &operator--() { i--; return *this; }
  151.         inline iterator operator--(int) { T *n = i; i--; return n; }
  152.         inline iterator &operator+=(int j) { i+=j; return *this; }
  153.         inline iterator &operator-=(int j) { i-=j; return *this; }
  154.         inline iterator operator+(int j) const { return iterator(i+j); }
  155.         inline iterator operator-(int j) const { return iterator(i-j); }
  156.         inline int operator-(iterator j) const { return i - j.i; }
  157.     };
  158.     friend class iterator;
  159.     class const_iterator {
  160.     public:
  161.         T *i;
  162.         typedef std::random_access_iterator_tag  iterator_category;
  163.         typedef ptrdiff_t difference_type;
  164.         typedef T value_type;
  165.         typedef const T *pointer;
  166.         typedef const T &reference;
  167.         inline const_iterator() : i(0) {}
  168.         inline const_iterator(T *n) : i(n) {}
  169.         inline const_iterator(const const_iterator &o): i(o.i) {}
  170.         inline explicit const_iterator(const iterator &o): i(o.i) {}
  171.         inline const T &operator*() const { return *i; }
  172.         inline const T *operator->() const { return i; }
  173.         inline const T &operator[](int j) const { return *(i + j); }
  174.         inline bool operator==(const const_iterator &o) const { return i == o.i; }
  175.         inline bool operator!=(const const_iterator &o) const { return i != o.i; }
  176.         inline bool operator<(const const_iterator& other) const { return i < other.i; }
  177.         inline bool operator<=(const const_iterator& other) const { return i <= other.i; }
  178.         inline bool operator>(const const_iterator& other) const { return i > other.i; }
  179.         inline bool operator>=(const const_iterator& other) const { return i >= other.i; }
  180.         inline const_iterator &operator++() { ++i; return *this; }
  181.         inline const_iterator operator++(int) { T *n = i; ++i; return n; }
  182.         inline const_iterator &operator--() { i--; return *this; }
  183.         inline const_iterator operator--(int) { T *n = i; i--; return n; }
  184.         inline const_iterator &operator+=(int j) { i+=j; return *this; }
  185.         inline const_iterator &operator-=(int j) { i+=j; return *this; }
  186.         inline const_iterator operator+(int j) const { return const_iterator(i+j); }
  187.         inline const_iterator operator-(int j) const { return const_iterator(i-j); }
  188.         inline int operator-(const_iterator j) const { return i - j.i; }
  189.     };
  190.     friend class const_iterator;
  191. #else
  192.     // STL-style
  193.     typedef T* iterator;
  194.     typedef const T* const_iterator;
  195. #endif
  196.     inline iterator begin() { detach(); return d->array; }
  197.     inline const_iterator begin() const { return d->array; }
  198.     inline const_iterator constBegin() const { return d->array; }
  199.     inline iterator end() { detach(); return d->array + d->size; }
  200.     inline const_iterator end() const { return d->array + d->size; }
  201.     inline const_iterator constEnd() const { return d->array + d->size; }
  202.     iterator insert(iterator before, int n, const T &x);
  203.     inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
  204.     iterator erase(iterator begin, iterator end);
  205.     inline iterator erase(iterator pos) { return erase(pos, pos+1); }
  206.     // more Qt
  207.     inline int count() const { return d->size; }
  208.     inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
  209.     inline const T &first() const { Q_ASSERT(!isEmpty()); return *begin(); }
  210.     inline T& last() { Q_ASSERT(!isEmpty()); return *(end()-1); }
  211.     inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
  212.     QVector<T> mid(int pos, int length = -1) const;
  213.     T value(int i) const;
  214.     T value(int i, const T &defaultValue) const;
  215.     // STL compatibility
  216.     typedef T value_type;
  217.     typedef value_type* pointer;
  218.     typedef const value_type* const_pointer;
  219.     typedef value_type& reference;
  220.     typedef const value_type& const_reference;
  221. #ifndef QT_NO_STL
  222.     typedef ptrdiff_t difference_type;
  223. #else
  224.     typedef int difference_type;
  225. #endif
  226.     typedef iterator Iterator;
  227.     typedef const_iterator ConstIterator;
  228.     typedef int size_type;
  229.     inline void push_back(const T &t) { append(t); }
  230.     inline void push_front(const T &t) { prepend(t); }
  231.     void pop_back() { Q_ASSERT(!isEmpty()); erase(end()-1); }
  232.     void pop_front() { Q_ASSERT(!isEmpty()); erase(begin()); }
  233.     inline bool empty() const
  234.     { return d->size == 0; }
  235.     inline T& front() { return first(); }
  236.     inline const_reference front() const { return first(); }
  237.     inline reference back() { return last(); }
  238.     inline const_reference back() const { return last(); }
  239.     // comfort
  240.     QVector<T> &operator+=(const QVector<T> &l);
  241.     inline QVector<T> operator+(const QVector<T> &l) const
  242.     { QVector n = *this; n += l; return n; }
  243.     inline QVector<T> &operator+=(const T &t)
  244.     { append(t); return *this; }
  245.     inline QVector<T> &operator<< (const T &t)
  246.     { append(t); return *this; }
  247.     inline QVector<T> &operator<<(const QVector<T> &l)
  248.     { *this += l; return *this; }
  249.     QList<T> toList() const;
  250.     static QVector<T> fromList(const QList<T> &list);
  251. #ifndef QT_NO_STL
  252.     static inline QVector<T> fromStdVector(const std::vector<T> &vector)
  253.     { QVector<T> tmp; qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
  254.     inline std::vector<T> toStdVector() const
  255.     { std::vector<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
  256. #endif
  257. private:
  258.     void detach_helper();
  259.     QVectorData *malloc(int alloc);
  260.     void realloc(int size, int alloc);
  261.     void free(Data *d);
  262.     int sizeOfTypedData() {
  263.         // this is more or less the same as sizeof(Data), except that it doesn't
  264.         // count the padding at the end
  265.         return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
  266.     }
  267. };
  268. template <typename T>
  269. void QVector<T>::detach_helper()
  270. { realloc(d->size, d->alloc); }
  271. template <typename T>
  272. void QVector<T>::reserve(int asize)
  273. { if (asize > d->alloc) realloc(d->size, asize); d->capacity = 1; }
  274. template <typename T>
  275. void QVector<T>::resize(int asize)
  276. { realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ?
  277.           QVectorData::grow(sizeOfTypedData(), asize, sizeof(T), QTypeInfo<T>::isStatic)
  278.           : d->alloc); }
  279. template <typename T>
  280. inline void QVector<T>::clear()
  281. { *this = QVector<T>(); }
  282. template <typename T>
  283. inline const T &QVector<T>::at(int i) const
  284. { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::at", "index out of range");
  285.   return d->array[i]; }
  286. template <typename T>
  287. inline const T &QVector<T>::operator[](int i) const
  288. { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
  289.   return d->array[i]; }
  290. template <typename T>
  291. inline T &QVector<T>::operator[](int i)
  292. { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
  293.   return data()[i]; }
  294. template <typename T>
  295. inline void QVector<T>::insert(int i, const T &t)
  296. { Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range");
  297.   insert(begin() + i, 1, t); }
  298. template <typename T>
  299. inline void QVector<T>::insert(int i, int n, const T &t)
  300. { Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range");
  301.   insert(begin() + i, n, t); }
  302. template <typename T>
  303. inline void QVector<T>::remove(int i, int n)
  304. { Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= d->size, "QVector<T>::remove", "index out of range");
  305.   erase(begin() + i, begin() + i + n); }
  306. template <typename T>
  307. inline void QVector<T>::remove(int i)
  308. { Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::remove", "index out of range");
  309.   erase(begin() + i, begin() + i + 1); }
  310. template <typename T>
  311. inline void QVector<T>::prepend(const T &t)
  312. { insert(begin(), 1, t); }
  313. template <typename T>
  314. inline void QVector<T>::replace(int i, const T &t)
  315. {
  316.     Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::replace", "index out of range");
  317.     const T copy(t);
  318.     data()[i] = copy;
  319. }
  320. template <typename T>
  321. QVector<T> &QVector<T>::operator=(const QVector<T> &v)
  322. {
  323.     v.d->ref.ref();
  324.     if (!d->ref.deref())
  325.         free(d);
  326.     d = v.d;
  327.     if (!d->sharable)
  328.         detach_helper();
  329.     return *this;
  330. }
  331. template <typename T>
  332. inline QVectorData *QVector<T>::malloc(int aalloc)
  333. {
  334.     return static_cast<QVectorData *>(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
  335. }
  336. template <typename T>
  337. QVector<T>::QVector(int asize)
  338. {
  339.     p = malloc(asize);
  340.     d->ref = 1;
  341.     d->alloc = d->size = asize;
  342.     d->sharable = true;
  343.     d->capacity = false;
  344.     if (QTypeInfo<T>::isComplex) {
  345.         T* b = d->array;
  346.         T* i = d->array + d->size;
  347.         while (i != b)
  348.             new (--i) T;
  349.     } else {
  350.         qMemSet(d->array, 0, asize * sizeof(T));
  351.     }
  352. }
  353. template <typename T>
  354. QVector<T>::QVector(int asize, const T &t)
  355. {
  356.     p = malloc(asize);
  357.     d->ref = 1;
  358.     d->alloc = d->size = asize;
  359.     d->sharable = true;
  360.     d->capacity = false;
  361.     T* i = d->array + d->size;
  362.     while (i != d->array)
  363.         new (--i) T(t);
  364. }
  365. template <typename T>
  366. void QVector<T>::free(Data *x)
  367. {
  368.     if (QTypeInfo<T>::isComplex) {
  369.         T* b = x->array;
  370.         T* i = b + x->size;
  371.         while (i-- != b)
  372.              i->~T();
  373.     }
  374.     qFree(x);
  375. }
  376. template <typename T>
  377. void QVector<T>::realloc(int asize, int aalloc)
  378. {
  379.     T *j, *i, *b;
  380.     union { QVectorData *p; Data *d; } x;
  381.     x.d = d;
  382.     if (QTypeInfo<T>::isComplex && aalloc == d->alloc && d->ref == 1) {
  383.         // pure resize
  384.         i = d->array + d->size;
  385.         j = d->array + asize;
  386.         if (i > j) {
  387.             while (i-- != j)
  388.                 i->~T();
  389.         } else {
  390.             while (j-- != i)
  391.                 new (j) T;
  392.         }
  393.         d->size = asize;
  394.         return;
  395.     }
  396.     if (aalloc != d->alloc || d->ref != 1) {
  397.         // (re)allocate memory
  398.         if (QTypeInfo<T>::isStatic) {
  399.             x.p = malloc(aalloc);
  400.         } else if (d->ref != 1) {
  401.             x.p = QVectorData::malloc(sizeOfTypedData(), aalloc, sizeof(T), p);
  402.         } else {
  403.             if (QTypeInfo<T>::isComplex) {
  404.                 // call the destructor on all objects that need to be
  405.                 // destroyed when shrinking
  406.                 if (asize < d->size) {
  407.                     j = d->array + asize;
  408.                     i = d->array + d->size;
  409.                     while (i-- != j)
  410.                         i->~T();
  411.                     i = d->array + asize;
  412.                 }
  413.             }
  414.             x.p = p = static_cast<QVectorData *>(qRealloc(p, sizeOfTypedData() + (aalloc - 1) * sizeof(T)));
  415.         }
  416.         x.d->ref = 1;
  417.         x.d->sharable = true;
  418.         x.d->capacity = d->capacity;
  419.     }
  420.     if (QTypeInfo<T>::isComplex) {
  421.         if (asize < d->size) {
  422.             j = d->array + asize;
  423.             i = x.d->array + asize;
  424.         } else {
  425.             // construct all new objects when growing
  426.             i = x.d->array + asize;
  427.             j = x.d->array + d->size;
  428.             while (i != j)
  429.                 new (--i) T;
  430.             j = d->array + d->size;
  431.         }
  432.         if (i != j) {
  433.             // copy objects from the old array into the new array
  434.             b = x.d->array;
  435.             while (i != b)
  436.                 new (--i) T(*--j);
  437.         }
  438.     } else if (asize > d->size) {
  439.         // initialize newly allocated memory to 0
  440.         qMemSet(x.d->array + d->size, 0, (asize - d->size) * sizeof(T));
  441.     }
  442.     x.d->size = asize;
  443.     x.d->alloc = aalloc;
  444.     if (d != x.d) {
  445.         if (!d->ref.deref())
  446.             free(d);
  447.         d = x.d;
  448.     }
  449. }
  450. template<typename T>
  451. Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i) const
  452. {
  453.     if (i < 0 || i >= p->size) {
  454.         return T();
  455.     }
  456.     return d->array[i];
  457. }
  458. template<typename T>
  459. Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i, const T &defaultValue) const
  460. {
  461.     return ((i < 0 || i >= p->size) ? defaultValue : d->array[i]);
  462. }
  463. template <typename T>
  464. void QVector<T>::append(const T &t)
  465. {
  466.     if (d->ref != 1 || d->size + 1 > d->alloc) {
  467.         const T copy(t);
  468.         realloc(d->size, QVectorData::grow(sizeOfTypedData(), d->size + 1, sizeof(T),
  469.                                            QTypeInfo<T>::isStatic));
  470.         if (QTypeInfo<T>::isComplex)
  471.             new (d->array + d->size) T(copy);
  472.         else
  473.             d->array[d->size] = copy;
  474.     } else {
  475.         if (QTypeInfo<T>::isComplex)
  476.             new (d->array + d->size) T(t);
  477.         else
  478.             d->array[d->size] = t;
  479.     }
  480.     ++d->size;
  481. }
  482. template <typename T>
  483. Q_TYPENAME QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
  484. {
  485.     int offset = before - d->array;
  486.     if (n != 0) {
  487.         const T copy(t);
  488.         if (d->ref != 1 || d->size + n > d->alloc)
  489.             realloc(d->size, QVectorData::grow(sizeOfTypedData(), d->size + n, sizeof(T),
  490.                                                QTypeInfo<T>::isStatic));
  491.         if (QTypeInfo<T>::isStatic) {
  492.             T *b = d->array + d->size;
  493.             T *i = d->array + d->size + n;
  494.             while (i != b)
  495.                 new (--i) T;
  496.             i = d->array + d->size;
  497.             T *j = i + n;
  498.             b = d->array + offset;
  499.             while (i != b)
  500.                 *--j = *--i;
  501.             i = b+n;
  502.             while (i != b)
  503.                 *--i = copy;
  504.         } else {
  505.             T *b = d->array + offset;
  506.             T *i = b + n;
  507.             memmove(i, b, (d->size - offset) * sizeof(T));
  508.             while (i != b)
  509.                 new (--i) T(copy);
  510.         }
  511.         d->size += n;
  512.     }
  513.     return d->array + offset;
  514. }
  515. template <typename T>
  516. Q_TYPENAME QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
  517. {
  518.     int f = abegin - d->array;
  519.     int l = aend - d->array;
  520.     int n = l - f;
  521.     detach();
  522.     if (QTypeInfo<T>::isComplex) {
  523.         qCopy(d->array+l, d->array+d->size, d->array+f);
  524.         T *i = d->array+d->size;
  525.         T* b = d->array+d->size-n;
  526.         while (i != b) {
  527.             --i;
  528.             i->~T();
  529.         }
  530.     } else {
  531.         memmove(d->array + f, d->array + l, (d->size-l)*sizeof(T));
  532.     }
  533.     d->size -= n;
  534.     return d->array + f;
  535. }
  536. template <typename T>
  537. bool QVector<T>::operator==(const QVector<T> &v) const
  538. {
  539.     if (d->size != v.d->size)
  540.         return false;
  541.     if (d == v.d)
  542.         return true;
  543.     T* b = d->array;
  544.     T* i = b + d->size;
  545.     T* j = v.d->array + d->size;
  546.     while (i != b)
  547.         if (!(*--i == *--j))
  548.             return false;
  549.     return true;
  550. }
  551. template <typename T>
  552. QVector<T> &QVector<T>::fill(const T &from, int asize)
  553. {
  554.     const T copy(from);
  555.     resize(asize < 0 ? d->size : asize);
  556.     if (d->size) {
  557.         T *i = d->array + d->size;
  558.         T *b = d->array;
  559.         while (i != b)
  560.             *--i = copy;
  561.     }
  562.     return *this;
  563. }
  564. template <typename T>
  565. QVector<T> &QVector<T>::operator+=(const QVector &l)
  566. {
  567.     int newSize = d->size + l.d->size;
  568.     realloc(d->size, newSize);
  569.     T *w = d->array + newSize;
  570.     T *i = l.d->array + l.d->size;
  571.     T *b = l.d->array;
  572.     while (i != b) {
  573.         if (QTypeInfo<T>::isComplex)
  574.             new (--w) T(*--i);
  575.         else
  576.             *--w = *--i;
  577.     }
  578.     d->size = newSize;
  579.     return *this;
  580. }
  581. template <typename T>
  582. int QVector<T>::indexOf(const T &t, int from) const
  583. {
  584.     if (from < 0)
  585.         from = qMax(from + d->size, 0);
  586.     if (from < d->size) {
  587.         T* n = d->array + from - 1;
  588.         T* e = d->array + d->size;
  589.         while (++n != e)
  590.             if (*n == t)
  591.                 return n - d->array;
  592.     }
  593.     return -1;
  594. }
  595. template <typename T>
  596. int QVector<T>::lastIndexOf(const T &t, int from) const
  597. {
  598.     if (from < 0)
  599.         from += d->size;
  600.     else if (from >= d->size)
  601.         from = d->size-1;
  602.     if (from >= 0) {
  603.         T* b = d->array;
  604.         T* n = d->array + from + 1;
  605.         while (n != b) {
  606.             if (*--n == t)
  607.                 return n - b;
  608.         }
  609.     }
  610.     return -1;
  611. }
  612. template <typename T>
  613. bool QVector<T>::contains(const T &t) const
  614. {
  615.     T* b = d->array;
  616.     T* i = d->array + d->size;
  617.     while (i != b)
  618.         if (*--i == t)
  619.             return true;
  620.     return false;
  621. }
  622. template <typename T>
  623. int QVector<T>::count(const T &t) const
  624. {
  625.     int c = 0;
  626.     T* b = d->array;
  627.     T* i = d->array + d->size;
  628.     while (i != b)
  629.         if (*--i == t)
  630.             ++c;
  631.     return c;
  632. }
  633. template <typename T>
  634. Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const
  635. {
  636.     if (length < 0)
  637.         length = size() - pos;
  638.     if (pos == 0 && length == size())
  639.         return *this;
  640.     QVector<T> copy;
  641.     if (pos + length > size())
  642.         length = size() - pos;
  643.     for (int i = pos; i < pos + length; ++i)
  644.         copy += at(i);
  645.     return copy;
  646. }
  647. template <typename T>
  648. Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const
  649. {
  650.     QList<T> result;
  651.     for (int i = 0; i < size(); ++i)
  652.         result.append(at(i));
  653.     return result;
  654. }
  655. template <typename T>
  656. Q_OUTOFLINE_TEMPLATE QVector<T> QList<T>::toVector() const
  657. {
  658.     QVector<T> result(size());
  659.     for (int i = 0; i < size(); ++i)
  660.         result[i] = at(i);
  661.     return result;
  662. }
  663. template <typename T>
  664. QVector<T> QVector<T>::fromList(const QList<T> &list)
  665. {
  666.     return list.toVector();
  667. }
  668. template <typename T>
  669. QList<T> QList<T>::fromVector(const QVector<T> &vector)
  670. {
  671.     return vector.toList();
  672. }
  673. Q_DECLARE_SEQUENTIAL_ITERATOR(Vector)
  674. Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Vector)
  675. /*
  676.    ### Qt 5:
  677.    ### This needs to be removed for next releases of Qt. It is a workaround for vc++ because
  678.    ### Qt exports QPolygon and QPolygonF that inherit QVector<QPoint> and
  679.    ### QVector<QPointF> respectively.
  680. */
  681. #ifdef Q_CC_MSVC
  682. QT_BEGIN_INCLUDE_NAMESPACE
  683. #include <QtCore/QPointF>
  684. #include <QtCore/QPoint>
  685. QT_END_INCLUDE_NAMESPACE
  686. #if defined(QT_BUILD_CORE_LIB)
  687. #define Q_TEMPLATE_EXTERN
  688. #else
  689. #define Q_TEMPLATE_EXTERN extern
  690. #endif
  691. # pragma warning(push)          /* MSVC 6.0 doesn't care about the disabling in qglobal.h (why?), so do it here */
  692. # pragma warning(disable: 4231) /* nonstandard extension used : 'extern' before template explicit instantiation */
  693. Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPointF>;
  694. Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPoint>;
  695. # pragma warning(pop)
  696. #endif
  697. QT_END_NAMESPACE
  698. QT_END_HEADER
  699. #endif // QVECTOR_H