aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/ftw
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-07-12 15:22:40 +1000
committerQt by Nokia <qt-info@nokia.com>2011-08-30 13:18:28 +0200
commitf68290cb245ecddaa720ff6853511259e449e568 (patch)
treefdb2a765875b07dc2d19fd17e305780c9b6c2a1e /src/declarative/qml/ftw
parent71af1349f5498e1f6a213bacd531f4f77840f24f (diff)
Move tools classes into their own directory
Change-Id: Ic8a3a35f36259659cb83b5e11641af47bd8b18a9 Reviewed-on: http://codereview.qt.nokia.com/3743 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com> Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Diffstat (limited to 'src/declarative/qml/ftw')
-rw-r--r--src/declarative/qml/ftw/ftw.pri16
-rw-r--r--src/declarative/qml/ftw/qbitfield_p.h165
-rw-r--r--src/declarative/qml/ftw/qdeclarativerefcount.cpp70
-rw-r--r--src/declarative/qml/ftw/qdeclarativerefcount_p.h147
-rw-r--r--src/declarative/qml/ftw/qhashedstring.cpp103
-rw-r--r--src/declarative/qml/ftw/qhashedstring_p.h664
-rw-r--r--src/declarative/qml/ftw/qintrusivelist.cpp179
-rw-r--r--src/declarative/qml/ftw/qintrusivelist_p.h274
-rw-r--r--src/declarative/qml/ftw/qmetaobjectbuilder.cpp2601
-rw-r--r--src/declarative/qml/ftw/qmetaobjectbuilder_p.h325
-rw-r--r--src/declarative/qml/ftw/qpodvector_p.h173
11 files changed, 4717 insertions, 0 deletions
diff --git a/src/declarative/qml/ftw/ftw.pri b/src/declarative/qml/ftw/ftw.pri
new file mode 100644
index 0000000000..8709363363
--- /dev/null
+++ b/src/declarative/qml/ftw/ftw.pri
@@ -0,0 +1,16 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qbitfield_p.h \
+ $$PWD/qintrusivelist_p.h \
+ $$PWD/qmetaobjectbuilder_p.h \
+ $$PWD/qpodvector_p.h \
+ $$PWD/qhashedstring_p.h \
+ $$PWD/qdeclarativerefcount_p.h \
+
+SOURCES += \
+ $$PWD/qintrusivelist.cpp \
+ $$PWD/qmetaobjectbuilder.cpp \
+ $$PWD/qhashedstring.cpp \
+ $$PWD/qdeclarativerefcount.cpp \
+
diff --git a/src/declarative/qml/ftw/qbitfield_p.h b/src/declarative/qml/ftw/qbitfield_p.h
new file mode 100644
index 0000000000..67f578beda
--- /dev/null
+++ b/src/declarative/qml/ftw/qbitfield_p.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBITFIELD_P_H
+#define QBITFIELD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QBitField
+{
+public:
+ inline QBitField();
+ inline QBitField(const quint32 *, int bits);
+ inline QBitField(const QBitField &);
+ inline ~QBitField();
+
+ inline QBitField &operator=(const QBitField &);
+
+ inline quint32 size() const;
+ inline QBitField united(const QBitField &);
+ inline bool testBit(int) const;
+
+private:
+ quint32 bits:31;
+ quint32 *ownData;
+ const quint32 *data;
+};
+
+QBitField::QBitField()
+: bits(0), ownData(0), data(0)
+{
+}
+
+QBitField::QBitField(const quint32 *bitData, int bitCount)
+: bits((quint32)bitCount), ownData(0), data(bitData)
+{
+}
+
+QBitField::QBitField(const QBitField &other)
+: bits(other.bits), ownData(other.ownData), data(other.data)
+{
+ if (ownData)
+ ++(*ownData);
+}
+
+QBitField::~QBitField()
+{
+ if (ownData)
+ if(0 == --(*ownData)) delete [] ownData;
+}
+
+QBitField &QBitField::operator=(const QBitField &other)
+{
+ if (other.data == data)
+ return *this;
+
+ if (ownData)
+ if(0 == --(*ownData)) delete [] ownData;
+
+ bits = other.bits;
+ ownData = other.ownData;
+ data = other.data;
+
+ if (ownData)
+ ++(*ownData);
+
+ return *this;
+}
+
+inline quint32 QBitField::size() const
+{
+ return bits;
+}
+
+QBitField QBitField::united(const QBitField &o)
+{
+ if (o.bits == 0) {
+ return *this;
+ } else if (bits == 0) {
+ return o;
+ } else {
+ int max = (bits > o.bits)?bits:o.bits;
+ int length = (max + 31) / 32;
+ QBitField rv;
+ rv.bits = max;
+ rv.ownData = new quint32[length + 1];
+ *(rv.ownData) = 1;
+ rv.data = rv.ownData + 1;
+ if (bits > o.bits) {
+ ::memcpy((quint32 *)rv.data, data, length * sizeof(quint32));
+ for (quint32 ii = 0; ii < (o.bits + quint32(31)) / 32; ++ii)
+ ((quint32 *)rv.data)[ii] |= o.data[ii];
+ } else {
+ ::memcpy((quint32 *)rv.data, o.data, length * sizeof(quint32));
+ for (quint32 ii = 0; ii < (bits + quint32(31)) / 32; ++ii)
+ ((quint32 *)rv.data)[ii] |= data[ii];
+ }
+ return rv;
+ }
+}
+
+bool QBitField::testBit(int b) const
+{
+ Q_ASSERT(b >= 0);
+ if ((quint32)b < bits) {
+ return data[b / 32] & (1 << (b % 32));
+ } else {
+ return false;
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QBITFIELD_P_H
diff --git a/src/declarative/qml/ftw/qdeclarativerefcount.cpp b/src/declarative/qml/ftw/qdeclarativerefcount.cpp
new file mode 100644
index 0000000000..a17d5b7142
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativerefcount.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qdeclarativerefcount_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QDeclarativeRefCount::QDeclarativeRefCount()
+: refCount(1)
+{
+}
+
+QDeclarativeRefCount::~QDeclarativeRefCount()
+{
+}
+
+void QDeclarativeRefCount::addref()
+{
+ Q_ASSERT(refCount > 0);
+ ++refCount;
+}
+
+void QDeclarativeRefCount::release()
+{
+ Q_ASSERT(refCount > 0);
+ --refCount;
+ if (refCount == 0)
+ delete this;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/ftw/qdeclarativerefcount_p.h b/src/declarative/qml/ftw/qdeclarativerefcount_p.h
new file mode 100644
index 0000000000..381327098c
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativerefcount_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEREFCOUNT_P_H
+#define QDECLARATIVEREFCOUNT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_DECLARATIVE_EXPORT QDeclarativeRefCount
+{
+public:
+ QDeclarativeRefCount();
+ virtual ~QDeclarativeRefCount();
+ void addref();
+ void release();
+
+private:
+ int refCount;
+};
+
+template<class T>
+class QDeclarativeRefPointer
+{
+public:
+ inline QDeclarativeRefPointer();
+ inline QDeclarativeRefPointer(T *);
+ inline QDeclarativeRefPointer(const QDeclarativeRefPointer<T> &);
+ inline ~QDeclarativeRefPointer();
+
+ inline QDeclarativeRefPointer<T> &operator=(const QDeclarativeRefPointer<T> &o);
+ inline QDeclarativeRefPointer<T> &operator=(T *);
+
+ inline bool isNull() const { return !o; }
+
+ inline T* operator->() const { return o; }
+ inline T& operator*() const { return *o; }
+ inline operator T*() const { return o; }
+ inline T* data() const { return o; }
+
+private:
+ T *o;
+};
+
+template<class T>
+QDeclarativeRefPointer<T>::QDeclarativeRefPointer()
+: o(0)
+{
+}
+
+template<class T>
+QDeclarativeRefPointer<T>::QDeclarativeRefPointer(T *o)
+: o(o)
+{
+ if (o) o->addref();
+}
+
+template<class T>
+QDeclarativeRefPointer<T>::QDeclarativeRefPointer(const QDeclarativeRefPointer<T> &other)
+: o(other.o)
+{
+ if (o) o->addref();
+}
+
+template<class T>
+QDeclarativeRefPointer<T>::~QDeclarativeRefPointer()
+{
+ if (o) o->release();
+}
+
+template<class T>
+QDeclarativeRefPointer<T> &QDeclarativeRefPointer<T>::operator=(const QDeclarativeRefPointer<T> &other)
+{
+ if (other.o) other.o->addref();
+ if (o) o->release();
+ o = other.o;
+ return *this;
+}
+
+template<class T>
+QDeclarativeRefPointer<T> &QDeclarativeRefPointer<T>::operator=(T *other)
+{
+ if (other) other->addref();
+ if (o) o->release();
+ o = other;
+ return *this;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEREFCOUNT_P_H
diff --git a/src/declarative/qml/ftw/qhashedstring.cpp b/src/declarative/qml/ftw/qhashedstring.cpp
new file mode 100644
index 0000000000..2e2af98ff4
--- /dev/null
+++ b/src/declarative/qml/ftw/qhashedstring.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhashedstring_p.h"
+
+inline unsigned stringHash(const QChar* data, unsigned length)
+{
+ return v8::String::ComputeHash((uint16_t *)data, length);
+}
+
+void QHashedString::computeHash() const
+{
+ m_hash = stringHash(constData(), length());
+}
+
+void QHashedStringRef::computeHash() const
+{
+ m_hash = stringHash(m_data, m_length);
+}
+
+/*
+ A QHash has initially around pow(2, MinNumBits) buckets. For
+ example, if MinNumBits is 4, it has 17 buckets.
+*/
+const int MinNumBits = 4;
+
+/*
+ The prime_deltas array is a table of selected prime values, even
+ though it doesn't look like one. The primes we are using are 1,
+ 2, 5, 11, 17, 37, 67, 131, 257, ..., i.e. primes in the immediate
+ surrounding of a power of two.
+
+ The primeForNumBits() function returns the prime associated to a
+ power of two. For example, primeForNumBits(8) returns 257.
+*/
+
+static const uchar prime_deltas[] = {
+ 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
+ 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
+};
+
+static inline int primeForNumBits(int numBits)
+{
+ return (1 << numBits) + prime_deltas[numBits];
+}
+
+void QStringHashData::rehash()
+{
+ numBits = qMax(MinNumBits, numBits + 1);
+ numBuckets = primeForNumBits(numBits);
+
+ delete [] buckets;
+ buckets = new QStringHashNode *[numBuckets];
+ ::memset(buckets, 0, sizeof(QStringHashNode *) * numBuckets);
+
+ QStringHashNode *nodeList = nodes;
+ while (nodeList) {
+ int bucket = nodeList->key.hash() % numBuckets;
+ nodeList->next = buckets[bucket];
+ buckets[bucket] = nodeList;
+
+ nodeList = nodeList->nlist;
+ }
+}
+
diff --git a/src/declarative/qml/ftw/qhashedstring_p.h b/src/declarative/qml/ftw/qhashedstring_p.h
new file mode 100644
index 0000000000..e0ca1d466a
--- /dev/null
+++ b/src/declarative/qml/ftw/qhashedstring_p.h
@@ -0,0 +1,664 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHASHEDSTRING_P_H
+#define QHASHEDSTRING_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qstring.h>
+#include <private/qv8_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QHashedStringRef;
+class QHashedString : public QString
+{
+public:
+ inline QHashedString();
+ inline QHashedString(const QString &string);
+ inline QHashedString(const QString &string, quint32);
+ inline QHashedString(const QHashedString &string);
+
+ inline QHashedString &operator=(const QHashedString &string);
+ inline bool operator==(const QHashedString &string) const;
+ inline bool operator==(const QHashedStringRef &string) const;
+
+ inline quint32 hash() const;
+ inline quint32 existingHash() const;
+
+ static inline bool isUpper(const QChar &);
+private:
+ friend class QHashedStringRef;
+
+ void computeHash() const;
+ mutable quint32 m_hash;
+};
+
+class QHashedV8String
+{
+public:
+ inline QHashedV8String();
+ explicit inline QHashedV8String(v8::Handle<v8::String>);
+ inline QHashedV8String(const QHashedV8String &string);
+ inline QHashedV8String &operator=(const QHashedV8String &other);
+
+ inline bool operator==(const QHashedV8String &string);
+
+ inline quint32 hash() const;
+ inline int length() const;
+ inline quint32 symbolId() const;
+
+ inline v8::Handle<v8::String> string() const;
+
+private:
+ v8::String::CompleteHashData m_hash;
+ v8::Handle<v8::String> m_string;
+};
+
+class QHashedStringRef
+{
+public:
+ inline QHashedStringRef();
+ inline QHashedStringRef(const QString &);
+ inline QHashedStringRef(const QChar *, int);
+ inline QHashedStringRef(const QChar *, int, quint32);
+ inline QHashedStringRef(const QHashedString &);
+ inline QHashedStringRef(const QHashedStringRef &);
+
+ inline bool operator==(const QHashedString &string) const;
+ inline bool operator==(const QHashedStringRef &string) const;
+
+ inline quint32 hash() const;
+
+ inline const QChar *constData() const;
+ inline quint32 length() const;
+ inline bool startsWithUpper() const;
+
+private:
+ friend class QHashedString;
+
+ void computeHash() const;
+
+ const QChar *m_data;
+ quint32 m_length;
+ mutable quint32 m_hash;
+};
+
+class QStringHashData;
+class QStringHashNode
+{
+public:
+ QStringHashNode(const QHashedString &key)
+ : nlist(0), next(0), key(key), symbolId(0) {
+ }
+
+ QStringHashNode *nlist;
+ QStringHashNode *next;
+ QHashedString key;
+ quint32 symbolId;
+
+ inline bool equals(v8::Handle<v8::String> string) {
+ return string->Equals((uint16_t*)key.constData(), key.length());
+ }
+};
+
+struct QStringHashData
+{
+public:
+ QStringHashData()
+ : nodes(0), buckets(0), numBuckets(0), size(0), numBits(0) {}
+
+ QStringHashNode *nodes;
+ QStringHashNode **buckets;
+ int numBuckets;
+ int size;
+ short numBits;
+
+ void rehash();
+};
+
+template<class T>
+class QStringHash
+{
+private:
+ struct Node : public QStringHashNode {
+ Node(const QHashedString &key, const T &value) : QStringHashNode(key), value(value) {}
+ T value;
+ };
+
+ QStringHashData data;
+
+ inline Node *findNode(const QHashedStringRef &) const;
+ inline Node *findNode(const QHashedV8String &) const;
+ inline Node *findSymbolNode(const QHashedV8String &) const;
+ Node *createNode(const QHashedString &, const T &);
+
+public:
+ inline QStringHash();
+ inline QStringHash(const QStringHash &);
+ inline ~QStringHash();
+
+ QStringHash &operator=(const QStringHash<T> &);
+
+ inline bool isEmpty() const;
+ inline void clear();
+ inline int count() const;
+
+ inline void insert(const QString &, const T &);
+ inline void insert(const QHashedString &, const T &);
+ inline void insert(const QHashedStringRef &, const T &);
+
+ inline T *value(const QString &) const;
+ inline T *value(const QHashedString &) const;
+ inline T *value(const QHashedStringRef &) const;
+ inline T *value(const QHashedV8String &) const;
+
+ inline bool contains(const QString &) const;
+ inline bool contains(const QHashedString &) const;
+ inline bool contains(const QHashedStringRef &) const;
+
+ T &operator[](const QString &);
+ T &operator[](const QHashedString &);
+ T &operator[](const QHashedStringRef &);
+
+ class ConstIterator {
+ public:
+ ConstIterator() : n(0) {}
+ ConstIterator(Node *n) : n(n) {}
+
+ ConstIterator &operator++() { n = (Node *)n->nlist; return *this; }
+ bool operator==(const ConstIterator &o) const { return n == o.n; }
+ bool operator!=(const ConstIterator &o) const { return n != o.n; }
+
+ const QHashedString &key() const { return n->key; }
+ const T &value() const { return n->value; }
+ const T &operator*() const { return n->value; }
+ private:
+ Node *n;
+ };
+
+ ConstIterator begin() const { return ConstIterator((Node *)data.nodes); }
+ ConstIterator end() const { return ConstIterator(); }
+};
+
+template<class T>
+QStringHash<T>::QStringHash()
+{
+}
+
+template<class T>
+QStringHash<T>::QStringHash(const QStringHash<T> &other)
+: data(other.data)
+{
+ data.nodes = 0;
+ data.buckets = 0;
+
+ QStringHashNode *n = other.data.nodes;
+ while (n) {
+ Node *o = (Node *)n;
+ Node *mynode = new Node(o->key, o->value);
+ mynode->nlist = data.nodes;
+ data.nodes = mynode;
+ n = o->nlist;
+ }
+
+ data.rehash();
+}
+
+template<class T>
+QStringHash<T> &QStringHash<T>::operator=(const QStringHash<T> &other)
+{
+ if (&other == this)
+ return *this;
+
+ clear();
+ data = other.data;
+ data.nodes = 0;
+ data.buckets = 0;
+
+ QStringHashNode *n = other.data.nodes;
+ while (n) {
+ Node *o = (Node *)n;
+ Node *mynode = new Node(o->key, o->value);
+ mynode->nlist = data.nodes;
+ data.nodes = mynode;
+ n = o->nlist;
+ }
+
+ data.rehash();
+
+ return *this;
+}
+
+template<class T>
+QStringHash<T>::~QStringHash()
+{
+ clear();
+}
+
+template<class T>
+void QStringHash<T>::clear()
+{
+ QStringHashNode *n = data.nodes;
+ while (n) {
+ Node *o = (Node *)n;
+ n = n->nlist;
+ delete o;
+ }
+
+ delete [] data.buckets;
+
+ data = QStringHashData();
+}
+
+template<class T>
+bool QStringHash<T>::isEmpty() const
+{
+ return data.nodes == 0;
+}
+
+template<class T>
+int QStringHash<T>::count() const
+{
+ return data.size;
+}
+
+template<class T>
+typename QStringHash<T>::Node *QStringHash<T>::createNode(const QHashedString &key, const T &value)
+{
+ if (data.size == data.numBuckets)
+ data.rehash();
+
+ Node *n = new Node(key, value);
+ n->nlist = data.nodes;
+ data.nodes = n;
+
+ int bucket = key.hash() % data.numBuckets;
+ n->next = data.buckets[bucket];
+ data.buckets[bucket] = n;
+
+ data.size++;
+
+ return n;
+}
+
+template<class T>
+void QStringHash<T>::insert(const QString &key, const T &value)
+{
+ QHashedStringRef ch(key);
+ Node *n = findNode(key);
+ if (n) n->value = value;
+ else createNode(QHashedString(key, ch.hash()), value);
+}
+
+template<class T>
+void QStringHash<T>::insert(const QHashedString &key, const T &value)
+{
+ Node *n = findNode(key);
+ if (n) n->value = value;
+ else createNode(key, value);
+}
+
+template<class T>
+void QStringHash<T>::insert(const QHashedStringRef &key, const T &value)
+{
+ Node *n = findNode(key);
+ if (n) n->value = value;
+ else createNode(key, value);
+}
+
+template<class T>
+typename QStringHash<T>::Node *QStringHash<T>::findNode(const QHashedStringRef &string) const
+{
+ QStringHashNode *node = 0;
+ if (data.numBuckets) {
+ node = data.buckets[string.hash() % data.numBuckets];
+ while (node && !(node->key == string))
+ node = node->next;
+ }
+
+ return (Node *)node;
+}
+
+template<class T>
+typename QStringHash<T>::Node *QStringHash<T>::findNode(const QHashedV8String &string) const
+{
+ QStringHashNode *node = 0;
+ if (data.numBuckets) {
+ quint32 hash = string.hash();
+ node = data.buckets[hash % data.numBuckets];
+ int length = string.length();
+ while (node && (length != node->key.length() || hash != node->key.hash() || !node->equals(string.string())))
+ node = node->next;
+ }
+
+ return (Node *)node;
+}
+
+template<class T>
+typename QStringHash<T>::Node *QStringHash<T>::findSymbolNode(const QHashedV8String &string) const
+{
+ Q_ASSERT(string.symbolId() != 0);
+
+ QStringHashNode *node = 0;
+ if (data.numBuckets) {
+ quint32 hash = string.hash();
+ quint32 symbolId = string.symbolId();
+ node = data.buckets[hash % data.numBuckets];
+ int length = string.length();
+ while (node && (length != node->key.length() || hash != node->key.hash() ||
+ !(node->symbolId == symbolId || node->equals(string.string()))))
+ node = node->next;
+ if (node)
+ node->symbolId = symbolId;
+ }
+
+ return (Node *)node;
+}
+
+template<class T>
+T *QStringHash<T>::value(const QString &key) const
+{
+ Node *n = findNode(key);
+ return n?&n->value:0;
+}
+
+template<class T>
+T *QStringHash<T>::value(const QHashedString &key) const
+{
+ Node *n = findNode(key);
+ return n?&n->value:0;
+}
+
+template<class T>
+T *QStringHash<T>::value(const QHashedStringRef &key) const
+{
+ Node *n = findNode(key);
+ return n?&n->value:0;
+}
+
+template<class T>
+T *QStringHash<T>::value(const QHashedV8String &string) const
+{
+ Node *n = string.symbolId()?findSymbolNode(string):findNode(string);
+ return n?&n->value:0;
+}
+
+template<class T>
+bool QStringHash<T>::contains(const QString &s) const
+{
+ return 0 != value(s);
+}
+
+template<class T>
+bool QStringHash<T>::contains(const QHashedString &s) const
+{
+ return 0 != value(s);
+}
+template<class T>
+bool QStringHash<T>::contains(const QHashedStringRef &s) const
+{
+ return 0 != value(s);
+}
+
+template<class T>
+T &QStringHash<T>::operator[](const QString &key)
+{
+ QHashedStringRef cs(key);
+ Node *n = findNode(cs);
+ if (n) return n->value;
+ else return createNode(QHashedString(key, cs.hash()), T())->value;
+}
+
+template<class T>
+T &QStringHash<T>::operator[](const QHashedString &key)
+{
+ Node *n = findNode(key);
+ if (n) return n->value;
+ else return createNode(key, T())->value;
+}
+
+template<class T>
+T &QStringHash<T>::operator[](const QHashedStringRef &key)
+{
+ Node *n = findNode(key);
+ if (n) return n->value;
+ else return createNode(key, T())->value;
+}
+
+inline uint qHash(const QHashedString &string)
+{
+ return uint(string.hash());
+}
+
+inline uint qHash(const QHashedStringRef &string)
+{
+ return uint(string.hash());
+}
+
+QHashedString::QHashedString()
+: QString(), m_hash(0)
+{
+}
+
+QHashedString::QHashedString(const QString &string)
+: QString(string), m_hash(0)
+{
+}
+
+QHashedString::QHashedString(const QString &string, quint32 hash)
+: QString(string), m_hash(hash)
+{
+}
+
+QHashedString::QHashedString(const QHashedString &string)
+: QString(string), m_hash(string.m_hash)
+{
+}
+
+QHashedString &QHashedString::operator=(const QHashedString &string)
+{
+ static_cast<QString &>(*this) = string;
+ m_hash = string.m_hash;
+ return *this;
+}
+
+bool QHashedString::operator==(const QHashedString &string) const
+{
+ return (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
+ static_cast<const QString &>(*this) == static_cast<const QString &>(string);
+}
+
+bool QHashedString::operator==(const QHashedStringRef &string) const
+{
+ return (uint)length() == string.m_length &&
+ (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
+ 0 == ::memcmp(constData(), string.m_data, string.m_length * sizeof(QChar));
+}
+
+quint32 QHashedString::hash() const
+{
+ if (!m_hash) computeHash();
+ return m_hash;
+}
+
+quint32 QHashedString::existingHash() const
+{
+ return m_hash;
+}
+
+bool QHashedString::isUpper(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ // Optimize for _, a-z and A-Z.
+ return ((c != '_' ) && (!(c >= 'a' && c <= 'z')) &&
+ ((c >= 'A' && c <= 'Z') || QChar::category(c) == QChar::Letter_Uppercase));
+}
+
+QHashedV8String::QHashedV8String()
+{
+}
+
+QHashedV8String::QHashedV8String(v8::Handle<v8::String> string)
+: m_hash(string->CompleteHash()), m_string(string)
+{
+ Q_ASSERT(!m_string.IsEmpty());
+}
+
+QHashedV8String::QHashedV8String(const QHashedV8String &string)
+: m_hash(string.m_hash), m_string(string.m_string)
+{
+}
+
+QHashedV8String &QHashedV8String::operator=(const QHashedV8String &other)
+{
+ m_hash = other.m_hash;
+ m_string = other.m_string;
+ return *this;
+}
+
+bool QHashedV8String::operator==(const QHashedV8String &string)
+{
+ return m_hash.hash == string.m_hash.hash && m_hash.length == string.m_hash.length &&
+ m_string.IsEmpty() == m_string.IsEmpty() &&
+ (m_string.IsEmpty() || m_string->StrictEquals(string.m_string));
+}
+
+quint32 QHashedV8String::hash() const
+{
+ return m_hash.hash;
+}
+
+int QHashedV8String::length() const
+{
+ return m_hash.length;
+}
+
+quint32 QHashedV8String::symbolId() const
+{
+ return m_hash.symbol_id;
+}
+
+v8::Handle<v8::String> QHashedV8String::string() const
+{
+ return m_string;
+}
+
+QHashedStringRef::QHashedStringRef()
+: m_data(0), m_length(0), m_hash(0)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QString &str)
+: m_data(str.constData()), m_length(str.length()), m_hash(0)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QChar *data, int length)
+: m_data(data), m_length(length), m_hash(0)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
+: m_data(data), m_length(length), m_hash(hash)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QHashedString &string)
+: m_data(string.constData()), m_length(string.length()), m_hash(string.m_hash)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QHashedStringRef &string)
+: m_data(string.m_data), m_length(string.m_length), m_hash(string.m_hash)
+{
+}
+
+bool QHashedStringRef::operator==(const QHashedString &string) const
+{
+ return m_length == (uint)string.length() &&
+ (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
+ 0 == ::memcmp(string.constData(), m_data, m_length * sizeof(QChar));
+}
+
+bool QHashedStringRef::operator==(const QHashedStringRef &string) const
+{
+ return m_length == string.m_length &&
+ (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
+ 0 == ::memcmp(string.m_data, m_data, m_length * sizeof(QChar));
+}
+
+const QChar *QHashedStringRef::constData() const
+{
+ return m_data;
+}
+
+quint32 QHashedStringRef::length() const
+{
+ return m_length;
+}
+
+bool QHashedStringRef::startsWithUpper() const
+{
+ if (m_length < 1) return false;
+ return QHashedString::isUpper(m_data[0]);
+}
+
+quint32 QHashedStringRef::hash() const
+{
+ if (!m_hash) computeHash();
+ return m_hash;
+}
+
+QT_END_NAMESPACE
+
+#endif // QHASHEDSTRING_P_H
diff --git a/src/declarative/qml/ftw/qintrusivelist.cpp b/src/declarative/qml/ftw/qintrusivelist.cpp
new file mode 100644
index 0000000000..dabb893e91
--- /dev/null
+++ b/src/declarative/qml/ftw/qintrusivelist.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qintrusivelist_p.h"
+
+/*!
+\class QIntrusiveList
+\brief The QIntrusiveList class is a template class that provides a list of objects using static storage.
+\internal
+
+QIntrusiveList creates a linked list of objects. Adding and removing objects from the
+QIntrusiveList is a constant time operation and is very quick. The list performs no memory
+allocations, but does require the objects being added to the list to contain a QIntrusiveListNode
+instance for the list's use. Even so, for small lists QIntrusiveList uses less memory than Qt's
+other list classes.
+
+As QIntrusiveList uses storage inside the objects in the list, each object can only be in one
+list at a time. Objects are inserted by the insert() method. If the object is already
+in a list (including the one it is being inserted into) it is first removed, and then inserted
+at the head of the list. QIntrusiveList is a last-in-first-out list. That is, following an
+insert() the inserted object becomes the list's first() object.
+
+\code
+struct MyObject {
+ MyObject(int value) : value(value) {}
+
+ int value;
+ QIntrusiveListNode node;
+};
+typedef QIntrusiveList<MyObject, &MyObject::node> MyObjectList;
+
+void foo() {
+ MyObjectList list;
+
+ MyObject m0(0);
+ MyObject m1(1);
+ MyObject m2(2);
+
+ list.insert(&m0);
+ list.insert(&m1);
+ list.insert(&m2);
+
+ // QIntrusiveList is LIFO, so will print: 2... 1... 0...
+ for (MyObjectList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ qWarning() << iter->value;
+ }
+}
+\endcode
+*/
+
+
+/*!
+\fn QIntrusiveList::QIntrusiveList();
+
+Construct an empty list.
+*/
+
+/*!
+\fn QIntrusiveList::~QIntrusiveList();
+
+Destroy the list. All entries are removed.
+*/
+
+/*!
+\fn void QIntrusiveList::insert(N *object);
+
+Insert \a object into the list. If \a object is a member of this, or another list, it will be
+removed and inserted at the head of this list.
+*/
+
+/*!
+\fn void QIntrusiveList::remove(N *object);
+
+Remove \a object from the list. \a object must not be null.
+*/
+
+/*!
+\fn bool QIntrusiveList::contains(N *object) const
+
+Returns true if the list contains \a object; otherwise returns false.
+*/
+
+/*!
+\fn N *QIntrusiveList::first() const
+
+Returns the first entry in this list, or null if the list is empty.
+*/
+
+/*!
+\fn N *QIntrusiveList::next(N *current)
+
+Returns the next object after \a current, or null if \a current is the last object. \a current cannot be null.
+*/
+
+/*!
+\fn iterator QIntrusiveList::begin()
+
+Returns an STL-style interator pointing to the first item in the list.
+
+\sa end()
+*/
+
+/*!
+\fn iterator QIntrusiveList::end()
+
+Returns an STL-style iterator pointing to the imaginary item after the last item in the list.
+
+\sa begin()
+*/
+
+/*!
+iterator &QInplacelist::iterator::erase()
+
+Remove the current object from the list, and return an iterator to the next element.
+*/
+
+
+/*!
+\fn QIntrusiveListNode::QIntrusiveListNode()
+
+Create a QIntrusiveListNode.
+*/
+
+/*!
+\fn QIntrusiveListNode::~QIntrusiveListNode()
+
+Destroy the QIntrusiveListNode. If the node is in a list, it is removed.
+*/
+
+/*!
+\fn void QIntrusiveListNode::remove()
+
+If in a list, remove this node otherwise do nothing.
+*/
+
+/*!
+\fn bool QIntrusiveListNode::isInList() const
+
+Returns true if this node is in a list, false otherwise.
+*/
+
diff --git a/src/declarative/qml/ftw/qintrusivelist_p.h b/src/declarative/qml/ftw/qintrusivelist_p.h
new file mode 100644
index 0000000000..717b11c344
--- /dev/null
+++ b/src/declarative/qml/ftw/qintrusivelist_p.h
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QINTRUSIVELIST_P_H
+#define QINTRUSIVELIST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIntrusiveListNode;
+template<class N, QIntrusiveListNode N::*member>
+class QIntrusiveList
+{
+public:
+ inline QIntrusiveList();
+ inline ~QIntrusiveList();
+
+ inline bool isEmpty() const;
+ inline void insert(N *n);
+ inline void remove(N *n);
+ inline bool contains(N *) const;
+
+ class iterator {
+ public:
+ inline iterator();
+ inline iterator(N *value);
+
+ inline N *operator*() const;
+ inline N *operator->() const;
+ inline bool operator==(const iterator &other) const;
+ inline bool operator!=(const iterator &other) const;
+ inline iterator &operator++();
+
+ inline iterator &erase();
+
+ private:
+ N *_value;
+ };
+ typedef iterator Iterator;
+
+ inline N *first() const;
+ static inline N *next(N *current);
+
+ inline iterator begin();
+ inline iterator end();
+
+private:
+ static inline N *nodeToN(QIntrusiveListNode *node);
+
+ QIntrusiveListNode *__first;
+};
+
+class QIntrusiveListNode
+{
+public:
+ inline QIntrusiveListNode();
+ inline ~QIntrusiveListNode();
+
+ inline void remove();
+ inline bool isInList() const;
+
+ QIntrusiveListNode *_next;
+ QIntrusiveListNode**_prev;
+};
+
+template<class N, QIntrusiveListNode N::*member>
+QIntrusiveList<N, member>::iterator::iterator()
+: _value(0)
+{
+}
+
+template<class N, QIntrusiveListNode N::*member>
+QIntrusiveList<N, member>::iterator::iterator(N *value)
+: _value(value)
+{
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::iterator::operator*() const
+{
+ return _value;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::iterator::operator->() const
+{
+ return _value;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+bool QIntrusiveList<N, member>::iterator::operator==(const iterator &other) const
+{
+ return other._value == _value;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+bool QIntrusiveList<N, member>::iterator::operator!=(const iterator &other) const
+{
+ return other._value != _value;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::operator++()
+{
+ _value = QIntrusiveList<N, member>::next(_value);
+ return *this;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::erase()
+{
+ N *old = _value;
+ _value = QIntrusiveList<N, member>::next(_value);
+ (old->*member).remove();
+ return *this;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+QIntrusiveList<N, member>::QIntrusiveList()
+: __first(0)
+{
+}
+
+template<class N, QIntrusiveListNode N::*member>
+QIntrusiveList<N, member>::~QIntrusiveList()
+{
+ while (__first) __first->remove();
+}
+
+template<class N, QIntrusiveListNode N::*member>
+bool QIntrusiveList<N, member>::isEmpty() const
+{
+ return __first == 0;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+void QIntrusiveList<N, member>::insert(N *n)
+{
+ QIntrusiveListNode *nnode = &(n->*member);
+ nnode->remove();
+
+ nnode->_next = __first;
+ if (nnode->_next) nnode->_next->_prev = &nnode->_next;
+ __first = nnode;
+ nnode->_prev = &__first;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+void QIntrusiveList<N, member>::remove(N *n)
+{
+ QIntrusiveListNode *nnode = &(n->*member);
+ nnode->remove();
+}
+
+template<class N, QIntrusiveListNode N::*member>
+bool QIntrusiveList<N, member>::contains(N *n) const
+{
+ QIntrusiveListNode *nnode = __first;
+ while (nnode) {
+ if (nodeToN(nnode) == n)
+ return true;
+ nnode = nnode->_next;
+ }
+ return false;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::first() const
+{
+ return __first?nodeToN(__first):0;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::next(N *current)
+{
+ QIntrusiveListNode *nextnode = (current->*member)._next;
+ N *nextstruct = nextnode?nodeToN(nextnode):0;
+ return nextstruct;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::begin()
+{
+ return __first?iterator(nodeToN(__first)):iterator();
+}
+
+template<class N, QIntrusiveListNode N::*member>
+typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::end()
+{
+ return iterator();
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::nodeToN(QIntrusiveListNode *node)
+{
+ return (N *)((char *)node - ((char *)&(((N *)0)->*member) - (char *)0));
+}
+
+QIntrusiveListNode::QIntrusiveListNode()
+: _next(0), _prev(0)
+{
+}
+
+QIntrusiveListNode::~QIntrusiveListNode()
+{
+ remove();
+}
+
+void QIntrusiveListNode::remove()
+{
+ if (_prev) *_prev = _next;
+ if (_next) _next->_prev = _prev;
+ _prev = 0;
+ _next = 0;
+}
+
+bool QIntrusiveListNode::isInList() const
+{
+ return _prev != 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // QINTRUSIVELIST_P_H
diff --git a/src/declarative/qml/ftw/qmetaobjectbuilder.cpp b/src/declarative/qml/ftw/qmetaobjectbuilder.cpp
new file mode 100644
index 0000000000..f5e8369ebc
--- /dev/null
+++ b/src/declarative/qml/ftw/qmetaobjectbuilder.cpp
@@ -0,0 +1,2601 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qmetaobjectbuilder_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QMetaObjectBuilder
+ \internal
+ \brief The QMetaObjectBuilder class supports building QMetaObject objects at runtime.
+
+*/
+
+/*!
+ \enum QMetaObjectBuilder::AddMember
+ This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject()
+
+ \value ClassName Add the class name.
+ \value SuperClass Add the super class.
+ \value Methods Add methods that aren't signals or slots.
+ \value Signals Add signals.
+ \value Slots Add slots.
+ \value Constructors Add constructors.
+ \value Properties Add properties.
+ \value Enumerators Add enumerators.
+ \value ClassInfos Add items of class information.
+ \value RelatedMetaObjects Add related meta objects.
+ \value StaticMetacall Add the static metacall function.
+ \value PublicMethods Add public methods (ignored for signals).
+ \value ProtectedMethods Add protected methods (ignored for signals).
+ \value PrivateMethods All private methods (ignored for signals).
+ \value AllMembers Add all members.
+ \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function.
+*/
+
+// copied from moc's generator.cpp
+uint qvariant_nameToType(const char* name)
+{
+ if (!name)
+ return 0;
+
+ if (strcmp(name, "QVariant") == 0)
+ return 0xffffffff;
+ if (strcmp(name, "QCString") == 0)
+ return QMetaType::QByteArray;
+ if (strcmp(name, "Q_LLONG") == 0)
+ return QMetaType::LongLong;
+ if (strcmp(name, "Q_ULLONG") == 0)
+ return QMetaType::ULongLong;
+ if (strcmp(name, "QIconSet") == 0)
+ return QMetaType::QIcon;
+
+ uint tp = QMetaType::type(name);
+ return tp < QMetaType::User ? tp : 0;
+}
+
+/*
+ Returns true if the type is a QVariant types.
+*/
+bool isVariantType(const char* type)
+{
+ return qvariant_nameToType(type) != 0;
+}
+
+// copied from qmetaobject_p.h
+// do not touch without touching the moc as well
+enum PropertyFlags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ Resettable = 0x00000004,
+ EnumOrFlag = 0x00000008,
+ StdCppSet = 0x00000100,
+// Override = 0x00000200,
+ Constant = 0x00000400,
+ Final = 0x00000800,
+ Designable = 0x00001000,
+ ResolveDesignable = 0x00002000,
+ Scriptable = 0x00004000,
+ ResolveScriptable = 0x00008000,
+ Stored = 0x00010000,
+ ResolveStored = 0x00020000,
+ Editable = 0x00040000,
+ ResolveEditable = 0x00080000,
+ User = 0x00100000,
+ ResolveUser = 0x00200000,
+ Notify = 0x00400000,
+ Revisioned = 0x00800000
+};
+
+enum MethodFlags {
+ AccessPrivate = 0x00,
+ AccessProtected = 0x01,
+ AccessPublic = 0x02,
+ AccessMask = 0x03, //mask
+
+ MethodMethod = 0x00,
+ MethodSignal = 0x04,
+ MethodSlot = 0x08,
+ MethodConstructor = 0x0c,
+ MethodTypeMask = 0x0c,
+
+ MethodCompatibility = 0x10,
+ MethodCloned = 0x20,
+ MethodScriptable = 0x40,
+ MethodRevisioned = 0x80
+};
+
+struct QMetaObjectPrivate
+{
+ int revision;
+ int className;
+ int classInfoCount, classInfoData;
+ int methodCount, methodData;
+ int propertyCount, propertyData;
+ int enumeratorCount, enumeratorData;
+ int constructorCount, constructorData;
+ int flags;
+};
+
+static inline const QMetaObjectPrivate *priv(const uint* data)
+{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
+// end of copied lines from qmetaobject.cpp
+
+class QMetaMethodBuilderPrivate
+{
+public:
+ QMetaMethodBuilderPrivate
+ (QMetaMethod::MethodType _methodType,
+ const QByteArray& _signature,
+ const QByteArray& _returnType = QByteArray(),
+ QMetaMethod::Access _access = QMetaMethod::Public)
+ : signature(QMetaObject::normalizedSignature(_signature.constData())),
+ returnType(QMetaObject::normalizedType(_returnType)),
+ attributes(((int)_access) | (((int)_methodType) << 2))
+ {
+ }
+
+ QByteArray signature;
+ QByteArray returnType;
+ QList<QByteArray> parameterNames;
+ QByteArray tag;
+ int attributes;
+
+ QMetaMethod::MethodType methodType() const
+ {
+ return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2);
+ }
+
+ QMetaMethod::Access access() const
+ {
+ return (QMetaMethod::Access)(attributes & AccessMask);
+ }
+
+ void setAccess(QMetaMethod::Access value)
+ {
+ attributes = ((attributes & ~AccessMask) | (int)value);
+ }
+};
+
+class QMetaPropertyBuilderPrivate
+{
+public:
+ QMetaPropertyBuilderPrivate
+ (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1)
+ : name(_name),
+ type(QMetaObject::normalizedType(_type.constData())),
+ flags(Readable | Writable | Scriptable), notifySignal(-1)
+ {
+ if (notifierIdx >= 0) {
+ flags |= Notify;
+ notifySignal = notifierIdx;
+ }
+ }
+
+ QByteArray name;
+ QByteArray type;
+ int flags;
+ int notifySignal;
+
+ bool flag(int f) const
+ {
+ return ((flags & f) != 0);
+ }
+
+ void setFlag(int f, bool value)
+ {
+ if (value)
+ flags |= f;
+ else
+ flags &= ~f;
+ }
+};
+
+class QMetaEnumBuilderPrivate
+{
+public:
+ QMetaEnumBuilderPrivate(const QByteArray& _name)
+ : name(_name), isFlag(false)
+ {
+ }
+
+ QByteArray name;
+ bool isFlag;
+ QList<QByteArray> keys;
+ QList<int> values;
+};
+
+class QMetaObjectBuilderPrivate
+{
+public:
+ QMetaObjectBuilderPrivate()
+ : flags(0)
+ {
+ superClass = &QObject::staticMetaObject;
+ staticMetacallFunction = 0;
+ }
+
+ QByteArray className;
+ const QMetaObject *superClass;
+ QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction;
+ QList<QMetaMethodBuilderPrivate> methods;
+ QList<QMetaMethodBuilderPrivate> constructors;
+ QList<QMetaPropertyBuilderPrivate> properties;
+ QList<QByteArray> classInfoNames;
+ QList<QByteArray> classInfoValues;
+ QList<QMetaEnumBuilderPrivate> enumerators;
+#ifdef Q_NO_DATA_RELOCATION
+ QList<QMetaObjectAccessor> relatedMetaObjects;
+#else
+ QList<const QMetaObject *> relatedMetaObjects;
+#endif
+ int flags;
+};
+
+/*!
+ Constructs a new QMetaObjectBuilder.
+*/
+QMetaObjectBuilder::QMetaObjectBuilder()
+{
+ d = new QMetaObjectBuilderPrivate();
+}
+
+/*!
+ Constructs a new QMetaObjectBuilder which is a copy of the
+ meta object information in \a prototype. Note: the super class
+ contents for \a prototype are not copied, only the immediate
+ class that is defined by \a prototype.
+
+ The \a members parameter indicates which members of \a prototype
+ should be added. The default is AllMembers.
+
+ \sa addMetaObject()
+*/
+QMetaObjectBuilder::QMetaObjectBuilder
+ (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members)
+{
+ d = new QMetaObjectBuilderPrivate();
+ addMetaObject(prototype, members);
+}
+
+/*!
+ Destroys this meta object builder.
+*/
+QMetaObjectBuilder::~QMetaObjectBuilder()
+{
+ delete d;
+}
+
+/*!
+ Returns the name of the class being constructed by this
+ meta object builder. The default value is an empty QByteArray.
+
+ \sa setClassName(), superClass()
+*/
+QByteArray QMetaObjectBuilder::className() const
+{
+ return d->className;
+}
+
+/*!
+ Sets the \a name of the class being constructed by this
+ meta object builder.
+
+ \sa className(), setSuperClass()
+*/
+void QMetaObjectBuilder::setClassName(const QByteArray& name)
+{
+ d->className = name;
+}
+
+/*!
+ Returns the superclass meta object of the class being constructed
+ by this meta object builder. The default value is the meta object
+ for QObject.
+
+ \sa setSuperClass(), className()
+*/
+const QMetaObject *QMetaObjectBuilder::superClass() const
+{
+ return d->superClass;
+}
+
+/*!
+ Sets the superclass meta object of the class being constructed
+ by this meta object builder to \a meta. The \a meta parameter
+ must not be null.
+
+ \sa superClass(), setClassName()
+*/
+void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta)
+{
+ Q_ASSERT(meta);
+ d->superClass = meta;
+}
+
+/*!
+ Returns the flags of the class being constructed by this meta object
+ builder.
+
+ \sa setFlags()
+*/
+QMetaObjectBuilder::MetaObjectFlags QMetaObjectBuilder::flags() const
+{
+ return (QMetaObjectBuilder::MetaObjectFlags)d->flags;
+}
+
+/*!
+ Sets the \a flags of the class being constructed by this meta object
+ builder.
+
+ \sa flags()
+*/
+void QMetaObjectBuilder::setFlags(MetaObjectFlags flags)
+{
+ d->flags = flags;
+}
+
+/*!
+ Returns the number of methods in this class, excluding the number
+ of methods in the base class. These include signals and slots
+ as well as normal member functions.
+
+ \sa addMethod(), method(), removeMethod(), indexOfMethod()
+*/
+int QMetaObjectBuilder::methodCount() const
+{
+ return d->methods.size();
+}
+
+/*!
+ Returns the number of constructors in this class.
+
+ \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor()
+*/
+int QMetaObjectBuilder::constructorCount() const
+{
+ return d->constructors.size();
+}
+
+/*!
+ Returns the number of properties in this class, excluding the number
+ of properties in the base class.
+
+ \sa addProperty(), property(), removeProperty(), indexOfProperty()
+*/
+int QMetaObjectBuilder::propertyCount() const
+{
+ return d->properties.size();
+}
+
+/*!
+ Returns the number of enumerators in this class, excluding the
+ number of enumerators in the base class.
+
+ \sa addEnumerator(), enumerator(), removeEnumerator()
+ \sa indexOfEnumerator()
+*/
+int QMetaObjectBuilder::enumeratorCount() const
+{
+ return d->enumerators.size();
+}
+
+/*!
+ Returns the number of items of class information in this class,
+ exclusing the number of items of class information in the base class.
+
+ \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo()
+ \sa indexOfClassInfo()
+*/
+int QMetaObjectBuilder::classInfoCount() const
+{
+ return d->classInfoNames.size();
+}
+
+/*!
+ Returns the number of related meta objects that are associated
+ with this class.
+
+ Related meta objects are used when resolving the enumerated type
+ associated with a property, where the enumerated type is in a
+ different class from the property.
+
+ \sa addRelatedMetaObject(), relatedMetaObject()
+ \sa removeRelatedMetaObject()
+*/
+int QMetaObjectBuilder::relatedMetaObjectCount() const
+{
+ return d->relatedMetaObjects.size();
+}
+
+/*!
+ Adds a new public method to this class with the specified \a signature.
+ Returns an object that can be used to adjust the other attributes
+ of the method. The \a signature will be normalized before it is
+ added to the class.
+
+ \sa method(), methodCount(), removeMethod(), indexOfMethod()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature)
+{
+ int index = d->methods.size();
+ d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature));
+ return QMetaMethodBuilder(this, index);
+}
+
+/*!
+ Adds a new public method to this class with the specified
+ \a signature and \a returnType. Returns an object that can be
+ used to adjust the other attributes of the method. The \a signature
+ and \a returnType will be normalized before they are added to
+ the class. If \a returnType is empty, then it indicates that
+ the method has \c{void} as its return type.
+
+ \sa method(), methodCount(), removeMethod(), indexOfMethod()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::addMethod
+ (const QByteArray& signature, const QByteArray& returnType)
+{
+ int index = d->methods.size();
+ d->methods.append(QMetaMethodBuilderPrivate
+ (QMetaMethod::Method, signature, returnType));
+ return QMetaMethodBuilder(this, index);
+}
+
+/*!
+ Adds a new public method to this class that has the same information as
+ \a prototype. This is used to clone the methods of an existing
+ QMetaObject. Returns an object that can be used to adjust the
+ attributes of the method.
+
+ This function will detect if \a prototype is an ordinary method,
+ signal, slot, or constructor and act accordingly.
+
+ \sa method(), methodCount(), removeMethod(), indexOfMethod()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
+{
+ QMetaMethodBuilder method;
+ if (prototype.methodType() == QMetaMethod::Method)
+ method = addMethod(prototype.signature());
+ else if (prototype.methodType() == QMetaMethod::Signal)
+ method = addSignal(prototype.signature());
+ else if (prototype.methodType() == QMetaMethod::Slot)
+ method = addSlot(prototype.signature());
+ else if (prototype.methodType() == QMetaMethod::Constructor)
+ method = addConstructor(prototype.signature());
+ method.setReturnType(prototype.typeName());
+ method.setParameterNames(prototype.parameterNames());
+ method.setTag(prototype.tag());
+ method.setAccess(prototype.access());
+ method.setAttributes(prototype.attributes());
+ return method;
+}
+
+/*!
+ Adds a new public slot to this class with the specified \a signature.
+ Returns an object that can be used to adjust the other attributes
+ of the slot. The \a signature will be normalized before it is
+ added to the class.
+
+ \sa addMethod(), addSignal(), indexOfSlot()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray& signature)
+{
+ int index = d->methods.size();
+ d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature));
+ return QMetaMethodBuilder(this, index);
+}
+
+/*!
+ Adds a new signal to this class with the specified \a signature.
+ Returns an object that can be used to adjust the other attributes
+ of the signal. The \a signature will be normalized before it is
+ added to the class.
+
+ \sa addMethod(), addSlot(), indexOfSignal()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
+{
+ int index = d->methods.size();
+ d->methods.append(QMetaMethodBuilderPrivate
+ (QMetaMethod::Signal, signature, QByteArray(), QMetaMethod::Protected));
+ return QMetaMethodBuilder(this, index);
+}
+
+/*!
+ Adds a new constructor to this class with the specified \a signature.
+ Returns an object that can be used to adjust the other attributes
+ of the constructor. The \a signature will be normalized before it is
+ added to the class.
+
+ \sa constructor(), constructorCount(), removeConstructor()
+ \sa indexOfConstructor()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature)
+{
+ int index = d->constructors.size();
+ d->constructors.append(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature));
+ return QMetaMethodBuilder(this, -(index + 1));
+}
+
+/*!
+ Adds a new constructor to this class that has the same information as
+ \a prototype. This is used to clone the constructors of an existing
+ QMetaObject. Returns an object that can be used to adjust the
+ attributes of the constructor.
+
+ This function requires that \a prototype be a constructor.
+
+ \sa constructor(), constructorCount(), removeConstructor()
+ \sa indexOfConstructor()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
+{
+ Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
+ QMetaMethodBuilder ctor = addConstructor(prototype.signature());
+ ctor.setReturnType(prototype.typeName());
+ ctor.setParameterNames(prototype.parameterNames());
+ ctor.setTag(prototype.tag());
+ ctor.setAccess(prototype.access());
+ ctor.setAttributes(prototype.attributes());
+ return ctor;
+}
+
+/*!
+ Adds a new readable/writable property to this class with the
+ specified \a name and \a type. Returns an object that can be used
+ to adjust the other attributes of the property. The \a type will
+ be normalized before it is added to the class. \a notifierId will
+ be registered as the property's \e notify signal.
+
+ \sa property(), propertyCount(), removeProperty(), indexOfProperty()
+*/
+QMetaPropertyBuilder QMetaObjectBuilder::addProperty
+ (const QByteArray& name, const QByteArray& type, int notifierId)
+{
+ int index = d->properties.size();
+ d->properties.append(QMetaPropertyBuilderPrivate(name, type, notifierId));
+ return QMetaPropertyBuilder(this, index);
+}
+
+/*!
+ Adds a new property to this class that has the same information as
+ \a prototype. This is used to clone the properties of an existing
+ QMetaObject. Returns an object that can be used to adjust the
+ attributes of the property.
+
+ \sa property(), propertyCount(), removeProperty(), indexOfProperty()
+*/
+QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& prototype)
+{
+ QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName());
+ property.setReadable(prototype.isReadable());
+ property.setWritable(prototype.isWritable());
+ property.setResettable(prototype.isResettable());
+ property.setDesignable(prototype.isDesignable());
+ property.setScriptable(prototype.isScriptable());
+ property.setStored(prototype.isStored());
+ property.setEditable(prototype.isEditable());
+ property.setUser(prototype.isUser());
+ property.setStdCppSet(prototype.hasStdCppSet());
+ property.setEnumOrFlag(prototype.isEnumType());
+ property.setConstant(prototype.isConstant());
+ property.setFinal(prototype.isFinal());
+ if (prototype.hasNotifySignal()) {
+ // Find an existing method for the notify signal, or add a new one.
+ QMetaMethod method = prototype.notifySignal();
+ int index = indexOfMethod(method.signature());
+ if (index == -1)
+ index = addMethod(method).index();
+ d->properties[property._index].notifySignal = index;
+ d->properties[property._index].setFlag(Notify, true);
+ }
+ return property;
+}
+
+/*!
+ Adds a new enumerator to this class with the specified
+ \a name. Returns an object that can be used to adjust
+ the other attributes of the enumerator.
+
+ \sa enumerator(), enumeratorCount(), removeEnumerator(),
+ \sa indexOfEnumerator()
+*/
+QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name)
+{
+ int index = d->enumerators.size();
+ d->enumerators.append(QMetaEnumBuilderPrivate(name));
+ return QMetaEnumBuilder(this, index);
+}
+
+/*!
+ Adds a new enumerator to this class that has the same information as
+ \a prototype. This is used to clone the enumerators of an existing
+ QMetaObject. Returns an object that can be used to adjust the
+ attributes of the enumerator.
+
+ \sa enumerator(), enumeratorCount(), removeEnumerator(),
+ \sa indexOfEnumerator()
+*/
+QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype)
+{
+ QMetaEnumBuilder en = addEnumerator(prototype.name());
+ en.setIsFlag(prototype.isFlag());
+ int count = prototype.keyCount();
+ for (int index = 0; index < count; ++index)
+ en.addKey(prototype.key(index), prototype.value(index));
+ return en;
+}
+
+/*!
+ Adds \a name and \a value as an item of class information to this class.
+ Returns the index of the new item of class information.
+
+ \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo()
+ \sa indexOfClassInfo()
+*/
+int QMetaObjectBuilder::addClassInfo(const QByteArray& name, const QByteArray& value)
+{
+ int index = d->classInfoNames.size();
+ d->classInfoNames += name;
+ d->classInfoValues += value;
+ return index;
+}
+
+/*!
+ Adds \a meta to this class as a related meta object. Returns
+ the index of the new related meta object entry.
+
+ Related meta objects are used when resolving the enumerated type
+ associated with a property, where the enumerated type is in a
+ different class from the property.
+
+ \sa relatedMetaObjectCount(), relatedMetaObject()
+ \sa removeRelatedMetaObject()
+*/
+#ifdef Q_NO_DATA_RELOCATION
+int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObjectAccessor &meta)
+#else
+int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta)
+#endif
+{
+ Q_ASSERT(meta);
+ int index = d->relatedMetaObjects.size();
+ d->relatedMetaObjects.append(meta);
+ return index;
+}
+
+/*!
+ Adds the contents of \a prototype to this meta object builder.
+ This function is useful for cloning the contents of an existing QMetaObject.
+
+ The \a members parameter indicates which members of \a prototype
+ should be added. The default is AllMembers.
+*/
+void QMetaObjectBuilder::addMetaObject
+ (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members)
+{
+ Q_ASSERT(prototype);
+ int index;
+
+ if ((members & ClassName) != 0)
+ d->className = prototype->className();
+
+ if ((members & SuperClass) != 0)
+ d->superClass = prototype->superClass();
+
+ if ((members & (Methods | Signals | Slots)) != 0) {
+ for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) {
+ QMetaMethod method = prototype->method(index);
+ if (method.methodType() != QMetaMethod::Signal) {
+ if (method.access() == QMetaMethod::Public && (members & PublicMethods) == 0)
+ continue;
+ if (method.access() == QMetaMethod::Private && (members & PrivateMethods) == 0)
+ continue;
+ if (method.access() == QMetaMethod::Protected && (members & ProtectedMethods) == 0)
+ continue;
+ }
+ if (method.methodType() == QMetaMethod::Method && (members & Methods) != 0) {
+ addMethod(method);
+ } else if (method.methodType() == QMetaMethod::Signal &&
+ (members & Signals) != 0) {
+ addMethod(method);
+ } else if (method.methodType() == QMetaMethod::Slot &&
+ (members & Slots) != 0) {
+ addMethod(method);
+ }
+ }
+ }
+
+ if ((members & Constructors) != 0) {
+ for (index = 0; index < prototype->constructorCount(); ++index)
+ addConstructor(prototype->constructor(index));
+ }
+
+ if ((members & Properties) != 0) {
+ for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index)
+ addProperty(prototype->property(index));
+ }
+
+ if ((members & Enumerators) != 0) {
+ for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index)
+ addEnumerator(prototype->enumerator(index));
+ }
+
+ if ((members & ClassInfos) != 0) {
+ for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) {
+ QMetaClassInfo ci = prototype->classInfo(index);
+ addClassInfo(ci.name(), ci.value());
+ }
+ }
+
+ if ((members & RelatedMetaObjects) != 0) {
+#ifdef Q_NO_DATA_RELOCATION
+ const QMetaObjectAccessor *objects = 0;
+#else
+ const QMetaObject **objects;
+ if (priv(prototype->d.data)->revision < 2) {
+ objects = (const QMetaObject **)(prototype->d.extradata);
+ } else
+#endif
+ {
+ const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata);
+ if (extra)
+ objects = extra->objects;
+ else
+ objects = 0;
+ }
+ if (objects) {
+ while (*objects != 0) {
+ addRelatedMetaObject(*objects);
+ ++objects;
+ }
+ }
+ }
+
+ if ((members & StaticMetacall) != 0) {
+ if (priv(prototype->d.data)->revision >= 6) {
+ const QMetaObjectExtraData *extra =
+ (const QMetaObjectExtraData *)(prototype->d.extradata);
+ if (extra && extra->static_metacall)
+ setStaticMetacallFunction(extra->static_metacall);
+ }
+ }
+}
+
+/*!
+ Returns the method at \a index in this class.
+
+ \sa methodCount(), addMethod(), removeMethod(), indexOfMethod()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::method(int index) const
+{
+ if (index >= 0 && index < d->methods.size())
+ return QMetaMethodBuilder(this, index);
+ else
+ return QMetaMethodBuilder();
+}
+
+/*!
+ Returns the constructor at \a index in this class.
+
+ \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor()
+*/
+QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const
+{
+ if (index >= 0 && index < d->constructors.size())
+ return QMetaMethodBuilder(this, -(index + 1));
+ else
+ return QMetaMethodBuilder();
+}
+
+/*!
+ Returns the property at \a index in this class.
+
+ \sa methodCount(), addMethod(), removeMethod(), indexOfProperty()
+*/
+QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const
+{
+ if (index >= 0 && index < d->properties.size())
+ return QMetaPropertyBuilder(this, index);
+ else
+ return QMetaPropertyBuilder();
+}
+
+/*!
+ Returns the enumerator at \a index in this class.
+
+ \sa enumeratorCount(), addEnumerator(), removeEnumerator()
+ \sa indexOfEnumerator()
+*/
+QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const
+{
+ if (index >= 0 && index < d->enumerators.size())
+ return QMetaEnumBuilder(this, index);
+ else
+ return QMetaEnumBuilder();
+}
+
+/*!
+ Returns the related meta object at \a index in this class.
+
+ Related meta objects are used when resolving the enumerated type
+ associated with a property, where the enumerated type is in a
+ different class from the property.
+
+ \sa relatedMetaObjectCount(), addRelatedMetaObject()
+ \sa removeRelatedMetaObject()
+*/
+const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const
+{
+ if (index >= 0 && index < d->relatedMetaObjects.size())
+#ifdef Q_NO_DATA_RELOCATION
+ return &((*(d->relatedMetaObjects[index]))());
+#else
+ return d->relatedMetaObjects[index];
+#endif
+ else
+ return 0;
+}
+
+/*!
+ Returns the name of the item of class information at \a index
+ in this class.
+
+ \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo()
+ \sa indexOfClassInfo()
+*/
+QByteArray QMetaObjectBuilder::classInfoName(int index) const
+{
+ if (index >= 0 && index < d->classInfoNames.size())
+ return d->classInfoNames[index];
+ else
+ return QByteArray();
+}
+
+/*!
+ Returns the value of the item of class information at \a index
+ in this class.
+
+ \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo()
+ \sa indexOfClassInfo()
+*/
+QByteArray QMetaObjectBuilder::classInfoValue(int index) const
+{
+ if (index >= 0 && index < d->classInfoValues.size())
+ return d->classInfoValues[index];
+ else
+ return QByteArray();
+}
+
+/*!
+ Removes the method at \a index from this class. The indices of
+ all following methods will be adjusted downwards by 1. If the
+ method is registered as a notify signal on a property, then the
+ notify signal will be removed from the property.
+
+ \sa methodCount(), addMethod(), method(), indexOfMethod()
+*/
+void QMetaObjectBuilder::removeMethod(int index)
+{
+ if (index >= 0 && index < d->methods.size()) {
+ d->methods.removeAt(index);
+ for (int prop = 0; prop < d->properties.size(); ++prop) {
+ // Adjust the indices of property notify signal references.
+ if (d->properties[prop].notifySignal == index) {
+ d->properties[prop].notifySignal = -1;
+ d->properties[prop].setFlag(Notify, false);
+ } else if (d->properties[prop].notifySignal > index)
+ (d->properties[prop].notifySignal)--;
+ }
+ }
+}
+
+/*!
+ Removes the constructor at \a index from this class. The indices of
+ all following constructors will be adjusted downwards by 1.
+
+ \sa constructorCount(), addConstructor(), constructor()
+ \sa indexOfConstructor()
+*/
+void QMetaObjectBuilder::removeConstructor(int index)
+{
+ if (index >= 0 && index < d->constructors.size())
+ d->constructors.removeAt(index);
+}
+
+/*!
+ Removes the property at \a index from this class. The indices of
+ all following properties will be adjusted downwards by 1.
+
+ \sa propertyCount(), addProperty(), property(), indexOfProperty()
+*/
+void QMetaObjectBuilder::removeProperty(int index)
+{
+ if (index >= 0 && index < d->properties.size())
+ d->properties.removeAt(index);
+}
+
+/*!
+ Removes the enumerator at \a index from this class. The indices of
+ all following enumerators will be adjusted downwards by 1.
+
+ \sa enumertorCount(), addEnumerator(), enumerator()
+ \sa indexOfEnumerator()
+*/
+void QMetaObjectBuilder::removeEnumerator(int index)
+{
+ if (index >= 0 && index < d->enumerators.size())
+ d->enumerators.removeAt(index);
+}
+
+/*!
+ Removes the item of class information at \a index from this class.
+ The indices of all following items will be adjusted downwards by 1.
+
+ \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue()
+ \sa indexOfClassInfo()
+*/
+void QMetaObjectBuilder::removeClassInfo(int index)
+{
+ if (index >= 0 && index < d->classInfoNames.size()) {
+ d->classInfoNames.removeAt(index);
+ d->classInfoValues.removeAt(index);
+ }
+}
+
+/*!
+ Removes the related meta object at \a index from this class.
+ The indices of all following related meta objects will be adjusted
+ downwards by 1.
+
+ Related meta objects are used when resolving the enumerated type
+ associated with a property, where the enumerated type is in a
+ different class from the property.
+
+ \sa relatedMetaObjectCount(), addRelatedMetaObject()
+ \sa relatedMetaObject()
+*/
+void QMetaObjectBuilder::removeRelatedMetaObject(int index)
+{
+ if (index >= 0 && index < d->relatedMetaObjects.size())
+ d->relatedMetaObjects.removeAt(index);
+}
+
+/*!
+ Finds a method with the specified \a signature and returns its index;
+ otherwise returns -1. The \a signature will be normalized by this method.
+
+ \sa method(), methodCount(), addMethod(), removeMethod()
+*/
+int QMetaObjectBuilder::indexOfMethod(const QByteArray& signature)
+{
+ QByteArray sig = QMetaObject::normalizedSignature(signature);
+ for (int index = 0; index < d->methods.size(); ++index) {
+ if (sig == d->methods[index].signature)
+ return index;
+ }
+ return -1;
+}
+
+/*!
+ Finds a signal with the specified \a signature and returns its index;
+ otherwise returns -1. The \a signature will be normalized by this method.
+
+ \sa indexOfMethod(), indexOfSlot()
+*/
+int QMetaObjectBuilder::indexOfSignal(const QByteArray& signature)
+{
+ QByteArray sig = QMetaObject::normalizedSignature(signature);
+ for (int index = 0; index < d->methods.size(); ++index) {
+ if (sig == d->methods[index].signature &&
+ d->methods[index].methodType() == QMetaMethod::Signal)
+ return index;
+ }
+ return -1;
+}
+
+/*!
+ Finds a slot with the specified \a signature and returns its index;
+ otherwise returns -1. The \a signature will be normalized by this method.
+
+ \sa indexOfMethod(), indexOfSignal()
+*/
+int QMetaObjectBuilder::indexOfSlot(const QByteArray& signature)
+{
+ QByteArray sig = QMetaObject::normalizedSignature(signature);
+ for (int index = 0; index < d->methods.size(); ++index) {
+ if (sig == d->methods[index].signature &&
+ d->methods[index].methodType() == QMetaMethod::Slot)
+ return index;
+ }
+ return -1;
+}
+
+/*!
+ Finds a constructor with the specified \a signature and returns its index;
+ otherwise returns -1. The \a signature will be normalized by this method.
+
+ \sa constructor(), constructorCount(), addConstructor(), removeConstructor()
+*/
+int QMetaObjectBuilder::indexOfConstructor(const QByteArray& signature)
+{
+ QByteArray sig = QMetaObject::normalizedSignature(signature);
+ for (int index = 0; index < d->constructors.size(); ++index) {
+ if (sig == d->constructors[index].signature)
+ return index;
+ }
+ return -1;
+}
+
+/*!
+ Finds a property with the specified \a name and returns its index;
+ otherwise returns -1.
+
+ \sa property(), propertyCount(), addProperty(), removeProperty()
+*/
+int QMetaObjectBuilder::indexOfProperty(const QByteArray& name)
+{
+ for (int index = 0; index < d->properties.size(); ++index) {
+ if (name == d->properties[index].name)
+ return index;
+ }
+ return -1;
+}
+
+/*!
+ Finds an enumerator with the specified \a name and returns its index;
+ otherwise returns -1.
+
+ \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator()
+*/
+int QMetaObjectBuilder::indexOfEnumerator(const QByteArray& name)
+{
+ for (int index = 0; index < d->enumerators.size(); ++index) {
+ if (name == d->enumerators[index].name)
+ return index;
+ }
+ return -1;
+}
+
+/*!
+ Finds an item of class information with the specified \a name and
+ returns its index; otherwise returns -1.
+
+ \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo()
+ \sa removeClassInfo()
+*/
+int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
+{
+ for (int index = 0; index < d->classInfoNames.size(); ++index) {
+ if (name == d->classInfoNames[index])
+ return index;
+ }
+ return -1;
+}
+
+// Align on a specific type boundary.
+#define ALIGN(size,type) \
+ (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
+
+// Build a string into a QMetaObject representation. Returns the
+// position in the string table where the string was placed.
+static int buildString
+ (char *buf, char *str, int *offset, const QByteArray& value, int empty)
+{
+ if (value.size() == 0 && empty >= 0)
+ return empty;
+ if (buf) {
+ memcpy(str + *offset, value.constData(), value.size());
+ str[*offset + value.size()] = '\0';
+ }
+ int posn = *offset;
+ *offset += value.size() + 1;
+ return posn;
+}
+
+// Build the parameter array string for a method.
+static QByteArray buildParameterNames
+ (const QByteArray& signature, const QList<QByteArray>& parameterNames)
+{
+ // If the parameter name list is specified, then concatenate them.
+ if (!parameterNames.isEmpty()) {
+ QByteArray names;
+ bool first = true;
+ foreach (const QByteArray &name, parameterNames) {
+ if (first)
+ first = false;
+ else
+ names += (char)',';
+ names += name;
+ }
+ return names;
+ }
+
+ // Count commas in the signature, excluding those inside template arguments.
+ int index = signature.indexOf('(');
+ if (index < 0)
+ return QByteArray();
+ ++index;
+ if (index >= signature.size())
+ return QByteArray();
+ if (signature[index] == ')')
+ return QByteArray();
+ int count = 1;
+ int brackets = 0;
+ while (index < signature.size() && signature[index] != ',') {
+ char ch = signature[index++];
+ if (ch == '<')
+ ++brackets;
+ else if (ch == '>')
+ --brackets;
+ else if (ch == ',' && brackets <= 0)
+ ++count;
+ }
+ return QByteArray(count - 1, ',');
+}
+
+// Build a QMetaObject in "buf" based on the information in "d".
+// If "buf" is null, then return the number of bytes needed to
+// build the QMetaObject. Returns -1 if the metaobject if
+// relocatable is set, but the metaobject contains extradata.
+static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
+ bool relocatable)
+{
+ int size = 0;
+ int dataIndex;
+ int enumIndex;
+ int index;
+ bool hasNotifySignals = false;
+
+ if (relocatable &&
+ (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction))
+ return -1;
+
+ // Create the main QMetaObject structure at the start of the buffer.
+ QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf);
+ size += sizeof(QMetaObject);
+ ALIGN(size, int);
+ if (buf) {
+ if (!relocatable) meta->d.superdata = d->superClass;
+ meta->d.extradata = 0;
+ }
+
+ // Populate the QMetaObjectPrivate structure.
+ QMetaObjectPrivate *pmeta
+ = reinterpret_cast<QMetaObjectPrivate *>(buf + size);
+ int pmetaSize = size;
+ dataIndex = 13; // Number of fields in the QMetaObjectPrivate.
+ for (index = 0; index < d->properties.size(); ++index) {
+ if (d->properties[index].notifySignal != -1) {
+ hasNotifySignals = true;
+ break;
+ }
+ }
+ if (buf) {
+ pmeta->revision = 3;
+ pmeta->flags = d->flags;
+ pmeta->className = 0; // Class name is always the first string.
+
+ pmeta->classInfoCount = d->classInfoNames.size();
+ pmeta->classInfoData = dataIndex;
+ dataIndex += 2 * d->classInfoNames.size();
+
+ pmeta->methodCount = d->methods.size();
+ pmeta->methodData = dataIndex;
+ dataIndex += 5 * d->methods.size();
+
+ pmeta->propertyCount = d->properties.size();
+ pmeta->propertyData = dataIndex;
+ dataIndex += 3 * d->properties.size();
+ if (hasNotifySignals)
+ dataIndex += d->properties.size();
+
+ pmeta->enumeratorCount = d->enumerators.size();
+ pmeta->enumeratorData = dataIndex;
+ dataIndex += 4 * d->enumerators.size();
+
+ pmeta->constructorCount = d->constructors.size();
+ pmeta->constructorData = dataIndex;
+ dataIndex += 5 * d->constructors.size();
+ } else {
+ dataIndex += 2 * d->classInfoNames.size();
+ dataIndex += 5 * d->methods.size();
+ dataIndex += 3 * d->properties.size();
+ if (hasNotifySignals)
+ dataIndex += d->properties.size();
+ dataIndex += 4 * d->enumerators.size();
+ dataIndex += 5 * d->constructors.size();
+ }
+
+ // Allocate space for the enumerator key names and values.
+ enumIndex = dataIndex;
+ for (index = 0; index < d->enumerators.size(); ++index) {
+ QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
+ dataIndex += 2 * enumerator->keys.size();
+ }
+
+ // Zero terminator at the end of the data offset table.
+ ++dataIndex;
+
+ // Find the start of the data and string tables.
+ int *data = reinterpret_cast<int *>(pmeta);
+ size += dataIndex * sizeof(int);
+ char *str = reinterpret_cast<char *>(buf + size);
+ if (buf) {
+ if (relocatable) {
+ meta->d.stringdata = reinterpret_cast<const char *>((quintptr)size);
+ meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
+ } else {
+ meta->d.stringdata = str;
+ meta->d.data = reinterpret_cast<uint *>(data);
+ }
+ }
+
+ // Reset the current data position to just past the QMetaObjectPrivate.
+ dataIndex = 13;
+
+ // Add the class name to the string table.
+ int offset = 0;
+ buildString(buf, str, &offset, d->className, -1);
+
+ // Add a common empty string, which is used to indicate "void"
+ // method returns, empty tag strings, etc.
+ int empty = buildString(buf, str, &offset, QByteArray(), -1);
+
+ // Output the class infos,
+ for (index = 0; index < d->classInfoNames.size(); ++index) {
+ int name = buildString(buf, str, &offset, d->classInfoNames[index], empty);
+ int value = buildString(buf, str, &offset, d->classInfoValues[index], empty);
+ if (buf) {
+ data[dataIndex] = name;
+ data[dataIndex + 1] = value;
+ }
+ dataIndex += 2;
+ }
+
+ // Output the methods in the class.
+ for (index = 0; index < d->methods.size(); ++index) {
+ QMetaMethodBuilderPrivate *method = &(d->methods[index]);
+ int sig = buildString(buf, str, &offset, method->signature, empty);
+ int params;
+ QByteArray names = buildParameterNames
+ (method->signature, method->parameterNames);
+ params = buildString(buf, str, &offset, names, empty);
+ int ret = buildString(buf, str, &offset, method->returnType, empty);
+ int tag = buildString(buf, str, &offset, method->tag, empty);
+ int attrs = method->attributes;
+ if (buf) {
+ data[dataIndex] = sig;
+ data[dataIndex + 1] = params;
+ data[dataIndex + 2] = ret;
+ data[dataIndex + 3] = tag;
+ data[dataIndex + 4] = attrs;
+ }
+ dataIndex += 5;
+ }
+
+ // Output the properties in the class.
+ for (index = 0; index < d->properties.size(); ++index) {
+ QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
+ int name = buildString(buf, str, &offset, prop->name, empty);
+ int type = buildString(buf, str, &offset, prop->type, empty);
+ int flags = prop->flags;
+
+ if (!isVariantType(prop->type)) {
+ flags |= EnumOrFlag;
+ } else {
+ flags |= qvariant_nameToType(prop->type) << 24;
+ }
+
+ if (buf) {
+ data[dataIndex] = name;
+ data[dataIndex + 1] = type;
+ data[dataIndex + 2] = flags;
+ }
+ dataIndex += 3;
+ }
+ if (hasNotifySignals) {
+ for (index = 0; index < d->properties.size(); ++index) {
+ QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
+ if (buf) {
+ if (prop->notifySignal != -1)
+ data[dataIndex] = prop->notifySignal;
+ else
+ data[dataIndex] = 0;
+ }
+ ++dataIndex;
+ }
+ }
+
+ // Output the enumerators in the class.
+ for (index = 0; index < d->enumerators.size(); ++index) {
+ QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
+ int name = buildString(buf, str, &offset, enumerator->name, empty);
+ int isFlag = (int)(enumerator->isFlag);
+ int count = enumerator->keys.size();
+ int enumOffset = enumIndex;
+ if (buf) {
+ data[dataIndex] = name;
+ data[dataIndex + 1] = isFlag;
+ data[dataIndex + 2] = count;
+ data[dataIndex + 3] = enumOffset;
+ }
+ for (int key = 0; key < count; ++key) {
+ int keyIndex = buildString(buf, str, &offset, enumerator->keys[key], empty);
+ if (buf) {
+ data[enumOffset++] = keyIndex;
+ data[enumOffset++] = enumerator->values[key];
+ }
+ }
+ dataIndex += 4;
+ enumIndex += 2 * count;
+ }
+
+ // Output the constructors in the class.
+ for (index = 0; index < d->constructors.size(); ++index) {
+ QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
+ int sig = buildString(buf, str, &offset, method->signature, empty);
+ int params;
+ QByteArray names = buildParameterNames
+ (method->signature, method->parameterNames);
+ params = buildString(buf, str, &offset, names, empty);
+ int ret = buildString(buf, str, &offset, method->returnType, empty);
+ int tag = buildString(buf, str, &offset, method->tag, empty);
+ int attrs = method->attributes;
+ if (buf) {
+ data[dataIndex] = sig;
+ data[dataIndex + 1] = params;
+ data[dataIndex + 2] = ret;
+ data[dataIndex + 3] = tag;
+ data[dataIndex + 4] = attrs;
+ }
+ dataIndex += 5;
+ }
+
+ // One more empty string to act as a terminator.
+ buildString(buf, str, &offset, QByteArray(), -1);
+ size += offset;
+
+ // Output the zero terminator in the data array.
+ if (buf)
+ data[enumIndex] = 0;
+
+ // Create the extradata block if we need one.
+ if (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction) {
+ ALIGN(size, QMetaObject **);
+ ALIGN(size, QMetaObjectBuilder::StaticMetacallFunction);
+ QMetaObjectExtraData *extra =
+ reinterpret_cast<QMetaObjectExtraData *>(buf + size);
+ size += sizeof(QMetaObjectExtraData);
+ ALIGN(size, QMetaObject *);
+#ifdef Q_NO_DATA_RELOCATION
+ QMetaObjectAccessor *objects =
+ reinterpret_cast<QMetaObjectAccessor *>(buf + size);
+#else
+ const QMetaObject **objects =
+ reinterpret_cast<const QMetaObject **>(buf + size);
+#endif
+ if (buf) {
+ if (d->relatedMetaObjects.size() > 0) {
+ extra->objects = objects;
+ for (index = 0; index < d->relatedMetaObjects.size(); ++index)
+ objects[index] = d->relatedMetaObjects[index];
+ objects[index] = 0;
+ } else {
+ extra->objects = 0;
+ }
+ extra->static_metacall = d->staticMetacallFunction;
+ meta->d.extradata = reinterpret_cast<void *>(extra);
+ }
+ if (d->relatedMetaObjects.size() > 0)
+ size += sizeof(QMetaObject *) * (d->relatedMetaObjects.size() + 1);
+ }
+
+ // Align the final size and return it.
+ ALIGN(size, void *);
+ return size;
+}
+
+/*!
+ Converts this meta object builder into a concrete QMetaObject.
+ The return value should be deallocated using qFree() once it
+ is no longer needed.
+
+ The returned meta object is a snapshot of the state of the
+ QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder
+ will not be reflected in previous meta objects returned by
+ this method.
+*/
+QMetaObject *QMetaObjectBuilder::toMetaObject() const
+{
+ int size = buildMetaObject(d, 0, false);
+ char *buf = reinterpret_cast<char *>(qMalloc(size));
+ memset(buf, 0, size);
+ buildMetaObject(d, buf, false);
+ return reinterpret_cast<QMetaObject *>(buf);
+}
+
+/*
+ \internal
+
+ Converts this meta object builder into relocatable data. This data can
+ be stored, copied and later passed to fromRelocatableData() to create a
+ concrete QMetaObject.
+
+ The data is specific to the architecture on which it was created, but is not
+ specific to the process that created it. Not all meta object builder's can
+ be converted to data in this way. If \a ok is provided, it will be set to
+ true if the conversion succeeds, and false otherwise. If a
+ staticMetacallFunction() or any relatedMetaObject()'s are specified the
+ conversion to relocatable data will fail.
+*/
+QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const
+{
+ int size = buildMetaObject(d, 0, true);
+ if (size == -1) {
+ if (ok) *ok = false;
+ return QByteArray();
+ }
+
+ QByteArray data;
+ data.resize(size);
+ char *buf = data.data();
+ memset(buf, 0, size);
+ buildMetaObject(d, buf, true);
+ if (ok) *ok = true;
+ return data;
+}
+
+/*
+ \internal
+
+ Sets the \a data returned from toRelocatableData() onto a concrete
+ QMetaObject instance, \a output. As the meta object's super class is not
+ saved in the relocatable data, it must be passed as \a superClass.
+*/
+void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
+ const QMetaObject *superclass,
+ const QByteArray &data)
+{
+ if (!output)
+ return;
+
+ const char *buf = data.constData();
+ const QMetaObject *dataMo = reinterpret_cast<const QMetaObject *>(buf);
+
+ quintptr stringdataOffset = (quintptr)dataMo->d.stringdata;
+ quintptr dataOffset = (quintptr)dataMo->d.data;
+
+ output->d.superdata = superclass;
+ output->d.stringdata = buf + stringdataOffset;
+ output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
+}
+
+/*!
+ \typedef QMetaObjectBuilder::StaticMetacallFunction
+
+ Typedef for static metacall functions. The three parameters are
+ the call type value, the constructor index, and the
+ array of parameters.
+*/
+
+/*!
+ Returns the static metacall function to use to construct objects
+ of this class. The default value is null.
+
+ \sa setStaticMetacallFunction()
+*/
+QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const
+{
+ return d->staticMetacallFunction;
+}
+
+/*!
+ Sets the static metacall function to use to construct objects
+ of this class to \a value. The default value is null.
+
+ \sa staticMetacallFunction()
+*/
+void QMetaObjectBuilder::setStaticMetacallFunction
+ (QMetaObjectBuilder::StaticMetacallFunction value)
+{
+ d->staticMetacallFunction = value;
+}
+
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ Serializes the contents of the meta object builder onto \a stream.
+
+ \sa deserialize()
+*/
+void QMetaObjectBuilder::serialize(QDataStream& stream) const
+{
+ int index;
+
+ // Write the class and super class names.
+ stream << d->className;
+ if (d->superClass)
+ stream << QByteArray(d->superClass->className());
+ else
+ stream << QByteArray();
+
+ // Write the counts for each type of class member.
+ stream << d->classInfoNames.size();
+ stream << d->methods.size();
+ stream << d->properties.size();
+ stream << d->enumerators.size();
+ stream << d->constructors.size();
+ stream << d->relatedMetaObjects.size();
+
+ // Write the items of class information.
+ for (index = 0; index < d->classInfoNames.size(); ++index) {
+ stream << d->classInfoNames[index];
+ stream << d->classInfoValues[index];
+ }
+
+ // Write the methods.
+ for (index = 0; index < d->methods.size(); ++index) {
+ const QMetaMethodBuilderPrivate *method = &(d->methods[index]);
+ stream << method->signature;
+ stream << method->returnType;
+ stream << method->parameterNames;
+ stream << method->tag;
+ stream << method->attributes;
+ }
+
+ // Write the properties.
+ for (index = 0; index < d->properties.size(); ++index) {
+ const QMetaPropertyBuilderPrivate *property = &(d->properties[index]);
+ stream << property->name;
+ stream << property->type;
+ stream << property->flags;
+ stream << property->notifySignal;
+ }
+
+ // Write the enumerators.
+ for (index = 0; index < d->enumerators.size(); ++index) {
+ const QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
+ stream << enumerator->name;
+ stream << enumerator->isFlag;
+ stream << enumerator->keys;
+ stream << enumerator->values;
+ }
+
+ // Write the constructors.
+ for (index = 0; index < d->constructors.size(); ++index) {
+ const QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
+ stream << method->signature;
+ stream << method->returnType;
+ stream << method->parameterNames;
+ stream << method->tag;
+ stream << method->attributes;
+ }
+
+ // Write the related meta objects.
+#ifdef Q_NO_DATA_RELOCATION
+ //### What do we do here?
+#else
+ for (index = 0; index < d->relatedMetaObjects.size(); ++index) {
+ const QMetaObject *meta = d->relatedMetaObjects[index];
+ stream << QByteArray(meta->className());
+ }
+#endif
+
+ // Add an extra empty QByteArray for additional data in future versions.
+ // This should help maintain backwards compatibility, allowing older
+ // versions to read newer data.
+ stream << QByteArray();
+}
+
+// Resolve a class name using the name reference map.
+static const QMetaObject *resolveClassName
+ (const QMap<QByteArray, const QMetaObject *>& references,
+ const QByteArray& name)
+{
+ if (name == QByteArray("QObject"))
+ return &QObject::staticMetaObject;
+ else
+ return references.value(name, 0);
+}
+
+/*!
+ Deserializes a meta object builder from \a stream into
+ this meta object builder.
+
+ The \a references parameter specifies a mapping from class names
+ to QMetaObject instances for resolving the super class name and
+ related meta objects in the object that is deserialized.
+ The meta object for QObject is implicitly added to \a references
+ and does not need to be supplied.
+
+ The QDataStream::status() value on \a stream will be set to
+ QDataStream::ReadCorruptData if the input data is corrupt.
+ The status will be set to QDataStream::ReadPastEnd if the
+ input was exhausted before the full meta object was read.
+
+ \sa serialize()
+*/
+void QMetaObjectBuilder::deserialize
+ (QDataStream& stream,
+ const QMap<QByteArray, const QMetaObject *>& references)
+{
+ QByteArray name;
+ const QMetaObject *cl;
+ int index;
+
+ // Clear all members in the builder to their default states.
+ d->className.clear();
+ d->superClass = &QObject::staticMetaObject;
+ d->classInfoNames.clear();
+ d->classInfoValues.clear();
+ d->methods.clear();
+ d->properties.clear();
+ d->enumerators.clear();
+ d->constructors.clear();
+ d->relatedMetaObjects.clear();
+ d->staticMetacallFunction = 0;
+
+ // Read the class and super class names.
+ stream >> d->className;
+ stream >> name;
+ if (name.isEmpty()) {
+ d->superClass = 0;
+ } else if ((cl = resolveClassName(references, name)) != 0) {
+ d->superClass = cl;
+ } else {
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return;
+ }
+
+ // Read the counts for each type of class member.
+ int classInfoCount, methodCount, propertyCount;
+ int enumeratorCount, constructorCount, relatedMetaObjectCount;
+ stream >> classInfoCount;
+ stream >> methodCount;
+ stream >> propertyCount;
+ stream >> enumeratorCount;
+ stream >> constructorCount;
+ stream >> relatedMetaObjectCount;
+ if (classInfoCount < 0 || methodCount < 0 ||
+ propertyCount < 0 || enumeratorCount < 0 ||
+ constructorCount < 0 || relatedMetaObjectCount < 0) {
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return;
+ }
+
+ // Read the items of class information.
+ for (index = 0; index < classInfoCount; ++index) {
+ if (stream.status() != QDataStream::Ok)
+ return;
+ QByteArray value;
+ stream >> name;
+ stream >> value;
+ addClassInfo(name, value);
+ }
+
+ // Read the member methods.
+ for (index = 0; index < methodCount; ++index) {
+ if (stream.status() != QDataStream::Ok)
+ return;
+ stream >> name;
+ addMethod(name);
+ QMetaMethodBuilderPrivate *method = &(d->methods[index]);
+ stream >> method->returnType;
+ stream >> method->parameterNames;
+ stream >> method->tag;
+ stream >> method->attributes;
+ if (method->methodType() == QMetaMethod::Constructor) {
+ // Cannot add a constructor in this set of methods.
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return;
+ }
+ }
+
+ // Read the properties.
+ for (index = 0; index < propertyCount; ++index) {
+ if (stream.status() != QDataStream::Ok)
+ return;
+ QByteArray type;
+ stream >> name;
+ stream >> type;
+ addProperty(name, type);
+ QMetaPropertyBuilderPrivate *property = &(d->properties[index]);
+ stream >> property->flags;
+ stream >> property->notifySignal;
+ if (property->notifySignal < -1 ||
+ property->notifySignal >= d->methods.size()) {
+ // Notify signal method index is out of range.
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return;
+ }
+ if (property->notifySignal >= 0 &&
+ d->methods[property->notifySignal].methodType() != QMetaMethod::Signal) {
+ // Notify signal method index does not refer to a signal.
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return;
+ }
+ }
+
+ // Read the enumerators.
+ for (index = 0; index < enumeratorCount; ++index) {
+ if (stream.status() != QDataStream::Ok)
+ return;
+ stream >> name;
+ addEnumerator(name);
+ QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
+ stream >> enumerator->isFlag;
+ stream >> enumerator->keys;
+ stream >> enumerator->values;
+ if (enumerator->keys.size() != enumerator->values.size()) {
+ // Mismatch between number of keys and number of values.
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return;
+ }
+ }
+
+ // Read the constructor methods.
+ for (index = 0; index < constructorCount; ++index) {
+ if (stream.status() != QDataStream::Ok)
+ return;
+ stream >> name;
+ addConstructor(name);
+ QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
+ stream >> method->returnType;
+ stream >> method->parameterNames;
+ stream >> method->tag;
+ stream >> method->attributes;
+ if (method->methodType() != QMetaMethod::Constructor) {
+ // The type must be Constructor.
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return;
+ }
+ }
+
+ // Read the related meta objects.
+#ifdef Q_NO_DATA_RELOCATION
+ //### What do we do here
+#else
+ for (index = 0; index < relatedMetaObjectCount; ++index) {
+ if (stream.status() != QDataStream::Ok)
+ return;
+ stream >> name;
+ cl = resolveClassName(references, name);
+ if (!cl) {
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return;
+ }
+ addRelatedMetaObject(cl);
+ }
+#endif
+
+ // Read the extra data block, which is reserved for future use.
+ stream >> name;
+}
+
+#endif // !QT_NO_DATASTREAM
+
+/*!
+ \class QMetaMethodBuilder
+ \internal
+ \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder.
+*/
+
+QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
+{
+ // Positive indices indicate methods, negative indices indicate constructors.
+ if (_mobj && _index >= 0 && _index < _mobj->d->methods.size())
+ return &(_mobj->d->methods[_index]);
+ else if (_mobj && -_index >= 1 && -_index <= _mobj->d->constructors.size())
+ return &(_mobj->d->constructors[(-_index) - 1]);
+ else
+ return 0;
+}
+
+/*!
+ \fn QMetaMethodBuilder::QMetaMethodBuilder()
+ \internal
+*/
+
+/*!
+ Returns the index of this method within its QMetaObjectBuilder.
+*/
+int QMetaMethodBuilder::index() const
+{
+ if (_index >= 0)
+ return _index; // Method, signal, or slot
+ else
+ return (-_index) - 1; // Constructor
+}
+
+/*!
+ Returns the type of this method (signal, slot, method, or constructor).
+*/
+QMetaMethod::MethodType QMetaMethodBuilder::methodType() const
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ return d->methodType();
+ else
+ return QMetaMethod::Method;
+}
+
+/*!
+ Returns the signature of this method.
+
+ \sa parameterNames(), returnType()
+*/
+QByteArray QMetaMethodBuilder::signature() const
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ return d->signature;
+ else
+ return QByteArray();
+}
+
+/*!
+ Returns the return type for this method; empty if the method's
+ return type is \c{void}.
+
+ \sa setReturnType(), signature()
+*/
+QByteArray QMetaMethodBuilder::returnType() const
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ return d->returnType;
+ else
+ return QByteArray();
+}
+
+/*!
+ Sets the return type for this method to \a value. If \a value
+ is empty, then the method's return type is \c{void}. The \a value
+ will be normalized before it is added to the method.
+
+ \sa returnType(), signature()
+*/
+void QMetaMethodBuilder::setReturnType(const QByteArray& value)
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ d->returnType = QMetaObject::normalizedType(value);
+}
+
+/*!
+ Returns the list of parameter names for this method.
+
+ \sa setParameterNames()
+*/
+QList<QByteArray> QMetaMethodBuilder::parameterNames() const
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ return d->parameterNames;
+ else
+ return QList<QByteArray>();
+}
+
+/*!
+ Sets the list of parameter names for this method to \a value.
+
+ \sa parameterNames()
+*/
+void QMetaMethodBuilder::setParameterNames(const QList<QByteArray>& value)
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ d->parameterNames = value;
+}
+
+/*!
+ Returns the tag associated with this method.
+
+ \sa setTag()
+*/
+QByteArray QMetaMethodBuilder::tag() const
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ return d->tag;
+ else
+ return QByteArray();
+}
+
+/*!
+ Sets the tag associated with this method to \a value.
+
+ \sa setTag()
+*/
+void QMetaMethodBuilder::setTag(const QByteArray& value)
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ d->tag = value;
+}
+
+/*!
+ Returns the access specification of this method (private, protected,
+ or public). The default value is QMetaMethod::Public for methods,
+ slots, and constructors. The default value is QMetaMethod::Protected
+ for signals.
+
+ \sa setAccess()
+*/
+QMetaMethod::Access QMetaMethodBuilder::access() const
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ return d->access();
+ else
+ return QMetaMethod::Public;
+}
+
+/*!
+ Sets the access specification of this method (private, protected,
+ or public) to \a value. If the method is a signal, this function
+ will be ignored.
+
+ \sa access()
+*/
+void QMetaMethodBuilder::setAccess(QMetaMethod::Access value)
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d && d->methodType() != QMetaMethod::Signal)
+ d->setAccess(value);
+}
+
+/*!
+ Returns the additional attributes for this method.
+
+ \sa setAttributes()
+*/
+int QMetaMethodBuilder::attributes() const
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ return (d->attributes >> 4);
+ else
+ return 0;
+}
+
+/*!
+ Sets the additional attributes for this method to \a value.
+
+ \sa attributes()
+*/
+void QMetaMethodBuilder::setAttributes(int value)
+{
+ QMetaMethodBuilderPrivate *d = d_func();
+ if (d)
+ d->attributes = ((d->attributes & 0x0f) | (value << 4));
+}
+
+/*!
+ \class QMetaPropertyBuilder
+ \internal
+ \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder.
+*/
+
+QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
+{
+ if (_mobj && _index >= 0 && _index < _mobj->d->properties.size())
+ return &(_mobj->d->properties[_index]);
+ else
+ return 0;
+}
+
+/*!
+ \fn QMetaPropertyBuilder::QMetaPropertyBuilder()
+ \internal
+*/
+
+/*!
+ \fn int QMetaPropertyBuilder::index() const
+
+ Returns the index of this property within its QMetaObjectBuilder.
+*/
+
+/*!
+ Returns the name associated with this property.
+
+ \sa type()
+*/
+QByteArray QMetaPropertyBuilder::name() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->name;
+ else
+ return QByteArray();
+}
+
+/*!
+ Returns the type associated with this property.
+
+ \sa name()
+*/
+QByteArray QMetaPropertyBuilder::type() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->type;
+ else
+ return QByteArray();
+}
+
+/*!
+ Returns true if this property has a notify signal; false otherwise.
+
+ \sa notifySignal(), setNotifySignal(), removeNotifySignal()
+*/
+bool QMetaPropertyBuilder::hasNotifySignal() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Notify);
+ else
+ return false;
+}
+
+/*!
+ Returns the notify signal associated with this property.
+
+ \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal()
+*/
+QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d && d->notifySignal >= 0)
+ return QMetaMethodBuilder(_mobj, d->notifySignal);
+ else
+ return QMetaMethodBuilder();
+}
+
+/*!
+ Sets the notify signal associated with this property to \a value.
+
+ \sa hasNotifySignal(), notifySignal(), removeNotifySignal()
+*/
+void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder& value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d) {
+ if (value._mobj) {
+ d->notifySignal = value._index;
+ d->setFlag(Notify, true);
+ } else {
+ d->notifySignal = -1;
+ d->setFlag(Notify, false);
+ }
+ }
+}
+
+/*!
+ Removes the notify signal from this property.
+
+ \sa hasNotifySignal(), notifySignal(), setNotifySignal()
+*/
+void QMetaPropertyBuilder::removeNotifySignal()
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d) {
+ d->notifySignal = -1;
+ d->setFlag(Notify, false);
+ }
+}
+
+/*!
+ Returns true if this property is readable; otherwise returns false.
+ The default value is true.
+
+ \sa setReadable(), isWritable()
+*/
+bool QMetaPropertyBuilder::isReadable() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Readable);
+ else
+ return false;
+}
+
+/*!
+ Returns true if this property is writable; otherwise returns false.
+ The default value is true.
+
+ \sa setWritable(), isReadable()
+*/
+bool QMetaPropertyBuilder::isWritable() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Writable);
+ else
+ return false;
+}
+
+/*!
+ Returns true if this property can be reset to a default value; otherwise
+ returns false. The default value is false.
+
+ \sa setResettable()
+*/
+bool QMetaPropertyBuilder::isResettable() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Resettable);
+ else
+ return false;
+}
+
+/*!
+ Returns true if this property is designable; otherwise returns false.
+ This default value is false.
+
+ \sa setDesignable(), isScriptable(), isStored()
+*/
+bool QMetaPropertyBuilder::isDesignable() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Designable);
+ else
+ return false;
+}
+
+/*!
+ Returns true if the property is scriptable; otherwise returns false.
+ This default value is true.
+
+ \sa setScriptable(), isDesignable(), isStored()
+*/
+bool QMetaPropertyBuilder::isScriptable() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Scriptable);
+ else
+ return false;
+}
+
+/*!
+ Returns true if the property is stored; otherwise returns false.
+ This default value is false.
+
+ \sa setStored(), isDesignable(), isScriptable()
+*/
+bool QMetaPropertyBuilder::isStored() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Stored);
+ else
+ return false;
+}
+
+/*!
+ Returns true if the property is editable; otherwise returns false.
+ This default value is false.
+
+ \sa setEditable(), isDesignable(), isScriptable(), isStored()
+*/
+bool QMetaPropertyBuilder::isEditable() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Editable);
+ else
+ return false;
+}
+
+/*!
+ Returns true if this property is designated as the \c USER
+ property, i.e., the one that the user can edit or that is
+ significant in some other way. Otherwise it returns
+ false. This default value is false.
+
+ \sa setUser(), isDesignable(), isScriptable()
+*/
+bool QMetaPropertyBuilder::isUser() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(User);
+ else
+ return false;
+}
+
+/*!
+ Returns true if the property has a C++ setter function that
+ follows Qt's standard "name" / "setName" pattern. Designer and uic
+ query hasStdCppSet() in order to avoid expensive
+ QObject::setProperty() calls. All properties in Qt [should] follow
+ this pattern. The default value is false.
+
+ \sa setStdCppSet()
+*/
+bool QMetaPropertyBuilder::hasStdCppSet() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(StdCppSet);
+ else
+ return false;
+}
+
+/*!
+ Returns true if the property is an enumerator or flag type;
+ otherwise returns false. This default value is false.
+
+ \sa setEnumOrFlag()
+*/
+bool QMetaPropertyBuilder::isEnumOrFlag() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(EnumOrFlag);
+ else
+ return false;
+}
+
+/*!
+ Returns true if the property is constant; otherwise returns false.
+ The default value is false.
+*/
+bool QMetaPropertyBuilder::isConstant() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Constant);
+ else
+ return false;
+}
+
+/*!
+ Returns true if the property is final; otherwise returns false.
+ The default value is false.
+*/
+bool QMetaPropertyBuilder::isFinal() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Final);
+ else
+ return false;
+}
+
+/*!
+ Sets this property to readable if \a value is true.
+
+ \sa isReadable(), setWritable()
+*/
+void QMetaPropertyBuilder::setReadable(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Readable, value);
+}
+
+/*!
+ Sets this property to writable if \a value is true.
+
+ \sa isWritable(), setReadable()
+*/
+void QMetaPropertyBuilder::setWritable(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Writable, value);
+}
+
+/*!
+ Sets this property to resettable if \a value is true.
+
+ \sa isResettable()
+*/
+void QMetaPropertyBuilder::setResettable(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Resettable, value);
+}
+
+/*!
+ Sets this property to designable if \a value is true.
+
+ \sa isDesignable(), setScriptable(), setStored()
+*/
+void QMetaPropertyBuilder::setDesignable(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Designable, value);
+}
+
+/*!
+ Sets this property to scriptable if \a value is true.
+
+ \sa isScriptable(), setDesignable(), setStored()
+*/
+void QMetaPropertyBuilder::setScriptable(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Scriptable, value);
+}
+
+/*!
+ Sets this property to storable if \a value is true.
+
+ \sa isStored(), setDesignable(), setScriptable()
+*/
+void QMetaPropertyBuilder::setStored(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Stored, value);
+}
+
+/*!
+ Sets this property to editable if \a value is true.
+
+ \sa isEditable(), setDesignable(), setScriptable(), setStored()
+*/
+void QMetaPropertyBuilder::setEditable(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Editable, value);
+}
+
+/*!
+ Sets the \c USER flag on this property to \a value.
+
+ \sa isUser(), setDesignable(), setScriptable()
+*/
+void QMetaPropertyBuilder::setUser(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(User, value);
+}
+
+/*!
+ Sets the C++ setter flag on this property to \a value, which is
+ true if the property has a C++ setter function that follows Qt's
+ standard "name" / "setName" pattern.
+
+ \sa hasStdCppSet()
+*/
+void QMetaPropertyBuilder::setStdCppSet(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(StdCppSet, value);
+}
+
+/*!
+ Sets this property to be of an enumerator or flag type if
+ \a value is true.
+
+ \sa isEnumOrFlag()
+*/
+void QMetaPropertyBuilder::setEnumOrFlag(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(EnumOrFlag, value);
+}
+
+/*!
+ Sets the \c CONSTANT flag on this property to \a value.
+
+ \sa isConstant()
+*/
+void QMetaPropertyBuilder::setConstant(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Constant, value);
+}
+
+/*!
+ Sets the \c FINAL flag on this property to \a value.
+
+ \sa isFinal()
+*/
+void QMetaPropertyBuilder::setFinal(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Final, value);
+}
+
+
+/*!
+ \class QMetaEnumBuilder
+ \internal
+ \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
+*/
+
+QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
+{
+ if (_mobj && _index >= 0 && _index < _mobj->d->enumerators.size())
+ return &(_mobj->d->enumerators[_index]);
+ else
+ return 0;
+}
+
+/*!
+ \fn QMetaEnumBuilder::QMetaEnumBuilder()
+ \internal
+*/
+
+/*!
+ \fn int QMetaEnumBuilder::index() const
+
+ Returns the index of this enumerator within its QMetaObjectBuilder.
+*/
+
+/*!
+ Returns the name of the enumerator (without the scope).
+*/
+QByteArray QMetaEnumBuilder::name() const
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d)
+ return d->name;
+ else
+ return QByteArray();
+}
+
+/*!
+ Returns true if this enumerator is used as a flag; otherwise returns
+ false.
+
+ \sa setIsFlag()
+*/
+bool QMetaEnumBuilder::isFlag() const
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d)
+ return d->isFlag;
+ else
+ return false;
+}
+
+/*!
+ Sets this enumerator to be used as a flag if \a value is true.
+
+ \sa isFlag()
+*/
+void QMetaEnumBuilder::setIsFlag(bool value)
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d)
+ d->isFlag = value;
+}
+
+/*!
+ Returns the number of keys.
+
+ \sa key(), addKey()
+*/
+int QMetaEnumBuilder::keyCount() const
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d)
+ return d->keys.size();
+ else
+ return 0;
+}
+
+/*!
+ Returns the key with the given \a index, or an empty QByteArray
+ if no such key exists.
+
+ \sa keyCount(), addKey(), value()
+*/
+QByteArray QMetaEnumBuilder::key(int index) const
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d && index >= 0 && index < d->keys.size())
+ return d->keys[index];
+ else
+ return QByteArray();
+}
+
+/*!
+ Returns the value with the given \a index; or returns -1 if there
+ is no such value.
+
+ \sa keyCount(), addKey(), key()
+*/
+int QMetaEnumBuilder::value(int index) const
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d && index >= 0 && index < d->keys.size())
+ return d->values[index];
+ else
+ return -1;
+}
+
+/*!
+ Adds a new key called \a name to this enumerator, associated
+ with \a value. Returns the index of the new key.
+
+ \sa keyCount(), key(), value(), removeKey()
+*/
+int QMetaEnumBuilder::addKey(const QByteArray& name, int value)
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d) {
+ int index = d->keys.size();
+ d->keys += name;
+ d->values += value;
+ return index;
+ } else {
+ return -1;
+ }
+}
+
+/*!
+ Removes the key at \a index from this enumerator.
+
+ \sa addKey()
+*/
+void QMetaEnumBuilder::removeKey(int index)
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d && index >= 0 && index < d->keys.size()) {
+ d->keys.removeAt(index);
+ d->values.removeAt(index);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/ftw/qmetaobjectbuilder_p.h b/src/declarative/qml/ftw/qmetaobjectbuilder_p.h
new file mode 100644
index 0000000000..a80ba904b6
--- /dev/null
+++ b/src/declarative/qml/ftw/qmetaobjectbuilder_p.h
@@ -0,0 +1,325 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMETAOBJECTBUILDER_H
+#define QMETAOBJECTBUILDER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of moc. This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qobject.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qdatastream.h>
+#include <QtCore/qmap.h>
+
+#include <private/qdeclarativeglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMetaObjectBuilderPrivate;
+class QMetaMethodBuilder;
+class QMetaMethodBuilderPrivate;
+class QMetaPropertyBuilder;
+class QMetaPropertyBuilderPrivate;
+class QMetaEnumBuilder;
+class QMetaEnumBuilderPrivate;
+
+class Q_DECLARATIVE_PRIVATE_EXPORT QMetaObjectBuilder
+{
+public:
+ enum AddMember
+ {
+ ClassName = 0x00000001,
+ SuperClass = 0x00000002,
+ Methods = 0x00000004,
+ Signals = 0x00000008,
+ Slots = 0x00000010,
+ Constructors = 0x00000020,
+ Properties = 0x00000040,
+ Enumerators = 0x00000080,
+ ClassInfos = 0x00000100,
+ RelatedMetaObjects = 0x00000200,
+ StaticMetacall = 0x00000400,
+ PublicMethods = 0x00000800,
+ ProtectedMethods = 0x00001000,
+ PrivateMethods = 0x00002000,
+ AllMembers = 0x7FFFFFFF,
+ AllPrimaryMembers = 0x7FFFFBFC
+ };
+ Q_DECLARE_FLAGS(AddMembers, AddMember)
+
+ enum MetaObjectFlag {
+ DynamicMetaObject = 0x01
+ };
+ Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
+
+ QMetaObjectBuilder();
+ explicit QMetaObjectBuilder(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
+ virtual ~QMetaObjectBuilder();
+
+ QByteArray className() const;
+ void setClassName(const QByteArray& name);
+
+ const QMetaObject *superClass() const;
+ void setSuperClass(const QMetaObject *meta);
+
+ MetaObjectFlags flags() const;
+ void setFlags(MetaObjectFlags);
+
+ int methodCount() const;
+ int constructorCount() const;
+ int propertyCount() const;
+ int enumeratorCount() const;
+ int classInfoCount() const;
+ int relatedMetaObjectCount() const;
+
+ QMetaMethodBuilder addMethod(const QByteArray& signature);
+ QMetaMethodBuilder addMethod(const QByteArray& signature, const QByteArray& returnType);
+ QMetaMethodBuilder addMethod(const QMetaMethod& prototype);
+
+ QMetaMethodBuilder addSlot(const QByteArray& signature);
+ QMetaMethodBuilder addSignal(const QByteArray& signature);
+
+ QMetaMethodBuilder addConstructor(const QByteArray& signature);
+ QMetaMethodBuilder addConstructor(const QMetaMethod& prototype);
+
+ QMetaPropertyBuilder addProperty(const QByteArray& name, const QByteArray& type, int notifierId=-1);
+ QMetaPropertyBuilder addProperty(const QMetaProperty& prototype);
+
+ QMetaEnumBuilder addEnumerator(const QByteArray& name);
+ QMetaEnumBuilder addEnumerator(const QMetaEnum& prototype);
+
+ int addClassInfo(const QByteArray& name, const QByteArray& value);
+
+#ifdef Q_NO_DATA_RELOCATION
+ int addRelatedMetaObject(const QMetaObjectAccessor &meta);
+#else
+ int addRelatedMetaObject(const QMetaObject *meta);
+#endif
+
+ void addMetaObject(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
+
+ QMetaMethodBuilder method(int index) const;
+ QMetaMethodBuilder constructor(int index) const;
+ QMetaPropertyBuilder property(int index) const;
+ QMetaEnumBuilder enumerator(int index) const;
+ const QMetaObject *relatedMetaObject(int index) const;
+
+ QByteArray classInfoName(int index) const;
+ QByteArray classInfoValue(int index) const;
+
+ void removeMethod(int index);
+ void removeConstructor(int index);
+ void removeProperty(int index);
+ void removeEnumerator(int index);
+ void removeClassInfo(int index);
+ void removeRelatedMetaObject(int index);
+
+ int indexOfMethod(const QByteArray& signature);
+ int indexOfSignal(const QByteArray& signature);
+ int indexOfSlot(const QByteArray& signature);
+ int indexOfConstructor(const QByteArray& signature);
+ int indexOfProperty(const QByteArray& name);
+ int indexOfEnumerator(const QByteArray& name);
+ int indexOfClassInfo(const QByteArray& name);
+
+ typedef QMetaObjectExtraData::StaticMetacallFunction StaticMetacallFunction;
+
+ QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction() const;
+ void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value);
+
+ QMetaObject *toMetaObject() const;
+ QByteArray toRelocatableData(bool * = 0) const;
+ static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &);
+
+#ifndef QT_NO_DATASTREAM
+ void serialize(QDataStream& stream) const;
+ void deserialize
+ (QDataStream& stream,
+ const QMap<QByteArray, const QMetaObject *>& references);
+#endif
+
+private:
+ Q_DISABLE_COPY(QMetaObjectBuilder)
+
+ QMetaObjectBuilderPrivate *d;
+
+ friend class QMetaMethodBuilder;
+ friend class QMetaPropertyBuilder;
+ friend class QMetaEnumBuilder;
+};
+
+class Q_DECLARATIVE_PRIVATE_EXPORT QMetaMethodBuilder
+{
+public:
+ QMetaMethodBuilder() : _mobj(0), _index(0) {}
+
+ int index() const;
+
+ QMetaMethod::MethodType methodType() const;
+ QByteArray signature() const;
+
+ QByteArray returnType() const;
+ void setReturnType(const QByteArray& value);
+
+ QList<QByteArray> parameterNames() const;
+ void setParameterNames(const QList<QByteArray>& value);
+
+ QByteArray tag() const;
+ void setTag(const QByteArray& value);
+
+ QMetaMethod::Access access() const;
+ void setAccess(QMetaMethod::Access value);
+
+ int attributes() const;
+ void setAttributes(int value);
+
+private:
+ const QMetaObjectBuilder *_mobj;
+ int _index;
+
+ friend class QMetaObjectBuilder;
+ friend class QMetaPropertyBuilder;
+
+ QMetaMethodBuilder(const QMetaObjectBuilder *mobj, int index)
+ : _mobj(mobj), _index(index) {}
+
+ QMetaMethodBuilderPrivate *d_func() const;
+};
+
+class Q_DECLARATIVE_PRIVATE_EXPORT QMetaPropertyBuilder
+{
+public:
+ QMetaPropertyBuilder() : _mobj(0), _index(0) {}
+
+ int index() const { return _index; }
+
+ QByteArray name() const;
+ QByteArray type() const;
+
+ bool hasNotifySignal() const;
+ QMetaMethodBuilder notifySignal() const;
+ void setNotifySignal(const QMetaMethodBuilder& value);
+ void removeNotifySignal();
+
+ bool isReadable() const;
+ bool isWritable() const;
+ bool isResettable() const;
+ bool isDesignable() const;
+ bool isScriptable() const;
+ bool isStored() const;
+ bool isEditable() const;
+ bool isUser() const;
+ bool hasStdCppSet() const;
+ bool isEnumOrFlag() const;
+ bool isConstant() const;
+ bool isFinal() const;
+
+ void setReadable(bool value);
+ void setWritable(bool value);
+ void setResettable(bool value);
+ void setDesignable(bool value);
+ void setScriptable(bool value);
+ void setStored(bool value);
+ void setEditable(bool value);
+ void setUser(bool value);
+ void setStdCppSet(bool value);
+ void setEnumOrFlag(bool value);
+ void setConstant(bool value);
+ void setFinal(bool value);
+
+private:
+ const QMetaObjectBuilder *_mobj;
+ int _index;
+
+ friend class QMetaObjectBuilder;
+
+ QMetaPropertyBuilder(const QMetaObjectBuilder *mobj, int index)
+ : _mobj(mobj), _index(index) {}
+
+ QMetaPropertyBuilderPrivate *d_func() const;
+};
+
+class Q_DECLARATIVE_PRIVATE_EXPORT QMetaEnumBuilder
+{
+public:
+ QMetaEnumBuilder() : _mobj(0), _index(0) {}
+
+ int index() const { return _index; }
+
+ QByteArray name() const;
+
+ bool isFlag() const;
+ void setIsFlag(bool value);
+
+ int keyCount() const;
+ QByteArray key(int index) const;
+ int value(int index) const;
+
+ int addKey(const QByteArray& name, int value);
+ void removeKey(int index);
+
+private:
+ const QMetaObjectBuilder *_mobj;
+ int _index;
+
+ friend class QMetaObjectBuilder;
+
+ QMetaEnumBuilder(const QMetaObjectBuilder *mobj, int index)
+ : _mobj(mobj), _index(index) {}
+
+ QMetaEnumBuilderPrivate *d_func() const;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::MetaObjectFlags)
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/qml/ftw/qpodvector_p.h b/src/declarative/qml/ftw/qpodvector_p.h
new file mode 100644
index 0000000000..7b50463145
--- /dev/null
+++ b/src/declarative/qml/ftw/qpodvector_p.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPODVECTOR_P_H
+#define QPODVECTOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+template<class T, int Increment=1024>
+class QPODVector
+{
+public:
+ QPODVector()
+ : m_count(0), m_capacity(0), m_data(0) {}
+ ~QPODVector() { if (m_data) ::free(m_data); }
+
+ const T &at(int idx) const {
+ return m_data[idx];
+ }
+
+ T &operator[](int idx) {
+ return m_data[idx];
+ }
+
+ void clear() {
+ m_count = 0;
+ }
+
+ void prepend(const T &v) {
+ insert(0, v);
+ }
+
+ void append(const T &v) {
+ insert(m_count, v);
+ }
+
+ void insert(int idx, const T &v) {
+ if (m_count == m_capacity) {
+ m_capacity += Increment;
+ m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
+ }
+ int moveCount = m_count - idx;
+ if (moveCount)
+ ::memmove(m_data + idx + 1, m_data + idx, moveCount * sizeof(T));
+ m_count++;
+ m_data[idx] = v;
+ }
+
+ void reserve(int count) {
+ if (count >= m_capacity) {
+ m_capacity = (count + (Increment-1)) & (0xFFFFFFFF - Increment + 1);
+ m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
+ }
+ }
+
+ void insertBlank(int idx, int count) {
+ int newSize = m_count + count;
+ reserve(newSize);
+ int moveCount = m_count - idx;
+ if (moveCount)
+ ::memmove(m_data + idx + count, m_data + idx,
+ moveCount * sizeof(T));
+ m_count = newSize;
+ }
+
+ void remove(int idx, int count = 1) {
+ int moveCount = m_count - (idx + count);
+ if (moveCount)
+ ::memmove(m_data + idx, m_data + idx + count,
+ moveCount * sizeof(T));
+ m_count -= count;
+ }
+
+ void removeOne(const T &v) {
+ int idx = 0;
+ while (idx < m_count) {
+ if (m_data[idx] == v) {
+ remove(idx);
+ return;
+ }
+ ++idx;
+ }
+ }
+
+ int find(const T &v) {
+ for (int idx = 0; idx < m_count; ++idx)
+ if (m_data[idx] == v)
+ return idx;
+ return -1;
+ }
+
+ bool contains(const T &v) {
+ return find(v) != -1;
+ }
+
+ int count() const {
+ return m_count;
+ }
+
+ void copyAndClear(QPODVector<T,Increment> &other) {
+ if (other.m_data) ::free(other.m_data);
+ other.m_count = m_count;
+ other.m_capacity = m_capacity;
+ other.m_data = m_data;
+ m_count = 0;
+ m_capacity = 0;
+ m_data = 0;
+ }
+
+ QPODVector<T,Increment> &operator<<(const T &v) { append(v); return *this; }
+private:
+ QPODVector(const QPODVector &);
+ QPODVector &operator=(const QPODVector &);
+ int m_count;
+ int m_capacity;
+ T *m_data;
+};
+
+QT_END_NAMESPACE
+
+#endif