1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qmetatype.h"
41#include "qmetatype_p.h"
42#include "qobjectdefs.h"
43#include "qdatetime.h"
44#include "qbytearray.h"
45#include "qreadwritelock.h"
46#include "qstring.h"
47#include "qstringlist.h"
48#include "qvector.h"
49#include "qlocale.h"
50#include "qeasingcurve.h"
51#include "quuid.h"
52#include "qvariant.h"
53#include "qdatastream.h"
54#include "qmetatypeswitcher_p.h"
55
56#if QT_CONFIG(regularexpression)
57# include "qregularexpression.h"
58#endif
59
60#ifndef QT_BOOTSTRAPPED
61# include "qbitarray.h"
62# include "qurl.h"
63# include "qvariant.h"
64# include "qjsonvalue.h"
65# include "qjsonobject.h"
66# include "qjsonarray.h"
67# include "qjsondocument.h"
68# include "qbytearraylist.h"
69#endif
70
71#if QT_CONFIG(itemmodel)
72# include "qabstractitemmodel.h"
73#endif
74
75#ifndef QT_NO_GEOM_VARIANT
76# include "qsize.h"
77# include "qpoint.h"
78# include "qrect.h"
79# include "qline.h"
80#endif
81
82QT_BEGIN_NAMESPACE
83
84#define NS(x) QT_PREPEND_NAMESPACE(x)
85
86
87namespace {
88struct DefinedTypesFilter {
89 template<typename T>
90 struct Acceptor {
91 static const bool IsAccepted = QtMetaTypePrivate::TypeDefinition<T>::IsAvailable && QModulesPrivate::QTypeModuleInfo<T>::IsCore;
92 };
93};
94} // namespace
95
96/*!
97 \macro Q_DECLARE_OPAQUE_POINTER(PointerType)
98 \relates QMetaType
99 \since 5.0
100
101 This macro enables pointers to forward-declared types (\a PointerType)
102 to be registered with QMetaType using either Q_DECLARE_METATYPE()
103 or qRegisterMetaType().
104
105 \sa Q_DECLARE_METATYPE(), qRegisterMetaType()
106*/
107
108/*!
109 \macro Q_DECLARE_METATYPE(Type)
110 \relates QMetaType
111
112 This macro makes the type \a Type known to QMetaType as long as it
113 provides a public default constructor, a public copy constructor and
114 a public destructor.
115 It is needed to use the type \a Type as a custom type in QVariant.
116
117 This macro requires that \a Type is a fully defined type at the point where
118 it is used. For pointer types, it also requires that the pointed to type is
119 fully defined. Use in conjunction with Q_DECLARE_OPAQUE_POINTER() to
120 register pointers to forward declared types.
121
122 Ideally, this macro should be placed below the declaration of
123 the class or struct. If that is not possible, it can be put in
124 a private header file which has to be included every time that
125 type is used in a QVariant.
126
127 Adding a Q_DECLARE_METATYPE() makes the type known to all template
128 based functions, including QVariant. Note that if you intend to
129 use the type in \e queued signal and slot connections or in
130 QObject's property system, you also have to call
131 qRegisterMetaType() since the names are resolved at runtime.
132
133 This example shows a typical use case of Q_DECLARE_METATYPE():
134
135 \snippet code/src_corelib_kernel_qmetatype.cpp 0
136
137 If \c MyStruct is in a namespace, the Q_DECLARE_METATYPE() macro
138 has to be outside the namespace:
139
140 \snippet code/src_corelib_kernel_qmetatype.cpp 1
141
142 Since \c{MyStruct} is now known to QMetaType, it can be used in QVariant:
143
144 \snippet code/src_corelib_kernel_qmetatype.cpp 2
145
146 Some types are registered automatically and do not need this macro:
147
148 \list
149 \li Pointers to classes derived from QObject
150 \li QList<T>, QVector<T>, QQueue<T>, QStack<T>, QSet<T> or QLinkedList<T>
151 where T is a registered meta type
152 \li QHash<T1, T2>, QMap<T1, T2> or QPair<T1, T2> where T1 and T2 are
153 registered meta types
154 \li QPointer<T>, QSharedPointer<T>, QWeakPointer<T>, where T is a class that derives from QObject
155 \li Enumerations registered with Q_ENUM or Q_FLAG
156 \li Classes that have a Q_GADGET macro
157 \endlist
158
159 \sa qRegisterMetaType()
160*/
161
162/*!
163 \macro Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(Container)
164 \relates QMetaType
165
166 This macro makes the container \a Container known to QMetaType as a sequential
167 container. This makes it possible to put an instance of Container<T> into
168 a QVariant, if T itself is known to QMetaType.
169
170 Note that all of the Qt sequential containers already have built-in
171 support, and it is not necessary to use this macro with them. The
172 std::vector and std::list containers also have built-in support.
173
174 This example shows a typical use of Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE():
175
176 \snippet code/src_corelib_kernel_qmetatype.cpp 10
177*/
178
179/*!
180 \macro Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(Container)
181 \relates QMetaType
182
183 This macro makes the container \a Container known to QMetaType as an associative
184 container. This makes it possible to put an instance of Container<T, U> into
185 a QVariant, if T and U are themselves known to QMetaType.
186
187 Note that all of the Qt associative containers already have built-in
188 support, and it is not necessary to use this macro with them. The
189 std::map container also has built-in support.
190
191 This example shows a typical use of Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE():
192
193 \snippet code/src_corelib_kernel_qmetatype.cpp 11
194*/
195
196/*!
197 \macro Q_DECLARE_SMART_POINTER_METATYPE(SmartPointer)
198 \relates QMetaType
199
200 This macro makes the smart pointer \a SmartPointer known to QMetaType as a
201 smart pointer. This makes it possible to put an instance of SmartPointer<T> into
202 a QVariant, if T is a type which inherits QObject.
203
204 Note that the QWeakPointer, QSharedPointer and QPointer already have built-in
205 support, and it is not necessary to use this macro with them.
206
207 This example shows a typical use of Q_DECLARE_SMART_POINTER_METATYPE():
208
209 \snippet code/src_corelib_kernel_qmetatype.cpp 13
210*/
211
212/*!
213 \enum QMetaType::Type
214
215 These are the built-in types supported by QMetaType:
216
217 \value Void \c void
218 \value Bool \c bool
219 \value Int \c int
220 \value UInt \c{unsigned int}
221 \value Double \c double
222 \value QChar QChar
223 \value QString QString
224 \value QByteArray QByteArray
225 \value Nullptr \c{std::nullptr_t}
226
227 \value VoidStar \c{void *}
228 \value Long \c{long}
229 \value LongLong LongLong
230 \value Short \c{short}
231 \value Char \c{char}
232 \value ULong \c{unsigned long}
233 \value ULongLong ULongLong
234 \value UShort \c{unsigned short}
235 \value SChar \c{signed char}
236 \value UChar \c{unsigned char}
237 \value Float \c float
238 \value QObjectStar QObject *
239 \value QVariant QVariant
240
241 \value QCursor QCursor
242 \value QDate QDate
243 \value QSize QSize
244 \value QTime QTime
245 \value QVariantList QVariantList
246 \value QPolygon QPolygon
247 \value QPolygonF QPolygonF
248 \value QColor QColor
249 \value QSizeF QSizeF
250 \value QRectF QRectF
251 \value QLine QLine
252 \value QTextLength QTextLength
253 \value QStringList QStringList
254 \value QVariantMap QVariantMap
255 \value QVariantHash QVariantHash
256 \value QIcon QIcon
257 \value QPen QPen
258 \value QLineF QLineF
259 \value QTextFormat QTextFormat
260 \value QRect QRect
261 \value QPoint QPoint
262 \value QUrl QUrl
263 \value QRegExp QRegExp
264 \value QRegularExpression QRegularExpression
265 \value QDateTime QDateTime
266 \value QPointF QPointF
267 \value QPalette QPalette
268 \value QFont QFont
269 \value QBrush QBrush
270 \value QRegion QRegion
271 \value QBitArray QBitArray
272 \value QImage QImage
273 \value QKeySequence QKeySequence
274 \value QSizePolicy QSizePolicy
275 \value QPixmap QPixmap
276 \value QLocale QLocale
277 \value QBitmap QBitmap
278 \value QMatrix QMatrix
279 \value QTransform QTransform
280 \value QMatrix4x4 QMatrix4x4
281 \value QVector2D QVector2D
282 \value QVector3D QVector3D
283 \value QVector4D QVector4D
284 \value QQuaternion QQuaternion
285 \value QEasingCurve QEasingCurve
286 \value QJsonValue QJsonValue
287 \value QJsonObject QJsonObject
288 \value QJsonArray QJsonArray
289 \value QJsonDocument QJsonDocument
290 \value QModelIndex QModelIndex
291 \value QPersistentModelIndex QPersistentModelIndex (since 5.5)
292 \value QUuid QUuid
293 \value QByteArrayList QByteArrayList
294
295 \value User Base value for user types
296 \value UnknownType This is an invalid type id. It is returned from QMetaType for types that are not registered
297 \omitvalue LastCoreType
298 \omitvalue LastGuiType
299
300 Additional types can be registered using Q_DECLARE_METATYPE().
301
302 \sa type(), typeName()
303*/
304
305/*!
306 \enum QMetaType::TypeFlag
307
308 The enum describes attributes of a type supported by QMetaType.
309
310 \value NeedsConstruction This type has non-trivial constructors. If the flag is not set instances can be safely initialized with memset to 0.
311 \value NeedsDestruction This type has a non-trivial destructor. If the flag is not set calls to the destructor are not necessary before discarding objects.
312 \value MovableType An instance of a type having this attribute can be safely moved by memcpy.
313 \omitvalue SharedPointerToQObject
314 \value IsEnumeration This type is an enumeration
315 \value PointerToQObject This type is a pointer to a derived of QObject
316 \omitvalue WeakPointerToQObject
317 \omitvalue TrackingPointerToQObject
318 \omitvalue WasDeclaredAsMetaType
319 \omitvalue IsGadget \omit This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5. \endomit
320 \omitvalue PointerToGadget
321*/
322
323/*!
324 \class QMetaType
325 \inmodule QtCore
326 \brief The QMetaType class manages named types in the meta-object system.
327
328 \ingroup objectmodel
329 \threadsafe
330
331 The class is used as a helper to marshall types in QVariant and
332 in queued signals and slots connections. It associates a type
333 name to a type so that it can be created and destructed
334 dynamically at run-time. Declare new types with Q_DECLARE_METATYPE()
335 to make them available to QVariant and other template-based functions.
336 Call qRegisterMetaType() to make types available to non-template based
337 functions, such as the queued signal and slot connections.
338
339 Any class or struct that has a public default
340 constructor, a public copy constructor, and a public destructor
341 can be registered.
342
343 The following code allocates and destructs an instance of
344 \c{MyClass}:
345
346 \snippet code/src_corelib_kernel_qmetatype.cpp 3
347
348 If we want the stream operators \c operator<<() and \c
349 operator>>() to work on QVariant objects that store custom types,
350 the custom type must provide \c operator<<() and \c operator>>()
351 operators.
352
353 \sa Q_DECLARE_METATYPE(), QVariant::setValue(), QVariant::value(), QVariant::fromValue()
354*/
355
356/*!
357 \fn bool QMetaType::isValid() const
358 \since 5.0
359
360 Returns \c true if this QMetaType object contains valid
361 information about a type, false otherwise.
362*/
363
364/*!
365 \fn bool QMetaType::isRegistered() const
366 \since 5.0
367
368 Returns \c true if this QMetaType object contains valid
369 information about a type, false otherwise.
370*/
371
372/*!
373 \fn bool QMetaType::sizeOf() const
374 \since 5.0
375
376 Returns the size of the type in bytes (i.e. sizeof(T),
377 where T is the actual type for which this QMetaType instance
378 was constructed for).
379
380 This function is typically used together with construct()
381 to perform low-level management of the memory used by a type.
382
383 \sa QMetaType::construct(), QMetaType::sizeOf()
384*/
385
386/*!
387 \fn TypeFlags QMetaType::flags() const
388 \since 5.0
389
390 Returns flags of the type for which this QMetaType instance was constructed.
391
392 \sa QMetaType::TypeFlags, QMetaType::typeFlags()
393*/
394
395/*!
396 \fn const QMetaObject *QMetaType::metaObject() const
397 \since 5.5
398
399 return a QMetaObject relative to this type.
400
401 If the type is a pointer type to a subclass of QObject, flags() contains
402 QMetaType::PointerToQObject and this function returns the corresponding QMetaObject. This can
403 be used to in combinaison with QMetaObject::construct to create QObject of this type.
404
405 If the type is a Q_GADGET, flags() contains QMetaType::IsGadget, and this function returns its
406 QMetaObject. This can be used to retrieve QMetaMethod and QMetaProperty and use them on a
407 pointer of this type. (given by QVariant::data for example)
408
409 If the type is an enumeration, flags() contains QMetaType::IsEnumeration, and this function
410 returns the QMetaObject of the enclosing object if the enum was registered as a Q_ENUM or 0
411 otherwise
412
413 \sa QMetaType::metaObjectForType(), QMetaType::flags()
414*/
415
416/*!
417 \fn void *QMetaType::create(const void *copy = 0) const
418 \since 5.0
419
420 Returns a copy of \a copy, assuming it is of the type that this
421 QMetaType instance was created for. If \a copy is null, creates
422 a default constructed instance.
423
424 \sa QMetaType::destroy()
425*/
426
427/*!
428 \fn void QMetaType::destroy(void *data) const
429 \since 5.0
430
431 Destroys the \a data, assuming it is of the type that this
432 QMetaType instance was created for.
433
434 \sa QMetaType::create()
435*/
436
437/*!
438 \fn void *QMetaType::construct(int type, const void *copy)
439 \deprecated
440
441 Constructs a value of the given type which is a copy of \a copy.
442 The default value for \a copy is 0.
443
444 Deprecated, use the static function QMetaType::create(int type,
445 const void *copy) instead.
446*/
447/*!
448 \fn void *QMetaType::construct(void *where, const void *copy = 0) const
449 \since 5.0
450
451 Constructs a value of the type that this QMetaType instance
452 was constructed for in the existing memory addressed by \a where,
453 that is a copy of \a copy, and returns \a where. If \a copy is
454 zero, the value is default constructed.
455
456 This is a low-level function for explicitly managing the memory
457 used to store the type. Consider calling create() if you don't
458 need this level of control (that is, use "new" rather than
459 "placement new").
460
461 You must ensure that \a where points to a location where the new
462 value can be stored and that \a where is suitably aligned.
463 The type's size can be queried by calling sizeOf().
464
465 The rule of thumb for alignment is that a type is aligned to its
466 natural boundary, which is the smallest power of 2 that is bigger
467 than the type, unless that alignment is larger than the maximum
468 useful alignment for the platform. For practical purposes,
469 alignment larger than 2 * sizeof(void*) is only necessary for
470 special hardware instructions (e.g., aligned SSE loads and stores
471 on x86).
472*/
473
474/*!
475 \fn void QMetaType::destruct(void *data) const
476 \since 5.0
477
478 Destructs the value, located at \a data, assuming that it is
479 of the type for which this QMetaType instance was constructed for.
480
481 Unlike destroy(), this function only invokes the type's
482 destructor, it doesn't invoke the delete operator.
483 \sa QMetaType::construct()
484*/
485
486/*!
487 \fn QMetaType::~QMetaType()
488
489 Destructs this object.
490*/
491
492#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
493 { #RealName, sizeof(#RealName) - 1, MetaTypeId },
494
495#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr) \
496 { RealNameStr, sizeof(RealNameStr) - 1, QMetaType::MetaTypeName },
497
498#define QT_ADD_STATIC_METATYPE_HACKS_ITER(MetaTypeName, TypeId, Name) \
499 QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeName, Name)
500
501static const struct { const char * typeName; int typeNameLength; int type; } types[] = {
502 QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE)
503 QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER)
504 QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER)
505 {0, 0, QMetaType::UnknownType}
506};
507
508Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0;
509Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = 0;
510Q_CORE_EXPORT const QMetaObject *qMetaObjectWidgetsHelper = 0;
511
512class QCustomTypeInfo : public QMetaTypeInterface
513{
514public:
515 QCustomTypeInfo()
516 : alias(-1)
517 {
518 QMetaTypeInterface empty = QT_METATYPE_INTERFACE_INIT(void);
519 *static_cast<QMetaTypeInterface*>(this) = empty;
520 }
521 QByteArray typeName;
522 int alias;
523};
524
525template<typename T, typename Key>
526class QMetaTypeFunctionRegistry
527{
528public:
529 ~QMetaTypeFunctionRegistry()
530 {
531 const QWriteLocker locker(&lock);
532 map.clear();
533 }
534
535 bool contains(Key k) const
536 {
537 const QReadLocker locker(&lock);
538 return map.contains(k);
539 }
540
541 bool insertIfNotContains(Key k, const T *f)
542 {
543 const QWriteLocker locker(&lock);
544 const T* &fun = map[k];
545 if (fun != 0)
546 return false;
547 fun = f;
548 return true;
549 }
550
551 const T *function(Key k) const
552 {
553 const QReadLocker locker(&lock);
554 return map.value(k, 0);
555 }
556
557 void remove(int from, int to)
558 {
559 const Key k(from, to);
560 const QWriteLocker locker(&lock);
561 map.remove(k);
562 }
563private:
564 mutable QReadWriteLock lock;
565 QHash<Key, const T *> map;
566};
567
568typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractConverterFunction,QPair<int,int> >
569QMetaTypeConverterRegistry;
570typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractComparatorFunction,int>
571QMetaTypeComparatorRegistry;
572typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractDebugStreamFunction,int>
573QMetaTypeDebugStreamRegistry;
574
575namespace
576{
577union CheckThatItIsPod
578{ // This should break if QMetaTypeInterface is not a POD type
579 QMetaTypeInterface iface;
580};
581}
582
583Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
584Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
585Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
586Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
587Q_GLOBAL_STATIC(QMetaTypeComparatorRegistry, customTypesComparatorRegistry)
588Q_GLOBAL_STATIC(QMetaTypeDebugStreamRegistry, customTypesDebugStreamRegistry)
589
590/*!
591 \fn bool QMetaType::registerConverter()
592 \since 5.2
593 Registers the possibility of an implicit conversion from type From to type To in the meta
594 type system. Returns \c true if the registration succeeded, otherwise false.
595*/
596
597/*!
598 \fn template<typename MemberFunction, int> bool QMetaType::registerConverter(MemberFunction function)
599 \since 5.2
600 \overload
601 Registers a method \a function like To From::function() const as converter from type From
602 to type To in the meta type system. Returns \c true if the registration succeeded, otherwise false.
603*/
604
605/*!
606 \fn template<typename MemberFunctionOk, char> bool QMetaType::registerConverter(MemberFunctionOk function)
607 \since 5.2
608 \overload
609 Registers a method \a function like To From::function(bool *ok) const as converter from type From
610 to type To in the meta type system. Returns \c true if the registration succeeded, otherwise false.
611*/
612
613/*!
614 \fn template<typename UnaryFunction> bool QMetaType::registerConverter(UnaryFunction function)
615 \since 5.2
616 \overload
617 Registers a unary function object \a function as converter from type From
618 to type To in the meta type system. Returns \c true if the registration succeeded, otherwise false.
619*/
620
621/*!
622 \fn bool QMetaType::registerComparators()
623 \since 5.2
624 Registers comparison operators for the user-registered type T. This requires T to have
625 both an operator== and an operator<.
626 Returns \c true if the registration succeeded, otherwise false.
627*/
628
629/*!
630 \fn bool QMetaType::registerEqualsComparator()
631 \since 5.5
632 Registers equals operator for the user-registered type T. This requires T to have
633 an operator==.
634 Returns \c true if the registration succeeded, otherwise false.
635*/
636
637#ifndef QT_NO_DEBUG_STREAM
638/*!
639 \fn bool QMetaType::registerDebugStreamOperator()
640 Registers the debug stream operator for the user-registered type T. This requires T to have
641 an operator<<(QDebug dbg, T).
642 Returns \c true if the registration succeeded, otherwise false.
643*/
644#endif
645
646/*!
647 Registers function \a f as converter function from type id \a from to \a to.
648 If there's already a conversion registered, this does nothing but deleting \a f.
649 Returns \c true if the registration succeeded, otherwise false.
650 \since 5.2
651 \internal
652*/
653bool QMetaType::registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to)
654{
655 if (!customTypesConversionRegistry()->insertIfNotContains(qMakePair(from, to), f)) {
656 qWarning("Type conversion already registered from type %s to type %s",
657 QMetaType::typeName(from), QMetaType::typeName(to));
658 return false;
659 }
660 return true;
661}
662
663/*!
664 \internal
665
666 Invoked automatically when a converter function object is destroyed.
667 */
668void QMetaType::unregisterConverterFunction(int from, int to)
669{
670 if (customTypesConversionRegistry.isDestroyed())
671 return;
672 customTypesConversionRegistry()->remove(from, to);
673}
674
675bool QMetaType::registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type)
676{
677 if (!customTypesComparatorRegistry()->insertIfNotContains(type, f)) {
678 qWarning("Comparators already registered for type %s", QMetaType::typeName(type));
679 return false;
680 }
681 return true;
682}
683
684/*!
685 \fn bool QMetaType::hasRegisteredComparators()
686 Returns \c true, if the meta type system has registered comparators for type T.
687 \since 5.2
688 */
689
690/*!
691 Returns \c true, if the meta type system has registered comparators for type id \a typeId.
692 \since 5.2
693 */
694bool QMetaType::hasRegisteredComparators(int typeId)
695{
696 return customTypesComparatorRegistry()->contains(typeId);
697}
698
699#ifndef QT_NO_DEBUG_STREAM
700bool QMetaType::registerDebugStreamOperatorFunction(const QtPrivate::AbstractDebugStreamFunction *f,
701 int type)
702{
703 if (!customTypesDebugStreamRegistry()->insertIfNotContains(type, f)) {
704 qWarning("Debug stream operator already registered for type %s", QMetaType::typeName(type));
705 return false;
706 }
707 return true;
708}
709
710/*!
711 \fn bool QMetaType::hasRegisteredDebugStreamOperator()
712 Returns \c true, if the meta type system has a registered debug stream operator for type T.
713 \since 5.2
714 */
715
716/*!
717 Returns \c true, if the meta type system has a registered debug stream operator for type
718 id \a typeId.
719 \since 5.2
720*/
721bool QMetaType::hasRegisteredDebugStreamOperator(int typeId)
722{
723 return customTypesDebugStreamRegistry()->contains(typeId);
724}
725#endif
726
727/*!
728 Converts the object at \a from from \a fromTypeId to the preallocated space at \a to
729 typed \a toTypeId. Returns \c true, if the conversion succeeded, otherwise false.
730 \since 5.2
731*/
732bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId)
733{
734 const QtPrivate::AbstractConverterFunction * const f =
735 customTypesConversionRegistry()->function(qMakePair(fromTypeId, toTypeId));
736 return f && f->convert(f, from, to);
737}
738
739/*!
740 Compares the objects at \a lhs and \a rhs. Both objects need to be of type \a typeId.
741 \a result is set to less than, equal to or greater than zero, if \a lhs is less than, equal to
742 or greater than \a rhs. Returns \c true, if the comparison succeeded, otherwise \c false.
743 \since 5.2
744*/
745bool QMetaType::compare(const void *lhs, const void *rhs, int typeId, int* result)
746{
747 const QtPrivate::AbstractComparatorFunction * const f =
748 customTypesComparatorRegistry()->function(typeId);
749 if (!f)
750 return false;
751 if (f->equals(f, lhs, rhs))
752 *result = 0;
753 else if (f->lessThan)
754 *result = f->lessThan(f, lhs, rhs) ? -1 : 1;
755 else
756 return false;
757 return true;
758}
759
760/*!
761 Compares the objects at \a lhs and \a rhs. Both objects need to be of type \a typeId.
762 \a result is set to zero, if \a lhs equals to rhs. Returns \c true, if the comparison
763 succeeded, otherwise \c false.
764 \since 5.5
765*/
766bool QMetaType::equals(const void *lhs, const void *rhs, int typeId, int *result)
767{
768 const QtPrivate::AbstractComparatorFunction * const f
769 = customTypesComparatorRegistry()->function(typeId);
770 if (!f)
771 return false;
772 if (f->equals(f, lhs, rhs))
773 *result = 0;
774 else
775 *result = -1;
776 return true;
777}
778
779/*!
780 Streams the object at \a rhs of type \a typeId to the debug stream \a dbg. Returns \c true
781 on success, otherwise false.
782 \since 5.2
783*/
784bool QMetaType::debugStream(QDebug& dbg, const void *rhs, int typeId)
785{
786 const QtPrivate::AbstractDebugStreamFunction * const f = customTypesDebugStreamRegistry()->function(typeId);
787 if (!f)
788 return false;
789 f->stream(f, dbg, rhs);
790 return true;
791}
792
793/*!
794 \fn bool QMetaType::hasRegisteredConverterFunction()
795 Returns \c true, if the meta type system has a registered conversion from type From to type To.
796 \since 5.2
797 \overload
798 */
799
800/*!
801 Returns \c true, if the meta type system has a registered conversion from meta type id \a fromTypeId
802 to \a toTypeId
803 \since 5.2
804*/
805bool QMetaType::hasRegisteredConverterFunction(int fromTypeId, int toTypeId)
806{
807 return customTypesConversionRegistry()->contains(qMakePair(fromTypeId, toTypeId));
808}
809
810#ifndef QT_NO_DATASTREAM
811/*!
812 \internal
813*/
814void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveOp,
815 LoadOperator loadOp)
816{
817 registerStreamOperators(type(typeName), saveOp, loadOp);
818}
819
820/*!
821 \internal
822*/
823void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
824 LoadOperator loadOp)
825{
826 if (idx < User)
827 return; //builtin types should not be registered;
828 QVector<QCustomTypeInfo> *ct = customTypes();
829 if (!ct)
830 return;
831 QWriteLocker locker(customTypesLock());
832 QCustomTypeInfo &inf = (*ct)[idx - User];
833 inf.saveOp = saveOp;
834 inf.loadOp = loadOp;
835}
836#endif // QT_NO_DATASTREAM
837
838#if defined(Q_COMPILER_CONSTEXPR) || (defined(Q_CC_MSVC) && Q_CC_MSVC >= 1900)
839// We don't officially support constexpr in MSVC 2015, but the limited support it
840// has is enough for the code below.
841
842# define STRINGIFY_TYPE_NAME(MetaTypeName, TypeId, RealName) \
843 #RealName "\0"
844# define CALCULATE_TYPE_LEN(MetaTypeName, TypeId, RealName) \
845 short(sizeof(#RealName)),
846# define MAP_TYPE_ID_TO_IDX(MetaTypeName, TypeId, RealName) \
847 TypeId,
848
849namespace {
850// All type names in one long string.
851constexpr char metaTypeStrings[] = QT_FOR_EACH_STATIC_TYPE(STRINGIFY_TYPE_NAME);
852
853// The sizes of the strings in the metaTypeStrings string (including terminating null)
854constexpr short metaTypeNameSizes[] = {
855 QT_FOR_EACH_STATIC_TYPE(CALCULATE_TYPE_LEN)
856};
857
858// The type IDs, in the order of the metaTypeStrings data
859constexpr short metaTypeIds[] = {
860 QT_FOR_EACH_STATIC_TYPE(MAP_TYPE_ID_TO_IDX)
861};
862
863constexpr int MetaTypeNameCount = sizeof(metaTypeNameSizes) / sizeof(metaTypeNameSizes[0]);
864
865template <typename IntegerSequence> struct MetaTypeOffsets;
866template <int... TypeIds> struct MetaTypeOffsets<QtPrivate::IndexesList<TypeIds...>>
867{
868 // This would have been a lot easier if the meta types that the macro
869 // QT_FOR_EACH_STATIC_TYPE declared were in sorted, ascending order, but
870 // they're not (i.e., the first one declared is QMetaType::Void == 43,
871 // followed by QMetaType::Bool == 1)... As a consequence, we need to use
872 // the C++11 constexpr function calculateOffsetForTypeId below in order to
873 // create the offset array.
874
875 static constexpr int findTypeId(int typeId, int i = 0)
876 {
877 return i >= MetaTypeNameCount ? -1 :
878 metaTypeIds[i] == typeId ? i : findTypeId(typeId, i + 1);
879 }
880
881 static constexpr short calculateOffsetForIdx(int i)
882 {
883 return i < 0 ? -1 :
884 i == 0 ? 0 : metaTypeNameSizes[i - 1] + calculateOffsetForIdx(i - 1);
885 }
886
887 static constexpr short calculateOffsetForTypeId(int typeId)
888 {
889 return calculateOffsetForIdx(findTypeId(typeId));
890#if 0
891 // same as, but this is only valid in C++14:
892 short offset = 0;
893 for (int i = 0; i < MetaTypeNameCount; ++i) {
894 if (metaTypeIds[i] == typeId)
895 return offset;
896 offset += metaTypeNameSizes[i];
897 }
898 return -1;
899#endif
900 }
901
902 short offsets[sizeof...(TypeIds)];
903 constexpr MetaTypeOffsets() : offsets{calculateOffsetForTypeId(TypeIds)...} {}
904
905 const char *operator[](int typeId) const Q_DECL_NOTHROW
906 {
907 short o = offsets[typeId];
908 return o < 0 ? nullptr : metaTypeStrings + o;
909 }
910};
911} // anonymous namespace
912
913constexpr MetaTypeOffsets<QtPrivate::Indexes<QMetaType::HighestInternalId + 1>::Value> metaTypeNames {};
914# undef STRINGIFY_TYPE_NAME
915# undef CALCULATE_TYPE_LEN
916# undef MAP_TYPE_ID_TO_IDX
917#endif
918
919/*!
920 Returns the type name associated with the given \a typeId, or a null
921 pointer if no matching type was found. The returned pointer must not be
922 deleted.
923
924 \sa type(), isRegistered(), Type
925*/
926const char *QMetaType::typeName(int typeId)
927{
928 const uint type = typeId;
929#define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \
930 case QMetaType::MetaTypeName: return #RealName; break;
931
932 if (Q_LIKELY(type <= QMetaType::HighestInternalId)) {
933#if defined(Q_COMPILER_CONSTEXPR) || (defined(Q_CC_MSVC) && Q_CC_MSVC >= 1900)
934 return metaTypeNames[typeId];
935#else
936 switch (QMetaType::Type(type)) {
937 QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER)
938 case QMetaType::UnknownType:
939 case QMetaType::User:
940 break;
941 }
942#endif
943 } else if (Q_UNLIKELY(type < QMetaType::User)) {
944 return nullptr; // It can happen when someone cast int to QVariant::Type, we should not crash...
945 }
946
947 const QVector<QCustomTypeInfo> * const ct = customTypes();
948 QReadLocker locker(customTypesLock());
949 return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty()
950 ? ct->at(type - QMetaType::User).typeName.constData()
951 : nullptr;
952
953#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
954}
955
956/*
957 Similar to QMetaType::type(), but only looks in the static set of types.
958*/
959static inline int qMetaTypeStaticType(const char *typeName, int length)
960{
961 int i = 0;
962 while (types[i].typeName && ((length != types[i].typeNameLength)
963 || memcmp(typeName, types[i].typeName, length))) {
964 ++i;
965 }
966 return types[i].type;
967}
968
969/*
970 Similar to QMetaType::type(), but only looks in the custom set of
971 types, and doesn't lock the mutex.
972 The extra \a firstInvalidIndex parameter is an easy way to avoid
973 iterating over customTypes() a second time in registerNormalizedType().
974*/
975static int qMetaTypeCustomType_unlocked(const char *typeName, int length, int *firstInvalidIndex = 0)
976{
977 const QVector<QCustomTypeInfo> * const ct = customTypes();
978 if (!ct)
979 return QMetaType::UnknownType;
980
981 if (firstInvalidIndex)
982 *firstInvalidIndex = -1;
983 for (int v = 0; v < ct->count(); ++v) {
984 const QCustomTypeInfo &customInfo = ct->at(v);
985 if ((length == customInfo.typeName.size())
986 && !memcmp(typeName, customInfo.typeName.constData(), length)) {
987 if (customInfo.alias >= 0)
988 return customInfo.alias;
989 return v + QMetaType::User;
990 }
991 if (firstInvalidIndex && (*firstInvalidIndex < 0) && customInfo.typeName.isEmpty())
992 *firstInvalidIndex = v;
993 }
994 return QMetaType::UnknownType;
995}
996
997/*!
998 \internal
999
1000 This function is needed until existing code outside of qtbase
1001 has been changed to call the new version of registerType().
1002 */
1003int QMetaType::registerType(const char *typeName, Deleter deleter,
1004 Creator creator)
1005{
1006 return registerType(typeName, deleter, creator,
1007 QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
1008 QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct, 0, TypeFlags(), 0);
1009}
1010
1011/*!
1012 \internal
1013 \since 5.5
1014
1015 Unregisters the user type with the given \a typeId and all its aliases.
1016 Returns \c true if the type was unregistered or \c false otherwise.
1017
1018 This function was added for QML to be able to deregister types after
1019 they are unloaded to prevent an infinite increase in custom types for
1020 applications that are unloading/reloading components often.
1021 */
1022bool QMetaType::unregisterType(int type)
1023{
1024 QWriteLocker locker(customTypesLock());
1025 QVector<QCustomTypeInfo> *ct = customTypes();
1026
1027 // check if user type
1028 if ((type < User) || ((type - User) >= ct->size()))
1029 return false;
1030
1031 // only types without Q_DECLARE_METATYPE can be unregistered
1032 if (ct->data()[type - User].flags & WasDeclaredAsMetaType)
1033 return false;
1034
1035 // invalidate type and all its alias entries
1036 for (int v = 0; v < ct->count(); ++v) {
1037 if (((v + User) == type) || (ct->at(v).alias == type))
1038 ct->data()[v].typeName.clear();
1039 }
1040 return true;
1041}
1042
1043
1044/*!
1045 \internal
1046 \since 5.0
1047
1048 Registers a user type for marshalling, with \a typeName, a \a
1049 deleter, a \a creator, a \a destructor, a \a constructor, and
1050 a \a size. Returns the type's handle, or -1 if the type could
1051 not be registered.
1052 */
1053int QMetaType::registerType(const char *typeName, Deleter deleter,
1054 Creator creator,
1055 Destructor destructor,
1056 Constructor constructor,
1057 int size, TypeFlags flags, const QMetaObject *metaObject)
1058{
1059#ifdef QT_NO_QOBJECT
1060 NS(QByteArray) normalizedTypeName = typeName;
1061#else
1062 NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
1063#endif
1064
1065 return registerNormalizedType(normalizedTypeName, deleter, creator, destructor, constructor, size, flags, metaObject);
1066}
1067
1068
1069/*!
1070 \internal
1071 \since 5.0
1072 \overload
1073 Don't use, kept for binary compatibility
1074
1075 ### TODO Qt6: remove me
1076*/
1077int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter,
1078 Creator creator,
1079 Destructor destructor,
1080 Constructor constructor,
1081 int size, TypeFlags flags, const QMetaObject *metaObject)
1082{
1083 Q_UNUSED(deleter);
1084 Q_UNUSED(creator);
1085 return registerNormalizedType(normalizedTypeName, destructor, constructor, size, flags, metaObject);
1086}
1087
1088
1089/*!
1090 \internal
1091 \since 5.5
1092
1093 Registers a user type for marshalling, with \a normalizedTypeName,
1094 a \a destructor, a \a constructor, and a \a size. Returns the type's
1095 handle, or -1 if the type could not be registered.
1096
1097 \note normalizedTypeName is not checked for conformance with
1098 Qt's normalized format, so it must already conform.
1099 */
1100int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
1101 Destructor destructor,
1102 Constructor constructor,
1103 int size, TypeFlags flags, const QMetaObject *metaObject)
1104{
1105 QVector<QCustomTypeInfo> *ct = customTypes();
1106 if (!ct || normalizedTypeName.isEmpty() || !destructor || !constructor)
1107 return -1;
1108
1109 int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
1110 normalizedTypeName.size());
1111
1112 int previousSize = 0;
1113 QMetaType::TypeFlags::Int previousFlags = 0;
1114 if (idx == UnknownType) {
1115 QWriteLocker locker(customTypesLock());
1116 int posInVector = -1;
1117 idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
1118 normalizedTypeName.size(),
1119 &posInVector);
1120 if (idx == UnknownType) {
1121 QCustomTypeInfo inf;
1122 inf.typeName = normalizedTypeName;
1123#ifndef QT_NO_DATASTREAM
1124 inf.loadOp = 0;
1125 inf.saveOp = 0;
1126#endif
1127 inf.alias = -1;
1128 inf.constructor = constructor;
1129 inf.destructor = destructor;
1130 inf.size = size;
1131 inf.flags = flags;
1132 inf.metaObject = metaObject;
1133 if (posInVector == -1) {
1134 idx = ct->size() + User;
1135 ct->append(inf);
1136 } else {
1137 idx = posInVector + User;
1138 ct->data()[posInVector] = inf;
1139 }
1140 return idx;
1141 }
1142
1143 if (idx >= User) {
1144 previousSize = ct->at(idx - User).size;
1145 previousFlags = ct->at(idx - User).flags;
1146
1147 // Set new/additional flags in case of old library/app.
1148 // Ensures that older code works in conjunction with new Qt releases
1149 // requiring the new flags.
1150 if (flags != previousFlags) {
1151 QCustomTypeInfo &inf = ct->data()[idx - User];
1152 inf.flags |= flags;
1153 if (metaObject)
1154 inf.metaObject = metaObject;
1155 }
1156 }
1157 }
1158
1159 if (idx < User) {
1160 previousSize = QMetaType::sizeOf(idx);
1161 previousFlags = QMetaType::typeFlags(idx);
1162 }
1163
1164 if (Q_UNLIKELY(previousSize != size)) {
1165 qFatal("QMetaType::registerType: Binary compatibility break "
1166 "-- Size mismatch for type '%s' [%i]. Previously registered "
1167 "size %i, now registering size %i.",
1168 normalizedTypeName.constData(), idx, previousSize, size);
1169 }
1170
1171 // these flags cannot change in a binary compatible way:
1172 const int binaryCompatibilityFlag = PointerToQObject | IsEnumeration | SharedPointerToQObject
1173 | WeakPointerToQObject | TrackingPointerToQObject;
1174 if (Q_UNLIKELY((previousFlags ^ flags) & binaryCompatibilityFlag)) {
1175
1176 const char *msg = "QMetaType::registerType: Binary compatibility break. "
1177 "\nType flags for type '%s' [%i] don't match. Previously "
1178 "registered TypeFlags(0x%x), now registering TypeFlags(0x%x). ";
1179
1180 qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags));
1181 }
1182
1183 return idx;
1184}
1185
1186/*!
1187 \internal
1188 \since 4.7
1189
1190 Registers a user type for marshalling, as an alias of another type (typedef)
1191*/
1192int QMetaType::registerTypedef(const char* typeName, int aliasId)
1193{
1194#ifdef QT_NO_QOBJECT
1195 NS(QByteArray) normalizedTypeName = typeName;
1196#else
1197 NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
1198#endif
1199
1200 return registerNormalizedTypedef(normalizedTypeName, aliasId);
1201}
1202
1203/*!
1204 \internal
1205 \since 5.0
1206
1207 Registers a user type for marshalling, as an alias of another type (typedef).
1208 Note that normalizedTypeName is not checked for conformance with Qt's normalized format,
1209 so it must already conform.
1210*/
1211int QMetaType::registerNormalizedTypedef(const NS(QByteArray) &normalizedTypeName, int aliasId)
1212{
1213 QVector<QCustomTypeInfo> *ct = customTypes();
1214 if (!ct || normalizedTypeName.isEmpty())
1215 return -1;
1216
1217 int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
1218 normalizedTypeName.size());
1219
1220 if (idx == UnknownType) {
1221 QWriteLocker locker(customTypesLock());
1222 int posInVector = -1;
1223 idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
1224 normalizedTypeName.size(),
1225 &posInVector);
1226
1227 if (idx == UnknownType) {
1228 QCustomTypeInfo inf;
1229 inf.typeName = normalizedTypeName;
1230 inf.alias = aliasId;
1231 if (posInVector == -1)
1232 ct->append(inf);
1233 else
1234 ct->data()[posInVector] = inf;
1235 return aliasId;
1236 }
1237 }
1238
1239 if (idx != aliasId) {
1240 qWarning("QMetaType::registerTypedef: "
1241 "-- Type name '%s' previously registered as typedef of '%s' [%i], "
1242 "now registering as typedef of '%s' [%i].",
1243 normalizedTypeName.constData(), QMetaType::typeName(idx), idx,
1244 QMetaType::typeName(aliasId), aliasId);
1245 }
1246 return idx;
1247}
1248
1249/*!
1250 Returns \c true if the datatype with ID \a type is registered;
1251 otherwise returns \c false.
1252
1253 \sa type(), typeName(), Type
1254*/
1255bool QMetaType::isRegistered(int type)
1256{
1257 // predefined type
1258 if ((type >= FirstCoreType && type <= LastCoreType)
1259 || (type >= FirstGuiType && type <= LastGuiType)
1260 || (type >= FirstWidgetsType && type <= LastWidgetsType)) {
1261 return true;
1262 }
1263
1264 QReadLocker locker(customTypesLock());
1265 const QVector<QCustomTypeInfo> * const ct = customTypes();
1266 return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
1267}
1268
1269template <bool tryNormalizedType>
1270static inline int qMetaTypeTypeImpl(const char *typeName, int length)
1271{
1272 if (!length)
1273 return QMetaType::UnknownType;
1274 int type = qMetaTypeStaticType(typeName, length);
1275 if (type == QMetaType::UnknownType) {
1276 QReadLocker locker(customTypesLock());
1277 type = qMetaTypeCustomType_unlocked(typeName, length);
1278#ifndef QT_NO_QOBJECT
1279 if ((type == QMetaType::UnknownType) && tryNormalizedType) {
1280 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
1281 type = qMetaTypeStaticType(normalizedTypeName.constData(),
1282 normalizedTypeName.size());
1283 if (type == QMetaType::UnknownType) {
1284 type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
1285 normalizedTypeName.size());
1286 }
1287 }
1288#endif
1289 }
1290 return type;
1291}
1292
1293/*!
1294 Returns a handle to the type called \a typeName, or QMetaType::UnknownType if there is
1295 no such type.
1296
1297 \sa isRegistered(), typeName(), Type
1298*/
1299int QMetaType::type(const char *typeName)
1300{
1301 return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName, qstrlen(typeName));
1302}
1303
1304/*!
1305 \a internal
1306
1307 Similar to QMetaType::type(); the only difference is that this function
1308 doesn't attempt to normalize the type name (i.e., the lookup will fail
1309 for type names in non-normalized form).
1310*/
1311int qMetaTypeTypeInternal(const char *typeName)
1312{
1313 return qMetaTypeTypeImpl</*tryNormalizedType=*/false>(typeName, qstrlen(typeName));
1314}
1315
1316/*!
1317 \since 5.5
1318 \overload
1319
1320 Returns a handle to the type called \a typeName, or 0 if there is
1321 no such type.
1322
1323 \sa isRegistered(), typeName()
1324*/
1325int QMetaType::type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName)
1326{
1327 return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName.constData(), typeName.size());
1328}
1329
1330#ifndef QT_NO_DATASTREAM
1331/*!
1332 Writes the object pointed to by \a data with the ID \a type to
1333 the given \a stream. Returns \c true if the object is saved
1334 successfully; otherwise returns \c false.
1335
1336 The type must have been registered with qRegisterMetaType() and
1337 qRegisterMetaTypeStreamOperators() beforehand.
1338
1339 Normally, you should not need to call this function directly.
1340 Instead, use QVariant's \c operator<<(), which relies on save()
1341 to stream custom types.
1342
1343 \sa load(), qRegisterMetaTypeStreamOperators()
1344*/
1345bool QMetaType::save(QDataStream &stream, int type, const void *data)
1346{
1347 if (!data || !isRegistered(type))
1348 return false;
1349
1350 switch(type) {
1351 case QMetaType::UnknownType:
1352 case QMetaType::Void:
1353 case QMetaType::VoidStar:
1354 case QMetaType::QObjectStar:
1355#if QT_CONFIG(itemmodel)
1356 case QMetaType::QModelIndex:
1357 case QMetaType::QPersistentModelIndex:
1358#endif
1359 case QMetaType::QJsonValue:
1360 case QMetaType::QJsonObject:
1361 case QMetaType::QJsonArray:
1362 case QMetaType::QJsonDocument:
1363 return false;
1364 case QMetaType::Nullptr:
1365 stream << *static_cast<const std::nullptr_t *>(data);
1366 return true;
1367 case QMetaType::Long:
1368 stream << qlonglong(*static_cast<const long *>(data));
1369 break;
1370 case QMetaType::Int:
1371 stream << *static_cast<const int *>(data);
1372 break;
1373 case QMetaType::Short:
1374 stream << *static_cast<const short *>(data);
1375 break;
1376 case QMetaType::Char:
1377 // force a char to be signed
1378 stream << *static_cast<const signed char *>(data);
1379 break;
1380 case QMetaType::ULong:
1381 stream << qulonglong(*static_cast<const ulong *>(data));
1382 break;
1383 case QMetaType::UInt:
1384 stream << *static_cast<const uint *>(data);
1385 break;
1386 case QMetaType::LongLong:
1387 stream << *static_cast<const qlonglong *>(data);
1388 break;
1389 case QMetaType::ULongLong:
1390 stream << *static_cast<const qulonglong *>(data);
1391 break;
1392 case QMetaType::UShort:
1393 stream << *static_cast<const ushort *>(data);
1394 break;
1395 case QMetaType::SChar:
1396 stream << *static_cast<const signed char *>(data);
1397 break;
1398 case QMetaType::UChar:
1399 stream << *static_cast<const uchar *>(data);
1400 break;
1401 case QMetaType::Bool:
1402 stream << qint8(*static_cast<const bool *>(data));
1403 break;
1404 case QMetaType::Float:
1405 stream << *static_cast<const float *>(data);
1406 break;
1407 case QMetaType::Double:
1408 stream << *static_cast<const double *>(data);
1409 break;
1410 case QMetaType::QChar:
1411 stream << *static_cast<const NS(QChar) *>(data);
1412 break;
1413#ifndef QT_BOOTSTRAPPED
1414 case QMetaType::QVariantMap:
1415 stream << *static_cast<const NS(QVariantMap)*>(data);
1416 break;
1417 case QMetaType::QVariantHash:
1418 stream << *static_cast<const NS(QVariantHash)*>(data);
1419 break;
1420 case QMetaType::QVariantList:
1421 stream << *static_cast<const NS(QVariantList)*>(data);
1422 break;
1423 case QMetaType::QVariant:
1424 stream << *static_cast<const NS(QVariant)*>(data);
1425 break;
1426 case QMetaType::QByteArrayList:
1427 stream << *static_cast<const NS(QByteArrayList)*>(data);
1428 break;
1429#endif
1430 case QMetaType::QByteArray:
1431 stream << *static_cast<const NS(QByteArray)*>(data);
1432 break;
1433 case QMetaType::QString:
1434 stream << *static_cast<const NS(QString)*>(data);
1435 break;
1436 case QMetaType::QStringList:
1437 stream << *static_cast<const NS(QStringList)*>(data);
1438 break;
1439#ifndef QT_BOOTSTRAPPED
1440 case QMetaType::QBitArray:
1441 stream << *static_cast<const NS(QBitArray)*>(data);
1442 break;
1443#endif
1444 case QMetaType::QDate:
1445 stream << *static_cast<const NS(QDate)*>(data);
1446 break;
1447 case QMetaType::QTime:
1448 stream << *static_cast<const NS(QTime)*>(data);
1449 break;
1450 case QMetaType::QDateTime:
1451 stream << *static_cast<const NS(QDateTime)*>(data);
1452 break;
1453#ifndef QT_BOOTSTRAPPED
1454 case QMetaType::QUrl:
1455 stream << *static_cast<const NS(QUrl)*>(data);
1456 break;
1457#endif
1458 case QMetaType::QLocale:
1459 stream << *static_cast<const NS(QLocale)*>(data);
1460 break;
1461#ifndef QT_NO_GEOM_VARIANT
1462 case QMetaType::QRect:
1463 stream << *static_cast<const NS(QRect)*>(data);
1464 break;
1465 case QMetaType::QRectF:
1466 stream << *static_cast<const NS(QRectF)*>(data);
1467 break;
1468 case QMetaType::QSize:
1469 stream << *static_cast<const NS(QSize)*>(data);
1470 break;
1471 case QMetaType::QSizeF:
1472 stream << *static_cast<const NS(QSizeF)*>(data);
1473 break;
1474 case QMetaType::QLine:
1475 stream << *static_cast<const NS(QLine)*>(data);
1476 break;
1477 case QMetaType::QLineF:
1478 stream << *static_cast<const NS(QLineF)*>(data);
1479 break;
1480 case QMetaType::QPoint:
1481 stream << *static_cast<const NS(QPoint)*>(data);
1482 break;
1483 case QMetaType::QPointF:
1484 stream << *static_cast<const NS(QPointF)*>(data);
1485 break;
1486#endif
1487#ifndef QT_NO_REGEXP
1488 case QMetaType::QRegExp:
1489 stream << *static_cast<const NS(QRegExp)*>(data);
1490 break;
1491#endif
1492#if QT_CONFIG(regularexpression)
1493 case QMetaType::QRegularExpression:
1494 stream << *static_cast<const NS(QRegularExpression)*>(data);
1495 break;
1496#endif // QT_CONFIG(regularexpression)
1497#ifndef QT_BOOTSTRAPPED
1498 case QMetaType::QEasingCurve:
1499 stream << *static_cast<const NS(QEasingCurve)*>(data);
1500 break;
1501#endif // QT_BOOTSTRAPPED
1502 case QMetaType::QFont:
1503 case QMetaType::QPixmap:
1504 case QMetaType::QBrush:
1505 case QMetaType::QColor:
1506 case QMetaType::QPalette:
1507 case QMetaType::QImage:
1508 case QMetaType::QPolygon:
1509 case QMetaType::QPolygonF:
1510 case QMetaType::QRegion:
1511 case QMetaType::QBitmap:
1512 case QMetaType::QCursor:
1513 case QMetaType::QKeySequence:
1514 case QMetaType::QPen:
1515 case QMetaType::QTextLength:
1516 case QMetaType::QTextFormat:
1517 case QMetaType::QMatrix:
1518 case QMetaType::QTransform:
1519 case QMetaType::QMatrix4x4:
1520 case QMetaType::QVector2D:
1521 case QMetaType::QVector3D:
1522 case QMetaType::QVector4D:
1523 case QMetaType::QQuaternion:
1524 case QMetaType::QIcon:
1525 if (!qMetaTypeGuiHelper)
1526 return false;
1527 qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
1528 break;
1529 case QMetaType::QSizePolicy:
1530 if (!qMetaTypeWidgetsHelper)
1531 return false;
1532 qMetaTypeWidgetsHelper[type - FirstWidgetsType].saveOp(stream, data);
1533 break;
1534 case QMetaType::QUuid:
1535 stream << *static_cast<const NS(QUuid)*>(data);
1536 break;
1537 default: {
1538 const QVector<QCustomTypeInfo> * const ct = customTypes();
1539 if (!ct)
1540 return false;
1541
1542 SaveOperator saveOp = 0;
1543 {
1544 QReadLocker locker(customTypesLock());
1545 saveOp = ct->at(type - User).saveOp;
1546 }
1547
1548 if (!saveOp)
1549 return false;
1550 saveOp(stream, data);
1551 break; }
1552 }
1553
1554 return true;
1555}
1556
1557/*!
1558 Reads the object of the specified \a type from the given \a
1559 stream into \a data. Returns \c true if the object is loaded
1560 successfully; otherwise returns \c false.
1561
1562 The type must have been registered with qRegisterMetaType() and
1563 qRegisterMetaTypeStreamOperators() beforehand.
1564
1565 Normally, you should not need to call this function directly.
1566 Instead, use QVariant's \c operator>>(), which relies on load()
1567 to stream custom types.
1568
1569 \sa save(), qRegisterMetaTypeStreamOperators()
1570*/
1571bool QMetaType::load(QDataStream &stream, int type, void *data)
1572{
1573 if (!data || !isRegistered(type))
1574 return false;
1575
1576 switch(type) {
1577 case QMetaType::UnknownType:
1578 case QMetaType::Void:
1579 case QMetaType::VoidStar:
1580 case QMetaType::QObjectStar:
1581#if QT_CONFIG(itemmodel)
1582 case QMetaType::QModelIndex:
1583 case QMetaType::QPersistentModelIndex:
1584#endif
1585 case QMetaType::QJsonValue:
1586 case QMetaType::QJsonObject:
1587 case QMetaType::QJsonArray:
1588 case QMetaType::QJsonDocument:
1589 return false;
1590 case QMetaType::Nullptr:
1591 stream >> *static_cast<std::nullptr_t *>(data);
1592 return true;
1593 case QMetaType::Long: {
1594 qlonglong l;
1595 stream >> l;
1596 *static_cast<long *>(data) = long(l);
1597 break; }
1598 case QMetaType::Int:
1599 stream >> *static_cast<int *>(data);
1600 break;
1601 case QMetaType::Short:
1602 stream >> *static_cast<short *>(data);
1603 break;
1604 case QMetaType::Char:
1605 // force a char to be signed
1606 stream >> *static_cast<signed char *>(data);
1607 break;
1608 case QMetaType::ULong: {
1609 qulonglong ul;
1610 stream >> ul;
1611 *static_cast<ulong *>(data) = ulong(ul);
1612 break; }
1613 case QMetaType::UInt:
1614 stream >> *static_cast<uint *>(data);
1615 break;
1616 case QMetaType::LongLong:
1617 stream >> *static_cast<qlonglong *>(data);
1618 break;
1619 case QMetaType::ULongLong:
1620 stream >> *static_cast<qulonglong *>(data);
1621 break;
1622 case QMetaType::UShort:
1623 stream >> *static_cast<ushort *>(data);
1624 break;
1625 case QMetaType::SChar:
1626 stream >> *static_cast<signed char *>(data);
1627 break;
1628 case QMetaType::UChar:
1629 stream >> *static_cast<uchar *>(data);
1630 break;
1631 case QMetaType::Bool: {
1632 qint8 b;
1633 stream >> b;
1634 *static_cast<bool *>(data) = b;
1635 break; }
1636 case QMetaType::Float:
1637 stream >> *static_cast<float *>(data);
1638 break;
1639 case QMetaType::Double:
1640 stream >> *static_cast<double *>(data);
1641 break;
1642 case QMetaType::QChar:
1643 stream >> *static_cast< NS(QChar)*>(data);
1644 break;
1645#ifndef QT_BOOTSTRAPPED
1646 case QMetaType::QVariantMap:
1647 stream >> *static_cast< NS(QVariantMap)*>(data);
1648 break;
1649 case QMetaType::QVariantHash:
1650 stream >> *static_cast< NS(QVariantHash)*>(data);
1651 break;
1652 case QMetaType::QVariantList:
1653 stream >> *static_cast< NS(QVariantList)*>(data);
1654 break;
1655 case QMetaType::QVariant:
1656 stream >> *static_cast< NS(QVariant)*>(data);
1657 break;
1658 case QMetaType::QByteArrayList:
1659 stream >> *static_cast< NS(QByteArrayList)*>(data);
1660 break;
1661#endif
1662 case QMetaType::QByteArray:
1663 stream >> *static_cast< NS(QByteArray)*>(data);
1664 break;
1665 case QMetaType::QString:
1666 stream >> *static_cast< NS(QString)*>(data);
1667 break;
1668 case QMetaType::QStringList:
1669 stream >> *static_cast< NS(QStringList)*>(data);
1670 break;
1671#ifndef QT_BOOTSTRAPPED
1672 case QMetaType::QBitArray:
1673 stream >> *static_cast< NS(QBitArray)*>(data);
1674 break;
1675#endif
1676 case QMetaType::QDate:
1677 stream >> *static_cast< NS(QDate)*>(data);
1678 break;
1679 case QMetaType::QTime:
1680 stream >> *static_cast< NS(QTime)*>(data);
1681 break;
1682 case QMetaType::QDateTime:
1683 stream >> *static_cast< NS(QDateTime)*>(data);
1684 break;
1685#ifndef QT_BOOTSTRAPPED
1686 case QMetaType::QUrl:
1687 stream >> *static_cast< NS(QUrl)*>(data);
1688 break;
1689#endif
1690 case QMetaType::QLocale:
1691 stream >> *static_cast< NS(QLocale)*>(data);
1692 break;
1693#ifndef QT_NO_GEOM_VARIANT
1694 case QMetaType::QRect:
1695 stream >> *static_cast< NS(QRect)*>(data);
1696 break;
1697 case QMetaType::QRectF:
1698 stream >> *static_cast< NS(QRectF)*>(data);
1699 break;
1700 case QMetaType::QSize:
1701 stream >> *static_cast< NS(QSize)*>(data);
1702 break;
1703 case QMetaType::QSizeF:
1704 stream >> *static_cast< NS(QSizeF)*>(data);
1705 break;
1706 case QMetaType::QLine:
1707 stream >> *static_cast< NS(QLine)*>(data);
1708 break;
1709 case QMetaType::QLineF:
1710 stream >> *static_cast< NS(QLineF)*>(data);
1711 break;
1712 case QMetaType::QPoint:
1713 stream >> *static_cast< NS(QPoint)*>(data);
1714 break;
1715 case QMetaType::QPointF:
1716 stream >> *static_cast< NS(QPointF)*>(data);
1717 break;
1718#endif
1719#ifndef QT_NO_REGEXP
1720 case QMetaType::QRegExp:
1721 stream >> *static_cast< NS(QRegExp)*>(data);
1722 break;
1723#endif
1724#if QT_CONFIG(regularexpression)
1725 case QMetaType::QRegularExpression:
1726 stream >> *static_cast< NS(QRegularExpression)*>(data);
1727 break;
1728#endif // QT_CONFIG(regularexpression)
1729#ifndef QT_BOOTSTRAPPED
1730 case QMetaType::QEasingCurve:
1731 stream >> *static_cast< NS(QEasingCurve)*>(data);
1732 break;
1733#endif // QT_BOOTSTRAPPED
1734 case QMetaType::QFont:
1735 case QMetaType::QPixmap:
1736 case QMetaType::QBrush:
1737 case QMetaType::QColor:
1738 case QMetaType::QPalette:
1739 case QMetaType::QImage:
1740 case QMetaType::QPolygon:
1741 case QMetaType::QPolygonF:
1742 case QMetaType::QRegion:
1743 case QMetaType::QBitmap:
1744 case QMetaType::QCursor:
1745 case QMetaType::QKeySequence:
1746 case QMetaType::QPen:
1747 case QMetaType::QTextLength:
1748 case QMetaType::QTextFormat:
1749 case QMetaType::QMatrix:
1750 case QMetaType::QTransform:
1751 case QMetaType::QMatrix4x4:
1752 case QMetaType::QVector2D:
1753 case QMetaType::QVector3D:
1754 case QMetaType::QVector4D:
1755 case QMetaType::QQuaternion:
1756 case QMetaType::QIcon:
1757 if (!qMetaTypeGuiHelper)
1758 return false;
1759 qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
1760 break;
1761 case QMetaType::QSizePolicy:
1762 if (!qMetaTypeWidgetsHelper)
1763 return false;
1764 qMetaTypeWidgetsHelper[type - FirstWidgetsType].loadOp(stream, data);
1765 break;
1766 case QMetaType::QUuid:
1767 stream >> *static_cast< NS(QUuid)*>(data);
1768 break;
1769 default: {
1770 const QVector<QCustomTypeInfo> * const ct = customTypes();
1771 if (!ct)
1772 return false;
1773
1774 LoadOperator loadOp = 0;
1775 {
1776 QReadLocker locker(customTypesLock());
1777 loadOp = ct->at(type - User).loadOp;
1778 }
1779
1780 if (!loadOp)
1781 return false;
1782 loadOp(stream, data);
1783 break; }
1784 }
1785 return true;
1786}
1787#endif // QT_NO_DATASTREAM
1788
1789/*!
1790 Returns a copy of \a copy, assuming it is of type \a type. If \a
1791 copy is zero, creates a default constructed instance.
1792
1793 \sa destroy(), isRegistered(), Type
1794*/
1795void *QMetaType::create(int type, const void *copy)
1796{
1797 QMetaType info(type);
1798 if (int size = info.sizeOf())
1799 return info.construct(operator new(size), copy);
1800 return 0;
1801}
1802
1803/*!
1804 Destroys the \a data, assuming it is of the \a type given.
1805
1806 \sa create(), isRegistered(), Type
1807*/
1808void QMetaType::destroy(int type, void *data)
1809{
1810 QMetaType info(type);
1811 info.destruct(data);
1812 operator delete(data);
1813}
1814
1815namespace {
1816class TypeConstructor {
1817 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1818 struct ConstructorImpl {
1819 static void *Construct(const int /*type*/, void *where, const void *copy) { return QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct(where, copy); }
1820 };
1821 template<typename T>
1822 struct ConstructorImpl<T, /* IsAcceptedType = */ false> {
1823 static void *Construct(const int type, void *where, const void *copy)
1824 {
1825 if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
1826 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy) : 0;
1827
1828 if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
1829 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy) : 0;
1830
1831 // This point can be reached only for known types that definition is not available, for example
1832 // in bootstrap mode. We have no other choice then ignore it.
1833 return 0;
1834 }
1835 };
1836public:
1837 TypeConstructor(const int type, void *where)
1838 : m_type(type)
1839 , m_where(where)
1840 {}
1841
1842 template<typename T>
1843 void *delegate(const T *copy) { return ConstructorImpl<T>::Construct(m_type, m_where, copy); }
1844 void *delegate(const void *) { return m_where; }
1845 void *delegate(const QMetaTypeSwitcher::UnknownType*) { return m_where; }
1846 void *delegate(const QMetaTypeSwitcher::NotBuiltinType *copy) { return customTypeConstructor(m_type, m_where, copy); }
1847
1848private:
1849 static void *customTypeConstructor(const int type, void *where, const void *copy)
1850 {
1851 QMetaType::Constructor ctor;
1852 const QVector<QCustomTypeInfo> * const ct = customTypes();
1853 {
1854 QReadLocker locker(customTypesLock());
1855 if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1856 return 0;
1857 ctor = ct->at(type - QMetaType::User).constructor;
1858 }
1859 Q_ASSERT_X(ctor, "void *QMetaType::construct(int type, void *where, const void *copy)", "The type was not properly registered");
1860 return ctor(where, copy);
1861 }
1862
1863 const int m_type;
1864 void *m_where;
1865};
1866} // namespace
1867
1868/*!
1869 \since 5.0
1870
1871 Constructs a value of the given \a type in the existing memory
1872 addressed by \a where, that is a copy of \a copy, and returns
1873 \a where. If \a copy is zero, the value is default constructed.
1874
1875 This is a low-level function for explicitly managing the memory
1876 used to store the type. Consider calling create() if you don't
1877 need this level of control (that is, use "new" rather than
1878 "placement new").
1879
1880 You must ensure that \a where points to a location that can store
1881 a value of type \a type, and that \a where is suitably aligned.
1882 The type's size can be queried by calling sizeOf().
1883
1884 The rule of thumb for alignment is that a type is aligned to its
1885 natural boundary, which is the smallest power of 2 that is bigger
1886 than the type, unless that alignment is larger than the maximum
1887 useful alignment for the platform. For practical purposes,
1888 alignment larger than 2 * sizeof(void*) is only necessary for
1889 special hardware instructions (e.g., aligned SSE loads and stores
1890 on x86).
1891
1892 \sa destruct(), sizeOf()
1893*/
1894void *QMetaType::construct(int type, void *where, const void *copy)
1895{
1896 if (!where)
1897 return 0;
1898 TypeConstructor constructor(type, where);
1899 return QMetaTypeSwitcher::switcher<void*>(constructor, type, copy);
1900}
1901
1902
1903namespace {
1904class TypeDestructor {
1905 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1906 struct DestructorImpl {
1907 static void Destruct(const int /* type */, void *where) { QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct(where); }
1908 };
1909 template<typename T>
1910 struct DestructorImpl<T, /* IsAcceptedType = */ false> {
1911 static void Destruct(const int type, void *where)
1912 {
1913 if (QModulesPrivate::QTypeModuleInfo<T>::IsGui) {
1914 if (Q_LIKELY(qMetaTypeGuiHelper))
1915 qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].destructor(where);
1916 return;
1917 }
1918 if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget) {
1919 if (Q_LIKELY(qMetaTypeWidgetsHelper))
1920 qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].destructor(where);
1921 return;
1922 }
1923 // This point can be reached only for known types that definition is not available, for example
1924 // in bootstrap mode. We have no other choice then ignore it.
1925 }
1926 };
1927public:
1928 TypeDestructor(const int type)
1929 : m_type(type)
1930 {}
1931
1932 template<typename T>
1933 void delegate(const T *where) { DestructorImpl<T>::Destruct(m_type, const_cast<T*>(where)); }
1934 // MSVC2013 and earlier can not const_cast a std::nullptr_t pointer.
1935 void delegate(const std::nullptr_t *) {}
1936 void delegate(const void *) {}
1937 void delegate(const QMetaTypeSwitcher::UnknownType*) {}
1938 void delegate(const QMetaTypeSwitcher::NotBuiltinType *where)
1939 { customTypeDestructor(m_type, const_cast<void *>(static_cast<const void *>(where))); }
1940
1941private:
1942 static void customTypeDestructor(const int type, void *where)
1943 {
1944 QMetaType::Destructor dtor;
1945 const QVector<QCustomTypeInfo> * const ct = customTypes();
1946 {
1947 QReadLocker locker(customTypesLock());
1948 if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
1949 return;
1950 dtor = ct->at(type - QMetaType::User).destructor;
1951 }
1952 Q_ASSERT_X(dtor, "void QMetaType::destruct(int type, void *where)", "The type was not properly registered");
1953 dtor(where);
1954 }
1955
1956 const int m_type;
1957};
1958} // namespace
1959
1960/*!
1961 \since 5.0
1962
1963 Destructs the value of the given \a type, located at \a where.
1964
1965 Unlike destroy(), this function only invokes the type's
1966 destructor, it doesn't invoke the delete operator.
1967
1968 \sa construct()
1969*/
1970void QMetaType::destruct(int type, void *where)
1971{
1972 if (!where)
1973 return;
1974 TypeDestructor destructor(type);
1975 QMetaTypeSwitcher::switcher<void>(destructor, type, where);
1976}
1977
1978
1979namespace {
1980class SizeOf {
1981 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
1982 struct SizeOfImpl {
1983 static int Size(const int) { return QTypeInfo<T>::sizeOf; }
1984 };
1985 template<typename T>
1986 struct SizeOfImpl<T, /* IsAcceptedType = */ false> {
1987 static int Size(const int type)
1988 {
1989 if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
1990 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].size : 0;
1991
1992 if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
1993 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].size : 0;
1994
1995 // This point can be reached only for known types that definition is not available, for example
1996 // in bootstrap mode. We have no other choice then ignore it.
1997 return 0;
1998 }
1999 };
2000
2001public:
2002 SizeOf(int type)
2003 : m_type(type)
2004 {}
2005
2006 template<typename T>
2007 int delegate(const T*) { return SizeOfImpl<T>::Size(m_type); }
2008 int delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
2009 int delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeSizeOf(m_type); }
2010private:
2011 static int customTypeSizeOf(const int type)
2012 {
2013 const QVector<QCustomTypeInfo> * const ct = customTypes();
2014 QReadLocker locker(customTypesLock());
2015 if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
2016 return 0;
2017 return ct->at(type - QMetaType::User).size;
2018 }
2019
2020 const int m_type;
2021};
2022} // namespace
2023
2024/*!
2025 \since 5.0
2026
2027 Returns the size of the given \a type in bytes (i.e. sizeof(T),
2028 where T is the actual type identified by the \a type argument).
2029
2030 This function is typically used together with construct()
2031 to perform low-level management of the memory used by a type.
2032
2033 \sa construct()
2034*/
2035int QMetaType::sizeOf(int type)
2036{
2037 SizeOf sizeOf(type);
2038 return QMetaTypeSwitcher::switcher<int>(sizeOf, type, 0);
2039}
2040
2041namespace {
2042class Flags
2043{
2044 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
2045 struct FlagsImpl
2046 {
2047 static quint32 Flags(const int /* type */)
2048 {
2049 return QtPrivate::QMetaTypeTypeFlags<T>::Flags;
2050 }
2051 };
2052 template<typename T>
2053 struct FlagsImpl<T, /* IsAcceptedType = */ false>
2054 {
2055 static quint32 Flags(const int type)
2056 {
2057 if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
2058 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].flags : 0;
2059
2060 if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
2061 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].flags : 0;
2062
2063 // This point can be reached only for known types that definition is not available, for example
2064 // in bootstrap mode. We have no other choice then ignore it.
2065 return 0;
2066 }
2067 };
2068public:
2069 Flags(const int type)
2070 : m_type(type)
2071 {}
2072 template<typename T>
2073 quint32 delegate(const T*) { return FlagsImpl<T>::Flags(m_type); }
2074 quint32 delegate(const void*) { return 0; }
2075 quint32 delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
2076 quint32 delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customTypeFlags(m_type); }
2077private:
2078 const int m_type;
2079 static quint32 customTypeFlags(const int type)
2080 {
2081 const QVector<QCustomTypeInfo> * const ct = customTypes();
2082 if (Q_UNLIKELY(!ct || type < QMetaType::User))
2083 return 0;
2084 QReadLocker locker(customTypesLock());
2085 if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
2086 return 0;
2087 return ct->at(type - QMetaType::User).flags;
2088 }
2089};
2090} // namespace
2091
2092/*!
2093 \since 5.0
2094
2095 Returns flags of the given \a type.
2096
2097 \sa QMetaType::TypeFlags
2098*/
2099QMetaType::TypeFlags QMetaType::typeFlags(int type)
2100{
2101 Flags flags(type);
2102 return static_cast<QMetaType::TypeFlags>(QMetaTypeSwitcher::switcher<quint32>(flags, type, 0));
2103}
2104
2105#ifndef QT_BOOTSTRAPPED
2106namespace {
2107class MetaObject
2108{
2109public:
2110 MetaObject(const int type)
2111 : m_type(type)
2112 {}
2113
2114 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
2115 struct MetaObjectImpl
2116 {
2117 static const QMetaObject *MetaObject(int /*type*/)
2118 { return QtPrivate::MetaObjectForType<T>::value(); }
2119 };
2120 template<typename T>
2121 struct MetaObjectImpl<T, /* IsAcceptedType = */ false>
2122 {
2123 static const QMetaObject *MetaObject(int type) {
2124 if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
2125 return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].metaObject : 0;
2126 if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
2127 return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].metaObject : 0;
2128 return 0;
2129 }
2130 };
2131
2132 template <typename T>
2133 const QMetaObject *delegate(const T *) { return MetaObjectImpl<T>::MetaObject(m_type); }
2134 const QMetaObject *delegate(const void*) { return 0; }
2135 const QMetaObject *delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
2136 const QMetaObject *delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customMetaObject(m_type); }
2137private:
2138 const int m_type;
2139 static const QMetaObject *customMetaObject(const int type)
2140 {
2141 const QVector<QCustomTypeInfo> * const ct = customTypes();
2142 if (Q_UNLIKELY(!ct || type < QMetaType::User))
2143 return 0;
2144 QReadLocker locker(customTypesLock());
2145 if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
2146 return 0;
2147 return ct->at(type - QMetaType::User).metaObject;
2148 }
2149};
2150} // namespace
2151#endif
2152
2153/*!
2154 \since 5.0
2155
2156 returns QMetaType::metaObject for \a type
2157
2158 \sa metaObject()
2159*/
2160const QMetaObject *QMetaType::metaObjectForType(int type)
2161{
2162#ifndef QT_BOOTSTRAPPED
2163 MetaObject mo(type);
2164 return QMetaTypeSwitcher::switcher<const QMetaObject*>(mo, type, 0);
2165#else
2166 Q_UNUSED(type);
2167 return 0;
2168#endif
2169}
2170
2171/*!
2172 \fn int qRegisterMetaType(const char *typeName)
2173 \relates QMetaType
2174 \threadsafe
2175
2176 Registers the type name \a typeName for the type \c{T}. Returns
2177 the internal ID used by QMetaType. Any class or struct that has a
2178 public default constructor, a public copy constructor and a public
2179 destructor can be registered.
2180
2181 This function requires that \c{T} is a fully defined type at the point
2182 where the function is called. For pointer types, it also requires that the
2183 pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able
2184 to register pointers to forward declared types.
2185
2186 After a type has been registered, you can create and destroy
2187 objects of that type dynamically at run-time.
2188
2189 This example registers the class \c{MyClass}:
2190
2191 \snippet code/src_corelib_kernel_qmetatype.cpp 4
2192
2193 This function is useful to register typedefs so they can be used
2194 by QMetaProperty, or in QueuedConnections
2195
2196 \snippet code/src_corelib_kernel_qmetatype.cpp 9
2197
2198 \warning This function is useful only for registering an alias (typedef)
2199 for every other use case Q_DECLARE_METATYPE and qMetaTypeId() should be used instead.
2200
2201 \sa {QMetaType::}{qRegisterMetaTypeStreamOperators()}, {QMetaType::}{isRegistered()},
2202 Q_DECLARE_METATYPE()
2203*/
2204
2205/*!
2206 \fn void qRegisterMetaTypeStreamOperators(const char *typeName)
2207 \relates QMetaType
2208 \threadsafe
2209
2210 Registers the stream operators for the type \c{T} called \a
2211 typeName.
2212
2213 Afterward, the type can be streamed using QMetaType::load() and
2214 QMetaType::save(). These functions are used when streaming a
2215 QVariant.
2216
2217 \snippet code/src_corelib_kernel_qmetatype.cpp 5
2218
2219 The stream operators should have the following signatures:
2220
2221 \snippet code/src_corelib_kernel_qmetatype.cpp 6
2222
2223 \sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
2224*/
2225
2226/*! \typedef QMetaType::Deleter
2227 \internal
2228*/
2229/*! \typedef QMetaType::Creator
2230 \internal
2231*/
2232/*! \typedef QMetaType::SaveOperator
2233 \internal
2234*/
2235/*! \typedef QMetaType::LoadOperator
2236 \internal
2237*/
2238/*! \typedef QMetaType::Destructor
2239 \internal
2240*/
2241/*! \typedef QMetaType::Constructor
2242 \internal
2243*/
2244
2245/*!
2246 \fn int qRegisterMetaType()
2247 \relates QMetaType
2248 \threadsafe
2249 \since 4.2
2250
2251 Call this function to register the type \c T. \c T must be declared with
2252 Q_DECLARE_METATYPE(). Returns the meta type Id.
2253
2254 Example:
2255
2256 \snippet code/src_corelib_kernel_qmetatype.cpp 7
2257
2258 This function requires that \c{T} is a fully defined type at the point
2259 where the function is called. For pointer types, it also requires that the
2260 pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able
2261 to register pointers to forward declared types.
2262
2263 After a type has been registered, you can create and destroy
2264 objects of that type dynamically at run-time.
2265
2266 To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
2267 sufficient. To use the type \c T in queued signal and slot connections,
2268 \c{qRegisterMetaType<T>()} must be called before the first connection
2269 is established.
2270
2271 Also, to use type \c T with the QObject::property() API,
2272 \c{qRegisterMetaType<T>()} must be called before it is used, typically
2273 in the constructor of the class that uses \c T, or in the \c{main()}
2274 function.
2275
2276 \sa Q_DECLARE_METATYPE()
2277 */
2278
2279/*!
2280 \fn int qMetaTypeId()
2281 \relates QMetaType
2282 \threadsafe
2283 \since 4.1
2284
2285 Returns the meta type id of type \c T at compile time. If the
2286 type was not declared with Q_DECLARE_METATYPE(), compilation will
2287 fail.
2288
2289 Typical usage:
2290
2291 \snippet code/src_corelib_kernel_qmetatype.cpp 8
2292
2293 QMetaType::type() returns the same ID as qMetaTypeId(), but does
2294 a lookup at runtime based on the name of the type.
2295 QMetaType::type() is a bit slower, but compilation succeeds if a
2296 type is not registered.
2297
2298 \sa Q_DECLARE_METATYPE(), QMetaType::type()
2299*/
2300
2301namespace {
2302class TypeInfo {
2303 template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted>
2304 struct TypeInfoImpl
2305 {
2306 TypeInfoImpl(const uint /* type */, QMetaTypeInterface &info)
2307 {
2308 QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_NO_DATASTREAM(T);
2309 info = tmp;
2310 }
2311 };
2312
2313 template<typename T>
2314 struct TypeInfoImpl<T, /* IsAcceptedType = */ false>
2315 {
2316 TypeInfoImpl(const uint type, QMetaTypeInterface &info)
2317 {
2318 if (QModulesPrivate::QTypeModuleInfo<T>::IsGui) {
2319 if (Q_LIKELY(qMetaTypeGuiHelper))
2320 info = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType];
2321 return;
2322 }
2323 if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget) {
2324 if (Q_LIKELY(qMetaTypeWidgetsHelper))
2325 info = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType];
2326 return;
2327 }
2328 }
2329 };
2330public:
2331 QMetaTypeInterface info;
2332 TypeInfo(const uint type)
2333 : m_type(type)
2334 {
2335 QMetaTypeInterface tmp = QT_METATYPE_INTERFACE_INIT_EMPTY();
2336 info = tmp;
2337 }
2338 template<typename T>
2339 void delegate(const T*) { TypeInfoImpl<T>(m_type, info); }
2340 void delegate(const QMetaTypeSwitcher::UnknownType*) {}
2341 void delegate(const QMetaTypeSwitcher::NotBuiltinType*) { customTypeInfo(m_type); }
2342private:
2343 void customTypeInfo(const uint type)
2344 {
2345 const QVector<QCustomTypeInfo> * const ct = customTypes();
2346 if (Q_UNLIKELY(!ct))
2347 return;
2348 QReadLocker locker(customTypesLock());
2349 if (Q_LIKELY(uint(ct->count()) > type - QMetaType::User))
2350 info = ct->at(type - QMetaType::User);
2351 }
2352
2353 const uint m_type;
2354};
2355} // namespace
2356
2357/*!
2358 \fn QMetaType QMetaType::typeInfo(const int type)
2359 \internal
2360*/
2361QMetaType QMetaType::typeInfo(const int type)
2362{
2363 TypeInfo typeInfo(type);
2364 QMetaTypeSwitcher::switcher<void>(typeInfo, type, 0);
2365 return typeInfo.info.constructor ? QMetaType(static_cast<ExtensionFlag>(QMetaType::CreateEx | QMetaType::DestroyEx)
2366 , static_cast<const QMetaTypeInterface *>(0) // typeInfo::info is a temporary variable, we can't return address of it.
2367 , 0 // unused
2368 , 0 // unused
2369 , typeInfo.info.saveOp
2370 , typeInfo.info.loadOp
2371 , typeInfo.info.constructor
2372 , typeInfo.info.destructor
2373 , typeInfo.info.size
2374 , typeInfo.info.flags
2375 , type
2376 , typeInfo.info.metaObject)
2377 : QMetaType(UnknownType);
2378}
2379
2380/*!
2381 \fn QMetaType::QMetaType(const int typeId)
2382 \since 5.0
2383
2384 Constructs a QMetaType object that contains all information about type \a typeId.
2385*/
2386QMetaType::QMetaType(const int typeId)
2387 : m_typeId(typeId)
2388{
2389 if (Q_UNLIKELY(typeId == UnknownType)) {
2390 // Constructs invalid QMetaType instance.
2391 m_extensionFlags = 0xffffffff;
2392 Q_ASSERT(!isValid());
2393 } else {
2394 // TODO it can be better.
2395 *this = QMetaType::typeInfo(typeId);
2396 if (m_typeId == UnknownType)
2397 m_extensionFlags = 0xffffffff;
2398 else if (m_typeId == QMetaType::Void)
2399 m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
2400 }
2401}
2402
2403/*!
2404 \fn QMetaType::QMetaType(const QMetaType &other)
2405 \since 5.0
2406
2407 Copy constructs a QMetaType object.
2408*/
2409QMetaType::QMetaType(const QMetaType &other)
2410 : m_creator_unused(other.m_creator_unused)
2411 , m_deleter_unused(other.m_deleter_unused)
2412 , m_saveOp(other.m_saveOp)
2413 , m_loadOp(other.m_loadOp)
2414 , m_constructor(other.m_constructor)
2415 , m_destructor(other.m_destructor)
2416 , m_extension(other.m_extension) // space reserved for future use
2417 , m_size(other.m_size)
2418 , m_typeFlags(other.m_typeFlags)
2419 , m_extensionFlags(other.m_extensionFlags)
2420 , m_typeId(other.m_typeId)
2421 , m_metaObject(other.m_metaObject)
2422{}
2423
2424QMetaType &QMetaType::operator =(const QMetaType &other)
2425{
2426 m_creator_unused = other.m_creator_unused;
2427 m_deleter_unused = other.m_deleter_unused;
2428 m_saveOp = other.m_saveOp;
2429 m_loadOp = other.m_loadOp;
2430 m_constructor = other.m_constructor;
2431 m_destructor = other.m_destructor;
2432 m_size = other.m_size;
2433 m_typeFlags = other.m_typeFlags;
2434 m_extensionFlags = other.m_extensionFlags;
2435 m_extension = other.m_extension; // space reserved for future use
2436 m_typeId = other.m_typeId;
2437 m_metaObject = other.m_metaObject;
2438 return *this;
2439}
2440
2441/*!
2442 \fn void QMetaType::ctor(const QMetaTypeInterface *info)
2443 \internal
2444
2445 Method used for future binary compatible extensions. The function may be
2446 called from within QMetaType's constructor to force a library call from
2447 inlined code.
2448*/
2449void QMetaType::ctor(const QMetaTypeInterface *info)
2450{
2451 // Special case for Void type, the type is valid but not constructible.
2452 // In future we may consider to remove this assert and extend this function to initialize
2453 // differently m_extensionFlags for different types. Currently it is not needed.
2454 Q_ASSERT(m_typeId == QMetaType::Void);
2455 Q_UNUSED(info);
2456 m_extensionFlags = CreateEx | DestroyEx | ConstructEx | DestructEx;
2457}
2458
2459/*!
2460 \fn void QMetaType::dtor()
2461 \internal
2462
2463 Method used for future binary compatible extensions. The function may be
2464 called from within QMetaType's destructor to force a library call from
2465 inlined code.
2466*/
2467void QMetaType::dtor()
2468{}
2469
2470/*!
2471 \fn void *QMetaType::createExtended(const void *copy) const
2472 \internal
2473
2474 Method used for future binary compatible extensions. The function may be called
2475 during QMetaType::create to force library call from inlined code.
2476
2477 ### TODO Qt6 remove the extension
2478*/
2479void *QMetaType::createExtended(const void *copy) const
2480{
2481 if (m_typeId == QMetaType::UnknownType)
2482 return 0;
2483 return m_constructor(operator new(m_size), copy);
2484}
2485
2486/*!
2487 \fn void QMetaType::destroyExtended(void *data) const
2488 \internal
2489
2490 Method used for future binary compatible extensions. The function may be called
2491 during QMetaType::destroy to force library call from inlined code.
2492
2493 ### TODO Qt6 remove the extension
2494*/
2495void QMetaType::destroyExtended(void *data) const
2496{
2497 m_destructor(data);
2498 operator delete(data);
2499}
2500
2501/*!
2502 \fn void *QMetaType::constructExtended(void *where, const void *copy) const
2503 \internal
2504
2505 Method used for future binary compatible extensions. The function may be called
2506 during QMetaType::construct to force library call from inlined code.
2507*/
2508void *QMetaType::constructExtended(void *where, const void *copy) const
2509{
2510 Q_UNUSED(where);
2511 Q_UNUSED(copy);
2512 return 0;
2513}
2514
2515/*!
2516 \fn void QMetaType::destructExtended(void *data) const
2517 \internal
2518
2519 Method used for future binary compatible extensions. The function may be called
2520 during QMetaType::destruct to force library call from inlined code.
2521*/
2522void QMetaType::destructExtended(void *data) const
2523{
2524 Q_UNUSED(data);
2525}
2526
2527/*!
2528 \fn uint QMetaType::sizeExtended() const
2529 \internal
2530
2531 Method used for future binary compatible extensions. The function may be
2532 called from within QMetaType::size to force a library call from
2533 inlined code.
2534*/
2535uint QMetaType::sizeExtended() const
2536{
2537 return 0;
2538}
2539
2540/*!
2541 \fn QMetaType::TypeFlags QMetaType::flagsExtended() const
2542 \internal
2543
2544 Method used for future binary compatible extensions. The function may be
2545 called from within QMetaType::flags to force a library call from
2546 inlined code.
2547*/
2548QMetaType::TypeFlags QMetaType::flagsExtended() const
2549{
2550 return 0;
2551}
2552
2553/*!
2554 \brief QMetaType::metaObjectExtended
2555 \internal
2556
2557 Method used for future binary compatible extensions. The function may be
2558 called from within QMetaType::metaObject to force a library call from
2559 inlined code.
2560*/
2561const QMetaObject *QMetaType::metaObjectExtended() const
2562{
2563 return 0;
2564}
2565
2566
2567namespace QtPrivate
2568{
2569const QMetaObject *metaObjectForQWidget()
2570{
2571 if (!qMetaTypeWidgetsHelper)
2572 return 0;
2573 return qMetaObjectWidgetsHelper;
2574}
2575}
2576
2577namespace QtMetaTypePrivate {
2578const bool VectorBoolElements::true_element = true;
2579const bool VectorBoolElements::false_element = false;
2580}
2581
2582QT_END_NAMESPACE
2583