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