summaryrefslogtreecommitdiffstats
path: root/src/gui
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/gui
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/gui')
-rw-r--r--src/gui/kernel/qguivariant.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index 982fc3ccd5..72f7e183e1 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -643,6 +643,9 @@ struct QMetaTypeGuiHelper
QMetaType::SaveOperator saveOp;
QMetaType::LoadOperator loadOp;
#endif
+ QMetaType::Constructor constructor;
+ QMetaType::Destructor destructor;
+ int size;
};
extern Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeGuiHelper;
@@ -653,13 +656,21 @@ extern Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeGuiHelper;
typedef void *(*QCreate##TYPE)(const TYPE *); \
static const QCreate##TYPE qCreate##TYPE = qMetaTypeCreateHelper<TYPE>; \
typedef void (*QDelete##TYPE)(TYPE *); \
- static const QDelete##TYPE qDelete##TYPE = qMetaTypeDeleteHelper<TYPE>;
+ static const QDelete##TYPE qDelete##TYPE = qMetaTypeDeleteHelper<TYPE>; \
+ typedef void *(*QConstruct##TYPE)(void *, const TYPE *); \
+ static const QConstruct##TYPE qConstruct##TYPE = qMetaTypeConstructHelper<TYPE>; \
+ typedef void (*QDestruct##TYPE)(TYPE *); \
+ static const QDestruct##TYPE qDestruct##TYPE = qMetaTypeDestructHelper<TYPE>;
#else
# define Q_DECL_METATYPE_HELPER(TYPE) \
typedef void *(*QCreate##TYPE)(const TYPE *); \
static const QCreate##TYPE qCreate##TYPE = qMetaTypeCreateHelper<TYPE>; \
typedef void (*QDelete##TYPE)(TYPE *); \
static const QDelete##TYPE qDelete##TYPE = qMetaTypeDeleteHelper<TYPE>; \
+ typedef void *(*QConstruct##TYPE)(void *, const TYPE *); \
+ static const QConstruct##TYPE qConstruct##TYPE = qMetaTypeConstructHelper<TYPE>; \
+ typedef void (*QDestruct##TYPE)(TYPE *); \
+ static const QDestruct##TYPE qDestruct##TYPE = qMetaTypeDestructHelper<TYPE>; \
typedef void (*QSave##TYPE)(QDataStream &, const TYPE *); \
static const QSave##TYPE qSave##TYPE = qMetaTypeSaveHelper<TYPE>; \
typedef void (*QLoad##TYPE)(QDataStream &, TYPE *); \
@@ -705,13 +716,20 @@ Q_DECL_METATYPE_HELPER(QQuaternion)
#ifdef QT_NO_DATASTREAM
# define Q_IMPL_METATYPE_HELPER(TYPE) \
{ reinterpret_cast<QMetaType::Creator>(qCreate##TYPE), \
- reinterpret_cast<QMetaType::Deleter>(qDelete##TYPE) }
+ reinterpret_cast<QMetaType::Deleter>(qDelete##TYPE), \
+ reinterpret_cast<QMetaType::Constructor>(qConstruct##TYPE), \
+ reinterpret_cast<QMetaType::Destructor>(qDestruct##TYPE), \
+ sizeof(TYPE) \
+ }
#else
# define Q_IMPL_METATYPE_HELPER(TYPE) \
{ reinterpret_cast<QMetaType::Creator>(qCreate##TYPE), \
reinterpret_cast<QMetaType::Deleter>(qDelete##TYPE), \
reinterpret_cast<QMetaType::SaveOperator>(qSave##TYPE), \
- reinterpret_cast<QMetaType::LoadOperator>(qLoad##TYPE) \
+ reinterpret_cast<QMetaType::LoadOperator>(qLoad##TYPE), \
+ reinterpret_cast<QMetaType::Constructor>(qConstruct##TYPE), \
+ reinterpret_cast<QMetaType::Destructor>(qDestruct##TYPE), \
+ sizeof(TYPE) \
}
#endif
@@ -726,12 +744,12 @@ static const QMetaTypeGuiHelper qVariantGuiHelper[] = {
Q_IMPL_METATYPE_HELPER(QRegion),
Q_IMPL_METATYPE_HELPER(QBitmap),
#ifdef QT_NO_CURSOR
- {0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0},
#else
Q_IMPL_METATYPE_HELPER(QCursor),
#endif
#ifdef QT_NO_SHORTCUT
- {0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0},
#else
Q_IMPL_METATYPE_HELPER(QKeySequence),
#endif
@@ -743,27 +761,27 @@ static const QMetaTypeGuiHelper qVariantGuiHelper[] = {
#ifndef QT_NO_MATRIX4X4
Q_IMPL_METATYPE_HELPER(QMatrix4x4),
#else
- {0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0},
#endif
#ifndef QT_NO_VECTOR2D
Q_IMPL_METATYPE_HELPER(QVector2D),
#else
- {0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0},
#endif
#ifndef QT_NO_VECTOR3D
Q_IMPL_METATYPE_HELPER(QVector3D),
#else
- {0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0},
#endif
#ifndef QT_NO_VECTOR4D
Q_IMPL_METATYPE_HELPER(QVector4D),
#else
- {0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0},
#endif
#ifndef QT_NO_QUATERNION
Q_IMPL_METATYPE_HELPER(QQuaternion)
#else
- {0, 0, 0, 0}
+ {0, 0, 0, 0, 0, 0, 0}
#endif
};