summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.h
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2011-10-10 11:56:43 +0200
committerQt by Nokia <qt-info@nokia.com>2011-10-19 10:25:28 +0200
commit9e92ecde74d33eddd39de88472964fb20feaaebf (patch)
treec127c382451255cf64d6259c33dc34c754e965b8 /src/corelib/kernel/qmetatype.h
parentae30d71413595b3cb0550e047132ea07510d35a3 (diff)
Provide API for "placement new" construction of meta-types
By making it possible to specify the place in memory where a type should be constructed, any meta-type can be allocated on the stack, for example. In the QML/JS QObject binding, this makes it possible to call slots and access properties from JavaScript without having to perform any mallocs (e.g. due to QVariant creation) in the C++ <--> JS value conversion, in the best case. In addition to QMetaType::construct() and QMetaType::destruct(), this change introduces QMetaType::typeSize(), which returns the size of a type in bytes. This can be used to prepare a suitable buffer for constructing a type using construct(). Benchmarks indicate that in-place construction is 2-5x faster than normal construction for core and GUI types on linux-g++. Note that there is already a QMetaType::construct() function in Qt 4, which has been renamed to QMetaType::create() in Qt 5. In order to avoid existing usages of construct() in user code to call the Qt 5 construct() (when they really meant to call create()), the third argument ("copy") of construct() is made mandatory. Hence, calls to QMetaType::construct() written for Qt 4 will cause a compile error when compiled with Qt 5, and the user must adapt his code. Task-number: QTBUG-12574 Change-Id: I836f06f6ee1c1c3edbd199a03424c78c942bdd3e Reviewed-by: João Abecasis <joao.abecasis@nokia.com> Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r--src/corelib/kernel/qmetatype.h41
1 files changed, 36 insertions, 5 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index e65c084ae0..660807c698 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -49,6 +49,8 @@
#include <QtCore/qdatastream.h>
#endif
+#include <new>
+
#ifdef Bool
#error qmetatype.h must be included before any header file that defines Bool
#endif
@@ -106,6 +108,9 @@ public:
typedef void (*Deleter)(void *);
typedef void *(*Creator)(const void *);
+ typedef void (*Destructor)(void *);
+ typedef void *(*Constructor)(void *, const void *);
+
#ifndef QT_NO_DATASTREAM
typedef void (*SaveOperator)(QDataStream &, const void *);
typedef void (*LoadOperator)(QDataStream &, void *);
@@ -116,16 +121,20 @@ public:
#endif
static int registerType(const char *typeName, Deleter deleter,
Creator creator);
+ static int registerType(const char *typeName, Deleter deleter,
+ Creator creator,
+ Destructor destructor,
+ Constructor constructor,
+ int size);
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 bool isRegistered(int type);
static void *create(int type, const void *copy = 0);
-#ifdef QT_DEPRECATED
- QT_DEPRECATED static void *construct(int type, const void *copy = 0)
- { return create(type, copy); }
-#endif
static void destroy(int type, void *data);
+ static void *construct(int type, void *where, const void *copy);
+ static void destruct(int type, void *where);
static void unregisterType(const char *typeName);
#ifndef QT_NO_DATASTREAM
@@ -148,6 +157,21 @@ void *qMetaTypeCreateHelper(const T *t)
return new T(*static_cast<const T*>(t));
}
+template <typename T>
+void qMetaTypeDestructHelper(T *t)
+{
+ t->~T();
+}
+
+template <typename T>
+void *qMetaTypeConstructHelper(void *where, const T *t)
+{
+ if (!t)
+ return new (where) T;
+ else
+ return new (where) T(*static_cast<const T*>(t));
+}
+
#ifndef QT_NO_DATASTREAM
template <typename T>
void qMetaTypeSaveHelper(QDataStream &stream, const T *t)
@@ -202,9 +226,16 @@ int qRegisterMetaType(const char *typeName
CreatePtr cptr = qMetaTypeCreateHelper<T>;
typedef void(*DeletePtr)(T*);
DeletePtr dptr = qMetaTypeDeleteHelper<T>;
+ typedef void*(*ConstructPtr)(void *, const T*);
+ ConstructPtr ipcptr = qMetaTypeConstructHelper<T>;
+ typedef void(*DestructPtr)(T*);
+ DestructPtr ipdptr = qMetaTypeDestructHelper<T>;
return QMetaType::registerType(typeName, reinterpret_cast<QMetaType::Deleter>(dptr),
- reinterpret_cast<QMetaType::Creator>(cptr));
+ reinterpret_cast<QMetaType::Creator>(cptr),
+ reinterpret_cast<QMetaType::Destructor>(ipdptr),
+ reinterpret_cast<QMetaType::Constructor>(ipcptr),
+ sizeof(T));
}
#ifndef QT_NO_DATASTREAM