• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDevelop Platform Libraries
  • Sitemap
  • Contact Us
 

util

kdevvarlengtharray.h

00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtCore module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License versions 2.0 or 3.0 as published by the Free Software
00009 ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
00010 ** included in the packaging of this file.  Alternatively you may (at
00011 ** your option) use any later version of the GNU General Public
00012 ** License if such license has been publicly approved by Trolltech ASA
00013 ** (or its successors, if any) and the KDE Free Qt Foundation. In
00014 ** addition, as a special exception, Trolltech gives you certain
00015 ** additional rights. These rights are described in the Trolltech GPL
00016 ** Exception version 1.2, which can be found at
00017 ** http://www.trolltech.com/products/qt/gplexception/ and in the file
00018 ** GPL_EXCEPTION.txt in this package.
00019 **
00020 ** Please review the following information to ensure GNU General
00021 ** Public Licensing requirements will be met:
00022 ** http://trolltech.com/products/qt/licenses/licensing/opensource/. If
00023 ** you are unsure which license is appropriate for your use, please
00024 ** review the following information:
00025 ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
00026 ** or contact the sales department at sales@trolltech.com.
00027 **
00028 ** In addition, as a special exception, Trolltech, as the sole
00029 ** copyright holder for Qt Designer, grants users of the Qt/Eclipse
00030 ** Integration plug-in the right for the Qt/Eclipse Integration to
00031 ** link to functionality provided by Qt Designer and its related
00032 ** libraries.
00033 **
00034 ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
00035 ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
00036 ** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly
00037 ** granted herein.
00038 **
00039 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00040 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00041 **
00042 ****************************************************************************/
00043 
00044 #ifndef KDEVVARLENGTHARRAY_H
00045 #define KDEVVARLENGTHARRAY_H
00046 
00047 //#include <QtCore/qcontainerfwd.h>
00048 #include <QtCore/QtGlobal>
00049 #include <QtCore/QVector>
00050 #include <new>
00051 
00054 #define FOREACH_ARRAY(item, container) for(int a = 0, mustDo = 1; a < container.size(); ++a) if((mustDo == 0 || mustDo == 1) && (mustDo = 2)) for(item(container[a]); mustDo; mustDo = 0)
00055 
00056 QT_BEGIN_HEADER
00057 
00058 QT_BEGIN_NAMESPACE
00059 
00060 QT_MODULE(Core)
00061 
00062 //When this is uncommented, a QVector will be used instead of a variable-length array. This is useful for debugging, to find problems in KDevVarLengthArray
00063 // #define FAKE_KDEVVARLENGTH_ARRAY
00064 
00065 #ifdef FAKE_KDEVVARLENGTH_ARRAY
00066 template<class T, int Prealloc = 256>
00067 class KDevVarLengthArray : public QVector<T> {
00068     public:
00070     void insert(const T& item, int position) {
00071     QVector<T>::insert(position, item);
00072     }
00073 
00074     // Removes exactly one occurrence of the given value from the array. Returns false if none was found.
00075     bool removeOne(const T& value) {
00076     int i = this->indexOf(value);
00077     if(i == -1)
00078     return false;
00079     erase(i);
00080     return true;
00081     }
00082     void erase(int pos) {
00083     this->remove(pos);
00084     }
00085     void append(const T& item) {
00086         QVector<T>::append(item);
00087     }
00088     
00089     void pop_back() {
00090         Q_ASSERT(!this->isEmpty());
00091         QVector<T>::pop_back();
00092     }
00093     
00094     void append(const T *buf, int size) {
00095     for(int a = 0; a < size; ++a)
00096         append(buf[a]);
00097     }
00098 };
00099 #else
00100 
00101 template<class T, int Prealloc = 256>
00102 class KDevVarLengthArray
00103 {
00104 public:
00105     inline explicit KDevVarLengthArray(int size = 0);
00106 
00107     inline KDevVarLengthArray(const KDevVarLengthArray<T, Prealloc> &other)
00108         : a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array))
00109     {
00110         append(other.constData(), other.size());
00111     }
00112 
00113     inline ~KDevVarLengthArray() {
00114         if (QTypeInfo<T>::isComplex) {
00115             T *i = ptr + s;
00116             while (i-- > ptr)
00117                 i->~T();
00118         }
00119         if (ptr != reinterpret_cast<T *>(array))
00120             qFree(ptr);
00121     }
00122     inline KDevVarLengthArray<T, Prealloc> &operator=(const KDevVarLengthArray<T, Prealloc> &other)
00123     {
00124         if (this != &other) {
00125             clear();
00126             append(other.constData(), other.size());
00127         }
00128         return *this;
00129     }
00130 
00131     inline int size() const { return s; }
00132     inline int count() const { return s; }
00133     inline bool isEmpty() const { return (s == 0); }
00134     inline void resize(int size);
00135     inline void clear() { resize(0); }
00136 
00137     inline int capacity() const { return a; }
00138     inline void reserve(int size);
00139 
00140     inline T &operator[](int idx) {
00141         Q_ASSERT(idx >= 0 && idx < s);
00142         return ptr[idx];
00143     }
00144     inline const T &operator[](int idx) const {
00145         Q_ASSERT(idx >= 0 && idx < s);
00146         return ptr[idx];
00147     }
00148 
00150     int indexOf(const T& t) const {
00151         for(int a = 0; a < s; ++a)
00152             if(t == ptr[a])
00153                 return a;
00154         return -1;
00155     }
00156     
00157     inline KDevVarLengthArray& operator<<(const T &t) {
00158         append(t);
00159         return *this;
00160     }
00161 
00162     inline void append(const T &t) {
00163         const int idx = s++;
00165         if (s >= a)
00166             realloc(s, s<<1);
00167         if (QTypeInfo<T>::isComplex) {
00168             new (ptr + idx) T(t);
00169         } else {
00170             ptr[idx] = t;
00171         }
00172     }
00173     void append(const T *buf, int size);
00174 
00175     inline T *data() { return ptr; }
00176     inline const T *data() const { return ptr; }
00177     inline const T * constData() const { return ptr; }
00178 
00180     bool contains(const T& value) const {
00181       for(int a = 0; a < s; ++a)
00182           if(ptr[a] == value)
00183           return true;
00184 
00185       return false;
00186     }
00187 
00189     void insert(const T& item, int position) {
00190         Q_ASSERT(position >= 0 && position <= size());
00191         resize(s+1);
00192         for(int a = s-1; a > position; --a) {
00193             ptr[a] = ptr[a-1];
00194         }
00195         ptr[position] = item;
00196     }
00197 
00199     void erase(int position) {
00200         Q_ASSERT(position >= 0 && position < s);
00201         for(int a = position; a < s-1; ++a) {
00202             ptr[a] = ptr[a+1];
00203         }
00204         resize(s-1);
00205     }
00206 
00207     // Removes exactly one occurrence of the given value from the array. Returns false if none was found.
00208     bool removeOne(const T& value) {
00209     for(int a = 0; a < s; ++a) {
00210         if(ptr[a] == value) {
00211         erase(a);
00212         return true;
00213         }
00214     }
00215     return false;
00216     }
00217 
00218     T& back() {
00219         return ptr[s-1];
00220     }
00221 
00222     const T& back() const {
00223         return ptr[s-1];
00224     }
00225 
00226     void pop_back() {
00227         Q_ASSERT(s > 0);
00228         resize(s-1);
00229     }
00230 
00231 private:
00232     void realloc(int size, int alloc);
00233 
00234     int a;
00235     int s;
00236     T *ptr;
00237     union {
00238         // ### Qt 5: Use 'Prealloc * sizeof(T)' as array size
00239         char array[sizeof(qint64) * (((Prealloc * sizeof(T)) / sizeof(qint64)) + 1)];
00240         qint64 q_for_alignment_1;
00241         double q_for_alignment_2;
00242     };
00243 };
00244 
00245 template <class T, int Prealloc>
00246 Q_INLINE_TEMPLATE KDevVarLengthArray<T, Prealloc>::KDevVarLengthArray(int asize)
00247     : s(asize) {
00248     if (s > Prealloc) {
00249         ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T)));
00250         a = s;
00251     } else {
00252         ptr = reinterpret_cast<T *>(array);
00253         a = Prealloc;
00254     }
00255     if (QTypeInfo<T>::isComplex) {
00256         T *i = ptr + s;
00257         while (i != ptr)
00258             new (--i) T;
00259     }
00260 }
00261 
00262 template <class T, int Prealloc>
00263 Q_INLINE_TEMPLATE void KDevVarLengthArray<T, Prealloc>::resize(int asize)
00264 { Q_ASSERT(asize >= 0 && asize < 100000); realloc(asize, qMax(asize, a)); }
00265 
00266 template <class T, int Prealloc>
00267 Q_INLINE_TEMPLATE void KDevVarLengthArray<T, Prealloc>::reserve(int asize)
00268 { if (asize > a) realloc(s, asize); }
00269 
00270 template <class T, int Prealloc>
00271 Q_OUTOFLINE_TEMPLATE void KDevVarLengthArray<T, Prealloc>::append(const T *abuf, int asize)
00272 {
00273     Q_ASSERT(abuf);
00274     if (asize <= 0)
00275         return;
00276 
00277     const int idx = s;
00278     const int news = s + asize;
00279     if (news >= a)
00280         realloc(news, news<<1);
00281     else
00282         s = news;
00283 
00284     if (QTypeInfo<T>::isComplex) {
00285         T *i = ptr + idx;
00286         T *j = i + asize;
00287         while (i < j)
00288             new (i++) T(*abuf++);
00289     } else {
00290         qMemCopy(&ptr[idx], abuf, asize * sizeof(T));
00291     }
00292 }
00293 
00294 template <class T, int Prealloc>
00295 Q_OUTOFLINE_TEMPLATE void KDevVarLengthArray<T, Prealloc>::realloc(int asize, int aalloc)
00296 {
00297     Q_ASSERT(aalloc >= asize);
00298     T *oldPtr = ptr;
00299     int osize = s;
00300     s = asize;
00301 
00302     if (aalloc != a) {
00303         ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T)));
00304         if (ptr) {
00305             a = aalloc;
00306 
00307             if (QTypeInfo<T>::isStatic) {
00308                 T *i = ptr + osize;
00309                 T *j = oldPtr + osize;
00310                 while (i != ptr) {
00311                     new (--i) T(*--j);
00312                     j->~T();
00313                 }
00314             } else {
00315                 qMemCopy(ptr, oldPtr, osize * sizeof(T));
00316             }
00317         } else {
00318             ptr = oldPtr;
00319             s = 0;
00320             asize = 0;
00321         }
00322     }
00323 
00324     if (QTypeInfo<T>::isComplex) {
00325         if (asize < osize) {
00326             T *i = oldPtr + osize;
00327             T *j = oldPtr + asize;
00328             while (i-- != j)
00329                 i->~T();
00330         } else {
00331             T *i = ptr + asize;
00332             T *j = ptr + osize;
00333             while (i != j)
00334                 new (--i) T;
00335         }
00336     }
00337 
00338     if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
00339         qFree(oldPtr);
00340 }
00341 #endif
00342 QT_END_NAMESPACE
00343 
00344 QT_END_HEADER
00345 
00346 #endif // QVARLENGTHARRAY_H

util

Skip menu "util"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDevelop Platform Libraries

Skip menu "KDevelop Platform Libraries"
  • interfaces
  • language
  •   codegen
  •   duchain
  •   editor
  • outputview
  • project
  • shell
  • sublime
  • util
  • vcs
Generated for KDevelop Platform Libraries by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal