summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorJędrzej Nowacki <jedrzej.nowacki@nokia.com>2011-12-13 12:07:47 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-22 13:20:40 +0100
commit56f154c747a6623fc8249265262160ac0adbe4cd (patch)
tree5b3a86073db010820b745d0ca8a9284997a71e7b /src/corelib
parentd868c9945a188d6ad22e0b7d6d24ac7fca00ab4e (diff)
Allow QMetaType to register information about movability
We need that information to perform some optimizations in QVariant. Change-Id: Id9a1716e49e4cedd17cd09a32fea4ff003ef61f2 Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qmetatype.cpp82
-rw-r--r--src/corelib/kernel/qmetatype.h24
-rw-r--r--src/corelib/kernel/qmetatype_p.h6
3 files changed, 107 insertions, 5 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index d5a22ef07d..02cf9ae49c 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -240,6 +240,16 @@ template<> struct TypeDefiniton<QRegExp> { static const bool IsAvailable = false
*/
/*!
+ \enum QMetaType::TypeFlags
+
+ The enum describes attributes of a type supported by QMetaType.
+
+ \value NeedsConstruction This type has non-trivial constructors. If the flag is not set instances can be safely initialized with memset to 0.
+ \value NeedsDestruction This type has a non-trivial destructor. If the flag is not set calls to the destructor are not necessary before discarding objects.
+ \value MovableType An instance of a type having this attribute can be safely moved by memcpy.
+*/
+
+/*!
\class QMetaType
\brief The QMetaType class manages named types in the meta-object system.
@@ -423,7 +433,7 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
int QMetaType::registerType(const char *typeName, Deleter deleter,
Creator creator)
{
- return registerType(typeName, deleter, creator, 0, 0, 0);
+ return registerType(typeName, deleter, creator, 0, 0, 0, TypeFlags());
}
/*! \internal
@@ -438,7 +448,7 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
Creator creator,
Destructor destructor,
Constructor constructor,
- int size)
+ int size, TypeFlags flags)
{
QVector<QCustomTypeInfo> *ct = customTypes();
if (!ct || !typeName || !deleter || !creator)
@@ -470,6 +480,7 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
inf.constructor = constructor;
inf.destructor = destructor;
inf.size = size;
+ inf.flags = flags;
idx = ct->size() + User;
ct->append(inf);
}
@@ -1633,6 +1644,73 @@ int QMetaType::sizeOf(int type)
return QMetaTypeSwitcher::switcher<int>(sizeOf, type, 0);
}
+namespace {
+class Flags
+{
+ template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
+ struct FlagsImpl
+ {
+ static quint32 Flags(const int)
+ {
+ return (!QTypeInfo<T>::isStatic * QMetaType::MovableType)
+ | (QTypeInfo<T>::isComplex * QMetaType::NeedsConstruction)
+ | (QTypeInfo<T>::isComplex * QMetaType::NeedsDestruction);
+ }
+ };
+ template<typename T>
+ struct FlagsImpl<T, /* IsAcceptedType = */ false>
+ {
+ static quint32 Flags(const int type)
+ {
+ return Flags::undefinedTypeFlags(type);
+ }
+ };
+public:
+ Flags(const int type)
+ : m_type(type)
+ {}
+ template<typename T>
+ quint32 delegate(const T*) { return FlagsImpl<T>::Flags(m_type); }
+ quint32 delegate(const QMetaTypeSwitcher::UnknownType*) { return customTypeFlags(m_type); }
+private:
+ const int m_type;
+ static quint32 customTypeFlags(const int type)
+ {
+ const QVector<QCustomTypeInfo> * const ct = customTypes();
+ if (!ct)
+ return 0;
+ QReadLocker locker(customTypesLock());
+ if (ct->count() <= type - QMetaType::User)
+ return 0;
+ return ct->at(type - QMetaType::User).flags;
+ }
+ static quint32 undefinedTypeFlags(const int type);
+};
+
+quint32 Flags::undefinedTypeFlags(const int type)
+{
+ if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType)
+ return qMetaTypeGuiHelper ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].flags : 0;
+ else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType)
+ return qMetaTypeWidgetsHelper ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].flags : 0;
+ return customTypeFlags(type);
+}
+
+} // namespace
+
+/*!
+ \since 5.0
+
+ Returns flags of the given \a type.
+
+ \sa TypeFlags()
+*/
+QMetaType::TypeFlags QMetaType::typeFlags(int type)
+{
+ Flags flags(type);
+ return static_cast<QMetaType::TypeFlags>(QMetaTypeSwitcher::switcher<quint32>(flags, type, 0));
+}
+
/*!
\fn int qRegisterMetaType(const char *typeName)
\relates QMetaType
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 717e72c810..dd5b1f8ed5 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -202,6 +202,13 @@ public:
User = 256
};
+ enum TypeFlag {
+ NeedsConstruction = 0x1,
+ NeedsDestruction = 0x2,
+ MovableType = 0x4
+ };
+ Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
+
typedef void (*Deleter)(void *);
typedef void *(*Creator)(const void *);
@@ -222,11 +229,13 @@ public:
Creator creator,
Destructor destructor,
Constructor constructor,
- int size);
+ int size,
+ QMetaType::TypeFlags flags);
static int registerTypedef(const char *typeName, int aliasId);
static int type(const char *typeName);
static const char *typeName(int type);
static int sizeOf(int type);
+ static TypeFlags typeFlags(int type);
static bool isRegistered(int type);
static void *create(int type, const void *copy = 0);
#if QT_DEPRECATED_SINCE(5, 0)
@@ -246,6 +255,8 @@ public:
#undef QT_DEFINE_METATYPE_ID
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
+
template <typename T>
void qMetaTypeDeleteHelper(T *t)
{
@@ -334,11 +345,20 @@ int qRegisterMetaType(const char *typeName
typedef void(*DestructPtr)(T*);
DestructPtr ipdptr = qMetaTypeDestructHelper<T>;
+ QMetaType::TypeFlags flags;
+ if (!QTypeInfo<T>::isStatic)
+ flags |= QMetaType::MovableType;
+ if (QTypeInfo<T>::isComplex) {
+ flags |= QMetaType::NeedsConstruction;
+ flags |= QMetaType::NeedsDestruction;
+ }
+
return QMetaType::registerType(typeName, reinterpret_cast<QMetaType::Deleter>(dptr),
reinterpret_cast<QMetaType::Creator>(cptr),
reinterpret_cast<QMetaType::Destructor>(ipdptr),
reinterpret_cast<QMetaType::Constructor>(ipcptr),
- sizeof(T));
+ sizeof(T),
+ flags);
}
#ifndef QT_NO_DATASTREAM
diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h
index 448c6ded13..46c5697678 100644
--- a/src/corelib/kernel/qmetatype_p.h
+++ b/src/corelib/kernel/qmetatype_p.h
@@ -150,6 +150,7 @@ public:
QMetaType::Constructor constructor;
QMetaType::Destructor destructor;
int size;
+ quint32 flags; // same as QMetaType::TypeFlags
};
#ifndef QT_NO_DATASTREAM
@@ -167,7 +168,10 @@ public:
QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \
/*constructor*/(reinterpret_cast<QMetaType::Constructor>(QMetaTypeInterface::Impl<Type>::constructor)), \
/*destructor*/(reinterpret_cast<QMetaType::Destructor>(QMetaTypeInterface::Impl<Type>::destructor)), \
- /*size*/(sizeof(Type)) \
+ /*size*/(sizeof(Type)), \
+ /*flags*/(!QTypeInfo<Type>::isStatic * QMetaType::MovableType) \
+ | (QTypeInfo<Type>::isComplex * QMetaType::NeedsConstruction) \
+ | (QTypeInfo<Type>::isComplex * QMetaType::NeedsDestruction) \
}
QT_END_NAMESPACE