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