--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/corelib/tools/qvarlengtharray.h Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVARLENGTHARRAY_H
+#define QVARLENGTHARRAY_H
+
+#include <QtCore/qcontainerfwd.h>
+#include <QtCore/qglobal.h>
+#include <new>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+template<class T, int Prealloc>
+class QPodList;
+
+// Prealloc = 256 by default, specified in qcontainerfwd.h
+template<class T, int Prealloc>
+class QVarLengthArray
+{
+public:
+ inline explicit QVarLengthArray(int size = 0);
+
+ inline QVarLengthArray(const QVarLengthArray<T, Prealloc> &other)
+ : a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array))
+ {
+ append(other.constData(), other.size());
+ }
+
+ inline ~QVarLengthArray() {
+ if (QTypeInfo<T>::isComplex) {
+ T *i = ptr + s;
+ while (i-- != ptr)
+ i->~T();
+ }
+ if (ptr != reinterpret_cast<T *>(array))
+ qFree(ptr);
+ }
+ inline QVarLengthArray<T, Prealloc> &operator=(const QVarLengthArray<T, Prealloc> &other)
+ {
+ if (this != &other) {
+ clear();
+ append(other.constData(), other.size());
+ }
+ return *this;
+ }
+
+ inline void removeLast() {
+ Q_ASSERT(s > 0);
+ realloc(s - 1, a);
+ }
+ inline int size() const { return s; }
+ inline int count() const { return s; }
+ inline bool isEmpty() const { return (s == 0); }
+ inline void resize(int size);
+ inline void clear() { resize(0); }
+
+ inline int capacity() const { return a; }
+ inline void reserve(int size);
+
+ inline T &operator[](int idx) {
+ Q_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+ inline const T &operator[](int idx) const {
+ Q_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+
+ inline void append(const T &t) {
+ if (s == a) // i.e. s != 0
+ realloc(s, s<<1);
+ const int idx = s++;
+ if (QTypeInfo<T>::isComplex) {
+ new (ptr + idx) T(t);
+ } else {
+ ptr[idx] = t;
+ }
+ }
+ void append(const T *buf, int size);
+
+ inline T *data() { return ptr; }
+ inline const T *data() const { return ptr; }
+ inline const T * constData() const { return ptr; }
+
+private:
+ friend class QPodList<T, Prealloc>;
+ void realloc(int size, int alloc);
+
+ int a;
+ int s;
+ T *ptr;
+ union {
+ // ### Qt 5: Use 'Prealloc * sizeof(T)' as array size
+ char array[sizeof(qint64) * (((Prealloc * sizeof(T)) / sizeof(qint64)) + 1)];
+ qint64 q_for_alignment_1;
+ double q_for_alignment_2;
+ };
+};
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
+ : s(asize) {
+ if (s > Prealloc) {
+ ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T)));
+ Q_CHECK_PTR(ptr);
+ a = s;
+ } else {
+ ptr = reinterpret_cast<T *>(array);
+ a = Prealloc;
+ }
+ if (QTypeInfo<T>::isComplex) {
+ T *i = ptr + s;
+ while (i != ptr)
+ new (--i) T;
+ }
+}
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::resize(int asize)
+{ realloc(asize, qMax(asize, a)); }
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reserve(int asize)
+{ if (asize > a) realloc(s, asize); }
+
+template <class T, int Prealloc>
+Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, int increment)
+{
+ Q_ASSERT(abuf);
+ if (increment <= 0)
+ return;
+
+ const int asize = s + increment;
+
+ if (asize >= a)
+ realloc(s, qMax(s*2, asize));
+
+ if (QTypeInfo<T>::isComplex) {
+ // call constructor for new objects (which can throw)
+ while (s < asize)
+ new (ptr+(s++)) T(*abuf++);
+ } else {
+ qMemCopy(&ptr[s], abuf, increment * sizeof(T));
+ s = asize;
+ }
+}
+
+template <class T, int Prealloc>
+Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int aalloc)
+{
+ Q_ASSERT(aalloc >= asize);
+ T *oldPtr = ptr;
+ int osize = s;
+ // s = asize;
+
+ if (aalloc != a) {
+ ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T)));
+ Q_CHECK_PTR(ptr);
+ if (ptr) {
+ s = 0;
+ a = aalloc;
+
+ if (QTypeInfo<T>::isStatic) {
+ QT_TRY {
+ // copy all the old elements
+ const int copySize = qMin(asize, osize);
+ while (s < copySize) {
+ new (ptr+s) T(*(oldPtr+s));
+ (oldPtr+s)->~T();
+ s++;
+ }
+ } QT_CATCH(...) {
+ // clean up all the old objects and then free the old ptr
+ int sClean = s;
+ while (sClean < osize)
+ (oldPtr+(sClean++))->~T();
+ if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
+ qFree(oldPtr);
+ QT_RETHROW;
+ }
+ } else {
+ qMemCopy(ptr, oldPtr, qMin(asize, osize) * sizeof(T));
+ s = asize;
+ }
+ } else {
+ ptr = oldPtr;
+ return;
+ }
+ }
+
+ if (QTypeInfo<T>::isComplex) {
+ while (osize > asize)
+ (oldPtr+(--osize))->~T();
+ if( oldPtr == ptr )
+ s = osize;
+ }
+
+ if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
+ qFree(oldPtr);
+
+ if (QTypeInfo<T>::isComplex) {
+ // call default constructor for new objects (which can throw)
+ while (s < asize)
+ new (ptr+(s++)) T;
+ } else {
+ s = asize;
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QVARLENGTHARRAY_H