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

系统编程

开发平台:

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 QVARLENGTHARRAY_H
  38. #define QVARLENGTHARRAY_H
  39. #include <QtCore/qcontainerfwd.h>
  40. #include <QtCore/qglobal.h>
  41. #include <new>
  42. QT_BEGIN_HEADER
  43. QT_BEGIN_NAMESPACE
  44. QT_MODULE(Core)
  45. // Prealloc = 256 by default, specified in qcontainerfwd.h
  46. template<class T, int Prealloc>
  47. class QVarLengthArray
  48. {
  49. public:
  50.     inline explicit QVarLengthArray(int size = 0);
  51.     inline QVarLengthArray(const QVarLengthArray<T, Prealloc> &other)
  52.         : a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array))
  53.     {
  54.         append(other.constData(), other.size());
  55.     }
  56.     inline ~QVarLengthArray() {
  57.         if (QTypeInfo<T>::isComplex) {
  58.             T *i = ptr + s;
  59.             while (i-- != ptr)
  60.                 i->~T();
  61.         }
  62.         if (ptr != reinterpret_cast<T *>(array))
  63.             qFree(ptr);
  64.     }
  65.     inline QVarLengthArray<T, Prealloc> &operator=(const QVarLengthArray<T, Prealloc> &other)
  66.     {
  67.         if (this != &other) {
  68.             clear();
  69.             append(other.constData(), other.size());
  70.         }
  71.         return *this;
  72.     }
  73.     inline int size() const { return s; }
  74.     inline int count() const { return s; }
  75.     inline bool isEmpty() const { return (s == 0); }
  76.     inline void resize(int size);
  77.     inline void clear() { resize(0); }
  78.     inline int capacity() const { return a; }
  79.     inline void reserve(int size);
  80.     inline T &operator[](int idx) {
  81.         Q_ASSERT(idx >= 0 && idx < s);
  82.         return ptr[idx];
  83.     }
  84.     inline const T &operator[](int idx) const {
  85.         Q_ASSERT(idx >= 0 && idx < s);
  86.         return ptr[idx];
  87.     }
  88.     inline void append(const T &t) {
  89.         const int idx = s++;
  90.         if (s == a)
  91.             realloc(s, s<<1);
  92.         if (QTypeInfo<T>::isComplex) {
  93.             new (ptr + idx) T(t);
  94.         } else {
  95.             ptr[idx] = t;
  96.         }
  97.     }
  98.     void append(const T *buf, int size);
  99.     inline T *data() { return ptr; }
  100.     inline const T *data() const { return ptr; }
  101.     inline const T * constData() const { return ptr; }
  102. private:
  103.     void realloc(int size, int alloc);
  104.     int a;
  105.     int s;
  106.     T *ptr;
  107.     union {
  108.         // ### Qt 5: Use 'Prealloc * sizeof(T)' as array size
  109.         char array[sizeof(qint64) * (((Prealloc * sizeof(T)) / sizeof(qint64)) + 1)];
  110.         qint64 q_for_alignment_1;
  111.         double q_for_alignment_2;
  112.     };
  113. };
  114. template <class T, int Prealloc>
  115. Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
  116.     : s(asize) {
  117.     if (s > Prealloc) {
  118.         ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T)));
  119.         a = s;
  120.     } else {
  121.         ptr = reinterpret_cast<T *>(array);
  122.         a = Prealloc;
  123.     }
  124.     if (QTypeInfo<T>::isComplex) {
  125.         T *i = ptr + s;
  126.         while (i != ptr)
  127.             new (--i) T;
  128.     }
  129. }
  130. template <class T, int Prealloc>
  131. Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::resize(int asize)
  132. { realloc(asize, qMax(asize, a)); }
  133. template <class T, int Prealloc>
  134. Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reserve(int asize)
  135. { if (asize > a) realloc(s, asize); }
  136. template <class T, int Prealloc>
  137. Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, int asize)
  138. {
  139.     Q_ASSERT(abuf);
  140.     if (asize <= 0)
  141.         return;
  142.     const int idx = s;
  143.     const int news = s + asize;
  144.     if (news >= a)
  145.         realloc(news, news<<1);
  146.     else
  147.         s = news;
  148.     if (QTypeInfo<T>::isComplex) {
  149.         T *i = ptr + idx;
  150.         T *j = i + asize;
  151.         while (i < j)
  152.             new (i++) T(*abuf++);
  153.     } else {
  154.         qMemCopy(&ptr[idx], abuf, asize * sizeof(T));
  155.     }
  156. }
  157. template <class T, int Prealloc>
  158. Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int aalloc)
  159. {
  160.     Q_ASSERT(aalloc >= asize);
  161.     T *oldPtr = ptr;
  162.     int osize = s;
  163.     s = asize;
  164.     if (aalloc != a) {
  165.         ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T)));
  166.         if (ptr) {
  167.             a = aalloc;
  168.             if (QTypeInfo<T>::isStatic) {
  169.                 T *i = ptr + osize;
  170.                 T *j = oldPtr + osize;
  171.                 while (i != ptr) {
  172.                     new (--i) T(*--j);
  173.                     j->~T();
  174.                 }
  175.             } else {
  176.                 qMemCopy(ptr, oldPtr, osize * sizeof(T));
  177.             }
  178.         } else {
  179.             ptr = oldPtr;
  180.             s = 0;
  181.             asize = 0;
  182.         }
  183.     }
  184.     if (QTypeInfo<T>::isComplex) {
  185.         if (asize < osize) {
  186.             T *i = oldPtr + osize;
  187.             T *j = oldPtr + asize;
  188.             while (i-- != j)
  189.                 i->~T();
  190.         } else {
  191.             T *i = ptr + asize;
  192.             T *j = ptr + osize;
  193.             while (i != j)
  194.                 new (--i) T;
  195.         }
  196.     }
  197.     if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
  198.         qFree(oldPtr);
  199. }
  200. QT_END_NAMESPACE
  201. QT_END_HEADER
  202. #endif // QVARLENGTHARRAY_H