Initialize member variable
[profile/ivi/qtbase.git] / src / corelib / kernel / qmetatype.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QMETATYPE_H
43 #define QMETATYPE_H
44
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>
50 #ifndef QT_NO_QOBJECT
51 #include <QtCore/qobjectdefs.h>
52 #endif
53 #include <new>
54
55 #ifdef Bool
56 #error qmetatype.h must be included before any header file that defines Bool
57 #endif
58
59 QT_BEGIN_HEADER
60
61 QT_BEGIN_NAMESPACE
62
63
64 // F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
65 #define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
66     F(Void, 43, void) \
67     F(Bool, 1, bool) \
68     F(Int, 2, int) \
69     F(UInt, 3, uint) \
70     F(LongLong, 4, qlonglong) \
71     F(ULongLong, 5, qulonglong) \
72     F(Double, 6, double) \
73     F(Long, 32, long) \
74     F(Short, 33, short) \
75     F(Char, 34, char) \
76     F(ULong, 35, ulong) \
77     F(UShort, 36, ushort) \
78     F(UChar, 37, uchar) \
79     F(Float, 38, float) \
80
81 #define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
82     F(VoidStar, 31, void*) \
83
84 #define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
85     F(QChar, 7, QChar) \
86     F(QString, 10, QString) \
87     F(QStringList, 11, QStringList) \
88     F(QByteArray, 12, QByteArray) \
89     F(QBitArray, 13, QBitArray) \
90     F(QDate, 14, QDate) \
91     F(QTime, 15, QTime) \
92     F(QDateTime, 16, QDateTime) \
93     F(QUrl, 17, QUrl) \
94     F(QLocale, 18, QLocale) \
95     F(QRect, 19, QRect) \
96     F(QRectF, 20, QRectF) \
97     F(QSize, 21, QSize) \
98     F(QSizeF, 22, QSizeF) \
99     F(QLine, 23, QLine) \
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) \
113
114 #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
115     F(QObjectStar, 39, QObject*) \
116     F(QWidgetStar, 40, QWidget*) \
117
118 #define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
119     F(QVariantMap, 8, QVariantMap) \
120     F(QVariantList, 9, QVariantList) \
121     F(QVariantHash, 28, QVariantHash) \
122
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) \
135     F(QPen, 75, QPen) \
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) \
146
147 #define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
148     F(QIcon, 120, QIcon) \
149     F(QSizePolicy, 121, QSizePolicy) \
150
151 // ### FIXME kill that set
152 #define QT_FOR_EACH_STATIC_HACKS_TYPE(F)\
153     F(QMetaTypeId2<qreal>::MetaType, -1, qreal)
154
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>") \
175
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)\
184
185 #define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
186     TypeName = Id,
187
188 class QDataStream;
189 class QMetaTypeInterface;
190 struct QMetaObject;
191
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,
198                          FlagsEx = 0x100
199                        };
200 public:
201 #ifndef Q_QDOC
202     // The code that actually gets compiled.
203     enum Type {
204         // these are merged with QVariant
205         QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
206
207         FirstCoreType = Bool,
208         LastCoreType = QJsonDocument,
209         FirstGuiType = QFont,
210         LastGuiType = QPolygonF,
211         FirstWidgetsType = QIcon,
212         LastWidgetsType = QSizePolicy,
213         HighestInternalId = LastWidgetsType,
214
215         QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
216
217         UnknownType = 0,
218         User = 1024
219     };
220 #else
221     // If we are using QDoc it fakes the Type enum looks like this.
222     enum Type {
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,
226         VoidStar = 31,
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,
240         User = 256
241     };
242 #endif
243
244     enum TypeFlag {
245         NeedsConstruction = 0x1,
246         NeedsDestruction = 0x2,
247         MovableType = 0x4,
248         PointerToQObject = 0x8,
249         IsEnumeration = 0x10
250     };
251     Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
252
253     typedef void (*Deleter)(void *);
254     typedef void *(*Creator)(const void *);
255
256     typedef void (*Destructor)(void *);
257     typedef void *(*Constructor)(void *, const void *);
258
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);
266 #endif
267     static int registerType(const char *typeName, Deleter deleter,
268                             Creator creator);
269     static int registerType(const char *typeName, Deleter deleter,
270                             Creator creator,
271                             Destructor destructor,
272                             Constructor constructor,
273                             int size,
274                             QMetaType::TypeFlags flags,
275                             const QMetaObject *metaObject);
276     static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Deleter deleter,
277                             Creator creator,
278                             Destructor destructor,
279                             Constructor constructor,
280                             int size,
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); }
294 #endif
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);
298
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);
302 #endif
303
304     explicit QMetaType(const int type);
305     inline ~QMetaType();
306
307     inline bool isValid() const;
308     inline bool isRegistered() const;
309     inline int sizeOf() const;
310     inline TypeFlags flags() const;
311
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;
316 private:
317     static QMetaType typeInfo(const int type);
318     inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
319                      Creator creator,
320                      Deleter deleter,
321                      SaveOperator saveOp,
322                      LoadOperator loadOp,
323                      Constructor constructor,
324                      Destructor destructor,
325                      uint sizeOf,
326                      uint theTypeFlags,
327                      int typeId,
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; }
332
333     // Methods used for future binary compatibile extensions
334     void ctor(const QMetaTypeInterface *info);
335     void dtor();
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;
342
343     Creator m_creator;
344     Deleter m_deleter;
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
350     uint m_size;
351     uint m_typeFlags;
352     uint m_extensionFlags;
353     int m_typeId;
354     const QMetaObject *m_metaObject; // Placeholder for Qt 5.1 feature.
355 };
356
357 #undef QT_DEFINE_METATYPE_ID
358
359 Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
360
361 template <typename T>
362 void qMetaTypeDeleteHelper(void *t)
363 {
364     delete static_cast<T*>(t);
365 }
366 template <> inline void qMetaTypeDeleteHelper<void>(void *) {}
367
368 template <typename T>
369 void *qMetaTypeCreateHelper(const void *t)
370 {
371     if (t)
372         return new T(*static_cast<const T*>(t));
373     return new T();
374 }
375
376 template <> inline void *qMetaTypeCreateHelper<void>(const void *) { return 0; }
377
378 template <typename T>
379 void qMetaTypeDestructHelper(void *t)
380 {
381     Q_UNUSED(t) // Silence MSVC that warns for POD types.
382     static_cast<T*>(t)->~T();
383 }
384
385 template <> inline void qMetaTypeDestructHelper<void>(void *) {}
386
387 template <typename T>
388 void *qMetaTypeConstructHelper(void *where, const void *t)
389 {
390     if (t)
391         return new (where) T(*static_cast<const T*>(t));
392     return new (where) T;
393 }
394
395 template <> inline void *qMetaTypeConstructHelper<void>(void *, const void *) { return 0; }
396
397 #ifndef QT_NO_DATASTREAM
398 template <typename T>
399 void qMetaTypeSaveHelper(QDataStream &stream, const void *t)
400 {
401     stream << *static_cast<const T*>(t);
402 }
403
404 template <> inline void qMetaTypeSaveHelper<void>(QDataStream &, const void *) {}
405
406 template <typename T>
407 void qMetaTypeLoadHelper(QDataStream &stream, void *t)
408 {
409     stream >> *static_cast<T*>(t);
410 }
411
412 template <> inline void qMetaTypeLoadHelper<void>(QDataStream &, void *) {}
413 #endif // QT_NO_DATASTREAM
414
415 class QObject;
416 class QWidget;
417
418 namespace QtPrivate
419 {
420     template<typename T>
421     struct IsPointerToTypeDerivedFromQObject
422     {
423         enum { Value = false };
424     };
425
426     // Specialize to avoid sizeof(void) warning
427     template<>
428     struct IsPointerToTypeDerivedFromQObject<void*>
429     {
430         enum { Value = false };
431     };
432     template<>
433     struct IsPointerToTypeDerivedFromQObject<QObject*>
434     {
435         enum { Value = true };
436     };
437     template<>
438     struct IsPointerToTypeDerivedFromQObject<QWidget*>
439     {
440         enum { Value = true };
441     };
442
443     template<typename T>
444     struct IsPointerToTypeDerivedFromQObject<T*>
445     {
446         typedef qint8 yes_type;
447         typedef qint64 no_type;
448
449 #ifndef QT_NO_QOBJECT
450         static yes_type checkType(QObject* );
451 #endif
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) };
455     };
456
457     template<typename T, bool = IsPointerToTypeDerivedFromQObject<T>::Value>
458     struct MetaObjectForType
459     {
460         static inline const QMetaObject *value() { return 0; }
461     };
462     template<typename T>
463     struct MetaObjectForType<T*, /* isPointerToTypeDerivedFromQObject = */ true>
464     {
465         static inline const QMetaObject *value() { return &T::staticMetaObject; }
466     };
467 }
468
469 template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value>
470 struct QMetaTypeIdQObject
471 {
472     enum {
473         Defined = 0
474     };
475 };
476
477 template <typename T>
478 struct QMetaTypeId : public QMetaTypeIdQObject<T>
479 {
480 };
481
482 template <typename T>
483 struct QMetaTypeId2
484 {
485     enum { Defined = QMetaTypeId<T>::Defined };
486     static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
487 };
488
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(); }
494     };
495     template <typename T> struct QMetaTypeIdHelper<T, false> {
496         static inline int qt_metatype_id()
497         { return -1; }
498     };
499
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 }; };
505
506     template<typename T>
507     struct QMetaTypeTypeFlags
508     {
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)
514              };
515     };
516 }
517
518 template <typename T>
519 int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName
520 #ifndef qdoc
521     , T * dummy = 0
522 #endif
523 )
524 {
525     const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
526     if (typedefOf != -1)
527         return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf);
528
529     QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags<T>::Flags);
530     return QMetaType::registerNormalizedType(normalizedTypeName, qMetaTypeDeleteHelper<T>,
531                                    qMetaTypeCreateHelper<T>,
532                                    qMetaTypeDestructHelper<T>,
533                                    qMetaTypeConstructHelper<T>,
534                                    sizeof(T),
535                                    flags,
536                                    QtPrivate::MetaObjectForType<T>::value());
537 }
538
539 template <typename T>
540 int qRegisterMetaType(const char *typeName
541 #ifndef qdoc
542     , T * dummy = 0
543 #endif
544 )
545 {
546 #ifdef QT_NO_QOBJECT
547     QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName;
548 #else
549     QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
550 #endif
551     return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy);
552 }
553
554 #ifndef QT_NO_DATASTREAM
555 template <typename T>
556 void qRegisterMetaTypeStreamOperators(const char *typeName
557 #ifndef qdoc
558     , T * /* dummy */ = 0
559 #endif
560 )
561 {
562     qRegisterMetaType<T>(typeName);
563     QMetaType::registerStreamOperators(typeName, qMetaTypeSaveHelper<T>, qMetaTypeLoadHelper<T>);
564 }
565 #endif // QT_NO_DATASTREAM
566
567 template <typename T>
568 inline int qMetaTypeId(
569 #ifndef qdoc
570     T * /* dummy */ = 0
571 #endif
572 )
573 {
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();
576 }
577
578 template <typename T>
579 inline int qRegisterMetaType(
580 #if !defined(qdoc) && !defined(Q_CC_SUN)
581     T * dummy = 0
582 #endif
583 )
584 {
585 #ifdef Q_CC_SUN
586     return qMetaTypeId(static_cast<T *>(0));
587 #else
588     return qMetaTypeId(dummy);
589 #endif
590 }
591
592 template <typename T>
593 struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true>
594 {
595     enum {
596         Defined = 1
597     };
598
599     static int qt_metatype_id()
600     {
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))));
609         }
610         return metatype_id.loadAcquire();
611     }
612 };
613
614 #ifndef QT_NO_DATASTREAM
615 template <typename T>
616 inline int qRegisterMetaTypeStreamOperators()
617 {
618     register int id = qMetaTypeId<T>();
619     QMetaType::registerStreamOperators(id, qMetaTypeSaveHelper<T>, qMetaTypeLoadHelper<T>);
620     return id;
621 }
622 #endif
623
624 #define Q_DECLARE_OPAQUE_POINTER(POINTER)                               \
625     QT_BEGIN_NAMESPACE namespace QtPrivate {                            \
626         template <>                                                     \
627         struct IsPointerToTypeDerivedFromQObject<POINTER >              \
628         {                                                               \
629             enum { Value = false };                                     \
630         };                                                              \
631     } QT_END_NAMESPACE                                                  \
632     /**/
633
634 #define Q_DECLARE_METATYPE(TYPE)                                        \
635     QT_BEGIN_NAMESPACE                                                  \
636     template <>                                                         \
637     struct QMetaTypeId< TYPE >                                          \
638     {                                                                   \
639         enum { Defined = 1 };                                           \
640         static int qt_metatype_id()                                     \
641             {                                                           \
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();                       \
647             }                                                           \
648     };                                                                  \
649     QT_END_NAMESPACE
650
651 #define Q_DECLARE_BUILTIN_METATYPE(TYPE, NAME) \
652     QT_BEGIN_NAMESPACE \
653     template<> struct QMetaTypeId2<TYPE> \
654     { \
655         enum { Defined = 1, MetaType = QMetaType::NAME }; \
656         static inline int qt_metatype_id() { return QMetaType::NAME; } \
657     }; \
658     QT_END_NAMESPACE
659
660 #define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
661     class Name;
662
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)
666
667 #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
668
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;
682
683 #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
684 template <typename T> \
685 struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
686 { \
687     enum { \
688         Defined = QMetaTypeId2<T>::Defined \
689     }; \
690     static int qt_metatype_id() \
691     { \
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(); \
697     } \
698 };
699
700 #define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
701 template<typename T, typename U> \
702 struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
703 { \
704     enum { \
705         Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \
706     }; \
707     static int qt_metatype_id() \
708     { \
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(); \
714     } \
715 };
716
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)
724
725 Q_DECLARE_METATYPE_TEMPLATE_2ARG(QHash)
726 Q_DECLARE_METATYPE_TEMPLATE_2ARG(QMap)
727 Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair)
728
729 inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
730                             Creator creator,
731                             Deleter deleter,
732                             SaveOperator saveOp,
733                             LoadOperator loadOp,
734                             Constructor constructor,
735                             Destructor destructor,
736                             uint size,
737                             uint theTypeFlags,
738                             int typeId,
739                             const QMetaObject *metaObject)
740     : m_creator(creator)
741     , m_deleter(deleter)
742     , m_saveOp(saveOp)
743     , m_loadOp(loadOp)
744     , m_constructor(constructor)
745     , m_destructor(destructor)
746     , m_extension(0)
747     , m_size(size)
748     , m_typeFlags(theTypeFlags)
749     , m_extensionFlags(extensionFlags)
750     , m_typeId(typeId)
751     , m_metaObject(metaObject)
752 {
753     if (Q_UNLIKELY(isExtended(CtorEx) || typeId == QMetaType::Void))
754         ctor(info);
755 }
756
757 inline QMetaType::~QMetaType()
758 {
759     if (Q_UNLIKELY(isExtended(DtorEx)))
760         dtor();
761 }
762
763 inline bool QMetaType::isValid() const
764 {
765     return m_typeId != UnknownType;
766 }
767
768 inline bool QMetaType::isRegistered() const
769 {
770     return isValid();
771 }
772
773 inline void *QMetaType::create(const void *copy) const
774 {
775     if (Q_UNLIKELY(isExtended(CreateEx)))
776         return createExtended(copy);
777     return m_creator(copy);
778 }
779
780 inline void QMetaType::destroy(void *data) const
781 {
782     if (Q_UNLIKELY(isExtended(DestroyEx)))
783         return destroyExtended(data);
784     m_deleter(data);
785 }
786
787 inline void *QMetaType::construct(void *where, const void *copy) const
788 {
789     if (Q_UNLIKELY(isExtended(ConstructEx)))
790         return constructExtended(where, copy);
791     return m_constructor(where, copy);
792 }
793
794 inline void QMetaType::destruct(void *data) const
795 {
796     if (Q_UNLIKELY(isExtended(DestructEx)))
797         return destructExtended(data);
798     if (Q_UNLIKELY(!data))
799         return;
800     m_destructor(data);
801 }
802
803 inline int QMetaType::sizeOf() const
804 {
805     if (Q_UNLIKELY(isExtended(SizeEx)))
806         return sizeExtended();
807     return m_size;
808 }
809
810 inline QMetaType::TypeFlags QMetaType::flags() const
811 {
812     if (Q_UNLIKELY(isExtended(FlagsEx)))
813         return flagsExtended();
814     return QMetaType::TypeFlags(m_typeFlags);
815 }
816
817 QT_END_NAMESPACE
818
819
820 #define QT_DECLARE_BUILTIN_METATYPE_ITER(MetaTypeName, MetaTypeId, Name) \
821     Q_DECLARE_BUILTIN_METATYPE(Name, MetaTypeName)
822
823 QT_FOR_EACH_STATIC_TYPE(QT_DECLARE_BUILTIN_METATYPE_ITER)
824 Q_DECLARE_BUILTIN_METATYPE(signed char, Char)
825
826 #undef QT_DECLARE_BUILTIN_METATYPE_ITER
827
828
829 QT_END_HEADER
830
831 #endif // QMETATYPE_H