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