Remove the remaining QT3_SUPPORT code in corelib
[profile/ivi/qtbase.git] / src / corelib / kernel / qmetatype.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qmetatype.h"
43 #include "qobjectdefs.h"
44 #include "qdatetime.h"
45 #include "qbytearray.h"
46 #include "qreadwritelock.h"
47 #include "qstring.h"
48 #include "qstringlist.h"
49 #include "qvector.h"
50 #include "qlocale.h"
51 #include "qeasingcurve.h"
52
53 #ifdef QT_BOOTSTRAPPED
54 # ifndef QT_NO_GEOM_VARIANT
55 #  define QT_NO_GEOM_VARIANT
56 # endif
57 #else
58 #  include "qbitarray.h"
59 #  include "qurl.h"
60 #  include "qvariant.h"
61 #endif
62
63 #ifndef QT_NO_GEOM_VARIANT
64 # include "qsize.h"
65 # include "qpoint.h"
66 # include "qrect.h"
67 # include "qline.h"
68 #endif
69
70 QT_BEGIN_NAMESPACE
71
72 #define NS(x) QT_PREPEND_NAMESPACE(x)
73
74 /*!
75     \macro Q_DECLARE_METATYPE(Type)
76     \relates QMetaType
77
78     This macro makes the type \a Type known to QMetaType as long as it
79     provides a public default constructor, a public copy constructor and
80     a public destructor.
81     It is needed to use the type \a Type as a custom type in QVariant.
82
83     Ideally, this macro should be placed below the declaration of
84     the class or struct. If that is not possible, it can be put in
85     a private header file which has to be included every time that
86     type is used in a QVariant.
87
88     Adding a Q_DECLARE_METATYPE() makes the type known to all template
89     based functions, including QVariant. Note that if you intend to
90     use the type in \e queued signal and slot connections or in
91     QObject's property system, you also have to call
92     qRegisterMetaType() since the names are resolved at runtime.
93
94     This example shows a typical use case of Q_DECLARE_METATYPE():
95
96     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 0
97
98     If \c MyStruct is in a namespace, the Q_DECLARE_METATYPE() macro
99     has to be outside the namespace:
100
101     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 1
102
103     Since \c{MyStruct} is now known to QMetaType, it can be used in QVariant:
104
105     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 2
106
107     \sa qRegisterMetaType()
108 */
109
110 /*!
111     \enum QMetaType::Type
112
113     These are the built-in types supported by QMetaType:
114
115     \value Void \c void
116     \value Bool \c bool
117     \value Int \c int
118     \value UInt \c{unsigned int}
119     \value Double \c double
120     \value QChar QChar
121     \value QString QString
122     \value QByteArray QByteArray
123
124     \value VoidStar \c{void *}
125     \value Long \c{long}
126     \value LongLong LongLong
127     \value Short \c{short}
128     \value Char \c{char}
129     \value ULong \c{unsigned long}
130     \value ULongLong ULongLong
131     \value UShort \c{unsigned short}
132     \value UChar \c{unsigned char}
133     \value Float \c float
134     \value QObjectStar QObject *
135     \value QWidgetStar QWidget *
136     \value QVariant QVariant
137
138     \value QColorGroup QColorGroup
139     \value QCursor QCursor
140     \value QDate QDate
141     \value QSize QSize
142     \value QTime QTime
143     \value QVariantList QVariantList
144     \value QPolygon QPolygon
145     \value QColor QColor
146     \value QSizeF QSizeF
147     \value QRectF QRectF
148     \value QLine QLine
149     \value QTextLength QTextLength
150     \value QStringList QStringList
151     \value QVariantMap QVariantMap
152     \value QVariantHash QVariantHash
153     \value QIcon QIcon
154     \value QPen QPen
155     \value QLineF QLineF
156     \value QTextFormat QTextFormat
157     \value QRect QRect
158     \value QPoint QPoint
159     \value QUrl QUrl
160     \value QRegExp QRegExp
161     \value QDateTime QDateTime
162     \value QPointF QPointF
163     \value QPalette QPalette
164     \value QFont QFont
165     \value QBrush QBrush
166     \value QRegion QRegion
167     \value QBitArray QBitArray
168     \value QImage QImage
169     \value QKeySequence QKeySequence
170     \value QSizePolicy QSizePolicy
171     \value QPixmap QPixmap
172     \value QLocale QLocale
173     \value QBitmap QBitmap
174     \value QMatrix QMatrix
175     \value QTransform QTransform
176     \value QMatrix4x4 QMatrix4x4
177     \value QVector2D QVector2D
178     \value QVector3D QVector3D
179     \value QVector4D QVector4D
180     \value QQuaternion QQuaternion
181     \value QEasingCurve QEasingCurve
182
183     \value User  Base value for user types
184
185     \omitvalue FirstCoreExtType
186     \omitvalue FirstGuiType
187     \omitvalue LastCoreExtType
188     \omitvalue LastCoreType
189     \omitvalue LastGuiType
190     \omitvalue QReal
191
192     Additional types can be registered using Q_DECLARE_METATYPE().
193
194     \sa type(), typeName()
195 */
196
197 /*!
198     \class QMetaType
199     \brief The QMetaType class manages named types in the meta-object system.
200
201     \ingroup objectmodel
202     \threadsafe
203
204     The class is used as a helper to marshall types in QVariant and
205     in queued signals and slots connections. It associates a type
206     name to a type so that it can be created and destructed
207     dynamically at run-time. Declare new types with Q_DECLARE_METATYPE()
208     to make them available to QVariant and other template-based functions.
209     Call qRegisterMetaType() to make type available to non-template based
210     functions, such as the queued signal and slot connections.
211
212     Any class or struct that has a public default
213     constructor, a public copy constructor, and a public destructor
214     can be registered.
215
216     The following code allocates and destructs an instance of
217     \c{MyClass}:
218
219     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 3
220
221     If we want the stream operators \c operator<<() and \c
222     operator>>() to work on QVariant objects that store custom types,
223     the custom type must provide \c operator<<() and \c operator>>()
224     operators.
225
226     \sa Q_DECLARE_METATYPE(), QVariant::setValue(), QVariant::value(), QVariant::fromValue()
227 */
228
229 #define QT_ADD_STATIC_METATYPE(STR, TP) \
230     { STR, sizeof(STR) - 1, TP }
231
232 /* Note: these MUST be in the order of the enums */
233 static const struct { const char * typeName; int typeNameLength; int type; } types[] = {
234
235     /* All Core types */
236     QT_ADD_STATIC_METATYPE("void", QMetaType::Void),
237     QT_ADD_STATIC_METATYPE("bool", QMetaType::Bool),
238     QT_ADD_STATIC_METATYPE("int", QMetaType::Int),
239     QT_ADD_STATIC_METATYPE("uint", QMetaType::UInt),
240     QT_ADD_STATIC_METATYPE("qlonglong", QMetaType::LongLong),
241     QT_ADD_STATIC_METATYPE("qulonglong", QMetaType::ULongLong),
242     QT_ADD_STATIC_METATYPE("double", QMetaType::Double),
243     QT_ADD_STATIC_METATYPE("QChar", QMetaType::QChar),
244     QT_ADD_STATIC_METATYPE("QVariantMap", QMetaType::QVariantMap),
245     QT_ADD_STATIC_METATYPE("QVariantList", QMetaType::QVariantList),
246     QT_ADD_STATIC_METATYPE("QString", QMetaType::QString),
247     QT_ADD_STATIC_METATYPE("QStringList", QMetaType::QStringList),
248     QT_ADD_STATIC_METATYPE("QByteArray", QMetaType::QByteArray),
249     QT_ADD_STATIC_METATYPE("QBitArray", QMetaType::QBitArray),
250     QT_ADD_STATIC_METATYPE("QDate", QMetaType::QDate),
251     QT_ADD_STATIC_METATYPE("QTime", QMetaType::QTime),
252     QT_ADD_STATIC_METATYPE("QDateTime", QMetaType::QDateTime),
253     QT_ADD_STATIC_METATYPE("QUrl", QMetaType::QUrl),
254     QT_ADD_STATIC_METATYPE("QLocale", QMetaType::QLocale),
255     QT_ADD_STATIC_METATYPE("QRect", QMetaType::QRect),
256     QT_ADD_STATIC_METATYPE("QRectF", QMetaType::QRectF),
257     QT_ADD_STATIC_METATYPE("QSize", QMetaType::QSize),
258     QT_ADD_STATIC_METATYPE("QSizeF", QMetaType::QSizeF),
259     QT_ADD_STATIC_METATYPE("QLine", QMetaType::QLine),
260     QT_ADD_STATIC_METATYPE("QLineF", QMetaType::QLineF),
261     QT_ADD_STATIC_METATYPE("QPoint", QMetaType::QPoint),
262     QT_ADD_STATIC_METATYPE("QPointF", QMetaType::QPointF),
263     QT_ADD_STATIC_METATYPE("QRegExp", QMetaType::QRegExp),
264     QT_ADD_STATIC_METATYPE("QVariantHash", QMetaType::QVariantHash),
265     QT_ADD_STATIC_METATYPE("QEasingCurve", QMetaType::QEasingCurve),
266
267     /* All GUI types */
268     QT_ADD_STATIC_METATYPE("QColorGroup", 63),
269     QT_ADD_STATIC_METATYPE("QFont", QMetaType::QFont),
270     QT_ADD_STATIC_METATYPE("QPixmap", QMetaType::QPixmap),
271     QT_ADD_STATIC_METATYPE("QBrush", QMetaType::QBrush),
272     QT_ADD_STATIC_METATYPE("QColor", QMetaType::QColor),
273     QT_ADD_STATIC_METATYPE("QPalette", QMetaType::QPalette),
274     QT_ADD_STATIC_METATYPE("QIcon", QMetaType::QIcon),
275     QT_ADD_STATIC_METATYPE("QImage", QMetaType::QImage),
276     QT_ADD_STATIC_METATYPE("QPolygon", QMetaType::QPolygon),
277     QT_ADD_STATIC_METATYPE("QRegion", QMetaType::QRegion),
278     QT_ADD_STATIC_METATYPE("QBitmap", QMetaType::QBitmap),
279     QT_ADD_STATIC_METATYPE("QCursor", QMetaType::QCursor),
280     QT_ADD_STATIC_METATYPE("QSizePolicy", QMetaType::QSizePolicy),
281     QT_ADD_STATIC_METATYPE("QKeySequence", QMetaType::QKeySequence),
282     QT_ADD_STATIC_METATYPE("QPen", QMetaType::QPen),
283     QT_ADD_STATIC_METATYPE("QTextLength", QMetaType::QTextLength),
284     QT_ADD_STATIC_METATYPE("QTextFormat", QMetaType::QTextFormat),
285     QT_ADD_STATIC_METATYPE("QMatrix", QMetaType::QMatrix),
286     QT_ADD_STATIC_METATYPE("QTransform", QMetaType::QTransform),
287     QT_ADD_STATIC_METATYPE("QMatrix4x4", QMetaType::QMatrix4x4),
288     QT_ADD_STATIC_METATYPE("QVector2D", QMetaType::QVector2D),
289     QT_ADD_STATIC_METATYPE("QVector3D", QMetaType::QVector3D),
290     QT_ADD_STATIC_METATYPE("QVector4D", QMetaType::QVector4D),
291     QT_ADD_STATIC_METATYPE("QQuaternion", QMetaType::QQuaternion),
292
293     /* All Metatype builtins */
294     QT_ADD_STATIC_METATYPE("void*", QMetaType::VoidStar),
295     QT_ADD_STATIC_METATYPE("long", QMetaType::Long),
296     QT_ADD_STATIC_METATYPE("short", QMetaType::Short),
297     QT_ADD_STATIC_METATYPE("char", QMetaType::Char),
298     QT_ADD_STATIC_METATYPE("ulong", QMetaType::ULong),
299     QT_ADD_STATIC_METATYPE("ushort", QMetaType::UShort),
300     QT_ADD_STATIC_METATYPE("uchar", QMetaType::UChar),
301     QT_ADD_STATIC_METATYPE("float", QMetaType::Float),
302     QT_ADD_STATIC_METATYPE("QObject*", QMetaType::QObjectStar),
303     QT_ADD_STATIC_METATYPE("QWidget*", QMetaType::QWidgetStar),
304     QT_ADD_STATIC_METATYPE("QVariant", QMetaType::QVariant),
305
306     /* Type aliases - order doesn't matter */
307     QT_ADD_STATIC_METATYPE("unsigned long", QMetaType::ULong),
308     QT_ADD_STATIC_METATYPE("unsigned int", QMetaType::UInt),
309     QT_ADD_STATIC_METATYPE("unsigned short", QMetaType::UShort),
310     QT_ADD_STATIC_METATYPE("unsigned char", QMetaType::UChar),
311     QT_ADD_STATIC_METATYPE("long long", QMetaType::LongLong),
312     QT_ADD_STATIC_METATYPE("unsigned long long", QMetaType::ULongLong),
313     QT_ADD_STATIC_METATYPE("qint8", QMetaType::Char),
314     QT_ADD_STATIC_METATYPE("signed char", QMetaType::Char),
315     QT_ADD_STATIC_METATYPE("quint8", QMetaType::UChar),
316     QT_ADD_STATIC_METATYPE("qint16", QMetaType::Short),
317     QT_ADD_STATIC_METATYPE("quint16", QMetaType::UShort),
318     QT_ADD_STATIC_METATYPE("qint32", QMetaType::Int),
319     QT_ADD_STATIC_METATYPE("quint32", QMetaType::UInt),
320     QT_ADD_STATIC_METATYPE("qint64", QMetaType::LongLong),
321     QT_ADD_STATIC_METATYPE("quint64", QMetaType::ULongLong),
322     QT_ADD_STATIC_METATYPE("QList<QVariant>", QMetaType::QVariantList),
323     QT_ADD_STATIC_METATYPE("QMap<QString,QVariant>", QMetaType::QVariantMap),
324     QT_ADD_STATIC_METATYPE("QHash<QString,QVariant>", QMetaType::QVariantHash),
325     // let QMetaTypeId2 figure out the type at compile time
326     QT_ADD_STATIC_METATYPE("qreal", QMetaTypeId2<qreal>::MetaType),
327
328     {0, 0, QMetaType::Void}
329 };
330
331 struct QMetaTypeGuiHelper
332 {
333     QMetaType::Constructor constr;
334     QMetaType::Destructor destr;
335 #ifndef QT_NO_DATASTREAM
336     QMetaType::SaveOperator saveOp;
337     QMetaType::LoadOperator loadOp;
338 #endif
339 };
340 Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeGuiHelper = 0;
341
342 class QCustomTypeInfo
343 {
344 public:
345     QCustomTypeInfo() : typeName(), constr(0), destr(0)
346 #ifndef QT_NO_DATASTREAM
347     , saveOp(0), loadOp(0)
348 #endif
349     {}
350
351     QByteArray typeName;
352     QMetaType::Constructor constr;
353     QMetaType::Destructor destr;
354 #ifndef QT_NO_DATASTREAM
355     QMetaType::SaveOperator saveOp;
356     QMetaType::LoadOperator loadOp;
357 #endif
358     int alias;
359 };
360
361 Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
362 Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
363 Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
364
365 #ifndef QT_NO_DATASTREAM
366 /*! \internal
367 */
368 void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
369                                         LoadOperator loadOp)
370 {
371     int idx = type(typeName);
372     if (!idx)
373         return;
374     registerStreamOperators(idx, saveOp, loadOp);
375 }
376
377 /*! \internal
378 */
379 void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
380                                         LoadOperator loadOp)
381 {
382     if (idx < User)
383         return; //builtin types should not be registered;
384     QVector<QCustomTypeInfo> *ct = customTypes();
385     if (!ct)
386         return;
387     QWriteLocker locker(customTypesLock());
388     QCustomTypeInfo &inf = (*ct)[idx - User];
389     inf.saveOp = saveOp;
390     inf.loadOp = loadOp;
391 }
392 #endif // QT_NO_DATASTREAM
393
394 /*!
395     Returns the type name associated with the given \a type, or 0 if no
396     matching type was found. The returned pointer must not be deleted.
397
398     \sa type(), isRegistered(), Type
399 */
400 const char *QMetaType::typeName(int type)
401 {
402     enum { GuiTypeCount = LastGuiType - FirstGuiType };
403
404     if (type >= 0 && type <= LastCoreType) {
405         return types[type].typeName;
406     } else if (type >= FirstGuiType && type <= LastGuiType) {
407         return types[type - FirstGuiType + LastCoreType + 1].typeName;
408     } else if (type >= FirstCoreExtType && type <= LastCoreExtType) {
409         return types[type - FirstCoreExtType + GuiTypeCount + LastCoreType + 2].typeName;
410     } else if (type >= User) {
411         const QVector<QCustomTypeInfo> * const ct = customTypes();
412         QReadLocker locker(customTypesLock());
413         return ct && ct->count() > type - User && !ct->at(type - User).typeName.isEmpty()
414                 ? ct->at(type - User).typeName.constData()
415                 : static_cast<const char *>(0);
416     }
417
418     return 0;
419 }
420
421 /*! \internal
422     Similar to QMetaType::type(), but only looks in the static set of types.
423 */
424 static inline int qMetaTypeStaticType(const char *typeName, int length)
425 {
426     int i = 0;
427     while (types[i].typeName && ((length != types[i].typeNameLength)
428                                  || strcmp(typeName, types[i].typeName))) {
429         ++i;
430     }
431     return types[i].type;
432 }
433
434 /*! \internal
435     Similar to QMetaType::type(), but only looks in the custom set of
436     types, and doesn't lock the mutex.
437 */
438 static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
439 {
440     const QVector<QCustomTypeInfo> * const ct = customTypes();
441     if (!ct)
442         return 0;
443
444     for (int v = 0; v < ct->count(); ++v) {
445         const QCustomTypeInfo &customInfo = ct->at(v);
446         if ((length == customInfo.typeName.size())
447             && !strcmp(typeName, customInfo.typeName.constData())) {
448             if (customInfo.alias >= 0)
449                 return customInfo.alias;
450             return v + QMetaType::User;
451         }
452     }
453     return 0;
454 }
455
456 /*! \internal
457
458     Registers a user type for marshalling, with \a typeName, a \a
459     destructor, and a \a constructor. Returns the type's handle,
460     or -1 if the type could not be registered.
461  */
462 int QMetaType::registerType(const char *typeName, Destructor destructor,
463                             Constructor constructor)
464 {
465     QVector<QCustomTypeInfo> *ct = customTypes();
466     if (!ct || !typeName || !destructor || !constructor)
467         return -1;
468
469 #ifdef QT_NO_QOBJECT
470     NS(QByteArray) normalizedTypeName = typeName;
471 #else
472     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
473 #endif
474
475     int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
476                                   normalizedTypeName.size());
477
478     if (!idx) {
479         QWriteLocker locker(customTypesLock());
480         idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
481                                            normalizedTypeName.size());
482         if (!idx) {
483             QCustomTypeInfo inf;
484             inf.typeName = normalizedTypeName;
485             inf.constr = constructor;
486             inf.destr = destructor;
487             inf.alias = -1;
488             idx = ct->size() + User;
489             ct->append(inf);
490         }
491     }
492     return idx;
493 }
494
495 /*! \internal
496     \since 4.7
497
498     Registers a user type for marshalling, as an alias of another type (typedef)
499 */
500 int QMetaType::registerTypedef(const char* typeName, int aliasId)
501 {
502     QVector<QCustomTypeInfo> *ct = customTypes();
503     if (!ct || !typeName)
504         return -1;
505
506 #ifdef QT_NO_QOBJECT
507     NS(QByteArray) normalizedTypeName = typeName;
508 #else
509     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
510 #endif
511
512     int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
513                                   normalizedTypeName.size());
514
515     if (idx) {
516         Q_ASSERT(idx == aliasId);
517         return idx;
518     }
519
520     QWriteLocker locker(customTypesLock());
521     idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
522                                            normalizedTypeName.size());
523
524     if (idx)
525         return idx;
526
527     QCustomTypeInfo inf;
528     inf.typeName = normalizedTypeName;
529     inf.alias = aliasId;
530     inf.constr = 0;
531     inf.destr = 0;
532     ct->append(inf);
533     return aliasId;
534 }
535
536 /*!
537     \since 4.4
538
539     Unregisters a user type, with \a typeName.
540
541     \sa type(), typeName()
542  */
543 void QMetaType::unregisterType(const char *typeName)
544 {
545     QVector<QCustomTypeInfo> *ct = customTypes();
546     if (!ct || !typeName)
547         return;
548
549 #ifdef QT_NO_QOBJECT
550     NS(QByteArray) normalizedTypeName = typeName;
551 #else
552     NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
553 #endif
554     QWriteLocker locker(customTypesLock());
555     for (int v = 0; v < ct->count(); ++v) {
556         if (ct->at(v).typeName == typeName) {
557             QCustomTypeInfo &inf = (*ct)[v];
558             inf.typeName.clear();
559             inf.constr = 0;
560             inf.destr = 0;
561             inf.alias = -1;
562         }
563     }
564 }
565
566 /*!
567     Returns true if the datatype with ID \a type is registered;
568     otherwise returns false.
569
570     \sa type(), typeName(), Type
571 */
572 bool QMetaType::isRegistered(int type)
573 {
574     if (type >= 0 && type < User) {
575         // predefined type
576         return true;
577     }
578     QReadLocker locker(customTypesLock());
579     const QVector<QCustomTypeInfo> * const ct = customTypes();
580     return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
581 }
582
583 /*!
584     Returns a handle to the type called \a typeName, or 0 if there is
585     no such type.
586
587     \sa isRegistered(), typeName(), Type
588 */
589 int QMetaType::type(const char *typeName)
590 {
591     int length = qstrlen(typeName);
592     if (!length)
593         return 0;
594     int type = qMetaTypeStaticType(typeName, length);
595     if (!type) {
596         QReadLocker locker(customTypesLock());
597         type = qMetaTypeCustomType_unlocked(typeName, length);
598 #ifndef QT_NO_QOBJECT
599         if (!type) {
600             const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
601             type = qMetaTypeStaticType(normalizedTypeName.constData(),
602                                        normalizedTypeName.size());
603             if (!type) {
604                 type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
605                                                     normalizedTypeName.size());
606             }
607         }
608 #endif
609     }
610     return type;
611 }
612
613 #ifndef QT_NO_DATASTREAM
614 /*!
615     Writes the object pointed to by \a data with the ID \a type to
616     the given \a stream. Returns true if the object is saved
617     successfully; otherwise returns false.
618
619     The type must have been registered with qRegisterMetaType() and
620     qRegisterMetaTypeStreamOperators() beforehand.
621
622     Normally, you should not need to call this function directly.
623     Instead, use QVariant's \c operator<<(), which relies on save()
624     to stream custom types.
625
626     \sa load(), qRegisterMetaTypeStreamOperators()
627 */
628 bool QMetaType::save(QDataStream &stream, int type, const void *data)
629 {
630     if (!data || !isRegistered(type))
631         return false;
632
633     switch(type) {
634     case QMetaType::Void:
635     case QMetaType::VoidStar:
636     case QMetaType::QObjectStar:
637     case QMetaType::QWidgetStar:
638         return false;
639     case QMetaType::Long:
640         stream << qlonglong(*static_cast<const long *>(data));
641         break;
642     case QMetaType::Int:
643         stream << *static_cast<const int *>(data);
644         break;
645     case QMetaType::Short:
646         stream << *static_cast<const short *>(data);
647         break;
648     case QMetaType::Char:
649         // force a char to be signed
650         stream << *static_cast<const signed char *>(data);
651         break;
652     case QMetaType::ULong:
653         stream << qulonglong(*static_cast<const ulong *>(data));
654         break;
655     case QMetaType::UInt:
656         stream << *static_cast<const uint *>(data);
657         break;
658     case QMetaType::LongLong:
659         stream << *static_cast<const qlonglong *>(data);
660         break;
661     case QMetaType::ULongLong:
662         stream << *static_cast<const qulonglong *>(data);
663         break;
664     case QMetaType::UShort:
665         stream << *static_cast<const ushort *>(data);
666         break;
667     case QMetaType::UChar:
668         stream << *static_cast<const uchar *>(data);
669         break;
670     case QMetaType::Bool:
671         stream << qint8(*static_cast<const bool *>(data));
672         break;
673     case QMetaType::Float:
674         stream << *static_cast<const float *>(data);
675         break;
676     case QMetaType::Double:
677         stream << *static_cast<const double *>(data);
678         break;
679     case QMetaType::QChar:
680         stream << *static_cast<const NS(QChar) *>(data);
681         break;
682 #ifndef QT_BOOTSTRAPPED
683     case QMetaType::QVariantMap:
684         stream << *static_cast<const NS(QVariantMap)*>(data);
685         break;
686     case QMetaType::QVariantHash:
687         stream << *static_cast<const NS(QVariantHash)*>(data);
688         break;
689     case QMetaType::QVariantList:
690         stream << *static_cast<const NS(QVariantList)*>(data);
691         break;
692     case QMetaType::QVariant:
693         stream << *static_cast<const NS(QVariant)*>(data);
694         break;
695 #endif
696     case QMetaType::QByteArray:
697         stream << *static_cast<const NS(QByteArray)*>(data);
698         break;
699     case QMetaType::QString:
700         stream << *static_cast<const NS(QString)*>(data);
701         break;
702     case QMetaType::QStringList:
703         stream << *static_cast<const NS(QStringList)*>(data);
704         break;
705 #ifndef QT_BOOTSTRAPPED
706     case QMetaType::QBitArray:
707         stream << *static_cast<const NS(QBitArray)*>(data);
708         break;
709 #endif
710     case QMetaType::QDate:
711         stream << *static_cast<const NS(QDate)*>(data);
712         break;
713     case QMetaType::QTime:
714         stream << *static_cast<const NS(QTime)*>(data);
715         break;
716     case QMetaType::QDateTime:
717         stream << *static_cast<const NS(QDateTime)*>(data);
718         break;
719 #ifndef QT_BOOTSTRAPPED
720     case QMetaType::QUrl:
721         stream << *static_cast<const NS(QUrl)*>(data);
722         break;
723 #endif
724     case QMetaType::QLocale:
725         stream << *static_cast<const NS(QLocale)*>(data);
726         break;
727 #ifndef QT_NO_GEOM_VARIANT
728     case QMetaType::QRect:
729         stream << *static_cast<const NS(QRect)*>(data);
730         break;
731     case QMetaType::QRectF:
732         stream << *static_cast<const NS(QRectF)*>(data);
733         break;
734     case QMetaType::QSize:
735         stream << *static_cast<const NS(QSize)*>(data);
736         break;
737     case QMetaType::QSizeF:
738         stream << *static_cast<const NS(QSizeF)*>(data);
739         break;
740     case QMetaType::QLine:
741         stream << *static_cast<const NS(QLine)*>(data);
742         break;
743     case QMetaType::QLineF:
744         stream << *static_cast<const NS(QLineF)*>(data);
745         break;
746     case QMetaType::QPoint:
747         stream << *static_cast<const NS(QPoint)*>(data);
748         break;
749     case QMetaType::QPointF:
750         stream << *static_cast<const NS(QPointF)*>(data);
751         break;
752 #endif
753 #ifndef QT_NO_REGEXP
754     case QMetaType::QRegExp:
755         stream << *static_cast<const NS(QRegExp)*>(data);
756         break;
757 #endif
758 #ifndef QT_BOOTSTRAPPED
759     case QMetaType::QEasingCurve:
760         stream << *static_cast<const NS(QEasingCurve)*>(data);
761         break;
762 #endif
763     case QMetaType::QFont:
764     case QMetaType::QPixmap:
765     case QMetaType::QBrush:
766     case QMetaType::QColor:
767     case QMetaType::QPalette:
768     case QMetaType::QIcon:
769     case QMetaType::QImage:
770     case QMetaType::QPolygon:
771     case QMetaType::QRegion:
772     case QMetaType::QBitmap:
773     case QMetaType::QCursor:
774     case QMetaType::QSizePolicy:
775     case QMetaType::QKeySequence:
776     case QMetaType::QPen:
777     case QMetaType::QTextLength:
778     case QMetaType::QTextFormat:
779     case QMetaType::QMatrix:
780     case QMetaType::QTransform:
781     case QMetaType::QMatrix4x4:
782     case QMetaType::QVector2D:
783     case QMetaType::QVector3D:
784     case QMetaType::QVector4D:
785     case QMetaType::QQuaternion:
786         if (!qMetaTypeGuiHelper)
787             return false;
788         qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
789         break;
790     default: {
791         const QVector<QCustomTypeInfo> * const ct = customTypes();
792         if (!ct)
793             return false;
794
795         SaveOperator saveOp = 0;
796         {
797             QReadLocker locker(customTypesLock());
798             saveOp = ct->at(type - User).saveOp;
799         }
800
801         if (!saveOp)
802             return false;
803         saveOp(stream, data);
804         break; }
805     }
806
807     return true;
808 }
809
810 /*!
811     Reads the object of the specified \a type from the given \a
812     stream into \a data. Returns true if the object is loaded
813     successfully; otherwise returns false.
814
815     The type must have been registered with qRegisterMetaType() and
816     qRegisterMetaTypeStreamOperators() beforehand.
817
818     Normally, you should not need to call this function directly.
819     Instead, use QVariant's \c operator>>(), which relies on load()
820     to stream custom types.
821
822     \sa save(), qRegisterMetaTypeStreamOperators()
823 */
824 bool QMetaType::load(QDataStream &stream, int type, void *data)
825 {
826     if (!data || !isRegistered(type))
827         return false;
828
829     switch(type) {
830     case QMetaType::Void:
831     case QMetaType::VoidStar:
832     case QMetaType::QObjectStar:
833     case QMetaType::QWidgetStar:
834         return false;
835     case QMetaType::Long: {
836         qlonglong l;
837         stream >> l;
838         *static_cast<long *>(data) = long(l);
839         break; }
840     case QMetaType::Int:
841         stream >> *static_cast<int *>(data);
842         break;
843     case QMetaType::Short:
844         stream >> *static_cast<short *>(data);
845         break;
846     case QMetaType::Char:
847         // force a char to be signed
848         stream >> *static_cast<signed char *>(data);
849         break;
850     case QMetaType::ULong: {
851         qulonglong ul;
852         stream >> ul;
853         *static_cast<ulong *>(data) = ulong(ul);
854         break; }
855     case QMetaType::UInt:
856         stream >> *static_cast<uint *>(data);
857         break;
858     case QMetaType::LongLong:
859         stream >> *static_cast<qlonglong *>(data);
860         break;
861     case QMetaType::ULongLong:
862         stream >> *static_cast<qulonglong *>(data);
863         break;
864     case QMetaType::UShort:
865         stream >> *static_cast<ushort *>(data);
866         break;
867     case QMetaType::UChar:
868         stream >> *static_cast<uchar *>(data);
869         break;
870     case QMetaType::Bool: {
871         qint8 b;
872         stream >> b;
873         *static_cast<bool *>(data) = b;
874         break; }
875     case QMetaType::Float:
876         stream >> *static_cast<float *>(data);
877         break;
878     case QMetaType::Double:
879         stream >> *static_cast<double *>(data);
880         break;
881     case QMetaType::QChar:
882         stream >> *static_cast< NS(QChar)*>(data);
883         break;
884 #ifndef QT_BOOTSTRAPPED
885     case QMetaType::QVariantMap:
886         stream >> *static_cast< NS(QVariantMap)*>(data);
887         break;
888     case QMetaType::QVariantHash:
889         stream >> *static_cast< NS(QVariantHash)*>(data);
890         break;
891     case QMetaType::QVariantList:
892         stream >> *static_cast< NS(QVariantList)*>(data);
893         break;
894     case QMetaType::QVariant:
895         stream >> *static_cast< NS(QVariant)*>(data);
896         break;
897 #endif
898     case QMetaType::QByteArray:
899         stream >> *static_cast< NS(QByteArray)*>(data);
900         break;
901     case QMetaType::QString:
902         stream >> *static_cast< NS(QString)*>(data);
903         break;
904     case QMetaType::QStringList:
905         stream >> *static_cast< NS(QStringList)*>(data);
906         break;
907 #ifndef QT_BOOTSTRAPPED
908     case QMetaType::QBitArray:
909         stream >> *static_cast< NS(QBitArray)*>(data);
910         break;
911 #endif
912     case QMetaType::QDate:
913         stream >> *static_cast< NS(QDate)*>(data);
914         break;
915     case QMetaType::QTime:
916         stream >> *static_cast< NS(QTime)*>(data);
917         break;
918     case QMetaType::QDateTime:
919         stream >> *static_cast< NS(QDateTime)*>(data);
920         break;
921 #ifndef QT_BOOTSTRAPPED
922     case QMetaType::QUrl:
923         stream >> *static_cast< NS(QUrl)*>(data);
924         break;
925 #endif
926     case QMetaType::QLocale:
927         stream >> *static_cast< NS(QLocale)*>(data);
928         break;
929 #ifndef QT_NO_GEOM_VARIANT
930     case QMetaType::QRect:
931         stream >> *static_cast< NS(QRect)*>(data);
932         break;
933     case QMetaType::QRectF:
934         stream >> *static_cast< NS(QRectF)*>(data);
935         break;
936     case QMetaType::QSize:
937         stream >> *static_cast< NS(QSize)*>(data);
938         break;
939     case QMetaType::QSizeF:
940         stream >> *static_cast< NS(QSizeF)*>(data);
941         break;
942     case QMetaType::QLine:
943         stream >> *static_cast< NS(QLine)*>(data);
944         break;
945     case QMetaType::QLineF:
946         stream >> *static_cast< NS(QLineF)*>(data);
947         break;
948     case QMetaType::QPoint:
949         stream >> *static_cast< NS(QPoint)*>(data);
950         break;
951     case QMetaType::QPointF:
952         stream >> *static_cast< NS(QPointF)*>(data);
953         break;
954 #endif
955 #ifndef QT_NO_REGEXP
956     case QMetaType::QRegExp:
957         stream >> *static_cast< NS(QRegExp)*>(data);
958         break;
959 #endif
960 #ifndef QT_BOOTSTRAPPED
961     case QMetaType::QEasingCurve:
962         stream >> *static_cast< NS(QEasingCurve)*>(data);
963         break;
964 #endif
965     case QMetaType::QFont:
966     case QMetaType::QPixmap:
967     case QMetaType::QBrush:
968     case QMetaType::QColor:
969     case QMetaType::QPalette:
970     case QMetaType::QIcon:
971     case QMetaType::QImage:
972     case QMetaType::QPolygon:
973     case QMetaType::QRegion:
974     case QMetaType::QBitmap:
975     case QMetaType::QCursor:
976     case QMetaType::QSizePolicy:
977     case QMetaType::QKeySequence:
978     case QMetaType::QPen:
979     case QMetaType::QTextLength:
980     case QMetaType::QTextFormat:
981     case QMetaType::QMatrix:
982     case QMetaType::QTransform:
983     case QMetaType::QMatrix4x4:
984     case QMetaType::QVector2D:
985     case QMetaType::QVector3D:
986     case QMetaType::QVector4D:
987     case QMetaType::QQuaternion:
988         if (!qMetaTypeGuiHelper)
989             return false;
990         qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
991         break;
992     default: {
993         const QVector<QCustomTypeInfo> * const ct = customTypes();
994         if (!ct)
995             return false;
996
997         LoadOperator loadOp = 0;
998         {
999             QReadLocker locker(customTypesLock());
1000             loadOp = ct->at(type - User).loadOp;
1001         }
1002
1003         if (!loadOp)
1004             return false;
1005         loadOp(stream, data);
1006         break; }
1007     }
1008     return true;
1009 }
1010 #endif // QT_NO_DATASTREAM
1011
1012 /*!
1013     Returns a copy of \a copy, assuming it is of type \a type. If \a
1014     copy is zero, creates a default type.
1015
1016     \sa destroy(), isRegistered(), Type
1017 */
1018 void *QMetaType::construct(int type, const void *copy)
1019 {
1020     if (copy) {
1021         switch(type) {
1022         case QMetaType::VoidStar:
1023         case QMetaType::QObjectStar:
1024         case QMetaType::QWidgetStar:
1025             return new void *(*static_cast<void* const *>(copy));
1026         case QMetaType::Long:
1027             return new long(*static_cast<const long*>(copy));
1028         case QMetaType::Int:
1029             return new int(*static_cast<const int*>(copy));
1030         case QMetaType::Short:
1031             return new short(*static_cast<const short*>(copy));
1032         case QMetaType::Char:
1033             return new char(*static_cast<const char*>(copy));
1034         case QMetaType::ULong:
1035             return new ulong(*static_cast<const ulong*>(copy));
1036         case QMetaType::UInt:
1037             return new uint(*static_cast<const uint*>(copy));
1038         case QMetaType::LongLong:
1039             return new qlonglong(*static_cast<const qlonglong*>(copy));
1040         case QMetaType::ULongLong:
1041             return new qulonglong(*static_cast<const qulonglong*>(copy));
1042         case QMetaType::UShort:
1043             return new ushort(*static_cast<const ushort*>(copy));
1044         case QMetaType::UChar:
1045             return new uchar(*static_cast<const uchar*>(copy));
1046         case QMetaType::Bool:
1047             return new bool(*static_cast<const bool*>(copy));
1048         case QMetaType::Float:
1049             return new float(*static_cast<const float*>(copy));
1050         case QMetaType::Double:
1051             return new double(*static_cast<const double*>(copy));
1052         case QMetaType::QChar:
1053             return new NS(QChar)(*static_cast<const NS(QChar)*>(copy));
1054 #ifndef QT_BOOTSTRAPPED
1055         case QMetaType::QVariantMap:
1056             return new NS(QVariantMap)(*static_cast<const NS(QVariantMap)*>(copy));
1057         case QMetaType::QVariantHash:
1058             return new NS(QVariantHash)(*static_cast<const NS(QVariantHash)*>(copy));
1059         case QMetaType::QVariantList:
1060             return new NS(QVariantList)(*static_cast<const NS(QVariantList)*>(copy));
1061         case QMetaType::QVariant:
1062             return new NS(QVariant)(*static_cast<const NS(QVariant)*>(copy));
1063 #endif
1064         case QMetaType::QByteArray:
1065             return new NS(QByteArray)(*static_cast<const NS(QByteArray)*>(copy));
1066         case QMetaType::QString:
1067             return new NS(QString)(*static_cast<const NS(QString)*>(copy));
1068         case QMetaType::QStringList:
1069             return new NS(QStringList)(*static_cast<const NS(QStringList)*>(copy));
1070 #ifndef QT_BOOTSTRAPPED
1071         case QMetaType::QBitArray:
1072             return new NS(QBitArray)(*static_cast<const NS(QBitArray)*>(copy));
1073 #endif
1074         case QMetaType::QDate:
1075             return new NS(QDate)(*static_cast<const NS(QDate)*>(copy));
1076         case QMetaType::QTime:
1077             return new NS(QTime)(*static_cast<const NS(QTime)*>(copy));
1078         case QMetaType::QDateTime:
1079             return new NS(QDateTime)(*static_cast<const NS(QDateTime)*>(copy));
1080 #ifndef QT_BOOTSTRAPPED
1081         case QMetaType::QUrl:
1082             return new NS(QUrl)(*static_cast<const NS(QUrl)*>(copy));
1083 #endif
1084         case QMetaType::QLocale:
1085             return new NS(QLocale)(*static_cast<const NS(QLocale)*>(copy));
1086 #ifndef QT_NO_GEOM_VARIANT
1087         case QMetaType::QRect:
1088             return new NS(QRect)(*static_cast<const NS(QRect)*>(copy));
1089         case QMetaType::QRectF:
1090             return new NS(QRectF)(*static_cast<const NS(QRectF)*>(copy));
1091         case QMetaType::QSize:
1092             return new NS(QSize)(*static_cast<const NS(QSize)*>(copy));
1093         case QMetaType::QSizeF:
1094             return new NS(QSizeF)(*static_cast<const NS(QSizeF)*>(copy));
1095         case QMetaType::QLine:
1096             return new NS(QLine)(*static_cast<const NS(QLine)*>(copy));
1097         case QMetaType::QLineF:
1098             return new NS(QLineF)(*static_cast<const NS(QLineF)*>(copy));
1099         case QMetaType::QPoint:
1100             return new NS(QPoint)(*static_cast<const NS(QPoint)*>(copy));
1101         case QMetaType::QPointF:
1102             return new NS(QPointF)(*static_cast<const NS(QPointF)*>(copy));
1103 #endif
1104 #ifndef QT_NO_REGEXP
1105         case QMetaType::QRegExp:
1106             return new NS(QRegExp)(*static_cast<const NS(QRegExp)*>(copy));
1107 #endif
1108 #ifndef QT_BOOTSTRAPPED
1109         case QMetaType::QEasingCurve:
1110             return new NS(QEasingCurve)(*static_cast<const NS(QEasingCurve)*>(copy));
1111 #endif
1112         case QMetaType::Void:
1113             return 0;
1114         default:
1115             ;
1116         }
1117     } else {
1118         switch(type) {
1119         case QMetaType::VoidStar:
1120         case QMetaType::QObjectStar:
1121         case QMetaType::QWidgetStar:
1122             return new void *;
1123         case QMetaType::Long:
1124             return new long;
1125         case QMetaType::Int:
1126             return new int;
1127         case QMetaType::Short:
1128             return new short;
1129         case QMetaType::Char:
1130             return new char;
1131         case QMetaType::ULong:
1132             return new ulong;
1133         case QMetaType::UInt:
1134             return new uint;
1135         case QMetaType::LongLong:
1136             return new qlonglong;
1137         case QMetaType::ULongLong:
1138             return new qulonglong;
1139         case QMetaType::UShort:
1140             return new ushort;
1141         case QMetaType::UChar:
1142             return new uchar;
1143         case QMetaType::Bool:
1144             return new bool;
1145         case QMetaType::Float:
1146             return new float;
1147         case QMetaType::Double:
1148             return new double;
1149         case QMetaType::QChar:
1150             return new NS(QChar);
1151 #ifndef QT_BOOTSTRAPPED
1152         case QMetaType::QVariantMap:
1153             return new NS(QVariantMap);
1154         case QMetaType::QVariantHash:
1155             return new NS(QVariantHash);
1156         case QMetaType::QVariantList:
1157             return new NS(QVariantList);
1158         case QMetaType::QVariant:
1159             return new NS(QVariant);
1160 #endif
1161         case QMetaType::QByteArray:
1162             return new NS(QByteArray);
1163         case QMetaType::QString:
1164             return new NS(QString);
1165         case QMetaType::QStringList:
1166             return new NS(QStringList);
1167 #ifndef QT_BOOTSTRAPPED
1168         case QMetaType::QBitArray:
1169             return new NS(QBitArray);
1170 #endif
1171         case QMetaType::QDate:
1172             return new NS(QDate);
1173         case QMetaType::QTime:
1174             return new NS(QTime);
1175         case QMetaType::QDateTime:
1176             return new NS(QDateTime);
1177 #ifndef QT_BOOTSTRAPPED
1178         case QMetaType::QUrl:
1179             return new NS(QUrl);
1180 #endif
1181         case QMetaType::QLocale:
1182             return new NS(QLocale);
1183 #ifndef QT_NO_GEOM_VARIANT
1184         case QMetaType::QRect:
1185             return new NS(QRect);
1186         case QMetaType::QRectF:
1187             return new NS(QRectF);
1188         case QMetaType::QSize:
1189             return new NS(QSize);
1190         case QMetaType::QSizeF:
1191             return new NS(QSizeF);
1192         case QMetaType::QLine:
1193             return new NS(QLine);
1194         case QMetaType::QLineF:
1195             return new NS(QLineF);
1196         case QMetaType::QPoint:
1197             return new NS(QPoint);
1198         case QMetaType::QPointF:
1199             return new NS(QPointF);
1200 #endif
1201 #ifndef QT_NO_REGEXP
1202         case QMetaType::QRegExp:
1203             return new NS(QRegExp);
1204 #endif
1205 #ifndef QT_BOOTSTRAPPED
1206         case QMetaType::QEasingCurve:
1207             return new NS(QEasingCurve);
1208 #endif
1209         case QMetaType::Void:
1210             return 0;
1211         default:
1212             ;
1213         }
1214     }
1215
1216     Constructor constr = 0;
1217     if (type >= FirstGuiType && type <= LastGuiType) {
1218         if (!qMetaTypeGuiHelper)
1219             return 0;
1220         constr = qMetaTypeGuiHelper[type - FirstGuiType].constr;
1221     } else {
1222         const QVector<QCustomTypeInfo> * const ct = customTypes();
1223         QReadLocker locker(customTypesLock());
1224         if (type < User || !ct || ct->count() <= type - User)
1225             return 0;
1226         if (ct->at(type - User).typeName.isEmpty())
1227             return 0;
1228         constr = ct->at(type - User).constr;
1229     }
1230
1231     return constr(copy);
1232 }
1233
1234 /*!
1235     Destroys the \a data, assuming it is of the \a type given.
1236
1237     \sa construct(), isRegistered(), Type
1238 */
1239 void QMetaType::destroy(int type, void *data)
1240 {
1241     if (!data)
1242         return;
1243     switch(type) {
1244     case QMetaType::VoidStar:
1245     case QMetaType::QObjectStar:
1246     case QMetaType::QWidgetStar:
1247         delete static_cast<void**>(data);
1248         break;
1249     case QMetaType::Long:
1250         delete static_cast<long*>(data);
1251         break;
1252     case QMetaType::Int:
1253         delete static_cast<int*>(data);
1254         break;
1255     case QMetaType::Short:
1256         delete static_cast<short*>(data);
1257         break;
1258     case QMetaType::Char:
1259         delete static_cast<char*>(data);
1260         break;
1261     case QMetaType::ULong:
1262         delete static_cast<ulong*>(data);
1263         break;
1264     case QMetaType::LongLong:
1265         delete static_cast<qlonglong*>(data);
1266         break;
1267     case QMetaType::ULongLong:
1268         delete static_cast<qulonglong*>(data);
1269         break;
1270     case QMetaType::UInt:
1271         delete static_cast<uint*>(data);
1272         break;
1273     case QMetaType::UShort:
1274         delete static_cast<ushort*>(data);
1275         break;
1276     case QMetaType::UChar:
1277         delete static_cast<uchar*>(data);
1278         break;
1279     case QMetaType::Bool:
1280         delete static_cast<bool*>(data);
1281         break;
1282     case QMetaType::Float:
1283         delete static_cast<float*>(data);
1284         break;
1285     case QMetaType::Double:
1286         delete static_cast<double*>(data);
1287         break;
1288     case QMetaType::QChar:
1289         delete static_cast< NS(QChar)* >(data);
1290         break;
1291 #ifndef QT_BOOTSTRAPPED
1292     case QMetaType::QVariantMap:
1293         delete static_cast< NS(QVariantMap)* >(data);
1294         break;
1295     case QMetaType::QVariantHash:
1296         delete static_cast< NS(QVariantHash)* >(data);
1297         break;
1298     case QMetaType::QVariantList:
1299         delete static_cast< NS(QVariantList)* >(data);
1300         break;
1301     case QMetaType::QVariant:
1302         delete static_cast< NS(QVariant)* >(data);
1303         break;
1304 #endif
1305     case QMetaType::QByteArray:
1306         delete static_cast< NS(QByteArray)* >(data);
1307         break;
1308     case QMetaType::QString:
1309         delete static_cast< NS(QString)* >(data);
1310         break;
1311     case QMetaType::QStringList:
1312         delete static_cast< NS(QStringList)* >(data);
1313         break;
1314 #ifndef QT_BOOTSTRAPPED
1315     case QMetaType::QBitArray:
1316         delete static_cast< NS(QBitArray)* >(data);
1317         break;
1318 #endif
1319     case QMetaType::QDate:
1320         delete static_cast< NS(QDate)* >(data);
1321         break;
1322     case QMetaType::QTime:
1323         delete static_cast< NS(QTime)* >(data);
1324         break;
1325     case QMetaType::QDateTime:
1326         delete static_cast< NS(QDateTime)* >(data);
1327         break;
1328 #ifndef QT_BOOTSTRAPPED
1329     case QMetaType::QUrl:
1330         delete static_cast< NS(QUrl)* >(data);
1331 #endif
1332         break;
1333     case QMetaType::QLocale:
1334         delete static_cast< NS(QLocale)* >(data);
1335         break;
1336 #ifndef QT_NO_GEOM_VARIANT
1337     case QMetaType::QRect:
1338         delete static_cast< NS(QRect)* >(data);
1339         break;
1340     case QMetaType::QRectF:
1341         delete static_cast< NS(QRectF)* >(data);
1342         break;
1343     case QMetaType::QSize:
1344         delete static_cast< NS(QSize)* >(data);
1345         break;
1346     case QMetaType::QSizeF:
1347         delete static_cast< NS(QSizeF)* >(data);
1348         break;
1349     case QMetaType::QLine:
1350         delete static_cast< NS(QLine)* >(data);
1351         break;
1352     case QMetaType::QLineF:
1353         delete static_cast< NS(QLineF)* >(data);
1354         break;
1355     case QMetaType::QPoint:
1356         delete static_cast< NS(QPoint)* >(data);
1357         break;
1358     case QMetaType::QPointF:
1359         delete static_cast< NS(QPointF)* >(data);
1360         break;
1361 #endif
1362 #ifndef QT_NO_REGEXP
1363     case QMetaType::QRegExp:
1364         delete static_cast< NS(QRegExp)* >(data);
1365         break;
1366 #endif
1367 #ifndef QT_BOOTSTRAPPED
1368     case QMetaType::QEasingCurve:
1369         delete static_cast< NS(QEasingCurve)* >(data);
1370         break;
1371 #endif
1372     case QMetaType::Void:
1373         break;
1374     default: {
1375         const QVector<QCustomTypeInfo> * const ct = customTypes();
1376         Destructor destr = 0;
1377         if (type >= FirstGuiType && type <= LastGuiType) {
1378             Q_ASSERT(qMetaTypeGuiHelper);
1379
1380             if (!qMetaTypeGuiHelper)
1381                 return;
1382             destr = qMetaTypeGuiHelper[type - FirstGuiType].destr;
1383         } else {
1384             QReadLocker locker(customTypesLock());
1385             if (type < User || !ct || ct->count() <= type - User)
1386                 break;
1387             if (ct->at(type - User).typeName.isEmpty())
1388                 break;
1389             destr = ct->at(type - User).destr;
1390         }
1391         destr(data);
1392         break; }
1393     }
1394 }
1395
1396 /*!
1397     \fn int qRegisterMetaType(const char *typeName)
1398     \relates QMetaType
1399     \threadsafe
1400
1401     Registers the type name \a typeName for the type \c{T}. Returns
1402     the internal ID used by QMetaType. Any class or struct that has a
1403     public default constructor, a public copy constructor and a public
1404     destructor can be registered.
1405
1406     After a type has been registered, you can create and destroy
1407     objects of that type dynamically at run-time.
1408
1409     This example registers the class \c{MyClass}:
1410
1411     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 4
1412
1413     This function is useful to register typedefs so they can be used
1414     by QMetaProperty, or in QueuedConnections
1415
1416     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 9
1417
1418     \sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
1419         Q_DECLARE_METATYPE()
1420 */
1421
1422 /*!
1423     \fn int qRegisterMetaTypeStreamOperators(const char *typeName)
1424     \relates QMetaType
1425     \threadsafe
1426
1427     Registers the stream operators for the type \c{T} called \a
1428     typeName.
1429
1430     Afterward, the type can be streamed using QMetaType::load() and
1431     QMetaType::save(). These functions are used when streaming a
1432     QVariant.
1433
1434     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 5
1435
1436     The stream operators should have the following signatures:
1437
1438     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 6
1439
1440     \sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
1441 */
1442
1443 /*! \typedef QMetaType::Destructor
1444     \internal
1445 */
1446 /*! \typedef QMetaType::Constructor
1447     \internal
1448 */
1449 /*! \typedef QMetaType::SaveOperator
1450     \internal
1451 */
1452 /*! \typedef QMetaType::LoadOperator
1453     \internal
1454 */
1455
1456 /*!
1457     \fn int qRegisterMetaType()
1458     \relates QMetaType
1459     \threadsafe
1460     \since 4.2
1461
1462     Call this function to register the type \c T. \c T must be declared with
1463     Q_DECLARE_METATYPE(). Returns the meta type Id.
1464
1465     Example:
1466
1467     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 7
1468
1469     To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
1470     sufficient. To use the type \c T in queued signal and slot connections,
1471     \c{qRegisterMetaType<T>()} must be called before the first connection
1472     is established.
1473
1474     Also, to use type \c T with the QObject::property() API,
1475     \c{qRegisterMetaType<T>()} must be called before it is used, typically
1476     in the constructor of the class that uses \c T, or in the \c{main()}
1477     function.
1478
1479     \sa Q_DECLARE_METATYPE()
1480  */
1481
1482 /*! \fn int qMetaTypeId()
1483     \relates QMetaType
1484     \threadsafe
1485     \since 4.1
1486
1487     Returns the meta type id of type \c T at compile time. If the
1488     type was not declared with Q_DECLARE_METATYPE(), compilation will
1489     fail.
1490
1491     Typical usage:
1492
1493     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 8
1494
1495     QMetaType::type() returns the same ID as qMetaTypeId(), but does
1496     a lookup at runtime based on the name of the type.
1497     QMetaType::type() is a bit slower, but compilation succeeds if a
1498     type is not registered.
1499
1500     \sa Q_DECLARE_METATYPE(), QMetaType::type()
1501 */
1502
1503 QT_END_NAMESPACE