1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtCore module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qmetatype.h"
43 #include "qmetatype_p.h"
44 #include "qobjectdefs.h"
45 #include "qdatetime.h"
46 #include "qbytearray.h"
47 #include "qreadwritelock.h"
49 #include "qstringlist.h"
52 #include "qeasingcurve.h"
55 #include "qmetatypeswitcher_p.h"
57 #ifdef QT_BOOTSTRAPPED
58 # ifndef QT_NO_GEOM_VARIANT
59 # define QT_NO_GEOM_VARIANT
62 # include "qbitarray.h"
64 # include "qvariant.h"
65 # include "qabstractitemmodel.h"
68 #ifndef QT_NO_GEOM_VARIANT
77 #define NS(x) QT_PREPEND_NAMESPACE(x)
82 struct TypeDefinition {
83 static const bool IsAvailable = true;
86 struct DefinedTypesFilter {
89 static const bool IsAccepted = TypeDefinition<T>::IsAvailable && QTypeModuleInfo<T>::IsCore;
93 // Ignore these types, as incomplete
94 #ifdef QT_NO_GEOM_VARIANT
95 template<> struct TypeDefinition<QRect> { static const bool IsAvailable = false; };
96 template<> struct TypeDefinition<QRectF> { static const bool IsAvailable = false; };
97 template<> struct TypeDefinition<QSize> { static const bool IsAvailable = false; };
98 template<> struct TypeDefinition<QSizeF> { static const bool IsAvailable = false; };
99 template<> struct TypeDefinition<QLine> { static const bool IsAvailable = false; };
100 template<> struct TypeDefinition<QLineF> { static const bool IsAvailable = false; };
101 template<> struct TypeDefinition<QPoint> { static const bool IsAvailable = false; };
102 template<> struct TypeDefinition<QPointF> { static const bool IsAvailable = false; };
104 #ifdef QT_BOOTSTRAPPED
105 template<> struct TypeDefinition<QVariantMap> { static const bool IsAvailable = false; };
106 template<> struct TypeDefinition<QVariantHash> { static const bool IsAvailable = false; };
107 template<> struct TypeDefinition<QVariantList> { static const bool IsAvailable = false; };
108 template<> struct TypeDefinition<QVariant> { static const bool IsAvailable = false; };
109 template<> struct TypeDefinition<QBitArray> { static const bool IsAvailable = false; };
110 template<> struct TypeDefinition<QUrl> { static const bool IsAvailable = false; };
111 template<> struct TypeDefinition<QEasingCurve> { static const bool IsAvailable = false; };
112 template<> struct TypeDefinition<QModelIndex> { static const bool IsAvailable = false; };
115 template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = false; };
120 \macro Q_DECLARE_OPAQUE_POINTER(Pointer)
123 This macro enables pointers to forward-declared types to be registered with
124 QMetaType using either Q_DECLARE_METATYPE() or qRegisterMetaType().
126 \sa Q_DECLARE_METATYPE(), qRegisterMetaType()
131 \macro Q_DECLARE_METATYPE(Type)
134 This macro makes the type \a Type known to QMetaType as long as it
135 provides a public default constructor, a public copy constructor and
137 It is needed to use the type \a Type as a custom type in QVariant.
139 This macro requires that \a Type is a fully defined type at the point where
140 it is used. For pointer types, it also requires that the pointed to type is
141 fully defined. Use in conjunction with Q_DECLARE_OPAQUE_POINTER() to
142 register pointers to forward declared types.
144 Ideally, this macro should be placed below the declaration of
145 the class or struct. If that is not possible, it can be put in
146 a private header file which has to be included every time that
147 type is used in a QVariant.
149 Adding a Q_DECLARE_METATYPE() makes the type known to all template
150 based functions, including QVariant. Note that if you intend to
151 use the type in \e queued signal and slot connections or in
152 QObject's property system, you also have to call
153 qRegisterMetaType() since the names are resolved at runtime.
155 This example shows a typical use case of Q_DECLARE_METATYPE():
157 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 0
159 If \c MyStruct is in a namespace, the Q_DECLARE_METATYPE() macro
160 has to be outside the namespace:
162 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 1
164 Since \c{MyStruct} is now known to QMetaType, it can be used in QVariant:
166 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 2
168 \sa qRegisterMetaType()
172 \enum QMetaType::Type
174 These are the built-in types supported by QMetaType:
179 \value UInt \c{unsigned int}
180 \value Double \c double
182 \value QString QString
183 \value QByteArray QByteArray
185 \value VoidStar \c{void *}
187 \value LongLong LongLong
188 \value Short \c{short}
190 \value ULong \c{unsigned long}
191 \value ULongLong ULongLong
192 \value UShort \c{unsigned short}
193 \value UChar \c{unsigned char}
194 \value Float \c float
195 \value QObjectStar QObject *
196 \value QWidgetStar QWidget *
197 \value QVariant QVariant
199 \value QCursor QCursor
203 \value QVariantList QVariantList
204 \value QPolygon QPolygon
205 \value QPolygonF QPolygonF
210 \value QTextLength QTextLength
211 \value QStringList QStringList
212 \value QVariantMap QVariantMap
213 \value QVariantHash QVariantHash
217 \value QTextFormat QTextFormat
221 \value QRegExp QRegExp
222 \value QDateTime QDateTime
223 \value QPointF QPointF
224 \value QPalette QPalette
227 \value QRegion QRegion
228 \value QBitArray QBitArray
230 \value QKeySequence QKeySequence
231 \value QSizePolicy QSizePolicy
232 \value QPixmap QPixmap
233 \value QLocale QLocale
234 \value QBitmap QBitmap
235 \value QMatrix QMatrix
236 \value QTransform QTransform
237 \value QMatrix4x4 QMatrix4x4
238 \value QVector2D QVector2D
239 \value QVector3D QVector3D
240 \value QVector4D QVector4D
241 \value QQuaternion QQuaternion
242 \value QEasingCurve QEasingCurve
244 \value User Base value for user types
245 \value UnknownType This is an invalid type id. It is returned from QMetaType for types that are not registered
247 \omitvalue FirstGuiType
248 \omitvalue FirstWidgetsType
249 \omitvalue LastCoreType
250 \omitvalue LastGuiType
251 \omitvalue LastWidgetsType
253 \omitvalue HighestInternalId
255 Additional types can be registered using Q_DECLARE_METATYPE().
257 \sa type(), typeName()
261 \enum QMetaType::TypeFlags
263 The enum describes attributes of a type supported by QMetaType.
265 \value NeedsConstruction This type has non-trivial constructors. If the flag is not set instances can be safely initialized with memset to 0.
266 \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.
267 \value MovableType An instance of a type having this attribute can be safely moved by memcpy.
272 \brief The QMetaType class manages named types in the meta-object system.
277 The class is used as a helper to marshall types in QVariant and
278 in queued signals and slots connections. It associates a type
279 name to a type so that it can be created and destructed
280 dynamically at run-time. Declare new types with Q_DECLARE_METATYPE()
281 to make them available to QVariant and other template-based functions.
282 Call qRegisterMetaType() to make type available to non-template based
283 functions, such as the queued signal and slot connections.
285 Any class or struct that has a public default
286 constructor, a public copy constructor, and a public destructor
289 The following code allocates and destructs an instance of
292 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 3
294 If we want the stream operators \c operator<<() and \c
295 operator>>() to work on QVariant objects that store custom types,
296 the custom type must provide \c operator<<() and \c operator>>()
299 \sa Q_DECLARE_METATYPE(), QVariant::setValue(), QVariant::value(), QVariant::fromValue()
302 #define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
303 { #RealName, sizeof(#RealName) - 1, MetaTypeId },
305 #define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr) \
306 { RealNameStr, sizeof(RealNameStr) - 1, QMetaType::MetaTypeName },
308 #define QT_ADD_STATIC_METATYPE_HACKS_ITER(MetaTypeName, TypeId, Name) \
309 QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeName, Name)
311 static const struct { const char * typeName; int typeNameLength; int type; } types[] = {
312 QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE)
313 QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER)
314 QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER)
315 {0, 0, QMetaType::UnknownType}
318 Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0;
319 Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = 0;
321 class QCustomTypeInfo : public QMetaTypeInterface
327 QMetaTypeInterface empty = QT_METATYPE_INTERFACE_INIT(void);
328 *static_cast<QMetaTypeInterface*>(this) = empty;
336 union CheckThatItIsPod
337 { // This should break if QMetaTypeInterface is not a POD type
338 QMetaTypeInterface iface;
342 Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
343 Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
344 Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
346 #ifndef QT_NO_DATASTREAM
349 void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
352 registerStreamOperators(type(typeName), saveOp, loadOp);
357 void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
361 return; //builtin types should not be registered;
362 QVector<QCustomTypeInfo> *ct = customTypes();
365 QWriteLocker locker(customTypesLock());
366 QCustomTypeInfo &inf = (*ct)[idx - User];
370 #endif // QT_NO_DATASTREAM
373 Returns the type name associated with the given \a type, or 0 if no
374 matching type was found. The returned pointer must not be deleted.
376 \sa type(), isRegistered(), Type
378 const char *QMetaType::typeName(int type)
380 // In theory it can be filled during compilation time, but for some reason template code
381 // that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably
382 // it is not worth of it.
383 static const char *namesCache[QMetaType::HighestInternalId + 1];
386 if (type <= QMetaType::HighestInternalId && ((result = namesCache[type])))
389 #define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \
390 case QMetaType::MetaTypeName: result = #RealName; break;
392 switch (QMetaType::Type(type)) {
393 QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER)
396 if (Q_UNLIKELY(type < QMetaType::User)) {
397 return 0; // It can happen when someone cast int to QVariant::Type, we should not crash...
399 const QVector<QCustomTypeInfo> * const ct = customTypes();
400 QReadLocker locker(customTypesLock());
401 return ct && ct->count() > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty()
402 ? ct->at(type - QMetaType::User).typeName.constData()
407 #undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
409 Q_ASSERT(type <= QMetaType::HighestInternalId);
410 namesCache[type] = result;
415 Similar to QMetaType::type(), but only looks in the static set of types.
417 static inline int qMetaTypeStaticType(const char *typeName, int length)
420 while (types[i].typeName && ((length != types[i].typeNameLength)
421 || strcmp(typeName, types[i].typeName))) {
424 return types[i].type;
428 Similar to QMetaType::type(), but only looks in the custom set of
429 types, and doesn't lock the mutex.
431 static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
433 const QVector<QCustomTypeInfo> * const ct = customTypes();
435 return QMetaType::UnknownType;
437 for (int v = 0; v < ct->count(); ++v) {
438 const QCustomTypeInfo &customInfo = ct->at(v);
439 if ((length == customInfo.typeName.size())
440 && !strcmp(typeName, customInfo.typeName.constData())) {
441 if (customInfo.alias >= 0)
442 return customInfo.alias;
443 return v + QMetaType::User;
446 return QMetaType::UnknownType;
451 This function is needed until existing code outside of qtbase
452 has been changed to call the new version of registerType().
454 int QMetaType::registerType(const char *typeName, Deleter deleter,
457 return registerType(typeName, deleter, creator, 0, 0, 0, TypeFlags());
463 Registers a user type for marshalling, with \a typeName, a \a
464 deleter, a \a creator, a \a destructor, a \a constructor, and
465 a \a size. Returns the type's handle, or -1 if the type could
468 int QMetaType::registerType(const char *typeName, Deleter deleter,
470 Destructor destructor,
471 Constructor constructor,
472 int size, TypeFlags flags)
474 QVector<QCustomTypeInfo> *ct = customTypes();
475 if (!ct || !typeName || !deleter || !creator)
479 NS(QByteArray) normalizedTypeName = typeName;
481 NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
484 int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
485 normalizedTypeName.size());
487 int previousSize = 0;
488 int previousFlags = 0;
489 if (idx == UnknownType) {
490 QWriteLocker locker(customTypesLock());
491 idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
492 normalizedTypeName.size());
493 if (idx == UnknownType) {
495 inf.typeName = normalizedTypeName;
496 inf.creator = creator;
497 inf.deleter = deleter;
498 #ifndef QT_NO_DATASTREAM
503 inf.constructor = constructor;
504 inf.destructor = destructor;
507 idx = ct->size() + User;
513 previousSize = ct->at(idx - User).size;
514 previousFlags = ct->at(idx - User).flags;
519 previousSize = QMetaType::sizeOf(idx);
520 previousFlags = QMetaType::typeFlags(idx);
523 if (previousSize != size) {
524 qFatal("QMetaType::registerType: Binary compatibility break "
525 "-- Size mismatch for type '%s' [%i]. Previously registered "
526 "size %i, now registering size %i.",
527 normalizedTypeName.constData(), idx, previousSize, size);
529 if (previousFlags != flags) {
530 qFatal("QMetaType::registerType: Binary compatibility break "
531 "-- Type flags for type '%s' [%i] don't match. Previously "
532 "registered TypeFlags(0x%x), now registering TypeFlags(0x%x).",
533 normalizedTypeName.constData(), idx, previousFlags, int(flags));
542 Registers a user type for marshalling, as an alias of another type (typedef)
544 int QMetaType::registerTypedef(const char* typeName, int aliasId)
546 QVector<QCustomTypeInfo> *ct = customTypes();
547 if (!ct || !typeName)
551 NS(QByteArray) normalizedTypeName = typeName;
553 NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
556 int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
557 normalizedTypeName.size());
559 if (idx == UnknownType) {
560 QWriteLocker locker(customTypesLock());
561 idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
562 normalizedTypeName.size());
564 if (idx == UnknownType) {
566 inf.typeName = normalizedTypeName;
575 if (idx != aliasId) {
576 qFatal("QMetaType::registerTypedef: Binary compatibility break "
577 "-- Type name '%s' previously registered as typedef of '%s' [%i], "
578 "now registering as typedef of '%s' [%i].",
579 normalizedTypeName.constData(), QMetaType::typeName(idx), idx,
580 QMetaType::typeName(aliasId), aliasId);
586 Returns true if the datatype with ID \a type is registered;
587 otherwise returns false.
589 \sa type(), typeName(), Type
591 bool QMetaType::isRegistered(int type)
594 if ((type >= FirstCoreType && type <= LastCoreType)
595 || (type >= FirstGuiType && type <= LastGuiType)
596 || (type >= FirstWidgetsType && type <= LastWidgetsType)) {
600 QReadLocker locker(customTypesLock());
601 const QVector<QCustomTypeInfo> * const ct = customTypes();
602 return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
606 Returns a handle to the type called \a typeName, or QMetaType::UnknownType if there is
609 \sa isRegistered(), typeName(), Type
611 int QMetaType::type(const char *typeName)
613 int length = qstrlen(typeName);
616 int type = qMetaTypeStaticType(typeName, length);
617 if (type == UnknownType) {
618 QReadLocker locker(customTypesLock());
619 type = qMetaTypeCustomType_unlocked(typeName, length);
620 #ifndef QT_NO_QOBJECT
621 if (type == UnknownType) {
622 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
623 type = qMetaTypeStaticType(normalizedTypeName.constData(),
624 normalizedTypeName.size());
625 if (type == UnknownType) {
626 type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
627 normalizedTypeName.size());
635 #ifndef QT_NO_DATASTREAM
637 Writes the object pointed to by \a data with the ID \a type to
638 the given \a stream. Returns true if the object is saved
639 successfully; otherwise returns false.
641 The type must have been registered with qRegisterMetaType() and
642 qRegisterMetaTypeStreamOperators() beforehand.
644 Normally, you should not need to call this function directly.
645 Instead, use QVariant's \c operator<<(), which relies on save()
646 to stream custom types.
648 \sa load(), qRegisterMetaTypeStreamOperators()
650 bool QMetaType::save(QDataStream &stream, int type, const void *data)
652 if (!data || !isRegistered(type))
656 case QMetaType::UnknownType:
657 case QMetaType::Void:
658 case QMetaType::VoidStar:
659 case QMetaType::QObjectStar:
660 case QMetaType::QWidgetStar:
661 case QMetaType::QModelIndex:
663 case QMetaType::Long:
664 stream << qlonglong(*static_cast<const long *>(data));
667 stream << *static_cast<const int *>(data);
669 case QMetaType::Short:
670 stream << *static_cast<const short *>(data);
672 case QMetaType::Char:
673 // force a char to be signed
674 stream << *static_cast<const signed char *>(data);
676 case QMetaType::ULong:
677 stream << qulonglong(*static_cast<const ulong *>(data));
679 case QMetaType::UInt:
680 stream << *static_cast<const uint *>(data);
682 case QMetaType::LongLong:
683 stream << *static_cast<const qlonglong *>(data);
685 case QMetaType::ULongLong:
686 stream << *static_cast<const qulonglong *>(data);
688 case QMetaType::UShort:
689 stream << *static_cast<const ushort *>(data);
691 case QMetaType::UChar:
692 stream << *static_cast<const uchar *>(data);
694 case QMetaType::Bool:
695 stream << qint8(*static_cast<const bool *>(data));
697 case QMetaType::Float:
698 stream << *static_cast<const float *>(data);
700 case QMetaType::Double:
701 stream << *static_cast<const double *>(data);
703 case QMetaType::QChar:
704 stream << *static_cast<const NS(QChar) *>(data);
706 #ifndef QT_BOOTSTRAPPED
707 case QMetaType::QVariantMap:
708 stream << *static_cast<const NS(QVariantMap)*>(data);
710 case QMetaType::QVariantHash:
711 stream << *static_cast<const NS(QVariantHash)*>(data);
713 case QMetaType::QVariantList:
714 stream << *static_cast<const NS(QVariantList)*>(data);
716 case QMetaType::QVariant:
717 stream << *static_cast<const NS(QVariant)*>(data);
720 case QMetaType::QByteArray:
721 stream << *static_cast<const NS(QByteArray)*>(data);
723 case QMetaType::QString:
724 stream << *static_cast<const NS(QString)*>(data);
726 case QMetaType::QStringList:
727 stream << *static_cast<const NS(QStringList)*>(data);
729 #ifndef QT_BOOTSTRAPPED
730 case QMetaType::QBitArray:
731 stream << *static_cast<const NS(QBitArray)*>(data);
734 case QMetaType::QDate:
735 stream << *static_cast<const NS(QDate)*>(data);
737 case QMetaType::QTime:
738 stream << *static_cast<const NS(QTime)*>(data);
740 case QMetaType::QDateTime:
741 stream << *static_cast<const NS(QDateTime)*>(data);
743 #ifndef QT_BOOTSTRAPPED
744 case QMetaType::QUrl:
745 stream << *static_cast<const NS(QUrl)*>(data);
748 case QMetaType::QLocale:
749 stream << *static_cast<const NS(QLocale)*>(data);
751 #ifndef QT_NO_GEOM_VARIANT
752 case QMetaType::QRect:
753 stream << *static_cast<const NS(QRect)*>(data);
755 case QMetaType::QRectF:
756 stream << *static_cast<const NS(QRectF)*>(data);
758 case QMetaType::QSize:
759 stream << *static_cast<const NS(QSize)*>(data);
761 case QMetaType::QSizeF:
762 stream << *static_cast<const NS(QSizeF)*>(data);
764 case QMetaType::QLine:
765 stream << *static_cast<const NS(QLine)*>(data);
767 case QMetaType::QLineF:
768 stream << *static_cast<const NS(QLineF)*>(data);
770 case QMetaType::QPoint:
771 stream << *static_cast<const NS(QPoint)*>(data);
773 case QMetaType::QPointF:
774 stream << *static_cast<const NS(QPointF)*>(data);
778 case QMetaType::QRegExp:
779 stream << *static_cast<const NS(QRegExp)*>(data);
782 #ifndef QT_BOOTSTRAPPED
783 case QMetaType::QEasingCurve:
784 stream << *static_cast<const NS(QEasingCurve)*>(data);
787 case QMetaType::QFont:
788 case QMetaType::QPixmap:
789 case QMetaType::QBrush:
790 case QMetaType::QColor:
791 case QMetaType::QPalette:
792 case QMetaType::QImage:
793 case QMetaType::QPolygon:
794 case QMetaType::QPolygonF:
795 case QMetaType::QRegion:
796 case QMetaType::QBitmap:
797 case QMetaType::QCursor:
798 case QMetaType::QKeySequence:
799 case QMetaType::QPen:
800 case QMetaType::QTextLength:
801 case QMetaType::QTextFormat:
802 case QMetaType::QMatrix:
803 case QMetaType::QTransform:
804 case QMetaType::QMatrix4x4:
805 case QMetaType::QVector2D:
806 case QMetaType::QVector3D:
807 case QMetaType::QVector4D:
808 case QMetaType::QQuaternion:
809 if (!qMetaTypeGuiHelper)
811 qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
813 case QMetaType::QIcon:
814 case QMetaType::QSizePolicy:
815 if (!qMetaTypeWidgetsHelper)
817 qMetaTypeWidgetsHelper[type - FirstWidgetsType].saveOp(stream, data);
819 case QMetaType::QUuid:
820 stream << *static_cast<const NS(QUuid)*>(data);
823 const QVector<QCustomTypeInfo> * const ct = customTypes();
827 SaveOperator saveOp = 0;
829 QReadLocker locker(customTypesLock());
830 saveOp = ct->at(type - User).saveOp;
835 saveOp(stream, data);
843 Reads the object of the specified \a type from the given \a
844 stream into \a data. Returns true if the object is loaded
845 successfully; otherwise returns false.
847 The type must have been registered with qRegisterMetaType() and
848 qRegisterMetaTypeStreamOperators() beforehand.
850 Normally, you should not need to call this function directly.
851 Instead, use QVariant's \c operator>>(), which relies on load()
852 to stream custom types.
854 \sa save(), qRegisterMetaTypeStreamOperators()
856 bool QMetaType::load(QDataStream &stream, int type, void *data)
858 if (!data || !isRegistered(type))
862 case QMetaType::UnknownType:
863 case QMetaType::Void:
864 case QMetaType::VoidStar:
865 case QMetaType::QObjectStar:
866 case QMetaType::QWidgetStar:
867 case QMetaType::QModelIndex:
869 case QMetaType::Long: {
872 *static_cast<long *>(data) = long(l);
875 stream >> *static_cast<int *>(data);
877 case QMetaType::Short:
878 stream >> *static_cast<short *>(data);
880 case QMetaType::Char:
881 // force a char to be signed
882 stream >> *static_cast<signed char *>(data);
884 case QMetaType::ULong: {
887 *static_cast<ulong *>(data) = ulong(ul);
889 case QMetaType::UInt:
890 stream >> *static_cast<uint *>(data);
892 case QMetaType::LongLong:
893 stream >> *static_cast<qlonglong *>(data);
895 case QMetaType::ULongLong:
896 stream >> *static_cast<qulonglong *>(data);
898 case QMetaType::UShort:
899 stream >> *static_cast<ushort *>(data);
901 case QMetaType::UChar:
902 stream >> *static_cast<uchar *>(data);
904 case QMetaType::Bool: {
907 *static_cast<bool *>(data) = b;
909 case QMetaType::Float:
910 stream >> *static_cast<float *>(data);
912 case QMetaType::Double:
913 stream >> *static_cast<double *>(data);
915 case QMetaType::QChar:
916 stream >> *static_cast< NS(QChar)*>(data);
918 #ifndef QT_BOOTSTRAPPED
919 case QMetaType::QVariantMap:
920 stream >> *static_cast< NS(QVariantMap)*>(data);
922 case QMetaType::QVariantHash:
923 stream >> *static_cast< NS(QVariantHash)*>(data);
925 case QMetaType::QVariantList:
926 stream >> *static_cast< NS(QVariantList)*>(data);
928 case QMetaType::QVariant:
929 stream >> *static_cast< NS(QVariant)*>(data);
932 case QMetaType::QByteArray:
933 stream >> *static_cast< NS(QByteArray)*>(data);
935 case QMetaType::QString:
936 stream >> *static_cast< NS(QString)*>(data);
938 case QMetaType::QStringList:
939 stream >> *static_cast< NS(QStringList)*>(data);
941 #ifndef QT_BOOTSTRAPPED
942 case QMetaType::QBitArray:
943 stream >> *static_cast< NS(QBitArray)*>(data);
946 case QMetaType::QDate:
947 stream >> *static_cast< NS(QDate)*>(data);
949 case QMetaType::QTime:
950 stream >> *static_cast< NS(QTime)*>(data);
952 case QMetaType::QDateTime:
953 stream >> *static_cast< NS(QDateTime)*>(data);
955 #ifndef QT_BOOTSTRAPPED
956 case QMetaType::QUrl:
957 stream >> *static_cast< NS(QUrl)*>(data);
960 case QMetaType::QLocale:
961 stream >> *static_cast< NS(QLocale)*>(data);
963 #ifndef QT_NO_GEOM_VARIANT
964 case QMetaType::QRect:
965 stream >> *static_cast< NS(QRect)*>(data);
967 case QMetaType::QRectF:
968 stream >> *static_cast< NS(QRectF)*>(data);
970 case QMetaType::QSize:
971 stream >> *static_cast< NS(QSize)*>(data);
973 case QMetaType::QSizeF:
974 stream >> *static_cast< NS(QSizeF)*>(data);
976 case QMetaType::QLine:
977 stream >> *static_cast< NS(QLine)*>(data);
979 case QMetaType::QLineF:
980 stream >> *static_cast< NS(QLineF)*>(data);
982 case QMetaType::QPoint:
983 stream >> *static_cast< NS(QPoint)*>(data);
985 case QMetaType::QPointF:
986 stream >> *static_cast< NS(QPointF)*>(data);
990 case QMetaType::QRegExp:
991 stream >> *static_cast< NS(QRegExp)*>(data);
994 #ifndef QT_BOOTSTRAPPED
995 case QMetaType::QEasingCurve:
996 stream >> *static_cast< NS(QEasingCurve)*>(data);
999 case QMetaType::QFont:
1000 case QMetaType::QPixmap:
1001 case QMetaType::QBrush:
1002 case QMetaType::QColor:
1003 case QMetaType::QPalette:
1004 case QMetaType::QImage:
1005 case QMetaType::QPolygon:
1006 case QMetaType::QPolygonF:
1007 case QMetaType::QRegion:
1008 case QMetaType::QBitmap:
1009 case QMetaType::QCursor:
1010 case QMetaType::QKeySequence:
1011 case QMetaType::QPen:
1012 case QMetaType::QTextLength:
1013 case QMetaType::QTextFormat:
1014 case QMetaType::QMatrix:
1015 case QMetaType::QTransform:
1016 case QMetaType::QMatrix4x4:
1017 case QMetaType::QVector2D:
1018 case QMetaType::QVector3D:
1019 case QMetaType::QVector4D:
1020 case QMetaType::QQuaternion:
1021 if (!qMetaTypeGuiHelper)
1023 qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
1025 case QMetaType::QIcon:
1026 case QMetaType::QSizePolicy:
1027 if (!qMetaTypeWidgetsHelper)
1029 qMetaTypeWidgetsHelper[type - FirstWidgetsType].loadOp(stream, data);
1031 case QMetaType::QUuid:
1032 stream >> *static_cast< NS(QUuid)*>(data);
1035 const QVector<QCustomTypeInfo> * const ct = customTypes();
1039 LoadOperator loadOp = 0;
1041 QReadLocker locker(customTypesLock());
1042 loadOp = ct->at(type - User).loadOp;
1047 loadOp(stream, data);
1052 #endif // QT_NO_DATASTREAM
1055 Returns a copy of \a copy, assuming it is of type \a type. If \a
1056 copy is zero, creates a default type.
1058 \sa destroy(), isRegistered(), Type
1060 void *QMetaType::create(int type, const void *copy)
1064 case QMetaType::VoidStar:
1065 case QMetaType::QObjectStar:
1066 case QMetaType::QWidgetStar:
1067 return new void *(*static_cast<void* const *>(copy));
1068 case QMetaType::Long:
1069 return new long(*static_cast<const long*>(copy));
1070 case QMetaType::Int:
1071 return new int(*static_cast<const int*>(copy));
1072 case QMetaType::Short:
1073 return new short(*static_cast<const short*>(copy));
1074 case QMetaType::Char:
1075 return new char(*static_cast<const char*>(copy));
1076 case QMetaType::ULong:
1077 return new ulong(*static_cast<const ulong*>(copy));
1078 case QMetaType::UInt:
1079 return new uint(*static_cast<const uint*>(copy));
1080 case QMetaType::LongLong:
1081 return new qlonglong(*static_cast<const qlonglong*>(copy));
1082 case QMetaType::ULongLong:
1083 return new qulonglong(*static_cast<const qulonglong*>(copy));
1084 case QMetaType::UShort:
1085 return new ushort(*static_cast<const ushort*>(copy));
1086 case QMetaType::UChar:
1087 return new uchar(*static_cast<const uchar*>(copy));
1088 case QMetaType::Bool:
1089 return new bool(*static_cast<const bool*>(copy));
1090 case QMetaType::Float:
1091 return new float(*static_cast<const float*>(copy));
1092 case QMetaType::Double:
1093 return new double(*static_cast<const double*>(copy));
1094 case QMetaType::QChar:
1095 return new NS(QChar)(*static_cast<const NS(QChar)*>(copy));
1096 #ifndef QT_BOOTSTRAPPED
1097 case QMetaType::QVariantMap:
1098 return new NS(QVariantMap)(*static_cast<const NS(QVariantMap)*>(copy));
1099 case QMetaType::QVariantHash:
1100 return new NS(QVariantHash)(*static_cast<const NS(QVariantHash)*>(copy));
1101 case QMetaType::QVariantList:
1102 return new NS(QVariantList)(*static_cast<const NS(QVariantList)*>(copy));
1103 case QMetaType::QVariant:
1104 return new NS(QVariant)(*static_cast<const NS(QVariant)*>(copy));
1106 case QMetaType::QByteArray:
1107 return new NS(QByteArray)(*static_cast<const NS(QByteArray)*>(copy));
1108 case QMetaType::QString:
1109 return new NS(QString)(*static_cast<const NS(QString)*>(copy));
1110 case QMetaType::QStringList:
1111 return new NS(QStringList)(*static_cast<const NS(QStringList)*>(copy));
1112 #ifndef QT_BOOTSTRAPPED
1113 case QMetaType::QBitArray:
1114 return new NS(QBitArray)(*static_cast<const NS(QBitArray)*>(copy));
1116 case QMetaType::QDate:
1117 return new NS(QDate)(*static_cast<const NS(QDate)*>(copy));
1118 case QMetaType::QTime:
1119 return new NS(QTime)(*static_cast<const NS(QTime)*>(copy));
1120 case QMetaType::QDateTime:
1121 return new NS(QDateTime)(*static_cast<const NS(QDateTime)*>(copy));
1122 #ifndef QT_BOOTSTRAPPED
1123 case QMetaType::QUrl:
1124 return new NS(QUrl)(*static_cast<const NS(QUrl)*>(copy));
1126 case QMetaType::QLocale:
1127 return new NS(QLocale)(*static_cast<const NS(QLocale)*>(copy));
1128 #ifndef QT_NO_GEOM_VARIANT
1129 case QMetaType::QRect:
1130 return new NS(QRect)(*static_cast<const NS(QRect)*>(copy));
1131 case QMetaType::QRectF:
1132 return new NS(QRectF)(*static_cast<const NS(QRectF)*>(copy));
1133 case QMetaType::QSize:
1134 return new NS(QSize)(*static_cast<const NS(QSize)*>(copy));
1135 case QMetaType::QSizeF:
1136 return new NS(QSizeF)(*static_cast<const NS(QSizeF)*>(copy));
1137 case QMetaType::QLine:
1138 return new NS(QLine)(*static_cast<const NS(QLine)*>(copy));
1139 case QMetaType::QLineF:
1140 return new NS(QLineF)(*static_cast<const NS(QLineF)*>(copy));
1141 case QMetaType::QPoint:
1142 return new NS(QPoint)(*static_cast<const NS(QPoint)*>(copy));
1143 case QMetaType::QPointF:
1144 return new NS(QPointF)(*static_cast<const NS(QPointF)*>(copy));
1146 #ifndef QT_NO_REGEXP
1147 case QMetaType::QRegExp:
1148 return new NS(QRegExp)(*static_cast<const NS(QRegExp)*>(copy));
1150 #ifndef QT_BOOTSTRAPPED
1151 case QMetaType::QEasingCurve:
1152 return new NS(QEasingCurve)(*static_cast<const NS(QEasingCurve)*>(copy));
1154 case QMetaType::QUuid:
1155 return new NS(QUuid)(*static_cast<const NS(QUuid)*>(copy));
1156 #ifndef QT_BOOTSTRAPPED
1157 case QMetaType::QModelIndex:
1158 return new NS(QModelIndex)(*static_cast<const NS(QModelIndex)*>(copy));
1160 case QMetaType::UnknownType:
1161 case QMetaType::Void:
1168 case QMetaType::VoidStar:
1169 case QMetaType::QObjectStar:
1170 case QMetaType::QWidgetStar:
1172 case QMetaType::Long:
1174 case QMetaType::Int:
1176 case QMetaType::Short:
1178 case QMetaType::Char:
1180 case QMetaType::ULong:
1182 case QMetaType::UInt:
1184 case QMetaType::LongLong:
1185 return new qlonglong;
1186 case QMetaType::ULongLong:
1187 return new qulonglong;
1188 case QMetaType::UShort:
1190 case QMetaType::UChar:
1192 case QMetaType::Bool:
1194 case QMetaType::Float:
1196 case QMetaType::Double:
1198 case QMetaType::QChar:
1199 return new NS(QChar);
1200 #ifndef QT_BOOTSTRAPPED
1201 case QMetaType::QVariantMap:
1202 return new NS(QVariantMap);
1203 case QMetaType::QVariantHash:
1204 return new NS(QVariantHash);
1205 case QMetaType::QVariantList:
1206 return new NS(QVariantList);
1207 case QMetaType::QVariant:
1208 return new NS(QVariant);
1210 case QMetaType::QByteArray:
1211 return new NS(QByteArray);
1212 case QMetaType::QString:
1213 return new NS(QString);
1214 case QMetaType::QStringList:
1215 return new NS(QStringList);
1216 #ifndef QT_BOOTSTRAPPED
1217 case QMetaType::QBitArray:
1218 return new NS(QBitArray);
1220 case QMetaType::QDate:
1221 return new NS(QDate);
1222 case QMetaType::QTime:
1223 return new NS(QTime);
1224 case QMetaType::QDateTime:
1225 return new NS(QDateTime);
1226 #ifndef QT_BOOTSTRAPPED
1227 case QMetaType::QUrl:
1228 return new NS(QUrl);
1230 case QMetaType::QLocale:
1231 return new NS(QLocale);
1232 #ifndef QT_NO_GEOM_VARIANT
1233 case QMetaType::QRect:
1234 return new NS(QRect);
1235 case QMetaType::QRectF:
1236 return new NS(QRectF);
1237 case QMetaType::QSize:
1238 return new NS(QSize);
1239 case QMetaType::QSizeF:
1240 return new NS(QSizeF);
1241 case QMetaType::QLine:
1242 return new NS(QLine);
1243 case QMetaType::QLineF:
1244 return new NS(QLineF);
1245 case QMetaType::QPoint:
1246 return new NS(QPoint);
1247 case QMetaType::QPointF:
1248 return new NS(QPointF);
1250 #ifndef QT_NO_REGEXP
1251 case QMetaType::QRegExp:
1252 return new NS(QRegExp);
1254 #ifndef QT_BOOTSTRAPPED
1255 case QMetaType::QEasingCurve:
1256 return new NS(QEasingCurve);
1258 case QMetaType::QUuid:
1259 return new NS(QUuid);
1260 #ifndef QT_BOOTSTRAPPED
1261 case QMetaType::QModelIndex:
1262 return new NS(QModelIndex);
1264 case QMetaType::UnknownType:
1265 case QMetaType::Void:
1272 Creator creator = 0;
1273 if (type >= FirstGuiType && type <= LastGuiType) {
1274 if (!qMetaTypeGuiHelper)
1276 creator = qMetaTypeGuiHelper[type - FirstGuiType].creator;
1277 } else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
1278 if (!qMetaTypeWidgetsHelper)
1280 creator = qMetaTypeWidgetsHelper[type - FirstWidgetsType].creator;
1282 const QVector<QCustomTypeInfo> * const ct = customTypes();
1283 QReadLocker locker(customTypesLock());
1284 if (type < User || !ct || ct->count() <= type - User)
1286 if (ct->at(type - User).typeName.isEmpty())
1288 creator = ct->at(type - User).creator;
1291 return creator(copy);
1295 class TypeDestroyer {
1296 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1297 struct DestroyerImpl {
1298 static void Destroy(const int /* type */, void *where) { qMetaTypeDeleteHelper<T>(where); }
1300 template<typename T>
1301 struct DestroyerImpl<T, /* IsAcceptedType = */ false> {
1302 static void Destroy(const int type, void *where)
1304 if (QTypeModuleInfo<T>::IsGui) {
1305 if (Q_LIKELY(qMetaTypeGuiHelper))
1306 qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].deleter(where);
1309 if (QTypeModuleInfo<T>::IsWidget) {
1310 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1311 qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].deleter(where);
1314 // This point can be reached only for known types that definition is not available, for example
1315 // in bootstrap mode. We have no other choice then ignore it.
1319 TypeDestroyer(const int type)
1323 template<typename T>
1324 void delegate(const T *where) { DestroyerImpl<T>::Destroy(m_type, const_cast<T*>(where)); }
1325 void delegate(const void *) {}
1326 void delegate(const QMetaTypeSwitcher::UnknownType*) {}
1327 void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestroyer(m_type, (void*)where); }
1330 static void customTypeDestroyer(const int type, void *where)
1332 QMetaType::Destructor deleter;
1333 const QVector<QCustomTypeInfo> * const ct = customTypes();
1335 QReadLocker locker(customTypesLock());
1336 if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1338 deleter = ct->at(type - QMetaType::User).deleter;
1349 Destroys the \a data, assuming it is of the \a type given.
1351 \sa create(), isRegistered(), Type
1353 void QMetaType::destroy(int type, void *data)
1355 TypeDestroyer deleter(type);
1356 QMetaTypeSwitcher::switcher<void>(deleter, type, data);
1360 class TypeConstructor {
1361 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1362 struct ConstructorImpl {
1363 static void *Construct(const int /*type*/, void *where, const void *copy) { return qMetaTypeConstructHelper<T>(where, copy); }
1365 template<typename T>
1366 struct ConstructorImpl<T, /* IsAcceptedType = */ false> {
1367 static void *Construct(const int type, void *where, const void *copy)
1369 if (QTypeModuleInfo<T>::IsGui)
1370 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy) : 0;
1372 if (QTypeModuleInfo<T>::IsWidget)
1373 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy) : 0;
1375 // This point can be reached only for known types that definition is not available, for example
1376 // in bootstrap mode. We have no other choice then ignore it.
1381 TypeConstructor(const int type, void *where)
1386 template<typename T>
1387 void *delegate(const T *copy) { return ConstructorImpl<T>::Construct(m_type, m_where, copy); }
1388 void *delegate(const void *) { return m_where; }
1389 void *delegate(const QMetaTypeSwitcher::UnknownType*) { return m_where; }
1390 void *delegate(const QMetaTypeSwitcher::NotBuiltinType *copy) { return customTypeConstructor(m_type, m_where, copy); }
1393 static void *customTypeConstructor(const int type, void *where, const void *copy)
1395 QMetaType::Constructor ctor;
1396 const QVector<QCustomTypeInfo> * const ct = customTypes();
1398 QReadLocker locker(customTypesLock());
1399 if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1401 ctor = ct->at(type - QMetaType::User).constructor;
1403 return ctor(where, copy);
1414 Constructs a value of the given \a type in the existing memory
1415 addressed by \a where, that is a copy of \a copy, and returns
1416 \a where. If \a copy is zero, the value is default constructed.
1418 This is a low-level function for explicitly managing the memory
1419 used to store the type. Consider calling create() if you don't
1420 need this level of control (that is, use "new" rather than
1423 You must ensure that \a where points to a location that can store
1424 a value of type \a type, and that \a where is suitably aligned.
1425 The type's size can be queried by calling sizeOf().
1427 The rule of thumb for alignment is that a type is aligned to its
1428 natural boundary, which is the smallest power of 2 that is bigger
1429 than the type, unless that alignment is larger than the maximum
1430 useful alignment for the platform. For practical purposes,
1431 alignment larger than 2 * sizeof(void*) is only necessary for
1432 special hardware instructions (e.g., aligned SSE loads and stores
1435 \sa destruct(), sizeOf()
1437 void *QMetaType::construct(int type, void *where, const void *copy)
1441 TypeConstructor constructor(type, where);
1442 return QMetaTypeSwitcher::switcher<void*>(constructor, type, copy);
1447 class TypeDestructor {
1448 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1449 struct DestructorImpl {
1450 static void Destruct(const int /* type */, void *where) { qMetaTypeDestructHelper<T>(where); }
1452 template<typename T>
1453 struct DestructorImpl<T, /* IsAcceptedType = */ false> {
1454 static void Destruct(const int type, void *where)
1456 if (QTypeModuleInfo<T>::IsGui) {
1457 if (Q_LIKELY(qMetaTypeGuiHelper))
1458 qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].destructor(where);
1461 if (QTypeModuleInfo<T>::IsWidget) {
1462 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1463 qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].destructor(where);
1466 // This point can be reached only for known types that definition is not available, for example
1467 // in bootstrap mode. We have no other choice then ignore it.
1471 TypeDestructor(const int type)
1475 template<typename T>
1476 void delegate(const T *where) { DestructorImpl<T>::Destruct(m_type, const_cast<T*>(where)); }
1477 void delegate(const void *) {}
1478 void delegate(const QMetaTypeSwitcher::UnknownType*) {}
1479 void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestructor(m_type, (void*)where); }
1482 static void customTypeDestructor(const int type, void *where)
1484 QMetaType::Destructor dtor;
1485 const QVector<QCustomTypeInfo> * const ct = customTypes();
1487 QReadLocker locker(customTypesLock());
1488 if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1490 dtor = ct->at(type - QMetaType::User).destructor;
1502 Destructs the value of the given \a type, located at \a where.
1504 Unlike destroy(), this function only invokes the type's
1505 destructor, it doesn't invoke the delete operator.
1509 void QMetaType::destruct(int type, void *where)
1513 TypeDestructor destructor(type);
1514 QMetaTypeSwitcher::switcher<void>(destructor, type, where);
1520 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1522 static int Size(const int) { return QTypeInfo<T>::sizeOf; }
1524 template<typename T>
1525 struct SizeOfImpl<T, /* IsAcceptedType = */ false> {
1526 static int Size(const int type)
1528 if (QTypeModuleInfo<T>::IsGui)
1529 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].size : 0;
1531 if (QTypeModuleInfo<T>::IsWidget)
1532 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].size : 0;
1534 // This point can be reached only for known types that definition is not available, for example
1535 // in bootstrap mode. We have no other choice then ignore it.
1545 template<typename T>
1546 int delegate(const T*) { return SizeOfImpl<T>::Size(m_type); }
1547 int delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
1548 int delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeSizeOf(m_type); }
1550 static int customTypeSizeOf(const int type)
1552 const QVector<QCustomTypeInfo> * const ct = customTypes();
1553 QReadLocker locker(customTypesLock());
1554 if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1556 return ct->at(type - QMetaType::User).size;
1566 Returns the size of the given \a type in bytes (i.e., sizeof(T),
1567 where T is the actual type identified by the \a type argument).
1569 This function is typically used together with construct()
1570 to perform low-level management of the memory used by a type.
1574 int QMetaType::sizeOf(int type)
1576 SizeOf sizeOf(type);
1577 return QMetaTypeSwitcher::switcher<int>(sizeOf, type, 0);
1583 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1586 static quint32 Flags(const int type)
1588 return (!QTypeInfo<T>::isStatic * QMetaType::MovableType)
1589 | (QTypeInfo<T>::isComplex * QMetaType::NeedsConstruction)
1590 | (QTypeInfo<T>::isComplex * QMetaType::NeedsDestruction)
1591 | (type == QMetaType::QObjectStar ? QMetaType::PointerToQObject : 0)
1592 | (type == QMetaType::QWidgetStar ? QMetaType::PointerToQObject : 0);
1595 template<typename T>
1596 struct FlagsImpl<T, /* IsAcceptedType = */ false>
1598 static quint32 Flags(const int type)
1600 if (QTypeModuleInfo<T>::IsGui)
1601 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].flags : 0;
1603 if (QTypeModuleInfo<T>::IsWidget)
1604 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].flags : 0;
1606 // This point can be reached only for known types that definition is not available, for example
1607 // in bootstrap mode. We have no other choice then ignore it.
1612 Flags(const int type)
1615 template<typename T>
1616 quint32 delegate(const T*) { return FlagsImpl<T>::Flags(m_type); }
1617 quint32 delegate(const void*) { return 0; }
1618 quint32 delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
1619 quint32 delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeFlags(m_type); }
1622 static quint32 customTypeFlags(const int type)
1624 const QVector<QCustomTypeInfo> * const ct = customTypes();
1625 if (Q_UNLIKELY(!ct || type < QMetaType::User))
1627 QReadLocker locker(customTypesLock());
1628 if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
1630 return ct->at(type - QMetaType::User).flags;
1638 Returns flags of the given \a type.
1642 QMetaType::TypeFlags QMetaType::typeFlags(int type)
1645 return static_cast<QMetaType::TypeFlags>(QMetaTypeSwitcher::switcher<quint32>(flags, type, 0));
1649 \fn int qRegisterMetaType(const char *typeName)
1653 Registers the type name \a typeName for the type \c{T}. Returns
1654 the internal ID used by QMetaType. Any class or struct that has a
1655 public default constructor, a public copy constructor and a public
1656 destructor can be registered.
1658 This function requires that \c{T} is a fully defined type at the point
1659 where the function is called. For pointer types, it also requires that the
1660 pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able
1661 to register pointers to forward declared types.
1663 After a type has been registered, you can create and destroy
1664 objects of that type dynamically at run-time.
1666 This example registers the class \c{MyClass}:
1668 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 4
1670 This function is useful to register typedefs so they can be used
1671 by QMetaProperty, or in QueuedConnections
1673 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 9
1675 \sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
1676 Q_DECLARE_METATYPE()
1680 \fn int qRegisterMetaTypeStreamOperators(const char *typeName)
1684 Registers the stream operators for the type \c{T} called \a
1687 Afterward, the type can be streamed using QMetaType::load() and
1688 QMetaType::save(). These functions are used when streaming a
1691 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 5
1693 The stream operators should have the following signatures:
1695 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 6
1697 \sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
1700 /*! \typedef QMetaType::Deleter
1703 /*! \typedef QMetaType::Creator
1706 /*! \typedef QMetaType::SaveOperator
1709 /*! \typedef QMetaType::LoadOperator
1712 /*! \typedef QMetaType::Destructor
1715 /*! \typedef QMetaType::Constructor
1720 \fn int qRegisterMetaType()
1725 Call this function to register the type \c T. \c T must be declared with
1726 Q_DECLARE_METATYPE(). Returns the meta type Id.
1730 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 7
1732 To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
1733 sufficient. To use the type \c T in queued signal and slot connections,
1734 \c{qRegisterMetaType<T>()} must be called before the first connection
1737 Also, to use type \c T with the QObject::property() API,
1738 \c{qRegisterMetaType<T>()} must be called before it is used, typically
1739 in the constructor of the class that uses \c T, or in the \c{main()}
1742 \sa Q_DECLARE_METATYPE()
1745 /*! \fn int qMetaTypeId()
1750 Returns the meta type id of type \c T at compile time. If the
1751 type was not declared with Q_DECLARE_METATYPE(), compilation will
1756 \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 8
1758 QMetaType::type() returns the same ID as qMetaTypeId(), but does
1759 a lookup at runtime based on the name of the type.
1760 QMetaType::type() is a bit slower, but compilation succeeds if a
1761 type is not registered.
1763 \sa Q_DECLARE_METATYPE(), QMetaType::type()
1768 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1771 TypeInfoImpl(const uint /* type */, QMetaTypeInterface &info)
1773 QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(T);
1778 template<typename T>
1779 struct TypeInfoImpl<T, /* IsAcceptedType = */ false>
1781 TypeInfoImpl(const uint type, QMetaTypeInterface &info)
1783 if (QTypeModuleInfo<T>::IsGui) {
1784 if (Q_LIKELY(qMetaTypeGuiHelper))
1785 info = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType];
1788 if (QTypeModuleInfo<T>::IsWidget) {
1789 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1790 info = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType];
1796 QMetaTypeInterface info;
1797 TypeInfo(const uint type)
1800 QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_EMPTY();
1803 template<typename T>
1804 void delegate(const T*) { TypeInfoImpl<T>(m_type, info); }
1805 void delegate(const void*) {}
1806 void delegate(const QMetaTypeSwitcher::UnknownType*) {}
1807 void delegate(const QMetaTypeSwitcher::NotBuiltinType*) { customTypeInfo(m_type); }
1809 void customTypeInfo(const uint type)
1811 const QVector<QCustomTypeInfo> * const ct = customTypes();
1812 if (Q_UNLIKELY(!ct))
1814 QReadLocker locker(customTypesLock());
1815 if (Q_LIKELY(uint(ct->count()) > type - QMetaType::User))
1816 info = ct->at(type - QMetaType::User);
1823 QMetaType QMetaType::typeInfo(const int type)
1825 TypeInfo typeInfo(type);
1826 QMetaTypeSwitcher::switcher<void>(typeInfo, type, 0);
1827 return typeInfo.info.creator || type == Void ? QMetaType(QMetaType::NoExtensionFlags
1828 , static_cast<const QMetaTypeInterface *>(0) // typeInfo::info is a temporary variable, we can't return address of it.
1829 , typeInfo.info.creator
1830 , typeInfo.info.deleter
1831 , typeInfo.info.saveOp
1832 , typeInfo.info.loadOp
1833 , typeInfo.info.constructor
1834 , typeInfo.info.destructor
1835 , typeInfo.info.size
1836 , typeInfo.info.flags
1838 : QMetaType(UnknownType);
1841 QMetaType::QMetaType(const int typeId)
1844 if (Q_UNLIKELY(typeId == UnknownType)) {
1845 // Constructs invalid QMetaType instance.
1846 m_extensionFlags = 0xffffffff;
1847 Q_ASSERT(!isValid());
1849 // TODO it can be better.
1850 *this = QMetaType::typeInfo(typeId);
1851 if (m_typeId == UnknownType)
1852 m_extensionFlags = 0xffffffff;
1853 else if (m_typeId == QMetaType::Void)
1854 m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
1858 QMetaType::QMetaType(const QMetaType &other)
1859 : m_creator(other.m_creator)
1860 , m_deleter(other.m_deleter)
1861 , m_saveOp(other.m_saveOp)
1862 , m_loadOp(other.m_loadOp)
1863 , m_constructor(other.m_constructor)
1864 , m_destructor(other.m_destructor)
1865 , m_extension(other.m_extension) // space reserved for future use
1866 , m_size(other.m_size)
1867 , m_typeFlags(other.m_typeFlags)
1868 , m_extensionFlags(other.m_extensionFlags)
1869 , m_typeId(other.m_typeId)
1872 QMetaType &QMetaType::operator =(const QMetaType &other)
1874 m_creator = other.m_creator;
1875 m_deleter = other.m_deleter;
1876 m_saveOp = other.m_saveOp;
1877 m_loadOp = other.m_loadOp;
1878 m_constructor = other.m_constructor;
1879 m_destructor = other.m_destructor;
1880 m_size = other.m_size;
1881 m_typeFlags = other.m_typeFlags;
1882 m_extensionFlags = other.m_extensionFlags;
1883 m_extension = other.m_extension; // space reserved for future use
1884 m_typeId = other.m_typeId;
1888 void QMetaType::ctor(const QMetaTypeInterface *info)
1890 // Special case for Void type, the type is valid but not constructible.
1891 // In future we may consider to remove this assert and extend this function to initialize
1892 // differently m_extensionFlags for different types. Currently it is not needed.
1893 Q_ASSERT(m_typeId == QMetaType::Void);
1895 m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
1898 void QMetaType::dtor()
1901 void *QMetaType::createExtended(const void *copy) const
1907 void QMetaType::destroyExtended(void *data) const
1912 void *QMetaType::constructExtended(void *where, const void *copy) const
1919 void QMetaType::destructExtended(void *data) const
1924 uint QMetaType::sizeExtended() const
1929 QMetaType::TypeFlags QMetaType::flagsExtended() const