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>
52 #error qmetatype.h must be included before any header file that defines Bool
60 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
61 #define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
66 F(LongLong, 4, qlonglong) \
67 F(ULongLong, 5, qulonglong) \
68 F(Double, 6, double) \
73 F(UShort, 36, ushort) \
77 #define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
78 F(VoidStar, 31, void*) \
80 #define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
82 F(QString, 10, QString) \
83 F(QStringList, 11, QStringList) \
84 F(QByteArray, 12, QByteArray) \
85 F(QBitArray, 13, QBitArray) \
88 F(QDateTime, 16, QDateTime) \
90 F(QLocale, 18, QLocale) \
92 F(QRectF, 20, QRectF) \
94 F(QSizeF, 22, QSizeF) \
96 F(QLineF, 24, QLineF) \
97 F(QPoint, 25, QPoint) \
98 F(QPointF, 26, QPointF) \
99 F(QRegExp, 27, QRegExp) \
100 F(QEasingCurve, 29, QEasingCurve) \
101 F(QUuid, 30, QUuid) \
102 F(QVariant, 41, QVariant) \
103 F(QModelIndex, 42, QModelIndex) \
105 #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
106 F(QObjectStar, 39, QObject*) \
107 F(QWidgetStar, 40, QWidget*) \
109 #define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
110 F(QVariantMap, 8, QVariantMap) \
111 F(QVariantList, 9, QVariantList) \
112 F(QVariantHash, 28, QVariantHash) \
114 #define QT_FOR_EACH_STATIC_GUI_CLASS(F)\
115 F(QFont, 64, QFont) \
116 F(QPixmap, 65, QPixmap) \
117 F(QBrush, 66, QBrush) \
118 F(QColor, 67, QColor) \
119 F(QPalette, 68, QPalette) \
120 F(QImage, 69, QImage) \
121 F(QPolygon, 70, QPolygon) \
122 F(QRegion, 71, QRegion) \
123 F(QBitmap, 72, QBitmap) \
124 F(QCursor, 73, QCursor) \
125 F(QKeySequence, 74, QKeySequence) \
127 F(QTextLength, 76, QTextLength) \
128 F(QTextFormat, 77, QTextFormat) \
129 F(QMatrix, 78, QMatrix) \
130 F(QTransform, 79, QTransform) \
131 F(QMatrix4x4, 80, QMatrix4x4) \
132 F(QVector2D, 81, QVector2D) \
133 F(QVector3D, 82, QVector3D) \
134 F(QVector4D, 83, QVector4D) \
135 F(QQuaternion, 84, QQuaternion) \
136 F(QPolygonF, 85, QPolygonF) \
138 #define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
139 F(QIcon, 120, QIcon) \
140 F(QSizePolicy, 121, QSizePolicy) \
142 // ### FIXME kill that set
143 #define QT_FOR_EACH_STATIC_HACKS_TYPE(F)\
144 F(QMetaTypeId2<qreal>::MetaType, -1, qreal)
146 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType")
147 #define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\
148 F(ULong, -1, ulong, "unsigned long") \
149 F(UInt, -1, uint, "unsigned int") \
150 F(UShort, -1, ushort, "unsigned short") \
151 F(UChar, -1, uchar, "unsigned char") \
152 F(LongLong, -1, qlonglong, "long long") \
153 F(ULongLong, -1, qulonglong, "unsigned long long") \
154 F(Char, -1, char, "qint8") \
155 F(Char, -1, char, "signed char") \
156 F(UChar, -1, uchar, "quint8") \
157 F(Short, -1, short, "qint16") \
158 F(UShort, -1, ushort, "quint16") \
159 F(Int, -1, int, "qint32") \
160 F(UInt, -1, uint, "quint32") \
161 F(LongLong, -1, qlonglong, "qint64") \
162 F(ULongLong, -1, qulonglong, "quint64") \
163 F(QVariantList, -1, QVariantList, "QList<QVariant>") \
164 F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \
165 F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \
167 #define QT_FOR_EACH_STATIC_TYPE(F)\
168 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
169 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
170 QT_FOR_EACH_STATIC_CORE_CLASS(F)\
171 QT_FOR_EACH_STATIC_CORE_POINTER(F)\
172 QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
173 QT_FOR_EACH_STATIC_GUI_CLASS(F)\
174 QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
176 #define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
180 class QMetaTypeInterface;
182 class Q_CORE_EXPORT QMetaType {
183 enum ExtensionFlag { NoExtensionFlags,
184 CreateEx = 0x1, DestroyEx = 0x2,
185 ConstructEx = 0x4, DestructEx = 0x8,
186 NameEx = 0x10, SizeEx = 0x20,
187 CtorEx = 0x40, DtorEx = 0x80,
192 // these are merged with QVariant
193 QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
195 FirstCoreType = Bool,
197 FirstGuiType = QFont,
198 LastGuiType = QPolygonF,
199 FirstWidgetsType = QIcon,
200 LastWidgetsType = QSizePolicy,
201 HighestInternalId = LastWidgetsType,
203 QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
210 NeedsConstruction = 0x1,
211 NeedsDestruction = 0x2,
213 PointerToQObject = 0x8
215 Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
217 typedef void (*Deleter)(void *);
218 typedef void *(*Creator)(const void *);
220 typedef void (*Destructor)(void *);
221 typedef void *(*Constructor)(void *, const void *);
223 typedef void (*SaveOperator)(QDataStream &, const void *);
224 typedef void (*LoadOperator)(QDataStream &, void *);
225 #ifndef QT_NO_DATASTREAM
226 static void registerStreamOperators(const char *typeName, SaveOperator saveOp,
227 LoadOperator loadOp);
228 static void registerStreamOperators(int type, SaveOperator saveOp,
229 LoadOperator loadOp);
231 static int registerType(const char *typeName, Deleter deleter,
233 static int registerType(const char *typeName, Deleter deleter,
235 Destructor destructor,
236 Constructor constructor,
238 QMetaType::TypeFlags flags);
239 static int registerTypedef(const char *typeName, int aliasId);
240 static int type(const char *typeName);
241 static const char *typeName(int type);
242 static int sizeOf(int type);
243 static TypeFlags typeFlags(int type);
244 static bool isRegistered(int type);
245 static void *create(int type, const void *copy = 0);
246 #if QT_DEPRECATED_SINCE(5, 0)
247 QT_DEPRECATED static void *construct(int type, const void *copy = 0)
248 { return create(type, copy); }
250 static void destroy(int type, void *data);
251 static void *construct(int type, void *where, const void *copy);
252 static void destruct(int type, void *where);
254 #ifndef QT_NO_DATASTREAM
255 static bool save(QDataStream &stream, int type, const void *data);
256 static bool load(QDataStream &stream, int type, void *data);
259 QMetaType(const int type);
262 inline bool isValid() const;
263 inline bool isRegistered() const;
264 inline int sizeOf() const;
265 inline TypeFlags flags() const;
267 inline void *create(const void *copy = 0) const;
268 inline void destroy(void *data) const;
269 inline void *construct(void *where, const void *copy = 0) const;
270 inline void destruct(void *data) const;
272 static QMetaType typeInfo(const int type);
273 inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
278 Constructor constructor,
279 Destructor destructor,
283 QMetaType(const QMetaType &other);
284 QMetaType &operator =(const QMetaType &);
285 inline bool isExtended(const ExtensionFlag flag) const { return m_extensionFlags & flag; }
287 // Methods used for future binary compatibile extensions
288 void ctor(const QMetaTypeInterface *info);
290 uint sizeExtended() const;
291 QMetaType::TypeFlags flagsExtended() const;
292 void *createExtended(const void *copy = 0) const;
293 void destroyExtended(void *data) const;
294 void *constructExtended(void *where, const void *copy = 0) const;
295 void destructExtended(void *data) const;
299 SaveOperator m_saveOp;
300 LoadOperator m_loadOp;
301 Constructor m_constructor;
302 Destructor m_destructor;
303 void *m_extension; // space reserved for future use
306 uint m_extensionFlags;
310 #undef QT_DEFINE_METATYPE_ID
312 Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
314 template <typename T>
315 void qMetaTypeDeleteHelper(void *t)
317 delete static_cast<T*>(t);
319 template <> inline void qMetaTypeDeleteHelper<void>(void *) {}
321 template <typename T>
322 void *qMetaTypeCreateHelper(const void *t)
325 return new T(*static_cast<const T*>(t));
329 template <> inline void *qMetaTypeCreateHelper<void>(const void *) { return 0; }
331 template <typename T>
332 void qMetaTypeDestructHelper(void *t)
334 Q_UNUSED(t) // Silence MSVC that warns for POD types.
335 static_cast<T*>(t)->~T();
338 template <> inline void qMetaTypeDestructHelper<void>(void *) {}
340 template <typename T>
341 void *qMetaTypeConstructHelper(void *where, const void *t)
344 return new (where) T(*static_cast<const T*>(t));
345 return new (where) T;
348 template <> inline void *qMetaTypeConstructHelper<void>(void *, const void *) { return 0; }
350 #ifndef QT_NO_DATASTREAM
351 template <typename T>
352 void qMetaTypeSaveHelper(QDataStream &stream, const void *t)
354 stream << *static_cast<const T*>(t);
357 template <> inline void qMetaTypeSaveHelper<void>(QDataStream &, const void *) {}
359 template <typename T>
360 void qMetaTypeLoadHelper(QDataStream &stream, void *t)
362 stream >> *static_cast<T*>(t);
365 template <> inline void qMetaTypeLoadHelper<void>(QDataStream &, void *) {}
366 #endif // QT_NO_DATASTREAM
368 template <typename T>
371 enum { Defined = 0 };
374 template <typename T>
377 enum { Defined = QMetaTypeId<T>::Defined };
378 static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
384 namespace QtPrivate {
385 template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
386 struct QMetaTypeIdHelper {
387 static inline int qt_metatype_id()
388 { return QMetaTypeId2<T>::qt_metatype_id(); }
390 template <typename T> struct QMetaTypeIdHelper<T, false> {
391 static inline int qt_metatype_id()
396 struct IsPointerToTypeDerivedFromQObject
398 enum { Value = false };
401 // Specialize to avoid sizeof(void) warning
403 struct IsPointerToTypeDerivedFromQObject<void*>
405 enum { Value = false };
408 struct IsPointerToTypeDerivedFromQObject<QObject*>
410 enum { Value = true };
413 struct IsPointerToTypeDerivedFromQObject<QWidget*>
415 enum { Value = true };
419 struct IsPointerToTypeDerivedFromQObject<T*>
421 typedef qint8 yes_type;
422 typedef qint64 no_type;
424 #ifndef QT_NO_QOBJECT
425 static yes_type checkType(QObject* );
427 static no_type checkType(...);
428 Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined");
429 enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) };
432 // Function pointers don't derive from QObject
433 template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
434 template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
435 template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
436 template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
439 template <typename T>
440 int qRegisterMetaType(const char *typeName
446 const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
448 return QMetaType::registerTypedef(typeName, typedefOf);
450 QMetaType::TypeFlags flags;
451 if (!QTypeInfo<T>::isStatic)
452 flags |= QMetaType::MovableType;
453 if (QTypeInfo<T>::isComplex) {
454 flags |= QMetaType::NeedsConstruction;
455 flags |= QMetaType::NeedsDestruction;
457 if (QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value)
458 flags |= QMetaType::PointerToQObject;
460 return QMetaType::registerType(typeName, qMetaTypeDeleteHelper<T>,
461 qMetaTypeCreateHelper<T>,
462 qMetaTypeDestructHelper<T>,
463 qMetaTypeConstructHelper<T>,
468 #ifndef QT_NO_DATASTREAM
469 template <typename T>
470 void qRegisterMetaTypeStreamOperators(const char *typeName
472 , T * /* dummy */ = 0
476 qRegisterMetaType<T>(typeName);
477 QMetaType::registerStreamOperators(typeName, qMetaTypeSaveHelper<T>, qMetaTypeLoadHelper<T>);
479 #endif // QT_NO_DATASTREAM
481 template <typename T>
482 inline int qMetaTypeId(
488 return QMetaTypeId2<T>::qt_metatype_id();
491 template <typename T>
492 inline int qRegisterMetaType(
493 #if !defined(qdoc) && !defined(Q_CC_SUN)
499 return qMetaTypeId(static_cast<T *>(0));
501 return qMetaTypeId(dummy);
505 #ifndef QT_NO_DATASTREAM
506 template <typename T>
507 inline int qRegisterMetaTypeStreamOperators()
509 register int id = qMetaTypeId<T>();
510 QMetaType::registerStreamOperators(id, qMetaTypeSaveHelper<T>, qMetaTypeLoadHelper<T>);
515 #define Q_DECLARE_OPAQUE_POINTER(POINTER) \
516 QT_BEGIN_NAMESPACE namespace QtPrivate { \
518 struct IsPointerToTypeDerivedFromQObject<POINTER > \
520 enum { Value = false }; \
525 #define Q_DECLARE_METATYPE(TYPE) \
528 struct QMetaTypeId< TYPE > \
530 enum { Defined = 1 }; \
531 static int qt_metatype_id() \
533 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
534 if (!metatype_id.load()) \
535 metatype_id.storeRelease(qRegisterMetaType< TYPE >(#TYPE, \
536 reinterpret_cast< TYPE *>(quintptr(-1)))); \
537 return metatype_id.loadAcquire(); \
542 #define Q_DECLARE_BUILTIN_METATYPE(TYPE, NAME) \
544 template<> struct QMetaTypeId2<TYPE> \
546 enum { Defined = 1, MetaType = QMetaType::NAME }; \
547 static inline int qt_metatype_id() { return QMetaType::NAME; } \
551 #define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
554 QT_FOR_EACH_STATIC_CORE_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
555 QT_FOR_EACH_STATIC_GUI_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
556 QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
558 #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
560 template <class T> class QList;
561 template <class T> class QLinkedList;
562 template <class T> class QVector;
563 template <class T> class QQueue;
564 template <class T> class QStack;
565 template <class T> class QSet;
566 template <class T> class QSharedPointer;
567 template <class T1, class T2> class QMap;
568 template <class T1, class T2> class QHash;
569 typedef QList<QVariant> QVariantList;
570 typedef QMap<QString, QVariant> QVariantMap;
571 typedef QHash<QString, QVariant> QVariantHash;
573 #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
574 template <typename T> \
575 struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
578 Defined = QMetaTypeId2<T>::Defined \
580 static int qt_metatype_id() \
582 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
583 if (!metatype_id.load()) \
584 metatype_id.storeRelease(qRegisterMetaType< SINGLE_ARG_TEMPLATE<T> >( QByteArray(QByteArray(#SINGLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId<T>()) + ">").constData(), \
585 reinterpret_cast< SINGLE_ARG_TEMPLATE<T> *>(quintptr(-1)))); \
586 return metatype_id.loadAcquire(); \
590 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QList)
591 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QVector)
592 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QQueue)
593 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QStack)
594 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSet)
595 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSharedPointer)
596 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QLinkedList)
598 inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
603 Constructor constructor,
604 Destructor destructor,
612 , m_constructor(constructor)
613 , m_destructor(destructor)
615 , m_typeFlags(theTypeFlags)
616 , m_extensionFlags(extensionFlags)
619 if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void))
623 inline QMetaType::~QMetaType()
625 if (Q_UNLIKELY(isExtended(DtorEx)))
629 inline bool QMetaType::isValid() const
631 return m_typeId != UnknownType;
634 inline bool QMetaType::isRegistered() const
639 inline void *QMetaType::create(const void *copy) const
641 if (Q_UNLIKELY(isExtended(CreateEx)))
642 return createExtended(copy);
643 return m_creator(copy);
646 inline void QMetaType::destroy(void *data) const
648 if (Q_UNLIKELY(isExtended(DestroyEx)))
649 return destroyExtended(data);
653 inline void *QMetaType::construct(void *where, const void *copy) const
655 if (Q_UNLIKELY(isExtended(ConstructEx)))
656 return constructExtended(where, copy);
657 return m_constructor(where, copy);
660 inline void QMetaType::destruct(void *data) const
662 if (Q_UNLIKELY(isExtended(DestructEx)))
663 return destructExtended(data);
664 if (Q_UNLIKELY(!data))
669 inline int QMetaType::sizeOf() const
671 if (Q_UNLIKELY(isExtended(SizeEx)))
672 return sizeExtended();
676 inline QMetaType::TypeFlags QMetaType::flags() const
678 if (Q_UNLIKELY(isExtended(FlagsEx)))
679 return flagsExtended();
680 return QMetaType::TypeFlags(m_typeFlags);
686 #define QT_DECLARE_BUILTIN_METATYPE_ITER(MetaTypeName, MetaTypeId, Name) \
687 Q_DECLARE_BUILTIN_METATYPE(Name, MetaTypeName)
689 QT_FOR_EACH_STATIC_TYPE(QT_DECLARE_BUILTIN_METATYPE_ITER)
690 Q_DECLARE_BUILTIN_METATYPE(signed char, Char)
692 #undef QT_DECLARE_BUILTIN_METATYPE_ITER
697 #endif // QMETATYPE_H