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 ****************************************************************************/
45 #include <QtCore/qglobal.h>
46 #include <QtCore/qatomic.h>
47 #include <QtCore/qbytearray.h>
48 #include <QtCore/qvarlengtharray.h>
49 #include <QtCore/qisenum.h>
51 #include <QtCore/qobjectdefs.h>
56 #error qmetatype.h must be included before any header file that defines Bool
64 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
65 #define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
70 F(LongLong, 4, qlonglong) \
71 F(ULongLong, 5, qulonglong) \
72 F(Double, 6, double) \
77 F(UShort, 36, ushort) \
81 #define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
82 F(VoidStar, 31, void*) \
84 #define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
86 F(QString, 10, QString) \
87 F(QStringList, 11, QStringList) \
88 F(QByteArray, 12, QByteArray) \
89 F(QBitArray, 13, QBitArray) \
92 F(QDateTime, 16, QDateTime) \
94 F(QLocale, 18, QLocale) \
96 F(QRectF, 20, QRectF) \
98 F(QSizeF, 22, QSizeF) \
100 F(QLineF, 24, QLineF) \
101 F(QPoint, 25, QPoint) \
102 F(QPointF, 26, QPointF) \
103 F(QRegExp, 27, QRegExp) \
104 F(QEasingCurve, 29, QEasingCurve) \
105 F(QUuid, 30, QUuid) \
106 F(QVariant, 41, QVariant) \
107 F(QModelIndex, 42, QModelIndex) \
108 F(QRegularExpression, 44, QRegularExpression) \
109 F(QJsonValue, 45, QJsonValue) \
110 F(QJsonObject, 46, QJsonObject) \
111 F(QJsonArray, 47, QJsonArray) \
112 F(QJsonDocument, 48, QJsonDocument) \
114 #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
115 F(QObjectStar, 39, QObject*) \
116 F(QWidgetStar, 40, QWidget*) \
118 #define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
119 F(QVariantMap, 8, QVariantMap) \
120 F(QVariantList, 9, QVariantList) \
121 F(QVariantHash, 28, QVariantHash) \
123 #define QT_FOR_EACH_STATIC_GUI_CLASS(F)\
124 F(QFont, 64, QFont) \
125 F(QPixmap, 65, QPixmap) \
126 F(QBrush, 66, QBrush) \
127 F(QColor, 67, QColor) \
128 F(QPalette, 68, QPalette) \
129 F(QImage, 69, QImage) \
130 F(QPolygon, 70, QPolygon) \
131 F(QRegion, 71, QRegion) \
132 F(QBitmap, 72, QBitmap) \
133 F(QCursor, 73, QCursor) \
134 F(QKeySequence, 74, QKeySequence) \
136 F(QTextLength, 76, QTextLength) \
137 F(QTextFormat, 77, QTextFormat) \
138 F(QMatrix, 78, QMatrix) \
139 F(QTransform, 79, QTransform) \
140 F(QMatrix4x4, 80, QMatrix4x4) \
141 F(QVector2D, 81, QVector2D) \
142 F(QVector3D, 82, QVector3D) \
143 F(QVector4D, 83, QVector4D) \
144 F(QQuaternion, 84, QQuaternion) \
145 F(QPolygonF, 85, QPolygonF) \
147 #define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
148 F(QIcon, 120, QIcon) \
149 F(QSizePolicy, 121, QSizePolicy) \
151 // ### FIXME kill that set
152 #define QT_FOR_EACH_STATIC_HACKS_TYPE(F)\
153 F(QMetaTypeId2<qreal>::MetaType, -1, qreal)
155 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType")
156 #define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\
157 F(ULong, -1, ulong, "unsigned long") \
158 F(UInt, -1, uint, "unsigned int") \
159 F(UShort, -1, ushort, "unsigned short") \
160 F(UChar, -1, uchar, "unsigned char") \
161 F(LongLong, -1, qlonglong, "long long") \
162 F(ULongLong, -1, qulonglong, "unsigned long long") \
163 F(Char, -1, char, "qint8") \
164 F(Char, -1, char, "signed char") \
165 F(UChar, -1, uchar, "quint8") \
166 F(Short, -1, short, "qint16") \
167 F(UShort, -1, ushort, "quint16") \
168 F(Int, -1, int, "qint32") \
169 F(UInt, -1, uint, "quint32") \
170 F(LongLong, -1, qlonglong, "qint64") \
171 F(ULongLong, -1, qulonglong, "quint64") \
172 F(QVariantList, -1, QVariantList, "QList<QVariant>") \
173 F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \
174 F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \
176 #define QT_FOR_EACH_STATIC_TYPE(F)\
177 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
178 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
179 QT_FOR_EACH_STATIC_CORE_CLASS(F)\
180 QT_FOR_EACH_STATIC_CORE_POINTER(F)\
181 QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
182 QT_FOR_EACH_STATIC_GUI_CLASS(F)\
183 QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
185 #define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
189 class QMetaTypeInterface;
192 class Q_CORE_EXPORT QMetaType {
193 enum ExtensionFlag { NoExtensionFlags,
194 CreateEx = 0x1, DestroyEx = 0x2,
195 ConstructEx = 0x4, DestructEx = 0x8,
196 NameEx = 0x10, SizeEx = 0x20,
197 CtorEx = 0x40, DtorEx = 0x80,
202 // The code that actually gets compiled.
204 // these are merged with QVariant
205 QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
207 FirstCoreType = Bool,
208 LastCoreType = QJsonDocument,
209 FirstGuiType = QFont,
210 LastGuiType = QPolygonF,
211 FirstWidgetsType = QIcon,
212 LastWidgetsType = QSizePolicy,
213 HighestInternalId = LastWidgetsType,
215 QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
221 // If we are using QDoc it fakes the Type enum looks like this.
223 Void = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5,
224 Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36,
225 UChar = 37, Float = 38,
227 QChar = 7, QString = 10, QStringList = 11, QByteArray = 12,
228 QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
229 QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,
230 QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27,
231 QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42,
232 QObjectStar = 39, QWidgetStar = 40,
233 QVariantMap = 8, QVariantList = 9, QVariantHash = 28,
234 QFont = 64, QPixmap = 65, QBrush = 66, QColor = 67, QPalette = 68,
235 QImage = 69, QPolygon = 70, QRegion = 71, QBitmap = 72, QCursor = 73,
236 QKeySequence = 74, QPen = 75, QTextLength = 76, QTextFormat = 77,
237 QMatrix = 78, QTransform = 79, QMatrix4x4 = 80, QVector2D = 81,
238 QVector3D = 82, QVector4D = 83, QQuaternion = 84, QPolygonF = 85,
239 QIcon = 120, QSizePolicy = 121,
245 NeedsConstruction = 0x1,
246 NeedsDestruction = 0x2,
248 PointerToQObject = 0x8,
251 Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
253 typedef void (*Deleter)(void *);
254 typedef void *(*Creator)(const void *);
256 typedef void (*Destructor)(void *);
257 typedef void *(*Constructor)(void *, const void *);
259 typedef void (*SaveOperator)(QDataStream &, const void *);
260 typedef void (*LoadOperator)(QDataStream &, void *);
261 #ifndef QT_NO_DATASTREAM
262 static void registerStreamOperators(const char *typeName, SaveOperator saveOp,
263 LoadOperator loadOp);
264 static void registerStreamOperators(int type, SaveOperator saveOp,
265 LoadOperator loadOp);
267 static int registerType(const char *typeName, Deleter deleter,
269 static int registerType(const char *typeName, Deleter deleter,
271 Destructor destructor,
272 Constructor constructor,
274 QMetaType::TypeFlags flags,
275 const QMetaObject *metaObject);
276 static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Deleter deleter,
278 Destructor destructor,
279 Constructor constructor,
281 QMetaType::TypeFlags flags,
282 const QMetaObject *metaObject);
283 static int registerTypedef(const char *typeName, int aliasId);
284 static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId);
285 static int type(const char *typeName);
286 static const char *typeName(int type);
287 static int sizeOf(int type);
288 static TypeFlags typeFlags(int type);
289 static bool isRegistered(int type);
290 static void *create(int type, const void *copy = 0);
291 #if QT_DEPRECATED_SINCE(5, 0)
292 QT_DEPRECATED static void *construct(int type, const void *copy = 0)
293 { return create(type, copy); }
295 static void destroy(int type, void *data);
296 static void *construct(int type, void *where, const void *copy);
297 static void destruct(int type, void *where);
299 #ifndef QT_NO_DATASTREAM
300 static bool save(QDataStream &stream, int type, const void *data);
301 static bool load(QDataStream &stream, int type, void *data);
304 explicit QMetaType(const int type);
307 inline bool isValid() const;
308 inline bool isRegistered() const;
309 inline int sizeOf() const;
310 inline TypeFlags flags() const;
312 inline void *create(const void *copy = 0) const;
313 inline void destroy(void *data) const;
314 inline void *construct(void *where, const void *copy = 0) const;
315 inline void destruct(void *data) const;
317 static QMetaType typeInfo(const int type);
318 inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
323 Constructor constructor,
324 Destructor destructor,
328 const QMetaObject *metaObject);
329 QMetaType(const QMetaType &other);
330 QMetaType &operator =(const QMetaType &);
331 inline bool isExtended(const ExtensionFlag flag) const { return m_extensionFlags & flag; }
333 // Methods used for future binary compatibile extensions
334 void ctor(const QMetaTypeInterface *info);
336 uint sizeExtended() const;
337 QMetaType::TypeFlags flagsExtended() const;
338 void *createExtended(const void *copy = 0) const;
339 void destroyExtended(void *data) const;
340 void *constructExtended(void *where, const void *copy = 0) const;
341 void destructExtended(void *data) const;
345 SaveOperator m_saveOp;
346 LoadOperator m_loadOp;
347 Constructor m_constructor;
348 Destructor m_destructor;
349 void *m_extension; // space reserved for future use
352 uint m_extensionFlags;
354 const QMetaObject *m_metaObject; // Placeholder for Qt 5.1 feature.
357 #undef QT_DEFINE_METATYPE_ID
359 Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
361 template <typename T>
362 void qMetaTypeDeleteHelper(void *t)
364 delete static_cast<T*>(t);
366 template <> inline void qMetaTypeDeleteHelper<void>(void *) {}
368 template <typename T>
369 void *qMetaTypeCreateHelper(const void *t)
372 return new T(*static_cast<const T*>(t));
376 template <> inline void *qMetaTypeCreateHelper<void>(const void *) { return 0; }
378 template <typename T>
379 void qMetaTypeDestructHelper(void *t)
381 Q_UNUSED(t) // Silence MSVC that warns for POD types.
382 static_cast<T*>(t)->~T();
385 template <> inline void qMetaTypeDestructHelper<void>(void *) {}
387 template <typename T>
388 void *qMetaTypeConstructHelper(void *where, const void *t)
391 return new (where) T(*static_cast<const T*>(t));
392 return new (where) T;
395 template <> inline void *qMetaTypeConstructHelper<void>(void *, const void *) { return 0; }
397 #ifndef QT_NO_DATASTREAM
398 template <typename T>
399 void qMetaTypeSaveHelper(QDataStream &stream, const void *t)
401 stream << *static_cast<const T*>(t);
404 template <> inline void qMetaTypeSaveHelper<void>(QDataStream &, const void *) {}
406 template <typename T>
407 void qMetaTypeLoadHelper(QDataStream &stream, void *t)
409 stream >> *static_cast<T*>(t);
412 template <> inline void qMetaTypeLoadHelper<void>(QDataStream &, void *) {}
413 #endif // QT_NO_DATASTREAM
421 struct IsPointerToTypeDerivedFromQObject
423 enum { Value = false };
426 // Specialize to avoid sizeof(void) warning
428 struct IsPointerToTypeDerivedFromQObject<void*>
430 enum { Value = false };
433 struct IsPointerToTypeDerivedFromQObject<QObject*>
435 enum { Value = true };
438 struct IsPointerToTypeDerivedFromQObject<QWidget*>
440 enum { Value = true };
444 struct IsPointerToTypeDerivedFromQObject<T*>
446 typedef qint8 yes_type;
447 typedef qint64 no_type;
449 #ifndef QT_NO_QOBJECT
450 static yes_type checkType(QObject* );
452 static no_type checkType(...);
453 Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined");
454 enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) };
457 template<typename T, bool = IsPointerToTypeDerivedFromQObject<T>::Value>
458 struct MetaObjectForType
460 static inline const QMetaObject *value() { return 0; }
463 struct MetaObjectForType<T*, /* isPointerToTypeDerivedFromQObject = */ true>
465 static inline const QMetaObject *value() { return &T::staticMetaObject; }
469 template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value>
470 struct QMetaTypeIdQObject
477 template <typename T>
478 struct QMetaTypeId : public QMetaTypeIdQObject<T>
482 template <typename T>
485 enum { Defined = QMetaTypeId<T>::Defined };
486 static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
489 namespace QtPrivate {
490 template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
491 struct QMetaTypeIdHelper {
492 static inline int qt_metatype_id()
493 { return QMetaTypeId2<T>::qt_metatype_id(); }
495 template <typename T> struct QMetaTypeIdHelper<T, false> {
496 static inline int qt_metatype_id()
500 // Function pointers don't derive from QObject
501 template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
502 template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
503 template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
504 template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
507 struct QMetaTypeTypeFlags
509 enum { Flags = (!QTypeInfo<T>::isStatic ? QMetaType::MovableType : 0)
510 | (QTypeInfo<T>::isComplex ? QMetaType::NeedsConstruction : 0)
511 | (QTypeInfo<T>::isComplex ? QMetaType::NeedsDestruction : 0)
512 | (IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : 0)
513 | (Q_IS_ENUM(T) ? QMetaType::IsEnumeration : 0)
518 template <typename T>
519 int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName
525 const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
527 return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf);
529 QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags<T>::Flags);
530 return QMetaType::registerNormalizedType(normalizedTypeName, qMetaTypeDeleteHelper<T>,
531 qMetaTypeCreateHelper<T>,
532 qMetaTypeDestructHelper<T>,
533 qMetaTypeConstructHelper<T>,
536 QtPrivate::MetaObjectForType<T>::value());
539 template <typename T>
540 int qRegisterMetaType(const char *typeName
547 QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName;
549 QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
551 return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy);
554 #ifndef QT_NO_DATASTREAM
555 template <typename T>
556 void qRegisterMetaTypeStreamOperators(const char *typeName
558 , T * /* dummy */ = 0
562 qRegisterMetaType<T>(typeName);
563 QMetaType::registerStreamOperators(typeName, qMetaTypeSaveHelper<T>, qMetaTypeLoadHelper<T>);
565 #endif // QT_NO_DATASTREAM
567 template <typename T>
568 inline int qMetaTypeId(
574 Q_STATIC_ASSERT_X(QMetaTypeId2<T>::Defined, "Type is not registered, please use Q_DECLARE_METATYPE macro to make it know to Qt's meta-object system");
575 return QMetaTypeId2<T>::qt_metatype_id();
578 template <typename T>
579 inline int qRegisterMetaType(
580 #if !defined(qdoc) && !defined(Q_CC_SUN)
586 return qMetaTypeId(static_cast<T *>(0));
588 return qMetaTypeId(dummy);
592 template <typename T>
593 struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true>
599 static int qt_metatype_id()
601 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
602 if (!metatype_id.load()) {
603 const int len = int(strlen(T::staticMetaObject.className()));
604 QVarLengthArray<char, 16> classNameStar;
605 classNameStar.append(T::staticMetaObject.className(), len);
606 classNameStar.append("*\0", 2);
607 metatype_id.storeRelease(qRegisterMetaType<T*>(classNameStar.constData(),
608 reinterpret_cast<T**>(quintptr(-1))));
610 return metatype_id.loadAcquire();
614 #ifndef QT_NO_DATASTREAM
615 template <typename T>
616 inline int qRegisterMetaTypeStreamOperators()
618 register int id = qMetaTypeId<T>();
619 QMetaType::registerStreamOperators(id, qMetaTypeSaveHelper<T>, qMetaTypeLoadHelper<T>);
624 #define Q_DECLARE_OPAQUE_POINTER(POINTER) \
625 QT_BEGIN_NAMESPACE namespace QtPrivate { \
627 struct IsPointerToTypeDerivedFromQObject<POINTER > \
629 enum { Value = false }; \
634 #define Q_DECLARE_METATYPE(TYPE) \
637 struct QMetaTypeId< TYPE > \
639 enum { Defined = 1 }; \
640 static int qt_metatype_id() \
642 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
643 if (!metatype_id.load()) \
644 metatype_id.storeRelease(qRegisterMetaType< TYPE >(#TYPE, \
645 reinterpret_cast< TYPE *>(quintptr(-1)))); \
646 return metatype_id.loadAcquire(); \
651 #define Q_DECLARE_BUILTIN_METATYPE(TYPE, NAME) \
653 template<> struct QMetaTypeId2<TYPE> \
655 enum { Defined = 1, MetaType = QMetaType::NAME }; \
656 static inline int qt_metatype_id() { return QMetaType::NAME; } \
660 #define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
663 QT_FOR_EACH_STATIC_CORE_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
664 QT_FOR_EACH_STATIC_GUI_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
665 QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
667 #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
669 template <class T> class QList;
670 template <class T> class QLinkedList;
671 template <class T> class QVector;
672 template <class T> class QQueue;
673 template <class T> class QStack;
674 template <class T> class QSet;
675 template <class T> class QSharedPointer;
676 template <class T1, class T2> class QMap;
677 template <class T1, class T2> class QHash;
678 template <class T1, class T2> struct QPair;
679 typedef QList<QVariant> QVariantList;
680 typedef QMap<QString, QVariant> QVariantMap;
681 typedef QHash<QString, QVariant> QVariantHash;
683 #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
684 template <typename T> \
685 struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
688 Defined = QMetaTypeId2<T>::Defined \
690 static int qt_metatype_id() \
692 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
693 if (!metatype_id.load()) \
694 metatype_id.storeRelease(qRegisterMetaType< SINGLE_ARG_TEMPLATE<T> >( QByteArray(QByteArray(#SINGLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId<T>()) + ">").constData(), \
695 reinterpret_cast< SINGLE_ARG_TEMPLATE<T> *>(quintptr(-1)))); \
696 return metatype_id.loadAcquire(); \
700 #define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
701 template<typename T, typename U> \
702 struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
705 Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \
707 static int qt_metatype_id() \
709 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
710 if (!metatype_id.load()) \
711 metatype_id.storeRelease(qRegisterMetaType< DOUBLE_ARG_TEMPLATE<T, U> >( QByteArray(QByteArray(#DOUBLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId<T>()) + ", " + QMetaType::typeName(qMetaTypeId<U>()) + ">").constData(), \
712 reinterpret_cast< DOUBLE_ARG_TEMPLATE<T, U> *>(quintptr(-1)))); \
713 return metatype_id.loadAcquire(); \
717 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QList)
718 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QVector)
719 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QQueue)
720 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QStack)
721 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSet)
722 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSharedPointer)
723 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QLinkedList)
725 Q_DECLARE_METATYPE_TEMPLATE_2ARG(QHash)
726 Q_DECLARE_METATYPE_TEMPLATE_2ARG(QMap)
727 Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair)
729 inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
734 Constructor constructor,
735 Destructor destructor,
739 const QMetaObject *metaObject)
744 , m_constructor(constructor)
745 , m_destructor(destructor)
748 , m_typeFlags(theTypeFlags)
749 , m_extensionFlags(extensionFlags)
751 , m_metaObject(metaObject)
753 if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void))
757 inline QMetaType::~QMetaType()
759 if (Q_UNLIKELY(isExtended(DtorEx)))
763 inline bool QMetaType::isValid() const
765 return m_typeId != UnknownType;
768 inline bool QMetaType::isRegistered() const
773 inline void *QMetaType::create(const void *copy) const
775 if (Q_UNLIKELY(isExtended(CreateEx)))
776 return createExtended(copy);
777 return m_creator(copy);
780 inline void QMetaType::destroy(void *data) const
782 if (Q_UNLIKELY(isExtended(DestroyEx)))
783 return destroyExtended(data);
787 inline void *QMetaType::construct(void *where, const void *copy) const
789 if (Q_UNLIKELY(isExtended(ConstructEx)))
790 return constructExtended(where, copy);
791 return m_constructor(where, copy);
794 inline void QMetaType::destruct(void *data) const
796 if (Q_UNLIKELY(isExtended(DestructEx)))
797 return destructExtended(data);
798 if (Q_UNLIKELY(!data))
803 inline int QMetaType::sizeOf() const
805 if (Q_UNLIKELY(isExtended(SizeEx)))
806 return sizeExtended();
810 inline QMetaType::TypeFlags QMetaType::flags() const
812 if (Q_UNLIKELY(isExtended(FlagsEx)))
813 return flagsExtended();
814 return QMetaType::TypeFlags(m_typeFlags);
820 #define QT_DECLARE_BUILTIN_METATYPE_ITER(MetaTypeName, MetaTypeId, Name) \
821 Q_DECLARE_BUILTIN_METATYPE(Name, MetaTypeName)
823 QT_FOR_EACH_STATIC_TYPE(QT_DECLARE_BUILTIN_METATYPE_ITER)
824 Q_DECLARE_BUILTIN_METATYPE(signed char, Char)
826 #undef QT_DECLARE_BUILTIN_METATYPE_ITER
831 #endif // QMETATYPE_H