diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2011-10-10 11:56:43 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-10-19 10:25:28 +0200 |
commit | 9e92ecde74d33eddd39de88472964fb20feaaebf (patch) | |
tree | c127c382451255cf64d6259c33dc34c754e965b8 /src/gui | |
parent | ae30d71413595b3cb0550e047132ea07510d35a3 (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.cpp | 38 |
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 }; |