003ad1c32df412297acb884a13b16a78137b7c76
[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
246     \omitvalue FirstGuiType
247     \omitvalue FirstWidgetsType
248     \omitvalue LastCoreType
249     \omitvalue LastGuiType
250     \omitvalue LastWidgetsType
251     \omitvalue QReal
252     \omitvalue HighestInternalId
253
254     Additional types can be registered using Q_DECLARE_METATYPE().
255
256     \sa type(), typeName()
257 */
258
259 /*!
260     \enum QMetaType::TypeFlags
261
262     The enum describes attributes of a type supported by QMetaType.
263
264     \value NeedsConstruction This type has non-trivial constructors. If the flag is not set instances can be safely initialized with memset to 0.
265     \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.
266     \value MovableType An instance of a type having this attribute can be safely moved by memcpy.
267 */
268
269 /*!
270     \class QMetaType
271     \brief The QMetaType class manages named types in the meta-object system.
272
273     \ingroup objectmodel
274     \threadsafe
275
276     The class is used as a helper to marshall types in QVariant and
277     in queued signals and slots connections. It associates a type
278     name to a type so that it can be created and destructed
279     dynamically at run-time. Declare new types with Q_DECLARE_METATYPE()
280     to make them available to QVariant and other template-based functions.
281     Call qRegisterMetaType() to make type available to non-template based
282     functions, such as the queued signal and slot connections.
283
284     Any class or struct that has a public default
285     constructor, a public copy constructor, and a public destructor
286     can be registered.
287
288     The following code allocates and destructs an instance of
289     \c{MyClass}:
290
291     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 3
292
293     If we want the stream operators \c operator<<() and \c
294     operator>>() to work on QVariant objects that store custom types,
295     the custom type must provide \c operator<<() and \c operator>>()
296     operators.
297
298     \sa Q_DECLARE_METATYPE(), QVariant::setValue(), QVariant::value(), QVariant::fromValue()
299 */
300
301 #define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
302     { #RealName, sizeof(#RealName) - 1, MetaTypeId },
303
304 #define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr) \
305     { RealNameStr, sizeof(RealNameStr) - 1, QMetaType::MetaTypeName },
306
307 #define QT_ADD_STATIC_METATYPE_HACKS_ITER(MetaTypeName, TypeId, Name) \
308     QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeName, Name)
309
310 static const struct { const char * typeName; int typeNameLength; int type; } types[] = {
311     QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE)
312     QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER)
313     QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER)
314     {0, 0, QMetaType::Void}
315 };
316
317 Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0;
318 Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = 0;
319
320 class QCustomTypeInfo : public QMetaTypeInterface
321 {
322 public:
323     QCustomTypeInfo()
324         : alias(-1)
325     {
326         QMetaTypeInterface empty = QT_METATYPE_INTERFACE_INIT(void);
327         *static_cast<QMetaTypeInterface*>(this) = empty;
328     }
329     QByteArray typeName;
330     int alias;
331 };
332
333 namespace
334 {
335 union CheckThatItIsPod
336 {   // This should break if QMetaTypeInterface is not a POD type
337     QMetaTypeInterface iface;
338 };
339 }
340
341 Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
342 Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
343 Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
344
345 #ifndef QT_NO_DATASTREAM
346 /*! \internal
347 */
348 void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
349                                         LoadOperator loadOp)
350 {
351     int idx = type(typeName);
352     if (!idx)
353         return;
354     registerStreamOperators(idx, saveOp, loadOp);
355 }
356
357 /*! \internal
358 */
359 void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
360                                         LoadOperator loadOp)
361 {
362     if (idx < User)
363         return; //builtin types should not be registered;
364     QVector<QCustomTypeInfo> *ct = customTypes();
365     if (!ct)
366         return;
367     QWriteLocker locker(customTypesLock());
368     QCustomTypeInfo &inf = (*ct)[idx - User];
369     inf.saveOp = saveOp;
370     inf.loadOp = loadOp;
371 }
372 #endif // QT_NO_DATASTREAM
373
374 /*!
375     Returns the type name associated with the given \a type, or 0 if no
376     matching type was found. The returned pointer must not be deleted.
377
378     \sa type(), isRegistered(), Type
379 */
380 const char *QMetaType::typeName(int type)
381 {
382     // In theory it can be filled during compilation time, but for some reason template code
383     // that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably
384     // it is not worth of it.
385     static const char *namesCache[QMetaType::HighestInternalId + 1];
386
387     const char *result;
388     if (type <= QMetaType::HighestInternalId && ((result = namesCache[type])))
389         return result;
390
391 #define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \
392         case QMetaType::MetaTypeName: result = #RealName; break;
393
394     switch (QMetaType::Type(type)) {
395     QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER)
396
397     default: {
398         if (Q_UNLIKELY(type < QMetaType::User)) {
399             return 0; // It can happen when someone cast int to QVariant::Type, we should not crash...
400         } else {
401             const QVector<QCustomTypeInfo> * const ct = customTypes();
402             QReadLocker locker(customTypesLock());
403             return ct && ct->count() > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty()
404                     ? ct->at(type - QMetaType::User).typeName.constData()
405                     : 0;
406         }
407     }
408     }
409 #undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
410
411     Q_ASSERT(type <= QMetaType::HighestInternalId);
412     namesCache[type] = result;
413     return result;
414 }
415
416 /*! \internal
417     Similar to QMetaType::type(), but only looks in the static set of types.
418 */
419 static inline int qMetaTypeStaticType(const char *typeName, int length)
420 {
421     int i = 0;
422     while (types[i].typeName && ((length != types[i].typeNameLength)
423                                  || strcmp(typeName, types[i].typeName))) {
424         ++i;
425     }
426     return types[i].type;
427 }
428
429 /*! \internal
430     Similar to QMetaType::type(), but only looks in the custom set of
431     types, and doesn't lock the mutex.
432 */
433 static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
434 {
435     const QVector<QCustomTypeInfo> * const ct = customTypes();
436     if (!ct)
437         return 0;
438
439     for (int v = 0; v < ct->count(); ++v) {
440         const QCustomTypeInfo &customInfo = ct->at(v);
441         if ((length == customInfo.typeName.size())
442             && !strcmp(typeName, customInfo.typeName.constData())) {
443             if (customInfo.alias >= 0)
444                 return customInfo.alias;
445             return v + QMetaType::User;
446         }
447     }
448     return 0;
449 }
450
451 /*! \internal
452
453     This function is needed until existing code outside of qtbase
454     has been changed to call the new version of registerType().
455  */
456 int QMetaType::registerType(const char *typeName, Deleter deleter,
457                             Creator creator)
458 {
459     return registerType(typeName, deleter, creator, 0, 0, 0, TypeFlags());
460 }
461
462 /*! \internal
463     \since 5.0
464
465     Registers a user type for marshalling, with \a typeName, a \a
466     deleter, a \a creator, a \a destructor, a \a constructor, and
467     a \a size. Returns the type's handle, or -1 if the type could
468     not be registered.
469  */
470 int QMetaType::registerType(const char *typeName, Deleter deleter,
471                             Creator creator,
472                             Destructor destructor,
473                             Constructor constructor,
474                             int size, TypeFlags flags)
475 {
476     QVector<QCustomTypeInfo> *ct = customTypes();
477     if (!ct || !typeName || !deleter || !creator)
478         return -1;
479
480 #ifdef QT_NO_QOBJECT
481     NS(QByteArray) normalizedTypeName = typeName;
482 #else
483     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
484 #endif
485
486     int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
487                                   normalizedTypeName.size());
488
489     int previousSize = 0;
490     int previousFlags = 0;
491     if (!idx) {
492         QWriteLocker locker(customTypesLock());
493         idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
494                                            normalizedTypeName.size());
495         if (!idx) {
496             QCustomTypeInfo inf;
497             inf.typeName = normalizedTypeName;
498             inf.creator = creator;
499             inf.deleter = deleter;
500 #ifndef QT_NO_DATASTREAM
501             inf.loadOp = 0;
502             inf.saveOp = 0;
503 #endif
504             inf.alias = -1;
505             inf.constructor = constructor;
506             inf.destructor = destructor;
507             inf.size = size;
508             inf.flags = flags;
509             idx = ct->size() + User;
510             ct->append(inf);
511             return idx;
512         }
513
514         if (idx >= User) {
515             previousSize = ct->at(idx - User).size;
516             previousFlags = ct->at(idx - User).flags;
517         }
518     }
519
520     if (idx < User) {
521         previousSize = QMetaType::sizeOf(idx);
522         previousFlags = QMetaType::typeFlags(idx);
523     }
524
525     if (previousSize != size) {
526         qFatal("QMetaType::registerType: Binary compatibility break "
527             "-- Size mismatch for type '%s' [%i]. Previously registered "
528             "size %i, now registering size %i.",
529             normalizedTypeName.constData(), idx, previousSize, size);
530     }
531     if (previousFlags != flags) {
532         qFatal("QMetaType::registerType: Binary compatibility break "
533             "-- Type flags for type '%s' [%i] don't match. Previously "
534             "registered TypeFlags(0x%x), now registering TypeFlags(0x%x).",
535             normalizedTypeName.constData(), idx, previousFlags, int(flags));
536     }
537
538     return idx;
539 }
540
541 /*! \internal
542     \since 4.7
543
544     Registers a user type for marshalling, as an alias of another type (typedef)
545 */
546 int QMetaType::registerTypedef(const char* typeName, int aliasId)
547 {
548     QVector<QCustomTypeInfo> *ct = customTypes();
549     if (!ct || !typeName)
550         return -1;
551
552 #ifdef QT_NO_QOBJECT
553     NS(QByteArray) normalizedTypeName = typeName;
554 #else
555     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
556 #endif
557
558     int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
559                                   normalizedTypeName.size());
560
561     if (!idx) {
562         QWriteLocker locker(customTypesLock());
563         idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
564                                                normalizedTypeName.size());
565
566         if (!idx) {
567             QCustomTypeInfo inf;
568             inf.typeName = normalizedTypeName;
569             inf.alias = aliasId;
570             inf.creator = 0;
571             inf.deleter = 0;
572             ct->append(inf);
573             return aliasId;
574         }
575     }
576
577     if (idx != aliasId) {
578         qFatal("QMetaType::registerTypedef: Binary compatibility break "
579             "-- Type name '%s' previously registered as typedef of '%s' [%i], "
580             "now registering as typedef of '%s' [%i].",
581             normalizedTypeName.constData(), QMetaType::typeName(idx), idx,
582             QMetaType::typeName(aliasId), aliasId);
583     }
584     return idx;
585 }
586
587 /*!
588     Returns true if the datatype with ID \a type is registered;
589     otherwise returns false.
590
591     \sa type(), typeName(), Type
592 */
593 bool QMetaType::isRegistered(int type)
594 {
595     if (type >= 0 && type < User) {
596         // predefined type
597         return true;
598     }
599     QReadLocker locker(customTypesLock());
600     const QVector<QCustomTypeInfo> * const ct = customTypes();
601     return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
602 }
603
604 /*!
605     Returns a handle to the type called \a typeName, or 0 if there is
606     no such type.
607
608     \sa isRegistered(), typeName(), Type
609 */
610 int QMetaType::type(const char *typeName)
611 {
612     int length = qstrlen(typeName);
613     if (!length)
614         return 0;
615     int type = qMetaTypeStaticType(typeName, length);
616     if (!type) {
617         QReadLocker locker(customTypesLock());
618         type = qMetaTypeCustomType_unlocked(typeName, length);
619 #ifndef QT_NO_QOBJECT
620         if (!type) {
621             const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
622             type = qMetaTypeStaticType(normalizedTypeName.constData(),
623                                        normalizedTypeName.size());
624             if (!type) {
625                 type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
626                                                     normalizedTypeName.size());
627             }
628         }
629 #endif
630     }
631     return type;
632 }
633
634 #ifndef QT_NO_DATASTREAM
635 /*!
636     Writes the object pointed to by \a data with the ID \a type to
637     the given \a stream. Returns true if the object is saved
638     successfully; otherwise returns false.
639
640     The type must have been registered with qRegisterMetaType() and
641     qRegisterMetaTypeStreamOperators() beforehand.
642
643     Normally, you should not need to call this function directly.
644     Instead, use QVariant's \c operator<<(), which relies on save()
645     to stream custom types.
646
647     \sa load(), qRegisterMetaTypeStreamOperators()
648 */
649 bool QMetaType::save(QDataStream &stream, int type, const void *data)
650 {
651     if (!data || !isRegistered(type))
652         return false;
653
654     switch(type) {
655     case QMetaType::Void:
656     case QMetaType::VoidStar:
657     case QMetaType::QObjectStar:
658     case QMetaType::QWidgetStar:
659     case QMetaType::QModelIndex:
660         return false;
661     case QMetaType::Long:
662         stream << qlonglong(*static_cast<const long *>(data));
663         break;
664     case QMetaType::Int:
665         stream << *static_cast<const int *>(data);
666         break;
667     case QMetaType::Short:
668         stream << *static_cast<const short *>(data);
669         break;
670     case QMetaType::Char:
671         // force a char to be signed
672         stream << *static_cast<const signed char *>(data);
673         break;
674     case QMetaType::ULong:
675         stream << qulonglong(*static_cast<const ulong *>(data));
676         break;
677     case QMetaType::UInt:
678         stream << *static_cast<const uint *>(data);
679         break;
680     case QMetaType::LongLong:
681         stream << *static_cast<const qlonglong *>(data);
682         break;
683     case QMetaType::ULongLong:
684         stream << *static_cast<const qulonglong *>(data);
685         break;
686     case QMetaType::UShort:
687         stream << *static_cast<const ushort *>(data);
688         break;
689     case QMetaType::UChar:
690         stream << *static_cast<const uchar *>(data);
691         break;
692     case QMetaType::Bool:
693         stream << qint8(*static_cast<const bool *>(data));
694         break;
695     case QMetaType::Float:
696         stream << *static_cast<const float *>(data);
697         break;
698     case QMetaType::Double:
699         stream << *static_cast<const double *>(data);
700         break;
701     case QMetaType::QChar:
702         stream << *static_cast<const NS(QChar) *>(data);
703         break;
704 #ifndef QT_BOOTSTRAPPED
705     case QMetaType::QVariantMap:
706         stream << *static_cast<const NS(QVariantMap)*>(data);
707         break;
708     case QMetaType::QVariantHash:
709         stream << *static_cast<const NS(QVariantHash)*>(data);
710         break;
711     case QMetaType::QVariantList:
712         stream << *static_cast<const NS(QVariantList)*>(data);
713         break;
714     case QMetaType::QVariant:
715         stream << *static_cast<const NS(QVariant)*>(data);
716         break;
717 #endif
718     case QMetaType::QByteArray:
719         stream << *static_cast<const NS(QByteArray)*>(data);
720         break;
721     case QMetaType::QString:
722         stream << *static_cast<const NS(QString)*>(data);
723         break;
724     case QMetaType::QStringList:
725         stream << *static_cast<const NS(QStringList)*>(data);
726         break;
727 #ifndef QT_BOOTSTRAPPED
728     case QMetaType::QBitArray:
729         stream << *static_cast<const NS(QBitArray)*>(data);
730         break;
731 #endif
732     case QMetaType::QDate:
733         stream << *static_cast<const NS(QDate)*>(data);
734         break;
735     case QMetaType::QTime:
736         stream << *static_cast<const NS(QTime)*>(data);
737         break;
738     case QMetaType::QDateTime:
739         stream << *static_cast<const NS(QDateTime)*>(data);
740         break;
741 #ifndef QT_BOOTSTRAPPED
742     case QMetaType::QUrl:
743         stream << *static_cast<const NS(QUrl)*>(data);
744         break;
745 #endif
746     case QMetaType::QLocale:
747         stream << *static_cast<const NS(QLocale)*>(data);
748         break;
749 #ifndef QT_NO_GEOM_VARIANT
750     case QMetaType::QRect:
751         stream << *static_cast<const NS(QRect)*>(data);
752         break;
753     case QMetaType::QRectF:
754         stream << *static_cast<const NS(QRectF)*>(data);
755         break;
756     case QMetaType::QSize:
757         stream << *static_cast<const NS(QSize)*>(data);
758         break;
759     case QMetaType::QSizeF:
760         stream << *static_cast<const NS(QSizeF)*>(data);
761         break;
762     case QMetaType::QLine:
763         stream << *static_cast<const NS(QLine)*>(data);
764         break;
765     case QMetaType::QLineF:
766         stream << *static_cast<const NS(QLineF)*>(data);
767         break;
768     case QMetaType::QPoint:
769         stream << *static_cast<const NS(QPoint)*>(data);
770         break;
771     case QMetaType::QPointF:
772         stream << *static_cast<const NS(QPointF)*>(data);
773         break;
774 #endif
775 #ifndef QT_NO_REGEXP
776     case QMetaType::QRegExp:
777         stream << *static_cast<const NS(QRegExp)*>(data);
778         break;
779 #endif
780 #ifndef QT_BOOTSTRAPPED
781     case QMetaType::QEasingCurve:
782         stream << *static_cast<const NS(QEasingCurve)*>(data);
783         break;
784 #endif
785     case QMetaType::QFont:
786     case QMetaType::QPixmap:
787     case QMetaType::QBrush:
788     case QMetaType::QColor:
789     case QMetaType::QPalette:
790     case QMetaType::QImage:
791     case QMetaType::QPolygon:
792     case QMetaType::QPolygonF:
793     case QMetaType::QRegion:
794     case QMetaType::QBitmap:
795     case QMetaType::QCursor:
796     case QMetaType::QKeySequence:
797     case QMetaType::QPen:
798     case QMetaType::QTextLength:
799     case QMetaType::QTextFormat:
800     case QMetaType::QMatrix:
801     case QMetaType::QTransform:
802     case QMetaType::QMatrix4x4:
803     case QMetaType::QVector2D:
804     case QMetaType::QVector3D:
805     case QMetaType::QVector4D:
806     case QMetaType::QQuaternion:
807         if (!qMetaTypeGuiHelper)
808             return false;
809         qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
810         break;
811     case QMetaType::QIcon:
812     case QMetaType::QSizePolicy:
813         if (!qMetaTypeWidgetsHelper)
814             return false;
815         qMetaTypeWidgetsHelper[type - FirstWidgetsType].saveOp(stream, data);
816         break;
817     case QMetaType::QUuid:
818         stream << *static_cast<const NS(QUuid)*>(data);
819         break;
820     default: {
821         const QVector<QCustomTypeInfo> * const ct = customTypes();
822         if (!ct)
823             return false;
824
825         SaveOperator saveOp = 0;
826         {
827             QReadLocker locker(customTypesLock());
828             saveOp = ct->at(type - User).saveOp;
829         }
830
831         if (!saveOp)
832             return false;
833         saveOp(stream, data);
834         break; }
835     }
836
837     return true;
838 }
839
840 /*!
841     Reads the object of the specified \a type from the given \a
842     stream into \a data. Returns true if the object is loaded
843     successfully; otherwise returns false.
844
845     The type must have been registered with qRegisterMetaType() and
846     qRegisterMetaTypeStreamOperators() beforehand.
847
848     Normally, you should not need to call this function directly.
849     Instead, use QVariant's \c operator>>(), which relies on load()
850     to stream custom types.
851
852     \sa save(), qRegisterMetaTypeStreamOperators()
853 */
854 bool QMetaType::load(QDataStream &stream, int type, void *data)
855 {
856     if (!data || !isRegistered(type))
857         return false;
858
859     switch(type) {
860     case QMetaType::Void:
861     case QMetaType::VoidStar:
862     case QMetaType::QObjectStar:
863     case QMetaType::QWidgetStar:
864     case QMetaType::QModelIndex:
865         return false;
866     case QMetaType::Long: {
867         qlonglong l;
868         stream >> l;
869         *static_cast<long *>(data) = long(l);
870         break; }
871     case QMetaType::Int:
872         stream >> *static_cast<int *>(data);
873         break;
874     case QMetaType::Short:
875         stream >> *static_cast<short *>(data);
876         break;
877     case QMetaType::Char:
878         // force a char to be signed
879         stream >> *static_cast<signed char *>(data);
880         break;
881     case QMetaType::ULong: {
882         qulonglong ul;
883         stream >> ul;
884         *static_cast<ulong *>(data) = ulong(ul);
885         break; }
886     case QMetaType::UInt:
887         stream >> *static_cast<uint *>(data);
888         break;
889     case QMetaType::LongLong:
890         stream >> *static_cast<qlonglong *>(data);
891         break;
892     case QMetaType::ULongLong:
893         stream >> *static_cast<qulonglong *>(data);
894         break;
895     case QMetaType::UShort:
896         stream >> *static_cast<ushort *>(data);
897         break;
898     case QMetaType::UChar:
899         stream >> *static_cast<uchar *>(data);
900         break;
901     case QMetaType::Bool: {
902         qint8 b;
903         stream >> b;
904         *static_cast<bool *>(data) = b;
905         break; }
906     case QMetaType::Float:
907         stream >> *static_cast<float *>(data);
908         break;
909     case QMetaType::Double:
910         stream >> *static_cast<double *>(data);
911         break;
912     case QMetaType::QChar:
913         stream >> *static_cast< NS(QChar)*>(data);
914         break;
915 #ifndef QT_BOOTSTRAPPED
916     case QMetaType::QVariantMap:
917         stream >> *static_cast< NS(QVariantMap)*>(data);
918         break;
919     case QMetaType::QVariantHash:
920         stream >> *static_cast< NS(QVariantHash)*>(data);
921         break;
922     case QMetaType::QVariantList:
923         stream >> *static_cast< NS(QVariantList)*>(data);
924         break;
925     case QMetaType::QVariant:
926         stream >> *static_cast< NS(QVariant)*>(data);
927         break;
928 #endif
929     case QMetaType::QByteArray:
930         stream >> *static_cast< NS(QByteArray)*>(data);
931         break;
932     case QMetaType::QString:
933         stream >> *static_cast< NS(QString)*>(data);
934         break;
935     case QMetaType::QStringList:
936         stream >> *static_cast< NS(QStringList)*>(data);
937         break;
938 #ifndef QT_BOOTSTRAPPED
939     case QMetaType::QBitArray:
940         stream >> *static_cast< NS(QBitArray)*>(data);
941         break;
942 #endif
943     case QMetaType::QDate:
944         stream >> *static_cast< NS(QDate)*>(data);
945         break;
946     case QMetaType::QTime:
947         stream >> *static_cast< NS(QTime)*>(data);
948         break;
949     case QMetaType::QDateTime:
950         stream >> *static_cast< NS(QDateTime)*>(data);
951         break;
952 #ifndef QT_BOOTSTRAPPED
953     case QMetaType::QUrl:
954         stream >> *static_cast< NS(QUrl)*>(data);
955         break;
956 #endif
957     case QMetaType::QLocale:
958         stream >> *static_cast< NS(QLocale)*>(data);
959         break;
960 #ifndef QT_NO_GEOM_VARIANT
961     case QMetaType::QRect:
962         stream >> *static_cast< NS(QRect)*>(data);
963         break;
964     case QMetaType::QRectF:
965         stream >> *static_cast< NS(QRectF)*>(data);
966         break;
967     case QMetaType::QSize:
968         stream >> *static_cast< NS(QSize)*>(data);
969         break;
970     case QMetaType::QSizeF:
971         stream >> *static_cast< NS(QSizeF)*>(data);
972         break;
973     case QMetaType::QLine:
974         stream >> *static_cast< NS(QLine)*>(data);
975         break;
976     case QMetaType::QLineF:
977         stream >> *static_cast< NS(QLineF)*>(data);
978         break;
979     case QMetaType::QPoint:
980         stream >> *static_cast< NS(QPoint)*>(data);
981         break;
982     case QMetaType::QPointF:
983         stream >> *static_cast< NS(QPointF)*>(data);
984         break;
985 #endif
986 #ifndef QT_NO_REGEXP
987     case QMetaType::QRegExp:
988         stream >> *static_cast< NS(QRegExp)*>(data);
989         break;
990 #endif
991 #ifndef QT_BOOTSTRAPPED
992     case QMetaType::QEasingCurve:
993         stream >> *static_cast< NS(QEasingCurve)*>(data);
994         break;
995 #endif
996     case QMetaType::QFont:
997     case QMetaType::QPixmap:
998     case QMetaType::QBrush:
999     case QMetaType::QColor:
1000     case QMetaType::QPalette:
1001     case QMetaType::QImage:
1002     case QMetaType::QPolygon:
1003     case QMetaType::QPolygonF:
1004     case QMetaType::QRegion:
1005     case QMetaType::QBitmap:
1006     case QMetaType::QCursor:
1007     case QMetaType::QKeySequence:
1008     case QMetaType::QPen:
1009     case QMetaType::QTextLength:
1010     case QMetaType::QTextFormat:
1011     case QMetaType::QMatrix:
1012     case QMetaType::QTransform:
1013     case QMetaType::QMatrix4x4:
1014     case QMetaType::QVector2D:
1015     case QMetaType::QVector3D:
1016     case QMetaType::QVector4D:
1017     case QMetaType::QQuaternion:
1018         if (!qMetaTypeGuiHelper)
1019             return false;
1020         qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
1021         break;
1022     case QMetaType::QIcon:
1023     case QMetaType::QSizePolicy:
1024         if (!qMetaTypeWidgetsHelper)
1025             return false;
1026         qMetaTypeWidgetsHelper[type - FirstWidgetsType].loadOp(stream, data);
1027         break;
1028     case QMetaType::QUuid:
1029         stream >> *static_cast< NS(QUuid)*>(data);
1030         break;
1031     default: {
1032         const QVector<QCustomTypeInfo> * const ct = customTypes();
1033         if (!ct)
1034             return false;
1035
1036         LoadOperator loadOp = 0;
1037         {
1038             QReadLocker locker(customTypesLock());
1039             loadOp = ct->at(type - User).loadOp;
1040         }
1041
1042         if (!loadOp)
1043             return false;
1044         loadOp(stream, data);
1045         break; }
1046     }
1047     return true;
1048 }
1049 #endif // QT_NO_DATASTREAM
1050
1051 /*!
1052     Returns a copy of \a copy, assuming it is of type \a type. If \a
1053     copy is zero, creates a default type.
1054
1055     \sa destroy(), isRegistered(), Type
1056 */
1057 void *QMetaType::create(int type, const void *copy)
1058 {
1059     if (copy) {
1060         switch(type) {
1061         case QMetaType::VoidStar:
1062         case QMetaType::QObjectStar:
1063         case QMetaType::QWidgetStar:
1064             return new void *(*static_cast<void* const *>(copy));
1065         case QMetaType::Long:
1066             return new long(*static_cast<const long*>(copy));
1067         case QMetaType::Int:
1068             return new int(*static_cast<const int*>(copy));
1069         case QMetaType::Short:
1070             return new short(*static_cast<const short*>(copy));
1071         case QMetaType::Char:
1072             return new char(*static_cast<const char*>(copy));
1073         case QMetaType::ULong:
1074             return new ulong(*static_cast<const ulong*>(copy));
1075         case QMetaType::UInt:
1076             return new uint(*static_cast<const uint*>(copy));
1077         case QMetaType::LongLong:
1078             return new qlonglong(*static_cast<const qlonglong*>(copy));
1079         case QMetaType::ULongLong:
1080             return new qulonglong(*static_cast<const qulonglong*>(copy));
1081         case QMetaType::UShort:
1082             return new ushort(*static_cast<const ushort*>(copy));
1083         case QMetaType::UChar:
1084             return new uchar(*static_cast<const uchar*>(copy));
1085         case QMetaType::Bool:
1086             return new bool(*static_cast<const bool*>(copy));
1087         case QMetaType::Float:
1088             return new float(*static_cast<const float*>(copy));
1089         case QMetaType::Double:
1090             return new double(*static_cast<const double*>(copy));
1091         case QMetaType::QChar:
1092             return new NS(QChar)(*static_cast<const NS(QChar)*>(copy));
1093 #ifndef QT_BOOTSTRAPPED
1094         case QMetaType::QVariantMap:
1095             return new NS(QVariantMap)(*static_cast<const NS(QVariantMap)*>(copy));
1096         case QMetaType::QVariantHash:
1097             return new NS(QVariantHash)(*static_cast<const NS(QVariantHash)*>(copy));
1098         case QMetaType::QVariantList:
1099             return new NS(QVariantList)(*static_cast<const NS(QVariantList)*>(copy));
1100         case QMetaType::QVariant:
1101             return new NS(QVariant)(*static_cast<const NS(QVariant)*>(copy));
1102 #endif
1103         case QMetaType::QByteArray:
1104             return new NS(QByteArray)(*static_cast<const NS(QByteArray)*>(copy));
1105         case QMetaType::QString:
1106             return new NS(QString)(*static_cast<const NS(QString)*>(copy));
1107         case QMetaType::QStringList:
1108             return new NS(QStringList)(*static_cast<const NS(QStringList)*>(copy));
1109 #ifndef QT_BOOTSTRAPPED
1110         case QMetaType::QBitArray:
1111             return new NS(QBitArray)(*static_cast<const NS(QBitArray)*>(copy));
1112 #endif
1113         case QMetaType::QDate:
1114             return new NS(QDate)(*static_cast<const NS(QDate)*>(copy));
1115         case QMetaType::QTime:
1116             return new NS(QTime)(*static_cast<const NS(QTime)*>(copy));
1117         case QMetaType::QDateTime:
1118             return new NS(QDateTime)(*static_cast<const NS(QDateTime)*>(copy));
1119 #ifndef QT_BOOTSTRAPPED
1120         case QMetaType::QUrl:
1121             return new NS(QUrl)(*static_cast<const NS(QUrl)*>(copy));
1122 #endif
1123         case QMetaType::QLocale:
1124             return new NS(QLocale)(*static_cast<const NS(QLocale)*>(copy));
1125 #ifndef QT_NO_GEOM_VARIANT
1126         case QMetaType::QRect:
1127             return new NS(QRect)(*static_cast<const NS(QRect)*>(copy));
1128         case QMetaType::QRectF:
1129             return new NS(QRectF)(*static_cast<const NS(QRectF)*>(copy));
1130         case QMetaType::QSize:
1131             return new NS(QSize)(*static_cast<const NS(QSize)*>(copy));
1132         case QMetaType::QSizeF:
1133             return new NS(QSizeF)(*static_cast<const NS(QSizeF)*>(copy));
1134         case QMetaType::QLine:
1135             return new NS(QLine)(*static_cast<const NS(QLine)*>(copy));
1136         case QMetaType::QLineF:
1137             return new NS(QLineF)(*static_cast<const NS(QLineF)*>(copy));
1138         case QMetaType::QPoint:
1139             return new NS(QPoint)(*static_cast<const NS(QPoint)*>(copy));
1140         case QMetaType::QPointF:
1141             return new NS(QPointF)(*static_cast<const NS(QPointF)*>(copy));
1142 #endif
1143 #ifndef QT_NO_REGEXP
1144         case QMetaType::QRegExp:
1145             return new NS(QRegExp)(*static_cast<const NS(QRegExp)*>(copy));
1146 #endif
1147 #ifndef QT_BOOTSTRAPPED
1148         case QMetaType::QEasingCurve:
1149             return new NS(QEasingCurve)(*static_cast<const NS(QEasingCurve)*>(copy));
1150 #endif
1151         case QMetaType::QUuid:
1152             return new NS(QUuid)(*static_cast<const NS(QUuid)*>(copy));
1153 #ifndef QT_BOOTSTRAPPED
1154         case QMetaType::QModelIndex:
1155             return new NS(QModelIndex)(*static_cast<const NS(QModelIndex)*>(copy));
1156 #endif
1157         case QMetaType::Void:
1158             return 0;
1159         default:
1160             ;
1161         }
1162     } else {
1163         switch(type) {
1164         case QMetaType::VoidStar:
1165         case QMetaType::QObjectStar:
1166         case QMetaType::QWidgetStar:
1167             return new void *;
1168         case QMetaType::Long:
1169             return new long;
1170         case QMetaType::Int:
1171             return new int;
1172         case QMetaType::Short:
1173             return new short;
1174         case QMetaType::Char:
1175             return new char;
1176         case QMetaType::ULong:
1177             return new ulong;
1178         case QMetaType::UInt:
1179             return new uint;
1180         case QMetaType::LongLong:
1181             return new qlonglong;
1182         case QMetaType::ULongLong:
1183             return new qulonglong;
1184         case QMetaType::UShort:
1185             return new ushort;
1186         case QMetaType::UChar:
1187             return new uchar;
1188         case QMetaType::Bool:
1189             return new bool;
1190         case QMetaType::Float:
1191             return new float;
1192         case QMetaType::Double:
1193             return new double;
1194         case QMetaType::QChar:
1195             return new NS(QChar);
1196 #ifndef QT_BOOTSTRAPPED
1197         case QMetaType::QVariantMap:
1198             return new NS(QVariantMap);
1199         case QMetaType::QVariantHash:
1200             return new NS(QVariantHash);
1201         case QMetaType::QVariantList:
1202             return new NS(QVariantList);
1203         case QMetaType::QVariant:
1204             return new NS(QVariant);
1205 #endif
1206         case QMetaType::QByteArray:
1207             return new NS(QByteArray);
1208         case QMetaType::QString:
1209             return new NS(QString);
1210         case QMetaType::QStringList:
1211             return new NS(QStringList);
1212 #ifndef QT_BOOTSTRAPPED
1213         case QMetaType::QBitArray:
1214             return new NS(QBitArray);
1215 #endif
1216         case QMetaType::QDate:
1217             return new NS(QDate);
1218         case QMetaType::QTime:
1219             return new NS(QTime);
1220         case QMetaType::QDateTime:
1221             return new NS(QDateTime);
1222 #ifndef QT_BOOTSTRAPPED
1223         case QMetaType::QUrl:
1224             return new NS(QUrl);
1225 #endif
1226         case QMetaType::QLocale:
1227             return new NS(QLocale);
1228 #ifndef QT_NO_GEOM_VARIANT
1229         case QMetaType::QRect:
1230             return new NS(QRect);
1231         case QMetaType::QRectF:
1232             return new NS(QRectF);
1233         case QMetaType::QSize:
1234             return new NS(QSize);
1235         case QMetaType::QSizeF:
1236             return new NS(QSizeF);
1237         case QMetaType::QLine:
1238             return new NS(QLine);
1239         case QMetaType::QLineF:
1240             return new NS(QLineF);
1241         case QMetaType::QPoint:
1242             return new NS(QPoint);
1243         case QMetaType::QPointF:
1244             return new NS(QPointF);
1245 #endif
1246 #ifndef QT_NO_REGEXP
1247         case QMetaType::QRegExp:
1248             return new NS(QRegExp);
1249 #endif
1250 #ifndef QT_BOOTSTRAPPED
1251         case QMetaType::QEasingCurve:
1252             return new NS(QEasingCurve);
1253 #endif
1254         case QMetaType::QUuid:
1255             return new NS(QUuid);
1256 #ifndef QT_BOOTSTRAPPED
1257         case QMetaType::QModelIndex:
1258             return new NS(QModelIndex);
1259 #endif
1260         case QMetaType::Void:
1261             return 0;
1262         default:
1263             ;
1264         }
1265     }
1266
1267     Creator creator = 0;
1268     if (type >= FirstGuiType && type <= LastGuiType) {
1269         if (!qMetaTypeGuiHelper)
1270             return 0;
1271         creator = qMetaTypeGuiHelper[type - FirstGuiType].creator;
1272     } else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
1273         if (!qMetaTypeWidgetsHelper)
1274             return 0;
1275         creator = qMetaTypeWidgetsHelper[type - FirstWidgetsType].creator;
1276     } else {
1277         const QVector<QCustomTypeInfo> * const ct = customTypes();
1278         QReadLocker locker(customTypesLock());
1279         if (type < User || !ct || ct->count() <= type - User)
1280             return 0;
1281         if (ct->at(type - User).typeName.isEmpty())
1282             return 0;
1283         creator = ct->at(type - User).creator;
1284     }
1285
1286     return creator(copy);
1287 }
1288
1289 namespace {
1290 class TypeDestroyer {
1291     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1292     struct DestroyerImpl {
1293         static void Destroy(const int /* type */, void *where) { qMetaTypeDeleteHelper<T>(where); }
1294     };
1295     template<typename T>
1296     struct DestroyerImpl<T, /* IsAcceptedType = */ false> {
1297         static void Destroy(const int type, void *where)
1298         {
1299             if (QTypeModuleInfo<T>::IsGui) {
1300                 if (Q_LIKELY(qMetaTypeGuiHelper))
1301                     qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].deleter(where);
1302                 return;
1303             }
1304             if (QTypeModuleInfo<T>::IsWidget) {
1305                 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1306                     qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].deleter(where);
1307                 return;
1308             }
1309             // This point can be reached only for known types that definition is not available, for example
1310             // in bootstrap mode. We have no other choice then ignore it.
1311         }
1312     };
1313 public:
1314     TypeDestroyer(const int type)
1315         : m_type(type)
1316     {}
1317
1318     template<typename T>
1319     void delegate(const T *where) { DestroyerImpl<T>::Destroy(m_type, const_cast<T*>(where)); }
1320     void delegate(const void *) {}
1321     void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestroyer(m_type, (void*)where); }
1322
1323 private:
1324     static void customTypeDestroyer(const int type, void *where)
1325     {
1326         QMetaType::Destructor deleter;
1327         const QVector<QCustomTypeInfo> * const ct = customTypes();
1328         {
1329             QReadLocker locker(customTypesLock());
1330             if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1331                 return;
1332             deleter = ct->at(type - QMetaType::User).deleter;
1333         }
1334         deleter(where);
1335     }
1336
1337     const int m_type;
1338 };
1339 } // namespace
1340
1341
1342 /*!
1343     Destroys the \a data, assuming it is of the \a type given.
1344
1345     \sa create(), isRegistered(), Type
1346 */
1347 void QMetaType::destroy(int type, void *data)
1348 {
1349     TypeDestroyer deleter(type);
1350     QMetaTypeSwitcher::switcher<void>(deleter, type, data);
1351 }
1352
1353 namespace {
1354 class TypeConstructor {
1355     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1356     struct ConstructorImpl {
1357         static void *Construct(const int /*type*/, void *where, const void *copy) { return qMetaTypeConstructHelper<T>(where, copy); }
1358     };
1359     template<typename T>
1360     struct ConstructorImpl<T, /* IsAcceptedType = */ false> {
1361         static void *Construct(const int type, void *where, const void *copy)
1362         {
1363             if (QTypeModuleInfo<T>::IsGui)
1364                 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy) : 0;
1365
1366             if (QTypeModuleInfo<T>::IsWidget)
1367                 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy) : 0;
1368
1369             // This point can be reached only for known types that definition is not available, for example
1370             // in bootstrap mode. We have no other choice then ignore it.
1371             return 0;
1372         }
1373     };
1374 public:
1375     TypeConstructor(const int type, void *where)
1376         : m_type(type)
1377         , m_where(where)
1378     {}
1379
1380     template<typename T>
1381     void *delegate(const T *copy) { return ConstructorImpl<T>::Construct(m_type, m_where, copy); }
1382     void *delegate(const void *) { return m_where; }
1383     void *delegate(const QMetaTypeSwitcher::NotBuiltinType *copy) { return customTypeConstructor(m_type, m_where, copy); }
1384
1385 private:
1386     static void *customTypeConstructor(const int type, void *where, const void *copy)
1387     {
1388         QMetaType::Constructor ctor;
1389         const QVector<QCustomTypeInfo> * const ct = customTypes();
1390         {
1391             QReadLocker locker(customTypesLock());
1392             if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1393                 return 0;
1394             ctor = ct->at(type - QMetaType::User).constructor;
1395         }
1396         return ctor(where, copy);
1397     }
1398
1399     const int m_type;
1400     void *m_where;
1401 };
1402 } // namespace
1403
1404 /*!
1405     \since 5.0
1406
1407     Constructs a value of the given \a type in the existing memory
1408     addressed by \a where, that is a copy of \a copy, and returns
1409     \a where. If \a copy is zero, the value is default constructed.
1410
1411     This is a low-level function for explicitly managing the memory
1412     used to store the type. Consider calling create() if you don't
1413     need this level of control (that is, use "new" rather than
1414     "placement new").
1415
1416     You must ensure that \a where points to a location that can store
1417     a value of type \a type, and that \a where is suitably aligned.
1418     The type's size can be queried by calling sizeOf().
1419
1420     The rule of thumb for alignment is that a type is aligned to its
1421     natural boundary, which is the smallest power of 2 that is bigger
1422     than the type, unless that alignment is larger than the maximum
1423     useful alignment for the platform. For practical purposes,
1424     alignment larger than 2 * sizeof(void*) is only necessary for
1425     special hardware instructions (e.g., aligned SSE loads and stores
1426     on x86).
1427
1428     \sa destruct(), sizeOf()
1429 */
1430 void *QMetaType::construct(int type, void *where, const void *copy)
1431 {
1432     if (!where)
1433         return 0;
1434     TypeConstructor constructor(type, where);
1435     return QMetaTypeSwitcher::switcher<void*>(constructor, type, copy);
1436 }
1437
1438
1439 namespace {
1440 class TypeDestructor {
1441     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1442     struct DestructorImpl {
1443         static void Destruct(const int /* type */, void *where) { qMetaTypeDestructHelper<T>(where); }
1444     };
1445     template<typename T>
1446     struct DestructorImpl<T, /* IsAcceptedType = */ false> {
1447         static void Destruct(const int type, void *where)
1448         {
1449             if (QTypeModuleInfo<T>::IsGui) {
1450                 if (Q_LIKELY(qMetaTypeGuiHelper))
1451                     qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].destructor(where);
1452                 return;
1453             }
1454             if (QTypeModuleInfo<T>::IsWidget) {
1455                 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1456                     qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].destructor(where);
1457                 return;
1458             }
1459             // This point can be reached only for known types that definition is not available, for example
1460             // in bootstrap mode. We have no other choice then ignore it.
1461         }
1462     };
1463 public:
1464     TypeDestructor(const int type)
1465         : m_type(type)
1466     {}
1467
1468     template<typename T>
1469     void delegate(const T *where) { DestructorImpl<T>::Destruct(m_type, const_cast<T*>(where)); }
1470     void delegate(const void *) {}
1471     void delegate(const QMetaTypeSwitcher::NotBuiltinType *where) { customTypeDestructor(m_type, (void*)where); }
1472
1473 private:
1474     static void customTypeDestructor(const int type, void *where)
1475     {
1476         QMetaType::Destructor dtor;
1477         const QVector<QCustomTypeInfo> * const ct = customTypes();
1478         {
1479             QReadLocker locker(customTypesLock());
1480             if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1481                 return;
1482             dtor = ct->at(type - QMetaType::User).destructor;
1483         }
1484         dtor(where);
1485     }
1486
1487     const int m_type;
1488 };
1489 } // namespace
1490
1491 /*!
1492     \since 5.0
1493
1494     Destructs the value of the given \a type, located at \a where.
1495
1496     Unlike destroy(), this function only invokes the type's
1497     destructor, it doesn't invoke the delete operator.
1498
1499     \sa construct()
1500 */
1501 void QMetaType::destruct(int type, void *where)
1502 {
1503     if (!where)
1504         return;
1505     TypeDestructor destructor(type);
1506     QMetaTypeSwitcher::switcher<void>(destructor, type, where);
1507 }
1508
1509
1510 namespace {
1511 class SizeOf {
1512     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1513     struct SizeOfImpl {
1514         static int Size(const int) { return QTypeInfo<T>::sizeOf; }
1515     };
1516     template<typename T>
1517     struct SizeOfImpl<T, /* IsAcceptedType = */ false> {
1518         static int Size(const int type)
1519         {
1520             if (QTypeModuleInfo<T>::IsGui)
1521                 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].size : 0;
1522
1523             if (QTypeModuleInfo<T>::IsWidget)
1524                 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].size : 0;
1525
1526             // This point can be reached only for known types that definition is not available, for example
1527             // in bootstrap mode. We have no other choice then ignore it.
1528             return 0;
1529         }
1530     };
1531
1532 public:
1533     SizeOf(int type)
1534         : m_type(type)
1535     {}
1536
1537     template<typename T>
1538     int delegate(const T*) { return SizeOfImpl<T>::Size(m_type); }
1539     int delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeSizeOf(m_type); }
1540 private:
1541     static int customTypeSizeOf(const int type)
1542     {
1543         const QVector<QCustomTypeInfo> * const ct = customTypes();
1544         QReadLocker locker(customTypesLock());
1545         if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1546             return 0;
1547         return ct->at(type - QMetaType::User).size;
1548     }
1549
1550     const int m_type;
1551 };
1552 } // namespace
1553
1554 /*!
1555     \since 5.0
1556
1557     Returns the size of the given \a type in bytes (i.e., sizeof(T),
1558     where T is the actual type identified by the \a type argument).
1559
1560     This function is typically used together with construct()
1561     to perform low-level management of the memory used by a type.
1562
1563     \sa construct()
1564 */
1565 int QMetaType::sizeOf(int type)
1566 {
1567     SizeOf sizeOf(type);
1568     return QMetaTypeSwitcher::switcher<int>(sizeOf, type, 0);
1569 }
1570
1571 namespace {
1572 class Flags
1573 {
1574     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1575     struct FlagsImpl
1576     {
1577         static quint32 Flags(const int type)
1578         {
1579             return (!QTypeInfo<T>::isStatic * QMetaType::MovableType)
1580                     | (QTypeInfo<T>::isComplex * QMetaType::NeedsConstruction)
1581                     | (QTypeInfo<T>::isComplex * QMetaType::NeedsDestruction)
1582                     | (type == QMetaType::QObjectStar ? QMetaType::PointerToQObject : 0)
1583                     | (type == QMetaType::QWidgetStar ? QMetaType::PointerToQObject : 0);
1584         }
1585     };
1586     template<typename T>
1587     struct FlagsImpl<T, /* IsAcceptedType = */ false>
1588     {
1589         static quint32 Flags(const int type)
1590         {
1591             if (QTypeModuleInfo<T>::IsGui)
1592                 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].flags : 0;
1593
1594             if (QTypeModuleInfo<T>::IsWidget)
1595                 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].flags : 0;
1596
1597             // This point can be reached only for known types that definition is not available, for example
1598             // in bootstrap mode. We have no other choice then ignore it.
1599             return 0;
1600         }
1601     };
1602 public:
1603     Flags(const int type)
1604         : m_type(type)
1605     {}
1606     template<typename T>
1607     quint32 delegate(const T*) { return FlagsImpl<T>::Flags(m_type); }
1608     quint32 delegate(const void*) { return 0; }
1609     quint32 delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeFlags(m_type); }
1610 private:
1611     const int m_type;
1612     static quint32 customTypeFlags(const int type)
1613     {
1614         const QVector<QCustomTypeInfo> * const ct = customTypes();
1615         if (Q_UNLIKELY(!ct))
1616             return 0;
1617         QReadLocker locker(customTypesLock());
1618         if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
1619             return 0;
1620         return ct->at(type - QMetaType::User).flags;
1621     }
1622 };
1623 }  // namespace
1624
1625 /*!
1626     \since 5.0
1627
1628     Returns flags of the given \a type.
1629
1630     \sa TypeFlags()
1631 */
1632 QMetaType::TypeFlags QMetaType::typeFlags(int type)
1633 {
1634     Flags flags(type);
1635     return static_cast<QMetaType::TypeFlags>(QMetaTypeSwitcher::switcher<quint32>(flags, type, 0));
1636 }
1637
1638 /*!
1639     \fn int qRegisterMetaType(const char *typeName)
1640     \relates QMetaType
1641     \threadsafe
1642
1643     Registers the type name \a typeName for the type \c{T}. Returns
1644     the internal ID used by QMetaType. Any class or struct that has a
1645     public default constructor, a public copy constructor and a public
1646     destructor can be registered.
1647
1648     This function requires that \c{T} is a fully defined type at the point
1649     where the function is called. For pointer types, it also requires that the
1650     pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able
1651     to register pointers to forward declared types.
1652
1653     After a type has been registered, you can create and destroy
1654     objects of that type dynamically at run-time.
1655
1656     This example registers the class \c{MyClass}:
1657
1658     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 4
1659
1660     This function is useful to register typedefs so they can be used
1661     by QMetaProperty, or in QueuedConnections
1662
1663     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 9
1664
1665     \sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
1666         Q_DECLARE_METATYPE()
1667 */
1668
1669 /*!
1670     \fn int qRegisterMetaTypeStreamOperators(const char *typeName)
1671     \relates QMetaType
1672     \threadsafe
1673
1674     Registers the stream operators for the type \c{T} called \a
1675     typeName.
1676
1677     Afterward, the type can be streamed using QMetaType::load() and
1678     QMetaType::save(). These functions are used when streaming a
1679     QVariant.
1680
1681     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 5
1682
1683     The stream operators should have the following signatures:
1684
1685     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 6
1686
1687     \sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
1688 */
1689
1690 /*! \typedef QMetaType::Deleter
1691     \internal
1692 */
1693 /*! \typedef QMetaType::Creator
1694     \internal
1695 */
1696 /*! \typedef QMetaType::SaveOperator
1697     \internal
1698 */
1699 /*! \typedef QMetaType::LoadOperator
1700     \internal
1701 */
1702 /*! \typedef QMetaType::Destructor
1703     \internal
1704 */
1705 /*! \typedef QMetaType::Constructor
1706     \internal
1707 */
1708
1709 /*!
1710     \fn int qRegisterMetaType()
1711     \relates QMetaType
1712     \threadsafe
1713     \since 4.2
1714
1715     Call this function to register the type \c T. \c T must be declared with
1716     Q_DECLARE_METATYPE(). Returns the meta type Id.
1717
1718     Example:
1719
1720     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 7
1721
1722     To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
1723     sufficient. To use the type \c T in queued signal and slot connections,
1724     \c{qRegisterMetaType<T>()} must be called before the first connection
1725     is established.
1726
1727     Also, to use type \c T with the QObject::property() API,
1728     \c{qRegisterMetaType<T>()} must be called before it is used, typically
1729     in the constructor of the class that uses \c T, or in the \c{main()}
1730     function.
1731
1732     \sa Q_DECLARE_METATYPE()
1733  */
1734
1735 /*! \fn int qMetaTypeId()
1736     \relates QMetaType
1737     \threadsafe
1738     \since 4.1
1739
1740     Returns the meta type id of type \c T at compile time. If the
1741     type was not declared with Q_DECLARE_METATYPE(), compilation will
1742     fail.
1743
1744     Typical usage:
1745
1746     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 8
1747
1748     QMetaType::type() returns the same ID as qMetaTypeId(), but does
1749     a lookup at runtime based on the name of the type.
1750     QMetaType::type() is a bit slower, but compilation succeeds if a
1751     type is not registered.
1752
1753     \sa Q_DECLARE_METATYPE(), QMetaType::type()
1754 */
1755
1756 namespace {
1757 class TypeInfo {
1758     template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1759     struct TypeInfoImpl
1760     {
1761         TypeInfoImpl(const uint /* type */, QMetaTypeInterface &info)
1762         {
1763             QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(T);
1764             info = tmp;
1765         }
1766     };
1767
1768     template<typename T>
1769     struct TypeInfoImpl<T, /* IsAcceptedType = */ false>
1770     {
1771         TypeInfoImpl(const uint type, QMetaTypeInterface &info)
1772         {
1773             if (QTypeModuleInfo<T>::IsGui) {
1774                 if (Q_LIKELY(qMetaTypeGuiHelper))
1775                     info = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType];
1776                 return;
1777             }
1778             if (QTypeModuleInfo<T>::IsWidget) {
1779                 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1780                     info = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType];
1781                 return;
1782             }
1783         }
1784     };
1785 public:
1786     QMetaTypeInterface info;
1787     TypeInfo(const uint type)
1788         : m_type(type)
1789     {
1790         QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_EMPTY();
1791         info = tmp;
1792     }
1793     template<typename T>
1794     void delegate(const T*) { TypeInfoImpl<T>(m_type, info); }
1795     void delegate(const void*) {}
1796     void delegate(const QMetaTypeSwitcher::NotBuiltinType*) { customTypeInfo(m_type); }
1797 private:
1798     void customTypeInfo(const uint type)
1799     {
1800         const QVector<QCustomTypeInfo> * const ct = customTypes();
1801         if (Q_UNLIKELY(!ct))
1802             return;
1803         QReadLocker locker(customTypesLock());
1804         if (Q_LIKELY(uint(ct->count()) > type - QMetaType::User))
1805             info = ct->at(type - QMetaType::User);
1806     }
1807
1808     const uint m_type;
1809 };
1810 } // namespace
1811
1812 QMetaType QMetaType::typeInfo(const int type)
1813 {
1814     TypeInfo typeInfo(type);
1815     QMetaTypeSwitcher::switcher<void>(typeInfo, type, 0);
1816     return typeInfo.info.creator || !type ? QMetaType(QMetaType::NoExtensionFlags
1817                                  , static_cast<const QMetaTypeInterface *>(0) // typeInfo::info is a temporary variable, we can't return address of it.
1818                                  , typeInfo.info.creator
1819                                  , typeInfo.info.deleter
1820                                  , typeInfo.info.saveOp
1821                                  , typeInfo.info.loadOp
1822                                  , typeInfo.info.constructor
1823                                  , typeInfo.info.destructor
1824                                  , typeInfo.info.size
1825                                  , typeInfo.info.flags
1826                                  , type)
1827                 : QMetaType(-1);
1828 }
1829
1830 QMetaType::QMetaType(const int typeId)
1831     : m_typeId(typeId)
1832 {
1833     if (Q_UNLIKELY(typeId == -1)) {
1834         // Constructs invalid QMetaType instance.
1835         m_extensionFlags = 0xffffffff;
1836         Q_ASSERT(!isValid());
1837     } else {
1838         // TODO it can be better.
1839         *this = QMetaType::typeInfo(typeId);
1840         if (m_typeId > 0 && !m_creator) {
1841             m_extensionFlags = 0xffffffff;
1842             m_typeId = -1;
1843         }
1844         if (m_typeId ==  QMetaType::Void) {
1845             m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
1846         }
1847     }
1848 }
1849
1850 QMetaType::QMetaType(const QMetaType &other)
1851     : m_creator(other.m_creator)
1852     , m_deleter(other.m_deleter)
1853     , m_saveOp(other.m_saveOp)
1854     , m_loadOp(other.m_loadOp)
1855     , m_constructor(other.m_constructor)
1856     , m_destructor(other.m_destructor)
1857     , m_extension(other.m_extension) // space reserved for future use
1858     , m_size(other.m_size)
1859     , m_typeFlags(other.m_typeFlags)
1860     , m_extensionFlags(other.m_extensionFlags)
1861     , m_typeId(other.m_typeId)
1862 {}
1863
1864 QMetaType &QMetaType::operator =(const QMetaType &other)
1865 {
1866     m_creator = other.m_creator;
1867     m_deleter = other.m_deleter;
1868     m_saveOp = other.m_saveOp;
1869     m_loadOp = other.m_loadOp;
1870     m_constructor = other.m_constructor;
1871     m_destructor = other.m_destructor;
1872     m_size = other.m_size;
1873     m_typeFlags = other.m_typeFlags;
1874     m_extensionFlags = other.m_extensionFlags;
1875     m_extension = other.m_extension; // space reserved for future use
1876     m_typeId = other.m_typeId;
1877     return *this;
1878 }
1879
1880 void QMetaType::ctor(const QMetaTypeInterface *info)
1881 {
1882     // Special case for Void type, the type is valid but not constructible.
1883     // In future we may consider to remove this assert and extend this function to initialize
1884     // differently m_extensionFlags for different types. Currently it is not needed.
1885     Q_ASSERT(m_typeId == QMetaType::Void);
1886     Q_UNUSED(info);
1887     m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
1888 }
1889
1890 void QMetaType::dtor()
1891 {}
1892
1893 void *QMetaType::createExtended(const void *copy) const
1894 {
1895     Q_UNUSED(copy);
1896     return 0;
1897 }
1898
1899 void QMetaType::destroyExtended(void *data) const
1900 {
1901     Q_UNUSED(data);
1902 }
1903
1904 void *QMetaType::constructExtended(void *where, const void *copy) const
1905 {
1906     Q_UNUSED(where);
1907     Q_UNUSED(copy);
1908     return 0;
1909 }
1910
1911 void QMetaType::destructExtended(void *data) const
1912 {
1913     Q_UNUSED(data);
1914 }
1915
1916 uint QMetaType::sizeExtended() const
1917 {
1918     return 0;
1919 }
1920
1921 QMetaType::TypeFlags QMetaType::flagsExtended() const
1922 {
1923     return 0;
1924 }
1925
1926 QT_END_NAMESPACE