Merge remote-tracking branch 'origin/containers' into api_changes
Change-Id: Ib8427caca38a14c040850bf45346f3213ffd04b3
This commit is contained in:
commit
08a993526e
26
dist/changes-5.0.0
vendored
26
dist/changes-5.0.0
vendored
@ -36,6 +36,13 @@ information about a particular change.
|
|||||||
- QCoreApplication::translate() will no longer return the source text when
|
- QCoreApplication::translate() will no longer return the source text when
|
||||||
the translation is empty. Use lrelease -removeidentical for optimization.
|
the translation is empty. Use lrelease -removeidentical for optimization.
|
||||||
|
|
||||||
|
- QString and QByteArray constructors that take a size argument will now treat
|
||||||
|
negative sizes to indicate nul-terminated strings (a nul-terminated array of
|
||||||
|
QChar, in the case of QString). In Qt 4, negative sizes were ignored and
|
||||||
|
result in empty QString and QByteArray, respectively. The size argument to
|
||||||
|
those constructors now has a default value of -1, thus replacing the separate
|
||||||
|
constructors that did the same.
|
||||||
|
|
||||||
- Qt::escape() is deprecated (but can be enabled via
|
- Qt::escape() is deprecated (but can be enabled via
|
||||||
QT_DISABLE_DEPRECATED_BEFORE), use QString::toHtmlEscaped() instead.
|
QT_DISABLE_DEPRECATED_BEFORE), use QString::toHtmlEscaped() instead.
|
||||||
|
|
||||||
@ -51,6 +58,11 @@ information about a particular change.
|
|||||||
* QMetaType::construct() has been renamed to QMetaType::create().
|
* QMetaType::construct() has been renamed to QMetaType::create().
|
||||||
* QMetaType::unregisterType() has been removed.
|
* QMetaType::unregisterType() has been removed.
|
||||||
|
|
||||||
|
- QMetaMethod::signature() has been renamed to QMetaMethod::methodSignature(),
|
||||||
|
and the return type has been changed to QByteArray. This was done to be able
|
||||||
|
to generate the signature string on demand, rather than always storing it in
|
||||||
|
the meta-data.
|
||||||
|
|
||||||
- QTestLib:
|
- QTestLib:
|
||||||
* The plain-text, xml and lightxml test output formats have been changed to
|
* The plain-text, xml and lightxml test output formats have been changed to
|
||||||
show a test result for every row of test data in data-driven tests. In
|
show a test result for every row of test data in data-driven tests. In
|
||||||
@ -533,6 +545,20 @@ Qt for Windows CE
|
|||||||
QMetaType::User, which means that it points to the first registered custom
|
QMetaType::User, which means that it points to the first registered custom
|
||||||
type, instead of a nonexistent type.
|
type, instead of a nonexistent type.
|
||||||
|
|
||||||
|
- QMetaType
|
||||||
|
|
||||||
|
* Interpretation of QMetaType::Void was changed. Before, in some cases
|
||||||
|
it was returned as an invalid type id, but sometimes it was used as a valid
|
||||||
|
type (C++ "void"). In Qt5, new QMetaType::UnknownType was introduced to
|
||||||
|
distinguish between these two. QMetaType::UnknownType is an invalid type id
|
||||||
|
signaling that a type is unknown to QMetaType, and QMetaType::Void
|
||||||
|
is a valid type id of C++ void type. The difference will be visible for
|
||||||
|
example in call to QMetaType::typeName(), this function will return null for
|
||||||
|
QMetaType::UnknownType and a pointer to "void" string for
|
||||||
|
QMetaType::Void.
|
||||||
|
Please, notice that QMetaType::UnknownType has value 0, which previously was
|
||||||
|
reserved for QMetaType::Void.
|
||||||
|
|
||||||
|
|
||||||
- QMessageBox
|
- QMessageBox
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i)
|
|||||||
const QMetaObject* metaObject = obj->metaObject();
|
const QMetaObject* metaObject = obj->metaObject();
|
||||||
QStringList methods;
|
QStringList methods;
|
||||||
for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
|
for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
|
||||||
methods << QString::fromLatin1(metaObject->method(i).signature());
|
methods << QString::fromLatin1(metaObject->method(i).methodSignature());
|
||||||
//! [methodCount]
|
//! [methodCount]
|
||||||
|
|
||||||
//! [6]
|
//! [6]
|
||||||
|
@ -73,7 +73,7 @@ MyStruct s2 = var.value<MyStruct>();
|
|||||||
|
|
||||||
//! [3]
|
//! [3]
|
||||||
int id = QMetaType::type("MyClass");
|
int id = QMetaType::type("MyClass");
|
||||||
if (id != 0) {
|
if (id != QMetaType::UnknownType) {
|
||||||
void *myClassPtr = QMetaType::create(id);
|
void *myClassPtr = QMetaType::create(id);
|
||||||
...
|
...
|
||||||
QMetaType::destroy(id, myClassPtr);
|
QMetaType::destroy(id, myClassPtr);
|
||||||
|
@ -400,7 +400,7 @@ QString QJsonValue::toString() const
|
|||||||
if (t != String)
|
if (t != String)
|
||||||
return QString();
|
return QString();
|
||||||
stringData->ref.ref(); // the constructor below doesn't add a ref.
|
stringData->ref.ref(); // the constructor below doesn't add a ref.
|
||||||
return QString(*(const QConstStringData<1> *)stringData);
|
return QString(*(const QStaticStringData<1> *)stringData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -57,8 +57,13 @@ class Q_CORE_EXPORT QMetaMethod
|
|||||||
public:
|
public:
|
||||||
inline QMetaMethod() : mobj(0),handle(0) {}
|
inline QMetaMethod() : mobj(0),handle(0) {}
|
||||||
|
|
||||||
const char *signature() const;
|
QByteArray methodSignature() const;
|
||||||
|
QByteArray name() const;
|
||||||
const char *typeName() const;
|
const char *typeName() const;
|
||||||
|
int returnType() const;
|
||||||
|
int parameterCount() const;
|
||||||
|
int parameterType(int index) const;
|
||||||
|
void getParameterTypes(int *types) const;
|
||||||
QList<QByteArray> parameterTypes() const;
|
QList<QByteArray> parameterTypes() const;
|
||||||
QList<QByteArray> parameterNames() const;
|
QList<QByteArray> parameterNames() const;
|
||||||
const char *tag() const;
|
const char *tag() const;
|
||||||
@ -137,8 +142,16 @@ public:
|
|||||||
inline bool isValid() const { return mobj != 0; }
|
inline bool isValid() const { return mobj != 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if QT_DEPRECATED_SINCE(5,0)
|
||||||
|
// signature() has been renamed to methodSignature() in Qt 5.
|
||||||
|
// Warning, that function returns a QByteArray; check the life time if
|
||||||
|
// you convert to char*.
|
||||||
|
char *signature(struct renamedInQt5_warning_checkTheLifeTime * = 0) Q_DECL_EQ_DELETE;
|
||||||
|
#endif
|
||||||
|
|
||||||
const QMetaObject *mobj;
|
const QMetaObject *mobj;
|
||||||
uint handle;
|
uint handle;
|
||||||
|
friend class QMetaMethodPrivate;
|
||||||
friend struct QMetaObject;
|
friend struct QMetaObject;
|
||||||
friend struct QMetaObjectPrivate;
|
friend struct QMetaObjectPrivate;
|
||||||
friend class QObject;
|
friend class QObject;
|
||||||
|
@ -105,11 +105,64 @@ enum MetaObjectFlags {
|
|||||||
RequiresVariantMetaObject = 0x02
|
RequiresVariantMetaObject = 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MetaDataFlags {
|
||||||
|
IsUnresolvedType = 0x80000000,
|
||||||
|
TypeNameIndexMask = 0x7FFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
class QArgumentType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QArgumentType(int type)
|
||||||
|
: _type(type)
|
||||||
|
{}
|
||||||
|
QArgumentType(const QByteArray &name)
|
||||||
|
: _type(QMetaType::type(name.constData())), _name(name)
|
||||||
|
{}
|
||||||
|
QArgumentType()
|
||||||
|
: _type(0)
|
||||||
|
{}
|
||||||
|
int type() const
|
||||||
|
{ return _type; }
|
||||||
|
QByteArray name() const
|
||||||
|
{
|
||||||
|
if (_type && _name.isEmpty())
|
||||||
|
const_cast<QArgumentType *>(this)->_name = QMetaType::typeName(_type);
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
bool operator==(const QArgumentType &other) const
|
||||||
|
{
|
||||||
|
if (_type)
|
||||||
|
return _type == other._type;
|
||||||
|
else if (other._type)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return _name == other._name;
|
||||||
|
}
|
||||||
|
bool operator!=(const QArgumentType &other) const
|
||||||
|
{
|
||||||
|
if (_type)
|
||||||
|
return _type != other._type;
|
||||||
|
else if (other._type)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return _name != other._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _type;
|
||||||
|
QByteArray _name;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, int> class QVarLengthArray;
|
||||||
|
typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
|
||||||
|
|
||||||
|
class QMetaMethodPrivate;
|
||||||
class QMutex;
|
class QMutex;
|
||||||
|
|
||||||
struct QMetaObjectPrivate
|
struct QMetaObjectPrivate
|
||||||
{
|
{
|
||||||
enum { OutputRevision = 6 }; // Used by moc and qmetaobjectbuilder
|
enum { OutputRevision = 7 }; // Used by moc, qmetaobjectbuilder and qdbus
|
||||||
|
|
||||||
int revision;
|
int revision;
|
||||||
int className;
|
int className;
|
||||||
@ -122,6 +175,7 @@ struct QMetaObjectPrivate
|
|||||||
int signalCount; //since revision 4
|
int signalCount; //since revision 4
|
||||||
// revision 5 introduces changes in normalized signatures, no new members
|
// revision 5 introduces changes in normalized signatures, no new members
|
||||||
// revision 6 added qt_static_metacall as a member of each Q_OBJECT and inside QMetaObject itself
|
// revision 6 added qt_static_metacall as a member of each Q_OBJECT and inside QMetaObject itself
|
||||||
|
// revision 7 is Qt 5
|
||||||
|
|
||||||
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
|
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
|
||||||
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
|
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
|
||||||
@ -134,6 +188,27 @@ struct QMetaObjectPrivate
|
|||||||
bool normalizeStringData);
|
bool normalizeStringData);
|
||||||
static int originalClone(const QMetaObject *obj, int local_method_index);
|
static int originalClone(const QMetaObject *obj, int local_method_index);
|
||||||
|
|
||||||
|
static QByteArray decodeMethodSignature(const char *signature,
|
||||||
|
QArgumentTypeArray &types);
|
||||||
|
static int indexOfSignalRelative(const QMetaObject **baseObject,
|
||||||
|
const QByteArray &name, int argc,
|
||||||
|
const QArgumentType *types);
|
||||||
|
static int indexOfSlotRelative(const QMetaObject **m,
|
||||||
|
const QByteArray &name, int argc,
|
||||||
|
const QArgumentType *types);
|
||||||
|
static int indexOfSignal(const QMetaObject *m, const QByteArray &name,
|
||||||
|
int argc, const QArgumentType *types);
|
||||||
|
static int indexOfSlot(const QMetaObject *m, const QByteArray &name,
|
||||||
|
int argc, const QArgumentType *types);
|
||||||
|
static int indexOfMethod(const QMetaObject *m, const QByteArray &name,
|
||||||
|
int argc, const QArgumentType *types);
|
||||||
|
static int indexOfConstructor(const QMetaObject *m, const QByteArray &name,
|
||||||
|
int argc, const QArgumentType *types);
|
||||||
|
static bool checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
|
||||||
|
int methodArgc, const QArgumentType *methodTypes);
|
||||||
|
static bool checkConnectArgs(const QMetaMethodPrivate *signal,
|
||||||
|
const QMetaMethodPrivate *method);
|
||||||
|
|
||||||
static QList<QByteArray> parameterTypeNamesFromSignature(const char *signature);
|
static QList<QByteArray> parameterTypeNamesFromSignature(const char *signature);
|
||||||
|
|
||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
|
@ -78,26 +78,17 @@ QT_BEGIN_NAMESPACE
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// copied from moc's generator.cpp
|
// copied from moc's generator.cpp
|
||||||
uint qvariant_nameToType(const char* name)
|
bool isBuiltinType(const QByteArray &type)
|
||||||
{
|
{
|
||||||
if (!name)
|
int id = QMetaType::type(type);
|
||||||
return 0;
|
if (!id && !type.isEmpty() && type != "void")
|
||||||
|
return false;
|
||||||
uint tp = QMetaType::type(name);
|
return (id < QMetaType::User);
|
||||||
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.cpp
|
||||||
static inline const QMetaObjectPrivate *priv(const uint* data)
|
static inline const QMetaObjectPrivate *priv(const uint* data)
|
||||||
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
|
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
|
||||||
// end of copied lines from qmetaobject.cpp
|
|
||||||
|
|
||||||
class QMetaMethodBuilderPrivate
|
class QMetaMethodBuilderPrivate
|
||||||
{
|
{
|
||||||
@ -136,6 +127,21 @@ public:
|
|||||||
{
|
{
|
||||||
attributes = ((attributes & ~AccessMask) | (int)value);
|
attributes = ((attributes & ~AccessMask) | (int)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QByteArray> parameterTypes() const
|
||||||
|
{
|
||||||
|
return QMetaObjectPrivate::parameterTypeNamesFromSignature(signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
int parameterCount() const
|
||||||
|
{
|
||||||
|
return parameterTypes().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray name() const
|
||||||
|
{
|
||||||
|
return signature.left(qMax(signature.indexOf('('), 0));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class QMetaPropertyBuilderPrivate
|
class QMetaPropertyBuilderPrivate
|
||||||
@ -458,13 +464,13 @@ QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
|
|||||||
{
|
{
|
||||||
QMetaMethodBuilder method;
|
QMetaMethodBuilder method;
|
||||||
if (prototype.methodType() == QMetaMethod::Method)
|
if (prototype.methodType() == QMetaMethod::Method)
|
||||||
method = addMethod(prototype.signature());
|
method = addMethod(prototype.methodSignature());
|
||||||
else if (prototype.methodType() == QMetaMethod::Signal)
|
else if (prototype.methodType() == QMetaMethod::Signal)
|
||||||
method = addSignal(prototype.signature());
|
method = addSignal(prototype.methodSignature());
|
||||||
else if (prototype.methodType() == QMetaMethod::Slot)
|
else if (prototype.methodType() == QMetaMethod::Slot)
|
||||||
method = addSlot(prototype.signature());
|
method = addSlot(prototype.methodSignature());
|
||||||
else if (prototype.methodType() == QMetaMethod::Constructor)
|
else if (prototype.methodType() == QMetaMethod::Constructor)
|
||||||
method = addConstructor(prototype.signature());
|
method = addConstructor(prototype.methodSignature());
|
||||||
method.setReturnType(prototype.typeName());
|
method.setReturnType(prototype.typeName());
|
||||||
method.setParameterNames(prototype.parameterNames());
|
method.setParameterNames(prototype.parameterNames());
|
||||||
method.setTag(prototype.tag());
|
method.setTag(prototype.tag());
|
||||||
@ -535,7 +541,7 @@ QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signatur
|
|||||||
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
|
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
|
||||||
{
|
{
|
||||||
Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
|
Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
|
||||||
QMetaMethodBuilder ctor = addConstructor(prototype.signature());
|
QMetaMethodBuilder ctor = addConstructor(prototype.methodSignature());
|
||||||
ctor.setReturnType(prototype.typeName());
|
ctor.setReturnType(prototype.typeName());
|
||||||
ctor.setParameterNames(prototype.parameterNames());
|
ctor.setParameterNames(prototype.parameterNames());
|
||||||
ctor.setTag(prototype.tag());
|
ctor.setTag(prototype.tag());
|
||||||
@ -588,7 +594,7 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot
|
|||||||
if (prototype.hasNotifySignal()) {
|
if (prototype.hasNotifySignal()) {
|
||||||
// Find an existing method for the notify signal, or add a new one.
|
// Find an existing method for the notify signal, or add a new one.
|
||||||
QMetaMethod method = prototype.notifySignal();
|
QMetaMethod method = prototype.notifySignal();
|
||||||
int index = indexOfMethod(method.signature());
|
int index = indexOfMethod(method.methodSignature());
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
index = addMethod(method).index();
|
index = addMethod(method).index();
|
||||||
d->properties[property._index].notifySignal = index;
|
d->properties[property._index].notifySignal = index;
|
||||||
@ -1070,75 +1076,82 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
|
|||||||
#define ALIGN(size,type) \
|
#define ALIGN(size,type) \
|
||||||
(size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
|
(size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
|
||||||
|
|
||||||
class MetaStringTable
|
/*!
|
||||||
|
\class QMetaStringTable
|
||||||
|
\internal
|
||||||
|
\brief The QMetaStringTable class can generate a meta-object string table at runtime.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QMetaStringTable::QMetaStringTable()
|
||||||
|
: m_index(0) {}
|
||||||
|
|
||||||
|
// Enters the given value into the string table (if it hasn't already been
|
||||||
|
// entered). Returns the index of the string.
|
||||||
|
int QMetaStringTable::enter(const QByteArray &value)
|
||||||
{
|
{
|
||||||
public:
|
Entries::iterator it = m_entries.find(value);
|
||||||
typedef QHash<QByteArray, int> Entries; // string --> offset mapping
|
if (it != m_entries.end())
|
||||||
typedef Entries::const_iterator const_iterator;
|
return it.value();
|
||||||
Entries::const_iterator constBegin() const
|
int pos = m_index;
|
||||||
{ return m_entries.constBegin(); }
|
m_entries.insert(value, pos);
|
||||||
Entries::const_iterator constEnd() const
|
++m_index;
|
||||||
{ return m_entries.constEnd(); }
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
MetaStringTable() : m_offset(0) {}
|
int QMetaStringTable::preferredAlignment()
|
||||||
|
|
||||||
int enter(const QByteArray &value)
|
|
||||||
{
|
|
||||||
Entries::iterator it = m_entries.find(value);
|
|
||||||
if (it != m_entries.end())
|
|
||||||
return it.value();
|
|
||||||
int pos = m_offset;
|
|
||||||
m_entries.insert(value, pos);
|
|
||||||
m_offset += value.size() + 1;
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
int arraySize() const { return m_offset; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Entries m_entries;
|
|
||||||
int m_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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.
|
#ifdef Q_ALIGNOF
|
||||||
if (!parameterNames.isEmpty()) {
|
return Q_ALIGNOF(QByteArrayData);
|
||||||
QByteArray names;
|
#else
|
||||||
bool first = true;
|
return sizeof(void *);
|
||||||
foreach (const QByteArray &name, parameterNames) {
|
#endif
|
||||||
if (first)
|
}
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
names += (char)',';
|
|
||||||
names += name;
|
|
||||||
}
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count commas in the signature, excluding those inside template arguments.
|
// Returns the size (in bytes) required for serializing this string table.
|
||||||
int index = signature.indexOf('(');
|
int QMetaStringTable::blobSize() const
|
||||||
if (index < 0)
|
{
|
||||||
return QByteArray();
|
int size = m_entries.size() * sizeof(QByteArrayData);
|
||||||
++index;
|
Entries::const_iterator it;
|
||||||
if (index >= signature.size())
|
for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
|
||||||
return QByteArray();
|
size += it.key().size() + 1;
|
||||||
if (signature[index] == ')')
|
return size;
|
||||||
return QByteArray();
|
}
|
||||||
int count = 1;
|
|
||||||
int brackets = 0;
|
// Writes strings to string data struct.
|
||||||
while (index < signature.size() && signature[index] != ',') {
|
// The struct consists of an array of QByteArrayData, followed by a char array
|
||||||
char ch = signature[index++];
|
// containing the actual strings. This format must match the one produced by
|
||||||
if (ch == '<')
|
// moc (see generator.cpp).
|
||||||
++brackets;
|
void QMetaStringTable::writeBlob(char *out)
|
||||||
else if (ch == '>')
|
{
|
||||||
--brackets;
|
Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1)));
|
||||||
else if (ch == ',' && brackets <= 0)
|
|
||||||
++count;
|
int offsetOfStringdataMember = m_entries.size() * sizeof(QByteArrayData);
|
||||||
|
int stringdataOffset = 0;
|
||||||
|
for (int i = 0; i < m_entries.size(); ++i) {
|
||||||
|
const QByteArray &str = m_entries.key(i);
|
||||||
|
int size = str.size();
|
||||||
|
qptrdiff offset = offsetOfStringdataMember + stringdataOffset
|
||||||
|
- i * sizeof(QByteArrayData);
|
||||||
|
const QByteArrayData data = { Q_REFCOUNT_INITIALIZE_STATIC, size, 0, 0, offset };
|
||||||
|
|
||||||
|
memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData));
|
||||||
|
|
||||||
|
memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size);
|
||||||
|
out[offsetOfStringdataMember + stringdataOffset + size] = '\0';
|
||||||
|
|
||||||
|
stringdataOffset += size + 1;
|
||||||
}
|
}
|
||||||
return QByteArray(count - 1, ',');
|
}
|
||||||
|
|
||||||
|
// Returns the sum of all parameters (including return type) for the given
|
||||||
|
// \a methods. This is needed for calculating the size of the methods'
|
||||||
|
// parameter type/name meta-data.
|
||||||
|
static int aggregateParameterCount(const QList<QMetaMethodBuilderPrivate> &methods)
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < methods.size(); ++i)
|
||||||
|
sum += methods.at(i).parameterCount() + 1; // +1 for return type
|
||||||
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a QMetaObject in "buf" based on the information in "d".
|
// Build a QMetaObject in "buf" based on the information in "d".
|
||||||
@ -1151,6 +1164,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
Q_UNUSED(expectedSize); // Avoid warning in release mode
|
Q_UNUSED(expectedSize); // Avoid warning in release mode
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int dataIndex;
|
int dataIndex;
|
||||||
|
int paramsIndex;
|
||||||
int enumIndex;
|
int enumIndex;
|
||||||
int index;
|
int index;
|
||||||
bool hasRevisionedMethods = d->hasRevisionedMethods();
|
bool hasRevisionedMethods = d->hasRevisionedMethods();
|
||||||
@ -1181,8 +1195,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int methodParametersDataSize =
|
||||||
|
((aggregateParameterCount(d->methods)
|
||||||
|
+ aggregateParameterCount(d->constructors)) * 2) // types and parameter names
|
||||||
|
- d->methods.size() // return "parameters" don't have names
|
||||||
|
- d->constructors.size(); // "this" parameters don't have names
|
||||||
if (buf) {
|
if (buf) {
|
||||||
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 6, "QMetaObjectBuilder should generate the same version as moc");
|
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QMetaObjectBuilder should generate the same version as moc");
|
||||||
pmeta->revision = QMetaObjectPrivate::OutputRevision;
|
pmeta->revision = QMetaObjectPrivate::OutputRevision;
|
||||||
pmeta->flags = d->flags;
|
pmeta->flags = d->flags;
|
||||||
pmeta->className = 0; // Class name is always the first string.
|
pmeta->className = 0; // Class name is always the first string.
|
||||||
@ -1197,6 +1216,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
dataIndex += 5 * d->methods.size();
|
dataIndex += 5 * d->methods.size();
|
||||||
if (hasRevisionedMethods)
|
if (hasRevisionedMethods)
|
||||||
dataIndex += d->methods.size();
|
dataIndex += d->methods.size();
|
||||||
|
paramsIndex = dataIndex;
|
||||||
|
dataIndex += methodParametersDataSize;
|
||||||
|
|
||||||
pmeta->propertyCount = d->properties.size();
|
pmeta->propertyCount = d->properties.size();
|
||||||
pmeta->propertyData = dataIndex;
|
pmeta->propertyData = dataIndex;
|
||||||
@ -1218,6 +1239,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
dataIndex += 5 * d->methods.size();
|
dataIndex += 5 * d->methods.size();
|
||||||
if (hasRevisionedMethods)
|
if (hasRevisionedMethods)
|
||||||
dataIndex += d->methods.size();
|
dataIndex += d->methods.size();
|
||||||
|
paramsIndex = dataIndex;
|
||||||
|
dataIndex += methodParametersDataSize;
|
||||||
dataIndex += 3 * d->properties.size();
|
dataIndex += 3 * d->properties.size();
|
||||||
if (hasNotifySignals)
|
if (hasNotifySignals)
|
||||||
dataIndex += d->properties.size();
|
dataIndex += d->properties.size();
|
||||||
@ -1240,13 +1263,14 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
// Find the start of the data and string tables.
|
// Find the start of the data and string tables.
|
||||||
int *data = reinterpret_cast<int *>(pmeta);
|
int *data = reinterpret_cast<int *>(pmeta);
|
||||||
size += dataIndex * sizeof(int);
|
size += dataIndex * sizeof(int);
|
||||||
|
ALIGN(size, void *);
|
||||||
char *str = reinterpret_cast<char *>(buf + size);
|
char *str = reinterpret_cast<char *>(buf + size);
|
||||||
if (buf) {
|
if (buf) {
|
||||||
if (relocatable) {
|
if (relocatable) {
|
||||||
meta->d.stringdata = reinterpret_cast<const char *>((quintptr)size);
|
meta->d.stringdata = reinterpret_cast<const QByteArrayData *>((quintptr)size);
|
||||||
meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
|
meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
|
||||||
} else {
|
} else {
|
||||||
meta->d.stringdata = str;
|
meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str);
|
||||||
meta->d.data = reinterpret_cast<uint *>(data);
|
meta->d.data = reinterpret_cast<uint *>(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1254,7 +1278,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
// Reset the current data position to just past the QMetaObjectPrivate.
|
// Reset the current data position to just past the QMetaObjectPrivate.
|
||||||
dataIndex = MetaObjectPrivateFieldCount;
|
dataIndex = MetaObjectPrivateFieldCount;
|
||||||
|
|
||||||
MetaStringTable strings;
|
QMetaStringTable strings;
|
||||||
strings.enter(d->className);
|
strings.enter(d->className);
|
||||||
|
|
||||||
// Output the class infos,
|
// Output the class infos,
|
||||||
@ -1273,24 +1297,21 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
Q_ASSERT(!buf || dataIndex == pmeta->methodData);
|
Q_ASSERT(!buf || dataIndex == pmeta->methodData);
|
||||||
for (index = 0; index < d->methods.size(); ++index) {
|
for (index = 0; index < d->methods.size(); ++index) {
|
||||||
QMetaMethodBuilderPrivate *method = &(d->methods[index]);
|
QMetaMethodBuilderPrivate *method = &(d->methods[index]);
|
||||||
int sig = strings.enter(method->signature);
|
int name = strings.enter(method->name());
|
||||||
int params;
|
int argc = method->parameterCount();
|
||||||
QByteArray names = buildParameterNames
|
|
||||||
(method->signature, method->parameterNames);
|
|
||||||
params = strings.enter(names);
|
|
||||||
int ret = strings.enter(method->returnType);
|
|
||||||
int tag = strings.enter(method->tag);
|
int tag = strings.enter(method->tag);
|
||||||
int attrs = method->attributes;
|
int attrs = method->attributes;
|
||||||
if (buf) {
|
if (buf) {
|
||||||
data[dataIndex] = sig;
|
data[dataIndex] = name;
|
||||||
data[dataIndex + 1] = params;
|
data[dataIndex + 1] = argc;
|
||||||
data[dataIndex + 2] = ret;
|
data[dataIndex + 2] = paramsIndex;
|
||||||
data[dataIndex + 3] = tag;
|
data[dataIndex + 3] = tag;
|
||||||
data[dataIndex + 4] = attrs;
|
data[dataIndex + 4] = attrs;
|
||||||
if (method->methodType() == QMetaMethod::Signal)
|
if (method->methodType() == QMetaMethod::Signal)
|
||||||
pmeta->signalCount++;
|
pmeta->signalCount++;
|
||||||
}
|
}
|
||||||
dataIndex += 5;
|
dataIndex += 5;
|
||||||
|
paramsIndex += 1 + argc * 2;
|
||||||
}
|
}
|
||||||
if (hasRevisionedMethods) {
|
if (hasRevisionedMethods) {
|
||||||
for (index = 0; index < d->methods.size(); ++index) {
|
for (index = 0; index < d->methods.size(); ++index) {
|
||||||
@ -1301,23 +1322,59 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Output the method parameters in the class.
|
||||||
|
Q_ASSERT(!buf || dataIndex == pmeta->methodData + d->methods.size() * 5
|
||||||
|
+ (hasRevisionedMethods ? d->methods.size() : 0));
|
||||||
|
for (int x = 0; x < 2; ++x) {
|
||||||
|
QList<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
|
||||||
|
for (index = 0; index < methods.size(); ++index) {
|
||||||
|
QMetaMethodBuilderPrivate *method = &(methods[index]);
|
||||||
|
QList<QByteArray> paramTypeNames = method->parameterTypes();
|
||||||
|
int paramCount = paramTypeNames.size();
|
||||||
|
for (int i = -1; i < paramCount; ++i) {
|
||||||
|
const QByteArray &typeName = (i < 0) ? method->returnType : paramTypeNames.at(i);
|
||||||
|
int typeInfo;
|
||||||
|
if (isBuiltinType(typeName))
|
||||||
|
typeInfo = QMetaType::type(typeName);
|
||||||
|
else
|
||||||
|
typeInfo = IsUnresolvedType | strings.enter(typeName);
|
||||||
|
if (buf)
|
||||||
|
data[dataIndex] = typeInfo;
|
||||||
|
++dataIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QByteArray> paramNames = method->parameterNames;
|
||||||
|
while (paramNames.size() < paramCount)
|
||||||
|
paramNames.append(QByteArray());
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
int stringIndex = strings.enter(paramNames.at(i));
|
||||||
|
if (buf)
|
||||||
|
data[dataIndex] = stringIndex;
|
||||||
|
++dataIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Output the properties in the class.
|
// Output the properties in the class.
|
||||||
Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
|
Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
|
||||||
for (index = 0; index < d->properties.size(); ++index) {
|
for (index = 0; index < d->properties.size(); ++index) {
|
||||||
QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
|
QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
|
||||||
int name = strings.enter(prop->name);
|
int name = strings.enter(prop->name);
|
||||||
int type = strings.enter(prop->type);
|
|
||||||
|
int typeInfo;
|
||||||
|
if (isBuiltinType(prop->type))
|
||||||
|
typeInfo = QMetaType::type(prop->type);
|
||||||
|
else
|
||||||
|
typeInfo = IsUnresolvedType | strings.enter(prop->type);
|
||||||
|
|
||||||
int flags = prop->flags;
|
int flags = prop->flags;
|
||||||
|
|
||||||
if (!isVariantType(prop->type)) {
|
if (!isBuiltinType(prop->type))
|
||||||
flags |= EnumOrFlag;
|
flags |= EnumOrFlag;
|
||||||
} else {
|
|
||||||
flags |= qvariant_nameToType(prop->type) << 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
data[dataIndex] = name;
|
data[dataIndex] = name;
|
||||||
data[dataIndex + 1] = type;
|
data[dataIndex + 1] = typeInfo;
|
||||||
data[dataIndex + 2] = flags;
|
data[dataIndex + 2] = flags;
|
||||||
}
|
}
|
||||||
dataIndex += 3;
|
dataIndex += 3;
|
||||||
@ -1372,34 +1429,25 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||||||
Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
|
Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
|
||||||
for (index = 0; index < d->constructors.size(); ++index) {
|
for (index = 0; index < d->constructors.size(); ++index) {
|
||||||
QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
|
QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
|
||||||
int sig = strings.enter(method->signature);
|
int name = strings.enter(method->name());
|
||||||
int params;
|
int argc = method->parameterCount();
|
||||||
QByteArray names = buildParameterNames
|
|
||||||
(method->signature, method->parameterNames);
|
|
||||||
params = strings.enter(names);
|
|
||||||
int ret = strings.enter(method->returnType);
|
|
||||||
int tag = strings.enter(method->tag);
|
int tag = strings.enter(method->tag);
|
||||||
int attrs = method->attributes;
|
int attrs = method->attributes;
|
||||||
if (buf) {
|
if (buf) {
|
||||||
data[dataIndex] = sig;
|
data[dataIndex] = name;
|
||||||
data[dataIndex + 1] = params;
|
data[dataIndex + 1] = argc;
|
||||||
data[dataIndex + 2] = ret;
|
data[dataIndex + 2] = paramsIndex;
|
||||||
data[dataIndex + 3] = tag;
|
data[dataIndex + 3] = tag;
|
||||||
data[dataIndex + 4] = attrs;
|
data[dataIndex + 4] = attrs;
|
||||||
}
|
}
|
||||||
dataIndex += 5;
|
dataIndex += 5;
|
||||||
|
paramsIndex += 1 + argc * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
size += strings.arraySize();
|
size += strings.blobSize();
|
||||||
|
|
||||||
if (buf) {
|
if (buf)
|
||||||
// Write strings to string data array.
|
strings.writeBlob(str);
|
||||||
MetaStringTable::const_iterator it;
|
|
||||||
for (it = strings.constBegin(); it != strings.constEnd(); ++it) {
|
|
||||||
memcpy(str + it.value(), it.key().constData(), it.key().size());
|
|
||||||
str[it.value() + it.key().size()] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output the zero terminator in the data array.
|
// Output the zero terminator in the data array.
|
||||||
if (buf)
|
if (buf)
|
||||||
@ -1508,7 +1556,7 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
|
|||||||
quintptr dataOffset = (quintptr)dataMo->d.data;
|
quintptr dataOffset = (quintptr)dataMo->d.data;
|
||||||
|
|
||||||
output->d.superdata = superclass;
|
output->d.superdata = superclass;
|
||||||
output->d.stringdata = buf + stringdataOffset;
|
output->d.stringdata = reinterpret_cast<const QByteArrayData *>(buf + stringdataOffset);
|
||||||
output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
|
output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
|
||||||
output->d.extradata = 0;
|
output->d.extradata = 0;
|
||||||
}
|
}
|
||||||
@ -1896,7 +1944,7 @@ QByteArray QMetaMethodBuilder::returnType() const
|
|||||||
is empty, then the method's return type is \c{void}. The \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.
|
will be normalized before it is added to the method.
|
||||||
|
|
||||||
\sa returnType(), signature()
|
\sa returnType(), parameterTypes(), signature()
|
||||||
*/
|
*/
|
||||||
void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
||||||
{
|
{
|
||||||
@ -1905,6 +1953,20 @@ void QMetaMethodBuilder::setReturnType(const QByteArray& value)
|
|||||||
d->returnType = QMetaObject::normalizedType(value);
|
d->returnType = QMetaObject::normalizedType(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the list of parameter types for this method.
|
||||||
|
|
||||||
|
\sa returnType(), parameterNames()
|
||||||
|
*/
|
||||||
|
QList<QByteArray> QMetaMethodBuilder::parameterTypes() const
|
||||||
|
{
|
||||||
|
QMetaMethodBuilderPrivate *d = d_func();
|
||||||
|
if (d)
|
||||||
|
return d->parameterTypes();
|
||||||
|
else
|
||||||
|
return QList<QByteArray>();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the list of parameter names for this method.
|
Returns the list of parameter names for this method.
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
#include <QtCore/qobject.h>
|
#include <QtCore/qobject.h>
|
||||||
#include <QtCore/qmetaobject.h>
|
#include <QtCore/qmetaobject.h>
|
||||||
#include <QtCore/qdatastream.h>
|
#include <QtCore/qdatastream.h>
|
||||||
|
#include <QtCore/qhash.h>
|
||||||
#include <QtCore/qmap.h>
|
#include <QtCore/qmap.h>
|
||||||
|
|
||||||
|
|
||||||
@ -203,6 +204,7 @@ public:
|
|||||||
QByteArray returnType() const;
|
QByteArray returnType() const;
|
||||||
void setReturnType(const QByteArray& value);
|
void setReturnType(const QByteArray& value);
|
||||||
|
|
||||||
|
QList<QByteArray> parameterTypes() const;
|
||||||
QList<QByteArray> parameterNames() const;
|
QList<QByteArray> parameterNames() const;
|
||||||
void setParameterNames(const QList<QByteArray>& value);
|
void setParameterNames(const QList<QByteArray>& value);
|
||||||
|
|
||||||
@ -318,6 +320,23 @@ private:
|
|||||||
QMetaEnumBuilderPrivate *d_func() const;
|
QMetaEnumBuilderPrivate *d_func() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Q_CORE_EXPORT QMetaStringTable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMetaStringTable();
|
||||||
|
|
||||||
|
int enter(const QByteArray &value);
|
||||||
|
|
||||||
|
static int preferredAlignment();
|
||||||
|
int blobSize() const;
|
||||||
|
void writeBlob(char *out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef QHash<QByteArray, int> Entries; // string --> index mapping
|
||||||
|
Entries m_entries;
|
||||||
|
int m_index;
|
||||||
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers)
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::MetaObjectFlags)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::MetaObjectFlags)
|
||||||
|
|
||||||
|
@ -242,6 +242,7 @@ template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = fals
|
|||||||
\value QEasingCurve QEasingCurve
|
\value QEasingCurve QEasingCurve
|
||||||
|
|
||||||
\value User Base value for user types
|
\value User Base value for user types
|
||||||
|
\value UnknownType This is an invalid type id. It is returned from QMetaType for types that are not registered
|
||||||
|
|
||||||
\omitvalue FirstGuiType
|
\omitvalue FirstGuiType
|
||||||
\omitvalue FirstWidgetsType
|
\omitvalue FirstWidgetsType
|
||||||
@ -311,7 +312,7 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ
|
|||||||
QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE)
|
QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE)
|
||||||
QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER)
|
QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER)
|
||||||
QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER)
|
QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER)
|
||||||
{0, 0, QMetaType::Void}
|
{0, 0, QMetaType::UnknownType}
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0;
|
Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0;
|
||||||
@ -348,10 +349,7 @@ Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
|
|||||||
void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
|
void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
|
||||||
LoadOperator loadOp)
|
LoadOperator loadOp)
|
||||||
{
|
{
|
||||||
int idx = type(typeName);
|
registerStreamOperators(type(typeName), saveOp, loadOp);
|
||||||
if (!idx)
|
|
||||||
return;
|
|
||||||
registerStreamOperators(idx, saveOp, loadOp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \internal
|
/*! \internal
|
||||||
@ -434,7 +432,7 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
|
|||||||
{
|
{
|
||||||
const QVector<QCustomTypeInfo> * const ct = customTypes();
|
const QVector<QCustomTypeInfo> * const ct = customTypes();
|
||||||
if (!ct)
|
if (!ct)
|
||||||
return 0;
|
return QMetaType::UnknownType;
|
||||||
|
|
||||||
for (int v = 0; v < ct->count(); ++v) {
|
for (int v = 0; v < ct->count(); ++v) {
|
||||||
const QCustomTypeInfo &customInfo = ct->at(v);
|
const QCustomTypeInfo &customInfo = ct->at(v);
|
||||||
@ -445,7 +443,7 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
|
|||||||
return v + QMetaType::User;
|
return v + QMetaType::User;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return QMetaType::UnknownType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \internal
|
/*! \internal
|
||||||
@ -488,11 +486,11 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
|
|||||||
|
|
||||||
int previousSize = 0;
|
int previousSize = 0;
|
||||||
int previousFlags = 0;
|
int previousFlags = 0;
|
||||||
if (!idx) {
|
if (idx == UnknownType) {
|
||||||
QWriteLocker locker(customTypesLock());
|
QWriteLocker locker(customTypesLock());
|
||||||
idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
|
idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
|
||||||
normalizedTypeName.size());
|
normalizedTypeName.size());
|
||||||
if (!idx) {
|
if (idx == UnknownType) {
|
||||||
QCustomTypeInfo inf;
|
QCustomTypeInfo inf;
|
||||||
inf.typeName = normalizedTypeName;
|
inf.typeName = normalizedTypeName;
|
||||||
inf.creator = creator;
|
inf.creator = creator;
|
||||||
@ -558,12 +556,12 @@ int QMetaType::registerTypedef(const char* typeName, int aliasId)
|
|||||||
int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
|
int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
|
||||||
normalizedTypeName.size());
|
normalizedTypeName.size());
|
||||||
|
|
||||||
if (!idx) {
|
if (idx == UnknownType) {
|
||||||
QWriteLocker locker(customTypesLock());
|
QWriteLocker locker(customTypesLock());
|
||||||
idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
|
idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
|
||||||
normalizedTypeName.size());
|
normalizedTypeName.size());
|
||||||
|
|
||||||
if (!idx) {
|
if (idx == UnknownType) {
|
||||||
QCustomTypeInfo inf;
|
QCustomTypeInfo inf;
|
||||||
inf.typeName = normalizedTypeName;
|
inf.typeName = normalizedTypeName;
|
||||||
inf.alias = aliasId;
|
inf.alias = aliasId;
|
||||||
@ -592,17 +590,20 @@ int QMetaType::registerTypedef(const char* typeName, int aliasId)
|
|||||||
*/
|
*/
|
||||||
bool QMetaType::isRegistered(int type)
|
bool QMetaType::isRegistered(int type)
|
||||||
{
|
{
|
||||||
if (type >= 0 && type < User) {
|
// predefined type
|
||||||
// predefined type
|
if ((type >= FirstCoreType && type <= LastCoreType)
|
||||||
|
|| (type >= FirstGuiType && type <= LastGuiType)
|
||||||
|
|| (type >= FirstWidgetsType && type <= LastWidgetsType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QReadLocker locker(customTypesLock());
|
QReadLocker locker(customTypesLock());
|
||||||
const QVector<QCustomTypeInfo> * const ct = customTypes();
|
const QVector<QCustomTypeInfo> * const ct = customTypes();
|
||||||
return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
|
return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns a handle to the type called \a typeName, or 0 if there is
|
Returns a handle to the type called \a typeName, or QMetaType::UnknownType if there is
|
||||||
no such type.
|
no such type.
|
||||||
|
|
||||||
\sa isRegistered(), typeName(), Type
|
\sa isRegistered(), typeName(), Type
|
||||||
@ -611,17 +612,17 @@ int QMetaType::type(const char *typeName)
|
|||||||
{
|
{
|
||||||
int length = qstrlen(typeName);
|
int length = qstrlen(typeName);
|
||||||
if (!length)
|
if (!length)
|
||||||
return 0;
|
return UnknownType;
|
||||||
int type = qMetaTypeStaticType(typeName, length);
|
int type = qMetaTypeStaticType(typeName, length);
|
||||||
if (!type) {
|
if (type == UnknownType) {
|
||||||
QReadLocker locker(customTypesLock());
|
QReadLocker locker(customTypesLock());
|
||||||
type = qMetaTypeCustomType_unlocked(typeName, length);
|
type = qMetaTypeCustomType_unlocked(typeName, length);
|
||||||
#ifndef QT_NO_QOBJECT
|
#ifndef QT_NO_QOBJECT
|
||||||
if (!type) {
|
if (type == UnknownType) {
|
||||||
const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
|
const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
|
||||||
type = qMetaTypeStaticType(normalizedTypeName.constData(),
|
type = qMetaTypeStaticType(normalizedTypeName.constData(),
|
||||||
normalizedTypeName.size());
|
normalizedTypeName.size());
|
||||||
if (!type) {
|
if (type == UnknownType) {
|
||||||
type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
|
type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
|
||||||
normalizedTypeName.size());
|
normalizedTypeName.size());
|
||||||
}
|
}
|
||||||
@ -652,6 +653,7 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
case QMetaType::UnknownType:
|
||||||
case QMetaType::Void:
|
case QMetaType::Void:
|
||||||
case QMetaType::VoidStar:
|
case QMetaType::VoidStar:
|
||||||
case QMetaType::QObjectStar:
|
case QMetaType::QObjectStar:
|
||||||
@ -857,6 +859,7 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
case QMetaType::UnknownType:
|
||||||
case QMetaType::Void:
|
case QMetaType::Void:
|
||||||
case QMetaType::VoidStar:
|
case QMetaType::VoidStar:
|
||||||
case QMetaType::QObjectStar:
|
case QMetaType::QObjectStar:
|
||||||
@ -1154,6 +1157,7 @@ void *QMetaType::create(int type, const void *copy)
|
|||||||
case QMetaType::QModelIndex:
|
case QMetaType::QModelIndex:
|
||||||
return new NS(QModelIndex)(*static_cast<const NS(QModelIndex)*>(copy));
|
return new NS(QModelIndex)(*static_cast<const NS(QModelIndex)*>(copy));
|
||||||
#endif
|
#endif
|
||||||
|
case QMetaType::UnknownType:
|
||||||
case QMetaType::Void:
|
case QMetaType::Void:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
@ -1257,6 +1261,7 @@ void *QMetaType::create(int type, const void *copy)
|
|||||||
case QMetaType::QModelIndex:
|
case QMetaType::QModelIndex:
|
||||||
return new NS(QModelIndex);
|
return new NS(QModelIndex);
|
||||||
#endif
|
#endif
|
||||||
|
case QMetaType::UnknownType:
|
||||||
case QMetaType::Void:
|
case QMetaType::Void:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
@ -1318,6 +1323,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void delegate(const T *where) { DestroyerImpl<T>::Destroy(m_type, const_cast<T*>(where)); }
|
void delegate(const T *where) { DestroyerImpl<T>::Destroy(m_type, const_cast<T*>(where)); }
|
||||||
void delegate(const void *) {}
|
void delegate(const void *) {}
|
||||||
|
void delegate(const QMetaTypeSwitcher::UnknownType*) {}
|
||||||
void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestroyer(m_type, (void*)where); }
|
void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestroyer(m_type, (void*)where); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1381,6 +1387,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void *delegate(const T *copy) { return ConstructorImpl<T>::Construct(m_type, m_where, copy); }
|
void *delegate(const T *copy) { return ConstructorImpl<T>::Construct(m_type, m_where, copy); }
|
||||||
void *delegate(const void *) { return m_where; }
|
void *delegate(const void *) { return m_where; }
|
||||||
|
void *delegate(const QMetaTypeSwitcher::UnknownType*) { return m_where; }
|
||||||
void *delegate(const QMetaTypeSwitcher::NotBuiltinType *copy) { return customTypeConstructor(m_type, m_where, copy); }
|
void *delegate(const QMetaTypeSwitcher::NotBuiltinType *copy) { return customTypeConstructor(m_type, m_where, copy); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1470,6 +1477,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void delegate(const T *where) { DestructorImpl<T>::Destruct(m_type, const_cast<T*>(where)); }
|
void delegate(const T *where) { DestructorImpl<T>::Destruct(m_type, const_cast<T*>(where)); }
|
||||||
void delegate(const void *) {}
|
void delegate(const void *) {}
|
||||||
|
void delegate(const QMetaTypeSwitcher::UnknownType*) {}
|
||||||
void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestructor(m_type, (void*)where); }
|
void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestructor(m_type, (void*)where); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1539,6 +1547,7 @@ public:
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int delegate(const T*) { return SizeOfImpl<T>::Size(m_type); }
|
int delegate(const T*) { return SizeOfImpl<T>::Size(m_type); }
|
||||||
|
int delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
|
||||||
int delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeSizeOf(m_type); }
|
int delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeSizeOf(m_type); }
|
||||||
private:
|
private:
|
||||||
static int customTypeSizeOf(const int type)
|
static int customTypeSizeOf(const int type)
|
||||||
@ -1609,13 +1618,14 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
quint32 delegate(const T*) { return FlagsImpl<T>::Flags(m_type); }
|
quint32 delegate(const T*) { return FlagsImpl<T>::Flags(m_type); }
|
||||||
quint32 delegate(const void*) { return 0; }
|
quint32 delegate(const void*) { return 0; }
|
||||||
|
quint32 delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
|
||||||
quint32 delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeFlags(m_type); }
|
quint32 delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeFlags(m_type); }
|
||||||
private:
|
private:
|
||||||
const int m_type;
|
const int m_type;
|
||||||
static quint32 customTypeFlags(const int type)
|
static quint32 customTypeFlags(const int type)
|
||||||
{
|
{
|
||||||
const QVector<QCustomTypeInfo> * const ct = customTypes();
|
const QVector<QCustomTypeInfo> * const ct = customTypes();
|
||||||
if (Q_UNLIKELY(!ct))
|
if (Q_UNLIKELY(!ct || type < QMetaType::User))
|
||||||
return 0;
|
return 0;
|
||||||
QReadLocker locker(customTypesLock());
|
QReadLocker locker(customTypesLock());
|
||||||
if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
|
if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
|
||||||
@ -1796,6 +1806,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void delegate(const T*) { TypeInfoImpl<T>(m_type, info); }
|
void delegate(const T*) { TypeInfoImpl<T>(m_type, info); }
|
||||||
void delegate(const void*) {}
|
void delegate(const void*) {}
|
||||||
|
void delegate(const QMetaTypeSwitcher::UnknownType*) {}
|
||||||
void delegate(const QMetaTypeSwitcher::NotBuiltinType*) { customTypeInfo(m_type); }
|
void delegate(const QMetaTypeSwitcher::NotBuiltinType*) { customTypeInfo(m_type); }
|
||||||
private:
|
private:
|
||||||
void customTypeInfo(const uint type)
|
void customTypeInfo(const uint type)
|
||||||
@ -1816,7 +1827,7 @@ QMetaType QMetaType::typeInfo(const int type)
|
|||||||
{
|
{
|
||||||
TypeInfo typeInfo(type);
|
TypeInfo typeInfo(type);
|
||||||
QMetaTypeSwitcher::switcher<void>(typeInfo, type, 0);
|
QMetaTypeSwitcher::switcher<void>(typeInfo, type, 0);
|
||||||
return typeInfo.info.creator || !type ? QMetaType(QMetaType::NoExtensionFlags
|
return typeInfo.info.creator || type == Void ? QMetaType(QMetaType::NoExtensionFlags
|
||||||
, static_cast<const QMetaTypeInterface *>(0) // typeInfo::info is a temporary variable, we can't return address of it.
|
, static_cast<const QMetaTypeInterface *>(0) // typeInfo::info is a temporary variable, we can't return address of it.
|
||||||
, typeInfo.info.creator
|
, typeInfo.info.creator
|
||||||
, typeInfo.info.deleter
|
, typeInfo.info.deleter
|
||||||
@ -1827,26 +1838,23 @@ QMetaType QMetaType::typeInfo(const int type)
|
|||||||
, typeInfo.info.size
|
, typeInfo.info.size
|
||||||
, typeInfo.info.flags
|
, typeInfo.info.flags
|
||||||
, type)
|
, type)
|
||||||
: QMetaType(-1);
|
: QMetaType(UnknownType);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMetaType::QMetaType(const int typeId)
|
QMetaType::QMetaType(const int typeId)
|
||||||
: m_typeId(typeId)
|
: m_typeId(typeId)
|
||||||
{
|
{
|
||||||
if (Q_UNLIKELY(typeId == -1)) {
|
if (Q_UNLIKELY(typeId == UnknownType)) {
|
||||||
// Constructs invalid QMetaType instance.
|
// Constructs invalid QMetaType instance.
|
||||||
m_extensionFlags = 0xffffffff;
|
m_extensionFlags = 0xffffffff;
|
||||||
Q_ASSERT(!isValid());
|
Q_ASSERT(!isValid());
|
||||||
} else {
|
} else {
|
||||||
// TODO it can be better.
|
// TODO it can be better.
|
||||||
*this = QMetaType::typeInfo(typeId);
|
*this = QMetaType::typeInfo(typeId);
|
||||||
if (m_typeId > 0 && !m_creator) {
|
if (m_typeId == UnknownType)
|
||||||
m_extensionFlags = 0xffffffff;
|
m_extensionFlags = 0xffffffff;
|
||||||
m_typeId = -1;
|
else if (m_typeId == QMetaType::Void)
|
||||||
}
|
|
||||||
if (m_typeId == QMetaType::Void) {
|
|
||||||
m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
|
m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
|
// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
|
||||||
#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
|
#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
|
||||||
F(Void, 0, void) \
|
F(Void, 43, void) \
|
||||||
F(Bool, 1, bool) \
|
F(Bool, 1, bool) \
|
||||||
F(Int, 2, int) \
|
F(Int, 2, int) \
|
||||||
F(UInt, 3, uint) \
|
F(UInt, 3, uint) \
|
||||||
@ -192,8 +192,8 @@ public:
|
|||||||
// these are merged with QVariant
|
// these are merged with QVariant
|
||||||
QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
|
QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
|
||||||
|
|
||||||
FirstCoreType = Void,
|
FirstCoreType = Bool,
|
||||||
LastCoreType = QModelIndex,
|
LastCoreType = Void,
|
||||||
FirstGuiType = QFont,
|
FirstGuiType = QFont,
|
||||||
LastGuiType = QPolygonF,
|
LastGuiType = QPolygonF,
|
||||||
FirstWidgetsType = QIcon,
|
FirstWidgetsType = QIcon,
|
||||||
@ -202,6 +202,7 @@ public:
|
|||||||
|
|
||||||
QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
|
QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
|
||||||
|
|
||||||
|
UnknownType = 0,
|
||||||
User = 256
|
User = 256
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -677,7 +678,7 @@ inline QMetaType::~QMetaType()
|
|||||||
|
|
||||||
inline bool QMetaType::isValid() const
|
inline bool QMetaType::isValid() const
|
||||||
{
|
{
|
||||||
return m_typeId >= 0;
|
return m_typeId != UnknownType;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool QMetaType::isRegistered() const
|
inline bool QMetaType::isRegistered() const
|
||||||
|
@ -59,7 +59,8 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QMetaTypeSwitcher {
|
class QMetaTypeSwitcher {
|
||||||
public:
|
public:
|
||||||
class NotBuiltinType;
|
class NotBuiltinType; // type is not a built-in type, but it may be a custom type or an unknown type
|
||||||
|
class UnknownType; // type not known to QMetaType system
|
||||||
template<class ReturnType, class DelegateObject>
|
template<class ReturnType, class DelegateObject>
|
||||||
static ReturnType switcher(DelegateObject &logic, int type, const void *data);
|
static ReturnType switcher(DelegateObject &logic, int type, const void *data);
|
||||||
};
|
};
|
||||||
@ -74,7 +75,11 @@ ReturnType QMetaTypeSwitcher::switcher(DelegateObject &logic, int type, const vo
|
|||||||
switch (QMetaType::Type(type)) {
|
switch (QMetaType::Type(type)) {
|
||||||
QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_SWICHER_CASE)
|
QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_SWICHER_CASE)
|
||||||
|
|
||||||
|
case QMetaType::UnknownType:
|
||||||
|
return logic.delegate(static_cast<UnknownType const *>(data));
|
||||||
default:
|
default:
|
||||||
|
if (type < QMetaType::User)
|
||||||
|
return logic.delegate(static_cast<UnknownType const *>(data));
|
||||||
return logic.delegate(static_cast<NotBuiltinType const *>(data));
|
return logic.delegate(static_cast<NotBuiltinType const *>(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,30 @@ static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
|
|||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int *queuedConnectionTypes(const QArgumentType *argumentTypes, int argc)
|
||||||
|
{
|
||||||
|
QScopedArrayPointer<int> types(new int [argc + 1]);
|
||||||
|
for (int i = 0; i < argc; ++i) {
|
||||||
|
const QArgumentType &type = argumentTypes[i];
|
||||||
|
if (type.type())
|
||||||
|
types[i] = type.type();
|
||||||
|
else if (type.name().endsWith('*'))
|
||||||
|
types[i] = QMetaType::VoidStar;
|
||||||
|
else
|
||||||
|
types[i] = QMetaType::type(type.name());
|
||||||
|
|
||||||
|
if (!types[i]) {
|
||||||
|
qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
|
||||||
|
"(Make sure '%s' is registered using qRegisterMetaType().)",
|
||||||
|
type.name().constData(), type.name().constData());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
types[argc] = 0;
|
||||||
|
|
||||||
|
return types.take();
|
||||||
|
}
|
||||||
|
|
||||||
static QBasicMutex _q_ObjectMutexPool[131];
|
static QBasicMutex _q_ObjectMutexPool[131];
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
@ -2179,12 +2203,12 @@ static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaM
|
|||||||
if (signal.attributes() & QMetaMethod::Compatibility) {
|
if (signal.attributes() & QMetaMethod::Compatibility) {
|
||||||
if (!(method.attributes() & QMetaMethod::Compatibility))
|
if (!(method.attributes() & QMetaMethod::Compatibility))
|
||||||
qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
|
qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
|
||||||
sender->className(), signal.signature());
|
sender->className(), signal.methodSignature().constData());
|
||||||
} else if ((method.attributes() & QMetaMethod::Compatibility) &&
|
} else if ((method.attributes() & QMetaMethod::Compatibility) &&
|
||||||
method.methodType() == QMetaMethod::Signal) {
|
method.methodType() == QMetaMethod::Signal) {
|
||||||
qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
|
qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
|
||||||
sender->className(), signal.signature(),
|
sender->className(), signal.methodSignature().constData(),
|
||||||
receiver->className(), method.signature());
|
receiver->className(), method.methodSignature().constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2283,20 +2307,40 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
|
|||||||
const QMetaObject *smeta = sender->metaObject();
|
const QMetaObject *smeta = sender->metaObject();
|
||||||
const char *signal_arg = signal;
|
const char *signal_arg = signal;
|
||||||
++signal; //skip code
|
++signal; //skip code
|
||||||
int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
|
QByteArray signalName;
|
||||||
if (signal_index < 0) {
|
QArgumentTypeArray signalTypes;
|
||||||
// check for normalized signatures
|
int signal_index;
|
||||||
tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
|
if (QMetaObjectPrivate::get(smeta)->revision >= 7) {
|
||||||
signal = tmp_signal_name.constData() + 1;
|
signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
|
||||||
|
signal_index = QMetaObjectPrivate::indexOfSignalRelative(
|
||||||
|
&smeta, signalName, signalTypes.size(), signalTypes.constData());
|
||||||
|
if (signal_index < 0) {
|
||||||
|
// check for normalized signatures
|
||||||
|
tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
|
||||||
|
signal = tmp_signal_name.constData() + 1;
|
||||||
|
|
||||||
smeta = sender->metaObject();
|
signalTypes.clear();
|
||||||
|
signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
|
||||||
|
smeta = sender->metaObject();
|
||||||
|
signal_index = QMetaObjectPrivate::indexOfSignalRelative(
|
||||||
|
&smeta, signalName, signalTypes.size(), signalTypes.constData());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
|
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
|
||||||
}
|
if (signal_index < 0) {
|
||||||
if (signal_index < 0) {
|
// check for normalized signatures
|
||||||
// re-use tmp_signal_name and signal from above
|
tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
|
||||||
|
signal = tmp_signal_name.constData() + 1;
|
||||||
|
|
||||||
smeta = sender->metaObject();
|
smeta = sender->metaObject();
|
||||||
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
|
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
|
||||||
|
if (signal_index < 0) {
|
||||||
|
// re-use tmp_signal_name and signal from above
|
||||||
|
|
||||||
|
smeta = sender->metaObject();
|
||||||
|
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (signal_index < 0) {
|
if (signal_index < 0) {
|
||||||
err_method_notfound(sender, signal_arg, "connect");
|
err_method_notfound(sender, signal_arg, "connect");
|
||||||
@ -2317,36 +2361,71 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
|
|||||||
const char *method_arg = method;
|
const char *method_arg = method;
|
||||||
++method; // skip code
|
++method; // skip code
|
||||||
|
|
||||||
|
QByteArray methodName;
|
||||||
|
QArgumentTypeArray methodTypes;
|
||||||
const QMetaObject *rmeta = receiver->metaObject();
|
const QMetaObject *rmeta = receiver->metaObject();
|
||||||
int method_index_relative = -1;
|
int method_index_relative = -1;
|
||||||
switch (membcode) {
|
if (QMetaObjectPrivate::get(rmeta)->revision >= 7) {
|
||||||
case QSLOT_CODE:
|
switch (membcode) {
|
||||||
method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
|
case QSLOT_CODE:
|
||||||
break;
|
method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
|
||||||
case QSIGNAL_CODE:
|
&rmeta, methodName, methodTypes.size(), methodTypes.constData());
|
||||||
method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
|
break;
|
||||||
break;
|
case QSIGNAL_CODE:
|
||||||
}
|
method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
|
||||||
|
&rmeta, methodName, methodTypes.size(), methodTypes.constData());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (method_index_relative < 0) {
|
||||||
|
// check for normalized methods
|
||||||
|
tmp_method_name = QMetaObject::normalizedSignature(method);
|
||||||
|
method = tmp_method_name.constData();
|
||||||
|
|
||||||
if (method_index_relative < 0) {
|
methodTypes.clear();
|
||||||
// check for normalized methods
|
methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
|
||||||
tmp_method_name = QMetaObject::normalizedSignature(method);
|
// rmeta may have been modified above
|
||||||
method = tmp_method_name.constData();
|
rmeta = receiver->metaObject();
|
||||||
|
switch (membcode) {
|
||||||
// rmeta may have been modified above
|
case QSLOT_CODE:
|
||||||
rmeta = receiver->metaObject();
|
method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
|
||||||
|
&rmeta, methodName, methodTypes.size(), methodTypes.constData());
|
||||||
|
break;
|
||||||
|
case QSIGNAL_CODE:
|
||||||
|
method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
|
||||||
|
&rmeta, methodName, methodTypes.size(), methodTypes.constData());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
switch (membcode) {
|
switch (membcode) {
|
||||||
case QSLOT_CODE:
|
case QSLOT_CODE:
|
||||||
method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
|
method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
|
||||||
if (method_index_relative < 0)
|
|
||||||
method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, true);
|
|
||||||
break;
|
break;
|
||||||
case QSIGNAL_CODE:
|
case QSIGNAL_CODE:
|
||||||
method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
|
method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
|
||||||
if (method_index_relative < 0)
|
|
||||||
method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, true);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (method_index_relative < 0) {
|
||||||
|
// check for normalized methods
|
||||||
|
tmp_method_name = QMetaObject::normalizedSignature(method);
|
||||||
|
method = tmp_method_name.constData();
|
||||||
|
|
||||||
|
// rmeta may have been modified above
|
||||||
|
rmeta = receiver->metaObject();
|
||||||
|
switch (membcode) {
|
||||||
|
case QSLOT_CODE:
|
||||||
|
method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
|
||||||
|
if (method_index_relative < 0)
|
||||||
|
method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, true);
|
||||||
|
break;
|
||||||
|
case QSIGNAL_CODE:
|
||||||
|
method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
|
||||||
|
if (method_index_relative < 0)
|
||||||
|
method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method_index_relative < 0) {
|
if (method_index_relative < 0) {
|
||||||
@ -2355,7 +2434,18 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
|
|||||||
return QMetaObject::Connection(0);
|
return QMetaObject::Connection(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QMetaObject::checkConnectArgs(signal, method)) {
|
bool compatibleArgs = true;
|
||||||
|
if ((QMetaObjectPrivate::get(smeta)->revision < 7) && (QMetaObjectPrivate::get(rmeta)->revision < 7)) {
|
||||||
|
compatibleArgs = QMetaObject::checkConnectArgs(signal, method);
|
||||||
|
} else {
|
||||||
|
if (signalName.isEmpty())
|
||||||
|
signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
|
||||||
|
if (methodName.isEmpty())
|
||||||
|
methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
|
||||||
|
compatibleArgs = QMetaObjectPrivate::checkConnectArgs(signalTypes.size(), signalTypes.constData(),
|
||||||
|
methodTypes.size(), methodTypes.constData());
|
||||||
|
}
|
||||||
|
if (!compatibleArgs) {
|
||||||
qWarning("QObject::connect: Incompatible sender/receiver arguments"
|
qWarning("QObject::connect: Incompatible sender/receiver arguments"
|
||||||
"\n %s::%s --> %s::%s",
|
"\n %s::%s --> %s::%s",
|
||||||
sender->metaObject()->className(), signal,
|
sender->metaObject()->className(), signal,
|
||||||
@ -2365,8 +2455,11 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
|
|||||||
|
|
||||||
int *types = 0;
|
int *types = 0;
|
||||||
if ((type == Qt::QueuedConnection)
|
if ((type == Qt::QueuedConnection)
|
||||||
&& !(types = queuedConnectionTypes(smeta->method(signal_absolute_index).parameterTypes())))
|
&& ((QMetaObjectPrivate::get(smeta)->revision >= 7)
|
||||||
|
? !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))
|
||||||
|
: !(types = queuedConnectionTypes(smeta->method(signal_absolute_index).parameterTypes())))) {
|
||||||
return QMetaObject::Connection(0);
|
return QMetaObject::Connection(0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
if (warnCompat) {
|
if (warnCompat) {
|
||||||
@ -2424,17 +2517,17 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
|
|||||||
|| method.methodType() == QMetaMethod::Constructor) {
|
|| method.methodType() == QMetaMethod::Constructor) {
|
||||||
qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
|
qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
|
||||||
sender ? sender->metaObject()->className() : "(null)",
|
sender ? sender->metaObject()->className() : "(null)",
|
||||||
signal.signature(),
|
signal.methodSignature().constData(),
|
||||||
receiver ? receiver->metaObject()->className() : "(null)",
|
receiver ? receiver->metaObject()->className() : "(null)",
|
||||||
method.signature() );
|
method.methodSignature().constData() );
|
||||||
return QMetaObject::Connection(0);
|
return QMetaObject::Connection(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconstructing SIGNAL() macro result for signal.signature() string
|
// Reconstructing SIGNAL() macro result for signal.methodSignature() string
|
||||||
QByteArray signalSignature;
|
QByteArray signalSignature;
|
||||||
signalSignature.reserve(qstrlen(signal.signature())+1);
|
signalSignature.reserve(signal.methodSignature().size()+1);
|
||||||
signalSignature.append((char)(QSIGNAL_CODE + '0'));
|
signalSignature.append((char)(QSIGNAL_CODE + '0'));
|
||||||
signalSignature.append(signal.signature());
|
signalSignature.append(signal.methodSignature());
|
||||||
|
|
||||||
int signal_index;
|
int signal_index;
|
||||||
int method_index;
|
int method_index;
|
||||||
@ -2448,20 +2541,20 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
|
|||||||
const QMetaObject *rmeta = receiver->metaObject();
|
const QMetaObject *rmeta = receiver->metaObject();
|
||||||
if (signal_index == -1) {
|
if (signal_index == -1) {
|
||||||
qWarning("QObject::connect: Can't find signal %s on instance of class %s",
|
qWarning("QObject::connect: Can't find signal %s on instance of class %s",
|
||||||
signal.signature(), smeta->className());
|
signal.methodSignature().constData(), smeta->className());
|
||||||
return QMetaObject::Connection(0);
|
return QMetaObject::Connection(0);
|
||||||
}
|
}
|
||||||
if (method_index == -1) {
|
if (method_index == -1) {
|
||||||
qWarning("QObject::connect: Can't find method %s on instance of class %s",
|
qWarning("QObject::connect: Can't find method %s on instance of class %s",
|
||||||
method.signature(), rmeta->className());
|
method.methodSignature().constData(), rmeta->className());
|
||||||
return QMetaObject::Connection(0);
|
return QMetaObject::Connection(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QMetaObject::checkConnectArgs(signal.signature(), method.signature())) {
|
if (!QMetaObject::checkConnectArgs(signal.methodSignature().constData(), method.methodSignature().constData())) {
|
||||||
qWarning("QObject::connect: Incompatible sender/receiver arguments"
|
qWarning("QObject::connect: Incompatible sender/receiver arguments"
|
||||||
"\n %s::%s --> %s::%s",
|
"\n %s::%s --> %s::%s",
|
||||||
smeta->className(), signal.signature(),
|
smeta->className(), signal.methodSignature().constData(),
|
||||||
rmeta->className(), method.signature());
|
rmeta->className(), method.methodSignature().constData());
|
||||||
return QMetaObject::Connection(0);
|
return QMetaObject::Connection(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2609,12 +2702,25 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
|
|||||||
*/
|
*/
|
||||||
bool res = false;
|
bool res = false;
|
||||||
const QMetaObject *smeta = sender->metaObject();
|
const QMetaObject *smeta = sender->metaObject();
|
||||||
|
QByteArray signalName;
|
||||||
|
QArgumentTypeArray signalTypes;
|
||||||
|
if (signal && (QMetaObjectPrivate::get(smeta)->revision >= 7))
|
||||||
|
signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
|
||||||
|
QByteArray methodName;
|
||||||
|
QArgumentTypeArray methodTypes;
|
||||||
|
if (method && (QMetaObjectPrivate::get(receiver->metaObject())->revision >= 7))
|
||||||
|
methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
|
||||||
do {
|
do {
|
||||||
int signal_index = -1;
|
int signal_index = -1;
|
||||||
if (signal) {
|
if (signal) {
|
||||||
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
|
if (QMetaObjectPrivate::get(smeta)->revision >= 7) {
|
||||||
if (signal_index < 0)
|
signal_index = QMetaObjectPrivate::indexOfSignalRelative(
|
||||||
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
|
&smeta, signalName, signalTypes.size(), signalTypes.constData());
|
||||||
|
} else {
|
||||||
|
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
|
||||||
|
if (signal_index < 0)
|
||||||
|
signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
|
||||||
|
}
|
||||||
if (signal_index < 0)
|
if (signal_index < 0)
|
||||||
break;
|
break;
|
||||||
signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
|
signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
|
||||||
@ -2629,7 +2735,13 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
|
|||||||
} else {
|
} else {
|
||||||
const QMetaObject *rmeta = receiver->metaObject();
|
const QMetaObject *rmeta = receiver->metaObject();
|
||||||
do {
|
do {
|
||||||
int method_index = rmeta->indexOfMethod(method);
|
int method_index;
|
||||||
|
if (QMetaObjectPrivate::get(rmeta)->revision >= 7) {
|
||||||
|
method_index = QMetaObjectPrivate::indexOfMethod(
|
||||||
|
rmeta, methodName, methodTypes.size(), methodTypes.constData());
|
||||||
|
} else {
|
||||||
|
method_index = rmeta->indexOfMethod(method);
|
||||||
|
}
|
||||||
if (method_index >= 0)
|
if (method_index >= 0)
|
||||||
while (method_index < rmeta->methodOffset())
|
while (method_index < rmeta->methodOffset())
|
||||||
rmeta = rmeta->superClass();
|
rmeta = rmeta->superClass();
|
||||||
@ -2693,24 +2805,24 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
|
|||||||
if(signal.methodType() != QMetaMethod::Signal) {
|
if(signal.methodType() != QMetaMethod::Signal) {
|
||||||
qWarning("QObject::%s: Attempt to %s non-signal %s::%s",
|
qWarning("QObject::%s: Attempt to %s non-signal %s::%s",
|
||||||
"disconnect","unbind",
|
"disconnect","unbind",
|
||||||
sender->metaObject()->className(), signal.signature());
|
sender->metaObject()->className(), signal.methodSignature().constData());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (method.mobj) {
|
if (method.mobj) {
|
||||||
if(method.methodType() == QMetaMethod::Constructor) {
|
if(method.methodType() == QMetaMethod::Constructor) {
|
||||||
qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
|
qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
|
||||||
receiver->metaObject()->className(), method.signature());
|
receiver->metaObject()->className(), method.methodSignature().constData());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconstructing SIGNAL() macro result for signal.signature() string
|
// Reconstructing SIGNAL() macro result for signal.methodSignature() string
|
||||||
QByteArray signalSignature;
|
QByteArray signalSignature;
|
||||||
if (signal.mobj) {
|
if (signal.mobj) {
|
||||||
signalSignature.reserve(qstrlen(signal.signature())+1);
|
signalSignature.reserve(signal.methodSignature().size()+1);
|
||||||
signalSignature.append((char)(QSIGNAL_CODE + '0'));
|
signalSignature.append((char)(QSIGNAL_CODE + '0'));
|
||||||
signalSignature.append(signal.signature());
|
signalSignature.append(signal.methodSignature());
|
||||||
}
|
}
|
||||||
|
|
||||||
int signal_index;
|
int signal_index;
|
||||||
@ -2724,13 +2836,13 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
|
|||||||
// is -1 then this signal is not a member of sender.
|
// is -1 then this signal is not a member of sender.
|
||||||
if (signal.mobj && signal_index == -1) {
|
if (signal.mobj && signal_index == -1) {
|
||||||
qWarning("QObject::disconect: signal %s not found on class %s",
|
qWarning("QObject::disconect: signal %s not found on class %s",
|
||||||
signal.signature(), sender->metaObject()->className());
|
signal.methodSignature().constData(), sender->metaObject()->className());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// If this condition is true then method is not a member of receeiver.
|
// If this condition is true then method is not a member of receeiver.
|
||||||
if (receiver && method.mobj && method_index == -1) {
|
if (receiver && method.mobj && method_index == -1) {
|
||||||
qWarning("QObject::disconect: method %s not found on class %s",
|
qWarning("QObject::disconect: method %s not found on class %s",
|
||||||
method.signature(), receiver->metaObject()->className());
|
method.methodSignature().constData(), receiver->metaObject()->className());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3045,7 +3157,8 @@ void QMetaObject::connectSlotsByName(QObject *o)
|
|||||||
Q_ASSERT(mo);
|
Q_ASSERT(mo);
|
||||||
const QObjectList list = o->findChildren<QObject *>(QString());
|
const QObjectList list = o->findChildren<QObject *>(QString());
|
||||||
for (int i = 0; i < mo->methodCount(); ++i) {
|
for (int i = 0; i < mo->methodCount(); ++i) {
|
||||||
const char *slot = mo->method(i).signature();
|
QByteArray slotSignature = mo->method(i).methodSignature();
|
||||||
|
const char *slot = slotSignature.constData();
|
||||||
Q_ASSERT(slot);
|
Q_ASSERT(slot);
|
||||||
if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
|
if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
|
||||||
continue;
|
continue;
|
||||||
@ -3065,7 +3178,7 @@ void QMetaObject::connectSlotsByName(QObject *o)
|
|||||||
if (method.methodType() != QMetaMethod::Signal)
|
if (method.methodType() != QMetaMethod::Signal)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!qstrncmp(method.signature(), slot + len + 4, slotlen)) {
|
if (!qstrncmp(method.methodSignature().constData(), slot + len + 4, slotlen)) {
|
||||||
int signalOffset, methodOffset;
|
int signalOffset, methodOffset;
|
||||||
computeOffsets(method.enclosingMetaObject(), &signalOffset, &methodOffset);
|
computeOffsets(method.enclosingMetaObject(), &signalOffset, &methodOffset);
|
||||||
sigIndex = k + - methodOffset + signalOffset;
|
sigIndex = k + - methodOffset + signalOffset;
|
||||||
@ -3311,9 +3424,17 @@ int QObjectPrivate::signalIndex(const char *signalName) const
|
|||||||
{
|
{
|
||||||
Q_Q(const QObject);
|
Q_Q(const QObject);
|
||||||
const QMetaObject *base = q->metaObject();
|
const QMetaObject *base = q->metaObject();
|
||||||
int relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, false);
|
int relative_index;
|
||||||
if (relative_index < 0)
|
if (QMetaObjectPrivate::get(base)->revision >= 7) {
|
||||||
relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, true);
|
QArgumentTypeArray types;
|
||||||
|
QByteArray name = QMetaObjectPrivate::decodeMethodSignature(signalName, types);
|
||||||
|
relative_index = QMetaObjectPrivate::indexOfSignalRelative(
|
||||||
|
&base, name, types.size(), types.constData());
|
||||||
|
} else {
|
||||||
|
relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, false);
|
||||||
|
if (relative_index < 0)
|
||||||
|
relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, true);
|
||||||
|
}
|
||||||
if (relative_index < 0)
|
if (relative_index < 0)
|
||||||
return relative_index;
|
return relative_index;
|
||||||
relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
|
relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
|
||||||
@ -3536,7 +3657,7 @@ void QObject::dumpObjectInfo()
|
|||||||
offset = methodOffset - signalOffset;
|
offset = methodOffset - signalOffset;
|
||||||
}
|
}
|
||||||
const QMetaMethod signal = metaObject()->method(signal_index + offset);
|
const QMetaMethod signal = metaObject()->method(signal_index + offset);
|
||||||
qDebug(" signal: %s", signal.signature());
|
qDebug(" signal: %s", signal.methodSignature().constData());
|
||||||
|
|
||||||
// receivers
|
// receivers
|
||||||
const QObjectPrivate::Connection *c =
|
const QObjectPrivate::Connection *c =
|
||||||
@ -3552,7 +3673,7 @@ void QObject::dumpObjectInfo()
|
|||||||
qDebug(" --> %s::%s %s",
|
qDebug(" --> %s::%s %s",
|
||||||
receiverMetaObject->className(),
|
receiverMetaObject->className(),
|
||||||
c->receiver->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver->objectName()),
|
c->receiver->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver->objectName()),
|
||||||
method.signature());
|
method.methodSignature().constData());
|
||||||
c = c->nextConnectionList;
|
c = c->nextConnectionList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3569,7 +3690,7 @@ void QObject::dumpObjectInfo()
|
|||||||
qDebug(" <-- %s::%s %s",
|
qDebug(" <-- %s::%s %s",
|
||||||
s->sender->metaObject()->className(),
|
s->sender->metaObject()->className(),
|
||||||
s->sender->objectName().isEmpty() ? "unnamed" : qPrintable(s->sender->objectName()),
|
s->sender->objectName().isEmpty() ? "unnamed" : qPrintable(s->sender->objectName()),
|
||||||
slot.signature());
|
slot.methodSignature().constData());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug(" <None>");
|
qDebug(" <None>");
|
||||||
@ -4041,9 +4162,16 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
|
|||||||
locker.unlock();
|
locker.unlock();
|
||||||
|
|
||||||
// reconstruct the signature to call connectNotify
|
// reconstruct the signature to call connectNotify
|
||||||
const char *sig = senderMetaObject->d.stringdata + senderMetaObject->d.data[
|
QByteArray tmp_sig;
|
||||||
reinterpret_cast<const QMetaObjectPrivate*>(senderMetaObject->d.data)->methodData
|
const char *sig;
|
||||||
+ 5 * (signal_index - signalOffset)];
|
if (QMetaObjectPrivate::get(senderMetaObject)->revision >= 7) {
|
||||||
|
tmp_sig = senderMetaObject->method(signal_index - signalOffset + methodOffset).methodSignature();
|
||||||
|
sig = tmp_sig.constData();
|
||||||
|
} else {
|
||||||
|
sig = reinterpret_cast<const char *>(senderMetaObject->d.stringdata)
|
||||||
|
+ senderMetaObject->d.data[QMetaObjectPrivate::get(senderMetaObject)->methodData
|
||||||
|
+ 5 * (signal_index - signalOffset)];
|
||||||
|
}
|
||||||
QVarLengthArray<char> signalSignature(qstrlen(sig) + 2);
|
QVarLengthArray<char> signalSignature(qstrlen(sig) + 2);
|
||||||
signalSignature.data()[0] = char(QSIGNAL_CODE + '0');
|
signalSignature.data()[0] = char(QSIGNAL_CODE + '0');
|
||||||
strcpy(signalSignature.data() + 1 , sig);
|
strcpy(signalSignature.data() + 1 , sig);
|
||||||
|
@ -50,11 +50,12 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
|
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
|
struct QByteArrayData;
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
|
|
||||||
#ifndef Q_MOC_OUTPUT_REVISION
|
#ifndef Q_MOC_OUTPUT_REVISION
|
||||||
#define Q_MOC_OUTPUT_REVISION 64
|
#define Q_MOC_OUTPUT_REVISION 65
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The following macros are our "extensions" to C++
|
// The following macros are our "extensions" to C++
|
||||||
@ -326,6 +327,8 @@ struct Q_CORE_EXPORT QMetaObject
|
|||||||
QMetaProperty userProperty() const;
|
QMetaProperty userProperty() const;
|
||||||
|
|
||||||
static bool checkConnectArgs(const char *signal, const char *method);
|
static bool checkConnectArgs(const char *signal, const char *method);
|
||||||
|
static bool checkConnectArgs(const QMetaMethod &signal,
|
||||||
|
const QMetaMethod &method);
|
||||||
static QByteArray normalizedSignature(const char *method);
|
static QByteArray normalizedSignature(const char *method);
|
||||||
static QByteArray normalizedType(const char *type);
|
static QByteArray normalizedType(const char *type);
|
||||||
|
|
||||||
@ -439,7 +442,7 @@ struct Q_CORE_EXPORT QMetaObject
|
|||||||
|
|
||||||
struct { // private data
|
struct { // private data
|
||||||
const QMetaObject *superdata;
|
const QMetaObject *superdata;
|
||||||
const char *stringdata;
|
const QByteArrayData *stringdata;
|
||||||
const uint *data;
|
const uint *data;
|
||||||
const void *extradata;
|
const void *extradata;
|
||||||
} d;
|
} d;
|
||||||
@ -480,9 +483,6 @@ struct QMetaObjectExtraData
|
|||||||
StaticMetacallFunction static_metacall;
|
StaticMetacallFunction static_metacall;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char *QMetaObject::className() const
|
|
||||||
{ return d.stringdata; }
|
|
||||||
|
|
||||||
inline const QMetaObject *QMetaObject::superClass() const
|
inline const QMetaObject *QMetaObject::superClass() const
|
||||||
{ return d.superdata; }
|
{ return d.superdata; }
|
||||||
|
|
||||||
|
@ -1697,7 +1697,7 @@ void QVariant::load(QDataStream &s)
|
|||||||
QByteArray name;
|
QByteArray name;
|
||||||
s >> name;
|
s >> name;
|
||||||
typeId = QMetaType::type(name.constData());
|
typeId = QMetaType::type(name.constData());
|
||||||
if (!typeId) {
|
if (typeId == QMetaType::UnknownType) {
|
||||||
s.setStatus(QDataStream::ReadCorruptData);
|
s.setStatus(QDataStream::ReadCorruptData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ class Q_CORE_EXPORT QVariant
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
Invalid = QMetaType::Void,
|
Invalid = QMetaType::UnknownType,
|
||||||
Bool = QMetaType::Bool,
|
Bool = QMetaType::Bool,
|
||||||
Int = QMetaType::Int,
|
Int = QMetaType::Int,
|
||||||
UInt = QMetaType::UInt,
|
UInt = QMetaType::UInt,
|
||||||
|
@ -187,7 +187,11 @@ public:
|
|||||||
return FilteredComparator<T>::compare(m_a, m_b);
|
return FilteredComparator<T>::compare(m_a, m_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool delegate(const void*) { return true; }
|
bool delegate(const void*) { Q_ASSERT(false); return true; }
|
||||||
|
bool delegate(const QMetaTypeSwitcher::UnknownType*)
|
||||||
|
{
|
||||||
|
return true; // for historical reason invalid variant == invalid variant
|
||||||
|
}
|
||||||
bool delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return false; }
|
bool delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return false; }
|
||||||
protected:
|
protected:
|
||||||
const QVariant::Private *m_a;
|
const QVariant::Private *m_a;
|
||||||
@ -281,7 +285,8 @@ public:
|
|||||||
return CallIsNull<T>::isNull(m_d);
|
return CallIsNull<T>::isNull(m_d);
|
||||||
}
|
}
|
||||||
// we need that as sizof(void) is undefined and it is needed in HasIsNullMethod
|
// we need that as sizof(void) is undefined and it is needed in HasIsNullMethod
|
||||||
bool delegate(const void *) { return m_d->is_null; }
|
bool delegate(const void *) { Q_ASSERT(false); return m_d->is_null; }
|
||||||
|
bool delegate(const QMetaTypeSwitcher::UnknownType *) { return m_d->is_null; }
|
||||||
bool delegate(const QMetaTypeSwitcher::NotBuiltinType *) { return m_d->is_null; }
|
bool delegate(const QMetaTypeSwitcher::NotBuiltinType *) { return m_d->is_null; }
|
||||||
protected:
|
protected:
|
||||||
const QVariant::Private *m_d;
|
const QVariant::Private *m_d;
|
||||||
@ -354,8 +359,18 @@ public:
|
|||||||
|
|
||||||
void delegate(const void*)
|
void delegate(const void*)
|
||||||
{
|
{
|
||||||
// QMetaType::Void == QVariant::Invalid, creating an invalid value creates invalid QVariant
|
qWarning("Trying to create a QVariant instance of QMetaType::Void type, an invalid QVariant will be constructed instead");
|
||||||
// TODO it might go away, check is needed
|
m_x->type = QMetaType::UnknownType;
|
||||||
|
m_x->is_shared = false;
|
||||||
|
m_x->is_null = !m_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delegate(const QMetaTypeSwitcher::UnknownType*)
|
||||||
|
{
|
||||||
|
if (m_x->type != QMetaType::UnknownType) {
|
||||||
|
qWarning("Trying to construct an instance of an invalid type, type id: %i", m_x->type);
|
||||||
|
m_x->type = QMetaType::UnknownType;
|
||||||
|
}
|
||||||
m_x->is_shared = false;
|
m_x->is_shared = false;
|
||||||
m_x->is_null = !m_copy;
|
m_x->is_null = !m_copy;
|
||||||
}
|
}
|
||||||
@ -401,7 +416,8 @@ public:
|
|||||||
qWarning("Trying to destruct an instance of an invalid type, type id: %i", m_d->type);
|
qWarning("Trying to destruct an instance of an invalid type, type id: %i", m_d->type);
|
||||||
}
|
}
|
||||||
// Ignore nonconstructible type
|
// Ignore nonconstructible type
|
||||||
void delegate(const void*) {}
|
void delegate(const QMetaTypeSwitcher::UnknownType*) {}
|
||||||
|
void delegate(const void*) { Q_ASSERT(false); }
|
||||||
private:
|
private:
|
||||||
QVariant::Private *m_d;
|
QVariant::Private *m_d;
|
||||||
};
|
};
|
||||||
@ -446,10 +462,11 @@ public:
|
|||||||
{
|
{
|
||||||
qWarning("Trying to stream an instance of an invalid type, type id: %i", m_d->type);
|
qWarning("Trying to stream an instance of an invalid type, type id: %i", m_d->type);
|
||||||
}
|
}
|
||||||
void delegate(const void*)
|
void delegate(const QMetaTypeSwitcher::UnknownType*)
|
||||||
{
|
{
|
||||||
m_debugStream.nospace() << "QVariant::Invalid";
|
m_debugStream.nospace() << "QVariant::Invalid";
|
||||||
}
|
}
|
||||||
|
void delegate(const void*) { Q_ASSERT(false); }
|
||||||
private:
|
private:
|
||||||
QDebug m_debugStream;
|
QDebug m_debugStream;
|
||||||
QVariant::Private *m_d;
|
QVariant::Private *m_d;
|
||||||
|
@ -1657,7 +1657,7 @@ void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalInd
|
|||||||
|
|
||||||
#ifdef QSTATEMACHINE_DEBUG
|
#ifdef QSTATEMACHINE_DEBUG
|
||||||
qDebug() << q_func() << ": sending signal event ( sender =" << sender
|
qDebug() << q_func() << ": sending signal event ( sender =" << sender
|
||||||
<< ", signal =" << sender->metaObject()->method(signalIndex).signature() << ')';
|
<< ", signal =" << sender->metaObject()->method(signalIndex).methodSignature().constData() << ')';
|
||||||
#endif
|
#endif
|
||||||
postInternalEvent(new QStateMachine::SignalEvent(sender, signalIndex, vargs));
|
postInternalEvent(new QStateMachine::SignalEvent(sender, signalIndex, vargs));
|
||||||
processEvents(DirectProcessing);
|
processEvents(DirectProcessing);
|
||||||
@ -2211,10 +2211,29 @@ void QStateMachine::removeDefaultAnimation(QAbstractAnimation *animation)
|
|||||||
|
|
||||||
|
|
||||||
// Begin moc-generated code -- modify carefully (check "HAND EDIT" parts)!
|
// Begin moc-generated code -- modify carefully (check "HAND EDIT" parts)!
|
||||||
|
struct qt_meta_stringdata_QSignalEventGenerator_t {
|
||||||
|
QByteArrayData data[3];
|
||||||
|
char stringdata[32];
|
||||||
|
};
|
||||||
|
#define QT_MOC_LITERAL(idx, ofs, len) { \
|
||||||
|
Q_REFCOUNT_INITIALIZE_STATIC, len, 0, 0, \
|
||||||
|
offsetof(qt_meta_stringdata_QSignalEventGenerator_t, stringdata) + ofs \
|
||||||
|
- idx * sizeof(QByteArrayData) \
|
||||||
|
}
|
||||||
|
static const qt_meta_stringdata_QSignalEventGenerator_t qt_meta_stringdata_QSignalEventGenerator = {
|
||||||
|
{
|
||||||
|
QT_MOC_LITERAL(0, 0, 21),
|
||||||
|
QT_MOC_LITERAL(1, 22, 7),
|
||||||
|
QT_MOC_LITERAL(2, 30, 0)
|
||||||
|
},
|
||||||
|
"QSignalEventGenerator\0execute\0\0"
|
||||||
|
};
|
||||||
|
#undef QT_MOC_LITERAL
|
||||||
|
|
||||||
static const uint qt_meta_data_QSignalEventGenerator[] = {
|
static const uint qt_meta_data_QSignalEventGenerator[] = {
|
||||||
|
|
||||||
// content:
|
// content:
|
||||||
6, // revision
|
7, // revision
|
||||||
0, // classname
|
0, // classname
|
||||||
0, 0, // classinfo
|
0, 0, // classinfo
|
||||||
1, 14, // methods
|
1, 14, // methods
|
||||||
@ -2224,16 +2243,15 @@ static const uint qt_meta_data_QSignalEventGenerator[] = {
|
|||||||
0, // flags
|
0, // flags
|
||||||
0, // signalCount
|
0, // signalCount
|
||||||
|
|
||||||
// slots: signature, parameters, type, tag, flags
|
// slots: name, argc, parameters, tag, flags
|
||||||
23, 22, 22, 22, 0x0a,
|
1, 0, 19, 2, 0x0a,
|
||||||
|
|
||||||
|
// slots: parameters
|
||||||
|
QMetaType::Void,
|
||||||
|
|
||||||
0 // eod
|
0 // eod
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char qt_meta_stringdata_QSignalEventGenerator[] = {
|
|
||||||
"QSignalEventGenerator\0\0execute()\0"
|
|
||||||
};
|
|
||||||
|
|
||||||
void QSignalEventGenerator::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
void QSignalEventGenerator::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||||
{
|
{
|
||||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||||
@ -2252,7 +2270,7 @@ const QMetaObjectExtraData QSignalEventGenerator::staticMetaObjectExtraData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const QMetaObject QSignalEventGenerator::staticMetaObject = {
|
const QMetaObject QSignalEventGenerator::staticMetaObject = {
|
||||||
{ &QObject::staticMetaObject, qt_meta_stringdata_QSignalEventGenerator,
|
{ &QObject::staticMetaObject, qt_meta_stringdata_QSignalEventGenerator.data,
|
||||||
qt_meta_data_QSignalEventGenerator, &staticMetaObjectExtraData }
|
qt_meta_data_QSignalEventGenerator, &staticMetaObjectExtraData }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2264,7 +2282,7 @@ const QMetaObject *QSignalEventGenerator::metaObject() const
|
|||||||
void *QSignalEventGenerator::qt_metacast(const char *_clname)
|
void *QSignalEventGenerator::qt_metacast(const char *_clname)
|
||||||
{
|
{
|
||||||
if (!_clname) return 0;
|
if (!_clname) return 0;
|
||||||
if (!strcmp(_clname, qt_meta_stringdata_QSignalEventGenerator))
|
if (!strcmp(_clname, qt_meta_stringdata_QSignalEventGenerator.stringdata))
|
||||||
return static_cast<void*>(const_cast< QSignalEventGenerator*>(this));
|
return static_cast<void*>(const_cast< QSignalEventGenerator*>(this));
|
||||||
return QObject::qt_metacast(_clname);
|
return QObject::qt_metacast(_clname);
|
||||||
}
|
}
|
||||||
|
111
src/corelib/tools/qarraydata.cpp
Normal file
111
src/corelib/tools/qarraydata.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore 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 <QtCore/qarraydata.h>
|
||||||
|
#include <QtCore/private/qtools_p.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
const QArrayData QArrayData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
static const QArrayData qt_array_empty = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 };
|
||||||
|
static const QArrayData qt_array_unsharable_empty = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
|
||||||
|
size_t capacity, AllocationOptions options)
|
||||||
|
{
|
||||||
|
// Alignment is a power of two
|
||||||
|
Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData)
|
||||||
|
&& !(alignment & (alignment - 1)));
|
||||||
|
|
||||||
|
// Don't allocate empty headers
|
||||||
|
if (!(options & RawData) && !capacity)
|
||||||
|
return !(options & Unsharable)
|
||||||
|
? const_cast<QArrayData *>(&qt_array_empty)
|
||||||
|
: const_cast<QArrayData *>(&qt_array_unsharable_empty);
|
||||||
|
|
||||||
|
size_t headerSize = sizeof(QArrayData);
|
||||||
|
|
||||||
|
// Allocate extra (alignment - Q_ALIGNOF(QArrayData)) padding bytes so we
|
||||||
|
// can properly align the data array. This assumes malloc is able to
|
||||||
|
// provide appropriate alignment for the header -- as it should!
|
||||||
|
// Padding is skipped when allocating a header for RawData.
|
||||||
|
if (!(options & RawData))
|
||||||
|
headerSize += (alignment - Q_ALIGNOF(QArrayData));
|
||||||
|
|
||||||
|
// Allocate additional space if array is growing
|
||||||
|
if (options & Grow)
|
||||||
|
capacity = qAllocMore(objectSize * capacity, headerSize) / objectSize;
|
||||||
|
|
||||||
|
size_t allocSize = headerSize + objectSize * capacity;
|
||||||
|
|
||||||
|
QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
|
||||||
|
if (header) {
|
||||||
|
quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1)
|
||||||
|
& ~(alignment - 1);
|
||||||
|
|
||||||
|
header->ref.atomic.store(bool(!(options & Unsharable)));
|
||||||
|
header->size = 0;
|
||||||
|
header->alloc = capacity;
|
||||||
|
header->capacityReserved = bool(options & CapacityReserved);
|
||||||
|
header->offset = data - quintptr(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QArrayData::deallocate(QArrayData *data, size_t objectSize,
|
||||||
|
size_t alignment)
|
||||||
|
{
|
||||||
|
// Alignment is a power of two
|
||||||
|
Q_ASSERT(alignment >= Q_ALIGNOF(QArrayData)
|
||||||
|
&& !(alignment & (alignment - 1)));
|
||||||
|
Q_UNUSED(objectSize) Q_UNUSED(alignment)
|
||||||
|
|
||||||
|
if (data == &qt_array_unsharable_empty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
::free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
275
src/corelib/tools/qarraydata.h
Normal file
275
src/corelib/tools/qarraydata.h
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore 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 QARRAYDATA_H
|
||||||
|
#define QARRAYDATA_H
|
||||||
|
|
||||||
|
#include <QtCore/qrefcount.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
QT_BEGIN_HEADER
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
struct Q_CORE_EXPORT QArrayData
|
||||||
|
{
|
||||||
|
QtPrivate::RefCount ref;
|
||||||
|
int size;
|
||||||
|
uint alloc : 31;
|
||||||
|
uint capacityReserved : 1;
|
||||||
|
|
||||||
|
qptrdiff offset; // in bytes from beginning of header
|
||||||
|
|
||||||
|
void *data()
|
||||||
|
{
|
||||||
|
Q_ASSERT(size == 0
|
||||||
|
|| offset < 0 || size_t(offset) >= sizeof(QArrayData));
|
||||||
|
return reinterpret_cast<char *>(this) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void *data() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(size == 0
|
||||||
|
|| offset < 0 || size_t(offset) >= sizeof(QArrayData));
|
||||||
|
return reinterpret_cast<const char *>(this) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This refers to array data mutability, not "header data" represented by
|
||||||
|
// data members in QArrayData. Shared data (array and header) must still
|
||||||
|
// follow COW principles.
|
||||||
|
bool isMutable() const
|
||||||
|
{
|
||||||
|
return alloc != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AllocationOption {
|
||||||
|
CapacityReserved = 0x1,
|
||||||
|
Unsharable = 0x2,
|
||||||
|
RawData = 0x4,
|
||||||
|
Grow = 0x8,
|
||||||
|
|
||||||
|
Default = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_FLAGS(AllocationOptions, AllocationOption)
|
||||||
|
|
||||||
|
AllocationOptions detachFlags() const
|
||||||
|
{
|
||||||
|
AllocationOptions result;
|
||||||
|
if (!ref.isSharable())
|
||||||
|
result |= Unsharable;
|
||||||
|
if (capacityReserved)
|
||||||
|
result |= CapacityReserved;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
AllocationOptions cloneFlags() const
|
||||||
|
{
|
||||||
|
AllocationOptions result;
|
||||||
|
if (capacityReserved)
|
||||||
|
result |= CapacityReserved;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QArrayData *allocate(size_t objectSize, size_t alignment,
|
||||||
|
size_t capacity, AllocationOptions options = Default)
|
||||||
|
Q_REQUIRED_RESULT;
|
||||||
|
static void deallocate(QArrayData *data, size_t objectSize,
|
||||||
|
size_t alignment);
|
||||||
|
|
||||||
|
static const QArrayData shared_null;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QArrayData::AllocationOptions)
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct QTypedArrayData
|
||||||
|
: QArrayData
|
||||||
|
{
|
||||||
|
typedef T *iterator;
|
||||||
|
typedef const T *const_iterator;
|
||||||
|
|
||||||
|
T *data() { return static_cast<T *>(QArrayData::data()); }
|
||||||
|
const T *data() const { return static_cast<const T *>(QArrayData::data()); }
|
||||||
|
|
||||||
|
T *begin() { return data(); }
|
||||||
|
T *end() { return data() + size; }
|
||||||
|
const T *begin() const { return data(); }
|
||||||
|
const T *end() const { return data() + size; }
|
||||||
|
|
||||||
|
class AlignmentDummy { QArrayData header; T data; };
|
||||||
|
|
||||||
|
static QTypedArrayData *allocate(size_t capacity,
|
||||||
|
AllocationOptions options = Default) Q_REQUIRED_RESULT
|
||||||
|
{
|
||||||
|
return static_cast<QTypedArrayData *>(QArrayData::allocate(sizeof(T),
|
||||||
|
Q_ALIGNOF(AlignmentDummy), capacity, options));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deallocate(QArrayData *data)
|
||||||
|
{
|
||||||
|
QArrayData::deallocate(data, sizeof(T), Q_ALIGNOF(AlignmentDummy));
|
||||||
|
}
|
||||||
|
|
||||||
|
static QTypedArrayData *fromRawData(const T *data, size_t n,
|
||||||
|
AllocationOptions options = Default)
|
||||||
|
{
|
||||||
|
QTypedArrayData *result = allocate(0, options | RawData);
|
||||||
|
if (result) {
|
||||||
|
Q_ASSERT(!result->ref.isShared()); // No shared empty, please!
|
||||||
|
|
||||||
|
result->offset = reinterpret_cast<const char *>(data)
|
||||||
|
- reinterpret_cast<const char *>(result);
|
||||||
|
result->size = n;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QTypedArrayData *sharedNull()
|
||||||
|
{
|
||||||
|
return static_cast<QTypedArrayData *>(
|
||||||
|
const_cast<QArrayData *>(&QArrayData::shared_null));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, size_t N>
|
||||||
|
struct QStaticArrayData
|
||||||
|
{
|
||||||
|
QArrayData header;
|
||||||
|
T data[N];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Support for returning QArrayDataPointer<T> from functions
|
||||||
|
template <class T>
|
||||||
|
struct QArrayDataPointerRef
|
||||||
|
{
|
||||||
|
QTypedArrayData<T> *ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(type, size) { \
|
||||||
|
Q_REFCOUNT_INITIALIZE_STATIC, size, 0, 0, \
|
||||||
|
(sizeof(QArrayData) + (Q_ALIGNOF(type) - 1)) \
|
||||||
|
& ~(Q_ALIGNOF(type) - 1) } \
|
||||||
|
/**/
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Q_ARRAY_LITERAL
|
||||||
|
|
||||||
|
// The idea here is to place a (read-only) copy of header and array data in an
|
||||||
|
// mmappable portion of the executable (typically, .rodata section). This is
|
||||||
|
// accomplished by hiding a static const instance of QStaticArrayData, which is
|
||||||
|
// POD.
|
||||||
|
|
||||||
|
#if defined(Q_COMPILER_VARIADIC_MACROS)
|
||||||
|
#if defined(Q_COMPILER_LAMBDA)
|
||||||
|
// Hide array inside a lambda
|
||||||
|
#define Q_ARRAY_LITERAL(Type, ...) \
|
||||||
|
([]() -> QArrayDataPointerRef<Type> { \
|
||||||
|
/* MSVC 2010 Doesn't support static variables in a lambda, but */ \
|
||||||
|
/* happily accepts them in a static function of a lambda-local */ \
|
||||||
|
/* struct :-) */ \
|
||||||
|
struct StaticWrapper { \
|
||||||
|
static QArrayDataPointerRef<Type> get() \
|
||||||
|
{ \
|
||||||
|
Q_ARRAY_LITERAL_IMPL(Type, __VA_ARGS__) \
|
||||||
|
return ref; \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
return StaticWrapper::get(); \
|
||||||
|
}()) \
|
||||||
|
/**/
|
||||||
|
#elif defined(Q_CC_GNU)
|
||||||
|
// Hide array within GCC's __extension__ {( )} block
|
||||||
|
#define Q_ARRAY_LITERAL(Type, ...) \
|
||||||
|
__extension__ ({ \
|
||||||
|
Q_ARRAY_LITERAL_IMPL(Type, __VA_ARGS__) \
|
||||||
|
ref; \
|
||||||
|
}) \
|
||||||
|
/**/
|
||||||
|
#endif
|
||||||
|
#endif // defined(Q_COMPILER_VARIADIC_MACROS)
|
||||||
|
|
||||||
|
#if defined(Q_ARRAY_LITERAL)
|
||||||
|
#define Q_ARRAY_LITERAL_IMPL(Type, ...) \
|
||||||
|
union { Type type_must_be_POD; } dummy; Q_UNUSED(dummy) \
|
||||||
|
\
|
||||||
|
/* Portable compile-time array size computation */ \
|
||||||
|
Type data[] = { __VA_ARGS__ }; Q_UNUSED(data) \
|
||||||
|
enum { Size = sizeof(data) / sizeof(data[0]) }; \
|
||||||
|
\
|
||||||
|
static const QStaticArrayData<Type, Size> literal = { \
|
||||||
|
Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER(Type, Size), { __VA_ARGS__ } }; \
|
||||||
|
\
|
||||||
|
QArrayDataPointerRef<Type> ref = \
|
||||||
|
{ static_cast<QTypedArrayData<Type> *>( \
|
||||||
|
const_cast<QArrayData *>(&literal.header)) }; \
|
||||||
|
/**/
|
||||||
|
#else
|
||||||
|
// As a fallback, memory is allocated and data copied to the heap.
|
||||||
|
|
||||||
|
// The fallback macro does NOT use variadic macros and does NOT support
|
||||||
|
// variable number of arguments. It is suitable for char arrays.
|
||||||
|
|
||||||
|
namespace QtPrivate {
|
||||||
|
template <class T, size_t N>
|
||||||
|
inline QArrayDataPointerRef<T> qMakeArrayLiteral(const T (&array)[N])
|
||||||
|
{
|
||||||
|
union { T type_must_be_POD; } dummy; Q_UNUSED(dummy)
|
||||||
|
|
||||||
|
QArrayDataPointerRef<T> result = { QTypedArrayData<T>::allocate(N) };
|
||||||
|
Q_CHECK_PTR(result.ptr);
|
||||||
|
|
||||||
|
::memcpy(result.ptr->data(), array, N * sizeof(T));
|
||||||
|
result.ptr->size = N;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Q_ARRAY_LITERAL(Type, Array) \
|
||||||
|
QT_PREPEND_NAMESPACE(QtPrivate::qMakeArrayLiteral)<Type>( Array )
|
||||||
|
#endif // !defined(Q_ARRAY_LITERAL)
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_HEADER
|
||||||
|
|
||||||
|
#endif // include guard
|
322
src/corelib/tools/qarraydataops.h
Normal file
322
src/corelib/tools/qarraydataops.h
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore 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 QARRAYDATAOPS_H
|
||||||
|
#define QARRAYDATAOPS_H
|
||||||
|
|
||||||
|
#include <QtCore/qarraydata.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
QT_BEGIN_HEADER
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace QtPrivate {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct QPodArrayOps
|
||||||
|
: QTypedArrayData<T>
|
||||||
|
{
|
||||||
|
void copyAppend(const T *b, const T *e)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(b < e);
|
||||||
|
Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
|
||||||
|
|
||||||
|
::memcpy(this->end(), b, (e - b) * sizeof(T));
|
||||||
|
this->size += e - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyAppend(size_t n, const T &t)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(n <= this->alloc - uint(this->size));
|
||||||
|
|
||||||
|
T *iter = this->end();
|
||||||
|
const T *const end = iter + n;
|
||||||
|
for (; iter != end; ++iter)
|
||||||
|
::memcpy(iter, &t, sizeof(T));
|
||||||
|
this->size += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyAll() // Call from destructors, ONLY!
|
||||||
|
{
|
||||||
|
Q_ASSERT(this->ref.atomic.load() == 0);
|
||||||
|
|
||||||
|
// As this is to be called only from destructor, it doesn't need to be
|
||||||
|
// exception safe; size not updated.
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(T *where, const T *b, const T *e)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(where >= this->begin() && where < this->end()); // Use copyAppend at end
|
||||||
|
Q_ASSERT(b < e);
|
||||||
|
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
||||||
|
Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
|
||||||
|
|
||||||
|
::memmove(where + (e - b), where, (this->end() - where) * sizeof(T));
|
||||||
|
::memcpy(where, b, (e - b) * sizeof(T));
|
||||||
|
this->size += (e - b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct QGenericArrayOps
|
||||||
|
: QTypedArrayData<T>
|
||||||
|
{
|
||||||
|
void copyAppend(const T *b, const T *e)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(b < e);
|
||||||
|
Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
|
||||||
|
|
||||||
|
T *iter = this->end();
|
||||||
|
for (; b != e; ++iter, ++b) {
|
||||||
|
new (iter) T(*b);
|
||||||
|
++this->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyAppend(size_t n, const T &t)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(n <= this->alloc - uint(this->size));
|
||||||
|
|
||||||
|
T *iter = this->end();
|
||||||
|
const T *const end = iter + n;
|
||||||
|
for (; iter != end; ++iter) {
|
||||||
|
new (iter) T(t);
|
||||||
|
++this->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyAll() // Call from destructors, ONLY
|
||||||
|
{
|
||||||
|
// As this is to be called only from destructor, it doesn't need to be
|
||||||
|
// exception safe; size not updated.
|
||||||
|
|
||||||
|
Q_ASSERT(this->ref.atomic.load() == 0);
|
||||||
|
|
||||||
|
const T *const b = this->begin();
|
||||||
|
const T *i = this->end();
|
||||||
|
|
||||||
|
while (i != b)
|
||||||
|
(--i)->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(T *where, const T *b, const T *e)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(where >= this->begin() && where < this->end()); // Use copyAppend at end
|
||||||
|
Q_ASSERT(b < e);
|
||||||
|
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
||||||
|
Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
|
||||||
|
|
||||||
|
// Array may be truncated at where in case of exceptions
|
||||||
|
|
||||||
|
T *const end = this->end();
|
||||||
|
const T *readIter = end;
|
||||||
|
T *writeIter = end + (e - b);
|
||||||
|
|
||||||
|
const T *const step1End = where + qMax(e - b, end - where);
|
||||||
|
|
||||||
|
struct Destructor
|
||||||
|
{
|
||||||
|
Destructor(T *&it)
|
||||||
|
: iter(&it)
|
||||||
|
, end(it)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void commit()
|
||||||
|
{
|
||||||
|
iter = &end;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Destructor()
|
||||||
|
{
|
||||||
|
for (; *iter != end; --*iter)
|
||||||
|
(*iter)->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
T **iter;
|
||||||
|
T *end;
|
||||||
|
} destroyer(writeIter);
|
||||||
|
|
||||||
|
// Construct new elements in array
|
||||||
|
do {
|
||||||
|
--readIter, --writeIter;
|
||||||
|
new (writeIter) T(*readIter);
|
||||||
|
} while (writeIter != step1End);
|
||||||
|
|
||||||
|
while (writeIter != end) {
|
||||||
|
--e, --writeIter;
|
||||||
|
new (writeIter) T(*e);
|
||||||
|
}
|
||||||
|
|
||||||
|
destroyer.commit();
|
||||||
|
this->size += destroyer.end - end;
|
||||||
|
|
||||||
|
// Copy assign over existing elements
|
||||||
|
while (readIter != where) {
|
||||||
|
--readIter, --writeIter;
|
||||||
|
*writeIter = *readIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (writeIter != where) {
|
||||||
|
--e, --writeIter;
|
||||||
|
*writeIter = *e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct QMovableArrayOps
|
||||||
|
: QGenericArrayOps<T>
|
||||||
|
{
|
||||||
|
// using QGenericArrayOps<T>::copyAppend;
|
||||||
|
// using QGenericArrayOps<T>::destroyAll;
|
||||||
|
|
||||||
|
void insert(T *where, const T *b, const T *e)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!this->ref.isShared());
|
||||||
|
Q_ASSERT(where >= this->begin() && where < this->end()); // Use copyAppend at end
|
||||||
|
Q_ASSERT(b < e);
|
||||||
|
Q_ASSERT(e <= where || b > this->end()); // No overlap
|
||||||
|
Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
|
||||||
|
|
||||||
|
// Provides strong exception safety guarantee,
|
||||||
|
// provided T::~T() nothrow
|
||||||
|
|
||||||
|
struct ReversibleDisplace
|
||||||
|
{
|
||||||
|
ReversibleDisplace(T *start, T *finish, size_t diff)
|
||||||
|
: begin(start)
|
||||||
|
, end(finish)
|
||||||
|
, displace(diff)
|
||||||
|
{
|
||||||
|
::memmove(begin + displace, begin, (end - begin) * sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
void commit() { displace = 0; }
|
||||||
|
|
||||||
|
~ReversibleDisplace()
|
||||||
|
{
|
||||||
|
if (displace)
|
||||||
|
::memmove(begin, begin + displace, (end - begin) * sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
T *const begin;
|
||||||
|
T *const end;
|
||||||
|
size_t displace;
|
||||||
|
|
||||||
|
} displace(where, this->end(), size_t(e - b));
|
||||||
|
|
||||||
|
struct CopyConstructor
|
||||||
|
{
|
||||||
|
CopyConstructor(T *w) : where(w) {}
|
||||||
|
|
||||||
|
void copy(const T *src, const T *const srcEnd)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
for (; src != srcEnd; ++src) {
|
||||||
|
new (where + n) T(*src);
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CopyConstructor()
|
||||||
|
{
|
||||||
|
while (n)
|
||||||
|
where[--n].~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
T *const where;
|
||||||
|
size_t n;
|
||||||
|
} copier(where);
|
||||||
|
|
||||||
|
copier.copy(b, e);
|
||||||
|
displace.commit();
|
||||||
|
this->size += (e - b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class = void>
|
||||||
|
struct QArrayOpsSelector
|
||||||
|
{
|
||||||
|
typedef QGenericArrayOps<T> Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct QArrayOpsSelector<T,
|
||||||
|
typename QEnableIf<
|
||||||
|
!QTypeInfo<T>::isComplex && !QTypeInfo<T>::isStatic
|
||||||
|
>::Type>
|
||||||
|
{
|
||||||
|
typedef QPodArrayOps<T> Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct QArrayOpsSelector<T,
|
||||||
|
typename QEnableIf<
|
||||||
|
QTypeInfo<T>::isComplex && !QTypeInfo<T>::isStatic
|
||||||
|
>::Type>
|
||||||
|
{
|
||||||
|
typedef QMovableArrayOps<T> Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QtPrivate
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct QArrayDataOps
|
||||||
|
: QtPrivate::QArrayOpsSelector<T>::Type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_HEADER
|
||||||
|
|
||||||
|
#endif // include guard
|
220
src/corelib/tools/qarraydatapointer.h
Normal file
220
src/corelib/tools/qarraydatapointer.h
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore 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 QARRAYDATAPOINTER_H
|
||||||
|
#define QARRAYDATAPOINTER_H
|
||||||
|
|
||||||
|
#include <QtCore/qarraydataops.h>
|
||||||
|
|
||||||
|
QT_BEGIN_HEADER
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct QArrayDataPointer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef QTypedArrayData<T> Data;
|
||||||
|
typedef QArrayDataOps<T> DataOps;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QArrayDataPointer()
|
||||||
|
: d(Data::sharedNull())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QArrayDataPointer(const QArrayDataPointer &other)
|
||||||
|
: d(other.d->ref.ref()
|
||||||
|
? other.d
|
||||||
|
: other.clone(other.d->cloneFlags()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit QArrayDataPointer(QTypedArrayData<T> *ptr)
|
||||||
|
: d(ptr)
|
||||||
|
{
|
||||||
|
Q_CHECK_PTR(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
QArrayDataPointer(QArrayDataPointerRef<T> ref)
|
||||||
|
: d(ref.ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QArrayDataPointer &operator=(const QArrayDataPointer &other)
|
||||||
|
{
|
||||||
|
QArrayDataPointer tmp(other);
|
||||||
|
this->swap(tmp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
|
QArrayDataPointer(QArrayDataPointer &&other)
|
||||||
|
: d(other.d)
|
||||||
|
{
|
||||||
|
other.d = Data::sharedNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
QArrayDataPointer &operator=(QArrayDataPointer &&other)
|
||||||
|
{
|
||||||
|
this->swap(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DataOps &operator*() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(d);
|
||||||
|
return *static_cast<DataOps *>(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataOps *operator->() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(d);
|
||||||
|
return static_cast<DataOps *>(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
~QArrayDataPointer()
|
||||||
|
{
|
||||||
|
if (!d->ref.deref()) {
|
||||||
|
(*this)->destroyAll();
|
||||||
|
Data::deallocate(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNull() const
|
||||||
|
{
|
||||||
|
return d == Data::sharedNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
Data *data() const
|
||||||
|
{
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSharable(bool sharable)
|
||||||
|
{
|
||||||
|
// Can't call setSharable on static read-only data, like shared_null
|
||||||
|
// and the internal shared-empties.
|
||||||
|
if (d->alloc == 0 && d->size == 0) {
|
||||||
|
d = Data::allocate(0, sharable
|
||||||
|
? QArrayData::Default
|
||||||
|
: QArrayData::Unsharable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
detach();
|
||||||
|
d->ref.setSharable(sharable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(QArrayDataPointer &other)
|
||||||
|
{
|
||||||
|
qSwap(d, other.d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
QArrayDataPointer tmp(d);
|
||||||
|
d = Data::sharedNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool detach()
|
||||||
|
{
|
||||||
|
if (!d->isMutable() || d->ref.isShared()) {
|
||||||
|
Data *copy = clone(d->detachFlags());
|
||||||
|
QArrayDataPointer old(d);
|
||||||
|
d = copy;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Data *clone(QArrayData::AllocationOptions options) const Q_REQUIRED_RESULT
|
||||||
|
{
|
||||||
|
QArrayDataPointer copy(Data::allocate(d->alloc ? d->alloc : d->size,
|
||||||
|
options));
|
||||||
|
if (d->size)
|
||||||
|
copy->copyAppend(d->begin(), d->end());
|
||||||
|
|
||||||
|
Data *result = copy.d;
|
||||||
|
copy.d = Data::sharedNull();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline bool operator==(const QArrayDataPointer<T> &lhs, const QArrayDataPointer<T> &rhs)
|
||||||
|
{
|
||||||
|
return lhs.data() == rhs.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline bool operator!=(const QArrayDataPointer<T> &lhs, const QArrayDataPointer<T> &rhs)
|
||||||
|
{
|
||||||
|
return lhs.data() != rhs.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline void qSwap(QArrayDataPointer<T> &p1, QArrayDataPointer<T> &p2)
|
||||||
|
{
|
||||||
|
p1.swap(p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
inline void swap(
|
||||||
|
QT_PREPEND_NAMESPACE(QArrayDataPointer)<T> &p1,
|
||||||
|
QT_PREPEND_NAMESPACE(QArrayDataPointer)<T> &p2)
|
||||||
|
{
|
||||||
|
p1.swap(p2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_HEADER
|
||||||
|
|
||||||
|
#endif // include guard
|
@ -57,7 +57,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define IS_RAW_DATA(d) ((d)->offset != 0)
|
#define IS_RAW_DATA(d) ((d)->offset != sizeof(QByteArrayData))
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -69,24 +69,25 @@ int qFindByteArray(
|
|||||||
|
|
||||||
int qAllocMore(int alloc, int extra)
|
int qAllocMore(int alloc, int extra)
|
||||||
{
|
{
|
||||||
if (alloc == 0 && extra == 0)
|
Q_ASSERT(alloc >= 0 && extra >= 0);
|
||||||
return 0;
|
Q_ASSERT(alloc < (1 << 30) - extra);
|
||||||
const int page = 1 << 12;
|
|
||||||
int nalloc;
|
unsigned nalloc = alloc + extra;
|
||||||
alloc += extra;
|
|
||||||
if (alloc < 1<<6) {
|
// Round up to next power of 2
|
||||||
nalloc = (1<<3) + ((alloc >>3) << 3);
|
|
||||||
} else {
|
// Assuming container is growing, always overshoot
|
||||||
// don't do anything if the loop will overflow signed int.
|
//--nalloc;
|
||||||
if (alloc >= INT_MAX/2)
|
|
||||||
return INT_MAX;
|
nalloc |= nalloc >> 1;
|
||||||
nalloc = (alloc < page) ? 1 << 3 : page;
|
nalloc |= nalloc >> 2;
|
||||||
while (nalloc < alloc) {
|
nalloc |= nalloc >> 4;
|
||||||
if (nalloc <= 0)
|
nalloc |= nalloc >> 8;
|
||||||
return INT_MAX;
|
nalloc |= nalloc >> 16;
|
||||||
nalloc *= 2;
|
++nalloc;
|
||||||
}
|
|
||||||
}
|
Q_ASSERT(nalloc > unsigned(alloc + extra));
|
||||||
|
|
||||||
return nalloc - extra;
|
return nalloc - extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +555,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||||||
}
|
}
|
||||||
d.take(); // realloc was successful
|
d.take(); // realloc was successful
|
||||||
d.reset(p);
|
d.reset(p);
|
||||||
d->offset = 0;
|
d->offset = sizeof(QByteArrayData);
|
||||||
|
|
||||||
int res = ::uncompress((uchar*)d->data(), &len,
|
int res = ::uncompress((uchar*)d->data(), &len,
|
||||||
(uchar*)data+4, nbytes-4);
|
(uchar*)data+4, nbytes-4);
|
||||||
@ -576,11 +577,11 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||||||
d.take(); // realloc was successful
|
d.take(); // realloc was successful
|
||||||
d.reset(p);
|
d.reset(p);
|
||||||
}
|
}
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->size = len;
|
d->size = len;
|
||||||
d->alloc = len;
|
d->alloc = len;
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
d->offset = 0;
|
d->offset = sizeof(QByteArrayData);
|
||||||
d->data()[len] = 0;
|
d->data()[len] = 0;
|
||||||
|
|
||||||
return QByteArray(d.take(), 0, 0);
|
return QByteArray(d.take(), 0, 0);
|
||||||
@ -614,10 +615,10 @@ static inline char qToLower(char c)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QConstByteArrayData<1> QByteArray::shared_null = { { Q_REFCOUNT_INITIALIZER(-1),
|
const QStaticByteArrayData<1> QByteArray::shared_null = { { Q_REFCOUNT_INITIALIZE_STATIC,
|
||||||
0, 0, 0, { 0 } }, { 0 } };
|
0, 0, 0, sizeof(QByteArrayData) }, { 0 } };
|
||||||
const QConstByteArrayData<1> QByteArray::shared_empty = { { Q_REFCOUNT_INITIALIZER(-1),
|
const QStaticByteArrayData<1> QByteArray::shared_empty = { { Q_REFCOUNT_INITIALIZE_STATIC,
|
||||||
0, 0, 0, { 0 } }, { 0 } };
|
0, 0, 0, sizeof(QByteArrayData) }, { 0 } };
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class QByteArray
|
\class QByteArray
|
||||||
@ -904,7 +905,7 @@ QByteArray &QByteArray::operator=(const char *str)
|
|||||||
x = const_cast<Data *>(&shared_empty.ba);
|
x = const_cast<Data *>(&shared_empty.ba);
|
||||||
} else {
|
} else {
|
||||||
int len = qstrlen(str);
|
int len = qstrlen(str);
|
||||||
if (d->ref != 1 || len > int(d->alloc) || (len < d->size && len < int(d->alloc) >> 1))
|
if (d->ref.isShared() || len > int(d->alloc) || (len < d->size && len < int(d->alloc) >> 1))
|
||||||
realloc(len);
|
realloc(len);
|
||||||
x = d;
|
x = d;
|
||||||
memcpy(x->data(), str, len + 1); // include null terminator
|
memcpy(x->data(), str, len + 1); // include null terminator
|
||||||
@ -1289,38 +1290,16 @@ void QByteArray::chop(int n)
|
|||||||
\sa isEmpty()
|
\sa isEmpty()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \fn QByteArray::QByteArray(const char *str)
|
|
||||||
|
|
||||||
Constructs a byte array initialized with the string \a str.
|
|
||||||
|
|
||||||
QByteArray makes a deep copy of the string data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QByteArray::QByteArray(const char *str)
|
|
||||||
{
|
|
||||||
if (!str) {
|
|
||||||
d = const_cast<Data *>(&shared_null.ba);
|
|
||||||
} else if (!*str) {
|
|
||||||
d = const_cast<Data *>(&shared_empty.ba);
|
|
||||||
} else {
|
|
||||||
int len = qstrlen(str);
|
|
||||||
d = static_cast<Data *>(malloc(sizeof(Data) + len + 1));
|
|
||||||
Q_CHECK_PTR(d);
|
|
||||||
d->ref = 1;
|
|
||||||
d->size = len;
|
|
||||||
d->alloc = len;
|
|
||||||
d->capacityReserved = false;
|
|
||||||
d->offset = 0;
|
|
||||||
memcpy(d->data(), str, len+1); // include null terminator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructs a byte array containing the first \a size bytes of
|
Constructs a byte array containing the first \a size bytes of
|
||||||
array \a data.
|
array \a data.
|
||||||
|
|
||||||
If \a data is 0, a null byte array is constructed.
|
If \a data is 0, a null byte array is constructed.
|
||||||
|
|
||||||
|
If \a size is negative, \a data is assumed to point to a nul-terminated
|
||||||
|
string and its length is determined dynamically. The terminating
|
||||||
|
nul-character is not considered part of the byte array.
|
||||||
|
|
||||||
QByteArray makes a deep copy of the string data.
|
QByteArray makes a deep copy of the string data.
|
||||||
|
|
||||||
\sa fromRawData()
|
\sa fromRawData()
|
||||||
@ -1330,18 +1309,22 @@ QByteArray::QByteArray(const char *data, int size)
|
|||||||
{
|
{
|
||||||
if (!data) {
|
if (!data) {
|
||||||
d = const_cast<Data *>(&shared_null.ba);
|
d = const_cast<Data *>(&shared_null.ba);
|
||||||
} else if (size <= 0) {
|
|
||||||
d = const_cast<Data *>(&shared_empty.ba);
|
|
||||||
} else {
|
} else {
|
||||||
d = static_cast<Data *>(malloc(sizeof(Data) + size + 1));
|
if (size < 0)
|
||||||
Q_CHECK_PTR(d);
|
size = strlen(data);
|
||||||
d->ref = 1;
|
if (!size) {
|
||||||
d->size = size;
|
d = const_cast<Data *>(&shared_empty.ba);
|
||||||
d->alloc = size;
|
} else {
|
||||||
d->capacityReserved = false;
|
d = static_cast<Data *>(malloc(sizeof(Data) + size + 1));
|
||||||
d->offset = 0;
|
Q_CHECK_PTR(d);
|
||||||
memcpy(d->data(), data, size);
|
d->ref.initializeOwned();
|
||||||
d->data()[size] = '\0';
|
d->size = size;
|
||||||
|
d->alloc = size;
|
||||||
|
d->capacityReserved = false;
|
||||||
|
d->offset = sizeof(QByteArrayData);
|
||||||
|
memcpy(d->data(), data, size);
|
||||||
|
d->data()[size] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1359,11 +1342,11 @@ QByteArray::QByteArray(int size, char ch)
|
|||||||
} else {
|
} else {
|
||||||
d = static_cast<Data *>(malloc(sizeof(Data) + size + 1));
|
d = static_cast<Data *>(malloc(sizeof(Data) + size + 1));
|
||||||
Q_CHECK_PTR(d);
|
Q_CHECK_PTR(d);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->alloc = size;
|
d->alloc = size;
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
d->offset = 0;
|
d->offset = sizeof(QByteArrayData);
|
||||||
memset(d->data(), ch, size);
|
memset(d->data(), ch, size);
|
||||||
d->data()[size] = '\0';
|
d->data()[size] = '\0';
|
||||||
}
|
}
|
||||||
@ -1379,11 +1362,11 @@ QByteArray::QByteArray(int size, Qt::Initialization)
|
|||||||
{
|
{
|
||||||
d = static_cast<Data *>(malloc(sizeof(Data) + size + 1));
|
d = static_cast<Data *>(malloc(sizeof(Data) + size + 1));
|
||||||
Q_CHECK_PTR(d);
|
Q_CHECK_PTR(d);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->alloc = size;
|
d->alloc = size;
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
d->offset = 0;
|
d->offset = sizeof(QByteArrayData);
|
||||||
d->data()[size] = '\0';
|
d->data()[size] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1405,7 +1388,7 @@ void QByteArray::resize(int size)
|
|||||||
if (size < 0)
|
if (size < 0)
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
if (d->offset && d->ref == 1 && size < d->size) {
|
if (IS_RAW_DATA(d) && !d->ref.isShared() && size < d->size) {
|
||||||
d->size = size;
|
d->size = size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1426,15 +1409,15 @@ void QByteArray::resize(int size)
|
|||||||
//
|
//
|
||||||
Data *x = static_cast<Data *>(malloc(sizeof(Data) + size + 1));
|
Data *x = static_cast<Data *>(malloc(sizeof(Data) + size + 1));
|
||||||
Q_CHECK_PTR(x);
|
Q_CHECK_PTR(x);
|
||||||
x->ref = 1;
|
x->ref.initializeOwned();
|
||||||
x->size = size;
|
x->size = size;
|
||||||
x->alloc = size;
|
x->alloc = size;
|
||||||
x->capacityReserved = false;
|
x->capacityReserved = false;
|
||||||
x->offset = 0;
|
x->offset = sizeof(QByteArrayData);
|
||||||
x->data()[size] = '\0';
|
x->data()[size] = '\0';
|
||||||
d = x;
|
d = x;
|
||||||
} else {
|
} else {
|
||||||
if (d->ref != 1 || size > int(d->alloc)
|
if (d->ref.isShared() || size > int(d->alloc)
|
||||||
|| (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
|
|| (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
|
||||||
realloc(qAllocMore(size, sizeof(Data)));
|
realloc(qAllocMore(size, sizeof(Data)));
|
||||||
if (int(d->alloc) >= size) {
|
if (int(d->alloc) >= size) {
|
||||||
@ -1465,14 +1448,14 @@ QByteArray &QByteArray::fill(char ch, int size)
|
|||||||
|
|
||||||
void QByteArray::realloc(int alloc)
|
void QByteArray::realloc(int alloc)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || d->offset) {
|
if (d->ref.isShared() || IS_RAW_DATA(d)) {
|
||||||
Data *x = static_cast<Data *>(malloc(sizeof(Data) + alloc + 1));
|
Data *x = static_cast<Data *>(malloc(sizeof(Data) + alloc + 1));
|
||||||
Q_CHECK_PTR(x);
|
Q_CHECK_PTR(x);
|
||||||
x->ref = 1;
|
x->ref.initializeOwned();
|
||||||
x->size = qMin(alloc, d->size);
|
x->size = qMin(alloc, d->size);
|
||||||
x->alloc = alloc;
|
x->alloc = alloc;
|
||||||
x->capacityReserved = d->capacityReserved;
|
x->capacityReserved = d->capacityReserved;
|
||||||
x->offset = 0;
|
x->offset = sizeof(QByteArrayData);
|
||||||
::memcpy(x->data(), d->data(), x->size);
|
::memcpy(x->data(), d->data(), x->size);
|
||||||
x->data()[x->size] = '\0';
|
x->data()[x->size] = '\0';
|
||||||
if (!d->ref.deref())
|
if (!d->ref.deref())
|
||||||
@ -1482,7 +1465,7 @@ void QByteArray::realloc(int alloc)
|
|||||||
Data *x = static_cast<Data *>(::realloc(d, sizeof(Data) + alloc + 1));
|
Data *x = static_cast<Data *>(::realloc(d, sizeof(Data) + alloc + 1));
|
||||||
Q_CHECK_PTR(x);
|
Q_CHECK_PTR(x);
|
||||||
x->alloc = alloc;
|
x->alloc = alloc;
|
||||||
x->offset = 0;
|
x->offset = sizeof(QByteArrayData);
|
||||||
d = x;
|
d = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1504,7 +1487,7 @@ void QByteArray::expand(int i)
|
|||||||
QByteArray QByteArray::nulTerminated() const
|
QByteArray QByteArray::nulTerminated() const
|
||||||
{
|
{
|
||||||
// is this fromRawData?
|
// is this fromRawData?
|
||||||
if (!d->offset)
|
if (!IS_RAW_DATA(d))
|
||||||
return *this; // no, then we're sure we're zero terminated
|
return *this; // no, then we're sure we're zero terminated
|
||||||
|
|
||||||
QByteArray copy(*this);
|
QByteArray copy(*this);
|
||||||
@ -1566,7 +1549,7 @@ QByteArray &QByteArray::prepend(const char *str)
|
|||||||
QByteArray &QByteArray::prepend(const char *str, int len)
|
QByteArray &QByteArray::prepend(const char *str, int len)
|
||||||
{
|
{
|
||||||
if (str) {
|
if (str) {
|
||||||
if (d->ref != 1 || d->size + len > int(d->alloc))
|
if (d->ref.isShared() || d->size + len > int(d->alloc))
|
||||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||||
memmove(d->data()+len, d->data(), d->size);
|
memmove(d->data()+len, d->data(), d->size);
|
||||||
memcpy(d->data(), str, len);
|
memcpy(d->data(), str, len);
|
||||||
@ -1584,7 +1567,7 @@ QByteArray &QByteArray::prepend(const char *str, int len)
|
|||||||
|
|
||||||
QByteArray &QByteArray::prepend(char ch)
|
QByteArray &QByteArray::prepend(char ch)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || d->size + 1 > int(d->alloc))
|
if (d->ref.isShared() || d->size + 1 > int(d->alloc))
|
||||||
realloc(qAllocMore(d->size + 1, sizeof(Data)));
|
realloc(qAllocMore(d->size + 1, sizeof(Data)));
|
||||||
memmove(d->data()+1, d->data(), d->size);
|
memmove(d->data()+1, d->data(), d->size);
|
||||||
d->data()[0] = ch;
|
d->data()[0] = ch;
|
||||||
@ -1622,7 +1605,7 @@ QByteArray &QByteArray::append(const QByteArray &ba)
|
|||||||
if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) {
|
if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) {
|
||||||
*this = ba;
|
*this = ba;
|
||||||
} else if (ba.d != &shared_null.ba) {
|
} else if (ba.d != &shared_null.ba) {
|
||||||
if (d->ref != 1 || d->size + ba.d->size > int(d->alloc))
|
if (d->ref.isShared() || d->size + ba.d->size > int(d->alloc))
|
||||||
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
|
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
|
||||||
memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
|
memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
|
||||||
d->size += ba.d->size;
|
d->size += ba.d->size;
|
||||||
@ -1656,7 +1639,7 @@ QByteArray& QByteArray::append(const char *str)
|
|||||||
{
|
{
|
||||||
if (str) {
|
if (str) {
|
||||||
int len = qstrlen(str);
|
int len = qstrlen(str);
|
||||||
if (d->ref != 1 || d->size + len > int(d->alloc))
|
if (d->ref.isShared() || d->size + len > int(d->alloc))
|
||||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||||
memcpy(d->data() + d->size, str, len + 1); // include null terminator
|
memcpy(d->data() + d->size, str, len + 1); // include null terminator
|
||||||
d->size += len;
|
d->size += len;
|
||||||
@ -1681,7 +1664,7 @@ QByteArray &QByteArray::append(const char *str, int len)
|
|||||||
if (len < 0)
|
if (len < 0)
|
||||||
len = qstrlen(str);
|
len = qstrlen(str);
|
||||||
if (str && len) {
|
if (str && len) {
|
||||||
if (d->ref != 1 || d->size + len > int(d->alloc))
|
if (d->ref.isShared() || d->size + len > int(d->alloc))
|
||||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||||
memcpy(d->data() + d->size, str, len); // include null terminator
|
memcpy(d->data() + d->size, str, len); // include null terminator
|
||||||
d->size += len;
|
d->size += len;
|
||||||
@ -1698,7 +1681,7 @@ QByteArray &QByteArray::append(const char *str, int len)
|
|||||||
|
|
||||||
QByteArray& QByteArray::append(char ch)
|
QByteArray& QByteArray::append(char ch)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || d->size + 1 > int(d->alloc))
|
if (d->ref.isShared() || d->size + 1 > int(d->alloc))
|
||||||
realloc(qAllocMore(d->size + 1, sizeof(Data)));
|
realloc(qAllocMore(d->size + 1, sizeof(Data)));
|
||||||
d->data()[d->size++] = ch;
|
d->data()[d->size++] = ch;
|
||||||
d->data()[d->size] = '\0';
|
d->data()[d->size] = '\0';
|
||||||
@ -3889,11 +3872,11 @@ QByteArray QByteArray::fromRawData(const char *data, int size)
|
|||||||
} else {
|
} else {
|
||||||
x = static_cast<Data *>(malloc(sizeof(Data) + 1));
|
x = static_cast<Data *>(malloc(sizeof(Data) + 1));
|
||||||
Q_CHECK_PTR(x);
|
Q_CHECK_PTR(x);
|
||||||
x->ref = 1;
|
x->ref.initializeOwned();
|
||||||
x->size = size;
|
x->size = size;
|
||||||
x->alloc = 0;
|
x->alloc = 0;
|
||||||
x->capacityReserved = false;
|
x->capacityReserved = false;
|
||||||
x->offset = data - (x->d + sizeof(qptrdiff));
|
x->offset = data - reinterpret_cast<char *>(x);
|
||||||
}
|
}
|
||||||
return QByteArray(x, 0, 0);
|
return QByteArray(x, 0, 0);
|
||||||
}
|
}
|
||||||
@ -3914,14 +3897,14 @@ QByteArray QByteArray::fromRawData(const char *data, int size)
|
|||||||
*/
|
*/
|
||||||
QByteArray &QByteArray::setRawData(const char *data, uint size)
|
QByteArray &QByteArray::setRawData(const char *data, uint size)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || d->alloc) {
|
if (d->ref.isShared() || d->alloc) {
|
||||||
*this = fromRawData(data, size);
|
*this = fromRawData(data, size);
|
||||||
} else {
|
} else {
|
||||||
if (data) {
|
if (data) {
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->offset = data - (d->d + sizeof(qptrdiff));
|
d->offset = data - reinterpret_cast<char *>(d);
|
||||||
} else {
|
} else {
|
||||||
d->offset = 0;
|
d->offset = sizeof(QByteArrayData);
|
||||||
d->size = 0;
|
d->size = 0;
|
||||||
*d->data() = 0;
|
*d->data() = 0;
|
||||||
}
|
}
|
||||||
|
@ -124,32 +124,31 @@ struct QByteArrayData
|
|||||||
int size;
|
int size;
|
||||||
uint alloc : 31;
|
uint alloc : 31;
|
||||||
uint capacityReserved : 1;
|
uint capacityReserved : 1;
|
||||||
union {
|
|
||||||
qptrdiff offset; // will always work as we add/subtract from a ushort ptr
|
qptrdiff offset;
|
||||||
char d[sizeof(qptrdiff)];
|
|
||||||
};
|
inline char *data() { return reinterpret_cast<char *>(this) + offset; }
|
||||||
inline char *data() { return d + sizeof(qptrdiff) + offset; }
|
inline const char *data() const { return reinterpret_cast<const char *>(this) + offset; }
|
||||||
inline const char *data() const { return d + sizeof(qptrdiff) + offset; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N> struct QConstByteArrayData
|
template<int N> struct QStaticByteArrayData
|
||||||
{
|
{
|
||||||
const QByteArrayData ba;
|
QByteArrayData ba;
|
||||||
const char data[N + 1];
|
char data[N + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N> struct QConstByteArrayDataPtr
|
template<int N> struct QStaticByteArrayDataPtr
|
||||||
{
|
{
|
||||||
const QConstByteArrayData<N> *ptr;
|
const QStaticByteArrayData<N> *ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if defined(Q_COMPILER_LAMBDA)
|
#if defined(Q_COMPILER_LAMBDA)
|
||||||
# define QByteArrayLiteral(str) ([]() -> QConstByteArrayDataPtr<sizeof(str) - 1> { \
|
# define QByteArrayLiteral(str) ([]() -> QStaticByteArrayDataPtr<sizeof(str) - 1> { \
|
||||||
enum { Size = sizeof(str) - 1 }; \
|
enum { Size = sizeof(str) - 1 }; \
|
||||||
static const QConstByteArrayData<Size> qbytearray_literal = \
|
static const QStaticByteArrayData<Size> qbytearray_literal = \
|
||||||
{ { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, str }; \
|
{ { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, sizeof(QByteArrayData) }, str }; \
|
||||||
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
|
QStaticByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
|
||||||
return holder; }())
|
return holder; }())
|
||||||
|
|
||||||
#elif defined(Q_CC_GNU)
|
#elif defined(Q_CC_GNU)
|
||||||
@ -160,9 +159,9 @@ template<int N> struct QConstByteArrayDataPtr
|
|||||||
# define QByteArrayLiteral(str) \
|
# define QByteArrayLiteral(str) \
|
||||||
__extension__ ({ \
|
__extension__ ({ \
|
||||||
enum { Size = sizeof(str) - 1 }; \
|
enum { Size = sizeof(str) - 1 }; \
|
||||||
static const QConstByteArrayData<Size> qbytearray_literal = \
|
static const QStaticByteArrayData<Size> qbytearray_literal = \
|
||||||
{ { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, str }; \
|
{ { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, sizeof(QByteArrayData) }, str }; \
|
||||||
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
|
QStaticByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
|
||||||
holder; })
|
holder; })
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -180,8 +179,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
inline QByteArray();
|
inline QByteArray();
|
||||||
QByteArray(const char *);
|
QByteArray(const char *, int size = -1);
|
||||||
QByteArray(const char *, int size);
|
|
||||||
QByteArray(int size, char c);
|
QByteArray(int size, char c);
|
||||||
QByteArray(int size, Qt::Initialization);
|
QByteArray(int size, Qt::Initialization);
|
||||||
inline QByteArray(const QByteArray &);
|
inline QByteArray(const QByteArray &);
|
||||||
@ -379,16 +377,16 @@ public:
|
|||||||
bool isNull() const;
|
bool isNull() const;
|
||||||
|
|
||||||
template <int n>
|
template <int n>
|
||||||
inline QByteArray(const QConstByteArrayData<n> &dd)
|
inline QByteArray(const QStaticByteArrayData<n> &dd)
|
||||||
: d(const_cast<QByteArrayData *>(&dd.ba)) {}
|
: d(const_cast<QByteArrayData *>(&dd.ba)) {}
|
||||||
template <int N>
|
template <int N>
|
||||||
Q_DECL_CONSTEXPR inline QByteArray(QConstByteArrayDataPtr<N> dd)
|
Q_DECL_CONSTEXPR inline QByteArray(QStaticByteArrayDataPtr<N> dd)
|
||||||
: d(const_cast<QByteArrayData *>(&dd.ptr->ba)) {}
|
: d(const_cast<QByteArrayData *>(&dd.ptr->ba)) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
operator QNoImplicitBoolCast() const;
|
operator QNoImplicitBoolCast() const;
|
||||||
static const QConstByteArrayData<1> shared_null;
|
static const QStaticByteArrayData<1> shared_null;
|
||||||
static const QConstByteArrayData<1> shared_empty;
|
static const QStaticByteArrayData<1> shared_empty;
|
||||||
Data *d;
|
Data *d;
|
||||||
QByteArray(Data *dd, int /*dummy*/, int /*dummy*/) : d(dd) {}
|
QByteArray(Data *dd, int /*dummy*/, int /*dummy*/) : d(dd) {}
|
||||||
void realloc(int alloc);
|
void realloc(int alloc);
|
||||||
@ -424,9 +422,9 @@ inline const char *QByteArray::data() const
|
|||||||
inline const char *QByteArray::constData() const
|
inline const char *QByteArray::constData() const
|
||||||
{ return d->data(); }
|
{ return d->data(); }
|
||||||
inline void QByteArray::detach()
|
inline void QByteArray::detach()
|
||||||
{ if (d->ref != 1 || d->offset) realloc(d->size); }
|
{ if (d->ref.isShared() || (d->offset != sizeof(QByteArrayData))) realloc(d->size); }
|
||||||
inline bool QByteArray::isDetached() const
|
inline bool QByteArray::isDetached() const
|
||||||
{ return d->ref == 1; }
|
{ return !d->ref.isShared(); }
|
||||||
inline QByteArray::QByteArray(const QByteArray &a) : d(a.d)
|
inline QByteArray::QByteArray(const QByteArray &a) : d(a.d)
|
||||||
{ d->ref.ref(); }
|
{ d->ref.ref(); }
|
||||||
|
|
||||||
@ -435,7 +433,7 @@ inline int QByteArray::capacity() const
|
|||||||
|
|
||||||
inline void QByteArray::reserve(int asize)
|
inline void QByteArray::reserve(int asize)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || asize > int(d->alloc))
|
if (d->ref.isShared() || asize > int(d->alloc))
|
||||||
realloc(asize);
|
realloc(asize);
|
||||||
|
|
||||||
if (!d->capacityReserved) {
|
if (!d->capacityReserved) {
|
||||||
@ -446,11 +444,12 @@ inline void QByteArray::reserve(int asize)
|
|||||||
|
|
||||||
inline void QByteArray::squeeze()
|
inline void QByteArray::squeeze()
|
||||||
{
|
{
|
||||||
if (d->ref > 1 || d->size < int(d->alloc))
|
if (d->ref.isShared() || d->size < int(d->alloc))
|
||||||
realloc(d->size);
|
realloc(d->size);
|
||||||
|
|
||||||
if (d->capacityReserved) {
|
if (d->capacityReserved) {
|
||||||
// cannot set unconditionally, since d could be the shared_null/shared_empty (which is const)
|
// cannot set unconditionally, since d could be shared_null or
|
||||||
|
// otherwise static.
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ static int countBits(int hint)
|
|||||||
const int MinNumBits = 4;
|
const int MinNumBits = 4;
|
||||||
|
|
||||||
const QHashData QHashData::shared_null = {
|
const QHashData QHashData::shared_null = {
|
||||||
0, 0, Q_REFCOUNT_INITIALIZER(-1), 0, 0, MinNumBits, 0, 0, true, false, 0
|
0, 0, Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, MinNumBits, 0, 0, true, false, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
void *QHashData::allocateNode(int nodeAlign)
|
void *QHashData::allocateNode(int nodeAlign)
|
||||||
@ -196,7 +196,7 @@ QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *),
|
|||||||
d = new QHashData;
|
d = new QHashData;
|
||||||
d->fakeNext = 0;
|
d->fakeNext = 0;
|
||||||
d->buckets = 0;
|
d->buckets = 0;
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->nodeSize = nodeSize;
|
d->nodeSize = nodeSize;
|
||||||
d->userNumBits = userNumBits;
|
d->userNumBits = userNumBits;
|
||||||
|
@ -288,8 +288,8 @@ public:
|
|||||||
void reserve(int size);
|
void reserve(int size);
|
||||||
inline void squeeze() { reserve(1); }
|
inline void squeeze() { reserve(1); }
|
||||||
|
|
||||||
inline void detach() { if (d->ref != 1) detach_helper(); }
|
inline void detach() { if (d->ref.isShared()) detach_helper(); }
|
||||||
inline bool isDetached() const { return d->ref == 1; }
|
inline bool isDetached() const { return !d->ref.isShared(); }
|
||||||
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QHashData::shared_null) d->sharable = sharable; }
|
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QHashData::shared_null) d->sharable = sharable; }
|
||||||
inline bool isSharedWith(const QHash<Key, T> &other) const { return d == other.d; }
|
inline bool isSharedWith(const QHash<Key, T> &other) const { return d == other.d; }
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
const QLinkedListData QLinkedListData::shared_null = {
|
const QLinkedListData QLinkedListData::shared_null = {
|
||||||
const_cast<QLinkedListData *>(&QLinkedListData::shared_null),
|
const_cast<QLinkedListData *>(&QLinkedListData::shared_null),
|
||||||
const_cast<QLinkedListData *>(&QLinkedListData::shared_null),
|
const_cast<QLinkedListData *>(&QLinkedListData::shared_null),
|
||||||
Q_REFCOUNT_INITIALIZER(-1), 0, true
|
Q_REFCOUNT_INITIALIZE_STATIC, 0, true
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \class QLinkedList
|
/*! \class QLinkedList
|
||||||
|
@ -94,8 +94,8 @@ public:
|
|||||||
|
|
||||||
inline int size() const { return d->size; }
|
inline int size() const { return d->size; }
|
||||||
inline void detach()
|
inline void detach()
|
||||||
{ if (d->ref != 1) detach_helper(); }
|
{ if (d->ref.isShared()) detach_helper(); }
|
||||||
inline bool isDetached() const { return d->ref == 1; }
|
inline bool isDetached() const { return !d->ref.isShared(); }
|
||||||
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; }
|
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; }
|
||||||
inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; }
|
inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; }
|
||||||
|
|
||||||
@ -241,8 +241,6 @@ private:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline QLinkedList<T>::~QLinkedList()
|
inline QLinkedList<T>::~QLinkedList()
|
||||||
{
|
{
|
||||||
if (!d)
|
|
||||||
return;
|
|
||||||
if (!d->ref.deref())
|
if (!d->ref.deref())
|
||||||
free(d);
|
free(d);
|
||||||
}
|
}
|
||||||
@ -252,7 +250,7 @@ void QLinkedList<T>::detach_helper()
|
|||||||
{
|
{
|
||||||
union { QLinkedListData *d; Node *e; } x;
|
union { QLinkedListData *d; Node *e; } x;
|
||||||
x.d = new QLinkedListData;
|
x.d = new QLinkedListData;
|
||||||
x.d->ref = 1;
|
x.d->ref.initializeOwned();
|
||||||
x.d->size = d->size;
|
x.d->size = d->size;
|
||||||
x.d->sharable = true;
|
x.d->sharable = true;
|
||||||
Node *original = e->n;
|
Node *original = e->n;
|
||||||
@ -265,6 +263,7 @@ void QLinkedList<T>::detach_helper()
|
|||||||
copy = copy->n;
|
copy = copy->n;
|
||||||
} QT_CATCH(...) {
|
} QT_CATCH(...) {
|
||||||
copy->n = x.e;
|
copy->n = x.e;
|
||||||
|
Q_ASSERT(!x.d->ref.deref()); // Don't trigger assert in free
|
||||||
free(x.d);
|
free(x.d);
|
||||||
QT_RETHROW;
|
QT_RETHROW;
|
||||||
}
|
}
|
||||||
@ -281,14 +280,13 @@ void QLinkedList<T>::free(QLinkedListData *x)
|
|||||||
{
|
{
|
||||||
Node *y = reinterpret_cast<Node*>(x);
|
Node *y = reinterpret_cast<Node*>(x);
|
||||||
Node *i = y->n;
|
Node *i = y->n;
|
||||||
if (x->ref == 0) {
|
Q_ASSERT(x->ref.atomic.load() == 0);
|
||||||
while(i != y) {
|
while (i != y) {
|
||||||
Node *n = i;
|
Node *n = i;
|
||||||
i = i->n;
|
i = i->n;
|
||||||
delete n;
|
delete n;
|
||||||
}
|
|
||||||
delete x;
|
|
||||||
}
|
}
|
||||||
|
delete x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
the number of elements in the list.
|
the number of elements in the list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const QListData::Data QListData::shared_null = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, true, { 0 } };
|
const QListData::Data QListData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, { 0 } };
|
||||||
|
|
||||||
static int grow(int size)
|
static int grow(int size)
|
||||||
{
|
{
|
||||||
@ -87,8 +87,7 @@ QListData::Data *QListData::detach_grow(int *idx, int num)
|
|||||||
Data* t = static_cast<Data *>(::malloc(DataHeaderSize + alloc * sizeof(void *)));
|
Data* t = static_cast<Data *>(::malloc(DataHeaderSize + alloc * sizeof(void *)));
|
||||||
Q_CHECK_PTR(t);
|
Q_CHECK_PTR(t);
|
||||||
|
|
||||||
t->ref = 1;
|
t->ref.initializeOwned();
|
||||||
t->sharable = true;
|
|
||||||
t->alloc = alloc;
|
t->alloc = alloc;
|
||||||
// The space reservation algorithm's optimization is biased towards appending:
|
// The space reservation algorithm's optimization is biased towards appending:
|
||||||
// Something which looks like an append will put the data at the beginning,
|
// Something which looks like an append will put the data at the beginning,
|
||||||
@ -129,8 +128,7 @@ QListData::Data *QListData::detach(int alloc)
|
|||||||
Data* t = static_cast<Data *>(::malloc(DataHeaderSize + alloc * sizeof(void *)));
|
Data* t = static_cast<Data *>(::malloc(DataHeaderSize + alloc * sizeof(void *)));
|
||||||
Q_CHECK_PTR(t);
|
Q_CHECK_PTR(t);
|
||||||
|
|
||||||
t->ref = 1;
|
t->ref.initializeOwned();
|
||||||
t->sharable = true;
|
|
||||||
t->alloc = alloc;
|
t->alloc = alloc;
|
||||||
if (!alloc) {
|
if (!alloc) {
|
||||||
t->begin = 0;
|
t->begin = 0;
|
||||||
@ -146,7 +144,7 @@ QListData::Data *QListData::detach(int alloc)
|
|||||||
|
|
||||||
void QListData::realloc(int alloc)
|
void QListData::realloc(int alloc)
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->ref == 1);
|
Q_ASSERT(!d->ref.isShared());
|
||||||
Data *x = static_cast<Data *>(::realloc(d, DataHeaderSize + alloc * sizeof(void *)));
|
Data *x = static_cast<Data *>(::realloc(d, DataHeaderSize + alloc * sizeof(void *)));
|
||||||
Q_CHECK_PTR(x);
|
Q_CHECK_PTR(x);
|
||||||
|
|
||||||
@ -159,7 +157,7 @@ void QListData::realloc(int alloc)
|
|||||||
// ensures that enough space is available to append n elements
|
// ensures that enough space is available to append n elements
|
||||||
void **QListData::append(int n)
|
void **QListData::append(int n)
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->ref == 1);
|
Q_ASSERT(!d->ref.isShared());
|
||||||
int e = d->end;
|
int e = d->end;
|
||||||
if (e + n > d->alloc) {
|
if (e + n > d->alloc) {
|
||||||
int b = d->begin;
|
int b = d->begin;
|
||||||
@ -190,7 +188,7 @@ void **QListData::append(const QListData& l)
|
|||||||
|
|
||||||
void **QListData::prepend()
|
void **QListData::prepend()
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->ref == 1);
|
Q_ASSERT(!d->ref.isShared());
|
||||||
if (d->begin == 0) {
|
if (d->begin == 0) {
|
||||||
if (d->end >= d->alloc / 3)
|
if (d->end >= d->alloc / 3)
|
||||||
realloc(grow(d->alloc + 1));
|
realloc(grow(d->alloc + 1));
|
||||||
@ -208,7 +206,7 @@ void **QListData::prepend()
|
|||||||
|
|
||||||
void **QListData::insert(int i)
|
void **QListData::insert(int i)
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->ref == 1);
|
Q_ASSERT(!d->ref.isShared());
|
||||||
if (i <= 0)
|
if (i <= 0)
|
||||||
return prepend();
|
return prepend();
|
||||||
int size = d->end - d->begin;
|
int size = d->end - d->begin;
|
||||||
@ -247,7 +245,7 @@ void **QListData::insert(int i)
|
|||||||
|
|
||||||
void QListData::remove(int i)
|
void QListData::remove(int i)
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->ref == 1);
|
Q_ASSERT(!d->ref.isShared());
|
||||||
i += d->begin;
|
i += d->begin;
|
||||||
if (i - d->begin < d->end - i) {
|
if (i - d->begin < d->end - i) {
|
||||||
if (int offset = i - d->begin)
|
if (int offset = i - d->begin)
|
||||||
@ -262,7 +260,7 @@ void QListData::remove(int i)
|
|||||||
|
|
||||||
void QListData::remove(int i, int n)
|
void QListData::remove(int i, int n)
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->ref == 1);
|
Q_ASSERT(!d->ref.isShared());
|
||||||
i += d->begin;
|
i += d->begin;
|
||||||
int middle = i + n/2;
|
int middle = i + n/2;
|
||||||
if (middle - d->begin < d->end - middle) {
|
if (middle - d->begin < d->end - middle) {
|
||||||
@ -278,7 +276,7 @@ void QListData::remove(int i, int n)
|
|||||||
|
|
||||||
void QListData::move(int from, int to)
|
void QListData::move(int from, int to)
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->ref == 1);
|
Q_ASSERT(!d->ref.isShared());
|
||||||
if (from == to)
|
if (from == to)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -318,7 +316,7 @@ void QListData::move(int from, int to)
|
|||||||
|
|
||||||
void **QListData::erase(void **xi)
|
void **QListData::erase(void **xi)
|
||||||
{
|
{
|
||||||
Q_ASSERT(d->ref == 1);
|
Q_ASSERT(!d->ref.isShared());
|
||||||
int i = xi - (d->array + d->begin);
|
int i = xi - (d->array + d->begin);
|
||||||
remove(i);
|
remove(i);
|
||||||
return d->array + d->begin + i;
|
return d->array + d->begin + i;
|
||||||
|
@ -71,7 +71,6 @@ struct Q_CORE_EXPORT QListData {
|
|||||||
struct Data {
|
struct Data {
|
||||||
QtPrivate::RefCount ref;
|
QtPrivate::RefCount ref;
|
||||||
int alloc, begin, end;
|
int alloc, begin, end;
|
||||||
uint sharable : 1;
|
|
||||||
void *array[1];
|
void *array[1];
|
||||||
};
|
};
|
||||||
enum { DataHeaderSize = sizeof(Data) - sizeof(void *) };
|
enum { DataHeaderSize = sizeof(Data) - sizeof(void *) };
|
||||||
@ -114,7 +113,7 @@ class QList
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
inline QList() : d(const_cast<QListData::Data *>(&QListData::shared_null)) { }
|
inline QList() : d(const_cast<QListData::Data *>(&QListData::shared_null)) { }
|
||||||
inline QList(const QList<T> &l) : d(l.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
|
QList(const QList<T> &l);
|
||||||
~QList();
|
~QList();
|
||||||
QList<T> &operator=(const QList<T> &l);
|
QList<T> &operator=(const QList<T> &l);
|
||||||
#ifdef Q_COMPILER_RVALUE_REFS
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
@ -132,17 +131,25 @@ public:
|
|||||||
|
|
||||||
inline int size() const { return p.size(); }
|
inline int size() const { return p.size(); }
|
||||||
|
|
||||||
inline void detach() { if (d->ref != 1) detach_helper(); }
|
inline void detach() { if (d->ref.isShared()) detach_helper(); }
|
||||||
|
|
||||||
inline void detachShared()
|
inline void detachShared()
|
||||||
{
|
{
|
||||||
// The "this->" qualification is needed for GCCE.
|
// The "this->" qualification is needed for GCCE.
|
||||||
if (d->ref != 1 && this->d != &QListData::shared_null)
|
if (d->ref.isShared() && this->d != &QListData::shared_null)
|
||||||
detach_helper();
|
detach_helper();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isDetached() const { return d->ref == 1; }
|
inline bool isDetached() const { return !d->ref.isShared(); }
|
||||||
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QListData::shared_null) d->sharable = sharable; }
|
inline void setSharable(bool sharable)
|
||||||
|
{
|
||||||
|
if (sharable == d->ref.isSharable())
|
||||||
|
return;
|
||||||
|
if (!sharable)
|
||||||
|
detach();
|
||||||
|
if (d != &QListData::shared_null)
|
||||||
|
d->ref.setSharable(sharable);
|
||||||
|
}
|
||||||
inline bool isSharedWith(const QList<T> &other) const { return d == other.d; }
|
inline bool isSharedWith(const QList<T> &other) const { return d == other.d; }
|
||||||
|
|
||||||
inline bool isEmpty() const { return p.isEmpty(); }
|
inline bool isEmpty() const { return p.isEmpty(); }
|
||||||
@ -419,13 +426,8 @@ template <typename T>
|
|||||||
Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
|
Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l)
|
||||||
{
|
{
|
||||||
if (d != l.d) {
|
if (d != l.d) {
|
||||||
QListData::Data *o = l.d;
|
QList<T> tmp(l);
|
||||||
o->ref.ref();
|
tmp.swap(*this);
|
||||||
if (!d->ref.deref())
|
|
||||||
dealloc(d);
|
|
||||||
d = o;
|
|
||||||
if (!d->sharable)
|
|
||||||
detach_helper();
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -478,7 +480,7 @@ template <typename T>
|
|||||||
Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc)
|
Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc)
|
||||||
{
|
{
|
||||||
if (d->alloc < alloc) {
|
if (d->alloc < alloc) {
|
||||||
if (d->ref != 1)
|
if (d->ref.isShared())
|
||||||
detach_helper(alloc);
|
detach_helper(alloc);
|
||||||
else
|
else
|
||||||
p.realloc(alloc);
|
p.realloc(alloc);
|
||||||
@ -488,7 +490,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
|
Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
|
||||||
{
|
{
|
||||||
if (d->ref != 1) {
|
if (d->ref.isShared()) {
|
||||||
Node *n = detach_helper_grow(INT_MAX, 1);
|
Node *n = detach_helper_grow(INT_MAX, 1);
|
||||||
QT_TRY {
|
QT_TRY {
|
||||||
node_construct(n, t);
|
node_construct(n, t);
|
||||||
@ -522,7 +524,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline void QList<T>::prepend(const T &t)
|
inline void QList<T>::prepend(const T &t)
|
||||||
{
|
{
|
||||||
if (d->ref != 1) {
|
if (d->ref.isShared()) {
|
||||||
Node *n = detach_helper_grow(0, 1);
|
Node *n = detach_helper_grow(0, 1);
|
||||||
QT_TRY {
|
QT_TRY {
|
||||||
node_construct(n, t);
|
node_construct(n, t);
|
||||||
@ -556,7 +558,7 @@ inline void QList<T>::prepend(const T &t)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline void QList<T>::insert(int i, const T &t)
|
inline void QList<T>::insert(int i, const T &t)
|
||||||
{
|
{
|
||||||
if (d->ref != 1) {
|
if (d->ref.isShared()) {
|
||||||
Node *n = detach_helper_grow(i, 1);
|
Node *n = detach_helper_grow(i, 1);
|
||||||
QT_TRY {
|
QT_TRY {
|
||||||
node_construct(n, t);
|
node_construct(n, t);
|
||||||
@ -707,6 +709,28 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
|
|||||||
detach_helper(d->alloc);
|
detach_helper(d->alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE QList<T>::QList(const QList<T> &l)
|
||||||
|
: d(l.d)
|
||||||
|
{
|
||||||
|
if (!d->ref.ref()) {
|
||||||
|
p.detach(d->alloc);
|
||||||
|
|
||||||
|
struct Cleanup
|
||||||
|
{
|
||||||
|
Cleanup(QListData::Data *d) : d_(d) {}
|
||||||
|
~Cleanup() { if (d_) qFree(d_); }
|
||||||
|
|
||||||
|
QListData::Data *d_;
|
||||||
|
} tryCatch(d);
|
||||||
|
|
||||||
|
node_copy(reinterpret_cast<Node *>(p.begin()),
|
||||||
|
reinterpret_cast<Node *>(p.end()),
|
||||||
|
reinterpret_cast<Node *>(l.p.begin()));
|
||||||
|
tryCatch.d_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Q_OUTOFLINE_TEMPLATE QList<T>::~QList()
|
Q_OUTOFLINE_TEMPLATE QList<T>::~QList()
|
||||||
{
|
{
|
||||||
@ -802,7 +826,7 @@ Q_OUTOFLINE_TEMPLATE QList<T> &QList<T>::operator+=(const QList<T> &l)
|
|||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
*this = l;
|
*this = l;
|
||||||
} else {
|
} else {
|
||||||
Node *n = (d->ref != 1)
|
Node *n = (d->ref.isShared())
|
||||||
? detach_helper_grow(INT_MAX, l.size())
|
? detach_helper_grow(INT_MAX, l.size())
|
||||||
: reinterpret_cast<Node *>(p.append(l.p));
|
: reinterpret_cast<Node *>(p.append(l.p));
|
||||||
QT_TRY {
|
QT_TRY {
|
||||||
|
@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
const QMapData QMapData::shared_null = {
|
const QMapData QMapData::shared_null = {
|
||||||
const_cast<QMapData *>(&shared_null),
|
const_cast<QMapData *>(&shared_null),
|
||||||
{ const_cast<QMapData *>(&shared_null), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
{ const_cast<QMapData *>(&shared_null), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, false, true, false, 0
|
Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, false, true, false, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
QMapData *QMapData::createData(int alignment)
|
QMapData *QMapData::createData(int alignment)
|
||||||
@ -63,7 +63,7 @@ QMapData *QMapData::createData(int alignment)
|
|||||||
Node *e = reinterpret_cast<Node *>(d);
|
Node *e = reinterpret_cast<Node *>(d);
|
||||||
e->backward = e;
|
e->backward = e;
|
||||||
e->forward[0] = e;
|
e->forward[0] = e;
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->topLevel = 0;
|
d->topLevel = 0;
|
||||||
d->size = 0;
|
d->size = 0;
|
||||||
d->randomBits = 0;
|
d->randomBits = 0;
|
||||||
|
@ -179,7 +179,7 @@ public:
|
|||||||
inline QMap() : d(const_cast<QMapData *>(&QMapData::shared_null)) { }
|
inline QMap() : d(const_cast<QMapData *>(&QMapData::shared_null)) { }
|
||||||
inline QMap(const QMap<Key, T> &other) : d(other.d)
|
inline QMap(const QMap<Key, T> &other) : d(other.d)
|
||||||
{ d->ref.ref(); if (!d->sharable) detach(); }
|
{ d->ref.ref(); if (!d->sharable) detach(); }
|
||||||
inline ~QMap() { if (!d) return; if (!d->ref.deref()) freeData(d); }
|
inline ~QMap() { if (!d->ref.deref()) freeData(d); }
|
||||||
|
|
||||||
QMap<Key, T> &operator=(const QMap<Key, T> &other);
|
QMap<Key, T> &operator=(const QMap<Key, T> &other);
|
||||||
#ifdef Q_COMPILER_RVALUE_REFS
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
@ -199,8 +199,8 @@ public:
|
|||||||
|
|
||||||
inline bool isEmpty() const { return d->size == 0; }
|
inline bool isEmpty() const { return d->size == 0; }
|
||||||
|
|
||||||
inline void detach() { if (d->ref != 1) detach_helper(); }
|
inline void detach() { if (d->ref.isShared()) detach_helper(); }
|
||||||
inline bool isDetached() const { return d->ref == 1; }
|
inline bool isDetached() const { return !d->ref.isShared(); }
|
||||||
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QMapData::shared_null) d->sharable = sharable; }
|
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QMapData::shared_null) d->sharable = sharable; }
|
||||||
inline bool isSharedWith(const QMap<Key, T> &other) const { return d == other.d; }
|
inline bool isSharedWith(const QMap<Key, T> &other) const { return d == other.d; }
|
||||||
inline void setInsertInOrder(bool ordered) { if (ordered) detach(); if (d != &QMapData::shared_null) d->insertInOrder = ordered; }
|
inline void setInsertInOrder(bool ordered) { if (ordered) detach(); if (d != &QMapData::shared_null) d->insertInOrder = ordered; }
|
||||||
|
@ -55,37 +55,61 @@ namespace QtPrivate
|
|||||||
class RefCount
|
class RefCount
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline void ref() {
|
inline bool ref() {
|
||||||
if (atomic.load() > 0)
|
int count = atomic.load();
|
||||||
|
if (count == 0) // !isSharable
|
||||||
|
return false;
|
||||||
|
if (count != -1) // !isStatic
|
||||||
atomic.ref();
|
atomic.ref();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool deref() {
|
inline bool deref() {
|
||||||
if (atomic.load() <= 0)
|
int count = atomic.load();
|
||||||
|
if (count == 0) // !isSharable
|
||||||
|
return false;
|
||||||
|
if (count == -1) // isStatic
|
||||||
return true;
|
return true;
|
||||||
return atomic.deref();
|
return atomic.deref();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(int value) const
|
bool setSharable(bool sharable)
|
||||||
{ return atomic.load() == value; }
|
{
|
||||||
inline bool operator!=(int value) const
|
Q_ASSERT(!isShared());
|
||||||
{ return atomic.load() != value; }
|
if (sharable)
|
||||||
inline bool operator!() const
|
return atomic.testAndSetRelaxed(0, 1);
|
||||||
{ return !atomic.load(); }
|
else
|
||||||
inline operator int() const
|
return atomic.testAndSetRelaxed(1, 0);
|
||||||
{ return atomic.load(); }
|
}
|
||||||
inline RefCount &operator=(int value)
|
|
||||||
{ atomic.store(value); return *this; }
|
bool isStatic() const
|
||||||
inline RefCount &operator=(const RefCount &other)
|
{
|
||||||
{ atomic.store(other.atomic.load()); return *this; }
|
// Persistent object, never deleted
|
||||||
|
return atomic.load() == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSharable() const
|
||||||
|
{
|
||||||
|
// Sharable === Shared ownership.
|
||||||
|
return atomic.load() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isShared() const
|
||||||
|
{
|
||||||
|
int count = atomic.load();
|
||||||
|
return (count != 1) && (count != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeOwned() { atomic.store(1); }
|
||||||
|
void initializeUnsharable() { atomic.store(0); }
|
||||||
|
|
||||||
QBasicAtomicInt atomic;
|
QBasicAtomicInt atomic;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define Q_REFCOUNT_INITIALIZER(a) { Q_BASIC_ATOMIC_INITIALIZER(a) }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define Q_REFCOUNT_INITIALIZE_STATIC { Q_BASIC_ATOMIC_INITIALIZER(-1) }
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
QT_END_HEADER
|
QT_END_HEADER
|
||||||
|
@ -94,6 +94,8 @@
|
|||||||
#define ULLONG_MAX quint64_C(18446744073709551615)
|
#define ULLONG_MAX quint64_C(18446744073709551615)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define IS_RAW_DATA(d) ((d)->offset != sizeof(QStringData))
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#ifdef QT_USE_ICU
|
#ifdef QT_USE_ICU
|
||||||
@ -793,8 +795,8 @@ const QString::Null QString::null = { };
|
|||||||
\sa split()
|
\sa split()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const QConstStringData<1> QString::shared_null = { { Q_REFCOUNT_INITIALIZER(-1), 0, 0, false, { 0 } }, { 0 } };
|
const QStaticStringData<1> QString::shared_null = { { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, false, sizeof(QStringData) }, { 0 } };
|
||||||
const QConstStringData<1> QString::shared_empty = { { Q_REFCOUNT_INITIALIZER(-1), 0, 0, false, { 0 } }, { 0 } };
|
const QStaticStringData<1> QString::shared_empty = { { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, false, sizeof(QStringData) }, { 0 } };
|
||||||
|
|
||||||
int QString::grow(int size)
|
int QString::grow(int size)
|
||||||
{
|
{
|
||||||
@ -1015,62 +1017,43 @@ int QString::toUcs4_helper(const ushort *uc, int length, uint *out)
|
|||||||
Constructs a string initialized with the first \a size characters
|
Constructs a string initialized with the first \a size characters
|
||||||
of the QChar array \a unicode.
|
of the QChar array \a unicode.
|
||||||
|
|
||||||
|
If \a unicode is 0, a null string is constructed.
|
||||||
|
|
||||||
|
If \a size is negative, \a unicode is assumed to point to a nul-terminated
|
||||||
|
array and its length is determined dynamically. The terminating
|
||||||
|
nul-character is not considered part of the string.
|
||||||
|
|
||||||
QString makes a deep copy of the string data. The unicode data is copied as
|
QString makes a deep copy of the string data. The unicode data is copied as
|
||||||
is and the Byte Order Mark is preserved if present.
|
is and the Byte Order Mark is preserved if present.
|
||||||
|
|
||||||
|
\sa fromRawData()
|
||||||
*/
|
*/
|
||||||
QString::QString(const QChar *unicode, int size)
|
QString::QString(const QChar *unicode, int size)
|
||||||
{
|
{
|
||||||
if (!unicode) {
|
if (!unicode) {
|
||||||
d = const_cast<Data *>(&shared_null.str);
|
d = const_cast<Data *>(&shared_null.str);
|
||||||
} else if (size <= 0) {
|
|
||||||
d = const_cast<Data *>(&shared_empty.str);
|
|
||||||
} else {
|
} else {
|
||||||
d = (Data*) ::malloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
if (size < 0) {
|
||||||
Q_CHECK_PTR(d);
|
size = 0;
|
||||||
d->ref = 1;
|
while (unicode[size] != 0)
|
||||||
d->size = size;
|
++size;
|
||||||
d->alloc = (uint) size;
|
}
|
||||||
d->capacityReserved = false;
|
if (!size) {
|
||||||
d->offset = 0;
|
d = const_cast<Data *>(&shared_empty.str);
|
||||||
memcpy(d->data(), unicode, size * sizeof(QChar));
|
} else {
|
||||||
d->data()[size] = '\0';
|
d = (Data*) ::malloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
||||||
|
Q_CHECK_PTR(d);
|
||||||
|
d->ref.initializeOwned();
|
||||||
|
d->size = size;
|
||||||
|
d->alloc = (uint) size;
|
||||||
|
d->capacityReserved = false;
|
||||||
|
d->offset = sizeof(QStringData);
|
||||||
|
memcpy(d->data(), unicode, size * sizeof(QChar));
|
||||||
|
d->data()[size] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\since 4.7
|
|
||||||
|
|
||||||
Constructs a string initialized with the characters of the QChar array
|
|
||||||
\a unicode, which must be terminated with a 0.
|
|
||||||
|
|
||||||
QString makes a deep copy of the string data. The unicode data is copied as
|
|
||||||
is and the Byte Order Mark is preserved if present.
|
|
||||||
*/
|
|
||||||
QString::QString(const QChar *unicode)
|
|
||||||
{
|
|
||||||
if (!unicode) {
|
|
||||||
d = const_cast<Data *>(&shared_null.str);
|
|
||||||
} else {
|
|
||||||
int size = 0;
|
|
||||||
while (unicode[size] != 0)
|
|
||||||
++size;
|
|
||||||
if (!size) {
|
|
||||||
d = const_cast<Data *>(&shared_empty.str);
|
|
||||||
} else {
|
|
||||||
d = (Data*) ::malloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
|
||||||
Q_CHECK_PTR(d);
|
|
||||||
d->ref = 1;
|
|
||||||
d->size = size;
|
|
||||||
d->alloc = (uint) size;
|
|
||||||
d->capacityReserved = false;
|
|
||||||
d->offset = 0;
|
|
||||||
memcpy(d->data(), unicode, size * sizeof(QChar));
|
|
||||||
d->data()[size] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructs a string of the given \a size with every character set
|
Constructs a string of the given \a size with every character set
|
||||||
to \a ch.
|
to \a ch.
|
||||||
@ -1084,11 +1067,11 @@ QString::QString(int size, QChar ch)
|
|||||||
} else {
|
} else {
|
||||||
d = (Data*) ::malloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
d = (Data*) ::malloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
||||||
Q_CHECK_PTR(d);
|
Q_CHECK_PTR(d);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->alloc = (uint) size;
|
d->alloc = (uint) size;
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
d->offset = 0;
|
d->offset = sizeof(QStringData);
|
||||||
d->data()[size] = '\0';
|
d->data()[size] = '\0';
|
||||||
ushort *i = d->data() + size;
|
ushort *i = d->data() + size;
|
||||||
ushort *b = d->data();
|
ushort *b = d->data();
|
||||||
@ -1108,11 +1091,11 @@ QString::QString(int size, Qt::Initialization)
|
|||||||
{
|
{
|
||||||
d = (Data*) ::malloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
d = (Data*) ::malloc(sizeof(Data)+(size+1)*sizeof(QChar));
|
||||||
Q_CHECK_PTR(d);
|
Q_CHECK_PTR(d);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->alloc = (uint) size;
|
d->alloc = (uint) size;
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
d->offset = 0;
|
d->offset = sizeof(QStringData);
|
||||||
d->data()[size] = '\0';
|
d->data()[size] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,11 +1113,11 @@ QString::QString(QChar ch)
|
|||||||
{
|
{
|
||||||
d = (Data *) ::malloc(sizeof(Data) + 2*sizeof(QChar));
|
d = (Data *) ::malloc(sizeof(Data) + 2*sizeof(QChar));
|
||||||
Q_CHECK_PTR(d);
|
Q_CHECK_PTR(d);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->size = 1;
|
d->size = 1;
|
||||||
d->alloc = 1;
|
d->alloc = 1;
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
d->offset = 0;
|
d->offset = sizeof(QStringData);
|
||||||
d->data()[0] = ch.unicode();
|
d->data()[0] = ch.unicode();
|
||||||
d->data()[1] = '\0';
|
d->data()[1] = '\0';
|
||||||
}
|
}
|
||||||
@ -1232,7 +1215,7 @@ void QString::resize(int size)
|
|||||||
if (size < 0)
|
if (size < 0)
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
if (d->offset && d->ref == 1 && size < d->size) {
|
if (IS_RAW_DATA(d) && !d->ref.isShared() && size < d->size) {
|
||||||
d->size = size;
|
d->size = size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1243,7 +1226,7 @@ void QString::resize(int size)
|
|||||||
QString::free(d);
|
QString::free(d);
|
||||||
d = x;
|
d = x;
|
||||||
} else {
|
} else {
|
||||||
if (d->ref != 1 || size > int(d->alloc) ||
|
if (d->ref.isShared() || size > int(d->alloc) ||
|
||||||
(!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
|
(!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
|
||||||
realloc(grow(size));
|
realloc(grow(size));
|
||||||
if (int(d->alloc) >= size) {
|
if (int(d->alloc) >= size) {
|
||||||
@ -1306,14 +1289,14 @@ void QString::resize(int size)
|
|||||||
// ### Qt 5: rename reallocData() to avoid confusion. 197625
|
// ### Qt 5: rename reallocData() to avoid confusion. 197625
|
||||||
void QString::realloc(int alloc)
|
void QString::realloc(int alloc)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || d->offset) {
|
if (d->ref.isShared() || IS_RAW_DATA(d)) {
|
||||||
Data *x = static_cast<Data *>(::malloc(sizeof(Data) + (alloc+1) * sizeof(QChar)));
|
Data *x = static_cast<Data *>(::malloc(sizeof(Data) + (alloc+1) * sizeof(QChar)));
|
||||||
Q_CHECK_PTR(x);
|
Q_CHECK_PTR(x);
|
||||||
x->ref = 1;
|
x->ref.initializeOwned();
|
||||||
x->size = qMin(alloc, d->size);
|
x->size = qMin(alloc, d->size);
|
||||||
x->alloc = (uint) alloc;
|
x->alloc = (uint) alloc;
|
||||||
x->capacityReserved = d->capacityReserved;
|
x->capacityReserved = d->capacityReserved;
|
||||||
x->offset =0;
|
x->offset = sizeof(QStringData);
|
||||||
::memcpy(x->data(), d->data(), x->size * sizeof(QChar));
|
::memcpy(x->data(), d->data(), x->size * sizeof(QChar));
|
||||||
x->data()[x->size] = 0;
|
x->data()[x->size] = 0;
|
||||||
if (!d->ref.deref())
|
if (!d->ref.deref())
|
||||||
@ -1324,7 +1307,7 @@ void QString::realloc(int alloc)
|
|||||||
Q_CHECK_PTR(p);
|
Q_CHECK_PTR(p);
|
||||||
d = p;
|
d = p;
|
||||||
d->alloc = alloc;
|
d->alloc = alloc;
|
||||||
d->offset = 0;
|
d->offset = sizeof(QStringData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1536,7 +1519,7 @@ QString &QString::append(const QString &str)
|
|||||||
if (d == &shared_null.str) {
|
if (d == &shared_null.str) {
|
||||||
operator=(str);
|
operator=(str);
|
||||||
} else {
|
} else {
|
||||||
if (d->ref != 1 || d->size + str.d->size > int(d->alloc))
|
if (d->ref.isShared() || d->size + str.d->size > int(d->alloc))
|
||||||
realloc(grow(d->size + str.d->size));
|
realloc(grow(d->size + str.d->size));
|
||||||
memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar));
|
memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar));
|
||||||
d->size += str.d->size;
|
d->size += str.d->size;
|
||||||
@ -1556,7 +1539,7 @@ QString &QString::append(const QLatin1String &str)
|
|||||||
const uchar *s = (const uchar *)str.latin1();
|
const uchar *s = (const uchar *)str.latin1();
|
||||||
if (s) {
|
if (s) {
|
||||||
int len = str.size();
|
int len = str.size();
|
||||||
if (d->ref != 1 || d->size + len > int(d->alloc))
|
if (d->ref.isShared() || d->size + len > int(d->alloc))
|
||||||
realloc(grow(d->size + len));
|
realloc(grow(d->size + len));
|
||||||
ushort *i = d->data() + d->size;
|
ushort *i = d->data() + d->size;
|
||||||
while ((*i++ = *s++))
|
while ((*i++ = *s++))
|
||||||
@ -1599,7 +1582,7 @@ QString &QString::append(const QLatin1String &str)
|
|||||||
*/
|
*/
|
||||||
QString &QString::append(QChar ch)
|
QString &QString::append(QChar ch)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || d->size + 1 > int(d->alloc))
|
if (d->ref.isShared() || d->size + 1 > int(d->alloc))
|
||||||
realloc(grow(d->size + 1));
|
realloc(grow(d->size + 1));
|
||||||
d->data()[d->size++] = ch.unicode();
|
d->data()[d->size++] = ch.unicode();
|
||||||
d->data()[d->size] = '\0';
|
d->data()[d->size] = '\0';
|
||||||
@ -3390,15 +3373,11 @@ QString QString::right(int n) const
|
|||||||
|
|
||||||
QString QString::mid(int position, int n) const
|
QString QString::mid(int position, int n) const
|
||||||
{
|
{
|
||||||
if (d == &shared_null.str || position > d->size)
|
if (position > d->size)
|
||||||
return QString();
|
return QString();
|
||||||
if (n < 0)
|
if (position < 0)
|
||||||
n = d->size - position;
|
|
||||||
if (position < 0) {
|
|
||||||
n += position;
|
|
||||||
position = 0;
|
position = 0;
|
||||||
}
|
if (n < 0 || n > d->size - position)
|
||||||
if (n + position > d->size)
|
|
||||||
n = d->size - position;
|
n = d->size - position;
|
||||||
if (position == 0 && n == d->size)
|
if (position == 0 && n == d->size)
|
||||||
return *this;
|
return *this;
|
||||||
@ -3753,11 +3732,11 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size)
|
|||||||
size = qstrlen(str);
|
size = qstrlen(str);
|
||||||
d = static_cast<Data *>(::malloc(sizeof(Data) + (size+1) * sizeof(QChar)));
|
d = static_cast<Data *>(::malloc(sizeof(Data) + (size+1) * sizeof(QChar)));
|
||||||
Q_CHECK_PTR(d);
|
Q_CHECK_PTR(d);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->alloc = (uint) size;
|
d->alloc = (uint) size;
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
d->offset = 0;
|
d->offset = sizeof(QStringData);
|
||||||
d->data()[size] = '\0';
|
d->data()[size] = '\0';
|
||||||
ushort *dst = d->data();
|
ushort *dst = d->data();
|
||||||
/* SIMD:
|
/* SIMD:
|
||||||
@ -4765,7 +4744,7 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
|
|||||||
|
|
||||||
const ushort *QString::utf16() const
|
const ushort *QString::utf16() const
|
||||||
{
|
{
|
||||||
if (d->offset)
|
if (IS_RAW_DATA(d))
|
||||||
const_cast<QString*>(this)->realloc(); // ensure '\\0'-termination for ::fromRawData strings
|
const_cast<QString*>(this)->realloc(); // ensure '\\0'-termination for ::fromRawData strings
|
||||||
return d->data();
|
return d->data();
|
||||||
}
|
}
|
||||||
@ -7067,11 +7046,11 @@ QString QString::fromRawData(const QChar *unicode, int size)
|
|||||||
} else {
|
} else {
|
||||||
x = static_cast<Data *>(::malloc(sizeof(Data) + sizeof(ushort)));
|
x = static_cast<Data *>(::malloc(sizeof(Data) + sizeof(ushort)));
|
||||||
Q_CHECK_PTR(x);
|
Q_CHECK_PTR(x);
|
||||||
x->ref = 1;
|
x->ref.initializeOwned();
|
||||||
x->size = size;
|
x->size = size;
|
||||||
x->alloc = 0;
|
x->alloc = 0;
|
||||||
x->capacityReserved = false;
|
x->capacityReserved = false;
|
||||||
x->offset = (const ushort *)unicode - (x->d + sizeof(qptrdiff)/sizeof(ushort));
|
x->offset = reinterpret_cast<const char *>(unicode) - reinterpret_cast<char *>(x);
|
||||||
}
|
}
|
||||||
return QString(x, 0);
|
return QString(x, 0);
|
||||||
}
|
}
|
||||||
@ -7092,14 +7071,14 @@ QString QString::fromRawData(const QChar *unicode, int size)
|
|||||||
*/
|
*/
|
||||||
QString &QString::setRawData(const QChar *unicode, int size)
|
QString &QString::setRawData(const QChar *unicode, int size)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || d->alloc) {
|
if (d->ref.isShared() || d->alloc) {
|
||||||
*this = fromRawData(unicode, size);
|
*this = fromRawData(unicode, size);
|
||||||
} else {
|
} else {
|
||||||
if (unicode) {
|
if (unicode) {
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->offset = (const ushort *)unicode - (d->d + sizeof(qptrdiff)/sizeof(ushort));
|
d->offset = reinterpret_cast<const char *>(unicode) - reinterpret_cast<char *>(d);
|
||||||
} else {
|
} else {
|
||||||
d->offset = 0;
|
d->offset = sizeof(QStringData);
|
||||||
d->size = 0;
|
d->size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8059,15 +8038,11 @@ QStringRef QString::rightRef(int n) const
|
|||||||
|
|
||||||
QStringRef QString::midRef(int position, int n) const
|
QStringRef QString::midRef(int position, int n) const
|
||||||
{
|
{
|
||||||
if (d == &shared_null.str || position > d->size)
|
if (position > d->size)
|
||||||
return QStringRef();
|
return QStringRef();
|
||||||
if (n < 0)
|
if (position < 0)
|
||||||
n = d->size - position;
|
|
||||||
if (position < 0) {
|
|
||||||
n += position;
|
|
||||||
position = 0;
|
position = 0;
|
||||||
}
|
if (n < 0 || n > d->size - position)
|
||||||
if (n + position > d->size)
|
|
||||||
n = d->size - position;
|
n = d->size - position;
|
||||||
return QStringRef(this, position, n);
|
return QStringRef(this, position, n);
|
||||||
}
|
}
|
||||||
|
@ -75,25 +75,24 @@ struct QStringData {
|
|||||||
int size;
|
int size;
|
||||||
uint alloc : 31;
|
uint alloc : 31;
|
||||||
uint capacityReserved : 1;
|
uint capacityReserved : 1;
|
||||||
union {
|
|
||||||
qptrdiff offset; // will always work as we add/subtract from a ushort ptr
|
qptrdiff offset;
|
||||||
ushort d[sizeof(qptrdiff)/sizeof(ushort)];
|
|
||||||
};
|
inline ushort *data() { return reinterpret_cast<ushort *>(reinterpret_cast<char *>(this) + offset); }
|
||||||
inline ushort *data() { return d + sizeof(qptrdiff)/sizeof(ushort) + offset; }
|
inline const ushort *data() const { return reinterpret_cast<const ushort *>(reinterpret_cast<const char *>(this) + offset); }
|
||||||
inline const ushort *data() const { return d + sizeof(qptrdiff)/sizeof(ushort) + offset; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N> struct QConstStringData;
|
template<int N> struct QStaticStringData;
|
||||||
template<int N> struct QConstStringDataPtr
|
template<int N> struct QStaticStringDataPtr
|
||||||
{
|
{
|
||||||
const QConstStringData<N> *ptr;
|
const QStaticStringData<N> *ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(Q_COMPILER_UNICODE_STRINGS)
|
#if defined(Q_COMPILER_UNICODE_STRINGS)
|
||||||
template<int N> struct QConstStringData
|
template<int N> struct QStaticStringData
|
||||||
{
|
{
|
||||||
const QStringData str;
|
QStringData str;
|
||||||
const char16_t data[N + 1];
|
char16_t data[N + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QT_UNICODE_LITERAL_II(str) u"" str
|
#define QT_UNICODE_LITERAL_II(str) u"" str
|
||||||
@ -102,10 +101,10 @@ template<int N> struct QConstStringData
|
|||||||
|| (defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2) \
|
|| (defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2) \
|
||||||
|| (!defined(__SIZEOF_WCHAR_T__) && defined(WCHAR_MAX) && (WCHAR_MAX - 0 < 65536))
|
|| (!defined(__SIZEOF_WCHAR_T__) && defined(WCHAR_MAX) && (WCHAR_MAX - 0 < 65536))
|
||||||
// wchar_t is 2 bytes
|
// wchar_t is 2 bytes
|
||||||
template<int N> struct QConstStringData
|
template<int N> struct QStaticStringData
|
||||||
{
|
{
|
||||||
const QStringData str;
|
QStringData str;
|
||||||
const wchar_t data[N + 1];
|
wchar_t data[N + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(Q_CC_MSVC)
|
#if defined(Q_CC_MSVC)
|
||||||
@ -115,21 +114,21 @@ template<int N> struct QConstStringData
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
template<int N> struct QConstStringData
|
template<int N> struct QStaticStringData
|
||||||
{
|
{
|
||||||
const QStringData str;
|
QStringData str;
|
||||||
const ushort data[N + 1];
|
ushort data[N + 1];
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(QT_UNICODE_LITERAL_II)
|
#if defined(QT_UNICODE_LITERAL_II)
|
||||||
# define QT_UNICODE_LITERAL(str) QT_UNICODE_LITERAL_II(str)
|
# define QT_UNICODE_LITERAL(str) QT_UNICODE_LITERAL_II(str)
|
||||||
# if defined(Q_COMPILER_LAMBDA)
|
# if defined(Q_COMPILER_LAMBDA)
|
||||||
# define QStringLiteral(str) ([]() -> QConstStringDataPtr<sizeof(QT_UNICODE_LITERAL(str))/2 - 1> { \
|
# define QStringLiteral(str) ([]() -> QStaticStringDataPtr<sizeof(QT_UNICODE_LITERAL(str))/2 - 1> { \
|
||||||
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
|
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
|
||||||
static const QConstStringData<Size> qstring_literal = \
|
static const QStaticStringData<Size> qstring_literal = \
|
||||||
{ { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, QT_UNICODE_LITERAL(str) }; \
|
{ { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, sizeof(QStringData) }, QT_UNICODE_LITERAL(str) }; \
|
||||||
QConstStringDataPtr<Size> holder = { &qstring_literal }; \
|
QStaticStringDataPtr<Size> holder = { &qstring_literal }; \
|
||||||
return holder; }())
|
return holder; }())
|
||||||
|
|
||||||
# elif defined(Q_CC_GNU)
|
# elif defined(Q_CC_GNU)
|
||||||
@ -140,9 +139,9 @@ template<int N> struct QConstStringData
|
|||||||
# define QStringLiteral(str) \
|
# define QStringLiteral(str) \
|
||||||
__extension__ ({ \
|
__extension__ ({ \
|
||||||
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
|
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
|
||||||
static const QConstStringData<Size> qstring_literal = \
|
static const QStaticStringData<Size> qstring_literal = \
|
||||||
{ { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, QT_UNICODE_LITERAL(str) }; \
|
{ { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, sizeof(QStringData) }, QT_UNICODE_LITERAL(str) }; \
|
||||||
QConstStringDataPtr<Size> holder = { &qstring_literal }; \
|
QStaticStringDataPtr<Size> holder = { &qstring_literal }; \
|
||||||
holder; })
|
holder; })
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
@ -160,8 +159,7 @@ public:
|
|||||||
typedef QStringData Data;
|
typedef QStringData Data;
|
||||||
|
|
||||||
inline QString();
|
inline QString();
|
||||||
QString(const QChar *unicode, int size); // Qt5: don't cap size < 0
|
explicit QString(const QChar *unicode, int size = -1);
|
||||||
explicit QString(const QChar *unicode); // Qt5: merge with the above
|
|
||||||
QString(QChar c);
|
QString(QChar c);
|
||||||
QString(int size, QChar c);
|
QString(int size, QChar c);
|
||||||
inline QString(const QLatin1String &latin1);
|
inline QString(const QLatin1String &latin1);
|
||||||
@ -340,7 +338,7 @@ public:
|
|||||||
inline QString &prepend(const QLatin1String &s) { return insert(0, s); }
|
inline QString &prepend(const QLatin1String &s) { return insert(0, s); }
|
||||||
|
|
||||||
inline QString &operator+=(QChar c) {
|
inline QString &operator+=(QChar c) {
|
||||||
if (d->ref != 1 || d->size + 1 > int(d->alloc))
|
if (d->ref.isShared() || d->size + 1 > int(d->alloc))
|
||||||
realloc(grow(d->size + 1));
|
realloc(grow(d->size + 1));
|
||||||
d->data()[d->size++] = c.unicode();
|
d->data()[d->size++] = c.unicode();
|
||||||
d->data()[d->size] = '\0';
|
d->data()[d->size] = '\0';
|
||||||
@ -592,9 +590,9 @@ public:
|
|||||||
|
|
||||||
QString(int size, Qt::Initialization);
|
QString(int size, Qt::Initialization);
|
||||||
template <int n>
|
template <int n>
|
||||||
inline QString(const QConstStringData<n> &dd) : d(const_cast<QStringData *>(&dd.str)) {}
|
inline QString(const QStaticStringData<n> &dd) : d(const_cast<QStringData *>(&dd.str)) {}
|
||||||
template <int N>
|
template <int N>
|
||||||
Q_DECL_CONSTEXPR inline QString(QConstStringDataPtr<N> dd) : d(const_cast<QStringData *>(&dd.ptr->str)) {}
|
Q_DECL_CONSTEXPR inline QString(QStaticStringDataPtr<N> dd) : d(const_cast<QStringData *>(&dd.ptr->str)) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED)
|
#if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED)
|
||||||
@ -606,8 +604,8 @@ private:
|
|||||||
QString &operator=(const QByteArray &a);
|
QString &operator=(const QByteArray &a);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const QConstStringData<1> shared_null;
|
static const QStaticStringData<1> shared_null;
|
||||||
static const QConstStringData<1> shared_empty;
|
static const QStaticStringData<1> shared_empty;
|
||||||
Data *d;
|
Data *d;
|
||||||
inline QString(Data *dd, int /*dummy*/) : d(dd) {}
|
inline QString(Data *dd, int /*dummy*/) : d(dd) {}
|
||||||
|
|
||||||
@ -709,9 +707,9 @@ inline QChar *QString::data()
|
|||||||
inline const QChar *QString::constData() const
|
inline const QChar *QString::constData() const
|
||||||
{ return reinterpret_cast<const QChar*>(d->data()); }
|
{ return reinterpret_cast<const QChar*>(d->data()); }
|
||||||
inline void QString::detach()
|
inline void QString::detach()
|
||||||
{ if (d->ref != 1 || d->offset) realloc(); }
|
{ if (d->ref.isShared() || (d->offset != sizeof(QStringData))) realloc(); }
|
||||||
inline bool QString::isDetached() const
|
inline bool QString::isDetached() const
|
||||||
{ return d->ref == 1; }
|
{ return !d->ref.isShared(); }
|
||||||
inline QString &QString::operator=(const QLatin1String &s)
|
inline QString &QString::operator=(const QLatin1String &s)
|
||||||
{
|
{
|
||||||
*this = fromLatin1(s.latin1(), s.size());
|
*this = fromLatin1(s.latin1(), s.size());
|
||||||
@ -874,7 +872,7 @@ inline QString::~QString() { if (!d->ref.deref()) free(d); }
|
|||||||
|
|
||||||
inline void QString::reserve(int asize)
|
inline void QString::reserve(int asize)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || asize > int(d->alloc))
|
if (d->ref.isShared() || asize > int(d->alloc))
|
||||||
realloc(asize);
|
realloc(asize);
|
||||||
|
|
||||||
if (!d->capacityReserved) {
|
if (!d->capacityReserved) {
|
||||||
@ -885,11 +883,12 @@ inline void QString::reserve(int asize)
|
|||||||
|
|
||||||
inline void QString::squeeze()
|
inline void QString::squeeze()
|
||||||
{
|
{
|
||||||
if (d->ref > 1 || d->size < int(d->alloc))
|
if (d->ref.isShared() || d->size < int(d->alloc))
|
||||||
realloc();
|
realloc();
|
||||||
|
|
||||||
if (d->capacityReserved) {
|
if (d->capacityReserved) {
|
||||||
// cannot set unconditionally, since d could be the shared_null/shared_empty (which is const)
|
// cannot set unconditionally, since d could be shared_null or
|
||||||
|
// otherwise static.
|
||||||
d->capacityReserved = false;
|
d->capacityReserved = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,9 +219,9 @@ template <> struct QConcatenable<QString> : private QAbstractConcatenable
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int N> struct QConcatenable<QConstStringDataPtr<N> > : private QAbstractConcatenable
|
template <int N> struct QConcatenable<QStaticStringDataPtr<N> > : private QAbstractConcatenable
|
||||||
{
|
{
|
||||||
typedef QConstStringDataPtr<N> type;
|
typedef QStaticStringDataPtr<N> type;
|
||||||
typedef QString ConvertTo;
|
typedef QString ConvertTo;
|
||||||
enum { ExactSize = true };
|
enum { ExactSize = true };
|
||||||
static int size(const type &) { return N; }
|
static int size(const type &) { return N; }
|
||||||
@ -324,9 +324,9 @@ template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int N> struct QConcatenable<QConstByteArrayDataPtr<N> > : private QAbstractConcatenable
|
template <int N> struct QConcatenable<QStaticByteArrayDataPtr<N> > : private QAbstractConcatenable
|
||||||
{
|
{
|
||||||
typedef QConstByteArrayDataPtr<N> type;
|
typedef QStaticByteArrayDataPtr<N> type;
|
||||||
typedef QByteArray ConvertTo;
|
typedef QByteArray ConvertTo;
|
||||||
enum { ExactSize = false };
|
enum { ExactSize = false };
|
||||||
static int size(const type &) { return N; }
|
static int size(const type &) { return N; }
|
||||||
@ -338,9 +338,8 @@ template <int N> struct QConcatenable<QConstByteArrayDataPtr<N> > : private QAbs
|
|||||||
#endif
|
#endif
|
||||||
static inline void appendTo(const type &ba, char *&out)
|
static inline void appendTo(const type &ba, char *&out)
|
||||||
{
|
{
|
||||||
const char *a = ba.ptr->data;
|
::memcpy(out, ba.ptr->data, N);
|
||||||
while (*a)
|
out += N;
|
||||||
*out++ = *a++;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,15 +54,7 @@ static inline int alignmentThreshold()
|
|||||||
return 2 * sizeof(void*);
|
return 2 * sizeof(void*);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVectorData QVectorData::shared_null = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, true, false, 0 };
|
const QVectorData QVectorData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, false, 0 };
|
||||||
|
|
||||||
QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init)
|
|
||||||
{
|
|
||||||
QVectorData* p = (QVectorData *)::malloc(sizeofTypedData + (size - 1) * sizeofT);
|
|
||||||
Q_CHECK_PTR(p);
|
|
||||||
::memcpy(p, init, sizeofTypedData + (qMin(size, init->alloc) - 1) * sizeofT);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVectorData *QVectorData::allocate(int size, int alignment)
|
QVectorData *QVectorData::allocate(int size, int alignment)
|
||||||
{
|
{
|
||||||
@ -84,11 +76,9 @@ void QVectorData::free(QVectorData *x, int alignment)
|
|||||||
::free(x);
|
::free(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
int QVectorData::grow(int sizeofTypedData, int size, int sizeofT, bool excessive)
|
int QVectorData::grow(int sizeOfHeader, int size, int sizeOfT)
|
||||||
{
|
{
|
||||||
if (excessive)
|
return qAllocMore(size * sizeOfT, sizeOfHeader) / sizeOfT;
|
||||||
return size + size / 2;
|
|
||||||
return qAllocMore(size * sizeofT, sizeofTypedData - sizeofT) / sizeofT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -65,37 +65,28 @@ QT_BEGIN_NAMESPACE
|
|||||||
struct Q_CORE_EXPORT QVectorData
|
struct Q_CORE_EXPORT QVectorData
|
||||||
{
|
{
|
||||||
QtPrivate::RefCount ref;
|
QtPrivate::RefCount ref;
|
||||||
int alloc;
|
|
||||||
int size;
|
int size;
|
||||||
#if defined(Q_PROCESSOR_SPARC) && defined(Q_CC_GNU) && defined(__LP64__) && defined(QT_BOOTSTRAPPED)
|
uint alloc : 31;
|
||||||
// workaround for bug in gcc 3.4.2
|
uint capacityReserved : 1;
|
||||||
uint sharable;
|
|
||||||
uint capacity;
|
qptrdiff offset;
|
||||||
uint reserved;
|
|
||||||
#else
|
void* data() { return reinterpret_cast<char *>(this) + this->offset; }
|
||||||
uint sharable : 1;
|
|
||||||
uint capacity : 1;
|
|
||||||
uint reserved : 30;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const QVectorData shared_null;
|
static const QVectorData shared_null;
|
||||||
// ### Qt 5: rename to 'allocate()'. The current name causes problems for
|
|
||||||
// some debugges when the QVector is member of a class within an unnamed namespace.
|
|
||||||
// ### Qt 5: can be removed completely. (Ralf)
|
|
||||||
static QVectorData *malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init);
|
|
||||||
static QVectorData *allocate(int size, int alignment);
|
static QVectorData *allocate(int size, int alignment);
|
||||||
static QVectorData *reallocate(QVectorData *old, int newsize, int oldsize, int alignment);
|
static QVectorData *reallocate(QVectorData *old, int newsize, int oldsize, int alignment);
|
||||||
static void free(QVectorData *data, int alignment);
|
static void free(QVectorData *data, int alignment);
|
||||||
static int grow(int sizeofTypedData, int size, int sizeofT, bool excessive);
|
static int grow(int sizeOfHeader, int size, int sizeOfT);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct QVectorTypedData : private QVectorData
|
struct QVectorTypedData : QVectorData
|
||||||
{ // private inheritance as we must not access QVectorData member thought QVectorTypedData
|
{
|
||||||
// as this would break strict aliasing rules. (in the case of shared_null)
|
T* begin() { return reinterpret_cast<T *>(this->data()); }
|
||||||
T array[1];
|
T* end() { return begin() + this->size; }
|
||||||
|
|
||||||
static inline void free(QVectorTypedData<T> *x, int alignment) { QVectorData::free(static_cast<QVectorData *>(x), alignment); }
|
static QVectorTypedData *sharedNull() { return static_cast<QVectorTypedData *>(const_cast<QVectorData *>(&QVectorData::shared_null)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class QRegion;
|
class QRegion;
|
||||||
@ -104,27 +95,30 @@ template <typename T>
|
|||||||
class QVector
|
class QVector
|
||||||
{
|
{
|
||||||
typedef QVectorTypedData<T> Data;
|
typedef QVectorTypedData<T> Data;
|
||||||
union {
|
Data *d;
|
||||||
QVectorData *d;
|
|
||||||
#if defined(Q_CC_SUN) && (__SUNPRO_CC <= 0x550)
|
|
||||||
QVectorTypedData<T> *p;
|
|
||||||
#else
|
|
||||||
Data *p;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// ### Qt 5: Consider making QVector non-shared to get at least one
|
inline QVector() : d(Data::sharedNull()) { }
|
||||||
// "really fast" container. See tests/benchmarks/corelib/tools/qvector/
|
|
||||||
inline QVector() : d(const_cast<QVectorData *>(&QVectorData::shared_null)) { }
|
|
||||||
explicit QVector(int size);
|
explicit QVector(int size);
|
||||||
QVector(int size, const T &t);
|
QVector(int size, const T &t);
|
||||||
inline QVector(const QVector<T> &v) : d(v.d) { d->ref.ref(); if (!d->sharable) detach_helper(); }
|
inline QVector(const QVector<T> &v)
|
||||||
inline ~QVector() { if (!d) return; if (!d->ref.deref()) free(p); }
|
{
|
||||||
|
if (v.d->ref.ref()) {
|
||||||
|
d = v.d;
|
||||||
|
} else {
|
||||||
|
d = Data::sharedNull();
|
||||||
|
realloc(0, int(v.d->alloc));
|
||||||
|
qCopy(v.d->begin(), v.d->end(), d->begin());
|
||||||
|
d->size = v.d->size;
|
||||||
|
d->capacityReserved = v.d->capacityReserved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ~QVector() { if (!d->ref.deref()) free(d); }
|
||||||
QVector<T> &operator=(const QVector<T> &v);
|
QVector<T> &operator=(const QVector<T> &v);
|
||||||
#ifdef Q_COMPILER_RVALUE_REFS
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
inline QVector<T> operator=(QVector<T> &&other)
|
inline QVector<T> operator=(QVector<T> &&other)
|
||||||
{ qSwap(p, other.p); return *this; }
|
{ qSwap(d, other.d); return *this; }
|
||||||
#endif
|
#endif
|
||||||
inline void swap(QVector<T> &other) { qSwap(d, other.d); }
|
inline void swap(QVector<T> &other) { qSwap(d, other.d); }
|
||||||
#ifdef Q_COMPILER_INITIALIZER_LISTS
|
#ifdef Q_COMPILER_INITIALIZER_LISTS
|
||||||
@ -139,18 +133,27 @@ public:
|
|||||||
|
|
||||||
void resize(int size);
|
void resize(int size);
|
||||||
|
|
||||||
inline int capacity() const { return d->alloc; }
|
inline int capacity() const { return int(d->alloc); }
|
||||||
void reserve(int size);
|
void reserve(int size);
|
||||||
inline void squeeze() { realloc(d->size, d->size); d->capacity = 0; }
|
inline void squeeze() { realloc(d->size, d->size); d->capacityReserved = 0; }
|
||||||
|
|
||||||
|
inline void detach() { if (!isDetached()) detach_helper(); }
|
||||||
|
inline bool isDetached() const { return !d->ref.isShared(); }
|
||||||
|
inline void setSharable(bool sharable)
|
||||||
|
{
|
||||||
|
if (sharable == d->ref.isSharable())
|
||||||
|
return;
|
||||||
|
if (!sharable)
|
||||||
|
detach();
|
||||||
|
if (d != Data::sharedNull())
|
||||||
|
d->ref.setSharable(sharable);
|
||||||
|
}
|
||||||
|
|
||||||
inline void detach() { if (d->ref != 1) detach_helper(); }
|
|
||||||
inline bool isDetached() const { return d->ref == 1; }
|
|
||||||
inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QVectorData::shared_null) d->sharable = sharable; }
|
|
||||||
inline bool isSharedWith(const QVector<T> &other) const { return d == other.d; }
|
inline bool isSharedWith(const QVector<T> &other) const { return d == other.d; }
|
||||||
|
|
||||||
inline T *data() { detach(); return p->array; }
|
inline T *data() { detach(); return d->begin(); }
|
||||||
inline const T *data() const { return p->array; }
|
inline const T *data() const { return d->begin(); }
|
||||||
inline const T *constData() const { return p->array; }
|
inline const T *constData() const { return d->begin(); }
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
const T &at(int i) const;
|
const T &at(int i) const;
|
||||||
@ -243,12 +246,12 @@ public:
|
|||||||
typedef T* iterator;
|
typedef T* iterator;
|
||||||
typedef const T* const_iterator;
|
typedef const T* const_iterator;
|
||||||
#endif
|
#endif
|
||||||
inline iterator begin() { detach(); return p->array; }
|
inline iterator begin() { detach(); return d->begin(); }
|
||||||
inline const_iterator begin() const { return p->array; }
|
inline const_iterator begin() const { return d->begin(); }
|
||||||
inline const_iterator constBegin() const { return p->array; }
|
inline const_iterator constBegin() const { return d->begin(); }
|
||||||
inline iterator end() { detach(); return p->array + d->size; }
|
inline iterator end() { detach(); return d->end(); }
|
||||||
inline const_iterator end() const { return p->array + d->size; }
|
inline const_iterator end() const { return d->end(); }
|
||||||
inline const_iterator constEnd() const { return p->array + d->size; }
|
inline const_iterator constEnd() const { return d->end(); }
|
||||||
iterator insert(iterator before, int n, const T &x);
|
iterator insert(iterator before, int n, const T &x);
|
||||||
inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
|
inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
|
||||||
iterator erase(iterator begin, iterator end);
|
iterator erase(iterator begin, iterator end);
|
||||||
@ -313,46 +316,49 @@ private:
|
|||||||
friend class QRegion; // Optimization for QRegion::rects()
|
friend class QRegion; // Optimization for QRegion::rects()
|
||||||
|
|
||||||
void detach_helper();
|
void detach_helper();
|
||||||
QVectorData *malloc(int alloc);
|
Data *malloc(int alloc);
|
||||||
void realloc(int size, int alloc);
|
void realloc(int size, int alloc);
|
||||||
void free(Data *d);
|
void free(Data *d);
|
||||||
int sizeOfTypedData() {
|
|
||||||
// this is more or less the same as sizeof(Data), except that it doesn't
|
class AlignmentDummy { QVectorData header; T array[1]; };
|
||||||
// count the padding at the end
|
|
||||||
return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
|
static Q_DECL_CONSTEXPR int offsetOfTypedData()
|
||||||
|
{
|
||||||
|
// (non-POD)-safe offsetof(AlignmentDummy, array)
|
||||||
|
return (sizeof(QVectorData) + (alignOfTypedData() - 1)) & ~(alignOfTypedData() - 1);
|
||||||
}
|
}
|
||||||
inline int alignOfTypedData() const
|
static Q_DECL_CONSTEXPR int alignOfTypedData()
|
||||||
{
|
{
|
||||||
#ifdef Q_ALIGNOF
|
#ifdef Q_ALIGNOF
|
||||||
return qMax<int>(sizeof(void*), Q_ALIGNOF(Data));
|
return Q_ALIGNOF(AlignmentDummy);
|
||||||
#else
|
#else
|
||||||
return 0;
|
return sizeof(void *);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void QVector<T>::detach_helper()
|
void QVector<T>::detach_helper()
|
||||||
{ realloc(d->size, d->alloc); }
|
{ realloc(d->size, int(d->alloc)); }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void QVector<T>::reserve(int asize)
|
void QVector<T>::reserve(int asize)
|
||||||
{ if (asize > d->alloc) realloc(d->size, asize); if (d->ref == 1) d->capacity = 1; }
|
{ if (asize > int(d->alloc)) realloc(d->size, asize); if (isDetached()) d->capacityReserved = 1; }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void QVector<T>::resize(int asize)
|
void QVector<T>::resize(int asize)
|
||||||
{ realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ?
|
{ realloc(asize, (asize > int(d->alloc) || (!d->capacityReserved && asize < d->size && asize < int(d->alloc >> 1))) ?
|
||||||
QVectorData::grow(sizeOfTypedData(), asize, sizeof(T), QTypeInfo<T>::isStatic)
|
QVectorData::grow(offsetOfTypedData(), asize, sizeof(T))
|
||||||
: d->alloc); }
|
: int(d->alloc)); }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void QVector<T>::clear()
|
inline void QVector<T>::clear()
|
||||||
{ *this = QVector<T>(); }
|
{ *this = QVector<T>(); }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline const T &QVector<T>::at(int i) const
|
inline const T &QVector<T>::at(int i) const
|
||||||
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::at", "index out of range");
|
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::at", "index out of range");
|
||||||
return p->array[i]; }
|
return d->begin()[i]; }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline const T &QVector<T>::operator[](int i) const
|
inline const T &QVector<T>::operator[](int i) const
|
||||||
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
|
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
|
||||||
return p->array[i]; }
|
return d->begin()[i]; }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T &QVector<T>::operator[](int i)
|
inline T &QVector<T>::operator[](int i)
|
||||||
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
|
{ Q_ASSERT_X(i >= 0 && i < d->size, "QVector<T>::operator[]", "index out of range");
|
||||||
@ -388,39 +394,37 @@ inline void QVector<T>::replace(int i, const T &t)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
QVector<T> &QVector<T>::operator=(const QVector<T> &v)
|
QVector<T> &QVector<T>::operator=(const QVector<T> &v)
|
||||||
{
|
{
|
||||||
QVectorData *o = v.d;
|
if (v.d != d) {
|
||||||
o->ref.ref();
|
QVector<T> tmp(v);
|
||||||
if (!d->ref.deref())
|
tmp.swap(*this);
|
||||||
free(p);
|
}
|
||||||
d = o;
|
|
||||||
if (!d->sharable)
|
|
||||||
detach_helper();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline QVectorData *QVector<T>::malloc(int aalloc)
|
inline typename QVector<T>::Data *QVector<T>::malloc(int aalloc)
|
||||||
{
|
{
|
||||||
QVectorData *vectordata = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData());
|
QVectorData *vectordata = QVectorData::allocate(offsetOfTypedData() + aalloc * sizeof(T), alignOfTypedData());
|
||||||
Q_CHECK_PTR(vectordata);
|
Q_CHECK_PTR(vectordata);
|
||||||
return vectordata;
|
return static_cast<Data *>(vectordata);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
QVector<T>::QVector(int asize)
|
QVector<T>::QVector(int asize)
|
||||||
{
|
{
|
||||||
d = malloc(asize);
|
d = malloc(asize);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->alloc = d->size = asize;
|
d->size = asize;
|
||||||
d->sharable = true;
|
d->alloc = uint(d->size);
|
||||||
d->capacity = false;
|
d->capacityReserved = false;
|
||||||
|
d->offset = offsetOfTypedData();
|
||||||
if (QTypeInfo<T>::isComplex) {
|
if (QTypeInfo<T>::isComplex) {
|
||||||
T* b = p->array;
|
T* b = d->begin();
|
||||||
T* i = p->array + d->size;
|
T* i = d->end();
|
||||||
while (i != b)
|
while (i != b)
|
||||||
new (--i) T;
|
new (--i) T;
|
||||||
} else {
|
} else {
|
||||||
qMemSet(p->array, 0, asize * sizeof(T));
|
qMemSet(d->begin(), 0, asize * sizeof(T));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,12 +432,13 @@ template <typename T>
|
|||||||
QVector<T>::QVector(int asize, const T &t)
|
QVector<T>::QVector(int asize, const T &t)
|
||||||
{
|
{
|
||||||
d = malloc(asize);
|
d = malloc(asize);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->alloc = d->size = asize;
|
d->size = asize;
|
||||||
d->sharable = true;
|
d->alloc = uint(d->size);
|
||||||
d->capacity = false;
|
d->capacityReserved = false;
|
||||||
T* i = p->array + d->size;
|
d->offset = offsetOfTypedData();
|
||||||
while (i != p->array)
|
T* i = d->end();
|
||||||
|
while (i != d->begin())
|
||||||
new (--i) T(t);
|
new (--i) T(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,14 +447,22 @@ template <typename T>
|
|||||||
QVector<T>::QVector(std::initializer_list<T> args)
|
QVector<T>::QVector(std::initializer_list<T> args)
|
||||||
{
|
{
|
||||||
d = malloc(int(args.size()));
|
d = malloc(int(args.size()));
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->alloc = d->size = int(args.size());
|
d->size = int(args.size());
|
||||||
d->sharable = true;
|
d->alloc = uint(d->size);
|
||||||
d->capacity = false;
|
d->capacityReserved = false;
|
||||||
T* i = p->array + d->size;
|
d->offset = offsetOfTypedData();
|
||||||
auto it = args.end();
|
if (QTypeInfo<T>::isComplex) {
|
||||||
while (i != p->array)
|
T* b = d->begin();
|
||||||
new (--i) T(*(--it));
|
T* i = d->end();
|
||||||
|
const T* s = args.end();
|
||||||
|
while (i != b)
|
||||||
|
new(--i) T(*--s);
|
||||||
|
} else {
|
||||||
|
// std::initializer_list<T>::iterator is guaranteed to be
|
||||||
|
// const T* ([support.initlist]/1), so can be memcpy'ed away from:
|
||||||
|
::memcpy(d->begin(), args.begin(), args.size() * sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -457,14 +470,12 @@ template <typename T>
|
|||||||
void QVector<T>::free(Data *x)
|
void QVector<T>::free(Data *x)
|
||||||
{
|
{
|
||||||
if (QTypeInfo<T>::isComplex) {
|
if (QTypeInfo<T>::isComplex) {
|
||||||
T* b = x->array;
|
T* b = x->begin();
|
||||||
union { QVectorData *d; Data *p; } u;
|
T* i = b + x->size;
|
||||||
u.p = x;
|
|
||||||
T* i = b + u.d->size;
|
|
||||||
while (i-- != b)
|
while (i-- != b)
|
||||||
i->~T();
|
i->~T();
|
||||||
}
|
}
|
||||||
x->free(x, alignOfTypedData());
|
Data::free(x, alignOfTypedData());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -473,84 +484,82 @@ void QVector<T>::realloc(int asize, int aalloc)
|
|||||||
Q_ASSERT(asize <= aalloc);
|
Q_ASSERT(asize <= aalloc);
|
||||||
T *pOld;
|
T *pOld;
|
||||||
T *pNew;
|
T *pNew;
|
||||||
union { QVectorData *d; Data *p; } x;
|
Data *x = d;
|
||||||
x.d = d;
|
|
||||||
|
|
||||||
if (QTypeInfo<T>::isComplex && asize < d->size && d->ref == 1 ) {
|
if (QTypeInfo<T>::isComplex && asize < d->size && isDetached()) {
|
||||||
// call the destructor on all objects that need to be
|
// call the destructor on all objects that need to be
|
||||||
// destroyed when shrinking
|
// destroyed when shrinking
|
||||||
pOld = p->array + d->size;
|
pOld = d->begin() + d->size;
|
||||||
pNew = p->array + asize;
|
pNew = d->begin() + asize;
|
||||||
while (asize < d->size) {
|
while (asize < d->size) {
|
||||||
(--pOld)->~T();
|
(--pOld)->~T();
|
||||||
d->size--;
|
d->size--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aalloc != d->alloc || d->ref != 1) {
|
if (aalloc != int(d->alloc) || !isDetached()) {
|
||||||
// (re)allocate memory
|
// (re)allocate memory
|
||||||
if (QTypeInfo<T>::isStatic) {
|
if (QTypeInfo<T>::isStatic) {
|
||||||
x.d = malloc(aalloc);
|
x = malloc(aalloc);
|
||||||
Q_CHECK_PTR(x.p);
|
Q_CHECK_PTR(x);
|
||||||
x.d->size = 0;
|
x->size = 0;
|
||||||
} else if (d->ref != 1) {
|
} else if (!isDetached()) {
|
||||||
x.d = malloc(aalloc);
|
x = malloc(aalloc);
|
||||||
Q_CHECK_PTR(x.p);
|
Q_CHECK_PTR(x);
|
||||||
if (QTypeInfo<T>::isComplex) {
|
if (QTypeInfo<T>::isComplex) {
|
||||||
x.d->size = 0;
|
x->size = 0;
|
||||||
} else {
|
} else {
|
||||||
::memcpy(x.p, p, sizeOfTypedData() + (qMin(aalloc, d->alloc) - 1) * sizeof(T));
|
::memcpy(x, d, offsetOfTypedData() + qMin(uint(aalloc), d->alloc) * sizeof(T));
|
||||||
x.d->size = d->size;
|
x->size = d->size;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QT_TRY {
|
QT_TRY {
|
||||||
QVectorData *mem = QVectorData::reallocate(d, sizeOfTypedData() + (aalloc - 1) * sizeof(T),
|
QVectorData *mem = QVectorData::reallocate(d, offsetOfTypedData() + aalloc * sizeof(T),
|
||||||
sizeOfTypedData() + (d->alloc - 1) * sizeof(T), alignOfTypedData());
|
offsetOfTypedData() + d->alloc * sizeof(T), alignOfTypedData());
|
||||||
Q_CHECK_PTR(mem);
|
Q_CHECK_PTR(mem);
|
||||||
x.d = d = mem;
|
x = d = static_cast<Data *>(mem);
|
||||||
x.d->size = d->size;
|
x->size = d->size;
|
||||||
} QT_CATCH (const std::bad_alloc &) {
|
} QT_CATCH (const std::bad_alloc &) {
|
||||||
if (aalloc > d->alloc) // ignore the error in case we are just shrinking.
|
if (aalloc > int(d->alloc)) // ignore the error in case we are just shrinking.
|
||||||
QT_RETHROW;
|
QT_RETHROW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x.d->ref = 1;
|
x->ref.initializeOwned();
|
||||||
x.d->alloc = aalloc;
|
x->alloc = uint(aalloc);
|
||||||
x.d->sharable = true;
|
x->capacityReserved = d->capacityReserved;
|
||||||
x.d->capacity = d->capacity;
|
x->offset = offsetOfTypedData();
|
||||||
x.d->reserved = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QTypeInfo<T>::isComplex) {
|
if (QTypeInfo<T>::isComplex) {
|
||||||
QT_TRY {
|
QT_TRY {
|
||||||
pOld = p->array + x.d->size;
|
pOld = d->begin() + x->size;
|
||||||
pNew = x.p->array + x.d->size;
|
pNew = x->begin() + x->size;
|
||||||
// copy objects from the old array into the new array
|
// copy objects from the old array into the new array
|
||||||
const int toMove = qMin(asize, d->size);
|
const int toMove = qMin(asize, d->size);
|
||||||
while (x.d->size < toMove) {
|
while (x->size < toMove) {
|
||||||
new (pNew++) T(*pOld++);
|
new (pNew++) T(*pOld++);
|
||||||
x.d->size++;
|
x->size++;
|
||||||
}
|
}
|
||||||
// construct all new objects when growing
|
// construct all new objects when growing
|
||||||
while (x.d->size < asize) {
|
while (x->size < asize) {
|
||||||
new (pNew++) T;
|
new (pNew++) T;
|
||||||
x.d->size++;
|
x->size++;
|
||||||
}
|
}
|
||||||
} QT_CATCH (...) {
|
} QT_CATCH (...) {
|
||||||
free(x.p);
|
free(x);
|
||||||
QT_RETHROW;
|
QT_RETHROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (asize > x.d->size) {
|
} else if (asize > x->size) {
|
||||||
// initialize newly allocated memory to 0
|
// initialize newly allocated memory to 0
|
||||||
qMemSet(x.p->array + x.d->size, 0, (asize - x.d->size) * sizeof(T));
|
qMemSet(x->end(), 0, (asize - x->size) * sizeof(T));
|
||||||
}
|
}
|
||||||
x.d->size = asize;
|
x->size = asize;
|
||||||
|
|
||||||
if (d != x.d) {
|
if (d != x) {
|
||||||
if (!d->ref.deref())
|
if (!d->ref.deref())
|
||||||
free(p);
|
free(d);
|
||||||
d = x.d;
|
d = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,31 +569,31 @@ Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i) const
|
|||||||
if (i < 0 || i >= d->size) {
|
if (i < 0 || i >= d->size) {
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
return p->array[i];
|
return d->begin()[i];
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i, const T &defaultValue) const
|
Q_OUTOFLINE_TEMPLATE T QVector<T>::value(int i, const T &defaultValue) const
|
||||||
{
|
{
|
||||||
return ((i < 0 || i >= d->size) ? defaultValue : p->array[i]);
|
return ((i < 0 || i >= d->size) ? defaultValue : d->begin()[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void QVector<T>::append(const T &t)
|
void QVector<T>::append(const T &t)
|
||||||
{
|
{
|
||||||
if (d->ref != 1 || d->size + 1 > d->alloc) {
|
if (!isDetached() || d->size + 1 > int(d->alloc)) {
|
||||||
const T copy(t);
|
const T copy(t);
|
||||||
realloc(d->size, (d->size + 1 > d->alloc) ?
|
realloc(d->size, (d->size + 1 > int(d->alloc)) ?
|
||||||
QVectorData::grow(sizeOfTypedData(), d->size + 1, sizeof(T), QTypeInfo<T>::isStatic)
|
QVectorData::grow(offsetOfTypedData(), d->size + 1, sizeof(T))
|
||||||
: d->alloc);
|
: int(d->alloc));
|
||||||
if (QTypeInfo<T>::isComplex)
|
if (QTypeInfo<T>::isComplex)
|
||||||
new (p->array + d->size) T(copy);
|
new (d->end()) T(copy);
|
||||||
else
|
else
|
||||||
p->array[d->size] = copy;
|
*d->end() = copy;
|
||||||
} else {
|
} else {
|
||||||
if (QTypeInfo<T>::isComplex)
|
if (QTypeInfo<T>::isComplex)
|
||||||
new (p->array + d->size) T(t);
|
new (d->end()) T(t);
|
||||||
else
|
else
|
||||||
p->array[d->size] = t;
|
*d->end() = t;
|
||||||
}
|
}
|
||||||
++d->size;
|
++d->size;
|
||||||
}
|
}
|
||||||
@ -592,27 +601,26 @@ void QVector<T>::append(const T &t)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
|
typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
|
||||||
{
|
{
|
||||||
int offset = int(before - p->array);
|
int offset = int(before - d->begin());
|
||||||
if (n != 0) {
|
if (n != 0) {
|
||||||
const T copy(t);
|
const T copy(t);
|
||||||
if (d->ref != 1 || d->size + n > d->alloc)
|
if (!isDetached() || d->size + n > int(d->alloc))
|
||||||
realloc(d->size, QVectorData::grow(sizeOfTypedData(), d->size + n, sizeof(T),
|
realloc(d->size, QVectorData::grow(offsetOfTypedData(), d->size + n, sizeof(T)));
|
||||||
QTypeInfo<T>::isStatic));
|
|
||||||
if (QTypeInfo<T>::isStatic) {
|
if (QTypeInfo<T>::isStatic) {
|
||||||
T *b = p->array + d->size;
|
T *b = d->end();
|
||||||
T *i = p->array + d->size + n;
|
T *i = d->end() + n;
|
||||||
while (i != b)
|
while (i != b)
|
||||||
new (--i) T;
|
new (--i) T;
|
||||||
i = p->array + d->size;
|
i = d->end();
|
||||||
T *j = i + n;
|
T *j = i + n;
|
||||||
b = p->array + offset;
|
b = d->begin() + offset;
|
||||||
while (i != b)
|
while (i != b)
|
||||||
*--j = *--i;
|
*--j = *--i;
|
||||||
i = b+n;
|
i = b+n;
|
||||||
while (i != b)
|
while (i != b)
|
||||||
*--i = copy;
|
*--i = copy;
|
||||||
} else {
|
} else {
|
||||||
T *b = p->array + offset;
|
T *b = d->begin() + offset;
|
||||||
T *i = b + n;
|
T *i = b + n;
|
||||||
memmove(i, b, (d->size - offset) * sizeof(T));
|
memmove(i, b, (d->size - offset) * sizeof(T));
|
||||||
while (i != b)
|
while (i != b)
|
||||||
@ -620,29 +628,29 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
|
|||||||
}
|
}
|
||||||
d->size += n;
|
d->size += n;
|
||||||
}
|
}
|
||||||
return p->array + offset;
|
return d->begin() + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
|
typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
|
||||||
{
|
{
|
||||||
int f = int(abegin - p->array);
|
int f = int(abegin - d->begin());
|
||||||
int l = int(aend - p->array);
|
int l = int(aend - d->begin());
|
||||||
int n = l - f;
|
int n = l - f;
|
||||||
detach();
|
detach();
|
||||||
if (QTypeInfo<T>::isComplex) {
|
if (QTypeInfo<T>::isComplex) {
|
||||||
qCopy(p->array+l, p->array+d->size, p->array+f);
|
qCopy(d->begin()+l, d->end(), d->begin()+f);
|
||||||
T *i = p->array+d->size;
|
T *i = d->end();
|
||||||
T* b = p->array+d->size-n;
|
T* b = d->end()-n;
|
||||||
while (i != b) {
|
while (i != b) {
|
||||||
--i;
|
--i;
|
||||||
i->~T();
|
i->~T();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
memmove(p->array + f, p->array + l, (d->size-l)*sizeof(T));
|
memmove(d->begin() + f, d->begin() + l, (d->size-l)*sizeof(T));
|
||||||
}
|
}
|
||||||
d->size -= n;
|
d->size -= n;
|
||||||
return p->array + f;
|
return d->begin() + f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -652,9 +660,9 @@ bool QVector<T>::operator==(const QVector<T> &v) const
|
|||||||
return false;
|
return false;
|
||||||
if (d == v.d)
|
if (d == v.d)
|
||||||
return true;
|
return true;
|
||||||
T* b = p->array;
|
T* b = d->begin();
|
||||||
T* i = b + d->size;
|
T* i = b + d->size;
|
||||||
T* j = v.p->array + d->size;
|
T* j = v.d->end();
|
||||||
while (i != b)
|
while (i != b)
|
||||||
if (!(*--i == *--j))
|
if (!(*--i == *--j))
|
||||||
return false;
|
return false;
|
||||||
@ -667,8 +675,8 @@ QVector<T> &QVector<T>::fill(const T &from, int asize)
|
|||||||
const T copy(from);
|
const T copy(from);
|
||||||
resize(asize < 0 ? d->size : asize);
|
resize(asize < 0 ? d->size : asize);
|
||||||
if (d->size) {
|
if (d->size) {
|
||||||
T *i = p->array + d->size;
|
T *i = d->end();
|
||||||
T *b = p->array;
|
T *b = d->begin();
|
||||||
while (i != b)
|
while (i != b)
|
||||||
*--i = copy;
|
*--i = copy;
|
||||||
}
|
}
|
||||||
@ -681,9 +689,9 @@ QVector<T> &QVector<T>::operator+=(const QVector &l)
|
|||||||
int newSize = d->size + l.d->size;
|
int newSize = d->size + l.d->size;
|
||||||
realloc(d->size, newSize);
|
realloc(d->size, newSize);
|
||||||
|
|
||||||
T *w = p->array + newSize;
|
T *w = d->begin() + newSize;
|
||||||
T *i = l.p->array + l.d->size;
|
T *i = l.d->end();
|
||||||
T *b = l.p->array;
|
T *b = l.d->begin();
|
||||||
while (i != b) {
|
while (i != b) {
|
||||||
if (QTypeInfo<T>::isComplex)
|
if (QTypeInfo<T>::isComplex)
|
||||||
new (--w) T(*--i);
|
new (--w) T(*--i);
|
||||||
@ -700,11 +708,11 @@ int QVector<T>::indexOf(const T &t, int from) const
|
|||||||
if (from < 0)
|
if (from < 0)
|
||||||
from = qMax(from + d->size, 0);
|
from = qMax(from + d->size, 0);
|
||||||
if (from < d->size) {
|
if (from < d->size) {
|
||||||
T* n = p->array + from - 1;
|
T* n = d->begin() + from - 1;
|
||||||
T* e = p->array + d->size;
|
T* e = d->end();
|
||||||
while (++n != e)
|
while (++n != e)
|
||||||
if (*n == t)
|
if (*n == t)
|
||||||
return n - p->array;
|
return n - d->begin();
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -717,8 +725,8 @@ int QVector<T>::lastIndexOf(const T &t, int from) const
|
|||||||
else if (from >= d->size)
|
else if (from >= d->size)
|
||||||
from = d->size-1;
|
from = d->size-1;
|
||||||
if (from >= 0) {
|
if (from >= 0) {
|
||||||
T* b = p->array;
|
T* b = d->begin();
|
||||||
T* n = p->array + from + 1;
|
T* n = d->begin() + from + 1;
|
||||||
while (n != b) {
|
while (n != b) {
|
||||||
if (*--n == t)
|
if (*--n == t)
|
||||||
return n - b;
|
return n - b;
|
||||||
@ -730,8 +738,8 @@ int QVector<T>::lastIndexOf(const T &t, int from) const
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
bool QVector<T>::contains(const T &t) const
|
bool QVector<T>::contains(const T &t) const
|
||||||
{
|
{
|
||||||
T* b = p->array;
|
T* b = d->begin();
|
||||||
T* i = p->array + d->size;
|
T* i = d->end();
|
||||||
while (i != b)
|
while (i != b)
|
||||||
if (*--i == t)
|
if (*--i == t)
|
||||||
return true;
|
return true;
|
||||||
@ -742,8 +750,8 @@ template <typename T>
|
|||||||
int QVector<T>::count(const T &t) const
|
int QVector<T>::count(const T &t) const
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
T* b = p->array;
|
T* b = d->begin();
|
||||||
T* i = p->array + d->size;
|
T* i = d->end();
|
||||||
while (i != b)
|
while (i != b)
|
||||||
if (*--i == t)
|
if (*--i == t)
|
||||||
++c;
|
++c;
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
tools/qalgorithms.h \
|
tools/qalgorithms.h \
|
||||||
|
tools/qarraydata.h \
|
||||||
|
tools/qarraydataops.h \
|
||||||
|
tools/qarraydatapointer.h \
|
||||||
tools/qbitarray.h \
|
tools/qbitarray.h \
|
||||||
tools/qbytearray.h \
|
tools/qbytearray.h \
|
||||||
tools/qbytearraymatcher.h \
|
tools/qbytearraymatcher.h \
|
||||||
@ -56,6 +59,7 @@ HEADERS += \
|
|||||||
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
tools/qarraydata.cpp \
|
||||||
tools/qbitarray.cpp \
|
tools/qbitarray.cpp \
|
||||||
tools/qbytearray.cpp \
|
tools/qbytearray.cpp \
|
||||||
tools/qbytearraymatcher.cpp \
|
tools/qbytearraymatcher.cpp \
|
||||||
|
@ -181,7 +181,7 @@ void QDBusAbstractAdaptor::setAutoRelaySignals(bool enable)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// try to connect/disconnect to a signal on the parent that has the same method signature
|
// try to connect/disconnect to a signal on the parent that has the same method signature
|
||||||
QByteArray sig = QMetaObject::normalizedSignature(mm.signature());
|
QByteArray sig = QMetaObject::normalizedSignature(mm.methodSignature().constData());
|
||||||
if (them->indexOfSignal(sig) == -1)
|
if (them->indexOfSignal(sig) == -1)
|
||||||
continue;
|
continue;
|
||||||
sig.prepend(QSIGNAL_CODE + '0');
|
sig.prepend(QSIGNAL_CODE + '0');
|
||||||
@ -307,7 +307,7 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void **
|
|||||||
// invalid signal signature
|
// invalid signal signature
|
||||||
// qDBusParametersForMethod has not yet complained about this one
|
// qDBusParametersForMethod has not yet complained about this one
|
||||||
qWarning("QDBusAbstractAdaptor: Cannot relay signal %s::%s",
|
qWarning("QDBusAbstractAdaptor: Cannot relay signal %s::%s",
|
||||||
senderMetaObject->className(), mm.signature());
|
senderMetaObject->className(), mm.methodSignature().constData());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,10 +323,38 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void **
|
|||||||
// modify carefully: this has been hand-edited!
|
// modify carefully: this has been hand-edited!
|
||||||
// the relaySlot slot gets called with the void** array
|
// the relaySlot slot gets called with the void** array
|
||||||
|
|
||||||
|
struct qt_meta_stringdata_QDBusAdaptorConnector_t {
|
||||||
|
QByteArrayData data[10];
|
||||||
|
char stringdata[96];
|
||||||
|
};
|
||||||
|
#define QT_MOC_LITERAL(idx, ofs, len) { \
|
||||||
|
Q_REFCOUNT_INITIALIZE_STATIC, len, 0, 0, \
|
||||||
|
offsetof(qt_meta_stringdata_QDBusAdaptorConnector_t, stringdata) + ofs \
|
||||||
|
- idx * sizeof(QByteArrayData) \
|
||||||
|
}
|
||||||
|
static const qt_meta_stringdata_QDBusAdaptorConnector_t qt_meta_stringdata_QDBusAdaptorConnector = {
|
||||||
|
{
|
||||||
|
QT_MOC_LITERAL(0, 0, 21),
|
||||||
|
QT_MOC_LITERAL(1, 22, 11),
|
||||||
|
QT_MOC_LITERAL(2, 34, 0),
|
||||||
|
QT_MOC_LITERAL(3, 35, 3),
|
||||||
|
QT_MOC_LITERAL(4, 39, 18),
|
||||||
|
QT_MOC_LITERAL(5, 58, 10),
|
||||||
|
QT_MOC_LITERAL(6, 69, 3),
|
||||||
|
QT_MOC_LITERAL(7, 73, 4),
|
||||||
|
QT_MOC_LITERAL(8, 78, 9),
|
||||||
|
QT_MOC_LITERAL(9, 88, 6)
|
||||||
|
},
|
||||||
|
"QDBusAdaptorConnector\0relaySignal\0\0"
|
||||||
|
"obj\0const QMetaObject*\0metaObject\0sid\0"
|
||||||
|
"args\0relaySlot\0polish\0"
|
||||||
|
};
|
||||||
|
#undef QT_MOC_LITERAL
|
||||||
|
|
||||||
static const uint qt_meta_data_QDBusAdaptorConnector[] = {
|
static const uint qt_meta_data_QDBusAdaptorConnector[] = {
|
||||||
|
|
||||||
// content:
|
// content:
|
||||||
6, // revision
|
7, // revision
|
||||||
0, // classname
|
0, // classname
|
||||||
0, 0, // classinfo
|
0, 0, // classinfo
|
||||||
3, 14, // methods
|
3, 14, // methods
|
||||||
@ -336,22 +364,23 @@ static const uint qt_meta_data_QDBusAdaptorConnector[] = {
|
|||||||
0, // flags
|
0, // flags
|
||||||
1, // signalCount
|
1, // signalCount
|
||||||
|
|
||||||
// signals: signature, parameters, type, tag, flags
|
// signals: name, argc, parameters, tag, flags
|
||||||
47, 23, 22, 22, 0x05,
|
1, 4, 29, 2, 0x05,
|
||||||
|
|
||||||
// slots: signature, parameters, type, tag, flags
|
// slots: name, argc, parameters, tag, flags
|
||||||
105, 22, 22, 22, 0x0a,
|
8, 0, 38, 2, 0x0a,
|
||||||
117, 22, 22, 22, 0x0a,
|
9, 0, 39, 2, 0x0a,
|
||||||
|
|
||||||
|
// signals: parameters
|
||||||
|
QMetaType::Void, QMetaType::QObjectStar, 0x80000000 | 4, QMetaType::Int, QMetaType::QVariantList, 3, 5, 6, 7,
|
||||||
|
|
||||||
|
// slots: parameters
|
||||||
|
QMetaType::Void,
|
||||||
|
QMetaType::Void,
|
||||||
|
|
||||||
0 // eod
|
0 // eod
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char qt_meta_stringdata_QDBusAdaptorConnector[] = {
|
|
||||||
"QDBusAdaptorConnector\0\0obj,metaObject,sid,args\0"
|
|
||||||
"relaySignal(QObject*,const QMetaObject*,int,QVariantList)\0"
|
|
||||||
"relaySlot()\0polish()\0"
|
|
||||||
};
|
|
||||||
|
|
||||||
void QDBusAdaptorConnector::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
void QDBusAdaptorConnector::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||||
{
|
{
|
||||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||||
@ -371,7 +400,7 @@ const QMetaObjectExtraData QDBusAdaptorConnector::staticMetaObjectExtraData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const QMetaObject QDBusAdaptorConnector::staticMetaObject = {
|
const QMetaObject QDBusAdaptorConnector::staticMetaObject = {
|
||||||
{ &QObject::staticMetaObject, qt_meta_stringdata_QDBusAdaptorConnector,
|
{ &QObject::staticMetaObject, qt_meta_stringdata_QDBusAdaptorConnector.data,
|
||||||
qt_meta_data_QDBusAdaptorConnector, &staticMetaObjectExtraData }
|
qt_meta_data_QDBusAdaptorConnector, &staticMetaObjectExtraData }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -383,7 +412,7 @@ const QMetaObject *QDBusAdaptorConnector::metaObject() const
|
|||||||
void *QDBusAdaptorConnector::qt_metacast(const char *_clname)
|
void *QDBusAdaptorConnector::qt_metacast(const char *_clname)
|
||||||
{
|
{
|
||||||
if (!_clname) return 0;
|
if (!_clname) return 0;
|
||||||
if (!strcmp(_clname, qt_meta_stringdata_QDBusAdaptorConnector))
|
if (!strcmp(_clname, qt_meta_stringdata_QDBusAdaptorConnector.stringdata))
|
||||||
return static_cast<void*>(const_cast< QDBusAdaptorConnector*>(this));
|
return static_cast<void*>(const_cast< QDBusAdaptorConnector*>(this));
|
||||||
return QObject::qt_metacast(_clname);
|
return QObject::qt_metacast(_clname);
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode,
|
|||||||
|
|
||||||
for (int i = staticMetaObject.methodCount(); i < mo->methodCount(); ++i) {
|
for (int i = staticMetaObject.methodCount(); i < mo->methodCount(); ++i) {
|
||||||
QMetaMethod mm = mo->method(i);
|
QMetaMethod mm = mo->method(i);
|
||||||
if (QByteArray(mm.signature()).startsWith(match)) {
|
if (mm.methodSignature().startsWith(match)) {
|
||||||
// found a method with the same name as what we're looking for
|
// found a method with the same name as what we're looking for
|
||||||
// hopefully, nobody is overloading asynchronous and synchronous methods with
|
// hopefully, nobody is overloading asynchronous and synchronous methods with
|
||||||
// the same name
|
// the same name
|
||||||
|
@ -640,7 +640,7 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check name:
|
// check name:
|
||||||
QByteArray slotname = mm.signature();
|
QByteArray slotname = mm.methodSignature();
|
||||||
int paren = slotname.indexOf('(');
|
int paren = slotname.indexOf('(');
|
||||||
if (paren != name.length() || !slotname.startsWith(name))
|
if (paren != name.length() || !slotname.startsWith(name))
|
||||||
continue;
|
continue;
|
||||||
@ -686,7 +686,7 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags,
|
|||||||
++i;
|
++i;
|
||||||
|
|
||||||
// make sure that the output parameters have signatures too
|
// make sure that the output parameters have signatures too
|
||||||
if (returnType != 0 && QDBusMetaType::typeToSignature(returnType) == 0)
|
if (returnType != QMetaType::UnknownType && returnType != QMetaType::Void && QDBusMetaType::typeToSignature(returnType) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
@ -919,7 +919,7 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q
|
|||||||
// output arguments
|
// output arguments
|
||||||
QVariantList outputArgs;
|
QVariantList outputArgs;
|
||||||
void *null = 0;
|
void *null = 0;
|
||||||
if (metaTypes[0] != QMetaType::Void) {
|
if (metaTypes[0] != QMetaType::Void && metaTypes[0] != QMetaType::UnknownType) {
|
||||||
QVariant arg(metaTypes[0], null);
|
QVariant arg(metaTypes[0], null);
|
||||||
outputArgs.append( arg );
|
outputArgs.append( arg );
|
||||||
params[0] = const_cast<void*>(outputArgs.at( outputArgs.count() - 1 ).constData());
|
params[0] = const_cast<void*>(outputArgs.at( outputArgs.count() - 1 ).constData());
|
||||||
@ -1188,7 +1188,7 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in
|
|||||||
QString interface = qDBusInterfaceFromMetaObject(mo);
|
QString interface = qDBusInterfaceFromMetaObject(mo);
|
||||||
|
|
||||||
QMetaMethod mm = mo->method(signalId);
|
QMetaMethod mm = mo->method(signalId);
|
||||||
QByteArray memberName = mm.signature();
|
QByteArray memberName = mm.methodSignature();
|
||||||
memberName.truncate(memberName.indexOf('('));
|
memberName.truncate(memberName.indexOf('('));
|
||||||
|
|
||||||
// check if it's scriptable
|
// check if it's scriptable
|
||||||
|
@ -280,7 +280,7 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv)
|
|||||||
} else if (mm.methodType() == QMetaMethod::Slot || mm.methodType() == QMetaMethod::Method) {
|
} else if (mm.methodType() == QMetaMethod::Slot || mm.methodType() == QMetaMethod::Method) {
|
||||||
// method call relay from Qt world to D-Bus world
|
// method call relay from Qt world to D-Bus world
|
||||||
// get D-Bus equivalent signature
|
// get D-Bus equivalent signature
|
||||||
QString methodName = QLatin1String(metaObject->dbusNameForMethod(id));
|
QString methodName = QString::fromLatin1(mm.name());
|
||||||
const int *inputTypes = metaObject->inputTypesForMethod(id);
|
const int *inputTypes = metaObject->inputTypesForMethod(id);
|
||||||
int inputTypesCount = *inputTypes;
|
int inputTypesCount = *inputTypes;
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include "qdbusabstractinterface_p.h"
|
#include "qdbusabstractinterface_p.h"
|
||||||
|
|
||||||
#include <private/qmetaobject_p.h>
|
#include <private/qmetaobject_p.h>
|
||||||
|
#include <private/qmetaobjectbuilder_p.h>
|
||||||
|
|
||||||
#ifndef QT_NO_DBUS
|
#ifndef QT_NO_DBUS
|
||||||
|
|
||||||
@ -69,8 +70,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct Method {
|
struct Method {
|
||||||
QByteArray parameters;
|
QList<QByteArray> parameterNames;
|
||||||
QByteArray typeName;
|
|
||||||
QByteArray tag;
|
QByteArray tag;
|
||||||
QByteArray name;
|
QByteArray name;
|
||||||
QVarLengthArray<int, 4> inputTypes;
|
QVarLengthArray<int, 4> inputTypes;
|
||||||
@ -103,10 +103,12 @@ private:
|
|||||||
void parseMethods();
|
void parseMethods();
|
||||||
void parseSignals();
|
void parseSignals();
|
||||||
void parseProperties();
|
void parseProperties();
|
||||||
|
|
||||||
|
static int aggregateParameterCount(const QMap<QByteArray, Method> &map);
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int intsPerProperty = 2;
|
static const int intsPerProperty = 2;
|
||||||
static const int intsPerMethod = 3;
|
static const int intsPerMethod = 2;
|
||||||
|
|
||||||
struct QDBusMetaObjectPrivate : public QMetaObjectPrivate
|
struct QDBusMetaObjectPrivate : public QMetaObjectPrivate
|
||||||
{
|
{
|
||||||
@ -132,6 +134,30 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
|
|||||||
const QDBusIntrospection::Annotations &annotations,
|
const QDBusIntrospection::Annotations &annotations,
|
||||||
const char *direction, int id)
|
const char *direction, int id)
|
||||||
{
|
{
|
||||||
|
struct QDBusRawTypeHandler {
|
||||||
|
static void destroy(void *)
|
||||||
|
{
|
||||||
|
qFatal("Cannot destroy placeholder type QDBusRawType");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *create(const void *)
|
||||||
|
{
|
||||||
|
qFatal("Cannot create placeholder type QDBusRawType");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destruct(void *)
|
||||||
|
{
|
||||||
|
qFatal("Cannot destruct placeholder type QDBusRawType");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *construct(void *, const void *)
|
||||||
|
{
|
||||||
|
qFatal("Cannot construct placeholder type QDBusRawType");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Type result;
|
Type result;
|
||||||
result.id = QVariant::Invalid;
|
result.id = QVariant::Invalid;
|
||||||
|
|
||||||
@ -157,8 +183,13 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature,
|
|||||||
if (type == QVariant::Invalid || signature != QDBusMetaType::typeToSignature(type)) {
|
if (type == QVariant::Invalid || signature != QDBusMetaType::typeToSignature(type)) {
|
||||||
// type is still unknown or doesn't match back to the signature that it
|
// type is still unknown or doesn't match back to the signature that it
|
||||||
// was expected to, so synthesize a fake type
|
// was expected to, so synthesize a fake type
|
||||||
type = QMetaType::VoidStar;
|
|
||||||
typeName = "QDBusRawType<0x" + signature.toHex() + ">*";
|
typeName = "QDBusRawType<0x" + signature.toHex() + ">*";
|
||||||
|
type = QMetaType::registerType(typeName, QDBusRawTypeHandler::destroy,
|
||||||
|
QDBusRawTypeHandler::create,
|
||||||
|
QDBusRawTypeHandler::destruct,
|
||||||
|
QDBusRawTypeHandler::construct,
|
||||||
|
sizeof(void *),
|
||||||
|
QMetaType::MovableType);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.name = typeName;
|
result.name = typeName;
|
||||||
@ -215,8 +246,7 @@ void QDBusMetaObjectGenerator::parseMethods()
|
|||||||
|
|
||||||
mm.inputTypes.append(type.id);
|
mm.inputTypes.append(type.id);
|
||||||
|
|
||||||
mm.parameters.append(arg.name.toLatin1());
|
mm.parameterNames.append(arg.name.toLatin1());
|
||||||
mm.parameters.append(',');
|
|
||||||
|
|
||||||
prototype.append(type.name);
|
prototype.append(type.name);
|
||||||
prototype.append(',');
|
prototype.append(',');
|
||||||
@ -235,13 +265,9 @@ void QDBusMetaObjectGenerator::parseMethods()
|
|||||||
|
|
||||||
mm.outputTypes.append(type.id);
|
mm.outputTypes.append(type.id);
|
||||||
|
|
||||||
if (i == 0) {
|
if (i != 0) {
|
||||||
// return value
|
|
||||||
mm.typeName = type.name;
|
|
||||||
} else {
|
|
||||||
// non-const ref parameter
|
// non-const ref parameter
|
||||||
mm.parameters.append(arg.name.toLatin1());
|
mm.parameterNames.append(arg.name.toLatin1());
|
||||||
mm.parameters.append(',');
|
|
||||||
|
|
||||||
prototype.append(type.name);
|
prototype.append(type.name);
|
||||||
prototype.append("&,");
|
prototype.append("&,");
|
||||||
@ -250,12 +276,10 @@ void QDBusMetaObjectGenerator::parseMethods()
|
|||||||
if (!ok) continue;
|
if (!ok) continue;
|
||||||
|
|
||||||
// convert the last commas:
|
// convert the last commas:
|
||||||
if (!mm.parameters.isEmpty()) {
|
if (!mm.parameterNames.isEmpty())
|
||||||
mm.parameters.truncate(mm.parameters.length() - 1);
|
|
||||||
prototype[prototype.length() - 1] = ')';
|
prototype[prototype.length() - 1] = ')';
|
||||||
} else {
|
else
|
||||||
prototype.append(')');
|
prototype.append(')');
|
||||||
}
|
|
||||||
|
|
||||||
// check the async tag
|
// check the async tag
|
||||||
if (m.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true"))
|
if (m.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true"))
|
||||||
@ -295,8 +319,7 @@ void QDBusMetaObjectGenerator::parseSignals()
|
|||||||
|
|
||||||
mm.inputTypes.append(type.id);
|
mm.inputTypes.append(type.id);
|
||||||
|
|
||||||
mm.parameters.append(arg.name.toLatin1());
|
mm.parameterNames.append(arg.name.toLatin1());
|
||||||
mm.parameters.append(',');
|
|
||||||
|
|
||||||
prototype.append(type.name);
|
prototype.append(type.name);
|
||||||
prototype.append(',');
|
prototype.append(',');
|
||||||
@ -304,12 +327,10 @@ void QDBusMetaObjectGenerator::parseSignals()
|
|||||||
if (!ok) continue;
|
if (!ok) continue;
|
||||||
|
|
||||||
// convert the last commas:
|
// convert the last commas:
|
||||||
if (!mm.parameters.isEmpty()) {
|
if (!mm.parameterNames.isEmpty())
|
||||||
mm.parameters.truncate(mm.parameters.length() - 1);
|
|
||||||
prototype[prototype.length() - 1] = ')';
|
prototype[prototype.length() - 1] = ')';
|
||||||
} else {
|
else
|
||||||
prototype.append(')');
|
prototype.append(')');
|
||||||
}
|
|
||||||
|
|
||||||
// meta method flags
|
// meta method flags
|
||||||
mm.flags = AccessProtected | MethodSignal | MethodScriptable;
|
mm.flags = AccessProtected | MethodSignal | MethodScriptable;
|
||||||
@ -342,49 +363,27 @@ void QDBusMetaObjectGenerator::parseProperties()
|
|||||||
if (p.access != QDBusIntrospection::Property::Read)
|
if (p.access != QDBusIntrospection::Property::Read)
|
||||||
mp.flags |= Writable;
|
mp.flags |= Writable;
|
||||||
|
|
||||||
if (mp.typeName == "QDBusVariant")
|
|
||||||
mp.flags |= QMetaType::QVariant << 24;
|
|
||||||
else if (mp.type < 0xff)
|
|
||||||
// encode the type in the flags
|
|
||||||
mp.flags |= mp.type << 24;
|
|
||||||
|
|
||||||
// add the property:
|
// add the property:
|
||||||
properties.insert(name, mp);
|
properties.insert(name, mp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the sum of all parameters (including return type) for the given
|
||||||
|
// \a map of methods. This is needed for calculating the size of the methods'
|
||||||
|
// parameter type/name meta-data.
|
||||||
|
int QDBusMetaObjectGenerator::aggregateParameterCount(const QMap<QByteArray, Method> &map)
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
QMap<QByteArray, Method>::const_iterator it;
|
||||||
|
for (it = map.constBegin(); it != map.constEnd(); ++it) {
|
||||||
|
const Method &m = it.value();
|
||||||
|
sum += m.inputTypes.size() + qMax(1, m.outputTypes.size());
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
||||||
{
|
{
|
||||||
class MetaStringTable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef QHash<QByteArray, int> Entries; // string --> offset mapping
|
|
||||||
typedef Entries::const_iterator const_iterator;
|
|
||||||
Entries::const_iterator constBegin() const
|
|
||||||
{ return m_entries.constBegin(); }
|
|
||||||
Entries::const_iterator constEnd() const
|
|
||||||
{ return m_entries.constEnd(); }
|
|
||||||
|
|
||||||
MetaStringTable() : m_offset(0) {}
|
|
||||||
|
|
||||||
int enter(const QByteArray &value)
|
|
||||||
{
|
|
||||||
Entries::iterator it = m_entries.find(value);
|
|
||||||
if (it != m_entries.end())
|
|
||||||
return it.value();
|
|
||||||
int pos = m_offset;
|
|
||||||
m_entries.insert(value, pos);
|
|
||||||
m_offset += value.size() + 1;
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
int arraySize() const { return m_offset; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Entries m_entries;
|
|
||||||
int m_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
// this code here is mostly copied from qaxbase.cpp
|
// this code here is mostly copied from qaxbase.cpp
|
||||||
// with a few modifications to make it cleaner
|
// with a few modifications to make it cleaner
|
||||||
|
|
||||||
@ -396,8 +395,14 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
QVarLengthArray<int> idata;
|
QVarLengthArray<int> idata;
|
||||||
idata.resize(sizeof(QDBusMetaObjectPrivate) / sizeof(int));
|
idata.resize(sizeof(QDBusMetaObjectPrivate) / sizeof(int));
|
||||||
|
|
||||||
|
int methodParametersDataSize =
|
||||||
|
((aggregateParameterCount(signals_)
|
||||||
|
+ aggregateParameterCount(methods)) * 2) // types and parameter names
|
||||||
|
- signals_.count() // return "parameters" don't have names
|
||||||
|
- methods.count(); // ditto
|
||||||
|
|
||||||
QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data());
|
QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data());
|
||||||
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 6, "QtDBus meta-object generator should generate the same version as moc");
|
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QtDBus meta-object generator should generate the same version as moc");
|
||||||
header->revision = QMetaObjectPrivate::OutputRevision;
|
header->revision = QMetaObjectPrivate::OutputRevision;
|
||||||
header->className = 0;
|
header->className = 0;
|
||||||
header->classInfoCount = 0;
|
header->classInfoCount = 0;
|
||||||
@ -405,7 +410,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
header->methodCount = signals_.count() + methods.count();
|
header->methodCount = signals_.count() + methods.count();
|
||||||
header->methodData = idata.size();
|
header->methodData = idata.size();
|
||||||
header->propertyCount = properties.count();
|
header->propertyCount = properties.count();
|
||||||
header->propertyData = header->methodData + header->methodCount * 5;
|
header->propertyData = header->methodData + header->methodCount * 5 + methodParametersDataSize;
|
||||||
header->enumeratorCount = 0;
|
header->enumeratorCount = 0;
|
||||||
header->enumeratorData = 0;
|
header->enumeratorData = 0;
|
||||||
header->constructorCount = 0;
|
header->constructorCount = 0;
|
||||||
@ -417,7 +422,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
header->methodDBusData = header->propertyDBusData + header->propertyCount * intsPerProperty;
|
header->methodDBusData = header->propertyDBusData + header->propertyCount * intsPerProperty;
|
||||||
|
|
||||||
int data_size = idata.size() +
|
int data_size = idata.size() +
|
||||||
(header->methodCount * (5+intsPerMethod)) +
|
(header->methodCount * (5+intsPerMethod)) + methodParametersDataSize +
|
||||||
(header->propertyCount * (3+intsPerProperty));
|
(header->propertyCount * (3+intsPerProperty));
|
||||||
foreach (const Method &mm, signals_)
|
foreach (const Method &mm, signals_)
|
||||||
data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
|
data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
|
||||||
@ -425,10 +430,11 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
|
data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
|
||||||
idata.resize(data_size + 1);
|
idata.resize(data_size + 1);
|
||||||
|
|
||||||
MetaStringTable strings;
|
QMetaStringTable strings;
|
||||||
strings.enter(className.toLatin1());
|
strings.enter(className.toLatin1());
|
||||||
|
|
||||||
int offset = header->methodData;
|
int offset = header->methodData;
|
||||||
|
int parametersOffset = offset + header->methodCount * 5;
|
||||||
int signatureOffset = header->methodDBusData;
|
int signatureOffset = header->methodDBusData;
|
||||||
int typeidOffset = header->methodDBusData + header->methodCount * intsPerMethod;
|
int typeidOffset = header->methodDBusData + header->methodCount * intsPerMethod;
|
||||||
idata[typeidOffset++] = 0; // eod
|
idata[typeidOffset++] = 0; // eod
|
||||||
@ -439,16 +445,45 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
QMap<QByteArray, Method> &map = (x == 0) ? signals_ : methods;
|
QMap<QByteArray, Method> &map = (x == 0) ? signals_ : methods;
|
||||||
for (QMap<QByteArray, Method>::ConstIterator it = map.constBegin();
|
for (QMap<QByteArray, Method>::ConstIterator it = map.constBegin();
|
||||||
it != map.constEnd(); ++it) {
|
it != map.constEnd(); ++it) {
|
||||||
// form "prototype\0parameters\0typeName\0tag\0methodname\0"
|
|
||||||
const Method &mm = it.value();
|
const Method &mm = it.value();
|
||||||
|
|
||||||
idata[offset++] = strings.enter(it.key()); // prototype
|
int argc = mm.inputTypes.size() + qMax(0, mm.outputTypes.size() - 1);
|
||||||
idata[offset++] = strings.enter(mm.parameters);
|
|
||||||
idata[offset++] = strings.enter(mm.typeName);
|
idata[offset++] = strings.enter(mm.name);
|
||||||
|
idata[offset++] = argc;
|
||||||
|
idata[offset++] = parametersOffset;
|
||||||
idata[offset++] = strings.enter(mm.tag);
|
idata[offset++] = strings.enter(mm.tag);
|
||||||
idata[offset++] = mm.flags;
|
idata[offset++] = mm.flags;
|
||||||
|
|
||||||
idata[signatureOffset++] = strings.enter(mm.name);
|
// Parameter types
|
||||||
|
for (int i = -1; i < argc; ++i) {
|
||||||
|
int type;
|
||||||
|
QByteArray typeName;
|
||||||
|
if (i < 0) { // Return type
|
||||||
|
if (!mm.outputTypes.isEmpty())
|
||||||
|
type = mm.outputTypes.first();
|
||||||
|
else
|
||||||
|
type = QMetaType::Void;
|
||||||
|
} else if (i < mm.inputTypes.size()) {
|
||||||
|
type = mm.inputTypes.at(i);
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(mm.outputTypes.size() > 1);
|
||||||
|
type = mm.outputTypes.at(i - mm.inputTypes.size() + 1);
|
||||||
|
// Output parameters are references; type id not available
|
||||||
|
typeName = QMetaType::typeName(type);
|
||||||
|
typeName.append('&');
|
||||||
|
}
|
||||||
|
Q_ASSERT(type != QMetaType::UnknownType);
|
||||||
|
int typeInfo;
|
||||||
|
if (!typeName.isEmpty())
|
||||||
|
typeInfo = IsUnresolvedType | strings.enter(typeName);
|
||||||
|
else
|
||||||
|
typeInfo = type;
|
||||||
|
idata[parametersOffset++] = typeInfo;
|
||||||
|
}
|
||||||
|
// Parameter names
|
||||||
|
for (int i = 0; i < argc; ++i)
|
||||||
|
idata[parametersOffset++] = strings.enter(mm.parameterNames.at(i));
|
||||||
|
|
||||||
idata[signatureOffset++] = typeidOffset;
|
idata[signatureOffset++] = typeidOffset;
|
||||||
idata[typeidOffset++] = mm.inputTypes.count();
|
idata[typeidOffset++] = mm.inputTypes.count();
|
||||||
@ -462,9 +497,12 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(offset == header->propertyData);
|
Q_ASSERT(offset == header->methodData + header->methodCount * 5);
|
||||||
|
Q_ASSERT(parametersOffset = header->propertyData);
|
||||||
Q_ASSERT(signatureOffset == header->methodDBusData + header->methodCount * intsPerMethod);
|
Q_ASSERT(signatureOffset == header->methodDBusData + header->methodCount * intsPerMethod);
|
||||||
Q_ASSERT(typeidOffset == idata.size());
|
Q_ASSERT(typeidOffset == idata.size());
|
||||||
|
offset += methodParametersDataSize;
|
||||||
|
Q_ASSERT(offset == header->propertyData);
|
||||||
|
|
||||||
// add each property
|
// add each property
|
||||||
signatureOffset = header->propertyDBusData;
|
signatureOffset = header->propertyDBusData;
|
||||||
@ -472,9 +510,10 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
it != properties.constEnd(); ++it) {
|
it != properties.constEnd(); ++it) {
|
||||||
const Property &mp = it.value();
|
const Property &mp = it.value();
|
||||||
|
|
||||||
// form is "name\0typeName\0signature\0"
|
// form is name, typeinfo, flags
|
||||||
idata[offset++] = strings.enter(it.key()); // name
|
idata[offset++] = strings.enter(it.key()); // name
|
||||||
idata[offset++] = strings.enter(mp.typeName);
|
Q_ASSERT(mp.type != QMetaType::UnknownType);
|
||||||
|
idata[offset++] = mp.type;
|
||||||
idata[offset++] = mp.flags;
|
idata[offset++] = mp.flags;
|
||||||
|
|
||||||
idata[signatureOffset++] = strings.enter(mp.signature);
|
idata[signatureOffset++] = strings.enter(mp.signature);
|
||||||
@ -484,14 +523,8 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
Q_ASSERT(offset == header->propertyDBusData);
|
Q_ASSERT(offset == header->propertyDBusData);
|
||||||
Q_ASSERT(signatureOffset == header->methodDBusData);
|
Q_ASSERT(signatureOffset == header->methodDBusData);
|
||||||
|
|
||||||
char *string_data = new char[strings.arraySize()];
|
char *string_data = new char[strings.blobSize()];
|
||||||
{
|
strings.writeBlob(string_data);
|
||||||
MetaStringTable::const_iterator it;
|
|
||||||
for (it = strings.constBegin(); it != strings.constEnd(); ++it) {
|
|
||||||
memcpy(string_data + it.value(), it.key().constData(), it.key().size());
|
|
||||||
string_data[it.value() + it.key().size()] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint *uint_data = new uint[idata.size()];
|
uint *uint_data = new uint[idata.size()];
|
||||||
memcpy(uint_data, idata.data(), idata.size() * sizeof(int));
|
memcpy(uint_data, idata.data(), idata.size() * sizeof(int));
|
||||||
@ -499,7 +532,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||||||
// put the metaobject together
|
// put the metaobject together
|
||||||
obj->d.data = uint_data;
|
obj->d.data = uint_data;
|
||||||
obj->d.extradata = 0;
|
obj->d.extradata = 0;
|
||||||
obj->d.stringdata = string_data;
|
obj->d.stringdata = reinterpret_cast<const QByteArrayData *>(string_data);
|
||||||
obj->d.superdata = &QDBusAbstractInterface::staticMetaObject;
|
obj->d.superdata = &QDBusAbstractInterface::staticMetaObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,22 +646,12 @@ static inline const QDBusMetaObjectPrivate *priv(const uint* data)
|
|||||||
return reinterpret_cast<const QDBusMetaObjectPrivate *>(data);
|
return reinterpret_cast<const QDBusMetaObjectPrivate *>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *QDBusMetaObject::dbusNameForMethod(int id) const
|
|
||||||
{
|
|
||||||
//id -= methodOffset();
|
|
||||||
if (id >= 0 && id < priv(d.data)->methodCount) {
|
|
||||||
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
|
|
||||||
return d.stringdata + d.data[handle];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int *QDBusMetaObject::inputTypesForMethod(int id) const
|
const int *QDBusMetaObject::inputTypesForMethod(int id) const
|
||||||
{
|
{
|
||||||
//id -= methodOffset();
|
//id -= methodOffset();
|
||||||
if (id >= 0 && id < priv(d.data)->methodCount) {
|
if (id >= 0 && id < priv(d.data)->methodCount) {
|
||||||
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
|
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
|
||||||
return reinterpret_cast<const int*>(d.data + d.data[handle + 1]);
|
return reinterpret_cast<const int*>(d.data + d.data[handle]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -638,7 +661,7 @@ const int *QDBusMetaObject::outputTypesForMethod(int id) const
|
|||||||
//id -= methodOffset();
|
//id -= methodOffset();
|
||||||
if (id >= 0 && id < priv(d.data)->methodCount) {
|
if (id >= 0 && id < priv(d.data)->methodCount) {
|
||||||
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
|
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
|
||||||
return reinterpret_cast<const int*>(d.data + d.data[handle + 2]);
|
return reinterpret_cast<const int*>(d.data + d.data[handle + 1]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -71,12 +71,11 @@ struct Q_DBUS_EXPORT QDBusMetaObject: public QMetaObject
|
|||||||
QDBusError &error);
|
QDBusError &error);
|
||||||
~QDBusMetaObject()
|
~QDBusMetaObject()
|
||||||
{
|
{
|
||||||
delete [] d.stringdata;
|
delete [] reinterpret_cast<const char *>(d.stringdata);
|
||||||
delete [] d.data;
|
delete [] d.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// methods (slots & signals):
|
// methods (slots & signals):
|
||||||
const char *dbusNameForMethod(int id) const;
|
|
||||||
const int *inputTypesForMethod(int id) const;
|
const int *inputTypesForMethod(int id) const;
|
||||||
const int *outputTypesForMethod(int id) const;
|
const int *outputTypesForMethod(int id) const;
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ bool QDBusMetaType::demarshall(const QDBusArgument &arg, int id, void *data)
|
|||||||
int QDBusMetaType::signatureToType(const char *signature)
|
int QDBusMetaType::signatureToType(const char *signature)
|
||||||
{
|
{
|
||||||
if (!signature)
|
if (!signature)
|
||||||
return QVariant::Invalid;
|
return QMetaType::UnknownType;
|
||||||
|
|
||||||
QDBusMetaTypeId::init();
|
QDBusMetaTypeId::init();
|
||||||
switch (signature[0])
|
switch (signature[0])
|
||||||
@ -378,7 +378,7 @@ int QDBusMetaType::signatureToType(const char *signature)
|
|||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
default:
|
default:
|
||||||
return QVariant::Invalid;
|
return QMetaType::UnknownType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& metaTypes)
|
|||||||
for ( ; it != end; ++it) {
|
for ( ; it != end; ++it) {
|
||||||
const QByteArray &type = *it;
|
const QByteArray &type = *it;
|
||||||
if (type.endsWith('*')) {
|
if (type.endsWith('*')) {
|
||||||
//qWarning("Could not parse the method '%s'", mm.signature());
|
//qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
|
||||||
// pointer?
|
// pointer?
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -152,7 +152,7 @@ int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& metaTypes)
|
|||||||
|
|
||||||
int id = QMetaType::type(basictype);
|
int id = QMetaType::type(basictype);
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
//qWarning("Could not parse the method '%s'", mm.signature());
|
//qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
|
||||||
// invalid type in method parameter list
|
// invalid type in method parameter list
|
||||||
return -1;
|
return -1;
|
||||||
} else if (QDBusMetaType::typeToSignature(id) == 0)
|
} else if (QDBusMetaType::typeToSignature(id) == 0)
|
||||||
@ -164,14 +164,14 @@ int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& metaTypes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (seenMessage) { // && !type.endsWith('&')
|
if (seenMessage) { // && !type.endsWith('&')
|
||||||
//qWarning("Could not parse the method '%s'", mm.signature());
|
//qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
|
||||||
// non-output parameters after message or after output params
|
// non-output parameters after message or after output params
|
||||||
return -1; // not allowed
|
return -1; // not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = QMetaType::type(type);
|
int id = QMetaType::type(type);
|
||||||
if (id == 0) {
|
if (id == QMetaType::UnknownType) {
|
||||||
//qWarning("Could not parse the method '%s'", mm.signature());
|
//qWarning("Could not parse the method '%s'", mm.methodSignature().constData());
|
||||||
// invalid type in method parameter list
|
// invalid type in method parameter list
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method
|
|||||||
// now add methods:
|
// now add methods:
|
||||||
for (int i = methodOffset; i < mo->methodCount(); ++i) {
|
for (int i = methodOffset; i < mo->methodCount(); ++i) {
|
||||||
QMetaMethod mm = mo->method(i);
|
QMetaMethod mm = mo->method(i);
|
||||||
QByteArray signature = mm.signature();
|
QByteArray signature = mm.methodSignature();
|
||||||
int paren = signature.indexOf('(');
|
int paren = signature.indexOf('(');
|
||||||
|
|
||||||
bool isSignal;
|
bool isSignal;
|
||||||
|
@ -78,10 +78,10 @@ QList<QByteArray> QAccessibleObjectPrivate::actionList() const
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!qstrcmp(member.tag(), "QACCESSIBLE_SLOT")) {
|
if (!qstrcmp(member.tag(), "QACCESSIBLE_SLOT")) {
|
||||||
if (member.signature() == defaultAction)
|
if (member.methodSignature() == defaultAction)
|
||||||
actionList.prepend(defaultAction);
|
actionList.prepend(defaultAction);
|
||||||
else
|
else
|
||||||
actionList << member.signature();
|
actionList << member.methodSignature();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ enum { IndentSpacesCount = 4 };
|
|||||||
|
|
||||||
static QByteArray memberName(const QMetaMethod &member)
|
static QByteArray memberName(const QMetaMethod &member)
|
||||||
{
|
{
|
||||||
QByteArray ba = member.signature();
|
QByteArray ba = member.methodSignature();
|
||||||
return ba.left(ba.indexOf('('));
|
return ba.left(ba.indexOf('('));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +112,8 @@ static void qSignalDumperCallback(QObject *caller, int method_index, void **argv
|
|||||||
|
|
||||||
quintptr addr = quintptr(*reinterpret_cast<void **>(argv[i + 1]));
|
quintptr addr = quintptr(*reinterpret_cast<void **>(argv[i + 1]));
|
||||||
str.append(QByteArray::number(addr, 16));
|
str.append(QByteArray::number(addr, 16));
|
||||||
} else if (typeId != QMetaType::Void) {
|
} else if (typeId != QMetaType::UnknownType) {
|
||||||
|
Q_ASSERT(typeId != QMetaType::Void); // void parameter => metaobject is corrupt
|
||||||
str.append(arg)
|
str.append(arg)
|
||||||
.append('(')
|
.append('(')
|
||||||
.append(QVariant(typeId, argv[i + 1]).toString().toLocal8Bit())
|
.append(QVariant(typeId, argv[i + 1]).toString().toLocal8Bit())
|
||||||
@ -152,7 +153,7 @@ static void qSignalDumperCallbackSlot(QObject *caller, int method_index, void **
|
|||||||
str += QByteArray::number(quintptr(caller), 16);
|
str += QByteArray::number(quintptr(caller), 16);
|
||||||
|
|
||||||
str += ") ";
|
str += ") ";
|
||||||
str += member.signature();
|
str += member.methodSignature();
|
||||||
qPrintMessage(str);
|
qPrintMessage(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,9 +122,11 @@ private:
|
|||||||
QList<QByteArray> params = member.parameterTypes();
|
QList<QByteArray> params = member.parameterTypes();
|
||||||
for (int i = 0; i < params.count(); ++i) {
|
for (int i = 0; i < params.count(); ++i) {
|
||||||
int tp = QMetaType::type(params.at(i).constData());
|
int tp = QMetaType::type(params.at(i).constData());
|
||||||
if (tp == QMetaType::Void)
|
if (tp == QMetaType::UnknownType) {
|
||||||
|
Q_ASSERT(tp != QMetaType::Void); // void parameter => metaobject is corrupt
|
||||||
qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",
|
qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",
|
||||||
params.at(i).constData());
|
params.at(i).constData());
|
||||||
|
}
|
||||||
args << tp;
|
args << tp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1061,7 +1061,8 @@ static bool isValidSlot(const QMetaMethod &sl)
|
|||||||
if (sl.access() != QMetaMethod::Private || !sl.parameterTypes().isEmpty()
|
if (sl.access() != QMetaMethod::Private || !sl.parameterTypes().isEmpty()
|
||||||
|| qstrlen(sl.typeName()) || sl.methodType() != QMetaMethod::Slot)
|
|| qstrlen(sl.typeName()) || sl.methodType() != QMetaMethod::Slot)
|
||||||
return false;
|
return false;
|
||||||
const char *sig = sl.signature();
|
QByteArray signature = sl.methodSignature();
|
||||||
|
const char *sig = signature.constData();
|
||||||
int len = qstrlen(sig);
|
int len = qstrlen(sig);
|
||||||
if (len < 2)
|
if (len < 2)
|
||||||
return false;
|
return false;
|
||||||
@ -1084,7 +1085,7 @@ static void qPrintTestSlots(FILE *stream)
|
|||||||
for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) {
|
for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) {
|
||||||
QMetaMethod sl = QTest::currentTestObject->metaObject()->method(i);
|
QMetaMethod sl = QTest::currentTestObject->metaObject()->method(i);
|
||||||
if (isValidSlot(sl))
|
if (isValidSlot(sl))
|
||||||
fprintf(stream, "%s\n", sl.signature());
|
fprintf(stream, "%s\n", sl.methodSignature().constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,7 +1110,7 @@ static void qPrintDataTags(FILE *stream)
|
|||||||
// Retrieve local tags:
|
// Retrieve local tags:
|
||||||
QStringList localTags;
|
QStringList localTags;
|
||||||
QTestTable table;
|
QTestTable table;
|
||||||
char *slot = qstrdup(tf.signature());
|
char *slot = qstrdup(tf.methodSignature().constData());
|
||||||
slot[strlen(slot) - 2] = '\0';
|
slot[strlen(slot) - 2] = '\0';
|
||||||
QByteArray member;
|
QByteArray member;
|
||||||
member.resize(qstrlen(slot) + qstrlen("_data()") + 1);
|
member.resize(qstrlen(slot) + qstrlen("_data()") + 1);
|
||||||
@ -1781,7 +1782,7 @@ static void qInvokeTestMethods(QObject *testObject)
|
|||||||
|
|
||||||
if (QTest::testFuncs) {
|
if (QTest::testFuncs) {
|
||||||
for (int i = 0; i != QTest::testFuncCount; i++) {
|
for (int i = 0; i != QTest::testFuncCount; i++) {
|
||||||
if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).signature(),
|
if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).methodSignature().constData(),
|
||||||
QTest::testFuncs[i].data())) {
|
QTest::testFuncs[i].data())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1795,7 +1796,7 @@ static void qInvokeTestMethods(QObject *testObject)
|
|||||||
for (int i = 0; i != methodCount; i++) {
|
for (int i = 0; i != methodCount; i++) {
|
||||||
if (!isValidSlot(testMethods[i]))
|
if (!isValidSlot(testMethods[i]))
|
||||||
continue;
|
continue;
|
||||||
if (!qInvokeTestMethod(testMethods[i].signature()))
|
if (!qInvokeTestMethod(testMethods[i].methodSignature().constData()))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delete[] testMethods;
|
delete[] testMethods;
|
||||||
|
@ -54,30 +54,37 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
uint qvariant_nameToType(const QByteArray &name)
|
uint nameToBuiltinType(const QByteArray &name)
|
||||||
{
|
{
|
||||||
if (name.isEmpty())
|
if (name.isEmpty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint tp = QMetaType::type(name.constData());
|
uint tp = QMetaType::type(name.constData());
|
||||||
return tp < QMetaType::User ? tp : 0;
|
return tp < uint(QMetaType::User) ? tp : QMetaType::UnknownType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns true if the type is a QVariant types.
|
Returns true if the type is a built-in type.
|
||||||
*/
|
*/
|
||||||
bool isVariantType(const QByteArray &type)
|
bool isBuiltinType(const QByteArray &type)
|
||||||
{
|
{
|
||||||
return qvariant_nameToType(type) != 0;
|
int id = QMetaType::type(type.constData());
|
||||||
|
if (id == QMetaType::UnknownType)
|
||||||
|
return false;
|
||||||
|
return (id < QMetaType::User);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
static const char *metaTypeEnumValueString(int type)
|
||||||
Returns true if the type is qreal.
|
{
|
||||||
*/
|
#define RETURN_METATYPENAME_STRING(MetaTypeName, MetaTypeId, RealType) \
|
||||||
static bool isQRealType(const QByteArray &type)
|
case QMetaType::MetaTypeName: return #MetaTypeName;
|
||||||
{
|
|
||||||
return (type == "qreal");
|
switch (type) {
|
||||||
}
|
QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING)
|
||||||
|
}
|
||||||
|
#undef RETURN_METATYPENAME_STRING
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Generator::Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile)
|
Generator::Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile)
|
||||||
: out(outfile), cdef(classDef), metaTypes(metaTypes)
|
: out(outfile), cdef(classDef), metaTypes(metaTypes)
|
||||||
@ -109,24 +116,28 @@ static inline int lengthOfEscapeSequence(const QByteArray &s, int i)
|
|||||||
return i - startPos;
|
return i - startPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Generator::strreg(const QByteArray &s)
|
void Generator::strreg(const QByteArray &s)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
if (!strings.contains(s))
|
||||||
for (int i = 0; i < strings.size(); ++i) {
|
strings.append(s);
|
||||||
const QByteArray &str = strings.at(i);
|
}
|
||||||
if (str == s)
|
|
||||||
return idx;
|
int Generator::stridx(const QByteArray &s)
|
||||||
idx += str.length() + 1;
|
{
|
||||||
for (int i = 0; i < str.length(); ++i) {
|
int i = strings.indexOf(s);
|
||||||
if (str.at(i) == '\\') {
|
Q_ASSERT_X(i != -1, Q_FUNC_INFO, "We forgot to register some strings");
|
||||||
int cnt = lengthOfEscapeSequence(str, i) - 1;
|
return i;
|
||||||
idx -= cnt;
|
}
|
||||||
i += cnt;
|
|
||||||
}
|
// Returns the sum of all parameters (including return type) for the given
|
||||||
}
|
// \a list of methods. This is needed for calculating the size of the methods'
|
||||||
}
|
// parameter type/name meta-data.
|
||||||
strings.append(s);
|
static int aggregateParameterCount(const QList<FunctionDef> &list)
|
||||||
return idx;
|
{
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < list.count(); ++i)
|
||||||
|
sum += list.at(i).arguments.count() + 1; // +1 for return type
|
||||||
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::generateCode()
|
void Generator::generateCode()
|
||||||
@ -135,10 +146,6 @@ void Generator::generateCode()
|
|||||||
bool isQObject = (cdef->classname == "QObject");
|
bool isQObject = (cdef->classname == "QObject");
|
||||||
bool isConstructible = !cdef->constructorList.isEmpty();
|
bool isConstructible = !cdef->constructorList.isEmpty();
|
||||||
|
|
||||||
//
|
|
||||||
// build the data array
|
|
||||||
//
|
|
||||||
|
|
||||||
// filter out undeclared enumerators and sets
|
// filter out undeclared enumerators and sets
|
||||||
{
|
{
|
||||||
QList<EnumDef> enumList;
|
QList<EnumDef> enumList;
|
||||||
@ -156,95 +163,71 @@ void Generator::generateCode()
|
|||||||
cdef->enumList = enumList;
|
cdef->enumList = enumList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register all strings used in data section
|
||||||
|
//
|
||||||
|
strreg(cdef->qualified);
|
||||||
|
registerClassInfoStrings();
|
||||||
|
registerFunctionStrings(cdef->signalList);
|
||||||
|
registerFunctionStrings(cdef->slotList);
|
||||||
|
registerFunctionStrings(cdef->methodList);
|
||||||
|
registerFunctionStrings(cdef->constructorList);
|
||||||
|
registerPropertyStrings();
|
||||||
|
registerEnumStrings();
|
||||||
|
|
||||||
QByteArray qualifiedClassNameIdentifier = cdef->qualified;
|
QByteArray qualifiedClassNameIdentifier = cdef->qualified;
|
||||||
qualifiedClassNameIdentifier.replace(':', '_');
|
qualifiedClassNameIdentifier.replace(':', '_');
|
||||||
|
|
||||||
int index = MetaObjectPrivateFieldCount;
|
|
||||||
fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
|
|
||||||
fprintf(out, "\n // content:\n");
|
|
||||||
fprintf(out, " %4d, // revision\n", int(QMetaObjectPrivate::OutputRevision));
|
|
||||||
fprintf(out, " %4d, // classname\n", strreg(cdef->qualified));
|
|
||||||
fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0);
|
|
||||||
index += cdef->classInfoList.count() * 2;
|
|
||||||
|
|
||||||
int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
|
|
||||||
fprintf(out, " %4d, %4d, // methods\n", methodCount, methodCount ? index : 0);
|
|
||||||
index += methodCount * 5;
|
|
||||||
if (cdef->revisionedMethods)
|
|
||||||
index += methodCount;
|
|
||||||
fprintf(out, " %4d, %4d, // properties\n", cdef->propertyList.count(), cdef->propertyList.count() ? index : 0);
|
|
||||||
index += cdef->propertyList.count() * 3;
|
|
||||||
if(cdef->notifyableProperties)
|
|
||||||
index += cdef->propertyList.count();
|
|
||||||
if (cdef->revisionedProperties)
|
|
||||||
index += cdef->propertyList.count();
|
|
||||||
fprintf(out, " %4d, %4d, // enums/sets\n", cdef->enumList.count(), cdef->enumList.count() ? index : 0);
|
|
||||||
|
|
||||||
int enumsIndex = index;
|
|
||||||
for (int i = 0; i < cdef->enumList.count(); ++i)
|
|
||||||
index += 4 + (cdef->enumList.at(i).values.count() * 2);
|
|
||||||
fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0,
|
|
||||||
isConstructible ? index : 0);
|
|
||||||
|
|
||||||
fprintf(out, " %4d, // flags\n", 0);
|
|
||||||
fprintf(out, " %4d, // signalCount\n", cdef->signalList.count());
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build classinfo array
|
// Build stringdata struct
|
||||||
//
|
//
|
||||||
generateClassInfos();
|
fprintf(out, "struct qt_meta_stringdata_%s_t {\n", qualifiedClassNameIdentifier.constData());
|
||||||
|
fprintf(out, " QByteArrayData data[%d];\n", strings.size());
|
||||||
//
|
{
|
||||||
// Build signals array first, otherwise the signal indices would be wrong
|
int len = 0;
|
||||||
//
|
for (int i = 0; i < strings.size(); ++i)
|
||||||
generateFunctions(cdef->signalList, "signal", MethodSignal);
|
len += strings.at(i).length() + 1;
|
||||||
|
fprintf(out, " char stringdata[%d];\n", len + 1);
|
||||||
//
|
|
||||||
// Build slots array
|
|
||||||
//
|
|
||||||
generateFunctions(cdef->slotList, "slot", MethodSlot);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Build method array
|
|
||||||
//
|
|
||||||
generateFunctions(cdef->methodList, "method", MethodMethod);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Build method version arrays
|
|
||||||
//
|
|
||||||
if (cdef->revisionedMethods) {
|
|
||||||
generateFunctionRevisions(cdef->signalList, "signal");
|
|
||||||
generateFunctionRevisions(cdef->slotList, "slot");
|
|
||||||
generateFunctionRevisions(cdef->methodList, "method");
|
|
||||||
}
|
}
|
||||||
|
fprintf(out, "};\n");
|
||||||
|
|
||||||
//
|
// Macro that expands into a QByteArrayData. The offset member is
|
||||||
// Build property array
|
// calculated from 1) the offset of the actual characters in the
|
||||||
//
|
// stringdata.stringdata member, and 2) the stringdata.data index of the
|
||||||
generateProperties();
|
// QByteArrayData being defined. This calculation relies on the
|
||||||
|
// QByteArrayData::data() implementation returning simply "this + offset".
|
||||||
|
fprintf(out, "#define QT_MOC_LITERAL(idx, ofs, len) { \\\n"
|
||||||
|
" Q_REFCOUNT_INITIALIZE_STATIC, len, 0, 0, \\\n"
|
||||||
|
" offsetof(qt_meta_stringdata_%s_t, stringdata) + ofs \\\n"
|
||||||
|
" - idx * sizeof(QByteArrayData) \\\n"
|
||||||
|
" }\n",
|
||||||
|
qualifiedClassNameIdentifier.constData());
|
||||||
|
|
||||||
//
|
fprintf(out, "static const qt_meta_stringdata_%s_t qt_meta_stringdata_%s = {\n",
|
||||||
// Build enums array
|
qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData());
|
||||||
//
|
fprintf(out, " {\n");
|
||||||
generateEnums(enumsIndex);
|
{
|
||||||
|
int idx = 0;
|
||||||
//
|
for (int i = 0; i < strings.size(); ++i) {
|
||||||
// Build constructors array
|
if (i)
|
||||||
//
|
fprintf(out, ",\n");
|
||||||
if (isConstructible)
|
const QByteArray &str = strings.at(i);
|
||||||
generateFunctions(cdef->constructorList, "constructor", MethodConstructor);
|
fprintf(out, "QT_MOC_LITERAL(%d, %d, %d)", i, idx, str.length());
|
||||||
|
idx += str.length() + 1;
|
||||||
//
|
for (int j = 0; j < str.length(); ++j) {
|
||||||
// Terminate data array
|
if (str.at(j) == '\\') {
|
||||||
//
|
int cnt = lengthOfEscapeSequence(str, j) - 1;
|
||||||
fprintf(out, "\n 0 // eod\n};\n\n");
|
idx -= cnt;
|
||||||
|
j += cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(out, "\n },\n");
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build stringdata array
|
// Build stringdata array
|
||||||
//
|
//
|
||||||
fprintf(out, "static const char qt_meta_stringdata_%s[] = {\n", qualifiedClassNameIdentifier.constData());
|
|
||||||
fprintf(out, " \"");
|
fprintf(out, " \"");
|
||||||
int col = 0;
|
int col = 0;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@ -279,7 +262,113 @@ void Generator::generateCode()
|
|||||||
fputs("\\0", out);
|
fputs("\\0", out);
|
||||||
col += len + 2;
|
col += len + 2;
|
||||||
}
|
}
|
||||||
fprintf(out, "\"\n};\n\n");
|
|
||||||
|
// Terminate stringdata struct
|
||||||
|
fprintf(out, "\"\n};\n");
|
||||||
|
fprintf(out, "#undef QT_MOC_LITERAL\n\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// build the data array
|
||||||
|
//
|
||||||
|
|
||||||
|
int index = MetaObjectPrivateFieldCount;
|
||||||
|
fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
|
||||||
|
fprintf(out, "\n // content:\n");
|
||||||
|
fprintf(out, " %4d, // revision\n", int(QMetaObjectPrivate::OutputRevision));
|
||||||
|
fprintf(out, " %4d, // classname\n", stridx(cdef->qualified));
|
||||||
|
fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0);
|
||||||
|
index += cdef->classInfoList.count() * 2;
|
||||||
|
|
||||||
|
int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
|
||||||
|
fprintf(out, " %4d, %4d, // methods\n", methodCount, methodCount ? index : 0);
|
||||||
|
index += methodCount * 5;
|
||||||
|
if (cdef->revisionedMethods)
|
||||||
|
index += methodCount;
|
||||||
|
int paramsIndex = index;
|
||||||
|
int totalParameterCount = aggregateParameterCount(cdef->signalList)
|
||||||
|
+ aggregateParameterCount(cdef->slotList)
|
||||||
|
+ aggregateParameterCount(cdef->methodList)
|
||||||
|
+ aggregateParameterCount(cdef->constructorList);
|
||||||
|
index += totalParameterCount * 2 // types and parameter names
|
||||||
|
- methodCount // return "parameters" don't have names
|
||||||
|
- cdef->constructorList.count(); // "this" parameters don't have names
|
||||||
|
|
||||||
|
fprintf(out, " %4d, %4d, // properties\n", cdef->propertyList.count(), cdef->propertyList.count() ? index : 0);
|
||||||
|
index += cdef->propertyList.count() * 3;
|
||||||
|
if(cdef->notifyableProperties)
|
||||||
|
index += cdef->propertyList.count();
|
||||||
|
if (cdef->revisionedProperties)
|
||||||
|
index += cdef->propertyList.count();
|
||||||
|
fprintf(out, " %4d, %4d, // enums/sets\n", cdef->enumList.count(), cdef->enumList.count() ? index : 0);
|
||||||
|
|
||||||
|
int enumsIndex = index;
|
||||||
|
for (int i = 0; i < cdef->enumList.count(); ++i)
|
||||||
|
index += 4 + (cdef->enumList.at(i).values.count() * 2);
|
||||||
|
fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0,
|
||||||
|
isConstructible ? index : 0);
|
||||||
|
|
||||||
|
fprintf(out, " %4d, // flags\n", 0);
|
||||||
|
fprintf(out, " %4d, // signalCount\n", cdef->signalList.count());
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build classinfo array
|
||||||
|
//
|
||||||
|
generateClassInfos();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build signals array first, otherwise the signal indices would be wrong
|
||||||
|
//
|
||||||
|
generateFunctions(cdef->signalList, "signal", MethodSignal, paramsIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build slots array
|
||||||
|
//
|
||||||
|
generateFunctions(cdef->slotList, "slot", MethodSlot, paramsIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build method array
|
||||||
|
//
|
||||||
|
generateFunctions(cdef->methodList, "method", MethodMethod, paramsIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build method version arrays
|
||||||
|
//
|
||||||
|
if (cdef->revisionedMethods) {
|
||||||
|
generateFunctionRevisions(cdef->signalList, "signal");
|
||||||
|
generateFunctionRevisions(cdef->slotList, "slot");
|
||||||
|
generateFunctionRevisions(cdef->methodList, "method");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build method parameters array
|
||||||
|
//
|
||||||
|
generateFunctionParameters(cdef->signalList, "signal");
|
||||||
|
generateFunctionParameters(cdef->slotList, "slot");
|
||||||
|
generateFunctionParameters(cdef->methodList, "method");
|
||||||
|
if (isConstructible)
|
||||||
|
generateFunctionParameters(cdef->constructorList, "constructor");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build property array
|
||||||
|
//
|
||||||
|
generateProperties();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build enums array
|
||||||
|
//
|
||||||
|
generateEnums(enumsIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build constructors array
|
||||||
|
//
|
||||||
|
if (isConstructible)
|
||||||
|
generateFunctions(cdef->constructorList, "constructor", MethodConstructor, paramsIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Terminate data array
|
||||||
|
//
|
||||||
|
fprintf(out, "\n 0 // eod\n};\n\n");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Generate internal qt_static_metacall() function
|
// Generate internal qt_static_metacall() function
|
||||||
@ -293,7 +382,7 @@ void Generator::generateCode()
|
|||||||
QList<QByteArray> extraList;
|
QList<QByteArray> extraList;
|
||||||
for (int i = 0; i < cdef->propertyList.count(); ++i) {
|
for (int i = 0; i < cdef->propertyList.count(); ++i) {
|
||||||
const PropertyDef &p = cdef->propertyList.at(i);
|
const PropertyDef &p = cdef->propertyList.at(i);
|
||||||
if (!isVariantType(p.type) && !metaTypes.contains(p.type) && !p.type.contains('*') &&
|
if (!isBuiltinType(p.type) && !metaTypes.contains(p.type) && !p.type.contains('*') &&
|
||||||
!p.type.contains('<') && !p.type.contains('>')) {
|
!p.type.contains('<') && !p.type.contains('>')) {
|
||||||
int s = p.type.lastIndexOf("::");
|
int s = p.type.lastIndexOf("::");
|
||||||
if (s > 0) {
|
if (s > 0) {
|
||||||
@ -356,8 +445,9 @@ void Generator::generateCode()
|
|||||||
fprintf(out, " { &%s::staticMetaObject, ", purestSuperClass.constData());
|
fprintf(out, " { &%s::staticMetaObject, ", purestSuperClass.constData());
|
||||||
else
|
else
|
||||||
fprintf(out, " { 0, ");
|
fprintf(out, " { 0, ");
|
||||||
fprintf(out, "qt_meta_stringdata_%s,\n qt_meta_data_%s, ",
|
fprintf(out, "qt_meta_stringdata_%s.data,\n"
|
||||||
qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData());
|
" qt_meta_data_%s, ", qualifiedClassNameIdentifier.constData(),
|
||||||
|
qualifiedClassNameIdentifier.constData());
|
||||||
if (!hasExtraData)
|
if (!hasExtraData)
|
||||||
fprintf(out, "0 }\n");
|
fprintf(out, "0 }\n");
|
||||||
else
|
else
|
||||||
@ -379,7 +469,7 @@ void Generator::generateCode()
|
|||||||
//
|
//
|
||||||
fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData());
|
fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData());
|
||||||
fprintf(out, " if (!_clname) return 0;\n");
|
fprintf(out, " if (!_clname) return 0;\n");
|
||||||
fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s))\n"
|
fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata))\n"
|
||||||
" return static_cast<void*>(const_cast< %s*>(this));\n",
|
" return static_cast<void*>(const_cast< %s*>(this));\n",
|
||||||
qualifiedClassNameIdentifier.constData(), cdef->classname.constData());
|
qualifiedClassNameIdentifier.constData(), cdef->classname.constData());
|
||||||
for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one
|
for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one
|
||||||
@ -430,6 +520,15 @@ void Generator::generateCode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Generator::registerClassInfoStrings()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cdef->classInfoList.size(); ++i) {
|
||||||
|
const ClassInfoDef &c = cdef->classInfoList.at(i);
|
||||||
|
strreg(c.name);
|
||||||
|
strreg(c.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Generator::generateClassInfos()
|
void Generator::generateClassInfos()
|
||||||
{
|
{
|
||||||
if (cdef->classInfoList.isEmpty())
|
if (cdef->classInfoList.isEmpty())
|
||||||
@ -439,32 +538,37 @@ void Generator::generateClassInfos()
|
|||||||
|
|
||||||
for (int i = 0; i < cdef->classInfoList.size(); ++i) {
|
for (int i = 0; i < cdef->classInfoList.size(); ++i) {
|
||||||
const ClassInfoDef &c = cdef->classInfoList.at(i);
|
const ClassInfoDef &c = cdef->classInfoList.at(i);
|
||||||
fprintf(out, " %4d, %4d,\n", strreg(c.name), strreg(c.value));
|
fprintf(out, " %4d, %4d,\n", stridx(c.name), stridx(c.value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::generateFunctions(const QList<FunctionDef>& list, const char *functype, int type)
|
void Generator::registerFunctionStrings(const QList<FunctionDef>& list)
|
||||||
{
|
{
|
||||||
if (list.isEmpty())
|
|
||||||
return;
|
|
||||||
fprintf(out, "\n // %ss: signature, parameters, type, tag, flags\n", functype);
|
|
||||||
|
|
||||||
for (int i = 0; i < list.count(); ++i) {
|
for (int i = 0; i < list.count(); ++i) {
|
||||||
const FunctionDef &f = list.at(i);
|
const FunctionDef &f = list.at(i);
|
||||||
|
|
||||||
QByteArray sig = f.name + '(';
|
strreg(f.name);
|
||||||
QByteArray arguments;
|
if (!isBuiltinType(f.normalizedType))
|
||||||
|
strreg(f.normalizedType);
|
||||||
|
strreg(f.tag);
|
||||||
|
|
||||||
for (int j = 0; j < f.arguments.count(); ++j) {
|
for (int j = 0; j < f.arguments.count(); ++j) {
|
||||||
const ArgumentDef &a = f.arguments.at(j);
|
const ArgumentDef &a = f.arguments.at(j);
|
||||||
if (j) {
|
if (!isBuiltinType(a.normalizedType))
|
||||||
sig += ",";
|
strreg(a.normalizedType);
|
||||||
arguments += ",";
|
strreg(a.name);
|
||||||
}
|
|
||||||
sig += a.normalizedType;
|
|
||||||
arguments += a.name;
|
|
||||||
}
|
}
|
||||||
sig += ')';
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Generator::generateFunctions(const QList<FunctionDef>& list, const char *functype, int type, int ¶msIndex)
|
||||||
|
{
|
||||||
|
if (list.isEmpty())
|
||||||
|
return;
|
||||||
|
fprintf(out, "\n // %ss: name, argc, parameters, tag, flags\n", functype);
|
||||||
|
|
||||||
|
for (int i = 0; i < list.count(); ++i) {
|
||||||
|
const FunctionDef &f = list.at(i);
|
||||||
|
|
||||||
unsigned char flags = type;
|
unsigned char flags = type;
|
||||||
if (f.access == FunctionDef::Private)
|
if (f.access == FunctionDef::Private)
|
||||||
@ -487,8 +591,12 @@ void Generator::generateFunctions(const QList<FunctionDef>& list, const char *fu
|
|||||||
flags |= MethodScriptable;
|
flags |= MethodScriptable;
|
||||||
if (f.revision > 0)
|
if (f.revision > 0)
|
||||||
flags |= MethodRevisioned;
|
flags |= MethodRevisioned;
|
||||||
fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x,\n", strreg(sig),
|
|
||||||
strreg(arguments), strreg(f.normalizedType), strreg(f.tag), flags);
|
int argc = f.arguments.count();
|
||||||
|
fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x,\n",
|
||||||
|
stridx(f.name), argc, paramsIndex, stridx(f.tag), flags);
|
||||||
|
|
||||||
|
paramsIndex += 1 + argc * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,6 +610,54 @@ void Generator::generateFunctionRevisions(const QList<FunctionDef>& list, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Generator::generateFunctionParameters(const QList<FunctionDef>& list, const char *functype)
|
||||||
|
{
|
||||||
|
if (list.isEmpty())
|
||||||
|
return;
|
||||||
|
fprintf(out, "\n // %ss: parameters\n", functype);
|
||||||
|
for (int i = 0; i < list.count(); ++i) {
|
||||||
|
const FunctionDef &f = list.at(i);
|
||||||
|
fprintf(out, " ");
|
||||||
|
|
||||||
|
// Types
|
||||||
|
for (int j = -1; j < f.arguments.count(); ++j) {
|
||||||
|
if (j > -1)
|
||||||
|
fputc(' ', out);
|
||||||
|
const QByteArray &typeName = (j < 0) ? f.normalizedType : f.arguments.at(j).normalizedType;
|
||||||
|
if (isBuiltinType(typeName)) {
|
||||||
|
int type = nameToBuiltinType(typeName);
|
||||||
|
const char *valueString = metaTypeEnumValueString(type);
|
||||||
|
if (valueString)
|
||||||
|
fprintf(out, "QMetaType::%s", valueString);
|
||||||
|
else
|
||||||
|
fprintf(out, "%4d", type);
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(!typeName.isEmpty() || f.isConstructor);
|
||||||
|
fprintf(out, "0x%.8x | %d", IsUnresolvedType, stridx(typeName));
|
||||||
|
}
|
||||||
|
fputc(',', out);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter names
|
||||||
|
for (int j = 0; j < f.arguments.count(); ++j) {
|
||||||
|
const ArgumentDef &arg = f.arguments.at(j);
|
||||||
|
fprintf(out, " %4d,", stridx(arg.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Generator::registerPropertyStrings()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cdef->propertyList.count(); ++i) {
|
||||||
|
const PropertyDef &p = cdef->propertyList.at(i);
|
||||||
|
strreg(p.name);
|
||||||
|
if (!isBuiltinType(p.type))
|
||||||
|
strreg(p.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Generator::generateProperties()
|
void Generator::generateProperties()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -513,11 +669,8 @@ void Generator::generateProperties()
|
|||||||
for (int i = 0; i < cdef->propertyList.count(); ++i) {
|
for (int i = 0; i < cdef->propertyList.count(); ++i) {
|
||||||
const PropertyDef &p = cdef->propertyList.at(i);
|
const PropertyDef &p = cdef->propertyList.at(i);
|
||||||
uint flags = Invalid;
|
uint flags = Invalid;
|
||||||
if (!isVariantType(p.type)) {
|
if (!isBuiltinType(p.type))
|
||||||
flags |= EnumOrFlag;
|
flags |= EnumOrFlag;
|
||||||
} else if (!isQRealType(p.type)) {
|
|
||||||
flags |= qvariant_nameToType(p.type) << 24;
|
|
||||||
}
|
|
||||||
if (!p.read.isEmpty())
|
if (!p.read.isEmpty())
|
||||||
flags |= Readable;
|
flags |= Readable;
|
||||||
if (!p.write.isEmpty()) {
|
if (!p.write.isEmpty()) {
|
||||||
@ -567,12 +720,20 @@ void Generator::generateProperties()
|
|||||||
if (p.final)
|
if (p.final)
|
||||||
flags |= Final;
|
flags |= Final;
|
||||||
|
|
||||||
fprintf(out, " %4d, %4d, ",
|
fprintf(out, " %4d, ", stridx(p.name));
|
||||||
strreg(p.name),
|
|
||||||
strreg(p.type));
|
if (isBuiltinType(p.type)) {
|
||||||
if (!(flags >> 24) && isQRealType(p.type))
|
int type = nameToBuiltinType(p.type);
|
||||||
fprintf(out, "(QMetaType::QReal << 24) | ");
|
const char *valueString = metaTypeEnumValueString(type);
|
||||||
fprintf(out, "0x%.8x,\n", flags);
|
if (valueString)
|
||||||
|
fprintf(out, "QMetaType::%s", valueString);
|
||||||
|
else
|
||||||
|
fprintf(out, "%4d", type);
|
||||||
|
} else {
|
||||||
|
fprintf(out, "0x%.8x | %d", IsUnresolvedType, stridx(p.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, ", 0x%.8x,\n", flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cdef->notifyableProperties) {
|
if(cdef->notifyableProperties) {
|
||||||
@ -596,6 +757,16 @@ void Generator::generateProperties()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Generator::registerEnumStrings()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cdef->enumList.count(); ++i) {
|
||||||
|
const EnumDef &e = cdef->enumList.at(i);
|
||||||
|
strreg(e.name);
|
||||||
|
for (int j = 0; j < e.values.count(); ++j)
|
||||||
|
strreg(e.values.at(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Generator::generateEnums(int index)
|
void Generator::generateEnums(int index)
|
||||||
{
|
{
|
||||||
if (cdef->enumDeclarations.isEmpty())
|
if (cdef->enumDeclarations.isEmpty())
|
||||||
@ -607,7 +778,7 @@ void Generator::generateEnums(int index)
|
|||||||
for (i = 0; i < cdef->enumList.count(); ++i) {
|
for (i = 0; i < cdef->enumList.count(); ++i) {
|
||||||
const EnumDef &e = cdef->enumList.at(i);
|
const EnumDef &e = cdef->enumList.at(i);
|
||||||
fprintf(out, " %4d, 0x%.1x, %4d, %4d,\n",
|
fprintf(out, " %4d, 0x%.1x, %4d, %4d,\n",
|
||||||
strreg(e.name),
|
stridx(e.name),
|
||||||
cdef->enumDeclarations.value(e.name) ? 1 : 0,
|
cdef->enumDeclarations.value(e.name) ? 1 : 0,
|
||||||
e.values.count(),
|
e.values.count(),
|
||||||
index);
|
index);
|
||||||
@ -624,7 +795,7 @@ void Generator::generateEnums(int index)
|
|||||||
code += "::" + e.name;
|
code += "::" + e.name;
|
||||||
code += "::" + val;
|
code += "::" + val;
|
||||||
fprintf(out, " %4d, uint(%s),\n",
|
fprintf(out, " %4d, uint(%s),\n",
|
||||||
strreg(val), code.constData());
|
stridx(val), code.constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,8 +1097,9 @@ void Generator::generateStaticMetacall()
|
|||||||
fprintf(out, " switch (_id) {\n");
|
fprintf(out, " switch (_id) {\n");
|
||||||
for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
|
for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
|
||||||
const FunctionDef &f = methodList.at(methodindex);
|
const FunctionDef &f = methodList.at(methodindex);
|
||||||
|
Q_ASSERT(!f.normalizedType.isEmpty());
|
||||||
fprintf(out, " case %d: ", methodindex);
|
fprintf(out, " case %d: ", methodindex);
|
||||||
if (f.normalizedType.size())
|
if (f.normalizedType != "void")
|
||||||
fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData());
|
fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData());
|
||||||
fprintf(out, "_t->");
|
fprintf(out, "_t->");
|
||||||
if (f.inPrivateClass.size())
|
if (f.inPrivateClass.size())
|
||||||
@ -942,7 +1114,7 @@ void Generator::generateStaticMetacall()
|
|||||||
isUsed_a = true;
|
isUsed_a = true;
|
||||||
}
|
}
|
||||||
fprintf(out, ");");
|
fprintf(out, ");");
|
||||||
if (f.normalizedType.size()) {
|
if (f.normalizedType != "void") {
|
||||||
fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ",
|
fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ",
|
||||||
noRef(f.normalizedType).constData());
|
noRef(f.normalizedType).constData());
|
||||||
isUsed_a = true;
|
isUsed_a = true;
|
||||||
@ -1021,7 +1193,8 @@ void Generator::generateSignal(FunctionDef *def,int index)
|
|||||||
constQualifier = "const";
|
constQualifier = "const";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->arguments.isEmpty() && def->normalizedType.isEmpty()) {
|
Q_ASSERT(!def->normalizedType.isEmpty());
|
||||||
|
if (def->arguments.isEmpty() && def->normalizedType == "void") {
|
||||||
fprintf(out, ")%s\n{\n"
|
fprintf(out, ")%s\n{\n"
|
||||||
" QMetaObject::activate(%s, &staticMetaObject, %d, 0);\n"
|
" QMetaObject::activate(%s, &staticMetaObject, %d, 0);\n"
|
||||||
"}\n", constQualifier, thisPtr.constData(), index);
|
"}\n", constQualifier, thisPtr.constData(), index);
|
||||||
@ -1036,11 +1209,11 @@ void Generator::generateSignal(FunctionDef *def,int index)
|
|||||||
fprintf(out, "%s _t%d%s", a.type.name.constData(), offset++, a.rightType.constData());
|
fprintf(out, "%s _t%d%s", a.type.name.constData(), offset++, a.rightType.constData());
|
||||||
}
|
}
|
||||||
fprintf(out, ")%s\n{\n", constQualifier);
|
fprintf(out, ")%s\n{\n", constQualifier);
|
||||||
if (def->type.name.size() && def->normalizedType.size())
|
if (def->type.name.size() && def->normalizedType != "void")
|
||||||
fprintf(out, " %s _t0 = %s();\n", noRef(def->normalizedType).constData(), noRef(def->normalizedType).constData());
|
fprintf(out, " %s _t0 = %s();\n", noRef(def->normalizedType).constData(), noRef(def->normalizedType).constData());
|
||||||
|
|
||||||
fprintf(out, " void *_a[] = { ");
|
fprintf(out, " void *_a[] = { ");
|
||||||
if (def->normalizedType.isEmpty()) {
|
if (def->normalizedType == "void") {
|
||||||
fprintf(out, "0");
|
fprintf(out, "0");
|
||||||
} else {
|
} else {
|
||||||
if (def->returnTypeIsVolatile)
|
if (def->returnTypeIsVolatile)
|
||||||
@ -1056,7 +1229,7 @@ void Generator::generateSignal(FunctionDef *def,int index)
|
|||||||
fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(&_t%d))", i);
|
fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(&_t%d))", i);
|
||||||
fprintf(out, " };\n");
|
fprintf(out, " };\n");
|
||||||
fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index);
|
fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index);
|
||||||
if (def->normalizedType.size())
|
if (def->normalizedType != "void")
|
||||||
fprintf(out, " return _t0;\n");
|
fprintf(out, " return _t0;\n");
|
||||||
fprintf(out, "}\n");
|
fprintf(out, "}\n");
|
||||||
}
|
}
|
||||||
|
@ -55,17 +55,23 @@ public:
|
|||||||
Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile = 0);
|
Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile = 0);
|
||||||
void generateCode();
|
void generateCode();
|
||||||
private:
|
private:
|
||||||
|
void registerClassInfoStrings();
|
||||||
void generateClassInfos();
|
void generateClassInfos();
|
||||||
void generateFunctions(const QList<FunctionDef> &list, const char *functype, int type);
|
void registerFunctionStrings(const QList<FunctionDef> &list);
|
||||||
|
void generateFunctions(const QList<FunctionDef> &list, const char *functype, int type, int ¶msIndex);
|
||||||
void generateFunctionRevisions(const QList<FunctionDef>& list, const char *functype);
|
void generateFunctionRevisions(const QList<FunctionDef>& list, const char *functype);
|
||||||
|
void generateFunctionParameters(const QList<FunctionDef> &list, const char *functype);
|
||||||
|
void registerEnumStrings();
|
||||||
void generateEnums(int index);
|
void generateEnums(int index);
|
||||||
|
void registerPropertyStrings();
|
||||||
void generateProperties();
|
void generateProperties();
|
||||||
void generateMetacall();
|
void generateMetacall();
|
||||||
void generateStaticMetacall();
|
void generateStaticMetacall();
|
||||||
void generateSignal(FunctionDef *def, int index);
|
void generateSignal(FunctionDef *def, int index);
|
||||||
void generatePluginMetaData();
|
void generatePluginMetaData();
|
||||||
|
|
||||||
int strreg(const QByteArray &); // registers a string and returns its id
|
void strreg(const QByteArray &); // registers a string
|
||||||
|
int stridx(const QByteArray &); // returns a string's id
|
||||||
QList<QByteArray> strings;
|
QList<QByteArray> strings;
|
||||||
QByteArray purestSuperClass;
|
QByteArray purestSuperClass;
|
||||||
QList<QByteArray> metaTypes;
|
QList<QByteArray> metaTypes;
|
||||||
|
@ -75,9 +75,7 @@ static QByteArray normalizeType(const QByteArray &ba, bool fixScope = false)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*d = '\0';
|
*d = '\0';
|
||||||
QByteArray result;
|
QByteArray result = normalizeTypeInternal(buf, d, fixScope);
|
||||||
if (strncmp("void", buf, d - buf) != 0)
|
|
||||||
result = normalizeTypeInternal(buf, d, fixScope);
|
|
||||||
if (buf != stackbuf)
|
if (buf != stackbuf)
|
||||||
delete [] buf;
|
delete [] buf;
|
||||||
return result;
|
return result;
|
||||||
@ -822,8 +820,8 @@ void Moc::generate(FILE *out)
|
|||||||
if (classList.size() && classList.first().classname == "Qt")
|
if (classList.size() && classList.first().classname == "Qt")
|
||||||
fprintf(out, "#include <QtCore/qobject.h>\n");
|
fprintf(out, "#include <QtCore/qobject.h>\n");
|
||||||
|
|
||||||
if (mustIncludeQMetaTypeH)
|
fprintf(out, "#include <QtCore/qbytearray.h>\n"); // For QByteArrayData
|
||||||
fprintf(out, "#include <QtCore/qmetatype.h>\n");
|
fprintf(out, "#include <QtCore/qmetatype.h>\n"); // For QMetaType::Type
|
||||||
if (mustIncludeQPluginH)
|
if (mustIncludeQPluginH)
|
||||||
fprintf(out, "#include <QtCore/qplugin.h>\n");
|
fprintf(out, "#include <QtCore/qplugin.h>\n");
|
||||||
|
|
||||||
@ -981,8 +979,6 @@ void Moc::createPropertyDef(PropertyDef &propDef)
|
|||||||
type = "qlonglong";
|
type = "qlonglong";
|
||||||
else if (type == "ULongLong")
|
else if (type == "ULongLong")
|
||||||
type = "qulonglong";
|
type = "qulonglong";
|
||||||
else if (type == "qreal")
|
|
||||||
mustIncludeQMetaTypeH = true;
|
|
||||||
|
|
||||||
propDef.type = type;
|
propDef.type = type;
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ class Moc : public Parser
|
|||||||
public:
|
public:
|
||||||
Moc(Preprocessor &p)
|
Moc(Preprocessor &p)
|
||||||
: preprocessor(p), noInclude(false), generatedCode(false),
|
: preprocessor(p), noInclude(false), generatedCode(false),
|
||||||
mustIncludeQMetaTypeH(false), mustIncludeQPluginH(false)
|
mustIncludeQPluginH(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QByteArray filename;
|
QByteArray filename;
|
||||||
@ -208,7 +208,6 @@ public:
|
|||||||
Preprocessor &preprocessor;
|
Preprocessor &preprocessor;
|
||||||
bool noInclude;
|
bool noInclude;
|
||||||
bool generatedCode;
|
bool generatedCode;
|
||||||
bool mustIncludeQMetaTypeH;
|
|
||||||
bool mustIncludeQPluginH;
|
bool mustIncludeQPluginH;
|
||||||
QByteArray includePath;
|
QByteArray includePath;
|
||||||
QList<QByteArray> includeFiles;
|
QList<QByteArray> includeFiles;
|
||||||
|
@ -43,6 +43,6 @@
|
|||||||
#define OUTPUTREVISION_H
|
#define OUTPUTREVISION_H
|
||||||
|
|
||||||
// if the output revision changes, you MUST change it in qobjectdefs.h too
|
// if the output revision changes, you MUST change it in qobjectdefs.h too
|
||||||
enum { mocOutputRevision = 64 }; // moc format output revision
|
enum { mocOutputRevision = 65 }; // moc format output revision
|
||||||
|
|
||||||
#endif // OUTPUTREVISION_H
|
#endif // OUTPUTREVISION_H
|
||||||
|
@ -223,7 +223,7 @@ void tst_QMetaMethod::method_data()
|
|||||||
|
|
||||||
QTest::newRow("MethodTestObject()")
|
QTest::newRow("MethodTestObject()")
|
||||||
<< QByteArray("MethodTestObject()")
|
<< QByteArray("MethodTestObject()")
|
||||||
<< int(QMetaType::Void) << QByteArray("")
|
<< int(QMetaType::UnknownType) << QByteArray("")
|
||||||
<< (QList<int>())
|
<< (QList<int>())
|
||||||
<< (QList<QByteArray>())
|
<< (QList<QByteArray>())
|
||||||
<< (QList<QByteArray>())
|
<< (QList<QByteArray>())
|
||||||
@ -259,7 +259,7 @@ void tst_QMetaMethod::method_data()
|
|||||||
|
|
||||||
QTest::newRow("MethodTestObject(int)")
|
QTest::newRow("MethodTestObject(int)")
|
||||||
<< QByteArray("MethodTestObject(int)")
|
<< QByteArray("MethodTestObject(int)")
|
||||||
<< int(QMetaType::Void) << QByteArray("")
|
<< int(QMetaType::UnknownType) << QByteArray("")
|
||||||
<< (QList<int>() << int(QMetaType::Int))
|
<< (QList<int>() << int(QMetaType::Int))
|
||||||
<< (QList<QByteArray>() << QByteArray("int"))
|
<< (QList<QByteArray>() << QByteArray("int"))
|
||||||
<< (QList<QByteArray>() << QByteArray("constructorIntArg"))
|
<< (QList<QByteArray>() << QByteArray("constructorIntArg"))
|
||||||
@ -295,7 +295,7 @@ void tst_QMetaMethod::method_data()
|
|||||||
|
|
||||||
QTest::newRow("MethodTestObject(qreal)")
|
QTest::newRow("MethodTestObject(qreal)")
|
||||||
<< QByteArray("MethodTestObject(qreal)")
|
<< QByteArray("MethodTestObject(qreal)")
|
||||||
<< int(QMetaType::Void) << QByteArray("")
|
<< int(QMetaType::UnknownType) << QByteArray("")
|
||||||
<< (QList<int>() << qMetaTypeId<qreal>())
|
<< (QList<int>() << qMetaTypeId<qreal>())
|
||||||
<< (QList<QByteArray>() << QByteArray("qreal"))
|
<< (QList<QByteArray>() << QByteArray("qreal"))
|
||||||
<< (QList<QByteArray>() << QByteArray("constructorQRealArg"))
|
<< (QList<QByteArray>() << QByteArray("constructorQRealArg"))
|
||||||
@ -331,7 +331,7 @@ void tst_QMetaMethod::method_data()
|
|||||||
|
|
||||||
QTest::newRow("MethodTestObject(QString)")
|
QTest::newRow("MethodTestObject(QString)")
|
||||||
<< QByteArray("MethodTestObject(QString)")
|
<< QByteArray("MethodTestObject(QString)")
|
||||||
<< int(QMetaType::Void) << QByteArray("")
|
<< int(QMetaType::UnknownType) << QByteArray("")
|
||||||
<< (QList<int>() << int(QMetaType::QString))
|
<< (QList<int>() << int(QMetaType::QString))
|
||||||
<< (QList<QByteArray>() << QByteArray("QString"))
|
<< (QList<QByteArray>() << QByteArray("QString"))
|
||||||
<< (QList<QByteArray>() << QByteArray("constructorQStringArg"))
|
<< (QList<QByteArray>() << QByteArray("constructorQStringArg"))
|
||||||
@ -367,7 +367,7 @@ void tst_QMetaMethod::method_data()
|
|||||||
|
|
||||||
QTest::newRow("MethodTestObject(CustomType)")
|
QTest::newRow("MethodTestObject(CustomType)")
|
||||||
<< QByteArray("MethodTestObject(CustomType)")
|
<< QByteArray("MethodTestObject(CustomType)")
|
||||||
<< int(QMetaType::Void) << QByteArray("")
|
<< int(QMetaType::UnknownType) << QByteArray("")
|
||||||
<< (QList<int>() << qMetaTypeId<CustomType>())
|
<< (QList<int>() << qMetaTypeId<CustomType>())
|
||||||
<< (QList<QByteArray>() << QByteArray("CustomType"))
|
<< (QList<QByteArray>() << QByteArray("CustomType"))
|
||||||
<< (QList<QByteArray>() << QByteArray("constructorCustomTypeArg"))
|
<< (QList<QByteArray>() << QByteArray("constructorCustomTypeArg"))
|
||||||
@ -403,7 +403,7 @@ void tst_QMetaMethod::method_data()
|
|||||||
|
|
||||||
QTest::newRow("MethodTestObject(CustomUnregisteredType)")
|
QTest::newRow("MethodTestObject(CustomUnregisteredType)")
|
||||||
<< QByteArray("MethodTestObject(CustomUnregisteredType)")
|
<< QByteArray("MethodTestObject(CustomUnregisteredType)")
|
||||||
<< int(QMetaType::Void) << QByteArray("")
|
<< int(QMetaType::UnknownType) << QByteArray("")
|
||||||
<< (QList<int>() << 0)
|
<< (QList<int>() << 0)
|
||||||
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
|
<< (QList<QByteArray>() << QByteArray("CustomUnregisteredType"))
|
||||||
<< (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg"))
|
<< (QList<QByteArray>() << QByteArray("constructorCustomUnregisteredTypeArg"))
|
||||||
@ -536,7 +536,7 @@ void tst_QMetaMethod::method_data()
|
|||||||
|
|
||||||
QTest::newRow("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
|
QTest::newRow("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
|
||||||
<< QByteArray("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
|
<< QByteArray("MethodTestObject(bool,int,uint,qlonglong,qulonglong,double,long,short,char,ulong,ushort,uchar,float)")
|
||||||
<< int(QMetaType::Void) << QByteArray("")
|
<< int(QMetaType::UnknownType) << QByteArray("")
|
||||||
<< parameterTypes << parameterTypeNames << parameterNames
|
<< parameterTypes << parameterTypeNames << parameterNames
|
||||||
<< QMetaMethod::Public
|
<< QMetaMethod::Public
|
||||||
<< QMetaMethod::Constructor;
|
<< QMetaMethod::Constructor;
|
||||||
@ -571,7 +571,7 @@ void tst_QMetaMethod::method_data()
|
|||||||
|
|
||||||
QTest::newRow("MethodTestObject(bool,int)")
|
QTest::newRow("MethodTestObject(bool,int)")
|
||||||
<< QByteArray("MethodTestObject(bool,int)")
|
<< QByteArray("MethodTestObject(bool,int)")
|
||||||
<< int(QMetaType::Void) << QByteArray("")
|
<< int(QMetaType::UnknownType) << QByteArray("")
|
||||||
<< (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
|
<< (QList<int>() << int(QMetaType::Bool) << int(QMetaType::Int))
|
||||||
<< (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
|
<< (QList<QByteArray>() << QByteArray("bool") << QByteArray("int"))
|
||||||
<< (QList<QByteArray>() << QByteArray("") << QByteArray(""))
|
<< (QList<QByteArray>() << QByteArray("") << QByteArray(""))
|
||||||
@ -603,15 +603,50 @@ void tst_QMetaMethod::method()
|
|||||||
QCOMPARE(method.methodType(), methodType);
|
QCOMPARE(method.methodType(), methodType);
|
||||||
QCOMPARE(method.access(), access);
|
QCOMPARE(method.access(), access);
|
||||||
|
|
||||||
QCOMPARE(method.signature(), signature.constData());
|
QVERIFY(!method.methodSignature().isEmpty());
|
||||||
|
if (method.methodSignature() != signature) {
|
||||||
|
// QMetaMethod should always produce a semantically equivalent signature
|
||||||
|
int signatureIndex = (methodType == QMetaMethod::Constructor)
|
||||||
|
? mo->indexOfConstructor(method.methodSignature())
|
||||||
|
: mo->indexOfMethod(method.methodSignature());
|
||||||
|
QCOMPARE(signatureIndex, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray computedName = signature.left(signature.indexOf('('));
|
||||||
|
QCOMPARE(method.name(), computedName);
|
||||||
|
|
||||||
QCOMPARE(method.tag(), "");
|
QCOMPARE(method.tag(), "");
|
||||||
|
QCOMPARE(method.returnType(), returnType);
|
||||||
|
if (QByteArray(method.typeName()) != returnTypeName) {
|
||||||
|
// QMetaMethod should always produce a semantically equivalent typename
|
||||||
|
QCOMPARE(QMetaType::type(method.typeName()), QMetaType::type(returnTypeName));
|
||||||
|
}
|
||||||
|
|
||||||
QCOMPARE(method.typeName(), returnTypeName.constData());
|
if (method.parameterTypes() != parameterTypeNames) {
|
||||||
QCOMPARE(QMetaType::type(method.typeName()), returnType);
|
// QMetaMethod should always produce semantically equivalent typenames
|
||||||
|
QList<QByteArray> actualTypeNames = method.parameterTypes();
|
||||||
QCOMPARE(method.parameterTypes(), parameterTypeNames);
|
QCOMPARE(actualTypeNames.size(), parameterTypeNames.size());
|
||||||
|
for (int i = 0; i < parameterTypeNames.size(); ++i) {
|
||||||
|
QCOMPARE(QMetaType::type(actualTypeNames.at(i)),
|
||||||
|
QMetaType::type(parameterTypeNames.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
QCOMPARE(method.parameterNames(), parameterNames);
|
QCOMPARE(method.parameterNames(), parameterNames);
|
||||||
|
|
||||||
|
QCOMPARE(method.parameterCount(), parameterTypes.size());
|
||||||
|
for (int i = 0; i < parameterTypes.size(); ++i)
|
||||||
|
QCOMPARE(method.parameterType(i), parameterTypes.at(i));
|
||||||
|
|
||||||
|
{
|
||||||
|
QVector<int> actualParameterTypes(parameterTypes.size());
|
||||||
|
method.getParameterTypes(actualParameterTypes.data());
|
||||||
|
for (int i = 0; i < parameterTypes.size(); ++i)
|
||||||
|
QCOMPARE(actualParameterTypes.at(i), parameterTypes.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bogus indexes
|
||||||
|
QCOMPARE(method.parameterType(-1), 0);
|
||||||
|
QCOMPARE(method.parameterType(parameterTypes.size()), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QMetaMethod::invalidMethod()
|
void tst_QMetaMethod::invalidMethod()
|
||||||
|
@ -978,25 +978,25 @@ void tst_QMetaObject::propertyNotify()
|
|||||||
QVERIFY(prop.isValid());
|
QVERIFY(prop.isValid());
|
||||||
QVERIFY(prop.hasNotifySignal());
|
QVERIFY(prop.hasNotifySignal());
|
||||||
QMetaMethod signal = prop.notifySignal();
|
QMetaMethod signal = prop.notifySignal();
|
||||||
QCOMPARE(signal.signature(), "value6Changed()");
|
QCOMPARE(signal.methodSignature(), QByteArray("value6Changed()"));
|
||||||
|
|
||||||
prop = mo->property(mo->indexOfProperty("value7"));
|
prop = mo->property(mo->indexOfProperty("value7"));
|
||||||
QVERIFY(prop.isValid());
|
QVERIFY(prop.isValid());
|
||||||
QVERIFY(prop.hasNotifySignal());
|
QVERIFY(prop.hasNotifySignal());
|
||||||
signal = prop.notifySignal();
|
signal = prop.notifySignal();
|
||||||
QCOMPARE(signal.signature(), "value7Changed(QString)");
|
QCOMPARE(signal.methodSignature(), QByteArray("value7Changed(QString)"));
|
||||||
|
|
||||||
prop = mo->property(mo->indexOfProperty("value8"));
|
prop = mo->property(mo->indexOfProperty("value8"));
|
||||||
QVERIFY(prop.isValid());
|
QVERIFY(prop.isValid());
|
||||||
QVERIFY(!prop.hasNotifySignal());
|
QVERIFY(!prop.hasNotifySignal());
|
||||||
signal = prop.notifySignal();
|
signal = prop.notifySignal();
|
||||||
QCOMPARE(signal.signature(), (const char *)0);
|
QCOMPARE(signal.methodSignature(), QByteArray());
|
||||||
|
|
||||||
prop = mo->property(mo->indexOfProperty("value"));
|
prop = mo->property(mo->indexOfProperty("value"));
|
||||||
QVERIFY(prop.isValid());
|
QVERIFY(prop.isValid());
|
||||||
QVERIFY(!prop.hasNotifySignal());
|
QVERIFY(!prop.hasNotifySignal());
|
||||||
signal = prop.notifySignal();
|
signal = prop.notifySignal();
|
||||||
QCOMPARE(signal.signature(), (const char *)0);
|
QCOMPARE(signal.methodSignature(), QByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QMetaObject::propertyConstant()
|
void tst_QMetaObject::propertyConstant()
|
||||||
@ -1114,7 +1114,7 @@ void tst_QMetaObject::indexOfMethod()
|
|||||||
QFETCH(bool, isSignal);
|
QFETCH(bool, isSignal);
|
||||||
int idx = object->metaObject()->indexOfMethod(name);
|
int idx = object->metaObject()->indexOfMethod(name);
|
||||||
QVERIFY(idx >= 0);
|
QVERIFY(idx >= 0);
|
||||||
QCOMPARE(object->metaObject()->method(idx).signature(), name.constData());
|
QCOMPARE(object->metaObject()->method(idx).methodSignature(), name);
|
||||||
QCOMPARE(object->metaObject()->indexOfSlot(name), isSignal ? -1 : idx);
|
QCOMPARE(object->metaObject()->indexOfSlot(name), isSignal ? -1 : idx);
|
||||||
QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx);
|
QCOMPARE(object->metaObject()->indexOfSignal(name), !isSignal ? -1 : idx);
|
||||||
}
|
}
|
||||||
|
@ -217,6 +217,7 @@ void tst_QMetaObjectBuilder::method()
|
|||||||
QCOMPARE(nullMethod.signature(), QByteArray());
|
QCOMPARE(nullMethod.signature(), QByteArray());
|
||||||
QVERIFY(nullMethod.methodType() == QMetaMethod::Method);
|
QVERIFY(nullMethod.methodType() == QMetaMethod::Method);
|
||||||
QVERIFY(nullMethod.returnType().isEmpty());
|
QVERIFY(nullMethod.returnType().isEmpty());
|
||||||
|
QVERIFY(nullMethod.parameterTypes().isEmpty());
|
||||||
QVERIFY(nullMethod.parameterNames().isEmpty());
|
QVERIFY(nullMethod.parameterNames().isEmpty());
|
||||||
QVERIFY(nullMethod.tag().isEmpty());
|
QVERIFY(nullMethod.tag().isEmpty());
|
||||||
QVERIFY(nullMethod.access() == QMetaMethod::Public);
|
QVERIFY(nullMethod.access() == QMetaMethod::Public);
|
||||||
@ -229,6 +230,7 @@ void tst_QMetaObjectBuilder::method()
|
|||||||
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
||||||
QVERIFY(method1.methodType() == QMetaMethod::Method);
|
QVERIFY(method1.methodType() == QMetaMethod::Method);
|
||||||
QVERIFY(method1.returnType().isEmpty());
|
QVERIFY(method1.returnType().isEmpty());
|
||||||
|
QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
|
||||||
QVERIFY(method1.parameterNames().isEmpty());
|
QVERIFY(method1.parameterNames().isEmpty());
|
||||||
QVERIFY(method1.tag().isEmpty());
|
QVERIFY(method1.tag().isEmpty());
|
||||||
QVERIFY(method1.access() == QMetaMethod::Public);
|
QVERIFY(method1.access() == QMetaMethod::Public);
|
||||||
@ -242,6 +244,7 @@ void tst_QMetaObjectBuilder::method()
|
|||||||
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(method2.methodType() == QMetaMethod::Method);
|
QVERIFY(method2.methodType() == QMetaMethod::Method);
|
||||||
QCOMPARE(method2.returnType(), QByteArray("int"));
|
QCOMPARE(method2.returnType(), QByteArray("int"));
|
||||||
|
QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QVERIFY(method2.parameterNames().isEmpty());
|
QVERIFY(method2.parameterNames().isEmpty());
|
||||||
QVERIFY(method2.tag().isEmpty());
|
QVERIFY(method2.tag().isEmpty());
|
||||||
QVERIFY(method2.access() == QMetaMethod::Public);
|
QVERIFY(method2.access() == QMetaMethod::Public);
|
||||||
@ -267,6 +270,7 @@ void tst_QMetaObjectBuilder::method()
|
|||||||
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
||||||
QVERIFY(method1.methodType() == QMetaMethod::Method);
|
QVERIFY(method1.methodType() == QMetaMethod::Method);
|
||||||
QCOMPARE(method1.returnType(), QByteArray("int"));
|
QCOMPARE(method1.returnType(), QByteArray("int"));
|
||||||
|
QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
|
||||||
QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
||||||
QCOMPARE(method1.tag(), QByteArray("tag"));
|
QCOMPARE(method1.tag(), QByteArray("tag"));
|
||||||
QVERIFY(method1.access() == QMetaMethod::Private);
|
QVERIFY(method1.access() == QMetaMethod::Private);
|
||||||
@ -276,6 +280,7 @@ void tst_QMetaObjectBuilder::method()
|
|||||||
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(method2.methodType() == QMetaMethod::Method);
|
QVERIFY(method2.methodType() == QMetaMethod::Method);
|
||||||
QCOMPARE(method2.returnType(), QByteArray("int"));
|
QCOMPARE(method2.returnType(), QByteArray("int"));
|
||||||
|
QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QVERIFY(method2.parameterNames().isEmpty());
|
QVERIFY(method2.parameterNames().isEmpty());
|
||||||
QVERIFY(method2.tag().isEmpty());
|
QVERIFY(method2.tag().isEmpty());
|
||||||
QVERIFY(method2.access() == QMetaMethod::Public);
|
QVERIFY(method2.access() == QMetaMethod::Public);
|
||||||
@ -296,6 +301,7 @@ void tst_QMetaObjectBuilder::method()
|
|||||||
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
||||||
QVERIFY(method1.methodType() == QMetaMethod::Method);
|
QVERIFY(method1.methodType() == QMetaMethod::Method);
|
||||||
QCOMPARE(method1.returnType(), QByteArray("int"));
|
QCOMPARE(method1.returnType(), QByteArray("int"));
|
||||||
|
QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
|
||||||
QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
QCOMPARE(method1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
||||||
QCOMPARE(method1.tag(), QByteArray("tag"));
|
QCOMPARE(method1.tag(), QByteArray("tag"));
|
||||||
QVERIFY(method1.access() == QMetaMethod::Private);
|
QVERIFY(method1.access() == QMetaMethod::Private);
|
||||||
@ -305,6 +311,7 @@ void tst_QMetaObjectBuilder::method()
|
|||||||
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(method2.methodType() == QMetaMethod::Method);
|
QVERIFY(method2.methodType() == QMetaMethod::Method);
|
||||||
QCOMPARE(method2.returnType(), QByteArray("QString"));
|
QCOMPARE(method2.returnType(), QByteArray("QString"));
|
||||||
|
QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
|
QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
|
||||||
QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
|
QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
|
||||||
QVERIFY(method2.access() == QMetaMethod::Protected);
|
QVERIFY(method2.access() == QMetaMethod::Protected);
|
||||||
@ -320,6 +327,7 @@ void tst_QMetaObjectBuilder::method()
|
|||||||
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(method2.methodType() == QMetaMethod::Method);
|
QVERIFY(method2.methodType() == QMetaMethod::Method);
|
||||||
QCOMPARE(method2.returnType(), QByteArray("QString"));
|
QCOMPARE(method2.returnType(), QByteArray("QString"));
|
||||||
|
QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
|
QCOMPARE(method2.parameterNames(), QList<QByteArray>() << "c");
|
||||||
QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
|
QCOMPARE(method2.tag(), QByteArray("Q_FOO"));
|
||||||
QVERIFY(method2.access() == QMetaMethod::Protected);
|
QVERIFY(method2.access() == QMetaMethod::Protected);
|
||||||
@ -347,6 +355,7 @@ void tst_QMetaObjectBuilder::slot()
|
|||||||
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
||||||
QVERIFY(method1.methodType() == QMetaMethod::Slot);
|
QVERIFY(method1.methodType() == QMetaMethod::Slot);
|
||||||
QVERIFY(method1.returnType().isEmpty());
|
QVERIFY(method1.returnType().isEmpty());
|
||||||
|
QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
|
||||||
QVERIFY(method1.parameterNames().isEmpty());
|
QVERIFY(method1.parameterNames().isEmpty());
|
||||||
QVERIFY(method1.tag().isEmpty());
|
QVERIFY(method1.tag().isEmpty());
|
||||||
QVERIFY(method1.access() == QMetaMethod::Public);
|
QVERIFY(method1.access() == QMetaMethod::Public);
|
||||||
@ -359,6 +368,7 @@ void tst_QMetaObjectBuilder::slot()
|
|||||||
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(method2.methodType() == QMetaMethod::Slot);
|
QVERIFY(method2.methodType() == QMetaMethod::Slot);
|
||||||
QVERIFY(method2.returnType().isEmpty());
|
QVERIFY(method2.returnType().isEmpty());
|
||||||
|
QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QVERIFY(method2.parameterNames().isEmpty());
|
QVERIFY(method2.parameterNames().isEmpty());
|
||||||
QVERIFY(method2.tag().isEmpty());
|
QVERIFY(method2.tag().isEmpty());
|
||||||
QVERIFY(method2.access() == QMetaMethod::Public);
|
QVERIFY(method2.access() == QMetaMethod::Public);
|
||||||
@ -384,6 +394,7 @@ void tst_QMetaObjectBuilder::signal()
|
|||||||
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
QCOMPARE(method1.signature(), QByteArray("foo(QString,int)"));
|
||||||
QVERIFY(method1.methodType() == QMetaMethod::Signal);
|
QVERIFY(method1.methodType() == QMetaMethod::Signal);
|
||||||
QVERIFY(method1.returnType().isEmpty());
|
QVERIFY(method1.returnType().isEmpty());
|
||||||
|
QCOMPARE(method1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
|
||||||
QVERIFY(method1.parameterNames().isEmpty());
|
QVERIFY(method1.parameterNames().isEmpty());
|
||||||
QVERIFY(method1.tag().isEmpty());
|
QVERIFY(method1.tag().isEmpty());
|
||||||
QVERIFY(method1.access() == QMetaMethod::Protected);
|
QVERIFY(method1.access() == QMetaMethod::Protected);
|
||||||
@ -396,6 +407,7 @@ void tst_QMetaObjectBuilder::signal()
|
|||||||
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(method2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(method2.methodType() == QMetaMethod::Signal);
|
QVERIFY(method2.methodType() == QMetaMethod::Signal);
|
||||||
QVERIFY(method2.returnType().isEmpty());
|
QVERIFY(method2.returnType().isEmpty());
|
||||||
|
QCOMPARE(method2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QVERIFY(method2.parameterNames().isEmpty());
|
QVERIFY(method2.parameterNames().isEmpty());
|
||||||
QVERIFY(method2.tag().isEmpty());
|
QVERIFY(method2.tag().isEmpty());
|
||||||
QVERIFY(method2.access() == QMetaMethod::Protected);
|
QVERIFY(method2.access() == QMetaMethod::Protected);
|
||||||
@ -421,6 +433,7 @@ void tst_QMetaObjectBuilder::constructor()
|
|||||||
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
||||||
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
||||||
QVERIFY(ctor1.returnType().isEmpty());
|
QVERIFY(ctor1.returnType().isEmpty());
|
||||||
|
QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
|
||||||
QVERIFY(ctor1.parameterNames().isEmpty());
|
QVERIFY(ctor1.parameterNames().isEmpty());
|
||||||
QVERIFY(ctor1.tag().isEmpty());
|
QVERIFY(ctor1.tag().isEmpty());
|
||||||
QVERIFY(ctor1.access() == QMetaMethod::Public);
|
QVERIFY(ctor1.access() == QMetaMethod::Public);
|
||||||
@ -433,6 +446,7 @@ void tst_QMetaObjectBuilder::constructor()
|
|||||||
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
||||||
QVERIFY(ctor2.returnType().isEmpty());
|
QVERIFY(ctor2.returnType().isEmpty());
|
||||||
|
QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QVERIFY(ctor2.parameterNames().isEmpty());
|
QVERIFY(ctor2.parameterNames().isEmpty());
|
||||||
QVERIFY(ctor2.tag().isEmpty());
|
QVERIFY(ctor2.tag().isEmpty());
|
||||||
QVERIFY(ctor2.access() == QMetaMethod::Public);
|
QVERIFY(ctor2.access() == QMetaMethod::Public);
|
||||||
@ -458,6 +472,7 @@ void tst_QMetaObjectBuilder::constructor()
|
|||||||
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
||||||
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
||||||
QCOMPARE(ctor1.returnType(), QByteArray("int"));
|
QCOMPARE(ctor1.returnType(), QByteArray("int"));
|
||||||
|
QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
|
||||||
QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
||||||
QCOMPARE(ctor1.tag(), QByteArray("tag"));
|
QCOMPARE(ctor1.tag(), QByteArray("tag"));
|
||||||
QVERIFY(ctor1.access() == QMetaMethod::Private);
|
QVERIFY(ctor1.access() == QMetaMethod::Private);
|
||||||
@ -466,6 +481,7 @@ void tst_QMetaObjectBuilder::constructor()
|
|||||||
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
||||||
QVERIFY(ctor2.returnType().isEmpty());
|
QVERIFY(ctor2.returnType().isEmpty());
|
||||||
|
QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QVERIFY(ctor2.parameterNames().isEmpty());
|
QVERIFY(ctor2.parameterNames().isEmpty());
|
||||||
QVERIFY(ctor2.tag().isEmpty());
|
QVERIFY(ctor2.tag().isEmpty());
|
||||||
QVERIFY(ctor2.access() == QMetaMethod::Public);
|
QVERIFY(ctor2.access() == QMetaMethod::Public);
|
||||||
@ -484,6 +500,7 @@ void tst_QMetaObjectBuilder::constructor()
|
|||||||
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
QCOMPARE(ctor1.signature(), QByteArray("foo(QString,int)"));
|
||||||
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
QVERIFY(ctor1.methodType() == QMetaMethod::Constructor);
|
||||||
QCOMPARE(ctor1.returnType(), QByteArray("int"));
|
QCOMPARE(ctor1.returnType(), QByteArray("int"));
|
||||||
|
QCOMPARE(ctor1.parameterTypes(), QList<QByteArray>() << "QString" << "int");
|
||||||
QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
QCOMPARE(ctor1.parameterNames(), QList<QByteArray>() << "a" << "b");
|
||||||
QCOMPARE(ctor1.tag(), QByteArray("tag"));
|
QCOMPARE(ctor1.tag(), QByteArray("tag"));
|
||||||
QVERIFY(ctor1.access() == QMetaMethod::Private);
|
QVERIFY(ctor1.access() == QMetaMethod::Private);
|
||||||
@ -492,6 +509,7 @@ void tst_QMetaObjectBuilder::constructor()
|
|||||||
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
||||||
QCOMPARE(ctor2.returnType(), QByteArray("QString"));
|
QCOMPARE(ctor2.returnType(), QByteArray("QString"));
|
||||||
|
QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
|
QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
|
||||||
QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
|
QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
|
||||||
QVERIFY(ctor2.access() == QMetaMethod::Protected);
|
QVERIFY(ctor2.access() == QMetaMethod::Protected);
|
||||||
@ -506,6 +524,7 @@ void tst_QMetaObjectBuilder::constructor()
|
|||||||
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
QCOMPARE(ctor2.signature(), QByteArray("bar(QString)"));
|
||||||
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
QVERIFY(ctor2.methodType() == QMetaMethod::Constructor);
|
||||||
QCOMPARE(ctor2.returnType(), QByteArray("QString"));
|
QCOMPARE(ctor2.returnType(), QByteArray("QString"));
|
||||||
|
QCOMPARE(ctor2.parameterTypes(), QList<QByteArray>() << "QString");
|
||||||
QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
|
QCOMPARE(ctor2.parameterNames(), QList<QByteArray>() << "c");
|
||||||
QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
|
QCOMPARE(ctor2.tag(), QByteArray("Q_FOO"));
|
||||||
QVERIFY(ctor2.access() == QMetaMethod::Protected);
|
QVERIFY(ctor2.access() == QMetaMethod::Protected);
|
||||||
@ -525,6 +544,7 @@ void tst_QMetaObjectBuilder::constructor()
|
|||||||
QCOMPARE(prototypeConstructor.signature(), QByteArray("SomethingOfEverything()"));
|
QCOMPARE(prototypeConstructor.signature(), QByteArray("SomethingOfEverything()"));
|
||||||
QVERIFY(prototypeConstructor.methodType() == QMetaMethod::Constructor);
|
QVERIFY(prototypeConstructor.methodType() == QMetaMethod::Constructor);
|
||||||
QCOMPARE(prototypeConstructor.returnType(), QByteArray());
|
QCOMPARE(prototypeConstructor.returnType(), QByteArray());
|
||||||
|
QVERIFY(prototypeConstructor.parameterTypes().isEmpty());
|
||||||
QVERIFY(prototypeConstructor.access() == QMetaMethod::Public);
|
QVERIFY(prototypeConstructor.access() == QMetaMethod::Public);
|
||||||
QCOMPARE(prototypeConstructor.index(), 1);
|
QCOMPARE(prototypeConstructor.index(), 1);
|
||||||
|
|
||||||
@ -1161,12 +1181,15 @@ bool tst_QMetaObjectBuilder::checkForSideEffects
|
|||||||
|
|
||||||
static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
|
static bool sameMethod(const QMetaMethod& method1, const QMetaMethod& method2)
|
||||||
{
|
{
|
||||||
if (QByteArray(method1.signature()) != QByteArray(method2.signature()))
|
if (method1.methodSignature() != method2.methodSignature())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (QByteArray(method1.typeName()) != QByteArray(method2.typeName()))
|
if (QByteArray(method1.typeName()) != QByteArray(method2.typeName()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (method1.parameterTypes() != method2.parameterTypes())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (method1.parameterNames() != method2.parameterNames())
|
if (method1.parameterNames() != method2.parameterNames())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1466,7 +1489,7 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id,
|
|||||||
if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
|
if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
|
||||||
default: {
|
default: {
|
||||||
QMetaMethod ctor = _o->metaObject()->constructor(_id);
|
QMetaMethod ctor = _o->metaObject()->constructor(_id);
|
||||||
qFatal("You forgot to add a case for CreateInstance %s", ctor.signature());
|
qFatal("You forgot to add a case for CreateInstance %s", ctor.methodSignature().constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_c == QMetaObject::InvokeMetaMethod) {
|
} else if (_c == QMetaObject::InvokeMetaMethod) {
|
||||||
@ -1478,7 +1501,7 @@ void TestObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id,
|
|||||||
case 2: *reinterpret_cast<QVariantList(*)>(_a[0]) = _t->listInvokableQRealQString(*reinterpret_cast<qreal(*)>(_a[1]), *reinterpret_cast<QString(*)>(_a[2])); break;
|
case 2: *reinterpret_cast<QVariantList(*)>(_a[0]) = _t->listInvokableQRealQString(*reinterpret_cast<qreal(*)>(_a[1]), *reinterpret_cast<QString(*)>(_a[2])); break;
|
||||||
default: {
|
default: {
|
||||||
QMetaMethod method = _o->metaObject()->method(_o->metaObject()->methodOffset() + _id);
|
QMetaMethod method = _o->metaObject()->method(_o->metaObject()->methodOffset() + _id);
|
||||||
qFatal("You forgot to add a case for InvokeMetaMethod %s", method.signature());
|
qFatal("You forgot to add a case for InvokeMetaMethod %s", method.methodSignature().constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_c == QMetaObject::IndexOfMethod) {
|
} else if (_c == QMetaObject::IndexOfMethod) {
|
||||||
|
@ -332,6 +332,7 @@ void tst_QMetaType::typeName_data()
|
|||||||
|
|
||||||
QT_FOR_EACH_STATIC_TYPE(TYPENAME_DATA)
|
QT_FOR_EACH_STATIC_TYPE(TYPENAME_DATA)
|
||||||
QT_FOR_EACH_STATIC_ALIAS_TYPE(TYPENAME_DATA_ALIAS)
|
QT_FOR_EACH_STATIC_ALIAS_TYPE(TYPENAME_DATA_ALIAS)
|
||||||
|
QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << static_cast<const char*>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QMetaType::typeName()
|
void tst_QMetaType::typeName()
|
||||||
@ -642,6 +643,8 @@ void tst_QMetaType::sizeOf_data()
|
|||||||
{
|
{
|
||||||
QTest::addColumn<QMetaType::Type>("type");
|
QTest::addColumn<QMetaType::Type>("type");
|
||||||
QTest::addColumn<int>("size");
|
QTest::addColumn<int>("size");
|
||||||
|
|
||||||
|
QTest::newRow("QMetaType::UnknownType") << QMetaType::UnknownType << 0;
|
||||||
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
|
#define ADD_METATYPE_TEST_ROW(MetaTypeName, MetaTypeId, RealType) \
|
||||||
QTest::newRow(#RealType) << QMetaType::MetaTypeName << int(QTypeInfo<RealType>::sizeOf);
|
QTest::newRow(#RealType) << QMetaType::MetaTypeName << int(QTypeInfo<RealType>::sizeOf);
|
||||||
FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
|
FOR_EACH_CORE_METATYPE(ADD_METATYPE_TEST_ROW)
|
||||||
@ -1040,6 +1043,7 @@ void tst_QMetaType::isRegistered_data()
|
|||||||
QTest::newRow("-1") << -1 << false;
|
QTest::newRow("-1") << -1 << false;
|
||||||
QTest::newRow("-42") << -42 << false;
|
QTest::newRow("-42") << -42 << false;
|
||||||
QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false;
|
QTest::newRow("IsRegisteredDummyType + 1") << (dummyTypeId + 1) << false;
|
||||||
|
QTest::newRow("QMetaType::UnknownType") << int(QMetaType::UnknownType) << false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QMetaType::isRegistered()
|
void tst_QMetaType::isRegistered()
|
||||||
|
@ -90,7 +90,7 @@ static const char qt_meta_stringdata_OldNormalizeObject[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const QMetaObject OldNormalizeObject::staticMetaObject = {
|
const QMetaObject OldNormalizeObject::staticMetaObject = {
|
||||||
{ &QObject::staticMetaObject, qt_meta_stringdata_OldNormalizeObject,
|
{ &QObject::staticMetaObject, reinterpret_cast<const QByteArrayData *>(qt_meta_stringdata_OldNormalizeObject),
|
||||||
qt_meta_data_OldNormalizeObject, 0 }
|
qt_meta_data_OldNormalizeObject, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1793,56 +1793,56 @@ void tst_QObject::metamethod()
|
|||||||
QMetaMethod m;
|
QMetaMethod m;
|
||||||
|
|
||||||
m = mobj->method(mobj->indexOfMethod("invoke1()"));
|
m = mobj->method(mobj->indexOfMethod("invoke1()"));
|
||||||
QVERIFY(QByteArray(m.signature()) == "invoke1()");
|
QVERIFY(m.methodSignature() == "invoke1()");
|
||||||
QVERIFY(m.methodType() == QMetaMethod::Method);
|
QVERIFY(m.methodType() == QMetaMethod::Method);
|
||||||
QVERIFY(m.access() == QMetaMethod::Public);
|
QVERIFY(m.access() == QMetaMethod::Public);
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
|
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
|
||||||
|
|
||||||
m = mobj->method(mobj->indexOfMethod("sinvoke1()"));
|
m = mobj->method(mobj->indexOfMethod("sinvoke1()"));
|
||||||
QVERIFY(QByteArray(m.signature()) == "sinvoke1()");
|
QVERIFY(m.methodSignature() == "sinvoke1()");
|
||||||
QVERIFY(m.methodType() == QMetaMethod::Method);
|
QVERIFY(m.methodType() == QMetaMethod::Method);
|
||||||
QVERIFY(m.access() == QMetaMethod::Public);
|
QVERIFY(m.access() == QMetaMethod::Public);
|
||||||
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
|
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
|
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
|
||||||
|
|
||||||
m = mobj->method(mobj->indexOfMethod("invoke2()"));
|
m = mobj->method(mobj->indexOfMethod("invoke2()"));
|
||||||
QVERIFY(QByteArray(m.signature()) == "invoke2()");
|
QVERIFY(m.methodSignature() == "invoke2()");
|
||||||
QVERIFY(m.methodType() == QMetaMethod::Method);
|
QVERIFY(m.methodType() == QMetaMethod::Method);
|
||||||
QVERIFY(m.access() == QMetaMethod::Protected);
|
QVERIFY(m.access() == QMetaMethod::Protected);
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
||||||
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
|
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
|
||||||
|
|
||||||
m = mobj->method(mobj->indexOfMethod("sinvoke2()"));
|
m = mobj->method(mobj->indexOfMethod("sinvoke2()"));
|
||||||
QVERIFY(QByteArray(m.signature()) == "sinvoke2()");
|
QVERIFY(m.methodSignature() == "sinvoke2()");
|
||||||
QVERIFY(m.methodType() == QMetaMethod::Method);
|
QVERIFY(m.methodType() == QMetaMethod::Method);
|
||||||
QVERIFY(m.access() == QMetaMethod::Protected);
|
QVERIFY(m.access() == QMetaMethod::Protected);
|
||||||
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
|
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
|
||||||
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
|
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
|
||||||
|
|
||||||
m = mobj->method(mobj->indexOfMethod("invoke3()"));
|
m = mobj->method(mobj->indexOfMethod("invoke3()"));
|
||||||
QVERIFY(QByteArray(m.signature()) == "invoke3()");
|
QVERIFY(m.methodSignature() == "invoke3()");
|
||||||
QVERIFY(m.methodType() == QMetaMethod::Method);
|
QVERIFY(m.methodType() == QMetaMethod::Method);
|
||||||
QVERIFY(m.access() == QMetaMethod::Private);
|
QVERIFY(m.access() == QMetaMethod::Private);
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
|
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
|
||||||
|
|
||||||
m = mobj->method(mobj->indexOfMethod("sinvoke3()"));
|
m = mobj->method(mobj->indexOfMethod("sinvoke3()"));
|
||||||
QVERIFY(QByteArray(m.signature()) == "sinvoke3()");
|
QVERIFY(m.methodSignature() == "sinvoke3()");
|
||||||
QVERIFY(m.methodType() == QMetaMethod::Method);
|
QVERIFY(m.methodType() == QMetaMethod::Method);
|
||||||
QVERIFY(m.access() == QMetaMethod::Private);
|
QVERIFY(m.access() == QMetaMethod::Private);
|
||||||
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
|
QVERIFY((m.attributes() & QMetaMethod::Scriptable));
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
|
QVERIFY(!(m.attributes() & QMetaMethod::Compatibility));
|
||||||
|
|
||||||
m = mobj->method(mobj->indexOfMethod("signal5()"));
|
m = mobj->method(mobj->indexOfMethod("signal5()"));
|
||||||
QVERIFY(QByteArray(m.signature()) == "signal5()");
|
QVERIFY(m.methodSignature() == "signal5()");
|
||||||
QVERIFY(m.methodType() == QMetaMethod::Signal);
|
QVERIFY(m.methodType() == QMetaMethod::Signal);
|
||||||
QVERIFY(m.access() == QMetaMethod::Protected);
|
QVERIFY(m.access() == QMetaMethod::Protected);
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
||||||
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
|
QVERIFY((m.attributes() & QMetaMethod::Compatibility));
|
||||||
|
|
||||||
m = mobj->method(mobj->indexOfMethod("aPublicSlot()"));
|
m = mobj->method(mobj->indexOfMethod("aPublicSlot()"));
|
||||||
QVERIFY(QByteArray(m.signature()) == "aPublicSlot()");
|
QVERIFY(m.methodSignature() == "aPublicSlot()");
|
||||||
QVERIFY(m.methodType() == QMetaMethod::Slot);
|
QVERIFY(m.methodType() == QMetaMethod::Slot);
|
||||||
QVERIFY(m.access() == QMetaMethod::Public);
|
QVERIFY(m.access() == QMetaMethod::Public);
|
||||||
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
QVERIFY(!(m.attributes() & QMetaMethod::Scriptable));
|
||||||
|
@ -3557,6 +3557,10 @@ void tst_QVariant::loadQVariantFromDataStream(QDataStream::Version version)
|
|||||||
stream >> typeName >> loadedVariant;
|
stream >> typeName >> loadedVariant;
|
||||||
|
|
||||||
const int id = QMetaType::type(typeName.toLatin1());
|
const int id = QMetaType::type(typeName.toLatin1());
|
||||||
|
if (id == QMetaType::Void) {
|
||||||
|
// Void type is not supported by QVariant
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QVariant constructedVariant(static_cast<QVariant::Type>(id));
|
QVariant constructedVariant(static_cast<QVariant::Type>(id));
|
||||||
QCOMPARE(constructedVariant.userType(), id);
|
QCOMPARE(constructedVariant.userType(), id);
|
||||||
@ -3576,6 +3580,10 @@ void tst_QVariant::saveQVariantFromDataStream(QDataStream::Version version)
|
|||||||
dataFileStream >> typeName;
|
dataFileStream >> typeName;
|
||||||
QByteArray data = file.readAll();
|
QByteArray data = file.readAll();
|
||||||
const int id = QMetaType::type(typeName.toLatin1());
|
const int id = QMetaType::type(typeName.toLatin1());
|
||||||
|
if (id == QMetaType::Void) {
|
||||||
|
// Void type is not supported by QVariant
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QBuffer buffer;
|
QBuffer buffer;
|
||||||
buffer.open(QIODevice::ReadWrite);
|
buffer.open(QIODevice::ReadWrite);
|
||||||
@ -3636,7 +3644,9 @@ void tst_QVariant::debugStream_data()
|
|||||||
const char *tagName = QMetaType::typeName(id);
|
const char *tagName = QMetaType::typeName(id);
|
||||||
if (!tagName)
|
if (!tagName)
|
||||||
continue;
|
continue;
|
||||||
QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id;
|
if (id != QMetaType::Void) {
|
||||||
|
QTest::newRow(tagName) << QVariant(static_cast<QVariant::Type>(id)) << id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId<QBitArray>();
|
QTest::newRow("QBitArray(111)") << QVariant(QBitArray(3, true)) << qMetaTypeId<QBitArray>();
|
||||||
QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>();
|
QTest::newRow("CustomStreamableClass") << QVariant(qMetaTypeId<CustomStreamableClass>(), 0) << qMetaTypeId<CustomStreamableClass>();
|
||||||
|
5
tests/auto/corelib/tools/qarraydata/qarraydata.pro
Normal file
5
tests/auto/corelib/tools/qarraydata/qarraydata.pro
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
TARGET = tst_qarraydata
|
||||||
|
SOURCES += tst_qarraydata.cpp
|
||||||
|
HEADERS += simplevector.h
|
||||||
|
QT = core testlib
|
||||||
|
CONFIG += testcase parallel_test
|
341
tests/auto/corelib/tools/qarraydata/simplevector.h
Normal file
341
tests/auto/corelib/tools/qarraydata/simplevector.h
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/
|
||||||
|
**
|
||||||
|
** This file is part of the test suite 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 QARRAY_TEST_SIMPLE_VECTOR_H
|
||||||
|
#define QARRAY_TEST_SIMPLE_VECTOR_H
|
||||||
|
|
||||||
|
#include <QtCore/qarraydata.h>
|
||||||
|
#include <QtCore/qarraydatapointer.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct SimpleVector
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef QTypedArrayData<T> Data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef typename Data::iterator iterator;
|
||||||
|
typedef typename Data::const_iterator const_iterator;
|
||||||
|
|
||||||
|
SimpleVector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleVector(size_t n, const T &t)
|
||||||
|
: d(Data::allocate(n))
|
||||||
|
{
|
||||||
|
if (n)
|
||||||
|
d->copyAppend(n, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleVector(const T *begin, const T *end)
|
||||||
|
: d(Data::allocate(end - begin))
|
||||||
|
{
|
||||||
|
if (end - begin)
|
||||||
|
d->copyAppend(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleVector(QArrayDataPointerRef<T> ptr)
|
||||||
|
: d(ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit SimpleVector(Data *ptr)
|
||||||
|
: d(ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const { return d->size == 0; }
|
||||||
|
bool isNull() const { return d.isNull(); }
|
||||||
|
bool isEmpty() const { return this->empty(); }
|
||||||
|
|
||||||
|
bool isStatic() const { return d->ref.isStatic(); }
|
||||||
|
bool isShared() const { return d->ref.isShared(); }
|
||||||
|
bool isSharedWith(const SimpleVector &other) const { return d == other.d; }
|
||||||
|
bool isSharable() const { return d->ref.isSharable(); }
|
||||||
|
|
||||||
|
void setSharable(bool sharable) { d.setSharable(sharable); }
|
||||||
|
|
||||||
|
size_t size() const { return d->size; }
|
||||||
|
size_t capacity() const { return d->alloc; }
|
||||||
|
|
||||||
|
iterator begin() { detach(); return d->begin(); }
|
||||||
|
iterator end() { detach(); return d->end(); }
|
||||||
|
|
||||||
|
const_iterator begin() const { return d->begin(); }
|
||||||
|
const_iterator end() const { return d->end(); }
|
||||||
|
|
||||||
|
const_iterator constBegin() const { return begin(); }
|
||||||
|
const_iterator constEnd() const { return end(); }
|
||||||
|
|
||||||
|
T &operator[](size_t i) { Q_ASSERT(i < size_t(d->size)); detach(); return begin()[i]; }
|
||||||
|
T &at(size_t i) { Q_ASSERT(i < size_t(d->size)); detach(); return begin()[i]; }
|
||||||
|
|
||||||
|
const T &operator[](size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; }
|
||||||
|
const T &at(size_t i) const { Q_ASSERT(i < size_t(d->size)); return begin()[i]; }
|
||||||
|
|
||||||
|
T &front()
|
||||||
|
{
|
||||||
|
Q_ASSERT(!isEmpty());
|
||||||
|
detach();
|
||||||
|
return *begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
T &back()
|
||||||
|
{
|
||||||
|
Q_ASSERT(!isEmpty());
|
||||||
|
detach();
|
||||||
|
return *(end() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const T &front() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(!isEmpty());
|
||||||
|
return *begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const T &back() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(!isEmpty());
|
||||||
|
return *(end() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reserve(size_t n)
|
||||||
|
{
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (n <= capacity()) {
|
||||||
|
if (d->capacityReserved)
|
||||||
|
return;
|
||||||
|
if (!d->ref.isShared()) {
|
||||||
|
d->capacityReserved = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleVector detached(Data::allocate(qMax(n, size()),
|
||||||
|
d->detachFlags() | Data::CapacityReserved));
|
||||||
|
if (size())
|
||||||
|
detached.d->copyAppend(constBegin(), constEnd());
|
||||||
|
detached.swap(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepend(const_iterator first, const_iterator last)
|
||||||
|
{
|
||||||
|
if (!d->size) {
|
||||||
|
append(first, last);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first == last)
|
||||||
|
return;
|
||||||
|
|
||||||
|
T *const begin = d->begin();
|
||||||
|
if (d->ref.isShared()
|
||||||
|
|| capacity() - size() < size_t(last - first)) {
|
||||||
|
SimpleVector detached(Data::allocate(
|
||||||
|
qMax(capacity(), size() + (last - first)),
|
||||||
|
d->detachFlags() | Data::Grow));
|
||||||
|
|
||||||
|
detached.d->copyAppend(first, last);
|
||||||
|
detached.d->copyAppend(begin, begin + d->size);
|
||||||
|
detached.swap(*this);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->insert(begin, first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(const_iterator first, const_iterator last)
|
||||||
|
{
|
||||||
|
if (first == last)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (d->ref.isShared()
|
||||||
|
|| capacity() - size() < size_t(last - first)) {
|
||||||
|
SimpleVector detached(Data::allocate(
|
||||||
|
qMax(capacity(), size() + (last - first)),
|
||||||
|
d->detachFlags() | Data::Grow));
|
||||||
|
|
||||||
|
if (d->size) {
|
||||||
|
const T *const begin = constBegin();
|
||||||
|
detached.d->copyAppend(begin, begin + d->size);
|
||||||
|
}
|
||||||
|
detached.d->copyAppend(first, last);
|
||||||
|
detached.swap(*this);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->copyAppend(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(int position, const_iterator first, const_iterator last)
|
||||||
|
{
|
||||||
|
if (position < 0)
|
||||||
|
position += d->size + 1;
|
||||||
|
|
||||||
|
if (position <= 0) {
|
||||||
|
prepend(first, last);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size_t(position) >= size()) {
|
||||||
|
append(first, last);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first == last)
|
||||||
|
return;
|
||||||
|
|
||||||
|
T *const begin = d->begin();
|
||||||
|
T *const where = begin + position;
|
||||||
|
const T *const end = begin + d->size;
|
||||||
|
if (d->ref.isShared()
|
||||||
|
|| capacity() - size() < size_t(last - first)) {
|
||||||
|
SimpleVector detached(Data::allocate(
|
||||||
|
qMax(capacity(), size() + (last - first)),
|
||||||
|
d->detachFlags() | Data::Grow));
|
||||||
|
|
||||||
|
if (position)
|
||||||
|
detached.d->copyAppend(begin, where);
|
||||||
|
detached.d->copyAppend(first, last);
|
||||||
|
detached.d->copyAppend(where, end);
|
||||||
|
detached.swap(*this);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((first >= where && first < end)
|
||||||
|
|| (last > where && last <= end)) {
|
||||||
|
// Copy overlapping data first and only then shuffle it into place
|
||||||
|
T *start = d->begin() + position;
|
||||||
|
T *middle = d->end();
|
||||||
|
|
||||||
|
d->copyAppend(first, last);
|
||||||
|
std::rotate(start, middle, d->end());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->insert(where, first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(SimpleVector &other)
|
||||||
|
{
|
||||||
|
qSwap(d, other.d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
d.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void detach()
|
||||||
|
{
|
||||||
|
d.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
static SimpleVector fromRawData(const T *data, size_t size,
|
||||||
|
QArrayData::AllocationOptions options = Data::Default)
|
||||||
|
{
|
||||||
|
return SimpleVector(Data::fromRawData(data, size, options));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QArrayDataPointer<T> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool operator==(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
|
||||||
|
{
|
||||||
|
if (lhs.isSharedWith(rhs))
|
||||||
|
return true;
|
||||||
|
if (lhs.size() != rhs.size())
|
||||||
|
return false;
|
||||||
|
return std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool operator!=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool operator<(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
|
||||||
|
{
|
||||||
|
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool operator>(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool operator<=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
|
||||||
|
{
|
||||||
|
return !(rhs < lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool operator>=(const SimpleVector<T> &lhs, const SimpleVector<T> &rhs)
|
||||||
|
{
|
||||||
|
return !(lhs < rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <class T>
|
||||||
|
void swap(SimpleVector<T> &v1, SimpleVector<T> &v2)
|
||||||
|
{
|
||||||
|
v1.swap(v2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // include guard
|
1464
tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
Normal file
1464
tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1078,18 +1078,25 @@ void tst_QByteArray::toULongLong()
|
|||||||
// global function defined in qbytearray.cpp
|
// global function defined in qbytearray.cpp
|
||||||
void tst_QByteArray::qAllocMore()
|
void tst_QByteArray::qAllocMore()
|
||||||
{
|
{
|
||||||
static const int t[] = {
|
using QT_PREPEND_NAMESPACE(qAllocMore);
|
||||||
INT_MIN, INT_MIN + 1, -1234567, -66000, -1025,
|
|
||||||
-3, -1, 0, +1, +3, +1025, +66000, +1234567, INT_MAX - 1, INT_MAX,
|
|
||||||
INT_MAX/3
|
|
||||||
};
|
|
||||||
static const int N = sizeof(t)/sizeof(t[0]);
|
|
||||||
|
|
||||||
// make sure qAllocMore() doesn't loop infinitely on any input
|
// Not very important, but please behave :-)
|
||||||
for (int i = 0; i < N; ++i) {
|
QVERIFY(qAllocMore(0, 0) >= 0);
|
||||||
for (int j = 0; j < N; ++j) {
|
|
||||||
::qAllocMore(t[i], t[j]);
|
for (int i = 1; i < 1 << 8; i <<= 1)
|
||||||
}
|
QVERIFY(qAllocMore(i, 0) >= i);
|
||||||
|
|
||||||
|
for (int i = 1 << 8; i < 1 << 30; i <<= 1) {
|
||||||
|
const int alloc = qAllocMore(i, 0);
|
||||||
|
|
||||||
|
QVERIFY(alloc >= i);
|
||||||
|
QCOMPARE(qAllocMore(i - 8, 8), alloc - 8);
|
||||||
|
QCOMPARE(qAllocMore(i - 16, 16), alloc - 16);
|
||||||
|
QCOMPARE(qAllocMore(i - 24, 24), alloc - 24);
|
||||||
|
QCOMPARE(qAllocMore(i - 32, 32), alloc - 32);
|
||||||
|
|
||||||
|
QVERIFY(qAllocMore(i - 1, 0) >= i - 1);
|
||||||
|
QVERIFY(qAllocMore(i + 1, 0) >= i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1587,8 +1594,8 @@ void tst_QByteArray::literals()
|
|||||||
|
|
||||||
QVERIFY(str.length() == 4);
|
QVERIFY(str.length() == 4);
|
||||||
QVERIFY(str == "abcd");
|
QVERIFY(str == "abcd");
|
||||||
QVERIFY(str.data_ptr()->ref == -1);
|
QVERIFY(str.data_ptr()->ref.isStatic());
|
||||||
QVERIFY(str.data_ptr()->offset == 0);
|
QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData));
|
||||||
|
|
||||||
const char *s = str.constData();
|
const char *s = str.constData();
|
||||||
QByteArray str2 = str;
|
QByteArray str2 = str;
|
||||||
|
@ -54,6 +54,9 @@ class tst_QList : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void init();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
void length() const;
|
void length() const;
|
||||||
void lengthSignature() const;
|
void lengthSignature() const;
|
||||||
void append() const;
|
void append() const;
|
||||||
@ -90,8 +93,100 @@ private slots:
|
|||||||
void initializeList() const;
|
void initializeList() const;
|
||||||
|
|
||||||
void const_shared_null() const;
|
void const_shared_null() const;
|
||||||
|
void setSharable1_data() const;
|
||||||
|
void setSharable1() const;
|
||||||
|
void setSharable2_data() const;
|
||||||
|
void setSharable2() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int dummyForGuard;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Complex
|
||||||
|
{
|
||||||
|
Complex(int val)
|
||||||
|
: value(val)
|
||||||
|
, checkSum(this)
|
||||||
|
{
|
||||||
|
++liveCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
Complex(Complex const &other)
|
||||||
|
: value(other.value)
|
||||||
|
, checkSum(this)
|
||||||
|
{
|
||||||
|
++liveCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
Complex &operator=(Complex const &other)
|
||||||
|
{
|
||||||
|
check(); other.check();
|
||||||
|
|
||||||
|
value = other.value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Complex()
|
||||||
|
{
|
||||||
|
--liveCount;
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator int() const { return value; }
|
||||||
|
|
||||||
|
bool operator==(Complex const &other) const
|
||||||
|
{
|
||||||
|
check(); other.check();
|
||||||
|
return value == other.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check() const
|
||||||
|
{
|
||||||
|
if (this != checkSum) {
|
||||||
|
++errorCount;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Guard
|
||||||
|
{
|
||||||
|
Guard() : initialLiveCount(liveCount) {}
|
||||||
|
~Guard() { if (liveCount != initialLiveCount) ++errorCount; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(Guard);
|
||||||
|
int initialLiveCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void resetErrors() { errorCount = 0; }
|
||||||
|
static int errors() { return errorCount; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int errorCount;
|
||||||
|
static int liveCount;
|
||||||
|
|
||||||
|
int value;
|
||||||
|
void *checkSum;
|
||||||
|
};
|
||||||
|
|
||||||
|
int Complex::errorCount = 0;
|
||||||
|
int Complex::liveCount = 0;
|
||||||
|
|
||||||
|
void tst_QList::init()
|
||||||
|
{
|
||||||
|
Complex::resetErrors();
|
||||||
|
new (&dummyForGuard) Complex::Guard();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QList::cleanup()
|
||||||
|
{
|
||||||
|
QCOMPARE(Complex::errors(), 0);
|
||||||
|
|
||||||
|
reinterpret_cast<Complex::Guard *>(&dummyForGuard)->~Guard();
|
||||||
|
QCOMPARE(Complex::errors(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QList::length() const
|
void tst_QList::length() const
|
||||||
{
|
{
|
||||||
/* Empty list. */
|
/* Empty list. */
|
||||||
@ -696,5 +791,82 @@ void tst_QList::const_shared_null() const
|
|||||||
QVERIFY(!list2.isDetached());
|
QVERIFY(!list2.isDetached());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QList<int>);
|
||||||
|
Q_DECLARE_METATYPE(QList<Complex>);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void generateSetSharableData()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QList<T> >("list");
|
||||||
|
QTest::addColumn<int>("size");
|
||||||
|
|
||||||
|
QTest::newRow("null") << QList<T>() << 0;
|
||||||
|
QTest::newRow("non-empty") << (QList<T>() << T(0) << T(1) << T(2) << T(3) << T(4)) << 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void runSetSharableTest()
|
||||||
|
{
|
||||||
|
QFETCH(QList<T>, list);
|
||||||
|
QFETCH(int, size);
|
||||||
|
|
||||||
|
QVERIFY(!list.isDetached()); // Shared with QTest
|
||||||
|
|
||||||
|
list.setSharable(true);
|
||||||
|
|
||||||
|
QCOMPARE(list.size(), size);
|
||||||
|
|
||||||
|
{
|
||||||
|
QList<T> copy(list);
|
||||||
|
QVERIFY(!copy.isDetached());
|
||||||
|
QVERIFY(copy.isSharedWith(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
list.setSharable(false);
|
||||||
|
QVERIFY(list.isDetached() || list.isSharedWith(QList<T>()));
|
||||||
|
|
||||||
|
{
|
||||||
|
QList<T> copy(list);
|
||||||
|
|
||||||
|
QVERIFY(copy.isDetached() || copy.isSharedWith(QList<T>()));
|
||||||
|
QCOMPARE(copy.size(), size);
|
||||||
|
QCOMPARE(copy, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
list.setSharable(true);
|
||||||
|
|
||||||
|
{
|
||||||
|
QList<T> copy(list);
|
||||||
|
|
||||||
|
QVERIFY(!copy.isDetached());
|
||||||
|
QVERIFY(copy.isSharedWith(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < list.size(); ++i)
|
||||||
|
QCOMPARE(int(list[i]), i);
|
||||||
|
|
||||||
|
QCOMPARE(list.size(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QList::setSharable1_data() const
|
||||||
|
{
|
||||||
|
generateSetSharableData<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QList::setSharable2_data() const
|
||||||
|
{
|
||||||
|
generateSetSharableData<Complex>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QList::setSharable1() const
|
||||||
|
{
|
||||||
|
runSetSharableTest<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QList::setSharable2() const
|
||||||
|
{
|
||||||
|
runSetSharableTest<Complex>();
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(tst_QList)
|
QTEST_APPLESS_MAIN(tst_QList)
|
||||||
#include "tst_qlist.moc"
|
#include "tst_qlist.moc"
|
||||||
|
@ -1421,16 +1421,51 @@ void tst_QString::mid()
|
|||||||
QVERIFY(a.mid(9999).isNull());
|
QVERIFY(a.mid(9999).isNull());
|
||||||
QVERIFY(a.mid(9999,1).isNull());
|
QVERIFY(a.mid(9999,1).isNull());
|
||||||
|
|
||||||
|
QCOMPARE(a.mid(-1, 6), QString("ABCDEF"));
|
||||||
|
QCOMPARE(a.mid(-100, 6), QString("ABCDEF"));
|
||||||
|
QVERIFY(a.mid(INT_MAX).isNull());
|
||||||
|
QVERIFY(a.mid(INT_MAX, INT_MAX).isNull());
|
||||||
|
QCOMPARE(a.mid(-5, INT_MAX), a);
|
||||||
|
QCOMPARE(a.mid(-1, INT_MAX), a);
|
||||||
|
QCOMPARE(a.mid(0, INT_MAX), a);
|
||||||
|
QCOMPARE(a.mid(1, INT_MAX), QString("BCDEFGHIEfGEFG"));
|
||||||
|
QCOMPARE(a.mid(5, INT_MAX), QString("FGHIEfGEFG"));
|
||||||
|
QVERIFY(a.mid(20, INT_MAX).isNull());
|
||||||
|
QCOMPARE(a.mid(-1, -1), a);
|
||||||
|
|
||||||
QString n;
|
QString n;
|
||||||
QVERIFY(n.mid(3,3).isNull());
|
QVERIFY(n.mid(3,3).isNull());
|
||||||
QVERIFY(n.mid(0,0).isNull());
|
QVERIFY(n.mid(0,0).isNull());
|
||||||
QVERIFY(n.mid(9999,0).isNull());
|
QVERIFY(n.mid(9999,0).isNull());
|
||||||
QVERIFY(n.mid(9999,1).isNull());
|
QVERIFY(n.mid(9999,1).isNull());
|
||||||
|
|
||||||
|
QVERIFY(n.mid(-1, 6).isNull());
|
||||||
|
QVERIFY(n.mid(-100, 6).isNull());
|
||||||
|
QVERIFY(n.mid(INT_MAX).isNull());
|
||||||
|
QVERIFY(n.mid(INT_MAX, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.mid(-5, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.mid(-1, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.mid(0, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.mid(1, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.mid(5, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.mid(20, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.mid(-1, -1).isNull());
|
||||||
|
|
||||||
QString x = "Nine pineapples";
|
QString x = "Nine pineapples";
|
||||||
QCOMPARE(x.mid(5, 4), QString("pine"));
|
QCOMPARE(x.mid(5, 4), QString("pine"));
|
||||||
QCOMPARE(x.mid(5), QString("pineapples"));
|
QCOMPARE(x.mid(5), QString("pineapples"));
|
||||||
|
|
||||||
|
QCOMPARE(x.mid(-1, 6), QString("Nine p"));
|
||||||
|
QCOMPARE(x.mid(-100, 6), QString("Nine p"));
|
||||||
|
QVERIFY(x.mid(INT_MAX).isNull());
|
||||||
|
QVERIFY(x.mid(INT_MAX, INT_MAX).isNull());
|
||||||
|
QCOMPARE(x.mid(-5, INT_MAX), x);
|
||||||
|
QCOMPARE(x.mid(-1, INT_MAX), x);
|
||||||
|
QCOMPARE(x.mid(0, INT_MAX), x);
|
||||||
|
QCOMPARE(x.mid(1, INT_MAX), QString("ine pineapples"));
|
||||||
|
QCOMPARE(x.mid(5, INT_MAX), QString("pineapples"));
|
||||||
|
QVERIFY(x.mid(20, INT_MAX).isNull());
|
||||||
|
QCOMPARE(x.mid(-1, -1), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QString::midRef()
|
void tst_QString::midRef()
|
||||||
@ -1447,16 +1482,51 @@ void tst_QString::midRef()
|
|||||||
QVERIFY(a.midRef(9999).toString().isEmpty());
|
QVERIFY(a.midRef(9999).toString().isEmpty());
|
||||||
QVERIFY(a.midRef(9999,1).toString().isEmpty());
|
QVERIFY(a.midRef(9999,1).toString().isEmpty());
|
||||||
|
|
||||||
|
QCOMPARE(a.midRef(-1, 6).toString(), QString("ABCDEF"));
|
||||||
|
QCOMPARE(a.midRef(-100, 6).toString(), QString("ABCDEF"));
|
||||||
|
QVERIFY(a.midRef(INT_MAX).isNull());
|
||||||
|
QVERIFY(a.midRef(INT_MAX, INT_MAX).isNull());
|
||||||
|
QCOMPARE(a.midRef(-5, INT_MAX).toString(), a);
|
||||||
|
QCOMPARE(a.midRef(-1, INT_MAX).toString(), a);
|
||||||
|
QCOMPARE(a.midRef(0, INT_MAX).toString(), a);
|
||||||
|
QCOMPARE(a.midRef(1, INT_MAX).toString(), QString("BCDEFGHIEfGEFG"));
|
||||||
|
QCOMPARE(a.midRef(5, INT_MAX).toString(), QString("FGHIEfGEFG"));
|
||||||
|
QVERIFY(a.midRef(20, INT_MAX).isNull());
|
||||||
|
QCOMPARE(a.midRef(-1, -1).toString(), a);
|
||||||
|
|
||||||
QString n;
|
QString n;
|
||||||
QVERIFY(n.midRef(3,3).toString().isEmpty());
|
QVERIFY(n.midRef(3,3).toString().isEmpty());
|
||||||
QVERIFY(n.midRef(0,0).toString().isEmpty());
|
QVERIFY(n.midRef(0,0).toString().isEmpty());
|
||||||
QVERIFY(n.midRef(9999,0).toString().isEmpty());
|
QVERIFY(n.midRef(9999,0).toString().isEmpty());
|
||||||
QVERIFY(n.midRef(9999,1).toString().isEmpty());
|
QVERIFY(n.midRef(9999,1).toString().isEmpty());
|
||||||
|
|
||||||
|
QVERIFY(n.midRef(-1, 6).isNull());
|
||||||
|
QVERIFY(n.midRef(-100, 6).isNull());
|
||||||
|
QVERIFY(n.midRef(INT_MAX).isNull());
|
||||||
|
QVERIFY(n.midRef(INT_MAX, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.midRef(-5, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.midRef(-1, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.midRef(0, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.midRef(1, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.midRef(5, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.midRef(20, INT_MAX).isNull());
|
||||||
|
QVERIFY(n.midRef(-1, -1).isNull());
|
||||||
|
|
||||||
QString x = "Nine pineapples";
|
QString x = "Nine pineapples";
|
||||||
QCOMPARE(x.midRef(5, 4).toString(), QString("pine"));
|
QCOMPARE(x.midRef(5, 4).toString(), QString("pine"));
|
||||||
QCOMPARE(x.midRef(5).toString(), QString("pineapples"));
|
QCOMPARE(x.midRef(5).toString(), QString("pineapples"));
|
||||||
|
|
||||||
|
QCOMPARE(x.midRef(-1, 6).toString(), QString("Nine p"));
|
||||||
|
QCOMPARE(x.midRef(-100, 6).toString(), QString("Nine p"));
|
||||||
|
QVERIFY(x.midRef(INT_MAX).isNull());
|
||||||
|
QVERIFY(x.midRef(INT_MAX, INT_MAX).isNull());
|
||||||
|
QCOMPARE(x.midRef(-5, INT_MAX).toString(), x);
|
||||||
|
QCOMPARE(x.midRef(-1, INT_MAX).toString(), x);
|
||||||
|
QCOMPARE(x.midRef(0, INT_MAX).toString(), x);
|
||||||
|
QCOMPARE(x.midRef(1, INT_MAX).toString(), QString("ine pineapples"));
|
||||||
|
QCOMPARE(x.midRef(5, INT_MAX).toString(), QString("pineapples"));
|
||||||
|
QVERIFY(x.midRef(20, INT_MAX).isNull());
|
||||||
|
QCOMPARE(x.midRef(-1, -1).toString(), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QString::stringRef()
|
void tst_QString::stringRef()
|
||||||
@ -5056,8 +5126,8 @@ void tst_QString::literals()
|
|||||||
|
|
||||||
QVERIFY(str.length() == 4);
|
QVERIFY(str.length() == 4);
|
||||||
QVERIFY(str == QLatin1String("abcd"));
|
QVERIFY(str == QLatin1String("abcd"));
|
||||||
QVERIFY(str.data_ptr()->ref == -1);
|
QVERIFY(str.data_ptr()->ref.isStatic());
|
||||||
QVERIFY(str.data_ptr()->offset == 0);
|
QVERIFY(str.data_ptr()->offset == sizeof(QStringData));
|
||||||
|
|
||||||
const QChar *s = str.constData();
|
const QChar *s = str.constData();
|
||||||
QString str2 = str;
|
QString str2 = str;
|
||||||
|
@ -85,6 +85,8 @@ private slots:
|
|||||||
void initializeList();
|
void initializeList();
|
||||||
|
|
||||||
void const_shared_null();
|
void const_shared_null();
|
||||||
|
void setSharable_data();
|
||||||
|
void setSharable();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QVector::constructors() const
|
void tst_QVector::constructors() const
|
||||||
@ -946,5 +948,97 @@ void tst_QVector::const_shared_null()
|
|||||||
QVERIFY(!v2.isDetached());
|
QVERIFY(!v2.isDetached());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QVector<int>);
|
||||||
|
|
||||||
|
void tst_QVector::setSharable_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QVector<int> >("vector");
|
||||||
|
QTest::addColumn<int>("size");
|
||||||
|
QTest::addColumn<int>("capacity");
|
||||||
|
QTest::addColumn<bool>("isCapacityReserved");
|
||||||
|
|
||||||
|
QVector<int> null;
|
||||||
|
QVector<int> empty(0, 5);
|
||||||
|
QVector<int> emptyReserved;
|
||||||
|
QVector<int> nonEmpty;
|
||||||
|
QVector<int> nonEmptyReserved;
|
||||||
|
|
||||||
|
emptyReserved.reserve(10);
|
||||||
|
nonEmptyReserved.reserve(15);
|
||||||
|
|
||||||
|
nonEmpty << 0 << 1 << 2 << 3 << 4;
|
||||||
|
nonEmptyReserved << 0 << 1 << 2 << 3 << 4 << 5 << 6;
|
||||||
|
|
||||||
|
QVERIFY(emptyReserved.capacity() >= 10);
|
||||||
|
QVERIFY(nonEmptyReserved.capacity() >= 15);
|
||||||
|
|
||||||
|
QTest::newRow("null") << null << 0 << 0 << false;
|
||||||
|
QTest::newRow("empty") << empty << 0 << 0 << false;
|
||||||
|
QTest::newRow("empty, Reserved") << emptyReserved << 0 << 10 << true;
|
||||||
|
QTest::newRow("non-empty") << nonEmpty << 5 << 0 << false;
|
||||||
|
QTest::newRow("non-empty, Reserved") << nonEmptyReserved << 7 << 15 << true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QVector::setSharable()
|
||||||
|
{
|
||||||
|
QFETCH(QVector<int>, vector);
|
||||||
|
QFETCH(int, size);
|
||||||
|
QFETCH(int, capacity);
|
||||||
|
QFETCH(bool, isCapacityReserved);
|
||||||
|
|
||||||
|
QVERIFY(!vector.isDetached()); // Shared with QTest
|
||||||
|
|
||||||
|
vector.setSharable(true);
|
||||||
|
|
||||||
|
QCOMPARE(vector.size(), size);
|
||||||
|
if (isCapacityReserved)
|
||||||
|
QVERIFY2(vector.capacity() >= capacity,
|
||||||
|
qPrintable(QString("Capacity is %1, expected at least %2.")
|
||||||
|
.arg(vector.capacity())
|
||||||
|
.arg(capacity)));
|
||||||
|
|
||||||
|
{
|
||||||
|
QVector<int> copy(vector);
|
||||||
|
|
||||||
|
QVERIFY(!copy.isDetached());
|
||||||
|
QVERIFY(copy.isSharedWith(vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
vector.setSharable(false);
|
||||||
|
QVERIFY(vector.isDetached() || vector.isSharedWith(QVector<int>()));
|
||||||
|
|
||||||
|
{
|
||||||
|
QVector<int> copy(vector);
|
||||||
|
|
||||||
|
QVERIFY(copy.isDetached() || copy.isSharedWith(QVector<int>()));
|
||||||
|
QCOMPARE(copy.size(), size);
|
||||||
|
if (isCapacityReserved)
|
||||||
|
QVERIFY2(copy.capacity() >= capacity,
|
||||||
|
qPrintable(QString("Capacity is %1, expected at least %2.")
|
||||||
|
.arg(vector.capacity())
|
||||||
|
.arg(capacity)));
|
||||||
|
QCOMPARE(copy, vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector.setSharable(true);
|
||||||
|
|
||||||
|
{
|
||||||
|
QVector<int> copy(vector);
|
||||||
|
|
||||||
|
QVERIFY(!copy.isDetached());
|
||||||
|
QVERIFY(copy.isSharedWith(vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < vector.size(); ++i)
|
||||||
|
QCOMPARE(vector[i], i);
|
||||||
|
|
||||||
|
QCOMPARE(vector.size(), size);
|
||||||
|
if (isCapacityReserved)
|
||||||
|
QVERIFY2(vector.capacity() >= capacity,
|
||||||
|
qPrintable(QString("Capacity is %1, expected at least %2.")
|
||||||
|
.arg(vector.capacity())
|
||||||
|
.arg(capacity)));
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(tst_QVector)
|
QTEST_APPLESS_MAIN(tst_QVector)
|
||||||
#include "tst_qvector.moc"
|
#include "tst_qvector.moc"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
TEMPLATE=subdirs
|
TEMPLATE=subdirs
|
||||||
SUBDIRS=\
|
SUBDIRS=\
|
||||||
qalgorithms \
|
qalgorithms \
|
||||||
|
qarraydata \
|
||||||
qbitarray \
|
qbitarray \
|
||||||
qbytearray \
|
qbytearray \
|
||||||
qbytearraymatcher \
|
qbytearraymatcher \
|
||||||
|
@ -397,16 +397,21 @@ void tst_QDBusMetaObject::types()
|
|||||||
for (int i = metaobject->methodOffset(); i < metaobject->methodCount(); ++i) {
|
for (int i = metaobject->methodOffset(); i < metaobject->methodCount(); ++i) {
|
||||||
QMetaMethod expected = metaobject->method(i);
|
QMetaMethod expected = metaobject->method(i);
|
||||||
|
|
||||||
int methodIdx = result->indexOfMethod(expected.signature());
|
int methodIdx = result->indexOfMethod(expected.methodSignature().constData());
|
||||||
QVERIFY(methodIdx != -1);
|
QVERIFY(methodIdx != -1);
|
||||||
QMetaMethod constructed = result->method(methodIdx);
|
QMetaMethod constructed = result->method(methodIdx);
|
||||||
|
|
||||||
QCOMPARE(int(constructed.access()), int(expected.access()));
|
QCOMPARE(int(constructed.access()), int(expected.access()));
|
||||||
QCOMPARE(int(constructed.methodType()), int(expected.methodType()));
|
QCOMPARE(int(constructed.methodType()), int(expected.methodType()));
|
||||||
|
QCOMPARE(constructed.name(), expected.name());
|
||||||
|
QCOMPARE(constructed.parameterCount(), expected.parameterCount());
|
||||||
QCOMPARE(constructed.parameterNames(), expected.parameterNames());
|
QCOMPARE(constructed.parameterNames(), expected.parameterNames());
|
||||||
QCOMPARE(constructed.parameterTypes(), expected.parameterTypes());
|
QCOMPARE(constructed.parameterTypes(), expected.parameterTypes());
|
||||||
|
for (int j = 0; j < constructed.parameterCount(); ++j)
|
||||||
|
QCOMPARE(constructed.parameterType(j), expected.parameterType(j));
|
||||||
QCOMPARE(constructed.tag(), expected.tag());
|
QCOMPARE(constructed.tag(), expected.tag());
|
||||||
QCOMPARE(constructed.typeName(), expected.typeName());
|
QCOMPARE(constructed.typeName(), expected.typeName());
|
||||||
|
QCOMPARE(constructed.returnType(), expected.returnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = metaobject->propertyOffset(); i < metaobject->propertyCount(); ++i) {
|
for (int i = metaobject->propertyOffset(); i < metaobject->propertyCount(); ++i) {
|
||||||
@ -427,6 +432,8 @@ void tst_QDBusMetaObject::types()
|
|||||||
QCOMPARE(constructed.isUser(), expected.isUser());
|
QCOMPARE(constructed.isUser(), expected.isUser());
|
||||||
QCOMPARE(constructed.isWritable(), expected.isWritable());
|
QCOMPARE(constructed.isWritable(), expected.isWritable());
|
||||||
QCOMPARE(constructed.typeName(), expected.typeName());
|
QCOMPARE(constructed.typeName(), expected.typeName());
|
||||||
|
QCOMPARE(constructed.type(), expected.type());
|
||||||
|
QCOMPARE(constructed.userType(), expected.userType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,6 +674,204 @@ const char PropertyTest4_xml[] =
|
|||||||
"<annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"Struct1\"/>"
|
"<annotation name=\"com.trolltech.QtDBus.QtTypeName\" value=\"Struct1\"/>"
|
||||||
"</property>";
|
"</property>";
|
||||||
|
|
||||||
|
class PropertyTest_b: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
bool property() { return false; }
|
||||||
|
void setProperty(bool) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_b_xml[] =
|
||||||
|
"<property name=\"property\" type=\"b\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_y: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(uchar property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
uchar property() { return 0; }
|
||||||
|
void setProperty(uchar) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_y_xml[] =
|
||||||
|
"<property name=\"property\" type=\"y\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_n: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(short property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
short property() { return 0; }
|
||||||
|
void setProperty(short) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_n_xml[] =
|
||||||
|
"<property name=\"property\" type=\"n\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_q: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(ushort property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
ushort property() { return 0; }
|
||||||
|
void setProperty(ushort) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_q_xml[] =
|
||||||
|
"<property name=\"property\" type=\"q\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_u: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(uint property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
uint property() { return 0; }
|
||||||
|
void setProperty(uint) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_u_xml[] =
|
||||||
|
"<property name=\"property\" type=\"u\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_x: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(qlonglong property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
qlonglong property() { return 0; }
|
||||||
|
void setProperty(qlonglong) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_x_xml[] =
|
||||||
|
"<property name=\"property\" type=\"x\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_t: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(qulonglong property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
qulonglong property() { return 0; }
|
||||||
|
void setProperty(qulonglong) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_t_xml[] =
|
||||||
|
"<property name=\"property\" type=\"t\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_d: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(double property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
double property() { return 0; }
|
||||||
|
void setProperty(double) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_d_xml[] =
|
||||||
|
"<property name=\"property\" type=\"d\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_s: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QString property() { return QString(); }
|
||||||
|
void setProperty(QString) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_s_xml[] =
|
||||||
|
"<property name=\"property\" type=\"s\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_v: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QDBusVariant property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QDBusVariant property() { return QDBusVariant(); }
|
||||||
|
void setProperty(QDBusVariant) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_v_xml[] =
|
||||||
|
"<property name=\"property\" type=\"v\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_o: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QDBusObjectPath property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QDBusObjectPath property() { return QDBusObjectPath(); }
|
||||||
|
void setProperty(QDBusObjectPath) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_o_xml[] =
|
||||||
|
"<property name=\"property\" type=\"o\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_g: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QDBusSignature property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QDBusSignature property() { return QDBusSignature(); }
|
||||||
|
void setProperty(QDBusSignature) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_g_xml[] =
|
||||||
|
"<property name=\"property\" type=\"g\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_h: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QDBusUnixFileDescriptor property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QDBusUnixFileDescriptor property() { return QDBusUnixFileDescriptor(); }
|
||||||
|
void setProperty(QDBusUnixFileDescriptor) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_h_xml[] =
|
||||||
|
"<property name=\"property\" type=\"h\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_ay: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QByteArray property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QByteArray property() { return QByteArray(); }
|
||||||
|
void setProperty(QByteArray) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_ay_xml[] =
|
||||||
|
"<property name=\"property\" type=\"ay\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_as: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QStringList property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QStringList property() { return QStringList(); }
|
||||||
|
void setProperty(QStringList) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_as_xml[] =
|
||||||
|
"<property name=\"property\" type=\"as\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_av: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QVariantList property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QVariantList property() { return QVariantList(); }
|
||||||
|
void setProperty(QVariantList) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_av_xml[] =
|
||||||
|
"<property name=\"property\" type=\"av\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_ao: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QList<QDBusObjectPath> property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QList<QDBusObjectPath> property() { return QList<QDBusObjectPath>(); }
|
||||||
|
void setProperty(QList<QDBusObjectPath>) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_ao_xml[] =
|
||||||
|
"<property name=\"property\" type=\"ao\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
|
class PropertyTest_ag: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QList<QDBusSignature> property READ property WRITE setProperty)
|
||||||
|
public:
|
||||||
|
QList<QDBusSignature> property() { return QList<QDBusSignature>(); }
|
||||||
|
void setProperty(QList<QDBusSignature>) { }
|
||||||
|
};
|
||||||
|
const char PropertyTest_ag_xml[] =
|
||||||
|
"<property name=\"property\" type=\"ag\" access=\"readwrite\"/>";
|
||||||
|
|
||||||
void tst_QDBusMetaObject::properties_data()
|
void tst_QDBusMetaObject::properties_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<const QMetaObject *>("metaobject");
|
QTest::addColumn<const QMetaObject *>("metaobject");
|
||||||
@ -676,6 +881,25 @@ void tst_QDBusMetaObject::properties_data()
|
|||||||
QTest::newRow("readwrite") << &PropertyTest2::staticMetaObject << QString(PropertyTest2_xml);
|
QTest::newRow("readwrite") << &PropertyTest2::staticMetaObject << QString(PropertyTest2_xml);
|
||||||
QTest::newRow("write") << &PropertyTest3::staticMetaObject << QString(PropertyTest3_xml);
|
QTest::newRow("write") << &PropertyTest3::staticMetaObject << QString(PropertyTest3_xml);
|
||||||
QTest::newRow("customtype") << &PropertyTest4::staticMetaObject << QString(PropertyTest4_xml);
|
QTest::newRow("customtype") << &PropertyTest4::staticMetaObject << QString(PropertyTest4_xml);
|
||||||
|
|
||||||
|
QTest::newRow("bool") << &PropertyTest_b::staticMetaObject << QString(PropertyTest_b_xml);
|
||||||
|
QTest::newRow("byte") << &PropertyTest_y::staticMetaObject << QString(PropertyTest_y_xml);
|
||||||
|
QTest::newRow("short") << &PropertyTest_n::staticMetaObject << QString(PropertyTest_n_xml);
|
||||||
|
QTest::newRow("ushort") << &PropertyTest_q::staticMetaObject << QString(PropertyTest_q_xml);
|
||||||
|
QTest::newRow("uint") << &PropertyTest_u::staticMetaObject << QString(PropertyTest_u_xml);
|
||||||
|
QTest::newRow("qlonglong") << &PropertyTest_x::staticMetaObject << QString(PropertyTest_x_xml);
|
||||||
|
QTest::newRow("qulonglong") << &PropertyTest_t::staticMetaObject << QString(PropertyTest_t_xml);
|
||||||
|
QTest::newRow("double") << &PropertyTest_d::staticMetaObject << QString(PropertyTest_d_xml);
|
||||||
|
QTest::newRow("QString") << &PropertyTest_s::staticMetaObject << QString(PropertyTest_s_xml);
|
||||||
|
QTest::newRow("QDBusVariant") << &PropertyTest_v::staticMetaObject << QString(PropertyTest_v_xml);
|
||||||
|
QTest::newRow("QDBusObjectPath") << &PropertyTest_o::staticMetaObject << QString(PropertyTest_o_xml);
|
||||||
|
QTest::newRow("QDBusSignature") << &PropertyTest_g::staticMetaObject << QString(PropertyTest_g_xml);
|
||||||
|
QTest::newRow("QDBusUnixFileDescriptor") << &PropertyTest_h::staticMetaObject << QString(PropertyTest_h_xml);
|
||||||
|
QTest::newRow("QByteArray") << &PropertyTest_ay::staticMetaObject << QString(PropertyTest_ay_xml);
|
||||||
|
QTest::newRow("QStringList") << &PropertyTest_as::staticMetaObject << QString(PropertyTest_as_xml);
|
||||||
|
QTest::newRow("QVariantList") << &PropertyTest_av::staticMetaObject << QString(PropertyTest_av_xml);
|
||||||
|
QTest::newRow("QList<QDBusObjectPath>") << &PropertyTest_ao::staticMetaObject << QString(PropertyTest_ao_xml);
|
||||||
|
QTest::newRow("QList<QDBusSignature>") << &PropertyTest_ag::staticMetaObject << QString(PropertyTest_ag_xml);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QDBusMetaObject::properties()
|
void tst_QDBusMetaObject::properties()
|
||||||
|
@ -748,7 +748,7 @@ void tst_Moc::classinfoWithEscapes()
|
|||||||
QCOMPARE(mobj->methodCount() - mobj->methodOffset(), 1);
|
QCOMPARE(mobj->methodCount() - mobj->methodOffset(), 1);
|
||||||
|
|
||||||
QMetaMethod mm = mobj->method(mobj->methodOffset());
|
QMetaMethod mm = mobj->method(mobj->methodOffset());
|
||||||
QCOMPARE(mm.signature(), "slotWithAReallyLongName(int)");
|
QCOMPARE(mm.methodSignature(), QByteArray("slotWithAReallyLongName(int)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_Moc::trNoopInClassInfo()
|
void tst_Moc::trNoopInClassInfo()
|
||||||
@ -1093,14 +1093,14 @@ void tst_Moc::invokable()
|
|||||||
{
|
{
|
||||||
const QMetaObject &mobj = InvokableBeforeReturnType::staticMetaObject;
|
const QMetaObject &mobj = InvokableBeforeReturnType::staticMetaObject;
|
||||||
QCOMPARE(mobj.methodCount(), 6);
|
QCOMPARE(mobj.methodCount(), 6);
|
||||||
QVERIFY(mobj.method(5).signature() == QByteArray("foo()"));
|
QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const QMetaObject &mobj = InvokableBeforeInline::staticMetaObject;
|
const QMetaObject &mobj = InvokableBeforeInline::staticMetaObject;
|
||||||
QCOMPARE(mobj.methodCount(), 7);
|
QCOMPARE(mobj.methodCount(), 7);
|
||||||
QVERIFY(mobj.method(5).signature() == QByteArray("foo()"));
|
QVERIFY(mobj.method(5).methodSignature() == QByteArray("foo()"));
|
||||||
QVERIFY(mobj.method(6).signature() == QByteArray("bar()"));
|
QVERIFY(mobj.method(6).methodSignature() == QByteArray("bar()"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,22 +1109,22 @@ void tst_Moc::singleFunctionKeywordSignalAndSlot()
|
|||||||
{
|
{
|
||||||
const QMetaObject &mobj = SingleFunctionKeywordBeforeReturnType::staticMetaObject;
|
const QMetaObject &mobj = SingleFunctionKeywordBeforeReturnType::staticMetaObject;
|
||||||
QCOMPARE(mobj.methodCount(), 7);
|
QCOMPARE(mobj.methodCount(), 7);
|
||||||
QVERIFY(mobj.method(5).signature() == QByteArray("mySignal()"));
|
QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
|
||||||
QVERIFY(mobj.method(6).signature() == QByteArray("mySlot()"));
|
QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const QMetaObject &mobj = SingleFunctionKeywordBeforeInline::staticMetaObject;
|
const QMetaObject &mobj = SingleFunctionKeywordBeforeInline::staticMetaObject;
|
||||||
QCOMPARE(mobj.methodCount(), 7);
|
QCOMPARE(mobj.methodCount(), 7);
|
||||||
QVERIFY(mobj.method(5).signature() == QByteArray("mySignal()"));
|
QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
|
||||||
QVERIFY(mobj.method(6).signature() == QByteArray("mySlot()"));
|
QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const QMetaObject &mobj = SingleFunctionKeywordAfterInline::staticMetaObject;
|
const QMetaObject &mobj = SingleFunctionKeywordAfterInline::staticMetaObject;
|
||||||
QCOMPARE(mobj.methodCount(), 7);
|
QCOMPARE(mobj.methodCount(), 7);
|
||||||
QVERIFY(mobj.method(5).signature() == QByteArray("mySignal()"));
|
QVERIFY(mobj.method(5).methodSignature() == QByteArray("mySignal()"));
|
||||||
QVERIFY(mobj.method(6).signature() == QByteArray("mySlot()"));
|
QVERIFY(mobj.method(6).methodSignature() == QByteArray("mySlot()"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1231,7 +1231,7 @@ void tst_Moc::constructors()
|
|||||||
QMetaMethod mm = mo->constructor(0);
|
QMetaMethod mm = mo->constructor(0);
|
||||||
QCOMPARE(mm.access(), QMetaMethod::Public);
|
QCOMPARE(mm.access(), QMetaMethod::Public);
|
||||||
QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
|
QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
|
||||||
QCOMPARE(mm.signature(), "CtorTestClass(QObject*)");
|
QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QObject*)"));
|
||||||
QCOMPARE(mm.typeName(), "");
|
QCOMPARE(mm.typeName(), "");
|
||||||
QList<QByteArray> paramNames = mm.parameterNames();
|
QList<QByteArray> paramNames = mm.parameterNames();
|
||||||
QCOMPARE(paramNames.size(), 1);
|
QCOMPARE(paramNames.size(), 1);
|
||||||
@ -1244,7 +1244,7 @@ void tst_Moc::constructors()
|
|||||||
QMetaMethod mm = mo->constructor(1);
|
QMetaMethod mm = mo->constructor(1);
|
||||||
QCOMPARE(mm.access(), QMetaMethod::Public);
|
QCOMPARE(mm.access(), QMetaMethod::Public);
|
||||||
QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
|
QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
|
||||||
QCOMPARE(mm.signature(), "CtorTestClass()");
|
QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass()"));
|
||||||
QCOMPARE(mm.typeName(), "");
|
QCOMPARE(mm.typeName(), "");
|
||||||
QCOMPARE(mm.parameterNames().size(), 0);
|
QCOMPARE(mm.parameterNames().size(), 0);
|
||||||
QCOMPARE(mm.parameterTypes().size(), 0);
|
QCOMPARE(mm.parameterTypes().size(), 0);
|
||||||
@ -1253,7 +1253,7 @@ void tst_Moc::constructors()
|
|||||||
QMetaMethod mm = mo->constructor(2);
|
QMetaMethod mm = mo->constructor(2);
|
||||||
QCOMPARE(mm.access(), QMetaMethod::Public);
|
QCOMPARE(mm.access(), QMetaMethod::Public);
|
||||||
QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
|
QCOMPARE(mm.methodType(), QMetaMethod::Constructor);
|
||||||
QCOMPARE(mm.signature(), "CtorTestClass(QString)");
|
QCOMPARE(mm.methodSignature(), QByteArray("CtorTestClass(QString)"));
|
||||||
QCOMPARE(mm.typeName(), "");
|
QCOMPARE(mm.typeName(), "");
|
||||||
QList<QByteArray> paramNames = mm.parameterNames();
|
QList<QByteArray> paramNames = mm.parameterNames();
|
||||||
QCOMPARE(paramNames.size(), 1);
|
QCOMPARE(paramNames.size(), 1);
|
||||||
|
@ -1275,7 +1275,7 @@ static int numberOfConnectedSignals(MySubWindow *subWindow)
|
|||||||
QMetaMethod method = subWindow->metaObject()->method(i);
|
QMetaMethod method = subWindow->metaObject()->method(i);
|
||||||
if (method.methodType() == QMetaMethod::Signal) {
|
if (method.methodType() == QMetaMethod::Signal) {
|
||||||
QString signature(QLatin1String("2"));
|
QString signature(QLatin1String("2"));
|
||||||
signature += QLatin1String(method.signature());
|
signature += QLatin1String(method.methodSignature().constData());
|
||||||
numConnectedSignals += subWindow->receivers(signature.toLatin1());
|
numConnectedSignals += subWindow->receivers(signature.toLatin1());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ void tst_qmetaobject::indexOfMethod_data()
|
|||||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||||
for (int i = 0; i < mo->methodCount(); ++i) {
|
for (int i = 0; i < mo->methodCount(); ++i) {
|
||||||
QMetaMethod method = mo->method(i);
|
QMetaMethod method = mo->method(i);
|
||||||
QByteArray sig = method.signature();
|
QByteArray sig = method.methodSignature();
|
||||||
QTest::newRow(sig) << sig;
|
QTest::newRow(sig) << sig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,7 +197,7 @@ void tst_qmetaobject::indexOfSignal_data()
|
|||||||
QMetaMethod method = mo->method(i);
|
QMetaMethod method = mo->method(i);
|
||||||
if (method.methodType() != QMetaMethod::Signal)
|
if (method.methodType() != QMetaMethod::Signal)
|
||||||
continue;
|
continue;
|
||||||
QByteArray sig = method.signature();
|
QByteArray sig = method.methodSignature();
|
||||||
QTest::newRow(sig) << sig;
|
QTest::newRow(sig) << sig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +220,7 @@ void tst_qmetaobject::indexOfSlot_data()
|
|||||||
QMetaMethod method = mo->method(i);
|
QMetaMethod method = mo->method(i);
|
||||||
if (method.methodType() != QMetaMethod::Slot)
|
if (method.methodType() != QMetaMethod::Slot)
|
||||||
continue;
|
continue;
|
||||||
QByteArray sig = method.signature();
|
QByteArray sig = method.methodSignature();
|
||||||
QTest::newRow(sig) << sig;
|
QTest::newRow(sig) << sig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,24 +66,18 @@ QT_BEGIN_NAMESPACE
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class QRawVector
|
class QRawVector
|
||||||
{
|
{
|
||||||
struct Data : QVectorData { T array[1]; };
|
typedef QVectorTypedData<T> Data;
|
||||||
|
|
||||||
T *m_begin;
|
T *m_begin;
|
||||||
int m_size;
|
int m_size;
|
||||||
int m_alloc;
|
int m_alloc;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//static Data dummy;
|
static Data *toBase(T *begin)
|
||||||
//int headerOffset() { return (char*)&dummy.array - (char*)&dummy; }
|
{ return (Data*)((char*)begin - offsetOfTypedData()); }
|
||||||
inline int headerOffset() const {
|
static T *fromBase(void *d)
|
||||||
// gcc complains about: return offsetof(Data, array); and also
|
{ return (T*)((char*)d + offsetOfTypedData()); }
|
||||||
// does not like '0' in the expression below.
|
|
||||||
return (char *)&(((Data *)(1))->array) - (char *)1;
|
|
||||||
}
|
|
||||||
inline Data *toBase(T *begin) const
|
|
||||||
{ return (Data*)((char*)begin - headerOffset()); }
|
|
||||||
inline T *fromBase(void *d) const
|
|
||||||
{ return (T*)((char*)d + headerOffset()); }
|
|
||||||
inline QRawVector()
|
inline QRawVector()
|
||||||
{ m_begin = fromBase(0); m_alloc = m_size = 0; realloc(m_size, m_alloc, true); }
|
{ m_begin = fromBase(0); m_alloc = m_size = 0; realloc(m_size, m_alloc, true); }
|
||||||
explicit QRawVector(int size);
|
explicit QRawVector(int size);
|
||||||
@ -270,17 +264,20 @@ private:
|
|||||||
T *allocate(int alloc);
|
T *allocate(int alloc);
|
||||||
void realloc(int size, int alloc, bool ref);
|
void realloc(int size, int alloc, bool ref);
|
||||||
void free(T *begin, int size);
|
void free(T *begin, int size);
|
||||||
int sizeOfTypedData() {
|
|
||||||
// this is more or less the same as sizeof(Data), except that it doesn't
|
class AlignmentDummy { QVectorData header; T array[1]; };
|
||||||
// count the padding at the end
|
|
||||||
return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
|
static Q_DECL_CONSTEXPR int offsetOfTypedData()
|
||||||
|
{
|
||||||
|
// (non-POD)-safe offsetof(AlignmentDummy, array)
|
||||||
|
return (sizeof(QVectorData) + (alignOfTypedData() - 1)) & ~(alignOfTypedData() - 1);
|
||||||
}
|
}
|
||||||
static inline int alignOfTypedData()
|
static Q_DECL_CONSTEXPR int alignOfTypedData()
|
||||||
{
|
{
|
||||||
#ifdef Q_ALIGNOF
|
#ifdef Q_ALIGNOF
|
||||||
return qMax<int>(sizeof(void*), Q_ALIGNOF(Data));
|
return Q_ALIGNOF(AlignmentDummy);
|
||||||
#else
|
#else
|
||||||
return 0;
|
return sizeof(void *);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,11 +285,11 @@ public:
|
|||||||
QVector<T> mutateToVector()
|
QVector<T> mutateToVector()
|
||||||
{
|
{
|
||||||
Data *d = toBase(m_begin);
|
Data *d = toBase(m_begin);
|
||||||
d->ref = 1;
|
d->ref.initializeOwned();
|
||||||
d->alloc = m_alloc;
|
d->alloc = m_alloc;
|
||||||
d->size = m_size;
|
d->size = m_size;
|
||||||
d->sharable = 0;
|
d->capacityReserved = 0;
|
||||||
d->capacity = 0;
|
d->offset = offsetOfTypedData();
|
||||||
|
|
||||||
QVector<T> v;
|
QVector<T> v;
|
||||||
*reinterpret_cast<QVectorData **>(&v) = d;
|
*reinterpret_cast<QVectorData **>(&v) = d;
|
||||||
@ -309,7 +306,7 @@ void QRawVector<T>::reserve(int asize)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void QRawVector<T>::resize(int asize)
|
void QRawVector<T>::resize(int asize)
|
||||||
{ realloc(asize, (asize > m_alloc || (asize < m_size && asize < (m_alloc >> 1)))
|
{ realloc(asize, (asize > m_alloc || (asize < m_size && asize < (m_alloc >> 1)))
|
||||||
? QVectorData::grow(sizeOfTypedData(), asize, sizeof(T), QTypeInfo<T>::isStatic)
|
? QVectorData::grow(offsetOfTypedData(), asize, sizeof(T))
|
||||||
: m_alloc, false); }
|
: m_alloc, false); }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void QRawVector<T>::clear()
|
inline void QRawVector<T>::clear()
|
||||||
@ -370,7 +367,7 @@ QRawVector<T> &QRawVector<T>::operator=(const QRawVector<T> &v)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *QRawVector<T>::allocate(int aalloc)
|
inline T *QRawVector<T>::allocate(int aalloc)
|
||||||
{
|
{
|
||||||
QVectorData *d = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData());
|
QVectorData *d = QVectorData::allocate(offsetOfTypedData() + aalloc * sizeof(T), alignOfTypedData());
|
||||||
Q_CHECK_PTR(d);
|
Q_CHECK_PTR(d);
|
||||||
return fromBase(d);
|
return fromBase(d);
|
||||||
}
|
}
|
||||||
@ -446,10 +443,9 @@ void QRawVector<T>::realloc(int asize, int aalloc, bool ref)
|
|||||||
changed = true;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
QT_TRY {
|
QT_TRY {
|
||||||
QVectorData *mem = QVectorData::reallocate(
|
QVectorData *mem = QVectorData::reallocate(toBase(m_begin),
|
||||||
toBase(m_begin), sizeOfTypedData() + (aalloc - 1) * sizeof(T),
|
offsetOfTypedData() + aalloc * sizeof(T),
|
||||||
sizeOfTypedData()
|
offsetOfTypedData() + xalloc * sizeof(T), alignOfTypedData());
|
||||||
+ (xalloc - 1) * sizeof(T), alignOfTypedData());
|
|
||||||
Q_CHECK_PTR(mem);
|
Q_CHECK_PTR(mem);
|
||||||
xbegin = fromBase(mem);
|
xbegin = fromBase(mem);
|
||||||
xsize = m_size;
|
xsize = m_size;
|
||||||
@ -511,8 +507,7 @@ void QRawVector<T>::append(const T &t)
|
|||||||
{
|
{
|
||||||
if (m_size + 1 > m_alloc) {
|
if (m_size + 1 > m_alloc) {
|
||||||
const T copy(t);
|
const T copy(t);
|
||||||
realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + 1, sizeof(T),
|
realloc(m_size, QVectorData::grow(offsetOfTypedData(), m_size + 1, sizeof(T)), false);
|
||||||
QTypeInfo<T>::isStatic), false);
|
|
||||||
if (QTypeInfo<T>::isComplex)
|
if (QTypeInfo<T>::isComplex)
|
||||||
new (m_begin + m_size) T(copy);
|
new (m_begin + m_size) T(copy);
|
||||||
else
|
else
|
||||||
@ -533,8 +528,7 @@ typename QRawVector<T>::iterator QRawVector<T>::insert(iterator before, size_typ
|
|||||||
if (n != 0) {
|
if (n != 0) {
|
||||||
const T copy(t);
|
const T copy(t);
|
||||||
if (m_size + n > m_alloc)
|
if (m_size + n > m_alloc)
|
||||||
realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + n, sizeof(T),
|
realloc(m_size, QVectorData::grow(offsetOfTypedData(), m_size + n, sizeof(T)), false);
|
||||||
QTypeInfo<T>::isStatic), false);
|
|
||||||
if (QTypeInfo<T>::isStatic) {
|
if (QTypeInfo<T>::isStatic) {
|
||||||
T *b = m_begin + m_size;
|
T *b = m_begin + m_size;
|
||||||
T *i = m_begin + m_size + n;
|
T *i = m_begin + m_size + n;
|
||||||
|
Loading…
Reference in New Issue
Block a user