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 = Void,
196 LastCoreType = QModelIndex,
197 FirstGuiType = QFont,
198 LastGuiType = QPolygonF,
199 FirstWidgetsType = QIcon,
200 LastWidgetsType = QSizePolicy,
201 HighestInternalId = LastWidgetsType,
203 QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
209 NeedsConstruction = 0x1,
210 NeedsDestruction = 0x2,
212 PointerToQObject = 0x8
214 Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
216 typedef void (*Deleter)(void *);
217 typedef void *(*Creator)(const void *);
219 typedef void (*Destructor)(void *);
220 typedef void *(*Constructor)(void *, const void *);
222 typedef void (*SaveOperator)(QDataStream &, const void *);
223 typedef void (*LoadOperator)(QDataStream &, void *);
224 #ifndef QT_NO_DATASTREAM
225 static void registerStreamOperators(const char *typeName, SaveOperator saveOp,
226 LoadOperator loadOp);
227 static void registerStreamOperators(int type, SaveOperator saveOp,
228 LoadOperator loadOp);
230 static int registerType(const char *typeName, Deleter deleter,
232 static int registerType(const char *typeName, Deleter deleter,
234 Destructor destructor,
235 Constructor constructor,
237 QMetaType::TypeFlags flags);
238 static int registerTypedef(const char *typeName, int aliasId);
239 static int type(const char *typeName);
240 static const char *typeName(int type);
241 static int sizeOf(int type);
242 static TypeFlags typeFlags(int type);
243 static bool isRegistered(int type);
244 static void *create(int type, const void *copy = 0);
245 #if QT_DEPRECATED_SINCE(5, 0)
246 QT_DEPRECATED static void *construct(int type, const void *copy = 0)
247 { return create(type, copy); }
249 static void destroy(int type, void *data);
250 static void *construct(int type, void *where, const void *copy);
251 static void destruct(int type, void *where);
253 #ifndef QT_NO_DATASTREAM
254 static bool save(QDataStream &stream, int type, const void *data);
255 static bool load(QDataStream &stream, int type, void *data);
258 QMetaType(const int type);
261 inline bool isValid() const;
262 inline bool isRegistered() const;
263 inline int sizeOf() const;
264 inline TypeFlags flags() const;
266 inline void *create(const void *copy = 0) const;
267 inline void destroy(void *data) const;
268 inline void *construct(void *where, const void *copy = 0) const;
269 inline void destruct(void *data) const;
271 static QMetaType typeInfo(const int type);
272 inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
277 Constructor constructor,
278 Destructor destructor,
282 QMetaType(const QMetaType &other);
283 QMetaType &operator =(const QMetaType &);
284 inline bool isExtended(const ExtensionFlag flag) const { return m_extensionFlags & flag; }
286 // Methods used for future binary compatibile extensions
287 void ctor(const QMetaTypeInterface *info);
289 uint sizeExtended() const;
290 QMetaType::TypeFlags flagsExtended() const;
291 void *createExtended(const void *copy = 0) const;
292 void destroyExtended(void *data) const;
293 void *constructExtended(void *where, const void *copy = 0) const;
294 void destructExtended(void *data) const;
298 SaveOperator m_saveOp;
299 LoadOperator m_loadOp;
300 Constructor m_constructor;
301 Destructor m_destructor;
302 void *m_extension; // space reserved for future use
305 uint m_extensionFlags;
309 #undef QT_DEFINE_METATYPE_ID
311 Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
313 template <typename T>
314 void qMetaTypeDeleteHelper(void *t)
316 delete static_cast<T*>(t);
318 template <> inline void qMetaTypeDeleteHelper<void>(void *) {}
320 template <typename T>
321 void *qMetaTypeCreateHelper(const void *t)
324 return new T(*static_cast<const T*>(t));
328 template <> inline void *qMetaTypeCreateHelper<void>(const void *) { return 0; }
330 template <typename T>
331 void qMetaTypeDestructHelper(void *t)
333 Q_UNUSED(t) // Silence MSVC that warns for POD types.
334 static_cast<T*>(t)->~T();
337 template <> inline void qMetaTypeDestructHelper<void>(void *) {}
339 template <typename T>
340 void *qMetaTypeConstructHelper(void *where, const void *t)
343 return new (where) T(*static_cast<const T*>(t));
344 return new (where) T;
347 template <> inline void *qMetaTypeConstructHelper<void>(void *, const void *) { return 0; }
349 #ifndef QT_NO_DATASTREAM
350 template <typename T>
351 void qMetaTypeSaveHelper(QDataStream &stream, const void *t)
353 stream << *static_cast<const T*>(t);
356 template <> inline void qMetaTypeSaveHelper<void>(QDataStream &, const void *) {}
358 template <typename T>
359 void qMetaTypeLoadHelper(QDataStream &stream, void *t)
361 stream >> *static_cast<T*>(t);
364 template <> inline void qMetaTypeLoadHelper<void>(QDataStream &, void *) {}
365 #endif // QT_NO_DATASTREAM
367 template <typename T>
370 enum { Defined = 0 };
373 template <typename T>
376 enum { Defined = QMetaTypeId<T>::Defined };
377 static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
383 namespace QtPrivate {
384 template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
385 struct QMetaTypeIdHelper {
386 static inline int qt_metatype_id()
387 { return QMetaTypeId2<T>::qt_metatype_id(); }
389 template <typename T> struct QMetaTypeIdHelper<T, false> {
390 static inline int qt_metatype_id()
395 struct IsPointerToTypeDerivedFromQObject
397 enum { Value = false };
400 // Specialize to avoid sizeof(void) warning
402 struct IsPointerToTypeDerivedFromQObject<void*>
404 enum { Value = false };
407 struct IsPointerToTypeDerivedFromQObject<QObject*>
409 enum { Value = true };
412 struct IsPointerToTypeDerivedFromQObject<QWidget*>
414 enum { Value = true };
418 struct IsPointerToTypeDerivedFromQObject<T*>
420 typedef qint8 yes_type;
421 typedef qint64 no_type;
423 #ifndef QT_NO_QOBJECT
424 static yes_type checkType(QObject* );
426 static no_type checkType(...);
427 Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined");
428 enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) };
431 // Function pointers don't derive from QObject
432 template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
433 template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
434 template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
435 template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
438 template <typename T>
439 int qRegisterMetaType(const char *typeName
445 const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
447 return QMetaType::registerTypedef(typeName, typedefOf);
449 QMetaType::TypeFlags flags;
450 if (!QTypeInfo<T>::isStatic)
451 flags |= QMetaType::MovableType;
452 if (QTypeInfo<T>::isComplex) {
453 flags |= QMetaType::NeedsConstruction;
454 flags |= QMetaType::NeedsDestruction;
456 if (QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value)
457 flags |= QMetaType::PointerToQObject;
459 return QMetaType::registerType(typeName, qMetaTypeDeleteHelper<T>,
460 qMetaTypeCreateHelper<T>,
461 qMetaTypeDestructHelper<T>,
462 qMetaTypeConstructHelper<T>,
467 #ifndef QT_NO_DATASTREAM
468 template <typename T>
469 void qRegisterMetaTypeStreamOperators(const char *typeName
471 , T * /* dummy */ = 0
475 qRegisterMetaType<T>(typeName);
476 QMetaType::registerStreamOperators(typeName, qMetaTypeSaveHelper<T>, qMetaTypeLoadHelper<T>);
478 #endif // QT_NO_DATASTREAM
480 template <typename T>
481 inline int qMetaTypeId(
487 return QMetaTypeId2<T>::qt_metatype_id();
490 template <typename T>
491 inline int qRegisterMetaType(
492 #if !defined(qdoc) && !defined(Q_CC_SUN)
498 return qMetaTypeId(static_cast<T *>(0));
500 return qMetaTypeId(dummy);
504 #ifndef QT_NO_DATASTREAM
505 template <typename T>
506 inline int qRegisterMetaTypeStreamOperators()
508 register int id = qMetaTypeId<T>();
509 QMetaType::registerStreamOperators(id, qMetaTypeSaveHelper<T>, qMetaTypeLoadHelper<T>);
514 #define Q_DECLARE_OPAQUE_POINTER(POINTER) \
515 QT_BEGIN_NAMESPACE namespace QtPrivate { \
517 struct IsPointerToTypeDerivedFromQObject<POINTER > \
519 enum { Value = false }; \
524 #define Q_DECLARE_METATYPE(TYPE) \
527 struct QMetaTypeId< TYPE > \
529 enum { Defined = 1 }; \
530 static int qt_metatype_id() \
532 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
533 if (!metatype_id.load()) \
534 metatype_id.storeRelease(qRegisterMetaType< TYPE >(#TYPE, \
535 reinterpret_cast< TYPE *>(quintptr(-1)))); \
536 return metatype_id.loadAcquire(); \
541 #define Q_DECLARE_BUILTIN_METATYPE(TYPE, NAME) \
543 template<> struct QMetaTypeId2<TYPE> \
545 enum { Defined = 1, MetaType = QMetaType::NAME }; \
546 static inline int qt_metatype_id() { return QMetaType::NAME; } \
550 #define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
553 QT_FOR_EACH_STATIC_CORE_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
554 QT_FOR_EACH_STATIC_GUI_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
555 QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
557 #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
559 template <class T> class QList;
560 template <class T> class QLinkedList;
561 template <class T> class QVector;
562 template <class T> class QQueue;
563 template <class T> class QStack;
564 template <class T> class QSet;
565 template <class T> class QSharedPointer;
566 template <class T1, class T2> class QMap;
567 template <class T1, class T2> class QHash;
568 typedef QList<QVariant> QVariantList;
569 typedef QMap<QString, QVariant> QVariantMap;
570 typedef QHash<QString, QVariant> QVariantHash;
572 #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
573 template <typename T> \
574 struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
577 Defined = QMetaTypeId2<T>::Defined \
579 static int qt_metatype_id() \
581 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
582 if (!metatype_id.load()) \
583 metatype_id.storeRelease(qRegisterMetaType< SINGLE_ARG_TEMPLATE<T> >( QByteArray(QByteArray(#SINGLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId<T>()) + ">").constData(), \
584 reinterpret_cast< SINGLE_ARG_TEMPLATE<T> *>(quintptr(-1)))); \
585 return metatype_id.loadAcquire(); \
589 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QList)
590 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QVector)
591 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QQueue)
592 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QStack)
593 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSet)
594 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSharedPointer)
595 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QLinkedList)
597 inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
602 Constructor constructor,
603 Destructor destructor,
611 , m_constructor(constructor)
612 , m_destructor(destructor)
614 , m_typeFlags(theTypeFlags)
615 , m_extensionFlags(extensionFlags)
618 if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void))
622 inline QMetaType::~QMetaType()
624 if (Q_UNLIKELY(isExtended(DtorEx)))
628 inline bool QMetaType::isValid() const
630 return m_typeId >= 0;
633 inline bool QMetaType::isRegistered() const
638 inline void *QMetaType::create(const void *copy) const
640 if (Q_UNLIKELY(isExtended(CreateEx)))
641 return createExtended(copy);
642 return m_creator(copy);
645 inline void QMetaType::destroy(void *data) const
647 if (Q_UNLIKELY(isExtended(DestroyEx)))
648 return destroyExtended(data);
652 inline void *QMetaType::construct(void *where, const void *copy) const
654 if (Q_UNLIKELY(isExtended(ConstructEx)))
655 return constructExtended(where, copy);
656 return m_constructor(where, copy);
659 inline void QMetaType::destruct(void *data) const
661 if (Q_UNLIKELY(isExtended(DestructEx)))
662 return destructExtended(data);
663 if (Q_UNLIKELY(!data))
668 inline int QMetaType::sizeOf() const
670 if (Q_UNLIKELY(isExtended(SizeEx)))
671 return sizeExtended();
675 inline QMetaType::TypeFlags QMetaType::flags() const
677 if (Q_UNLIKELY(isExtended(FlagsEx)))
678 return flagsExtended();
679 return QMetaType::TypeFlags(m_typeFlags);
685 #define QT_DECLARE_BUILTIN_METATYPE_ITER(MetaTypeName, MetaTypeId, Name) \
686 Q_DECLARE_BUILTIN_METATYPE(Name, MetaTypeName)
688 QT_FOR_EACH_STATIC_TYPE(QT_DECLARE_BUILTIN_METATYPE_ITER)
689 Q_DECLARE_BUILTIN_METATYPE(signed char, Char)
691 #undef QT_DECLARE_BUILTIN_METATYPE_ITER
696 #endif // QMETATYPE_H