Introduce QMetaType::UnknownType.
[profile/ivi/qtbase.git] / src / corelib / kernel / qmetatype.cpp
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 #include "qmetatype.h"
43 #include "qmetatype_p.h"
44 #include "qobjectdefs.h"
45 #include "qdatetime.h"
46 #include "qbytearray.h"
47 #include "qreadwritelock.h"
48 #include "qstring.h"
49 #include "qstringlist.h"
50 #include "qvector.h"
51 #include "qlocale.h"
52 #include "qeasingcurve.h"
53 #include "quuid.h"
54 #include "qvariant.h"
55 #include "qmetatypeswitcher_p.h"
56
57 #ifdef QT_BOOTSTRAPPED
58 # ifndef QT_NO_GEOM_VARIANT
59 #  define QT_NO_GEOM_VARIANT
60 # endif
61 #else
62 #  include "qbitarray.h"
63 #  include "qurl.h"
64 #  include "qvariant.h"
65 #  include "qabstractitemmodel.h"
66 #endif
67
68 #ifndef QT_NO_GEOM_VARIANT
69 # include "qsize.h"
70 # include "qpoint.h"
71 # include "qrect.h"
72 # include "qline.h"
73 #endif
74
75 QT_BEGIN_NAMESPACE
76
77 #define NS(x) QT_PREPEND_NAMESPACE(x)
78
79
80 namespace {
81 template<typename T>
82 struct TypeDefinition {
83     static const bool IsAvailable = true;
84 };
85
86 struct DefinedTypesFilter {
87     template<typename T>
88     struct Acceptor {
89         static const bool IsAccepted = TypeDefinition<T>::IsAvailable && QTypeModuleInfo<T>::IsCore;
90     };
91 };
92
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; };
103 #endif
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; };
113 #endif
114 #ifdef QT_NO_REGEXP
115 template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = false; };
116 #endif
117 } // namespace
118
119 /*!
120     \macro Q_DECLARE_OPAQUE_POINTER(Pointer)
121     \relates QMetaType
122
123     This macro enables pointers to forward-declared types to be registered with
124     QMetaType using either Q_DECLARE_METATYPE() or qRegisterMetaType().
125
126     \sa Q_DECLARE_METATYPE(), qRegisterMetaType()
127
128 */
129
130 /*!
131     \macro Q_DECLARE_METATYPE(Type)
132     \relates QMetaType
133
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
136     a public destructor.
137     It is needed to use the type \a Type as a custom type in QVariant.
138
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.
143
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.
148
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.
154
155     This example shows a typical use case of Q_DECLARE_METATYPE():
156
157     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 0
158
159     If \c MyStruct is in a namespace, the Q_DECLARE_METATYPE() macro
160     has to be outside the namespace:
161
162     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 1
163
164     Since \c{MyStruct} is now known to QMetaType, it can be used in QVariant:
165
166     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 2
167
168     \sa qRegisterMetaType()
169 */
170
171 /*!
172     \enum QMetaType::Type
173
174     These are the built-in types supported by QMetaType:
175
176     \value Void \c void
177     \value Bool \c bool
178     \value Int \c int
179     \value UInt \c{unsigned int}
180     \value Double \c double
181     \value QChar QChar
182     \value QString QString
183     \value QByteArray QByteArray
184
185     \value VoidStar \c{void *}
186     \value Long \c{long}
187     \value LongLong LongLong
188     \value Short \c{short}
189     \value Char \c{char}
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
198
199     \value QCursor QCursor
200     \value QDate QDate
201     \value QSize QSize
202     \value QTime QTime
203     \value QVariantList QVariantList
204     \value QPolygon QPolygon
205     \value QPolygonF QPolygonF
206     \value QColor QColor
207     \value QSizeF QSizeF
208     \value QRectF QRectF
209     \value QLine QLine
210     \value QTextLength QTextLength
211     \value QStringList QStringList
212     \value QVariantMap QVariantMap
213     \value QVariantHash QVariantHash
214     \value QIcon QIcon
215     \value QPen QPen
216     \value QLineF QLineF
217     \value QTextFormat QTextFormat
218     \value QRect QRect
219     \value QPoint QPoint
220     \value QUrl QUrl
221     \value QRegExp QRegExp
222     \value QDateTime QDateTime
223     \value QPointF QPointF
224     \value QPalette QPalette
225     \value QFont QFont
226     \value QBrush QBrush
227     \value QRegion QRegion
228     \value QBitArray QBitArray
229     \value QImage QImage
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
243
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
246
247     \omitvalue FirstGuiType
248     \omitvalue FirstWidgetsType
249     \omitvalue LastCoreType
250     \omitvalue LastGuiType
251     \omitvalue LastWidgetsType
252     \omitvalue QReal
253     \omitvalue HighestInternalId
254
255     Additional types can be registered using Q_DECLARE_METATYPE().
256
257     \sa type(), typeName()
258 */
259
260 /*!
261     \enum QMetaType::TypeFlags
262
263     The enum describes attributes of a type supported by QMetaType.
264
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.
268 */
269
270 /*!
271     \class QMetaType
272     \brief The QMetaType class manages named types in the meta-object system.
273
274     \ingroup objectmodel
275     \threadsafe
276
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.
284
285     Any class or struct that has a public default
286     constructor, a public copy constructor, and a public destructor
287     can be registered.
288
289     The following code allocates and destructs an instance of
290     \c{MyClass}:
291
292     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 3
293
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>>()
297     operators.
298
299     \sa Q_DECLARE_METATYPE(), QVariant::setValue(), QVariant::value(), QVariant::fromValue()
300 */
301
302 #define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
303     { #RealName, sizeof(#RealName) - 1, MetaTypeId },
304
305 #define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr) \
306     { RealNameStr, sizeof(RealNameStr) - 1, QMetaType::MetaTypeName },
307
308 #define QT_ADD_STATIC_METATYPE_HACKS_ITER(MetaTypeName, TypeId, Name) \
309     QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeName, Name)
310
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}
316 };
317
318 Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0;
319 Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = 0;
320
321 class QCustomTypeInfo : public QMetaTypeInterface
322 {
323 public:
324     QCustomTypeInfo()
325         : alias(-1)
326     {
327         QMetaTypeInterface empty = QT_METATYPE_INTERFACE_INIT(void);
328         *static_cast<QMetaTypeInterface*>(this) = empty;
329     }
330     QByteArray typeName;
331     int alias;
332 };
333
334 namespace
335 {
336 union CheckThatItIsPod
337 {   // This should break if QMetaTypeInterface is not a POD type
338     QMetaTypeInterface iface;
339 };
340 }
341
342 Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
343 Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
344 Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
345
346 #ifndef QT_NO_DATASTREAM
347 /*! \internal
348 */
349 void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
350                                         LoadOperator loadOp)
351 {
352     registerStreamOperators(type(typeName), saveOp, loadOp);
353 }
354
355 /*! \internal
356 */
357 void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
358                                         LoadOperator loadOp)
359 {
360     if (idx < User)
361         return; //builtin types should not be registered;
362     QVector<QCustomTypeInfo> *ct = customTypes();
363     if (!ct)
364         return;
365     QWriteLocker locker(customTypesLock());
366     QCustomTypeInfo &inf = (*ct)[idx - User];
367     inf.saveOp = saveOp;
368     inf.loadOp = loadOp;
369 }
370 #endif // QT_NO_DATASTREAM
371
372 /*!
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.
375
376     \sa type(), isRegistered(), Type
377 */
378 const char *QMetaType::typeName(int type)
379 {
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];
384
385     const char *result;
386     if (type <= QMetaType::HighestInternalId && ((result = namesCache[type])))
387         return result;
388
389 #define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \
390         case QMetaType::MetaTypeName: result = #RealName; break;
391
392     switch (QMetaType::Type(type)) {
393     QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER)
394
395     default: {
396         if (Q_UNLIKELY(type < QMetaType::User)) {
397             return 0; // It can happen when someone cast int to QVariant::Type, we should not crash...
398         } else {
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()
403                     : 0;
404         }
405     }
406     }
407 #undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
408
409     Q_ASSERT(type <= QMetaType::HighestInternalId);
410     namesCache[type] = result;
411     return result;
412 }
413
414 /*! \internal
415     Similar to QMetaType::type(), but only looks in the static set of types.
416 */
417 static inline int qMetaTypeStaticType(const char *typeName, int length)
418 {
419     int i = 0;
420     while (types[i].typeName && ((length != types[i].typeNameLength)
421                                  || strcmp(typeName, types[i].typeName))) {
422         ++i;
423     }
424     return types[i].type;
425 }
426
427 /*! \internal
428     Similar to QMetaType::type(), but only looks in the custom set of
429     types, and doesn't lock the mutex.
430 */
431 static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
432 {
433     const QVector<QCustomTypeInfo> * const ct = customTypes();
434     if (!ct)
435         return QMetaType::UnknownType;
436
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;
444         }
445     }
446     return QMetaType::UnknownType;
447 }
448
449 /*! \internal
450
451     This function is needed until existing code outside of qtbase
452     has been changed to call the new version of registerType().
453  */
454 int QMetaType::registerType(const char *typeName, Deleter deleter,
455                             Creator creator)
456 {
457     return registerType(typeName, deleter, creator, 0, 0, 0, TypeFlags());
458 }
459
460 /*! \internal
461     \since 5.0
462
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
466     not be registered.
467  */
468 int QMetaType::registerType(const char *typeName, Deleter deleter,
469                             Creator creator,
470                             Destructor destructor,
471                             Constructor constructor,
472                             int size, TypeFlags flags)
473 {
474     QVector<QCustomTypeInfo> *ct = customTypes();
475     if (!ct || !typeName || !deleter || !creator)
476         return -1;
477
478 #ifdef QT_NO_QOBJECT
479     NS(QByteArray) normalizedTypeName = typeName;
480 #else
481     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
482 #endif
483
484     int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
485                                   normalizedTypeName.size());
486
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) {
494             QCustomTypeInfo inf;
495             inf.typeName = normalizedTypeName;
496             inf.creator = creator;
497             inf.deleter = deleter;
498 #ifndef QT_NO_DATASTREAM
499             inf.loadOp = 0;
500             inf.saveOp = 0;
501 #endif
502             inf.alias = -1;
503             inf.constructor = constructor;
504             inf.destructor = destructor;
505             inf.size = size;
506             inf.flags = flags;
507             idx = ct->size() + User;
508             ct->append(inf);
509             return idx;
510         }
511
512         if (idx >= User) {
513             previousSize = ct->at(idx - User).size;
514             previousFlags = ct->at(idx - User).flags;
515         }
516     }
517
518     if (idx < User) {
519         previousSize = QMetaType::sizeOf(idx);
520         previousFlags = QMetaType::typeFlags(idx);
521     }
522
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);
528     }
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));
534     }
535
536     return idx;
537 }
538
539 /*! \internal
540     \since 4.7
541
542     Registers a user type for marshalling, as an alias of another type (typedef)
543 */
544 int QMetaType::registerTypedef(const char* typeName, int aliasId)
545 {
546     QVector<QCustomTypeInfo> *ct = customTypes();
547     if (!ct || !typeName)
548         return -1;
549
550 #ifdef QT_NO_QOBJECT
551     NS(QByteArray) normalizedTypeName = typeName;
552 #else
553     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
554 #endif
555
556     int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
557                                   normalizedTypeName.size());
558
559     if (idx == UnknownType) {
560         QWriteLocker locker(customTypesLock());
561         idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
562                                                normalizedTypeName.size());
563
564         if (idx == UnknownType) {
565             QCustomTypeInfo inf;
566             inf.typeName = normalizedTypeName;
567             inf.alias = aliasId;
568             inf.creator = 0;
569             inf.deleter = 0;
570             ct->append(inf);
571             return aliasId;
572         }
573     }
574
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);
581     }
582     return idx;
583 }
584
585 /*!
586     Returns true if the datatype with ID \a type is registered;
587     otherwise returns false.
588
589     \sa type(), typeName(), Type
590 */
591 bool QMetaType::isRegistered(int type)
592 {
593     // predefined type
594     if ((type >= FirstCoreType && type <= LastCoreType)
595         || (type >= FirstGuiType && type <= LastGuiType)
596         || (type >= FirstWidgetsType && type <= LastWidgetsType)) {
597         return true;
598     }
599
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());
603 }
604
605 /*!
606     Returns a handle to the type called \a typeName, or QMetaType::UnknownType if there is
607     no such type.
608
609     \sa isRegistered(), typeName(), Type
610 */
611 int QMetaType::type(const char *typeName)
612 {
613     int length = qstrlen(typeName);
614     if (!length)
615         return UnknownType;
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());
628             }
629         }
630 #endif
631     }
632     return type;
633 }
634
635 #ifndef QT_NO_DATASTREAM
636 /*!
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.
640
641     The type must have been registered with qRegisterMetaType() and
642     qRegisterMetaTypeStreamOperators() beforehand.
643
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.
647
648     \sa load(), qRegisterMetaTypeStreamOperators()
649 */
650 bool QMetaType::save(QDataStream &stream, int type, const void *data)
651 {
652     if (!data || !isRegistered(type))
653         return false;
654
655     switch(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:
662         return false;
663     case QMetaType::Long:
664         stream << qlonglong(*static_cast<const long *>(data));
665         break;
666     case QMetaType::Int:
667         stream << *static_cast<const int *>(data);
668         break;
669     case QMetaType::Short:
670         stream << *static_cast<const short *>(data);
671         break;
672     case QMetaType::Char:
673         // force a char to be signed
674         stream << *static_cast<const signed char *>(data);
675         break;
676     case QMetaType::ULong:
677         stream << qulonglong(*static_cast<const ulong *>(data));
678         break;
679     case QMetaType::UInt:
680         stream << *static_cast<const uint *>(data);
681         break;
682     case QMetaType::LongLong:
683         stream << *static_cast<const qlonglong *>(data);
684         break;
685     case QMetaType::ULongLong:
686         stream << *static_cast<const qulonglong *>(data);
687         break;
688     case QMetaType::UShort:
689         stream << *static_cast<const ushort *>(data);
690         break;
691     case QMetaType::UChar:
692         stream << *static_cast<const uchar *>(data);
693         break;
694     case QMetaType::Bool:
695         stream << qint8(*static_cast<const bool *>(data));
696         break;
697     case QMetaType::Float:
698         stream << *static_cast<const float *>(data);
699         break;
700     case QMetaType::Double:
701         stream << *static_cast<const double *>(data);
702         break;
703     case QMetaType::QChar:
704         stream << *static_cast<const NS(QChar) *>(data);
705         break;
706 #ifndef QT_BOOTSTRAPPED
707     case QMetaType::QVariantMap:
708         stream << *static_cast<const NS(QVariantMap)*>(data);
709         break;
710     case QMetaType::QVariantHash:
711         stream << *static_cast<const NS(QVariantHash)*>(data);
712         break;
713     case QMetaType::QVariantList:
714         stream << *static_cast<const NS(QVariantList)*>(data);
715         break;
716     case QMetaType::QVariant:
717         stream << *static_cast<const NS(QVariant)*>(data);
718         break;
719 #endif
720     case QMetaType::QByteArray:
721         stream << *static_cast<const NS(QByteArray)*>(data);
722         break;
723     case QMetaType::QString:
724         stream << *static_cast<const NS(QString)*>(data);
725         break;
726     case QMetaType::QStringList:
727         stream << *static_cast<const NS(QStringList)*>(data);
728         break;
729 #ifndef QT_BOOTSTRAPPED
730     case QMetaType::QBitArray:
731         stream << *static_cast<const NS(QBitArray)*>(data);
732         break;
733 #endif
734     case QMetaType::QDate:
735         stream << *static_cast<const NS(QDate)*>(data);
736         break;
737     case QMetaType::QTime:
738         stream << *static_cast<const NS(QTime)*>(data);
739         break;
740     case QMetaType::QDateTime:
741         stream << *static_cast<const NS(QDateTime)*>(data);
742         break;
743 #ifndef QT_BOOTSTRAPPED
744     case QMetaType::QUrl:
745         stream << *static_cast<const NS(QUrl)*>(data);
746         break;
747 #endif
748     case QMetaType::QLocale:
749         stream << *static_cast<const NS(QLocale)*>(data);
750         break;
751 #ifndef QT_NO_GEOM_VARIANT
752     case QMetaType::QRect:
753         stream << *static_cast<const NS(QRect)*>(data);
754         break;
755     case QMetaType::QRectF:
756         stream << *static_cast<const NS(QRectF)*>(data);
757         break;
758     case QMetaType::QSize:
759         stream << *static_cast<const NS(QSize)*>(data);
760         break;
761     case QMetaType::QSizeF:
762         stream << *static_cast<const NS(QSizeF)*>(data);
763         break;
764     case QMetaType::QLine:
765         stream << *static_cast<const NS(QLine)*>(data);
766         break;
767     case QMetaType::QLineF:
768         stream << *static_cast<const NS(QLineF)*>(data);
769         break;
770     case QMetaType::QPoint:
771         stream << *static_cast<const NS(QPoint)*>(data);
772         break;
773     case QMetaType::QPointF:
774         stream << *static_cast<const NS(QPointF)*>(data);
775         break;
776 #endif
777 #ifndef QT_NO_REGEXP
778     case QMetaType::QRegExp:
779         stream << *static_cast<const NS(QRegExp)*>(data);
780         break;
781 #endif
782 #ifndef QT_BOOTSTRAPPED
783     case QMetaType::QEasingCurve:
784         stream << *static_cast<const NS(QEasingCurve)*>(data);
785         break;
786 #endif
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)
810             return false;
811         qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
812         break;
813     case QMetaType::QIcon:
814     case QMetaType::QSizePolicy:
815         if (!qMetaTypeWidgetsHelper)
816             return false;
817         qMetaTypeWidgetsHelper[type - FirstWidgetsType].saveOp(stream, data);
818         break;
819     case QMetaType::QUuid:
820         stream << *static_cast<const NS(QUuid)*>(data);
821         break;
822     default: {
823         const QVector<QCustomTypeInfo> * const ct = customTypes();
824         if (!ct)
825             return false;
826
827         SaveOperator saveOp = 0;
828         {
829             QReadLocker locker(customTypesLock());
830             saveOp = ct->at(type - User).saveOp;
831         }
832
833         if (!saveOp)
834             return false;
835         saveOp(stream, data);
836         break; }
837     }
838
839     return true;
840 }
841
842 /*!
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.
846
847     The type must have been registered with qRegisterMetaType() and
848     qRegisterMetaTypeStreamOperators() beforehand.
849
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.
853
854     \sa save(), qRegisterMetaTypeStreamOperators()
855 */
856 bool QMetaType::load(QDataStream &stream, int type, void *data)
857 {
858     if (!data || !isRegistered(type))
859         return false;
860
861     switch(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:
868         return false;
869     case QMetaType::Long: {
870         qlonglong l;
871         stream >> l;
872         *static_cast<long *>(data) = long(l);
873         break; }
874     case QMetaType::Int:
875         stream >> *static_cast<int *>(data);
876         break;
877     case QMetaType::Short:
878         stream >> *static_cast<short *>(data);
879         break;
880     case QMetaType::Char:
881         // force a char to be signed
882         stream >> *static_cast<signed char *>(data);
883         break;
884     case QMetaType::ULong: {
885         qulonglong ul;
886         stream >> ul;
887         *static_cast<ulong *>(data) = ulong(ul);
888         break; }
889     case QMetaType::UInt:
890         stream >> *static_cast<uint *>(data);
891         break;
892     case QMetaType::LongLong:
893         stream >> *static_cast<qlonglong *>(data);
894         break;
895     case QMetaType::ULongLong:
896         stream >> *static_cast<qulonglong *>(data);
897         break;
898     case QMetaType::UShort:
899         stream >> *static_cast<ushort *>(data);
900         break;
901     case QMetaType::UChar:
902         stream >> *static_cast<uchar *>(data);
903         break;
904     case QMetaType::Bool: {
905         qint8 b;
906         stream >> b;
907         *static_cast<bool *>(data) = b;
908         break; }
909     case QMetaType::Float:
910         stream >> *static_cast<float *>(data);
911         break;
912     case QMetaType::Double:
913         stream >> *static_cast<double *>(data);
914         break;
915     case QMetaType::QChar:
916         stream >> *static_cast< NS(QChar)*>(data);
917         break;
918 #ifndef QT_BOOTSTRAPPED
919     case QMetaType::QVariantMap:
920         stream >> *static_cast< NS(QVariantMap)*>(data);
921         break;
922     case QMetaType::QVariantHash:
923         stream >> *static_cast< NS(QVariantHash)*>(data);
924         break;
925     case QMetaType::QVariantList:
926         stream >> *static_cast< NS(QVariantList)*>(data);
927         break;
928     case QMetaType::QVariant:
929         stream >> *static_cast< NS(QVariant)*>(data);
930         break;
931 #endif
932     case QMetaType::QByteArray:
933         stream >> *static_cast< NS(QByteArray)*>(data);
934         break;
935     case QMetaType::QString:
936         stream >> *static_cast< NS(QString)*>(data);
937         break;
938     case QMetaType::QStringList:
939         stream >> *static_cast< NS(QStringList)*>(data);
940         break;
941 #ifndef QT_BOOTSTRAPPED
942     case QMetaType::QBitArray:
943         stream >> *static_cast< NS(QBitArray)*>(data);
944         break;
945 #endif
946     case QMetaType::QDate:
947         stream >> *static_cast< NS(QDate)*>(data);
948         break;
949     case QMetaType::QTime:
950         stream >> *static_cast< NS(QTime)*>(data);
951         break;
952     case QMetaType::QDateTime:
953         stream >> *static_cast< NS(QDateTime)*>(data);
954         break;
955 #ifndef QT_BOOTSTRAPPED
956     case QMetaType::QUrl:
957         stream >> *static_cast< NS(QUrl)*>(data);
958         break;
959 #endif
960     case QMetaType::QLocale:
961         stream >> *static_cast< NS(QLocale)*>(data);
962         break;
963 #ifndef QT_NO_GEOM_VARIANT
964     case QMetaType::QRect:
965         stream >> *static_cast< NS(QRect)*>(data);
966         break;
967     case QMetaType::QRectF:
968         stream >> *static_cast< NS(QRectF)*>(data);
969         break;
970     case QMetaType::QSize:
971         stream >> *static_cast< NS(QSize)*>(data);
972         break;
973     case QMetaType::QSizeF:
974         stream >> *static_cast< NS(QSizeF)*>(data);
975         break;
976     case QMetaType::QLine:
977         stream >> *static_cast< NS(QLine)*>(data);
978         break;
979     case QMetaType::QLineF:
980         stream >> *static_cast< NS(QLineF)*>(data);
981         break;
982     case QMetaType::QPoint:
983         stream >> *static_cast< NS(QPoint)*>(data);
984         break;
985     case QMetaType::QPointF:
986         stream >> *static_cast< NS(QPointF)*>(data);
987         break;
988 #endif
989 #ifndef QT_NO_REGEXP
990     case QMetaType::QRegExp:
991         stream >> *static_cast< NS(QRegExp)*>(data);
992         break;
993 #endif
994 #ifndef QT_BOOTSTRAPPED
995     case QMetaType::QEasingCurve:
996         stream >> *static_cast< NS(QEasingCurve)*>(data);
997         break;
998 #endif
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)
1022             return false;
1023         qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
1024         break;
1025     case QMetaType::QIcon:
1026     case QMetaType::QSizePolicy:
1027         if (!qMetaTypeWidgetsHelper)
1028             return false;
1029         qMetaTypeWidgetsHelper[type - FirstWidgetsType].loadOp(stream, data);
1030         break;
1031     case QMetaType::QUuid:
1032         stream >> *static_cast< NS(QUuid)*>(data);
1033         break;
1034     default: {
1035         const QVector<QCustomTypeInfo> * const ct = customTypes();
1036         if (!ct)
1037             return false;
1038
1039         LoadOperator loadOp = 0;
1040         {
1041             QReadLocker locker(customTypesLock());
1042             loadOp = ct->at(type - User).loadOp;
1043         }
1044
1045         if (!loadOp)
1046             return false;
1047         loadOp(stream, data);
1048         break; }
1049     }
1050     return true;
1051 }
1052 #endif // QT_NO_DATASTREAM
1053
1054 /*!
1055     Returns a copy of \a copy, assuming it is of type \a type. If \a
1056     copy is zero, creates a default type.
1057
1058     \sa destroy(), isRegistered(), Type
1059 */
1060 void *QMetaType::create(int type, const void *copy)
1061 {
1062     if (copy) {
1063         switch(type) {
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));
1105 #endif
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));
1115 #endif
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));
1125 #endif
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));
1145 #endif
1146 #ifndef QT_NO_REGEXP
1147         case QMetaType::QRegExp:
1148             return new NS(QRegExp)(*static_cast<const NS(QRegExp)*>(copy));
1149 #endif
1150 #ifndef QT_BOOTSTRAPPED
1151         case QMetaType::QEasingCurve:
1152             return new NS(QEasingCurve)(*static_cast<const NS(QEasingCurve)*>(copy));
1153 #endif
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));
1159 #endif
1160         case QMetaType::UnknownType:
1161         case QMetaType::Void:
1162             return 0;
1163         default:
1164             ;
1165         }
1166     } else {
1167         switch(type) {
1168         case QMetaType::VoidStar:
1169         case QMetaType::QObjectStar:
1170         case QMetaType::QWidgetStar:
1171             return new void *;
1172         case QMetaType::Long:
1173             return new long;
1174         case QMetaType::Int:
1175             return new int;
1176         case QMetaType::Short:
1177             return new short;
1178         case QMetaType::Char:
1179             return new char;
1180         case QMetaType::ULong:
1181             return new ulong;
1182         case QMetaType::UInt:
1183             return new uint;
1184         case QMetaType::LongLong:
1185             return new qlonglong;
1186         case QMetaType::ULongLong:
1187             return new qulonglong;
1188         case QMetaType::UShort:
1189             return new ushort;
1190         case QMetaType::UChar:
1191             return new uchar;
1192         case QMetaType::Bool:
1193             return new bool;
1194         case QMetaType::Float:
1195             return new float;
1196         case QMetaType::Double:
1197             return new 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);
1209 #endif
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);
1219 #endif
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);
1229 #endif
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);
1249 #endif
1250 #ifndef QT_NO_REGEXP
1251         case QMetaType::QRegExp:
1252             return new NS(QRegExp);
1253 #endif
1254 #ifndef QT_BOOTSTRAPPED
1255         case QMetaType::QEasingCurve:
1256             return new NS(QEasingCurve);
1257 #endif
1258         case QMetaType::QUuid:
1259             return new NS(QUuid);
1260 #ifndef QT_BOOTSTRAPPED
1261         case QMetaType::QModelIndex:
1262             return new NS(QModelIndex);
1263 #endif
1264         case QMetaType::UnknownType:
1265         case QMetaType::Void:
1266             return 0;
1267         default:
1268             ;
1269         }
1270     }
1271
1272     Creator creator = 0;
1273     if (type >= FirstGuiType && type <= LastGuiType) {
1274         if (!qMetaTypeGuiHelper)
1275             return 0;
1276         creator = qMetaTypeGuiHelper[type - FirstGuiType].creator;
1277     } else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
1278         if (!qMetaTypeWidgetsHelper)
1279             return 0;
1280         creator = qMetaTypeWidgetsHelper[type - FirstWidgetsType].creator;
1281     } else {
1282         const QVector<QCustomTypeInfo> * const ct = customTypes();
1283         QReadLocker locker(customTypesLock());
1284         if (type < User || !ct || ct->count() <= type - User)
1285             return 0;
1286         if (ct->at(type - User).typeName.isEmpty())
1287             return 0;
1288         creator = ct->at(type - User).creator;
1289     }
1290
1291     return creator(copy);
1292 }
1293
1294 namespace {
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); }
1299     };
1300     template<typename T>
1301     struct DestroyerImpl<T, /* IsAcceptedType = */ false> {
1302         static void Destroy(const int type, void *where)
1303         {
1304             if (QTypeModuleInfo<T>::IsGui) {
1305                 if (Q_LIKELY(qMetaTypeGuiHelper))
1306                     qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].deleter(where);
1307                 return;
1308             }
1309             if (QTypeModuleInfo<T>::IsWidget) {
1310                 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1311                     qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].deleter(where);
1312                 return;
1313             }
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.
1316         }
1317     };
1318 public:
1319     TypeDestroyer(const int type)
1320         : m_type(type)
1321     {}
1322
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); }
1328
1329 private:
1330     static void customTypeDestroyer(const int type, void *where)
1331     {
1332         QMetaType::Destructor deleter;
1333         const QVector<QCustomTypeInfo> * const ct = customTypes();
1334         {
1335             QReadLocker locker(customTypesLock());
1336             if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1337                 return;
1338             deleter = ct->at(type - QMetaType::User).deleter;
1339         }
1340         deleter(where);
1341     }
1342
1343     const int m_type;
1344 };
1345 } // namespace
1346
1347
1348 /*!
1349     Destroys the \a data, assuming it is of the \a type given.
1350
1351     \sa create(), isRegistered(), Type
1352 */
1353 void QMetaType::destroy(int type, void *data)
1354 {
1355     TypeDestroyer deleter(type);
1356     QMetaTypeSwitcher::switcher<void>(deleter, type, data);
1357 }
1358
1359 namespace {
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); }
1364     };
1365     template<typename T>
1366     struct ConstructorImpl<T, /* IsAcceptedType = */ false> {
1367         static void *Construct(const int type, void *where, const void *copy)
1368         {
1369             if (QTypeModuleInfo<T>::IsGui)
1370                 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy) : 0;
1371
1372             if (QTypeModuleInfo<T>::IsWidget)
1373                 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy) : 0;
1374
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.
1377             return 0;
1378         }
1379     };
1380 public:
1381     TypeConstructor(const int type, void *where)
1382         : m_type(type)
1383         , m_where(where)
1384     {}
1385
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); }
1391
1392 private:
1393     static void *customTypeConstructor(const int type, void *where, const void *copy)
1394     {
1395         QMetaType::Constructor ctor;
1396         const QVector<QCustomTypeInfo> * const ct = customTypes();
1397         {
1398             QReadLocker locker(customTypesLock());
1399             if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1400                 return 0;
1401             ctor = ct->at(type - QMetaType::User).constructor;
1402         }
1403         return ctor(where, copy);
1404     }
1405
1406     const int m_type;
1407     void *m_where;
1408 };
1409 } // namespace
1410
1411 /*!
1412     \since 5.0
1413
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.
1417
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
1421     "placement new").
1422
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().
1426
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
1433     on x86).
1434
1435     \sa destruct(), sizeOf()
1436 */
1437 void *QMetaType::construct(int type, void *where, const void *copy)
1438 {
1439     if (!where)
1440         return 0;
1441     TypeConstructor constructor(type, where);
1442     return QMetaTypeSwitcher::switcher<void*>(constructor, type, copy);
1443 }
1444
1445
1446 namespace {
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); }
1451     };
1452     template<typename T>
1453     struct DestructorImpl<T, /* IsAcceptedType = */ false> {
1454         static void Destruct(const int type, void *where)
1455         {
1456             if (QTypeModuleInfo<T>::IsGui) {
1457                 if (Q_LIKELY(qMetaTypeGuiHelper))
1458                     qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].destructor(where);
1459                 return;
1460             }
1461             if (QTypeModuleInfo<T>::IsWidget) {
1462                 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1463                     qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].destructor(where);
1464                 return;
1465             }
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.
1468         }
1469     };
1470 public:
1471     TypeDestructor(const int type)
1472         : m_type(type)
1473     {}
1474
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); }
1480
1481 private:
1482     static void customTypeDestructor(const int type, void *where)
1483     {
1484         QMetaType::Destructor dtor;
1485         const QVector<QCustomTypeInfo> * const ct = customTypes();
1486         {
1487             QReadLocker locker(customTypesLock());
1488             if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1489                 return;
1490             dtor = ct->at(type - QMetaType::User).destructor;
1491         }
1492         dtor(where);
1493     }
1494
1495     const int m_type;
1496 };
1497 } // namespace
1498
1499 /*!
1500     \since 5.0
1501
1502     Destructs the value of the given \a type, located at \a where.
1503
1504     Unlike destroy(), this function only invokes the type's
1505     destructor, it doesn't invoke the delete operator.
1506
1507     \sa construct()
1508 */
1509 void QMetaType::destruct(int type, void *where)
1510 {
1511     if (!where)
1512         return;
1513     TypeDestructor destructor(type);
1514     QMetaTypeSwitcher::switcher<void>(destructor, type, where);
1515 }
1516
1517
1518 namespace {
1519 class SizeOf {
1520     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1521     struct SizeOfImpl {
1522         static int Size(const int) { return QTypeInfo<T>::sizeOf; }
1523     };
1524     template<typename T>
1525     struct SizeOfImpl<T, /* IsAcceptedType = */ false> {
1526         static int Size(const int type)
1527         {
1528             if (QTypeModuleInfo<T>::IsGui)
1529                 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].size : 0;
1530
1531             if (QTypeModuleInfo<T>::IsWidget)
1532                 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].size : 0;
1533
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.
1536             return 0;
1537         }
1538     };
1539
1540 public:
1541     SizeOf(int type)
1542         : m_type(type)
1543     {}
1544
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); }
1549 private:
1550     static int customTypeSizeOf(const int type)
1551     {
1552         const QVector<QCustomTypeInfo> * const ct = customTypes();
1553         QReadLocker locker(customTypesLock());
1554         if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1555             return 0;
1556         return ct->at(type - QMetaType::User).size;
1557     }
1558
1559     const int m_type;
1560 };
1561 } // namespace
1562
1563 /*!
1564     \since 5.0
1565
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).
1568
1569     This function is typically used together with construct()
1570     to perform low-level management of the memory used by a type.
1571
1572     \sa construct()
1573 */
1574 int QMetaType::sizeOf(int type)
1575 {
1576     SizeOf sizeOf(type);
1577     return QMetaTypeSwitcher::switcher<int>(sizeOf, type, 0);
1578 }
1579
1580 namespace {
1581 class Flags
1582 {
1583     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1584     struct FlagsImpl
1585     {
1586         static quint32 Flags(const int type)
1587         {
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);
1593         }
1594     };
1595     template<typename T>
1596     struct FlagsImpl<T, /* IsAcceptedType = */ false>
1597     {
1598         static quint32 Flags(const int type)
1599         {
1600             if (QTypeModuleInfo<T>::IsGui)
1601                 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].flags : 0;
1602
1603             if (QTypeModuleInfo<T>::IsWidget)
1604                 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].flags : 0;
1605
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.
1608             return 0;
1609         }
1610     };
1611 public:
1612     Flags(const int type)
1613         : m_type(type)
1614     {}
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); }
1620 private:
1621     const int m_type;
1622     static quint32 customTypeFlags(const int type)
1623     {
1624         const QVector<QCustomTypeInfo> * const ct = customTypes();
1625         if (Q_UNLIKELY(!ct || type < QMetaType::User))
1626             return 0;
1627         QReadLocker locker(customTypesLock());
1628         if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
1629             return 0;
1630         return ct->at(type - QMetaType::User).flags;
1631     }
1632 };
1633 }  // namespace
1634
1635 /*!
1636     \since 5.0
1637
1638     Returns flags of the given \a type.
1639
1640     \sa TypeFlags()
1641 */
1642 QMetaType::TypeFlags QMetaType::typeFlags(int type)
1643 {
1644     Flags flags(type);
1645     return static_cast<QMetaType::TypeFlags>(QMetaTypeSwitcher::switcher<quint32>(flags, type, 0));
1646 }
1647
1648 /*!
1649     \fn int qRegisterMetaType(const char *typeName)
1650     \relates QMetaType
1651     \threadsafe
1652
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.
1657
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.
1662
1663     After a type has been registered, you can create and destroy
1664     objects of that type dynamically at run-time.
1665
1666     This example registers the class \c{MyClass}:
1667
1668     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 4
1669
1670     This function is useful to register typedefs so they can be used
1671     by QMetaProperty, or in QueuedConnections
1672
1673     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 9
1674
1675     \sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
1676         Q_DECLARE_METATYPE()
1677 */
1678
1679 /*!
1680     \fn int qRegisterMetaTypeStreamOperators(const char *typeName)
1681     \relates QMetaType
1682     \threadsafe
1683
1684     Registers the stream operators for the type \c{T} called \a
1685     typeName.
1686
1687     Afterward, the type can be streamed using QMetaType::load() and
1688     QMetaType::save(). These functions are used when streaming a
1689     QVariant.
1690
1691     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 5
1692
1693     The stream operators should have the following signatures:
1694
1695     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 6
1696
1697     \sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
1698 */
1699
1700 /*! \typedef QMetaType::Deleter
1701     \internal
1702 */
1703 /*! \typedef QMetaType::Creator
1704     \internal
1705 */
1706 /*! \typedef QMetaType::SaveOperator
1707     \internal
1708 */
1709 /*! \typedef QMetaType::LoadOperator
1710     \internal
1711 */
1712 /*! \typedef QMetaType::Destructor
1713     \internal
1714 */
1715 /*! \typedef QMetaType::Constructor
1716     \internal
1717 */
1718
1719 /*!
1720     \fn int qRegisterMetaType()
1721     \relates QMetaType
1722     \threadsafe
1723     \since 4.2
1724
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.
1727
1728     Example:
1729
1730     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 7
1731
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
1735     is established.
1736
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()}
1740     function.
1741
1742     \sa Q_DECLARE_METATYPE()
1743  */
1744
1745 /*! \fn int qMetaTypeId()
1746     \relates QMetaType
1747     \threadsafe
1748     \since 4.1
1749
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
1752     fail.
1753
1754     Typical usage:
1755
1756     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 8
1757
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.
1762
1763     \sa Q_DECLARE_METATYPE(), QMetaType::type()
1764 */
1765
1766 namespace {
1767 class TypeInfo {
1768     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1769     struct TypeInfoImpl
1770     {
1771         TypeInfoImpl(const uint /* type */, QMetaTypeInterface &info)
1772         {
1773             QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(T);
1774             info = tmp;
1775         }
1776     };
1777
1778     template<typename T>
1779     struct TypeInfoImpl<T, /* IsAcceptedType = */ false>
1780     {
1781         TypeInfoImpl(const uint type, QMetaTypeInterface &info)
1782         {
1783             if (QTypeModuleInfo<T>::IsGui) {
1784                 if (Q_LIKELY(qMetaTypeGuiHelper))
1785                     info = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType];
1786                 return;
1787             }
1788             if (QTypeModuleInfo<T>::IsWidget) {
1789                 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1790                     info = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType];
1791                 return;
1792             }
1793         }
1794     };
1795 public:
1796     QMetaTypeInterface info;
1797     TypeInfo(const uint type)
1798         : m_type(type)
1799     {
1800         QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_EMPTY();
1801         info = tmp;
1802     }
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); }
1808 private:
1809     void customTypeInfo(const uint type)
1810     {
1811         const QVector<QCustomTypeInfo> * const ct = customTypes();
1812         if (Q_UNLIKELY(!ct))
1813             return;
1814         QReadLocker locker(customTypesLock());
1815         if (Q_LIKELY(uint(ct->count()) > type - QMetaType::User))
1816             info = ct->at(type - QMetaType::User);
1817     }
1818
1819     const uint m_type;
1820 };
1821 } // namespace
1822
1823 QMetaType QMetaType::typeInfo(const int type)
1824 {
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
1837                                  , type)
1838                 : QMetaType(UnknownType);
1839 }
1840
1841 QMetaType::QMetaType(const int typeId)
1842     : m_typeId(typeId)
1843 {
1844     if (Q_UNLIKELY(typeId == UnknownType)) {
1845         // Constructs invalid QMetaType instance.
1846         m_extensionFlags = 0xffffffff;
1847         Q_ASSERT(!isValid());
1848     } else {
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;
1855     }
1856 }
1857
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)
1870 {}
1871
1872 QMetaType &QMetaType::operator =(const QMetaType &other)
1873 {
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;
1885     return *this;
1886 }
1887
1888 void QMetaType::ctor(const QMetaTypeInterface *info)
1889 {
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);
1894     Q_UNUSED(info);
1895     m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
1896 }
1897
1898 void QMetaType::dtor()
1899 {}
1900
1901 void *QMetaType::createExtended(const void *copy) const
1902 {
1903     Q_UNUSED(copy);
1904     return 0;
1905 }
1906
1907 void QMetaType::destroyExtended(void *data) const
1908 {
1909     Q_UNUSED(data);
1910 }
1911
1912 void *QMetaType::constructExtended(void *where, const void *copy) const
1913 {
1914     Q_UNUSED(where);
1915     Q_UNUSED(copy);
1916     return 0;
1917 }
1918
1919 void QMetaType::destructExtended(void *data) const
1920 {
1921     Q_UNUSED(data);
1922 }
1923
1924 uint QMetaType::sizeExtended() const
1925 {
1926     return 0;
1927 }
1928
1929 QMetaType::TypeFlags QMetaType::flagsExtended() const
1930 {
1931     return 0;
1932 }
1933
1934 QT_END_NAMESPACE