Go to the
documentation of this file.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef QVARLENGTHARRAY_H
00043 #define QVARLENGTHARRAY_H
00044
00045 #include <QtCore/qcontainerfwd.h>
00046 #include <QtCore/qglobal.h>
00047 #include <new>
00048
00049 QT_BEGIN_HEADER
00050
00051 QT_BEGIN_NAMESPACE
00052
00053 QT_MODULE(Core)
00054
00055 template<class T, int Prealloc>
00056 class QPodList;
00057
00058
00059 template<class T, int Prealloc>
00060 class QVarLengthArray
00061 {
00062 public:
00063 inline explicit QVarLengthArray(int size = 0);
00064
00065 inline QVarLengthArray(const QVarLengthArray<T, Prealloc> &other)
00066 : a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array))
00067 {
00068 append(other.constData(), other.size());
00069 }
00070
00071 inline ~QVarLengthArray() {
00072 if (QTypeInfo<T>::isComplex) {
00073 T *i = ptr + s;
00074 while (i-- != ptr)
00075 i->~T();
00076 }
00077 if (ptr != reinterpret_cast<T *>(array))
00078 qFree(ptr);
00079 }
00080 inline QVarLengthArray<T, Prealloc> &operator=(const QVarLengthArray<T, Prealloc> &other)
00081 {
00082 if (this != &other) {
00083 clear();
00084 append(other.constData(), other.size());
00085 }
00086 return *this;
00087 }
00088
00089 inline void removeLast() {
00090 Q_ASSERT(s > 0);
00091 realloc(s - 1, a);
00092 }
00093 inline int size() const { return s; }
00094 inline int count() const { return s; }
00095 inline bool isEmpty() const { return (s == 0); }
00096 inline void resize(int size);
00097 inline void clear() { resize(0); }
00098
00099 inline int capacity() const { return a; }
00100 inline void reserve(int size);
00101
00102 inline T &operator[](int idx) {
00103 Q_ASSERT(idx >= 0 && idx < s);
00104 return ptr[idx];
00105 }
00106 inline const T &operator[](int idx) const {
00107 Q_ASSERT(idx >= 0 && idx < s);
00108 return ptr[idx];
00109 }
00110 inline const T &at(int idx) const { return operator[](idx); }
00111
00112 T value(int i) const;
00113 T value(int i, const T &defaultValue) const;
00114
00115 inline void append(const T &t) {
00116 if (s == a)
00117 realloc(s, s<<1);
00118 const int idx = s++;
00119 if (QTypeInfo<T>::isComplex) {
00120 new (ptr + idx) T(t);
00121 } else {
00122 ptr[idx] = t;
00123 }
00124 }
00125 void append(const T *buf, int size);
00126
00127 inline T *data() { return ptr; }
00128 inline const T *data() const { return ptr; }
00129 inline const T * constData() const { return ptr; }
00130 typedef int size_type;
00131 typedef T value_type;
00132 typedef value_type *pointer;
00133 typedef const value_type *const_pointer;
00134 typedef value_type &reference;
00135 typedef const value_type &const_reference;
00136 typedef qptrdiff difference_type;
00137
00138 private:
00139 friend class QPodList<T, Prealloc>;
00140 void realloc(int size, int alloc);
00141
00142 int a;
00143 int s;
00144 T *ptr;
00145 union {
00146
00147 char array[sizeof(qint64) * (((Prealloc * sizeof(T)) / sizeof(qint64)) + 1)];
00148 qint64 q_for_alignment_1;
00149 double q_for_alignment_2;
00150 };
00151 };
00152
00153 template <class T, int Prealloc>
00154 Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
00155 : s(asize) {
00156 if (s > Prealloc) {
00157 ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T)));
00158 Q_CHECK_PTR(ptr);
00159 a = s;
00160 } else {
00161 ptr = reinterpret_cast<T *>(array);
00162 a = Prealloc;
00163 }
00164 if (QTypeInfo<T>::isComplex) {
00165 T *i = ptr + s;
00166 while (i != ptr)
00167 new (--i) T;
00168 }
00169 }
00170
00171 template <class T, int Prealloc>
00172 Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::resize(int asize)
00173 { realloc(asize, qMax(asize, a)); }
00174
00175 template <class T, int Prealloc>
00176 Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reserve(int asize)
00177 { if (asize > a) realloc(s, asize); }
00178
00179 template <class T, int Prealloc>
00180 Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, int increment)
00181 {
00182 Q_ASSERT(abuf);
00183 if (increment <= 0)
00184 return;
00185
00186 const int asize = s + increment;
00187
00188 if (asize >= a)
00189 realloc(s, qMax(s*2, asize));
00190
00191 if (QTypeInfo<T>::isComplex) {
00192
00193 while (s < asize)
00194 new (ptr+(s++)) T(*abuf++);
00195 } else {
00196 qMemCopy(&ptr[s], abuf, increment * sizeof(T));
00197 s = asize;
00198 }
00199 }
00200
00201 template <class T, int Prealloc>
00202 Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int aalloc)
00203 {
00204 Q_ASSERT(aalloc >= asize);
00205 T *oldPtr = ptr;
00206 int osize = s;
00207
00208 const int copySize = qMin(asize, osize);
00209 if (aalloc != a) {
00210 ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T)));
00211 Q_CHECK_PTR(ptr);
00212 if (ptr) {
00213 s = 0;
00214 a = aalloc;
00215
00216 if (QTypeInfo<T>::isStatic) {
00217 QT_TRY {
00218
00219 while (s < copySize) {
00220 new (ptr+s) T(*(oldPtr+s));
00221 (oldPtr+s)->~T();
00222 s++;
00223 }
00224 } QT_CATCH(...) {
00225
00226 int sClean = s;
00227 while (sClean < osize)
00228 (oldPtr+(sClean++))->~T();
00229 if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
00230 qFree(oldPtr);
00231 QT_RETHROW;
00232 }
00233 } else {
00234 qMemCopy(ptr, oldPtr, copySize * sizeof(T));
00235 }
00236 } else {
00237 ptr = oldPtr;
00238 return;
00239 }
00240 }
00241 s = copySize;
00242
00243 if (QTypeInfo<T>::isComplex) {
00244
00245 while (osize > asize)
00246 (oldPtr+(--osize))->~T();
00247 }
00248
00249 if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
00250 qFree(oldPtr);
00251
00252 if (QTypeInfo<T>::isComplex) {
00253
00254 while (s < asize)
00255 new (ptr+(s++)) T;
00256 } else {
00257 s = asize;
00258 }
00259 }
00260
00261 template <class T, int Prealloc>
00262 Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(int i) const
00263 {
00264 if (i < 0 || i >= size()) {
00265 return T();
00266 }
00267 return at(i);
00268 }
00269 template <class T, int Prealloc>
00270 Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(int i, const T &defaultValue) const
00271 {
00272 return (i < 0 || i >= size()) ? defaultValue : at(i);
00273 }
00274
00275
00276 QT_END_NAMESPACE
00277
00278 QT_END_HEADER
00279
00280 #endif // QVARLENGTHARRAY_H