Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qmetatype.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2018 Intel Corporation.
3// Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#ifndef QMETATYPE_H
7#define QMETATYPE_H
8
9#include <QtCore/qglobal.h>
10#include <QtCore/qatomic.h>
11#include <QtCore/qbytearray.h>
12#include <QtCore/qcompare.h>
13#include <QtCore/qdatastream.h>
14#include <QtCore/qfloat16.h>
15#include <QtCore/qhashfunctions.h>
16#include <QtCore/qiterable.h>
17#ifndef QT_NO_QOBJECT
18#include <QtCore/qobjectdefs.h>
19#endif
20#include <QtCore/qscopeguard.h>
21
22#include <array>
23#include <new>
24#include <vector>
25#include <list>
26#include <map>
27#include <functional>
28#include <optional>
29#include <QtCore/q20type_traits.h>
30
31#ifdef Bool
32#error qmetatype.h must be included before any header file that defines Bool
33#endif
34
36
37// from qcborcommon.h
38enum class QCborSimpleType : quint8;
39
40template <typename T>
41struct QMetaTypeId2;
42
43template <typename T>
44inline constexpr int qMetaTypeId();
45
46// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, RealType)
47#define QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(F)\
48 F(Bool, 1, bool) \
49 F(Int, 2, int) \
50 F(UInt, 3, uint) \
51 F(LongLong, 4, qlonglong) \
52 F(ULongLong, 5, qulonglong) \
53 F(Double, 6, double) \
54 F(Long, 32, long) \
55 F(Short, 33, short) \
56 F(Char, 34, char) \
57 F(Char16, 56, char16_t) \
58 F(Char32, 57, char32_t) \
59 F(ULong, 35, ulong) \
60 F(UShort, 36, ushort) \
61 F(UChar, 37, uchar) \
62 F(Float, 38, float) \
63 F(SChar, 40, signed char) \
64 F(Nullptr, 51, std::nullptr_t) \
65 F(QCborSimpleType, 52, QCborSimpleType) \
66
67#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
68 QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(F) \
69 F(Void, 43, void) \
70
71#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F) \
72 F(VoidStar, 31, void*) \
73
74#if QT_CONFIG(easingcurve)
75#define QT_FOR_EACH_STATIC_EASINGCURVE(F)\
76 F(QEasingCurve, 29, QEasingCurve)
77#else
78#define QT_FOR_EACH_STATIC_EASINGCURVE(F)
79#endif
80
81#if QT_CONFIG(itemmodel)
82#define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)\
83 F(QModelIndex, 42, QModelIndex) \
84 F(QPersistentModelIndex, 50, QPersistentModelIndex)
85#else
86#define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
87#endif
88
89#if QT_CONFIG(regularexpression)
90# define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \
91 F(QRegularExpression, 44, QRegularExpression)
92#else
93# define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F)
94#endif
95
96#define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
97 F(QChar, 7, QChar) \
98 F(QString, 10, QString) \
99 F(QByteArray, 12, QByteArray) \
100 F(QBitArray, 13, QBitArray) \
101 F(QDate, 14, QDate) \
102 F(QTime, 15, QTime) \
103 F(QDateTime, 16, QDateTime) \
104 F(QUrl, 17, QUrl) \
105 F(QLocale, 18, QLocale) \
106 F(QRect, 19, QRect) \
107 F(QRectF, 20, QRectF) \
108 F(QSize, 21, QSize) \
109 F(QSizeF, 22, QSizeF) \
110 F(QLine, 23, QLine) \
111 F(QLineF, 24, QLineF) \
112 F(QPoint, 25, QPoint) \
113 F(QPointF, 26, QPointF) \
114 QT_FOR_EACH_STATIC_EASINGCURVE(F) \
115 F(QUuid, 30, QUuid) \
116 F(QVariant, 41, QVariant) \
117 QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \
118 F(QJsonValue, 45, QJsonValue) \
119 F(QJsonObject, 46, QJsonObject) \
120 F(QJsonArray, 47, QJsonArray) \
121 F(QJsonDocument, 48, QJsonDocument) \
122 F(QCborValue, 53, QCborValue) \
123 F(QCborArray, 54, QCborArray) \
124 F(QCborMap, 55, QCborMap) \
125 F(Float16, 63, qfloat16) \
126 QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
127
128#define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
129 F(QObjectStar, 39, QObject*)
130
131#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
132 F(QVariantMap, 8, QVariantMap) \
133 F(QVariantList, 9, QVariantList) \
134 F(QVariantHash, 28, QVariantHash) \
135 F(QVariantPair, 58, QVariantPair) \
136 F(QByteArrayList, 49, QByteArrayList) \
137 F(QStringList, 11, QStringList) \
138
139#if QT_CONFIG(shortcut)
140#define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)\
141 F(QKeySequence, 0x100b, QKeySequence)
142#else
143#define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)
144#endif
145
146#define QT_FOR_EACH_STATIC_GUI_CLASS(F)\
147 F(QFont, 0x1000, QFont) \
148 F(QPixmap, 0x1001, QPixmap) \
149 F(QBrush, 0x1002, QBrush) \
150 F(QColor, 0x1003, QColor) \
151 F(QPalette, 0x1004, QPalette) \
152 F(QIcon, 0x1005, QIcon) \
153 F(QImage, 0x1006, QImage) \
154 F(QPolygon, 0x1007, QPolygon) \
155 F(QRegion, 0x1008, QRegion) \
156 F(QBitmap, 0x1009, QBitmap) \
157 F(QCursor, 0x100a, QCursor) \
158 QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F) \
159 F(QPen, 0x100c, QPen) \
160 F(QTextLength, 0x100d, QTextLength) \
161 F(QTextFormat, 0x100e, QTextFormat) \
162 F(QTransform, 0x1010, QTransform) \
163 F(QMatrix4x4, 0x1011, QMatrix4x4) \
164 F(QVector2D, 0x1012, QVector2D) \
165 F(QVector3D, 0x1013, QVector3D) \
166 F(QVector4D, 0x1014, QVector4D) \
167 F(QQuaternion, 0x1015, QQuaternion) \
168 F(QPolygonF, 0x1016, QPolygonF) \
169 F(QColorSpace, 0x1017, QColorSpace) \
170
171
172#define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
173 F(QSizePolicy, 0x2000, QSizePolicy) \
174
175// F is a tuple: (QMetaType::TypeName, QMetaType::TypeNameID, AliasingType, "RealType")
176#define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\
177 F(ULong, -1, ulong, "unsigned long") \
178 F(UInt, -1, uint, "unsigned int") \
179 F(UShort, -1, ushort, "unsigned short") \
180 F(UChar, -1, uchar, "unsigned char") \
181 F(LongLong, -1, qlonglong, "long long") \
182 F(ULongLong, -1, qulonglong, "unsigned long long") \
183 F(SChar, -1, signed char, "qint8") \
184 F(UChar, -1, uchar, "quint8") \
185 F(Short, -1, short, "qint16") \
186 F(UShort, -1, ushort, "quint16") \
187 F(Int, -1, int, "qint32") \
188 F(UInt, -1, uint, "quint32") \
189 F(LongLong, -1, qlonglong, "qint64") \
190 F(ULongLong, -1, qulonglong, "quint64") \
191 F(QVariantList, -1, QVariantList, "QList<QVariant>") \
192 F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \
193 F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \
194 F(QVariantPair, -1, QVariantPair, "QPair<QVariant,QVariant>") \
195 F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \
196 F(QStringList, -1, QStringList, "QList<QString>") \
197
198#define QT_FOR_EACH_STATIC_TYPE(F)\
199 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
200 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
201 QT_FOR_EACH_STATIC_CORE_CLASS(F)\
202 QT_FOR_EACH_STATIC_CORE_POINTER(F)\
203 QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
204 QT_FOR_EACH_STATIC_GUI_CLASS(F)\
205 QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
206
207#define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
208 TypeName = Id,
209
210#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
211 F(QList) \
212 F(QQueue) \
213 F(QStack) \
214 F(QSet) \
215 /*end*/
216
217#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
218 F(QHash, class) \
219 F(QMap, class)
220
221#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
222 F(QSharedPointer) \
223 F(QWeakPointer) \
224 F(QPointer)
225
226class QDataStream;
227struct QMetaObject;
228
229namespace QtPrivate
230{
231
232class QMetaTypeInterface;
233
234// MSVC is the only supported compiler that includes the type of a variable in
235// its mangled form, so it's not binary-compatible to drop the const in
236// QMetaTypeInterfaceWrapper::metaType for it, which means we must keep the
237// mutable field until Qt 7.
238#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED) || !defined(Q_CC_MSVC)
239# define QMTI_MUTABLE
241#else
242# define QMTI_MUTABLE mutable
244#endif
245
247{
248public:
249
250 /* Revision: Can increase if new field are added, or if semantics changes
251 0: Initial Revision
252 1: the meaning of the NeedsDestruction flag changed
253 */
254 static inline constexpr ushort CurrentRevision = 1;
255
261
262 using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *);
264
265 const char *name;
266
267 using DefaultCtrFn = void (*)(const QMetaTypeInterface *, void *);
269 using CopyCtrFn = void (*)(const QMetaTypeInterface *, void *, const void *);
271 using MoveCtrFn = void (*)(const QMetaTypeInterface *, void *, void *);
273 using DtorFn = void (*)(const QMetaTypeInterface *, void *);
275 using EqualsFn = bool (*)(const QMetaTypeInterface *, const void *, const void *);
277 using LessThanFn = bool (*)(const QMetaTypeInterface *, const void *, const void *);
279 using DebugStreamFn = void (*)(const QMetaTypeInterface *, QDebug &, const void *);
281 using DataStreamOutFn = void (*)(const QMetaTypeInterface *, QDataStream &, const void *);
283 using DataStreamInFn = void (*)(const QMetaTypeInterface *, QDataStream &, void *);
285
286 using LegacyRegisterOp = void (*)();
288};
289#undef QMTI_MUTABLE
290
295template<typename From, typename To>
296To convertImplicit(const From& from)
297{
298 return from;
299}
300
301 template<typename T, bool>
302 struct SequentialValueTypeIsMetaType;
303 template<typename T, bool>
305 template<typename T, bool>
306 struct IsMetaTypePair;
307 template<typename, typename>
309
310 template<typename T>
311 struct IsQFlags : std::false_type {};
312
313 template<typename Enum>
314 struct IsQFlags<QFlags<Enum>> : std::true_type {};
315
316 template<typename T>
317 struct IsEnumOrFlags : std::disjunction<std::is_enum<T>, IsQFlags<T>> {};
318} // namespace QtPrivate
319
320class Q_CORE_EXPORT QMetaType {
321public:
322#ifndef Q_QDOC
323 // The code that actually gets compiled.
324 enum Type {
325 // these are merged with QVariant
327
328 FirstCoreType = Bool,
329 LastCoreType = Float16,
330 FirstGuiType = QFont,
331 LastGuiType = QColorSpace,
332 FirstWidgetsType = QSizePolicy,
333 LastWidgetsType = QSizePolicy,
334 HighestInternalId = LastWidgetsType,
335
336 QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
337
338 UnknownType = 0,
339 User = 65536
340 };
341#else
342 // If we are using QDoc it fakes the Type enum looks like this.
343 enum Type {
344 UnknownType = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5,
345 Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36,
346 UChar = 37, Float = 38,
347 VoidStar = 31,
348 QChar = 7, QString = 10, QStringList = 11, QByteArray = 12,
349 QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
350 QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,
351 QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26,
352 QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42,
354 QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48,
355 QByteArrayList = 49, QObjectStar = 39, SChar = 40,
356 Void = 43,
357 Nullptr = 51,
359 QCborSimpleType = 52, QCborValue = 53, QCborArray = 54, QCborMap = 55,
360 Char16 = 56, Char32 = 57,
361 Int128 = 59, UInt128 = 60, Float128 = 61, BFloat16 = 62, Float16 = 63,
362
363 // Gui types
364 QFont = 0x1000, QPixmap = 0x1001, QBrush = 0x1002, QColor = 0x1003, QPalette = 0x1004,
365 QIcon = 0x1005, QImage = 0x1006, QPolygon = 0x1007, QRegion = 0x1008, QBitmap = 0x1009,
366 QCursor = 0x100a, QKeySequence = 0x100b, QPen = 0x100c, QTextLength = 0x100d, QTextFormat = 0x100e,
367 QTransform = 0x1010, QMatrix4x4 = 0x1011, QVector2D = 0x1012,
368 QVector3D = 0x1013, QVector4D = 0x1014, QQuaternion = 0x1015, QPolygonF = 0x1016, QColorSpace = 0x1017,
369
370 // Widget types
371 QSizePolicy = 0x2000,
372
373 // Start-point for client-code types:
374 User = 65536
375 };
376#endif
377
378 enum TypeFlag {
379 NeedsConstruction = 0x1,
380 NeedsDestruction = 0x2,
381 RelocatableType = 0x4,
382#if QT_DEPRECATED_SINCE(6, 0)
383 MovableType Q_DECL_ENUMERATOR_DEPRECATED_X("Use RelocatableType instead.") = RelocatableType,
384#endif
385 PointerToQObject = 0x8,
386 IsEnumeration = 0x10,
387 SharedPointerToQObject = 0x20,
388 WeakPointerToQObject = 0x40,
389 TrackingPointerToQObject = 0x80,
390 IsUnsignedEnumeration = 0x100,
391 IsGadget = 0x200,
392 PointerToGadget = 0x400,
393 IsPointer = 0x800,
394 IsQmlList =0x1000, // used in the QML engine to recognize QQmlListProperty<T> and list<T>
395 IsConst = 0x2000,
396 // since 6.5:
397 NeedsCopyConstruction = 0x4000,
398 NeedsMoveConstruction = 0x8000,
399 };
400 Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
401
402 static void registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, QMetaType type);
403
404#if QT_DEPRECATED_SINCE(6, 0)
406 static int type(const char *typeName)
407 { return QMetaType::fromName(typeName).id(); }
409 static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName)
410 { return QMetaType::fromName(typeName).id(); }
412 static const char *typeName(int type)
413 { return QMetaType(type).name(); }
415 static int sizeOf(int type)
416 { return int(QMetaType(type).sizeOf()); }
418 static TypeFlags typeFlags(int type)
419 { return QMetaType(type).flags(); }
421 static const QMetaObject *metaObjectForType(int type)
422 { return QMetaType(type).metaObject(); }
424 static void *create(int type, const void *copy = nullptr)
425 { return QMetaType(type).create(copy); }
427 static void destroy(int type, void *data)
428 { return QMetaType(type).destroy(data); }
430 static void *construct(int type, void *where, const void *copy)
431 { return QMetaType(type).construct(where, copy); }
433 static void destruct(int type, void *where)
434 { return QMetaType(type).destruct(where); }
435#endif
436 static bool isRegistered(int type);
437
438 explicit QMetaType(int type);
439 explicit constexpr QMetaType(const QtPrivate::QMetaTypeInterface *d) : d_ptr(d) {}
440 constexpr QMetaType() = default;
441
442 bool isValid() const;
443 bool isRegistered() const;
444 void registerType() const
445 {
446 // "register" is a reserved keyword
447 registerHelper();
448 }
449#if QT_CORE_REMOVED_SINCE(6, 1) || defined(Q_QDOC)
450 int id() const;
451#else
452 // ### Qt 7: Remove traces of out of line version
453 // unused int parameter is used to avoid ODR violation
454 int id(int = 0) const
455 {
456 // keep in sync with the version in removed_api.cpp
457 return registerHelper();
458 }
459#endif
460 constexpr qsizetype sizeOf() const;
461 constexpr qsizetype alignOf() const;
462 constexpr TypeFlags flags() const;
463 constexpr const QMetaObject *metaObject() const;
464 constexpr const char *name() const;
465
466 void *create(const void *copy = nullptr) const;
467 void destroy(void *data) const;
468 void *construct(void *where, const void *copy = nullptr) const;
469 void destruct(void *data) const;
470 QPartialOrdering compare(const void *lhs, const void *rhs) const;
471 bool equals(const void *lhs, const void *rhs) const;
472
473 bool isDefaultConstructible() const noexcept { return d_ptr && isDefaultConstructible(d_ptr); }
474 bool isCopyConstructible() const noexcept { return d_ptr && isCopyConstructible(d_ptr); }
475 bool isMoveConstructible() const noexcept { return d_ptr && isMoveConstructible(d_ptr); }
476 bool isDestructible() const noexcept { return d_ptr && isDestructible(d_ptr); }
477 bool isEqualityComparable() const;
478 bool isOrdered() const;
479
480#ifndef QT_NO_DATASTREAM
481 bool save(QDataStream &stream, const void *data) const;
482 bool load(QDataStream &stream, void *data) const;
483 bool hasRegisteredDataStreamOperators() const;
484
485#if QT_DEPRECATED_SINCE(6, 0)
487 static bool save(QDataStream &stream, int type, const void *data)
488 { return QMetaType(type).save(stream, data); }
490 static bool load(QDataStream &stream, int type, void *data)
491 { return QMetaType(type).load(stream, data); }
492#endif
493#endif
494
495 QMetaType underlyingType() const;
496
497 template<typename T>
498 constexpr static QMetaType fromType();
499 static QMetaType fromName(QByteArrayView name);
500
502 {
503 if (a.d_ptr == b.d_ptr)
504 return true;
505 if (!a.d_ptr || !b.d_ptr)
506 return false; // one type is undefined, the other is defined
507 // avoid id call if we already have the id
508 const int aId = a.id();
509 const int bId = b.id();
510 return aId == bId;
511 }
512 friend bool operator!=(QMetaType a, QMetaType b) { return !(a == b); }
513
514#ifndef QT_NO_DEBUG_STREAM
515private:
516 friend Q_CORE_EXPORT QDebug operator<<(QDebug d, QMetaType m);
517public:
518 bool debugStream(QDebug& dbg, const void *rhs);
519 bool hasRegisteredDebugStreamOperator() const;
520
521#if QT_DEPRECATED_SINCE(6, 0)
523 static bool debugStream(QDebug& dbg, const void *rhs, int typeId)
524 { return QMetaType(typeId).debugStream(dbg, rhs); }
525 template<typename T>
527 static bool hasRegisteredDebugStreamOperator()
528 { return QMetaType::fromType<T>().hasRegisteredDebugStreamOperator(); }
530 static bool hasRegisteredDebugStreamOperator(int typeId)
531 { return QMetaType(typeId).hasRegisteredDebugStreamOperator(); }
532#endif
533#endif
534
535 // type erased converter function
536 using ConverterFunction = std::function<bool(const void *src, void *target)>;
537
538 // type erased mutable view, primarily for containers
539 using MutableViewFunction = std::function<bool(void *src, void *target)>;
540
541 // implicit conversion supported like double -> float
542 template<typename From, typename To>
543 static bool registerConverter()
544 {
545 return registerConverter<From, To>(QtPrivate::convertImplicit<From, To>);
546 }
547
548 // member function as in "QString QFont::toString() const"
549 template<typename From, typename To>
550 static bool registerConverter(To(From::*function)() const)
551 {
553 "QMetaType::registerConverter: At least one of the types must be a custom type.");
554
555 const QMetaType fromType = QMetaType::fromType<From>();
556 const QMetaType toType = QMetaType::fromType<To>();
557 auto converter = [function](const void *from, void *to) -> bool {
558 const From *f = static_cast<const From *>(from);
559 To *t = static_cast<To *>(to);
560 *t = (f->*function)();
561 return true;
562 };
563 return registerConverterImpl<From, To>(converter, fromType, toType);
564 }
565
566 // member function
567 template<typename From, typename To>
568 static bool registerMutableView(To(From::*function)())
569 {
571 "QMetaType::registerMutableView: At least one of the types must be a custom type.");
572
573 const QMetaType fromType = QMetaType::fromType<From>();
574 const QMetaType toType = QMetaType::fromType<To>();
575 auto view = [function](void *from, void *to) -> bool {
576 From *f = static_cast<From *>(from);
577 To *t = static_cast<To *>(to);
578 *t = (f->*function)();
579 return true;
580 };
581 return registerMutableViewImpl<From, To>(view, fromType, toType);
582 }
583
584 // member function as in "double QString::toDouble(bool *ok = nullptr) const"
585 template<typename From, typename To>
586 static bool registerConverter(To(From::*function)(bool*) const)
587 {
589 "QMetaType::registerConverter: At least one of the types must be a custom type.");
590
591 const QMetaType fromType = QMetaType::fromType<From>();
592 const QMetaType toType = QMetaType::fromType<To>();
593 auto converter = [function](const void *from, void *to) -> bool {
594 const From *f = static_cast<const From *>(from);
595 To *t = static_cast<To *>(to);
596 bool result = true;
597 *t = (f->*function)(&result);
598 if (!result)
599 *t = To();
600 return result;
601 };
602 return registerConverterImpl<From, To>(converter, fromType, toType);
603 }
604
605 // functor or function pointer
606 template<typename From, typename To, typename UnaryFunction>
607 static bool registerConverter(UnaryFunction function)
608 {
610 "QMetaType::registerConverter: At least one of the types must be a custom type.");
611
612 const QMetaType fromType = QMetaType::fromType<From>();
613 const QMetaType toType = QMetaType::fromType<To>();
614 auto converter = [function = std::move(function)](const void *from, void *to) -> bool {
615 const From *f = static_cast<const From *>(from);
616 To *t = static_cast<To *>(to);
617 auto &&r = function(*f);
618 if constexpr (std::is_same_v<q20::remove_cvref_t<decltype(r)>, std::optional<To>>) {
619 if (!r)
620 return false;
621 *t = *std::forward<decltype(r)>(r);
622 } else {
623 *t = std::forward<decltype(r)>(r);
624 }
625 return true;
626 };
627 return registerConverterImpl<From, To>(std::move(converter), fromType, toType);
628 }
629
630 // functor or function pointer
631 template<typename From, typename To, typename UnaryFunction>
632 static bool registerMutableView(UnaryFunction function)
633 {
635 "QMetaType::registerMutableView: At least one of the types must be a custom type.");
636
637 const QMetaType fromType = QMetaType::fromType<From>();
638 const QMetaType toType = QMetaType::fromType<To>();
639 auto view = [function = std::move(function)](void *from, void *to) -> bool {
640 From *f = static_cast<From *>(from);
641 To *t = static_cast<To *>(to);
642 *t = function(*f);
643 return true;
644 };
645 return registerMutableViewImpl<From, To>(std::move(view), fromType, toType);
646 }
647
648private:
649 template<typename From, typename To>
650 static bool registerConverterImpl(ConverterFunction converter, QMetaType fromType, QMetaType toType)
651 {
652 if (registerConverterFunction(std::move(converter), fromType, toType)) {
653 static const auto unregister = qScopeGuard([=] {
654 unregisterConverterFunction(fromType, toType);
655 });
656 return true;
657 } else {
658 return false;
659 }
660 }
661
662 template<typename From, typename To>
663 static bool registerMutableViewImpl(MutableViewFunction view, QMetaType fromType, QMetaType toType)
664 {
665 if (registerMutableViewFunction(std::move(view), fromType, toType)) {
666 static const auto unregister = qScopeGuard([=] {
667 unregisterMutableViewFunction(fromType, toType);
668 });
669 return true;
670 } else {
671 return false;
672 }
673 }
674public:
675
676 static bool convert(QMetaType fromType, const void *from, QMetaType toType, void *to);
677 static bool canConvert(QMetaType fromType, QMetaType toType);
678
679 static bool view(QMetaType fromType, void *from, QMetaType toType, void *to);
680 static bool canView(QMetaType fromType, QMetaType toType);
681#if QT_DEPRECATED_SINCE(6, 0)
683 static bool convert(const void *from, int fromTypeId, void *to, int toTypeId)
684 { return convert(QMetaType(fromTypeId), from, QMetaType(toTypeId), to); }
686 static bool compare(const void *lhs, const void *rhs, int typeId, int *result)
687 {
688 QMetaType t(typeId);
689 auto c = t.compare(lhs, rhs);
691 *result = 0;
692 return false;
693 } else if (c == QPartialOrdering::Less) {
694 *result = -1;
695 return true;
696 } else if (c == QPartialOrdering::Equivalent) {
697 *result = 0;
698 return true;
699 } else {
700 *result = 1;
701 return true;
702 }
703 }
705 static bool equals(const void *lhs, const void *rhs, int typeId, int *result)
706 {
707 QMetaType t(typeId);
708 if (!t.isEqualityComparable())
709 return false;
710 *result = t.equals(lhs, rhs) ? 0 : -1;
711 return true;
712 }
713#endif
714
715 template<typename From, typename To>
717 {
718 return hasRegisteredConverterFunction(
719 QMetaType::fromType<From>(), QMetaType::fromType<To>());
720 }
721
722 static bool hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType);
723
724 template<typename From, typename To>
726 {
727 return hasRegisteredMutableViewFunction(
728 QMetaType::fromType<From>(), QMetaType::fromType<To>());
729 }
730
731 static bool hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType);
732
733#ifndef Q_QDOC
734 template<typename, bool> friend struct QtPrivate::SequentialValueTypeIsMetaType;
735 template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType;
736 template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
737 template<typename, typename> friend struct QtPrivate::MetaTypeSmartPointerHelper;
738#endif
739 static bool registerConverterFunction(const ConverterFunction &f, QMetaType from, QMetaType to);
740 static void unregisterConverterFunction(QMetaType from, QMetaType to);
741
742 static bool registerMutableViewFunction(const MutableViewFunction &f, QMetaType from, QMetaType to);
743 static void unregisterMutableViewFunction(QMetaType from, QMetaType to);
744
745 static void unregisterMetaType(QMetaType type);
746
747#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
748 const QtPrivate::QMetaTypeInterface *iface() { return d_ptr; }
749#endif
750 const QtPrivate::QMetaTypeInterface *iface() const { return d_ptr; }
751
752private:
753 static bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION;
754 static bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION;
755 static bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION;
756 static bool isDestructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION;
757
758#if QT_CORE_REMOVED_SINCE(6, 5)
759 int idHelper() const;
760#endif
761 static int registerHelper(const QtPrivate::QMetaTypeInterface *iface);
762 int registerHelper() const
763 {
764 // keep in sync with the QMetaType::id() version in removed_api.cpp
765 if (d_ptr) {
766 if (int id = d_ptr->typeId.loadRelaxed())
767 return id;
768 return registerHelper(d_ptr);
769 }
770 return 0;
771 }
772
773 friend int qRegisterMetaType(QMetaType meta);
774
775 friend class QVariant;
776 const QtPrivate::QMetaTypeInterface *d_ptr = nullptr;
777};
778
779#undef QT_DEFINE_METATYPE_ID
780
781Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
782
783#define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F) \
784 } \
785 Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \
786 namespace QtMetaTypePrivate {
787
788
790
792{
793public:
794 const void *_pair;
797
798 typedef void (*getFunc)(const void * const *p, void *);
799
800 getFunc _getFirst;
801 getFunc _getSecond;
802
803 template<class T>
804 static void getFirstImpl(const void * const *pair, void *dataPtr)
805 { *static_cast<typename T::first_type *>(dataPtr) = static_cast<const T*>(*pair)->first; }
806 template<class T>
807 static void getSecondImpl(const void * const *pair, void *dataPtr)
808 { *static_cast<typename T::second_type *>(dataPtr) = static_cast<const T*>(*pair)->second; }
809
810public:
811 template<class T> QPairVariantInterfaceImpl(const T*p)
812 : _pair(p)
813 , _metaType_first(QMetaType::fromType<typename T::first_type>())
814 , _metaType_second(QMetaType::fromType<typename T::second_type>())
815 , _getFirst(getFirstImpl<T>)
816 , _getSecond(getSecondImpl<T>)
817 {
818 }
819
821 : _pair(nullptr)
822 , _getFirst(nullptr)
823 , _getSecond(nullptr)
824 {
825 }
826
827 inline void first(void *dataPtr) const { _getFirst(&_pair, dataPtr); }
828 inline void second(void *dataPtr) const { _getSecond(&_pair, dataPtr); }
829};
831
832template<typename From>
834
835template<typename T, typename U>
837{
838 QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const
839 {
841 }
842};
843
844}
845
846class QObject;
847
848#define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \
849 template <class T> class Name; \
850
852
853namespace QtPrivate
854{
855 namespace detail {
856 template<typename T, typename ODR_VIOLATION_PREVENTER>
858 {
859 template<typename U>
860 static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
861 static auto check(...) -> std::false_type;
862 using type = decltype(check(static_cast<T *>(nullptr)));
863 };
864 } // namespace detail
865
866 template <typename T, typename ODR_VIOLATION_PREVENTER>
867 struct is_complete : detail::is_complete_helper<std::remove_reference_t<T>, ODR_VIOLATION_PREVENTER>::type {};
868
869 template <typename T> struct MetatypeDecay { using type = T; };
870 template <typename T> struct MetatypeDecay<const T> { using type = T; };
871 template <typename T> struct MetatypeDecay<const T &> { using type = T; };
872
873 template <typename T> struct IsPointerDeclaredOpaque :
874 std::disjunction<std::is_member_pointer<T>,
875 std::is_function<std::remove_pointer_t<T>>>
876 {};
877 template <> struct IsPointerDeclaredOpaque<void *> : std::true_type {};
878 template <> struct IsPointerDeclaredOpaque<const void *> : std::true_type {};
879
880 // Note: this does not check that T = U* isn't pointing to a
881 // forward-declared type. You may want to combine with
882 // checkTypeIsSuitableForMetaType().
883 template<typename T>
885 {
886 enum { Value = false };
887 };
888
889 // Specialize to avoid sizeof(void) warning
890 template<>
892 {
893 enum { Value = false };
894 };
895 template<>
897 {
898 enum { Value = false };
899 };
900 template<>
902 {
903 enum { Value = true };
904 };
905
906 template<typename T>
908 {
911
912#ifndef QT_NO_QOBJECT
914 static yes_type checkType(const QObject* );
915#endif
916 static no_type checkType(...);
917 enum { Value = sizeof(checkType(static_cast<T*>(nullptr))) == sizeof(yes_type) };
918 };
919
920 template<typename T, typename Enable = void>
921 struct IsGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; };
922
923 template<typename T>
924 struct IsGadgetHelper<T, typename T::QtGadgetHelper>
925 {
926 template <typename X>
927 static char checkType(void (X::*)());
928 static void *checkType(void (T::*)());
929 enum {
930 IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *),
931 IsGadgetOrDerivedFrom = true
932 };
933 };
934
935 template <typename T>
936 using IsRealGadget = std::bool_constant<IsGadgetHelper<T>::IsRealGadget>;
937
938 template<typename T, typename Enable = void>
939 struct IsPointerToGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; };
940
941 template<typename T>
942 struct IsPointerToGadgetHelper<T*, typename T::QtGadgetHelper>
943 {
944 using BaseType = T;
945 template <typename X>
946 static char checkType(void (X::*)());
947 static void *checkType(void (T::*)());
948 enum {
949 IsRealGadget = !IsPointerToTypeDerivedFromQObject<T*>::Value && sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *),
950 IsGadgetOrDerivedFrom = !IsPointerToTypeDerivedFromQObject<T*>::Value
951 };
952 };
953
954
955 template<typename T> char qt_getEnumMetaObject(const T&);
956
957 template<typename T>
959 static const T &declval();
960 // If the type was declared with Q_ENUM, the friend qt_getEnumMetaObject() declared in the
961 // Q_ENUM macro will be chosen by ADL, and the return type will be QMetaObject*.
962 // Otherwise the chosen overload will be the catch all template function
963 // qt_getEnumMetaObject(T) which returns 'char'
964 enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
965 };
966 template<> struct IsQEnumHelper<void> { enum { Value = false }; };
967
968 template<typename T, typename Enable = void>
970 {
971 static constexpr const QMetaObject *value() { return nullptr; }
972 using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *);
973 static constexpr MetaObjectFn metaObjectFunction = nullptr;
974 };
975#ifndef QT_NO_QOBJECT
976 template<typename T>
977 struct MetaObjectForType<T*, typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value>::type>
978 {
979 static constexpr const QMetaObject *value() { return &T::staticMetaObject; }
980 static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return &T::staticMetaObject; }
981 };
982 template<typename T>
983 struct MetaObjectForType<T, std::enable_if_t<
984 std::disjunction_v<
985 std::bool_constant<IsGadgetHelper<T>::IsGadgetOrDerivedFrom>,
986 std::is_base_of<QObject, T>
987 >
988 >>
989 {
990 static constexpr const QMetaObject *value() { return &T::staticMetaObject; }
991 static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return &T::staticMetaObject; }
992 };
993 template<typename T>
994 struct MetaObjectForType<T, typename std::enable_if<IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom>::type>
995 {
996 static constexpr const QMetaObject *value()
997 {
999 }
1000 static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return value(); }
1001 };
1002 template<typename T>
1003 struct MetaObjectForType<T, typename std::enable_if<IsQEnumHelper<T>::Value>::type >
1004 {
1005 static constexpr const QMetaObject *value() { return qt_getEnumMetaObject(T()); }
1006 static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return value(); }
1007 };
1008#endif
1009
1010 template<typename T>
1012 {
1013 enum { Value = false };
1014 };
1015
1016 template<typename T>
1018 {
1019 };
1020
1021 template<typename T>
1023 {
1024 enum { Value = false };
1025 };
1026
1027 template<typename T>
1029 {
1030 };
1031
1032 template<typename T>
1034 {
1035 enum { Value = false };
1036 };
1037
1038 template<typename T>
1040 {
1041 enum { Value = true };
1042 };
1043
1044 template<typename T>
1046 {
1047 enum { Value = false };
1048 };
1049
1050 template<typename T>
1052 {
1053 enum { Value = false };
1054 };
1055
1056 template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value>
1058 {
1059 static bool registerConverter()
1060 {
1061 return false;
1062 }
1063
1065 {
1066 return false;
1067 }
1068 };
1069
1070 template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
1072 {
1073 static bool registerConverter()
1074 {
1075 return false;
1076 }
1077
1079 {
1080 return false;
1081 }
1082 };
1083
1084 template<typename T>
1086 {
1087 };
1088
1089 template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value>
1091 {
1092 static bool registerConverter()
1093 {
1094 return false;
1095 }
1096
1098 {
1099 return false;
1100 }
1101 };
1102
1103 template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
1105 {
1106 static bool registerConverter()
1107 {
1108 return false;
1109 }
1110
1112 {
1113 return false;
1114 }
1115 };
1116
1117 template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
1119 {
1120 static bool registerConverter()
1121 {
1122 return false;
1123 }
1124
1126 {
1127 return false;
1128 }
1129 };
1130
1131 template<typename T>
1133 {
1134 };
1135
1136 template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
1139 {
1140 static bool registerConverter()
1141 {
1142 return false;
1143 }
1144 };
1145
1146 template<typename T>
1147 struct IsMetaTypePair<T, true>
1148 {
1149 inline static bool registerConverter();
1150 };
1151
1152 template<typename T>
1153 struct IsPair
1154 {
1155 static bool registerConverter()
1156 {
1157 return false;
1158 }
1159 };
1160 template<typename T, typename U>
1161 struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
1162
1163 template<typename T>
1165
1166 template<typename T, typename = void>
1168 {
1169 static bool registerConverter() { return false; }
1170 };
1171
1172#if QT_CONFIG(future)
1173 template<typename T>
1174 struct MetaTypeQFutureHelper
1175 {
1176 static bool registerConverter() { return false; }
1177 };
1178#endif
1179
1180 template <typename X> static constexpr bool checkTypeIsSuitableForMetaType()
1181 {
1182 using T = typename MetatypeDecay<X>::type;
1183 static_assert(is_complete<T, void>::value || std::is_void_v<T>,
1184 "Meta Types must be fully defined");
1185 static_assert(!std::is_reference_v<T>,
1186 "Meta Types cannot be non-const references or rvalue references.");
1187 if constexpr (std::is_pointer_v<T> && !IsPointerDeclaredOpaque<T>::value) {
1188 using Pointed = std::remove_pointer_t<T>;
1190 "Pointer Meta Types must either point to fully-defined types "
1191 "or be declared with Q_DECLARE_OPAQUE_POINTER(T *)");
1192 }
1193 return true;
1194 }
1195
1196 Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
1197} // namespace QtPrivate
1198
1199template <typename T, int =
1205{
1206 enum {
1207 Defined = 0
1209};
1210
1211template <typename T>
1213{
1214};
1215
1216template <typename T>
1218{
1220 enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
1221 static inline constexpr int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
1222};
1223
1224template <typename T>
1225struct QMetaTypeId2<const T&> : QMetaTypeId2<T> {};
1226
1227template <typename T>
1229{
1231 enum { Defined = false, IsBuiltIn = false };
1232 static inline constexpr int qt_metatype_id() { return 0; }
1233};
1234
1235namespace QtPrivate {
1236 template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
1238 static inline constexpr int qt_metatype_id()
1240 };
1241 template <typename T> struct QMetaTypeIdHelper<T, false> {
1242 static inline constexpr int qt_metatype_id()
1243 { return -1; }
1244 };
1245
1246 // Function pointers don't derive from QObject
1247 template <typename Result, typename... Args>
1248 struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
1249
1250 template<typename T>
1251 inline constexpr bool IsQmlListType = false;
1252
1253 template<typename T, bool = std::is_enum<T>::value>
1254 constexpr bool IsUnsignedEnum = false;
1255 template<typename T>
1256 constexpr bool IsUnsignedEnum<T, true> = !std::is_signed_v<std::underlying_type_t<T>>;
1257
1258 template<typename T>
1260 {
1262 | ((!std::is_default_constructible_v<T> || !QTypeInfo<T>::isValueInitializationBitwiseZero) ? QMetaType::NeedsConstruction : 0)
1263 | (!std::is_trivially_destructible_v<T> ? QMetaType::NeedsDestruction : 0)
1264 | (!std::is_trivially_copy_constructible_v<T> ? QMetaType::NeedsCopyConstruction : 0)
1265 | (!std::is_trivially_move_constructible_v<T> ? QMetaType::NeedsMoveConstruction : 0)
1273 | (std::is_pointer_v<T> ? QMetaType::IsPointer : 0)
1274 | (IsUnsignedEnum<T> ? QMetaType::IsUnsignedEnumeration : 0)
1275 | (IsQmlListType<T> ? QMetaType::IsQmlList : 0)
1276 | (std::is_const_v<std::remove_pointer_t<T>> ? QMetaType::IsConst : 0)
1278 };
1279
1280 template<typename T, bool defined>
1282 {
1283 enum DefinedType { Defined = defined };
1284 };
1285
1286 template<typename SmartPointer>
1288 {
1289 QObject* operator()(const SmartPointer &p) const
1290 {
1291 return p.operator->();
1292 }
1293 };
1294
1295 // hack to delay name lookup to instantiation time by making
1296 // EnableInternalData a dependent name:
1297 template <typename T>
1298 struct EnableInternalDataWrap;
1299
1300 template<typename T>
1302 {
1304 {
1306 }
1307 };
1308}
1309
1310template <typename T>
1312{
1313#ifndef QT_NO_QOBJECT
1314 Q_ASSERT_X(normalizedTypeName == QMetaObject::normalizedType(normalizedTypeName.constData()),
1315 "qRegisterNormalizedMetaType",
1316 "qRegisterNormalizedMetaType was called with a not normalized type name, "
1317 "please call qRegisterMetaType instead.");
1318#endif
1319
1320 const QMetaType metaType = QMetaType::fromType<T>();
1321 const int id = metaType.id();
1322
1329#if QT_CONFIG(future)
1330 QtPrivate::MetaTypeQFutureHelper<T>::registerConverter();
1331#endif
1332
1333 if (normalizedTypeName != metaType.name())
1334 QMetaType::registerNormalizedTypedef(normalizedTypeName, metaType);
1335
1336 return id;
1337}
1338
1339// This primary template calls the -Implementation, like all other specialisations should.
1340// But the split allows to
1341// - in a header:
1342// - define a specialization of this template calling an out-of-line function
1343// (QT_DECL_METATYPE_EXTERN{,_TAGGED})
1344// - in the .cpp file:
1345// - define the out-of-line wrapper to call the -Implementation
1346// (QT_IMPL_METATYPE_EXTERN{,_TAGGED})
1347// The _TAGGED variants let you choose a tag (must be a C identifier) to disambiguate
1348// the out-of-line function; the non-_TAGGED variants use the passed class name as tag.
1349template <typename T>
1351{
1352 return qRegisterNormalizedMetaTypeImplementation<T>(normalizedTypeName);
1353}
1354
1355#define QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TAG, EXPORT) \
1356 QT_BEGIN_NAMESPACE \
1357 EXPORT int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &); \
1358 template <> inline int qRegisterNormalizedMetaType< TYPE >(const QByteArray &name) \
1359 { return qRegisterNormalizedMetaType_ ## TAG (name); } \
1360 QT_END_NAMESPACE \
1361 Q_DECLARE_METATYPE(TYPE) \
1362 /* end */
1363#define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG) \
1364 int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &name) \
1365 { return qRegisterNormalizedMetaTypeImplementation< TYPE >(name); } \
1366 /* end */
1367#define QT_DECL_METATYPE_EXTERN(TYPE, EXPORT) \
1368 QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TYPE, EXPORT)
1369#define QT_IMPL_METATYPE_EXTERN(TYPE) \
1370 QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TYPE)
1371
1372template <typename T>
1374{
1375#ifdef QT_NO_QOBJECT
1376 QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName;
1377#else
1379#endif
1380 return qRegisterNormalizedMetaType<T>(normalizedTypeName);
1381}
1382
1383template <typename T>
1384inline constexpr int qMetaTypeId()
1385{
1386 if constexpr (bool(QMetaTypeId2<T>::IsBuiltIn)) {
1387 // this has the same result as the below code, but avoids asking the
1388 // compiler to load a global variable whose value we know at compile
1389 // time
1391 } else {
1392 return QMetaType::fromType<T>().id();
1393 }
1394}
1395
1396template <typename T>
1397inline constexpr int qRegisterMetaType()
1398{
1399 int id = qMetaTypeId<T>();
1400 return id;
1401}
1402
1404{
1405 return meta.registerHelper();
1406}
1407
1408#ifndef QT_NO_QOBJECT
1409template <typename T>
1411{
1412 enum {
1413 Defined = 1
1415
1416 static int qt_metatype_id()
1417 {
1418 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1419 if (const int id = metatype_id.loadAcquire())
1420 return id;
1421 const char *const cName = T::staticMetaObject.className();
1423 typeName.reserve(strlen(cName) + 1);
1424 typeName.append(cName).append('*');
1425 const int newId = qRegisterNormalizedMetaType<T *>(typeName);
1426 metatype_id.storeRelease(newId);
1427 return newId;
1428 }
1429};
1430
1431template <typename T>
1432struct QMetaTypeIdQObject<T, QMetaType::IsGadget>
1433{
1434 enum {
1435 Defined = std::is_default_constructible<T>::value
1437
1438 static int qt_metatype_id()
1439 {
1440 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1441 if (const int id = metatype_id.loadAcquire())
1442 return id;
1443 const char *const cName = T::staticMetaObject.className();
1444 const int newId = qRegisterNormalizedMetaType<T>(cName);
1445 metatype_id.storeRelease(newId);
1446 return newId;
1447 }
1448};
1449
1450template <typename T>
1452{
1453 enum {
1454 Defined = 1
1456
1457 static int qt_metatype_id()
1458 {
1459 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1460 if (const int id = metatype_id.loadAcquire())
1461 return id;
1462 const char *const cName = T::staticMetaObject.className();
1464 typeName.reserve(strlen(cName) + 1);
1465 typeName.append(cName).append('*');
1466 const int newId = qRegisterNormalizedMetaType<T *>(typeName);
1467 metatype_id.storeRelease(newId);
1468 return newId;
1469 }
1470};
1471
1472template <typename T>
1473struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
1474{
1475 enum {
1476 Defined = 1
1478
1479 static int qt_metatype_id()
1480 {
1481 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1482 if (const int id = metatype_id.loadAcquire())
1483 return id;
1484 const char *eName = qt_getEnumName(T());
1485 const char *cName = qt_getEnumMetaObject(T())->className();
1487 typeName.reserve(strlen(cName) + 2 + strlen(eName));
1488 typeName.append(cName).append("::").append(eName);
1489 const int newId = qRegisterNormalizedMetaType<T>(typeName);
1490 metatype_id.storeRelease(newId);
1491 return newId;
1492 }
1493};
1494#endif
1495
1496#define Q_DECLARE_OPAQUE_POINTER(POINTER) \
1497 QT_BEGIN_NAMESPACE namespace QtPrivate { \
1498 template <> struct IsPointerDeclaredOpaque<POINTER> \
1499 : std::true_type {}; \
1500 } QT_END_NAMESPACE \
1501
1502
1503#ifndef Q_MOC_RUN
1504#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
1505#define Q_DECLARE_METATYPE_IMPL(TYPE) \
1506 QT_BEGIN_NAMESPACE \
1507 template <> \
1508 struct QMetaTypeId< TYPE > \
1509 { \
1510 enum { Defined = 1 }; \
1511 static_assert(QtPrivate::checkTypeIsSuitableForMetaType<TYPE>()); \
1512 static int qt_metatype_id() \
1513 { \
1514 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1515 if (const int id = metatype_id.loadAcquire()) \
1516 return id; \
1517 constexpr auto arr = QtPrivate::typenameHelper<TYPE>(); \
1518 auto name = arr.data(); \
1519 if (QByteArrayView(name) == (#TYPE)) { \
1520 const int id = qRegisterNormalizedMetaType<TYPE>(name); \
1521 metatype_id.storeRelease(id); \
1522 return id; \
1523 } \
1524 const int newId = qRegisterMetaType< TYPE >(#TYPE); \
1525 metatype_id.storeRelease(newId); \
1526 return newId; \
1527 } \
1528 }; \
1529 QT_END_NAMESPACE
1530#endif // Q_MOC_RUN
1531
1532#define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME) \
1533 QT_BEGIN_NAMESPACE \
1534 template<> struct QMetaTypeId2<NAME> \
1535 { \
1536 using NameAsArrayType = std::array<char, sizeof(#NAME)>; \
1537 enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID }; \
1538 static inline constexpr int qt_metatype_id() { return METATYPEID; } \
1539 static constexpr NameAsArrayType nameAsArray = { #NAME }; \
1540 }; \
1541 QT_END_NAMESPACE
1542
1543#define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
1544 class Name;
1545
1549
1550#undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
1551
1552#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
1553QT_BEGIN_NAMESPACE \
1554template <typename T> \
1555struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
1556{ \
1557 enum { \
1558 Defined = QMetaTypeId2<T>::Defined \
1559 }; \
1560 static int qt_metatype_id() \
1561 { \
1562 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1563 if (const int id = metatype_id.loadRelaxed()) \
1564 return id; \
1565 const char *tName = QMetaType::fromType<T>().name(); \
1566 Q_ASSERT(tName); \
1567 const size_t tNameLen = qstrlen(tName); \
1568 QByteArray typeName; \
1569 typeName.reserve(sizeof(#SINGLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + 1); \
1570 typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \
1571 .append('<').append(tName, tNameLen); \
1572 typeName.append('>'); \
1573 const int newId = qRegisterNormalizedMetaType< SINGLE_ARG_TEMPLATE<T> >(typeName); \
1574 metatype_id.storeRelease(newId); \
1575 return newId; \
1576 } \
1577}; \
1578QT_END_NAMESPACE
1579
1580#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
1581QT_BEGIN_NAMESPACE \
1582template<typename T, typename U> \
1583struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
1584{ \
1585 enum { \
1586 Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \
1587 }; \
1588 static int qt_metatype_id() \
1589 { \
1590 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1591 if (const int id = metatype_id.loadAcquire()) \
1592 return id; \
1593 const char *tName = QMetaType::fromType<T>().name(); \
1594 const char *uName = QMetaType::fromType<U>().name(); \
1595 Q_ASSERT(tName); \
1596 Q_ASSERT(uName); \
1597 const size_t tNameLen = qstrlen(tName); \
1598 const size_t uNameLen = qstrlen(uName); \
1599 QByteArray typeName; \
1600 typeName.reserve(sizeof(#DOUBLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
1601 typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \
1602 .append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \
1603 typeName.append('>'); \
1604 const int newId = qRegisterNormalizedMetaType< DOUBLE_ARG_TEMPLATE<T, U> >(typeName); \
1605 metatype_id.storeRelease(newId); \
1606 return newId; \
1607 } \
1608}; \
1609QT_END_NAMESPACE
1610
1611namespace QtPrivate {
1612
1613template<typename T, bool /* isSharedPointerToQObjectDerived */ = false>
1615{
1616 enum {
1617 Defined = 0
1619 static int qt_metatype_id()
1620 {
1621 return -1;
1622 }
1623};
1624
1625}
1626
1627#define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
1628QT_BEGIN_NAMESPACE \
1629namespace QtPrivate { \
1630template<typename T> \
1631struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
1632{ \
1633 enum { \
1634 Defined = 1 \
1635 }; \
1636 static int qt_metatype_id() \
1637 { \
1638 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1639 if (const int id = metatype_id.loadAcquire()) \
1640 return id; \
1641 const char * const cName = T::staticMetaObject.className(); \
1642 QByteArray typeName; \
1643 typeName.reserve(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1); \
1644 typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \
1645 .append('<').append(cName).append('>'); \
1646 const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >(typeName); \
1647 metatype_id.storeRelease(newId); \
1648 return newId; \
1649 } \
1650}; \
1651template<typename T> \
1652struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
1653 typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value && !std::is_const_v<T>>::type> \
1654{ \
1655 static bool registerConverter() \
1656 { \
1657 const QMetaType to = QMetaType(QMetaType::QObjectStar); \
1658 if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<SMART_POINTER<T>>(), to)) { \
1659 QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
1660 return QMetaType::registerConverter<SMART_POINTER<T>, QObject*>(o); \
1661 } \
1662 return true; \
1663 } \
1664}; \
1665} \
1666template <typename T> \
1667struct QMetaTypeId< SMART_POINTER<T> > \
1668 : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
1669 QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
1670{ \
1671};\
1672QT_END_NAMESPACE
1673
1674#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(SINGLE_ARG_TEMPLATE) \
1675 QT_BEGIN_NAMESPACE \
1676 namespace QtPrivate { \
1677 template<typename T> \
1678 struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \
1679 { \
1680 enum { Value = true }; \
1681 }; \
1682 } \
1683 QT_END_NAMESPACE \
1684 Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE)
1685
1686#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \
1687 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(TEMPLATENAME)
1688
1690
1692
1693#undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER
1694
1697
1698#define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \
1699 QT_BEGIN_NAMESPACE \
1700 namespace QtPrivate { \
1701 template<typename T, typename U> \
1702 struct IsAssociativeContainer<TEMPLATENAME<T, U> > \
1703 { \
1704 enum { Value = true }; \
1705 }; \
1706 } \
1707 QT_END_NAMESPACE \
1708 Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
1709
1713
1715
1716#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
1717 Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
1718
1720
1722
1723#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
1724
1726
1728
1729
1731
1732template <typename T>
1734{
1735 const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
1736 if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
1738 return QMetaType::registerConverter<T, QtMetaTypePrivate::QPairVariantInterfaceImpl>(o);
1739 }
1740 return true;
1741}
1742
1743namespace QtPrivate {
1744
1745template<typename From>
1747{
1749 {
1750 return QIterable<QMetaSequence>(QMetaSequence::fromContainer<From>(), &f);
1751 }
1752};
1753
1754template<typename From>
1756{
1758 {
1759 return QIterable<QMetaSequence>(QMetaSequence::fromContainer<From>(), &f);
1760 }
1761};
1762
1763template<typename T>
1765{
1766 static bool registerConverter()
1767 {
1768 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
1769 if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
1771 return QMetaType::registerConverter<T, QIterable<QMetaSequence>>(o);
1772 }
1773 return true;
1774 }
1775
1777 {
1778 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
1779 if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
1781 return QMetaType::registerMutableView<T, QIterable<QMetaSequence>>(o);
1782 }
1783 return true;
1784 }
1785};
1786
1787template<typename From>
1789{
1791 {
1792 return QIterable<QMetaAssociation>(QMetaAssociation::fromContainer<From>(), &f);
1793 }
1794};
1795
1796template<typename From>
1798{
1800 {
1801 return QIterable<QMetaAssociation>(QMetaAssociation::fromContainer<From>(), &f);
1802 }
1803};
1804
1805// Mapped type can be omitted, for example in case of a set.
1806// However, if it is available, we want to instantiate the metatype here.
1807template<typename T>
1809{
1810 static bool registerConverter()
1811 {
1812 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
1813 if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
1815 return QMetaType::registerConverter<T, QIterable<QMetaAssociation>>(o);
1816 }
1817 return true;
1818 }
1819
1821 {
1822 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
1823 if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
1825 return QMetaType::registerMutableView<T, QIterable<QMetaAssociation>>(o);
1826 }
1827 return true;
1828 }
1829};
1830
1832{
1833 char *output;
1834 int len = 0;
1835 char last = 0;
1836
1837private:
1838 static constexpr bool is_ident_char(char s)
1839 {
1840 return ((s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || (s >= '0' && s <= '9')
1841 || s == '_');
1842 }
1843 static constexpr bool is_space(char s) { return (s == ' ' || s == '\t' || s == '\n'); }
1844 static constexpr bool is_number(char s) { return s >= '0' && s <= '9'; }
1845 static constexpr bool starts_with_token(const char *b, const char *e, const char *token,
1846 bool msvcKw = false)
1847 {
1848 while (b != e && *token && *b == *token) {
1849 b++;
1850 token++;
1851 }
1852 if (*token)
1853 return false;
1854#ifdef Q_CC_MSVC
1857 if (msvcKw && !is_ident_char(*b))
1858 return true;
1859#endif
1860 Q_UNUSED(msvcKw);
1861 return b == e || !is_ident_char(*b);
1862 }
1863 static constexpr bool skipToken(const char *&x, const char *e, const char *token,
1864 bool msvcKw = false)
1865 {
1866 if (!starts_with_token(x, e, token, msvcKw))
1867 return false;
1868 while (*token++)
1869 x++;
1870 while (x != e && is_space(*x))
1871 x++;
1872 return true;
1873 }
1874 static constexpr const char *skipString(const char *x, const char *e)
1875 {
1876 char delim = *x;
1877 x++;
1878 while (x != e && *x != delim) {
1879 if (*x == '\\') {
1880 x++;
1881 if (x == e)
1882 return e;
1883 }
1884 x++;
1885 }
1886 if (x != e)
1887 x++;
1888 return x;
1889 }
1890 static constexpr const char *skipTemplate(const char *x, const char *e, bool stopAtComa = false)
1891 {
1892 int scopeDepth = 0;
1893 int templateDepth = 0;
1894 while (x != e) {
1895 switch (*x) {
1896 case '<':
1897 if (!scopeDepth)
1898 templateDepth++;
1899 break;
1900 case ',':
1901 if (stopAtComa && !scopeDepth && !templateDepth)
1902 return x;
1903 break;
1904 case '>':
1905 if (!scopeDepth)
1906 if (--templateDepth < 0)
1907 return x;
1908 break;
1909 case '(':
1910 case '[':
1911 case '{':
1912 scopeDepth++;
1913 break;
1914 case '}':
1915 case ']':
1916 case ')':
1917 scopeDepth--;
1918 break;
1919 case '\'':
1920 if (is_number(x[-1]))
1921 break;
1922 Q_FALLTHROUGH();
1923 case '\"':
1924 x = skipString(x, e);
1925 continue;
1926 }
1927 x++;
1928 }
1929 return x;
1930 }
1931
1932 constexpr void append(char x)
1933 {
1934 last = x;
1935 len++;
1936 if (output)
1937 *output++ = x;
1938 }
1939
1940 constexpr void replaceLast(char x)
1941 {
1942 last = x;
1943 if (output)
1944 *(output - 1) = x;
1945 }
1946
1947 constexpr void appendStr(const char *x)
1948 {
1949 while (*x)
1950 append(*x++);
1951 }
1952
1953 constexpr void normalizeIntegerTypes(const char *&begin, const char *end)
1954 {
1955 int numLong = 0;
1956 int numSigned = 0;
1957 int numUnsigned = 0;
1958 int numInt = 0;
1959 int numShort = 0;
1960 int numChar = 0;
1961 while (begin < end) {
1962 if (skipToken(begin, end, "long")) {
1963 numLong++;
1964 continue;
1965 }
1966 if (skipToken(begin, end, "int")) {
1967 numInt++;
1968 continue;
1969 }
1970 if (skipToken(begin, end, "short")) {
1971 numShort++;
1972 continue;
1973 }
1974 if (skipToken(begin, end, "unsigned")) {
1975 numUnsigned++;
1976 continue;
1977 }
1978 if (skipToken(begin, end, "signed")) {
1979 numSigned++;
1980 continue;
1981 }
1982 if (skipToken(begin, end, "char")) {
1983 numChar++;
1984 continue;
1985 }
1986#ifdef Q_CC_MSVC
1987 if (skipToken(begin, end, "__int64")) {
1988 numLong = 2;
1989 continue;
1990 }
1991#endif
1992 break;
1993 }
1994 if (numLong == 2)
1995 append('q'); // q(u)longlong
1996 if (numSigned && numChar)
1997 appendStr("signed ");
1998 else if (numUnsigned)
1999 appendStr("u");
2000 if (numChar)
2001 appendStr("char");
2002 else if (numShort)
2003 appendStr("short");
2004 else if (numLong == 1)
2005 appendStr("long");
2006 else if (numLong == 2)
2007 appendStr("longlong");
2008 else if (numUnsigned || numSigned || numInt)
2009 appendStr("int");
2010 }
2011
2012 constexpr void skipStructClassOrEnum(const char *&begin, const char *end)
2013 {
2014 // discard 'struct', 'class', and 'enum'; they are optional
2015 // and we don't want them in the normalized signature
2016 skipToken(begin, end, "struct", true) || skipToken(begin, end, "class", true)
2017 || skipToken(begin, end, "enum", true);
2018 }
2019
2020 constexpr void skipQtNamespace(const char *&begin, const char *end)
2021 {
2022#ifdef QT_NAMESPACE
2023 const char *nsbeg = begin;
2024 if (skipToken(nsbeg, end, QT_STRINGIFY(QT_NAMESPACE)) && nsbeg + 2 < end && nsbeg[0] == ':'
2025 && nsbeg[1] == ':') {
2026 begin = nsbeg + 2;
2027 while (begin != end && is_space(*begin))
2028 begin++;
2029 }
2030#else
2031 Q_UNUSED(begin);
2032 Q_UNUSED(end);
2033#endif
2034 }
2035
2036public:
2037#if defined(Q_CC_CLANG) || defined (Q_CC_GNU)
2038 // this is much simpler than the full type normalization below
2039 // the reason is that the signature returned by Q_FUNC_INFO is already
2040 // normalized to the largest degree, and we need to do only small adjustments
2041 constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
2042 {
2043 // bail out if there is an anonymous struct
2044 std::string_view name(begin, end-begin);
2045#if defined (Q_CC_CLANG)
2046 if (name.find("anonymous ") != std::string_view::npos)
2047 return normalizeType(begin, end);
2048#endif
2049 if (name.find("unnamed ") != std::string_view::npos)
2050 return normalizeType(begin, end);
2051 while (begin < end) {
2052 if (*begin == ' ') {
2053 if (last == ',' || last == '>' || last == '<' || last == '*' || last == '&') {
2054 ++begin;
2055 continue;
2056 }
2057 }
2058 if (last == ' ') {
2059 if (*begin == '*' || *begin == '&' || *begin == '(') {
2060 replaceLast(*begin);
2061 ++begin;
2062 continue;
2063 }
2064 }
2065 if (!is_ident_char(last)) {
2066 skipStructClassOrEnum(begin, end);
2067 if (begin == end)
2068 break;
2069
2070 skipQtNamespace(begin, end);
2071 if (begin == end)
2072 break;
2073
2074 normalizeIntegerTypes(begin, end);
2075 if (begin == end)
2076 break;
2077 }
2078 append(*begin);
2079 ++begin;
2080 }
2081 return len;
2082 }
2083#else
2084 // MSVC needs the full normalization, as it puts the const in a different
2085 // place than we expect
2086 constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
2087 { return normalizeType(begin, end); }
2088#endif
2089
2090 constexpr int normalizeType(const char *begin, const char *end, bool adjustConst = true)
2091 {
2092 // Trim spaces
2093 while (begin != end && is_space(*begin))
2094 begin++;
2095 while (begin != end && is_space(*(end - 1)))
2096 end--;
2097
2098 // Convert 'char const *' into 'const char *'. Start at index 1,
2099 // not 0, because 'const char *' is already OK.
2100 const char *cst = begin + 1;
2101 if (*begin == '\'' || *begin == '"')
2102 cst = skipString(begin, end);
2103 bool seenStar = false;
2104 bool hasMiddleConst = false;
2105 while (cst < end) {
2106 if (*cst == '\"' || (*cst == '\'' && !is_number(cst[-1]))) {
2107 cst = skipString(cst, end);
2108 if (cst == end)
2109 break;
2110 }
2111
2112 // We mustn't convert 'char * const *' into 'const char **'
2113 // and we must beware of 'Bar<const Bla>'.
2114 if (*cst == '&' || *cst == '*' || *cst == '[') {
2115 seenStar = *cst != '&' || cst != (end - 1);
2116 break;
2117 }
2118 if (*cst == '<') {
2119 cst = skipTemplate(cst + 1, end);
2120 if (cst == end)
2121 break;
2122 }
2123 cst++;
2124 const char *skipedCst = cst;
2125 if (!is_ident_char(*(cst - 1)) && skipToken(skipedCst, end, "const")) {
2126 const char *testEnd = end;
2127 while (skipedCst < testEnd--) {
2128 if (*testEnd == '*' || *testEnd == '['
2129 || (*testEnd == '&' && testEnd != (end - 1))) {
2130 seenStar = true;
2131 break;
2132 }
2133 if (*testEnd == '>')
2134 break;
2135 }
2136 if (adjustConst && !seenStar) {
2137 if (*(end - 1) == '&')
2138 end--;
2139 } else {
2140 appendStr("const ");
2141 }
2142 normalizeType(begin, cst, false);
2143 begin = skipedCst;
2144 hasMiddleConst = true;
2145 break;
2146 }
2147 }
2148 if (skipToken(begin, end, "const")) {
2149 if (adjustConst && !seenStar) {
2150 if (*(end - 1) == '&')
2151 end--;
2152 } else {
2153 appendStr("const ");
2154 }
2155 }
2156 if (seenStar && adjustConst) {
2157 const char *e = end;
2158 if (*(end - 1) == '&' && *(end - 2) != '&')
2159 e--;
2160 while (begin != e && is_space(*(e - 1)))
2161 e--;
2162 const char *token = "tsnoc"; // 'const' reverse, to check if it ends with const
2163 while (*token && begin != e && *(--e) == *token++)
2164 ;
2165 if (!*token && begin != e && !is_ident_char(*(e - 1))) {
2166 while (begin != e && is_space(*(e - 1)))
2167 e--;
2168 end = e;
2169 }
2170 }
2171
2172 skipStructClassOrEnum(begin, end);
2173 skipQtNamespace(begin, end);
2174
2175 if (skipToken(begin, end, "QVector")) {
2176 // Replace QVector by QList
2177 appendStr("QList");
2178 }
2179
2180 if (skipToken(begin, end, "QPair")) {
2181 // replace QPair by std::pair
2182 appendStr("std::pair");
2183 }
2184
2185 if (!hasMiddleConst)
2186 // Normalize the integer types
2187 normalizeIntegerTypes(begin, end);
2188
2189 bool spaceSkiped = true;
2190 while (begin != end) {
2191 char c = *begin++;
2192 if (is_space(c)) {
2193 spaceSkiped = true;
2194 } else if ((c == '\'' && !is_number(last)) || c == '\"') {
2195 begin--;
2196 auto x = skipString(begin, end);
2197 while (begin < x)
2198 append(*begin++);
2199 } else {
2200 if (spaceSkiped && is_ident_char(last) && is_ident_char(c))
2201 append(' ');
2202 append(c);
2203 spaceSkiped = false;
2204 if (c == '<') {
2205 do {
2206 // template recursion
2207 const char *tpl = skipTemplate(begin, end, true);
2208 normalizeType(begin, tpl, false);
2209 if (tpl == end)
2210 return len;
2211 append(*tpl);
2212 begin = tpl;
2213 } while (*begin++ == ',');
2214 }
2215 }
2216 }
2217 return len;
2218 }
2219};
2220
2221// Normalize the type between begin and end, and store the data in the output. Returns the length.
2222// The idea is to first run this function with nullptr as output to allocate the output with the
2223// size
2224constexpr int qNormalizeType(const char *begin, const char *end, char *output)
2225{
2226 return QTypeNormalizer { output }.normalizeType(begin, end);
2227}
2228
2229template<typename T>
2230struct is_std_pair : std::false_type {};
2231
2232template <typename T1_, typename T2_>
2233struct is_std_pair<std::pair<T1_, T2_>> : std::true_type {
2234 using T1 = T1_;
2235 using T2 = T2_;
2236};
2237
2238template<typename T>
2239constexpr auto typenameHelper()
2240{
2241 if constexpr (is_std_pair<T>::value) {
2242 using T1 = typename is_std_pair<T>::T1;
2243 using T2 = typename is_std_pair<T>::T2;
2244 std::remove_const_t<std::conditional_t<bool (QMetaTypeId2<T1>::IsBuiltIn), typename QMetaTypeId2<T1>::NameAsArrayType, decltype(typenameHelper<T1>())>> t1Name {};
2245 std::remove_const_t<std::conditional_t<bool (QMetaTypeId2<T2>::IsBuiltIn), typename QMetaTypeId2<T2>::NameAsArrayType, decltype(typenameHelper<T2>())>> t2Name {};
2246 if constexpr (bool (QMetaTypeId2<T1>::IsBuiltIn) ) {
2248 } else {
2249 t1Name = typenameHelper<T1>();
2250 }
2251 if constexpr (bool(QMetaTypeId2<T2>::IsBuiltIn)) {
2253 } else {
2254 t2Name = typenameHelper<T2>();
2255 }
2256 constexpr auto nonTypeDependentLen = sizeof("std::pair<,>");
2257 constexpr auto t1Len = t1Name.size() - 1;
2258 constexpr auto t2Len = t2Name.size() - 1;
2259 constexpr auto length = nonTypeDependentLen + t1Len + t2Len;
2260 std::array<char, length + 1> result {};
2261 constexpr auto prefix = "std::pair<";
2262 int currentLength = 0;
2263 for (; currentLength < int(sizeof("std::pair<") - 1); ++currentLength)
2264 result[currentLength] = prefix[currentLength];
2265 for (int i = 0; i < int(t1Len); ++currentLength, ++i)
2266 result[currentLength] = t1Name[i];
2267 result[currentLength++] = ',';
2268 for (int i = 0; i < int(t2Len); ++currentLength, ++i)
2269 result[currentLength] = t2Name[i];
2270 result[currentLength++] = '>';
2271 result[currentLength++] = '\0';
2272 return result;
2273 } else {
2274 constexpr auto prefix = sizeof(
2275#ifdef QT_NAMESPACE
2276 QT_STRINGIFY(QT_NAMESPACE) "::"
2277#endif
2278#if defined(Q_CC_MSVC) && defined(Q_CC_CLANG)
2279 "auto __cdecl QtPrivate::typenameHelper(void) [T = "
2280#elif defined(Q_CC_MSVC)
2281 "auto __cdecl QtPrivate::typenameHelper<"
2282#elif defined(Q_CC_CLANG)
2283 "auto QtPrivate::typenameHelper() [T = "
2284#elif defined(Q_CC_GHS)
2285 "auto QtPrivate::typenameHelper<T>()[with T="
2286#else
2287 "constexpr auto QtPrivate::typenameHelper() [with T = "
2288#endif
2289 ) - 1;
2290#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
2291 constexpr int suffix = sizeof(">(void)");
2292#else
2293 constexpr int suffix = sizeof("]");
2294#endif
2295
2296#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU_ONLY < 804
2297 auto func = Q_FUNC_INFO;
2298 const char *begin = func + prefix;
2299 const char *end = func + sizeof(Q_FUNC_INFO) - suffix;
2300 // This is an upper bound of the size since the normalized signature should always be smaller
2301 constexpr int len = sizeof(Q_FUNC_INFO) - suffix - prefix;
2302#else
2303 constexpr auto func = Q_FUNC_INFO;
2304 constexpr const char *begin = func + prefix;
2305 constexpr const char *end = func + sizeof(Q_FUNC_INFO) - suffix;
2306 constexpr int len = QTypeNormalizer{ nullptr }.normalizeTypeFromSignature(begin, end);
2307#endif
2308 std::array<char, len + 1> result {};
2310 return result;
2311 }
2312}
2313
2314template<typename T, typename = void>
2315struct BuiltinMetaType : std::integral_constant<int, 0>
2316{
2317};
2318template<typename T>
2319struct BuiltinMetaType<T, std::enable_if_t<QMetaTypeId2<T>::IsBuiltIn>>
2320 : std::integral_constant<int, QMetaTypeId2<T>::MetaType>
2321{
2322};
2323
2324template<typename T, bool = (QTypeTraits::has_operator_equal_v<T> && !std::is_pointer_v<T>)>
2326{
2329 static bool equals(const QMetaTypeInterface *, const void *a, const void *b)
2330 { return *reinterpret_cast<const T *>(a) == *reinterpret_cast<const T *>(b); }
2332};
2333
2334template<typename T>
2336{
2337 static constexpr QMetaTypeInterface::EqualsFn equals = nullptr;
2338};
2339
2340template<typename T, bool = (QTypeTraits::has_operator_less_than_v<T> && !std::is_pointer_v<T>)>
2342{
2343 static bool lessThan(const QMetaTypeInterface *, const void *a, const void *b)
2344 { return *reinterpret_cast<const T *>(a) < *reinterpret_cast<const T *>(b); }
2345};
2346
2347template<typename T>
2349{
2350 static constexpr QMetaTypeInterface::LessThanFn lessThan = nullptr;
2351};
2352
2353template<typename T, bool = (QTypeTraits::has_ostream_operator_v<QDebug, T> && !std::is_pointer_v<T>)>
2355{
2356 static void debugStream(const QMetaTypeInterface *, QDebug &dbg, const void *a)
2357 { dbg << *reinterpret_cast<const T *>(a); }
2358};
2359
2360template<typename T>
2362{
2363 static constexpr QMetaTypeInterface::DebugStreamFn debugStream = nullptr;
2364};
2365
2366template<typename T, bool = QTypeTraits::has_stream_operator_v<QDataStream, T>>
2368{
2369 static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a)
2370 { ds << *reinterpret_cast<const T *>(a); }
2371 static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a)
2372 { ds >> *reinterpret_cast<T *>(a); }
2373};
2374
2375template<typename T>
2377{
2378 static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr;
2379 static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
2380};
2381
2382// Performance optimization:
2383//
2384// Don't add all these symbols to the dynamic symbol tables on ELF systems and
2385// on Darwin. Each library is going to have a copy anyway and QMetaType already
2386// copes with some of these being "hidden" (see QMetaType::idHelper()). We may
2387// as well let the linker know it can always use the local copy.
2388//
2389// This is currently not enabled for GCC due to
2390// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106023
2391
2392#if !defined(Q_OS_WIN) && defined(Q_CC_CLANG)
2393# pragma GCC visibility push(hidden)
2394#endif
2395
2396template<typename S>
2398{
2399public:
2400 static constexpr decltype(typenameHelper<S>()) name = typenameHelper<S>();
2401 static constexpr unsigned Flags = QMetaTypeTypeFlags<S>::Flags;
2402
2404 {
2405 if constexpr (std::is_default_constructible_v<S> && !QTypeInfo<S>::isValueInitializationBitwiseZero) {
2406 return [](const QMetaTypeInterface *, void *addr) { new (addr) S(); };
2407 } else {
2408 return nullptr;
2409 }
2410 }
2411
2413 {
2414 if constexpr (std::is_copy_constructible_v<S> && !std::is_trivially_copy_constructible_v<S>) {
2415 return [](const QMetaTypeInterface *, void *addr, const void *other) {
2416 new (addr) S(*reinterpret_cast<const S *>(other));
2417 };
2418 } else {
2419 return nullptr;
2420 }
2421 }
2422
2424 {
2425 if constexpr (std::is_move_constructible_v<S> && !std::is_trivially_move_constructible_v<S>) {
2426 return [](const QMetaTypeInterface *, void *addr, void *other) {
2427 new (addr) S(std::move(*reinterpret_cast<S *>(other)));
2428 };
2429 } else {
2430 return nullptr;
2431 }
2432 }
2433
2435 {
2436 if constexpr (std::is_destructible_v<S> && !std::is_trivially_destructible_v<S>)
2437 return [](const QMetaTypeInterface *, void *addr) {
2438 reinterpret_cast<S *>(addr)->~S();
2439 };
2440 else
2441 return nullptr;
2442 }
2443
2445 {
2447 return []() { QMetaTypeId2<S>::qt_metatype_id(); };
2448 } else {
2449 return nullptr;
2450 }
2451 }
2452
2453 static constexpr const char *getName()
2454 {
2455 if constexpr (bool(QMetaTypeId2<S>::IsBuiltIn)) {
2456 return QMetaTypeId2<S>::nameAsArray.data();
2457 } else {
2458 return name.data();
2459 }
2460 }
2461};
2462
2463template<typename T>
2465{
2466 // if the type ID for T is known at compile-time, then we can declare
2467 // the QMetaTypeInterface object const; otherwise, we declare it as
2468 // non-const and the .typeId is updated by QMetaType::idHelper().
2469 static constexpr bool IsConstMetaTypeInterface = !!BuiltinMetaType<T>::value;
2470 using InterfaceType = std::conditional_t<IsConstMetaTypeInterface, const QMetaTypeInterface, NonConstMetaTypeInterface>;
2471
2472 static inline InterfaceType metaType = {
2473 /*.revision=*/ QMetaTypeInterface::CurrentRevision,
2474 /*.alignment=*/ alignof(T),
2475 /*.size=*/ sizeof(T),
2476 /*.flags=*/ QMetaTypeForType<T>::Flags,
2477 /*.typeId=*/ BuiltinMetaType<T>::value,
2479 /*.name=*/ QMetaTypeForType<T>::getName(),
2480 /*.defaultCtr=*/ QMetaTypeForType<T>::getDefaultCtr(),
2481 /*.copyCtr=*/ QMetaTypeForType<T>::getCopyCtr(),
2482 /*.moveCtr=*/ QMetaTypeForType<T>::getMoveCtr(),
2483 /*.dtor=*/ QMetaTypeForType<T>::getDtor(),
2489 /*.legacyRegisterOp=*/ QMetaTypeForType<T>::getLegacyRegister()
2490 };
2491};
2492
2493#if !defined(Q_OS_WIN) && defined(Q_CC_CLANG)
2494# pragma GCC visibility pop
2495#endif
2496
2497template<>
2499{
2500public:
2501 static constexpr QMetaTypeInterface metaType =
2502 {
2503 /*.revision=*/ 0,
2504 /*.alignment=*/ 0,
2505 /*.size=*/ 0,
2506 /*.flags=*/ 0,
2507 /*.typeId=*/ BuiltinMetaType<void>::value,
2508 /*.metaObjectFn=*/ nullptr,
2509 /*.name=*/ "void",
2510 /*.defaultCtr=*/ nullptr,
2511 /*.copyCtr=*/ nullptr,
2512 /*.moveCtr=*/ nullptr,
2513 /*.dtor=*/ nullptr,
2514 /*.equals=*/ nullptr,
2515 /*.lessThan=*/ nullptr,
2516 /*.debugStream=*/ nullptr,
2517 /*.dataStreamOut=*/ nullptr,
2518 /*.dataStreamIn=*/ nullptr,
2519 /*.legacyRegisterOp=*/ nullptr
2520 };
2521};
2522
2523/*
2524 MSVC instantiates extern templates
2525(https://developercommunity.visualstudio.com/t/c11-extern-templates-doesnt-work-for-class-templat/157868)
2526
2527 The INTEGRITY compiler apparently does too.
2528
2529 On Windows (with other compilers or whenever MSVC is fixed), we can't declare
2530 QMetaTypeInterfaceWrapper with __declspec(dllimport) because taking its
2531 address is not a core constant expression.
2532 */
2533#if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
2534
2535#ifdef QT_NO_DATA_RELOCATION
2536# define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name) \
2537 extern template class Q_CORE_EXPORT QMetaTypeForType<Name>;
2538#else
2539# define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name) \
2540 extern template class Q_CORE_EXPORT QMetaTypeForType<Name>; \
2541 extern template struct Q_CORE_EXPORT QMetaTypeInterfaceWrapper<Name>;
2542#endif
2543
2549#undef QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER
2550#endif
2551
2552template<typename T>
2554{
2555 using type = std::remove_pointer_t<T>;
2556};
2557
2558#define Q_REMOVE_POINTER_LIKE_IMPL(Pointer) \
2559template <typename T> \
2560struct qRemovePointerLike<Pointer<T>> \
2561{ \
2562 using type = T; \
2563};
2564
2566template<typename T>
2568#undef Q_REMOVE_POINTER_LIKE_IMPL
2569
2570template<typename T, typename ForceComplete_>
2572{
2573 using type = T;
2574 using ForceComplete = ForceComplete_;
2575};
2576
2577template<typename T>
2579{
2580 // don't check the type is suitable here
2581 using Ty = typename MetatypeDecay<T>::type;
2583}
2584
2585template<typename Unique, typename TypeCompletePair>
2587{
2588 using T = typename TypeCompletePair::type;
2589 using ForceComplete = typename TypeCompletePair::ForceComplete;
2590 using Ty = typename MetatypeDecay<T>::type;
2591 using Tz = qRemovePointerLike_t<Ty>;
2592
2593 if constexpr (std::is_void_v<Tz>) {
2594 // early out to avoid expanding the rest of the templates
2596 } else if constexpr (ForceComplete::value) {
2597 checkTypeIsSuitableForMetaType<Ty>();
2599 } else if constexpr (std::is_reference_v<Tz>) {
2600 return nullptr;
2601 } else if constexpr (!is_complete<Tz, Unique>::value) {
2602 return nullptr;
2603 } else {
2604 // don't check the type is suitable here
2606 }
2607}
2608
2609} // namespace QtPrivate
2610
2611template<typename T>
2613{
2614 QtPrivate::checkTypeIsSuitableForMetaType<T>();
2615 return QMetaType(QtPrivate::qMetaTypeInterfaceForType<T>());
2616}
2617
2619{
2620 return d_ptr ? d_ptr->size : 0;
2621}
2622
2624{
2625 return d_ptr ? d_ptr->alignment : 0;
2626}
2627
2628constexpr QMetaType::TypeFlags QMetaType::flags() const
2629{
2630 return d_ptr ? TypeFlags(d_ptr->flags) : TypeFlags{};
2631}
2632
2633constexpr const QMetaObject *QMetaType::metaObject() const
2634{
2635 return d_ptr && d_ptr->metaObjectFn ? d_ptr->metaObjectFn(d_ptr) : nullptr;
2636}
2637
2638template<typename... T>
2640 /*
2641 Unique in qTryMetaTypeInterfaceForType does not have to be unique here
2642 as we require _all_ types here to be actually complete.
2643 We just want to have the additional type processing that exist in
2644 QtPrivate::qTryMetaTypeInterfaceForType as opposed to the normal
2645 QtPrivate::qMetaTypeInterfaceForType used in QMetaType::fromType
2646 */
2647 QtPrivate::qTryMetaTypeInterfaceForType<void, QtPrivate::TypeAndForceComplete<T, std::true_type>>()...
2648};
2649
2650constexpr const char *QMetaType::name() const
2651{
2652 return d_ptr ? d_ptr->name : nullptr;
2653}
2654
2655template<typename Unique,typename... T>
2657 QtPrivate::qTryMetaTypeInterfaceForType<Unique, T>()...
2658};
2659
2660inline size_t qHash(QMetaType type, size_t seed = 0)
2661{
2662 // We cannot use d_ptr here since the same type in different DLLs
2663 // might result in different pointers!
2664 return qHash(type.id(), seed);
2665}
2666
2668
2670 QPairVariantInterfaceImpl, Q_CORE_EXPORT)
2671
2672#endif // QMETATYPE_H
\inmodule QtCore
Definition qbitarray.h:13
\inmodule QtGui
Definition qbitmap.h:16
\inmodule QtGui
Definition qbrush.h:30
\inmodule QtCore
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
\inmodule QtCore\reentrant
Definition qcborarray.h:20
\inmodule QtCore\reentrant
Definition qcbormap.h:21
\inmodule QtCore\reentrant
Definition qcborvalue.h:50
\inmodule QtCore
Definition qchar.h:48
The QColorSpace class provides a color space abstraction.
Definition qcolorspace.h:21
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition qcursor.h:45
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore\reentrant
Definition qdatetime.h:257
\inmodule QtCore \reentrant
Definition qdatetime.h:27
\inmodule QtCore
\inmodule QtCore
\reentrant
Definition qfont.h:20
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
\inmodule QtGui
Definition qimage.h:37
\inmodule QtCore
Definition qiterable.h:408
\inmodule QtCore\reentrant
Definition qjsonarray.h:18
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
Definition qjsonobject.h:20
\inmodule QtCore\reentrant
Definition qjsonvalue.h:24
The QKeySequence class encapsulates a key sequence as used by shortcuts.
\inmodule QtCore
Definition qline.h:182
\inmodule QtCore
Definition qline.h:18
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
\inmodule QtCore
Definition qmetatype.h:320
static constexpr QMetaType fromType()
Definition qmetatype.h:2612
void destruct(void *data) const
constexpr TypeFlags flags() const
Definition qmetatype.h:2628
static bool hasRegisteredConverterFunction()
Returns true, if the meta type system has a registered conversion from type From to type To.
Definition qmetatype.h:716
const QtPrivate::QMetaTypeInterface * iface() const
Definition qmetatype.h:750
constexpr qsizetype sizeOf() const
Definition qmetatype.h:2618
constexpr qsizetype alignOf() const
Definition qmetatype.h:2623
bool debugStream(QDebug &dbg, const void *rhs)
Streams the object at rhs to the debug stream dbg.
static QMetaType fromName(QByteArrayView name)
Returns a QMetaType matching typeName.
static bool hasRegisteredMutableViewFunction()
Returns true, if the meta type system has a registered mutable view on type From of type To.
Definition qmetatype.h:725
bool isMoveConstructible() const noexcept
Definition qmetatype.h:475
void destroy(void *data) const
int id(int=0) const
Definition qmetatype.h:454
static bool registerConverter(To(From::*function)() const)
Definition qmetatype.h:550
static void registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, QMetaType type)
std::function< bool(void *src, void *target)> MutableViewFunction
Definition qmetatype.h:539
friend bool operator==(QMetaType a, QMetaType b)
Definition qmetatype.h:501
TypeFlag
The enum describes attributes of a type supported by QMetaType.
Definition qmetatype.h:378
@ SharedPointerToQObject
Definition qmetatype.h:387
@ NeedsDestruction
Definition qmetatype.h:380
@ WeakPointerToQObject
Definition qmetatype.h:388
@ NeedsCopyConstruction
Definition qmetatype.h:397
@ IsUnsignedEnumeration
Definition qmetatype.h:390
@ PointerToQObject
Definition qmetatype.h:385
@ IsEnumeration
Definition qmetatype.h:386
@ TrackingPointerToQObject
Definition qmetatype.h:389
@ RelocatableType
Definition qmetatype.h:381
@ NeedsMoveConstruction
Definition qmetatype.h:398
@ NeedsConstruction
Definition qmetatype.h:379
@ PointerToGadget
Definition qmetatype.h:392
void * create(const void *copy=nullptr) const
static bool registerConverter(UnaryFunction function)
Definition qmetatype.h:607
void registerType() const
Definition qmetatype.h:444
std::function< bool(const void *src, void *target)> ConverterFunction
Definition qmetatype.h:536
friend bool operator!=(QMetaType a, QMetaType b)
Definition qmetatype.h:512
constexpr const QMetaObject * metaObject() const
Definition qmetatype.h:2633
bool isCopyConstructible() const noexcept
Definition qmetatype.h:474
static bool registerConverter()
Definition qmetatype.h:543
bool isDefaultConstructible() const noexcept
Definition qmetatype.h:473
constexpr QMetaType(const QtPrivate::QMetaTypeInterface *d)
Definition qmetatype.h:439
constexpr const char * name() const
Definition qmetatype.h:2650
constexpr QMetaType()=default
void * construct(void *where, const void *copy=nullptr) const
static bool registerMutableView(UnaryFunction function)
Definition qmetatype.h:632
bool load(QDataStream &stream, void *data) const
Reads the object of this type from the given stream into data.
bool save(QDataStream &stream, const void *data) const
Writes the object pointed to by data to the given stream.
static bool registerConverter(To(From::*function)(bool *) const)
Definition qmetatype.h:586
static bool registerMutableView(To(From::*function)())
Definition qmetatype.h:568
bool hasRegisteredDebugStreamOperator() const
bool isDestructible() const noexcept
Definition qmetatype.h:476
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:90
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
static const QPartialOrdering Less
Definition qcompare.h:39
static const QPartialOrdering Equivalent
Definition qcompare.h:40
static const QPartialOrdering Unordered
Definition qcompare.h:42
\inmodule QtGui
Definition qpen.h:25
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
\inmodule QtCore\reentrant
Definition qpoint.h:214
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore
Definition qpointer.h:18
The QPolygonF class provides a list of points using floating point precision.
Definition qpolygon.h:96
The QPolygon class provides a list of points using integer precision.
Definition qpolygon.h:23
The QQuaternion class represents a quaternion consisting of a vector and scalar.
Definition qquaternion.h:21
\inmodule QtCore\reentrant
Definition qrect.h:483
\inmodule QtCore\reentrant
Definition qrect.h:30
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
\inmodule QtCore \reentrant
\inmodule QtCore
\inmodule QtCore
Definition qsize.h:207
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
Definition qsizepolicy.h:18
\inmodule QtCore
Definition qsize.h:25
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\reentrant
Definition qtextformat.h:90
\reentrant
Definition qtextformat.h:45
\inmodule QtCore \reentrant
Definition qdatetime.h:189
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
\inmodule QtCore
Definition qurl.h:94
\inmodule QtCore
Definition quuid.h:31
\inmodule QtCore
Definition qvariant.h:64
The QVector2D class represents a vector or vertex in 2D space.
Definition qvectornd.h:31
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
The QVector4D class represents a vector or vertex in 4D space.
Definition qvectornd.h:330
\inmodule QtCore
static void getSecondImpl(const void *const *pair, void *dataPtr)
Definition qmetatype.h:807
static void getFirstImpl(const void *const *pair, void *dataPtr)
Definition qmetatype.h:804
static constexpr QMetaTypeInterface::DtorFn getDtor()
Definition qmetatype.h:2434
static constexpr QMetaTypeInterface::CopyCtrFn getCopyCtr()
Definition qmetatype.h:2412
static constexpr QMetaTypeInterface::LegacyRegisterOp getLegacyRegister()
Definition qmetatype.h:2444
static constexpr const char * getName()
Definition qmetatype.h:2453
static constexpr QMetaTypeInterface::DefaultCtrFn getDefaultCtr()
Definition qmetatype.h:2403
static constexpr QMetaTypeInterface::MoveCtrFn getMoveCtr()
Definition qmetatype.h:2423
void(*)(const QMetaTypeInterface *, void *) DefaultCtrFn
Definition qmetatype.h:267
void(*)(const QMetaTypeInterface *, void *, const void *) CopyCtrFn
Definition qmetatype.h:269
DataStreamOutFn dataStreamOut
Definition qmetatype.h:282
QMTI_MUTABLE QBasicAtomicInt typeId
Definition qmetatype.h:260
void(*)(const QMetaTypeInterface *, QDataStream &, const void *) DataStreamOutFn
Definition qmetatype.h:281
void(*)(const QMetaTypeInterface *, QDataStream &, void *) DataStreamInFn
Definition qmetatype.h:283
void(*)(const QMetaTypeInterface *, void *, void *) MoveCtrFn
Definition qmetatype.h:271
const QMetaObject *(*)(const QMetaTypeInterface *) MetaObjectFn
Definition qmetatype.h:262
void(*)(const QMetaTypeInterface *, void *) DtorFn
Definition qmetatype.h:273
bool(*)(const QMetaTypeInterface *, const void *, const void *) LessThanFn
Definition qmetatype.h:277
LegacyRegisterOp legacyRegisterOp
Definition qmetatype.h:287
void(*)(const QMetaTypeInterface *, QDebug &, const void *) DebugStreamFn
Definition qmetatype.h:279
bool(*)(const QMetaTypeInterface *, const void *, const void *) EqualsFn
Definition qmetatype.h:275
static constexpr ushort CurrentRevision
Definition qmetatype.h:254
p1 load("image.bmp")
list append(new Employee("Blackpool", "Stephen"))
double e
bool isBuiltinType(const QByteArray &type)
Definition generator.cpp:40
Token token
Definition keywords.cpp:444
static QByteArray normalizeType(const QByteArray &ba)
Definition moc.cpp:24
Combined button and popup list for selecting options.
bool canConvert(const QQmlPropertyCache *fromMo, const QQmlPropertyCache *toMo)
void destruct(const QtPrivate::QMetaTypeInterface *iface, void *where)
void construct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy)
\macro QT_NAMESPACE
typename qRemovePointerLike< T >::type qRemovePointerLike_t
Definition qmetatype.h:2567
static constexpr bool checkTypeIsSuitableForMetaType()
Definition qmetatype.h:1180
constexpr auto typenameHelper()
Definition qmetatype.h:2239
constexpr bool IsQmlListType
Definition qmetatype.h:1251
constexpr bool IsUnsignedEnum
Definition qmetatype.h:1254
constexpr const QMetaTypeInterface * qTryMetaTypeInterfaceForType()
Definition qmetatype.h:2586
To convertImplicit(const From &from)
This template is used for implicit conversion from type From to type To.
Definition qmetatype.h:296
std::bool_constant< IsGadgetHelper< T >::IsRealGadget > IsRealGadget
Definition qmetatype.h:936
constexpr const QMetaTypeInterface * qMetaTypeInterfaceForType()
Definition qmetatype.h:2578
char qt_getEnumMetaObject(const T &)
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
static jboolean copy(JNIEnv *, jobject)
#define Q_BASIC_ATOMIC_INITIALIZER(a)
QCborSimpleType
Definition qcborcommon.h:23
#define Q_FALLTHROUGH()
#define Q_DECL_ENUMERATOR_DEPRECATED_X(x)
#define Q_DECL_PURE_FUNCTION
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_FLOAT_COMPARE
#define Q_FUNC_INFO
#define QT_WARNING_PUSH
QPair< QVariant, QVariant > QVariantPair
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
EGLStreamKHR stream
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
size_t qHash(const QFileSystemWatcherPathKey &key, size_t seed=0)
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition qflags.h:194
Flags
static char * qNormalizeType(char *d, int &templdepth, QByteArray &result)
static bool is_ident_char(char s)
static bool is_space(char s)
@ User
const char * typeName
constexpr int qMetaTypeId()
Definition qmetatype.h:1384
#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(SINGLE_ARG_TEMPLATE)
Definition qmetatype.h:1674
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
Definition qmetatype.h:1350
#define Q_REMOVE_POINTER_LIKE_IMPL(Pointer)
Definition qmetatype.h:2558
#define QT_FOR_EACH_STATIC_GUI_CLASS(F)
Definition qmetatype.h:146
constexpr const QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray[]
Definition qmetatype.h:2656
#define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME)
Definition qmetatype.h:1686
#define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)
Definition qmetatype.h:172
#define QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TAG, EXPORT)
Definition qmetatype.h:1355
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)
Definition qmetatype.h:128
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F)
Definition qmetatype.h:221
#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE)
Definition qmetatype.h:1580
#define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name)
Definition qmetatype.h:848
#define QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(F)
Definition qmetatype.h:47
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F)
Definition qmetatype.h:210
#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
Definition qmetatype.h:131
#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)
Definition qmetatype.h:71
#define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME)
Definition qmetatype.h:1532
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME)
Definition qmetatype.h:1716
#define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name)
Definition qmetatype.h:1543
constexpr const QtPrivate::QMetaTypeInterface *const qt_metaTypeArray[]
Definition qmetatype.h:2639
#define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F)
Definition qmetatype.h:783
constexpr int qRegisterMetaType()
Definition qmetatype.h:1397
#define QT_FOR_EACH_STATIC_CORE_CLASS(F)
Definition qmetatype.h:96
#define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME)
Definition qmetatype.h:1698
#define QT_DEFINE_METATYPE_ID(TypeName, Id, Name)
Definition qmetatype.h:207
int qRegisterNormalizedMetaTypeImplementation(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
Definition qmetatype.h:1311
#define QMTI_MUTABLE
Definition qmetatype.h:239
#define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name)
Definition qmetatype.h:2539
#define QT_FOR_EACH_STATIC_TYPE(F)
Definition qmetatype.h:198
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLenum GLuint id
[7]
GLfloat GLfloat f
GLenum src
GLenum type
GLenum target
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLenum func
Definition qopenglext.h:663
const GLubyte * c
GLenum GLsizei len
GLenum const void * addr
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
#define X(name)
static constexpr To convert(const std::array< Mapping, N > &mapping, From Mapping::*from, To Mapping::*to, From value, To defaultValue)
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
#define QT_DEPRECATED_VERSION_6_0
char Char
#define QT_STRINGIFY(x)
#define Q_UNUSED(x)
static int compare(quint64 a, quint64 b)
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:145
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned int uint
Definition qtypes.h:29
long long qint64
Definition qtypes.h:55
unsigned short ushort
Definition qtypes.h:28
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition qtypes.h:40
double qreal
Definition qtypes.h:92
unsigned char quint8
Definition qtypes.h:41
static bool lessThan(const QChar *a, int l, const char *c)
Definition qurlidna.cpp:321
QT_BEGIN_NAMESPACE typedef uchar * output
QT_END_NAMESPACE typedef QT_PREPEND_NAMESPACE(quintptr) WId
QDataStream & operator<<(QDataStream &out, const MyClass &myObj)
[4]
obj metaObject() -> className()
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QQuickView * view
[0]
view create()
\inmodule QtCore
static QByteArray normalizedType(const char *type)
static constexpr int qt_metatype_id()
Definition qmetatype.h:1232
void NameAsArrayType
Definition qmetatype.h:1219
static constexpr int qt_metatype_id()
Definition qmetatype.h:1221
QPairVariantInterfaceImpl operator()(const std::pair< T, U > &f) const
Definition qmetatype.h:838
static T * internalData(const QWeakPointer< T > &p) noexcept
static bool registerConverter()
Definition qmetatype.h:1140
static bool registerConverter()
Definition qmetatype.h:1155
static yes_type checkType(const QObject *)
static const T & declval()
static constexpr const QMetaObject * metaObjectFunction(const QMetaTypeInterface *)
Definition qmetatype.h:1006
static constexpr const QMetaObject * value()
Definition qmetatype.h:971
const QMetaObject *(*)(const QMetaTypeInterface *) MetaObjectFn
Definition qmetatype.h:972
QIterable< QMetaAssociation > operator()(const From &f) const
Definition qmetatype.h:1790
QIterable< QMetaAssociation > operator()(From &f) const
Definition qmetatype.h:1799
static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a)
Definition qmetatype.h:2371
static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a)
Definition qmetatype.h:2369
static void debugStream(const QMetaTypeInterface *, QDebug &dbg, const void *a)
Definition qmetatype.h:2356
QT_WARNING_PUSH static QT_WARNING_DISABLE_FLOAT_COMPARE bool equals(const QMetaTypeInterface *, const void *a, const void *b)
Definition qmetatype.h:2329
static bool lessThan(const QMetaTypeInterface *, const void *a, const void *b)
Definition qmetatype.h:2343
static constexpr int qt_metatype_id()
Definition qmetatype.h:1242
static constexpr int qt_metatype_id()
Definition qmetatype.h:1238
std::conditional_t< IsConstMetaTypeInterface, const QMetaTypeInterface, NonConstMetaTypeInterface > InterfaceType
Definition qmetatype.h:2470
QIterable< QMetaSequence > operator()(const From &f) const
Definition qmetatype.h:1748
QIterable< QMetaSequence > operator()(From &f) const
Definition qmetatype.h:1757
QObject * operator()(const QWeakPointer< T > &p) const
Definition qmetatype.h:1303
QObject * operator()(const SmartPointer &p) const
Definition qmetatype.h:1289
constexpr int normalizeType(const char *begin, const char *end, bool adjustConst=true)
Definition qmetatype.h:2090
constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
Definition qmetatype.h:2086
static auto check(...) -> std::false_type
static auto check(U *) -> std::integral_constant< bool, sizeof(U) !=0 >
decltype(check(static_cast< T * >(nullptr))) type
Definition qmetatype.h:862
std::remove_pointer_t< T > type
Definition qmetatype.h:2555
Definition moc.h:24