1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
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:
QCustomTypeInfo()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);
Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>,customTypes)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 */
registerStreamOperators(int idx,SaveOperator saveOp,LoadOperator loadOp)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 */
typeName(int type)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 */
qMetaTypeStaticType(const char * typeName,int length)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 */
qMetaTypeCustomType_unlocked(const char * typeName,int length)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  */
registerType(const char * typeName,Destructor destructor,Constructor constructor)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 */
registerTypedef(const char * typeName,int aliasId)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  */
unregisterType(const char * typeName)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 */
isRegistered(int type)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 */
type(const char * typeName)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 */
save(QDataStream & stream,int type,const void * data)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 #ifdef QT3_SUPPORT
764     case QMetaType::QColorGroup:
765 #endif
766     case QMetaType::QFont:
767     case QMetaType::QPixmap:
768     case QMetaType::QBrush:
769     case QMetaType::QColor:
770     case QMetaType::QPalette:
771     case QMetaType::QIcon:
772     case QMetaType::QImage:
773     case QMetaType::QPolygon:
774     case QMetaType::QRegion:
775     case QMetaType::QBitmap:
776     case QMetaType::QCursor:
777     case QMetaType::QSizePolicy:
778     case QMetaType::QKeySequence:
779     case QMetaType::QPen:
780     case QMetaType::QTextLength:
781     case QMetaType::QTextFormat:
782     case QMetaType::QMatrix:
783     case QMetaType::QTransform:
784     case QMetaType::QMatrix4x4:
785     case QMetaType::QVector2D:
786     case QMetaType::QVector3D:
787     case QMetaType::QVector4D:
788     case QMetaType::QQuaternion:
789         if (!qMetaTypeGuiHelper)
790             return false;
791         qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
792         break;
793     default: {
794         const QVector<QCustomTypeInfo> * const ct = customTypes();
795         if (!ct)
796             return false;
797 
798         SaveOperator saveOp = 0;
799         {
800             QReadLocker locker(customTypesLock());
801             saveOp = ct->at(type - User).saveOp;
802         }
803 
804         if (!saveOp)
805             return false;
806         saveOp(stream, data);
807         break; }
808     }
809 
810     return true;
811 }
812 
813 /*!
814     Reads the object of the specified \a type from the given \a
815     stream into \a data. Returns true if the object is loaded
816     successfully; otherwise returns false.
817 
818     The type must have been registered with qRegisterMetaType() and
819     qRegisterMetaTypeStreamOperators() beforehand.
820 
821     Normally, you should not need to call this function directly.
822     Instead, use QVariant's \c operator>>(), which relies on load()
823     to stream custom types.
824 
825     \sa save(), qRegisterMetaTypeStreamOperators()
826 */
load(QDataStream & stream,int type,void * data)827 bool QMetaType::load(QDataStream &stream, int type, void *data)
828 {
829     if (!data || !isRegistered(type))
830         return false;
831 
832     switch(type) {
833     case QMetaType::Void:
834     case QMetaType::VoidStar:
835     case QMetaType::QObjectStar:
836     case QMetaType::QWidgetStar:
837         return false;
838     case QMetaType::Long: {
839         qlonglong l;
840         stream >> l;
841         *static_cast<long *>(data) = long(l);
842         break; }
843     case QMetaType::Int:
844         stream >> *static_cast<int *>(data);
845         break;
846     case QMetaType::Short:
847         stream >> *static_cast<short *>(data);
848         break;
849     case QMetaType::Char:
850         // force a char to be signed
851         stream >> *static_cast<signed char *>(data);
852         break;
853     case QMetaType::ULong: {
854         qulonglong ul;
855         stream >> ul;
856         *static_cast<ulong *>(data) = ulong(ul);
857         break; }
858     case QMetaType::UInt:
859         stream >> *static_cast<uint *>(data);
860         break;
861     case QMetaType::LongLong:
862         stream >> *static_cast<qlonglong *>(data);
863         break;
864     case QMetaType::ULongLong:
865         stream >> *static_cast<qulonglong *>(data);
866         break;
867     case QMetaType::UShort:
868         stream >> *static_cast<ushort *>(data);
869         break;
870     case QMetaType::UChar:
871         stream >> *static_cast<uchar *>(data);
872         break;
873     case QMetaType::Bool: {
874         qint8 b;
875         stream >> b;
876         *static_cast<bool *>(data) = b;
877         break; }
878     case QMetaType::Float:
879         stream >> *static_cast<float *>(data);
880         break;
881     case QMetaType::Double:
882         stream >> *static_cast<double *>(data);
883         break;
884     case QMetaType::QChar:
885         stream >> *static_cast< NS(QChar)*>(data);
886         break;
887 #ifndef QT_BOOTSTRAPPED
888     case QMetaType::QVariantMap:
889         stream >> *static_cast< NS(QVariantMap)*>(data);
890         break;
891     case QMetaType::QVariantHash:
892         stream >> *static_cast< NS(QVariantHash)*>(data);
893         break;
894     case QMetaType::QVariantList:
895         stream >> *static_cast< NS(QVariantList)*>(data);
896         break;
897     case QMetaType::QVariant:
898         stream >> *static_cast< NS(QVariant)*>(data);
899         break;
900 #endif
901     case QMetaType::QByteArray:
902         stream >> *static_cast< NS(QByteArray)*>(data);
903         break;
904     case QMetaType::QString:
905         stream >> *static_cast< NS(QString)*>(data);
906         break;
907     case QMetaType::QStringList:
908         stream >> *static_cast< NS(QStringList)*>(data);
909         break;
910 #ifndef QT_BOOTSTRAPPED
911     case QMetaType::QBitArray:
912         stream >> *static_cast< NS(QBitArray)*>(data);
913         break;
914 #endif
915     case QMetaType::QDate:
916         stream >> *static_cast< NS(QDate)*>(data);
917         break;
918     case QMetaType::QTime:
919         stream >> *static_cast< NS(QTime)*>(data);
920         break;
921     case QMetaType::QDateTime:
922         stream >> *static_cast< NS(QDateTime)*>(data);
923         break;
924 #ifndef QT_BOOTSTRAPPED
925     case QMetaType::QUrl:
926         stream >> *static_cast< NS(QUrl)*>(data);
927         break;
928 #endif
929     case QMetaType::QLocale:
930         stream >> *static_cast< NS(QLocale)*>(data);
931         break;
932 #ifndef QT_NO_GEOM_VARIANT
933     case QMetaType::QRect:
934         stream >> *static_cast< NS(QRect)*>(data);
935         break;
936     case QMetaType::QRectF:
937         stream >> *static_cast< NS(QRectF)*>(data);
938         break;
939     case QMetaType::QSize:
940         stream >> *static_cast< NS(QSize)*>(data);
941         break;
942     case QMetaType::QSizeF:
943         stream >> *static_cast< NS(QSizeF)*>(data);
944         break;
945     case QMetaType::QLine:
946         stream >> *static_cast< NS(QLine)*>(data);
947         break;
948     case QMetaType::QLineF:
949         stream >> *static_cast< NS(QLineF)*>(data);
950         break;
951     case QMetaType::QPoint:
952         stream >> *static_cast< NS(QPoint)*>(data);
953         break;
954     case QMetaType::QPointF:
955         stream >> *static_cast< NS(QPointF)*>(data);
956         break;
957 #endif
958 #ifndef QT_NO_REGEXP
959     case QMetaType::QRegExp:
960         stream >> *static_cast< NS(QRegExp)*>(data);
961         break;
962 #endif
963 #ifndef QT_BOOTSTRAPPED
964     case QMetaType::QEasingCurve:
965         stream >> *static_cast< NS(QEasingCurve)*>(data);
966         break;
967 #endif
968 #ifdef QT3_SUPPORT
969     case QMetaType::QColorGroup:
970 #endif
971     case QMetaType::QFont:
972     case QMetaType::QPixmap:
973     case QMetaType::QBrush:
974     case QMetaType::QColor:
975     case QMetaType::QPalette:
976     case QMetaType::QIcon:
977     case QMetaType::QImage:
978     case QMetaType::QPolygon:
979     case QMetaType::QRegion:
980     case QMetaType::QBitmap:
981     case QMetaType::QCursor:
982     case QMetaType::QSizePolicy:
983     case QMetaType::QKeySequence:
984     case QMetaType::QPen:
985     case QMetaType::QTextLength:
986     case QMetaType::QTextFormat:
987     case QMetaType::QMatrix:
988     case QMetaType::QTransform:
989     case QMetaType::QMatrix4x4:
990     case QMetaType::QVector2D:
991     case QMetaType::QVector3D:
992     case QMetaType::QVector4D:
993     case QMetaType::QQuaternion:
994         if (!qMetaTypeGuiHelper)
995             return false;
996         qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
997         break;
998     default: {
999         const QVector<QCustomTypeInfo> * const ct = customTypes();
1000         if (!ct)
1001             return false;
1002 
1003         LoadOperator loadOp = 0;
1004         {
1005             QReadLocker locker(customTypesLock());
1006             loadOp = ct->at(type - User).loadOp;
1007         }
1008 
1009         if (!loadOp)
1010             return false;
1011         loadOp(stream, data);
1012         break; }
1013     }
1014     return true;
1015 }
1016 #endif // QT_NO_DATASTREAM
1017 
1018 /*!
1019     Returns a copy of \a copy, assuming it is of type \a type. If \a
1020     copy is zero, creates a default type.
1021 
1022     \sa destroy(), isRegistered(), Type
1023 */
construct(int type,const void * copy)1024 void *QMetaType::construct(int type, const void *copy)
1025 {
1026     if (copy) {
1027         switch(type) {
1028         case QMetaType::VoidStar:
1029         case QMetaType::QObjectStar:
1030         case QMetaType::QWidgetStar:
1031             return new void *(*static_cast<void* const *>(copy));
1032         case QMetaType::Long:
1033             return new long(*static_cast<const long*>(copy));
1034         case QMetaType::Int:
1035             return new int(*static_cast<const int*>(copy));
1036         case QMetaType::Short:
1037             return new short(*static_cast<const short*>(copy));
1038         case QMetaType::Char:
1039             return new char(*static_cast<const char*>(copy));
1040         case QMetaType::ULong:
1041             return new ulong(*static_cast<const ulong*>(copy));
1042         case QMetaType::UInt:
1043             return new uint(*static_cast<const uint*>(copy));
1044         case QMetaType::LongLong:
1045             return new qlonglong(*static_cast<const qlonglong*>(copy));
1046         case QMetaType::ULongLong:
1047             return new qulonglong(*static_cast<const qulonglong*>(copy));
1048         case QMetaType::UShort:
1049             return new ushort(*static_cast<const ushort*>(copy));
1050         case QMetaType::UChar:
1051             return new uchar(*static_cast<const uchar*>(copy));
1052         case QMetaType::Bool:
1053             return new bool(*static_cast<const bool*>(copy));
1054         case QMetaType::Float:
1055             return new float(*static_cast<const float*>(copy));
1056         case QMetaType::Double:
1057             return new double(*static_cast<const double*>(copy));
1058         case QMetaType::QChar:
1059             return new NS(QChar)(*static_cast<const NS(QChar)*>(copy));
1060 #ifndef QT_BOOTSTRAPPED
1061         case QMetaType::QVariantMap:
1062             return new NS(QVariantMap)(*static_cast<const NS(QVariantMap)*>(copy));
1063         case QMetaType::QVariantHash:
1064             return new NS(QVariantHash)(*static_cast<const NS(QVariantHash)*>(copy));
1065         case QMetaType::QVariantList:
1066             return new NS(QVariantList)(*static_cast<const NS(QVariantList)*>(copy));
1067         case QMetaType::QVariant:
1068             return new NS(QVariant)(*static_cast<const NS(QVariant)*>(copy));
1069 #endif
1070         case QMetaType::QByteArray:
1071             return new NS(QByteArray)(*static_cast<const NS(QByteArray)*>(copy));
1072         case QMetaType::QString:
1073             return new NS(QString)(*static_cast<const NS(QString)*>(copy));
1074         case QMetaType::QStringList:
1075             return new NS(QStringList)(*static_cast<const NS(QStringList)*>(copy));
1076 #ifndef QT_BOOTSTRAPPED
1077         case QMetaType::QBitArray:
1078             return new NS(QBitArray)(*static_cast<const NS(QBitArray)*>(copy));
1079 #endif
1080         case QMetaType::QDate:
1081             return new NS(QDate)(*static_cast<const NS(QDate)*>(copy));
1082         case QMetaType::QTime:
1083             return new NS(QTime)(*static_cast<const NS(QTime)*>(copy));
1084         case QMetaType::QDateTime:
1085             return new NS(QDateTime)(*static_cast<const NS(QDateTime)*>(copy));
1086 #ifndef QT_BOOTSTRAPPED
1087         case QMetaType::QUrl:
1088             return new NS(QUrl)(*static_cast<const NS(QUrl)*>(copy));
1089 #endif
1090         case QMetaType::QLocale:
1091             return new NS(QLocale)(*static_cast<const NS(QLocale)*>(copy));
1092 #ifndef QT_NO_GEOM_VARIANT
1093         case QMetaType::QRect:
1094             return new NS(QRect)(*static_cast<const NS(QRect)*>(copy));
1095         case QMetaType::QRectF:
1096             return new NS(QRectF)(*static_cast<const NS(QRectF)*>(copy));
1097         case QMetaType::QSize:
1098             return new NS(QSize)(*static_cast<const NS(QSize)*>(copy));
1099         case QMetaType::QSizeF:
1100             return new NS(QSizeF)(*static_cast<const NS(QSizeF)*>(copy));
1101         case QMetaType::QLine:
1102             return new NS(QLine)(*static_cast<const NS(QLine)*>(copy));
1103         case QMetaType::QLineF:
1104             return new NS(QLineF)(*static_cast<const NS(QLineF)*>(copy));
1105         case QMetaType::QPoint:
1106             return new NS(QPoint)(*static_cast<const NS(QPoint)*>(copy));
1107         case QMetaType::QPointF:
1108             return new NS(QPointF)(*static_cast<const NS(QPointF)*>(copy));
1109 #endif
1110 #ifndef QT_NO_REGEXP
1111         case QMetaType::QRegExp:
1112             return new NS(QRegExp)(*static_cast<const NS(QRegExp)*>(copy));
1113 #endif
1114 #ifndef QT_BOOTSTRAPPED
1115         case QMetaType::QEasingCurve:
1116             return new NS(QEasingCurve)(*static_cast<const NS(QEasingCurve)*>(copy));
1117 #endif
1118         case QMetaType::Void:
1119             return 0;
1120         default:
1121             ;
1122         }
1123     } else {
1124         switch(type) {
1125         case QMetaType::VoidStar:
1126         case QMetaType::QObjectStar:
1127         case QMetaType::QWidgetStar:
1128             return new void *;
1129         case QMetaType::Long:
1130             return new long;
1131         case QMetaType::Int:
1132             return new int;
1133         case QMetaType::Short:
1134             return new short;
1135         case QMetaType::Char:
1136             return new char;
1137         case QMetaType::ULong:
1138             return new ulong;
1139         case QMetaType::UInt:
1140             return new uint;
1141         case QMetaType::LongLong:
1142             return new qlonglong;
1143         case QMetaType::ULongLong:
1144             return new qulonglong;
1145         case QMetaType::UShort:
1146             return new ushort;
1147         case QMetaType::UChar:
1148             return new uchar;
1149         case QMetaType::Bool:
1150             return new bool;
1151         case QMetaType::Float:
1152             return new float;
1153         case QMetaType::Double:
1154             return new double;
1155         case QMetaType::QChar:
1156             return new NS(QChar);
1157 #ifndef QT_BOOTSTRAPPED
1158         case QMetaType::QVariantMap:
1159             return new NS(QVariantMap);
1160         case QMetaType::QVariantHash:
1161             return new NS(QVariantHash);
1162         case QMetaType::QVariantList:
1163             return new NS(QVariantList);
1164         case QMetaType::QVariant:
1165             return new NS(QVariant);
1166 #endif
1167         case QMetaType::QByteArray:
1168             return new NS(QByteArray);
1169         case QMetaType::QString:
1170             return new NS(QString);
1171         case QMetaType::QStringList:
1172             return new NS(QStringList);
1173 #ifndef QT_BOOTSTRAPPED
1174         case QMetaType::QBitArray:
1175             return new NS(QBitArray);
1176 #endif
1177         case QMetaType::QDate:
1178             return new NS(QDate);
1179         case QMetaType::QTime:
1180             return new NS(QTime);
1181         case QMetaType::QDateTime:
1182             return new NS(QDateTime);
1183 #ifndef QT_BOOTSTRAPPED
1184         case QMetaType::QUrl:
1185             return new NS(QUrl);
1186 #endif
1187         case QMetaType::QLocale:
1188             return new NS(QLocale);
1189 #ifndef QT_NO_GEOM_VARIANT
1190         case QMetaType::QRect:
1191             return new NS(QRect);
1192         case QMetaType::QRectF:
1193             return new NS(QRectF);
1194         case QMetaType::QSize:
1195             return new NS(QSize);
1196         case QMetaType::QSizeF:
1197             return new NS(QSizeF);
1198         case QMetaType::QLine:
1199             return new NS(QLine);
1200         case QMetaType::QLineF:
1201             return new NS(QLineF);
1202         case QMetaType::QPoint:
1203             return new NS(QPoint);
1204         case QMetaType::QPointF:
1205             return new NS(QPointF);
1206 #endif
1207 #ifndef QT_NO_REGEXP
1208         case QMetaType::QRegExp:
1209             return new NS(QRegExp);
1210 #endif
1211 #ifndef QT_BOOTSTRAPPED
1212         case QMetaType::QEasingCurve:
1213             return new NS(QEasingCurve);
1214 #endif
1215         case QMetaType::Void:
1216             return 0;
1217         default:
1218             ;
1219         }
1220     }
1221 
1222     Constructor constr = 0;
1223     if (type >= FirstGuiType && type <= LastGuiType) {
1224         if (!qMetaTypeGuiHelper)
1225             return 0;
1226         constr = qMetaTypeGuiHelper[type - FirstGuiType].constr;
1227     } else {
1228         const QVector<QCustomTypeInfo> * const ct = customTypes();
1229         QReadLocker locker(customTypesLock());
1230         if (type < User || !ct || ct->count() <= type - User)
1231             return 0;
1232         if (ct->at(type - User).typeName.isEmpty())
1233             return 0;
1234         constr = ct->at(type - User).constr;
1235     }
1236 
1237     return constr(copy);
1238 }
1239 
1240 /*!
1241     Destroys the \a data, assuming it is of the \a type given.
1242 
1243     \sa construct(), isRegistered(), Type
1244 */
destroy(int type,void * data)1245 void QMetaType::destroy(int type, void *data)
1246 {
1247     if (!data)
1248         return;
1249     switch(type) {
1250     case QMetaType::VoidStar:
1251     case QMetaType::QObjectStar:
1252     case QMetaType::QWidgetStar:
1253         delete static_cast<void**>(data);
1254         break;
1255     case QMetaType::Long:
1256         delete static_cast<long*>(data);
1257         break;
1258     case QMetaType::Int:
1259         delete static_cast<int*>(data);
1260         break;
1261     case QMetaType::Short:
1262         delete static_cast<short*>(data);
1263         break;
1264     case QMetaType::Char:
1265         delete static_cast<char*>(data);
1266         break;
1267     case QMetaType::ULong:
1268         delete static_cast<ulong*>(data);
1269         break;
1270     case QMetaType::LongLong:
1271         delete static_cast<qlonglong*>(data);
1272         break;
1273     case QMetaType::ULongLong:
1274         delete static_cast<qulonglong*>(data);
1275         break;
1276     case QMetaType::UInt:
1277         delete static_cast<uint*>(data);
1278         break;
1279     case QMetaType::UShort:
1280         delete static_cast<ushort*>(data);
1281         break;
1282     case QMetaType::UChar:
1283         delete static_cast<uchar*>(data);
1284         break;
1285     case QMetaType::Bool:
1286         delete static_cast<bool*>(data);
1287         break;
1288     case QMetaType::Float:
1289         delete static_cast<float*>(data);
1290         break;
1291     case QMetaType::Double:
1292         delete static_cast<double*>(data);
1293         break;
1294     case QMetaType::QChar:
1295         delete static_cast< NS(QChar)* >(data);
1296         break;
1297 #ifndef QT_BOOTSTRAPPED
1298     case QMetaType::QVariantMap:
1299         delete static_cast< NS(QVariantMap)* >(data);
1300         break;
1301     case QMetaType::QVariantHash:
1302         delete static_cast< NS(QVariantHash)* >(data);
1303         break;
1304     case QMetaType::QVariantList:
1305         delete static_cast< NS(QVariantList)* >(data);
1306         break;
1307     case QMetaType::QVariant:
1308         delete static_cast< NS(QVariant)* >(data);
1309         break;
1310 #endif
1311     case QMetaType::QByteArray:
1312         delete static_cast< NS(QByteArray)* >(data);
1313         break;
1314     case QMetaType::QString:
1315         delete static_cast< NS(QString)* >(data);
1316         break;
1317     case QMetaType::QStringList:
1318         delete static_cast< NS(QStringList)* >(data);
1319         break;
1320 #ifndef QT_BOOTSTRAPPED
1321     case QMetaType::QBitArray:
1322         delete static_cast< NS(QBitArray)* >(data);
1323         break;
1324 #endif
1325     case QMetaType::QDate:
1326         delete static_cast< NS(QDate)* >(data);
1327         break;
1328     case QMetaType::QTime:
1329         delete static_cast< NS(QTime)* >(data);
1330         break;
1331     case QMetaType::QDateTime:
1332         delete static_cast< NS(QDateTime)* >(data);
1333         break;
1334 #ifndef QT_BOOTSTRAPPED
1335     case QMetaType::QUrl:
1336         delete static_cast< NS(QUrl)* >(data);
1337 #endif
1338         break;
1339     case QMetaType::QLocale:
1340         delete static_cast< NS(QLocale)* >(data);
1341         break;
1342 #ifndef QT_NO_GEOM_VARIANT
1343     case QMetaType::QRect:
1344         delete static_cast< NS(QRect)* >(data);
1345         break;
1346     case QMetaType::QRectF:
1347         delete static_cast< NS(QRectF)* >(data);
1348         break;
1349     case QMetaType::QSize:
1350         delete static_cast< NS(QSize)* >(data);
1351         break;
1352     case QMetaType::QSizeF:
1353         delete static_cast< NS(QSizeF)* >(data);
1354         break;
1355     case QMetaType::QLine:
1356         delete static_cast< NS(QLine)* >(data);
1357         break;
1358     case QMetaType::QLineF:
1359         delete static_cast< NS(QLineF)* >(data);
1360         break;
1361     case QMetaType::QPoint:
1362         delete static_cast< NS(QPoint)* >(data);
1363         break;
1364     case QMetaType::QPointF:
1365         delete static_cast< NS(QPointF)* >(data);
1366         break;
1367 #endif
1368 #ifndef QT_NO_REGEXP
1369     case QMetaType::QRegExp:
1370         delete static_cast< NS(QRegExp)* >(data);
1371         break;
1372 #endif
1373 #ifndef QT_BOOTSTRAPPED
1374     case QMetaType::QEasingCurve:
1375         delete static_cast< NS(QEasingCurve)* >(data);
1376         break;
1377 #endif
1378     case QMetaType::Void:
1379         break;
1380     default: {
1381         const QVector<QCustomTypeInfo> * const ct = customTypes();
1382         Destructor destr = 0;
1383         if (type >= FirstGuiType && type <= LastGuiType) {
1384             Q_ASSERT(qMetaTypeGuiHelper);
1385 
1386             if (!qMetaTypeGuiHelper)
1387                 return;
1388             destr = qMetaTypeGuiHelper[type - FirstGuiType].destr;
1389         } else {
1390             QReadLocker locker(customTypesLock());
1391             if (type < User || !ct || ct->count() <= type - User)
1392                 break;
1393             if (ct->at(type - User).typeName.isEmpty())
1394                 break;
1395             destr = ct->at(type - User).destr;
1396         }
1397         destr(data);
1398         break; }
1399     }
1400 }
1401 
1402 /*!
1403     \fn int qRegisterMetaType(const char *typeName)
1404     \relates QMetaType
1405     \threadsafe
1406 
1407     Registers the type name \a typeName for the type \c{T}. Returns
1408     the internal ID used by QMetaType. Any class or struct that has a
1409     public default constructor, a public copy constructor and a public
1410     destructor can be registered.
1411 
1412     After a type has been registered, you can create and destroy
1413     objects of that type dynamically at run-time.
1414 
1415     This example registers the class \c{MyClass}:
1416 
1417     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 4
1418 
1419     This function is useful to register typedefs so they can be used
1420     by QMetaProperty, or in QueuedConnections
1421 
1422     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 9
1423 
1424     \sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
1425         Q_DECLARE_METATYPE()
1426 */
1427 
1428 /*!
1429     \fn int qRegisterMetaTypeStreamOperators(const char *typeName)
1430     \relates QMetaType
1431     \threadsafe
1432 
1433     Registers the stream operators for the type \c{T} called \a
1434     typeName.
1435 
1436     Afterward, the type can be streamed using QMetaType::load() and
1437     QMetaType::save(). These functions are used when streaming a
1438     QVariant.
1439 
1440     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 5
1441 
1442     The stream operators should have the following signatures:
1443 
1444     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 6
1445 
1446     \sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
1447 */
1448 
1449 /*! \typedef QMetaType::Destructor
1450     \internal
1451 */
1452 /*! \typedef QMetaType::Constructor
1453     \internal
1454 */
1455 /*! \typedef QMetaType::SaveOperator
1456     \internal
1457 */
1458 /*! \typedef QMetaType::LoadOperator
1459     \internal
1460 */
1461 
1462 /*!
1463     \fn int qRegisterMetaType()
1464     \relates QMetaType
1465     \threadsafe
1466     \since 4.2
1467 
1468     Call this function to register the type \c T. \c T must be declared with
1469     Q_DECLARE_METATYPE(). Returns the meta type Id.
1470 
1471     Example:
1472 
1473     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 7
1474 
1475     To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
1476     sufficient. To use the type \c T in queued signal and slot connections,
1477     \c{qRegisterMetaType<T>()} must be called before the first connection
1478     is established.
1479 
1480     Also, to use type \c T with the QObject::property() API,
1481     \c{qRegisterMetaType<T>()} must be called before it is used, typically
1482     in the constructor of the class that uses \c T, or in the \c{main()}
1483     function.
1484 
1485     \sa Q_DECLARE_METATYPE()
1486  */
1487 
1488 /*! \fn int qMetaTypeId()
1489     \relates QMetaType
1490     \threadsafe
1491     \since 4.1
1492 
1493     Returns the meta type id of type \c T at compile time. If the
1494     type was not declared with Q_DECLARE_METATYPE(), compilation will
1495     fail.
1496 
1497     Typical usage:
1498 
1499     \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 8
1500 
1501     QMetaType::type() returns the same ID as qMetaTypeId(), but does
1502     a lookup at runtime based on the name of the type.
1503     QMetaType::type() is a bit slower, but compilation succeeds if a
1504     type is not registered.
1505 
1506     \sa Q_DECLARE_METATYPE(), QMetaType::type()
1507 */
1508 
1509 QT_END_NAMESPACE
1510