File indexing completed on 2025-09-18 09:26:38
0001
0002
0003
0004
0005
0006 #ifndef QMETATYPE_H
0007 #define QMETATYPE_H
0008
0009 #include <QtCore/qglobal.h>
0010 #include <QtCore/qatomic.h>
0011 #include <QtCore/qbytearray.h>
0012 #include <QtCore/qcompare.h>
0013 #include <QtCore/qdatastream.h>
0014 #include <QtCore/qflags.h>
0015 #include <QtCore/qfloat16.h>
0016 #include <QtCore/qhashfunctions.h>
0017 #include <QtCore/qiterable.h>
0018 #ifndef QT_NO_QOBJECT
0019 #include <QtCore/qobjectdefs.h>
0020 #endif
0021 #include <QtCore/qscopeguard.h>
0022 #include <QtCore/qttypetraits.h>
0023
0024 #include <array>
0025 #include <new>
0026 #include <vector>
0027 #include <list>
0028 #include <map>
0029 #include <functional>
0030 #include <optional>
0031 #include <QtCore/qxptype_traits.h>
0032
0033 #ifdef Bool
0034 #error qmetatype.h must be included before any header file that defines Bool
0035 #endif
0036
0037 QT_BEGIN_NAMESPACE
0038
0039
0040 enum class QCborSimpleType : quint8;
0041
0042 template <typename T>
0043 struct QMetaTypeId2;
0044
0045 template <typename T>
0046 inline constexpr int qMetaTypeId();
0047
0048
0049 #define QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(F)\
0050 F(Bool, 1, bool) \
0051 F(Int, 2, int) \
0052 F(UInt, 3, uint) \
0053 F(LongLong, 4, qlonglong) \
0054 F(ULongLong, 5, qulonglong) \
0055 F(Double, 6, double) \
0056 F(Long, 32, long) \
0057 F(Short, 33, short) \
0058 F(Char, 34, char) \
0059 F(Char16, 56, char16_t) \
0060 F(Char32, 57, char32_t) \
0061 F(ULong, 35, ulong) \
0062 F(UShort, 36, ushort) \
0063 F(UChar, 37, uchar) \
0064 F(Float, 38, float) \
0065 F(SChar, 40, signed char) \
0066 F(Nullptr, 51, std::nullptr_t) \
0067 F(QCborSimpleType, 52, QCborSimpleType) \
0068
0069 #define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F) \
0070 QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(F) \
0071 F(Void, 43, void) \
0072
0073 #define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F) \
0074 F(VoidStar, 31, void*) \
0075
0076 #if QT_CONFIG(easingcurve)
0077 #define QT_FOR_EACH_STATIC_EASINGCURVE(F)\
0078 F(QEasingCurve, 29, QEasingCurve)
0079 #else
0080 #define QT_FOR_EACH_STATIC_EASINGCURVE(F)
0081 #endif
0082
0083 #if QT_CONFIG(itemmodel)
0084 #define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)\
0085 F(QModelIndex, 42, QModelIndex) \
0086 F(QPersistentModelIndex, 50, QPersistentModelIndex)
0087 #else
0088 #define QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
0089 #endif
0090
0091 #if QT_CONFIG(regularexpression)
0092 # define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \
0093 F(QRegularExpression, 44, QRegularExpression)
0094 #else
0095 # define QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F)
0096 #endif
0097 #ifndef QT_NO_VARIANT
0098 # define QT_FOR_EACH_STATIC_QVARIANT(F) \
0099 F(QVariant, 41, QVariant)
0100 #else
0101 # define QT_FOR_EACH_STATIC_QVARIANT(F)
0102 #endif
0103
0104 #define QT_FOR_EACH_STATIC_CORE_CLASS(F)\
0105 F(QChar, 7, QChar) \
0106 F(QString, 10, QString) \
0107 F(QByteArray, 12, QByteArray) \
0108 F(QBitArray, 13, QBitArray) \
0109 F(QDate, 14, QDate) \
0110 F(QTime, 15, QTime) \
0111 F(QDateTime, 16, QDateTime) \
0112 F(QUrl, 17, QUrl) \
0113 F(QLocale, 18, QLocale) \
0114 F(QRect, 19, QRect) \
0115 F(QRectF, 20, QRectF) \
0116 F(QSize, 21, QSize) \
0117 F(QSizeF, 22, QSizeF) \
0118 F(QLine, 23, QLine) \
0119 F(QLineF, 24, QLineF) \
0120 F(QPoint, 25, QPoint) \
0121 F(QPointF, 26, QPointF) \
0122 QT_FOR_EACH_STATIC_EASINGCURVE(F) \
0123 F(QUuid, 30, QUuid) \
0124 QT_FOR_EACH_STATIC_QVARIANT(F) \
0125 QT_FOR_EACH_STATIC_REGULAR_EXPRESSION(F) \
0126 F(QJsonValue, 45, QJsonValue) \
0127 F(QJsonObject, 46, QJsonObject) \
0128 F(QJsonArray, 47, QJsonArray) \
0129 F(QJsonDocument, 48, QJsonDocument) \
0130 F(QCborValue, 53, QCborValue) \
0131 F(QCborArray, 54, QCborArray) \
0132 F(QCborMap, 55, QCborMap) \
0133 F(Float16, 63, qfloat16) \
0134 QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
0135
0136 #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
0137 F(QObjectStar, 39, QObject*)
0138
0139 #ifndef QT_NO_VARIANT
0140 # define QT_FOR_EACH_STATIC_CORE_QVARIANT_TEMPLATE(F) \
0141 F(QVariantMap, 8, QVariantMap) \
0142 F(QVariantList, 9, QVariantList) \
0143 F(QVariantHash, 28, QVariantHash) \
0144 F(QVariantPair, 58, QVariantPair) \
0145
0146 #else
0147 # define QT_FOR_EACH_STATIC_CORE_QVARIANT_TEMPLATE(F)
0148 #endif
0149
0150 #define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F) \
0151 QT_FOR_EACH_STATIC_CORE_QVARIANT_TEMPLATE(F) \
0152 F(QByteArrayList, 49, QByteArrayList) \
0153 F(QStringList, 11, QStringList)
0154
0155 #if QT_CONFIG(shortcut)
0156 #define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)\
0157 F(QKeySequence, 0x100b, QKeySequence)
0158 #else
0159 #define QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F)
0160 #endif
0161
0162 #define QT_FOR_EACH_STATIC_GUI_CLASS(F)\
0163 F(QFont, 0x1000, QFont) \
0164 F(QPixmap, 0x1001, QPixmap) \
0165 F(QBrush, 0x1002, QBrush) \
0166 F(QColor, 0x1003, QColor) \
0167 F(QPalette, 0x1004, QPalette) \
0168 F(QIcon, 0x1005, QIcon) \
0169 F(QImage, 0x1006, QImage) \
0170 F(QPolygon, 0x1007, QPolygon) \
0171 F(QRegion, 0x1008, QRegion) \
0172 F(QBitmap, 0x1009, QBitmap) \
0173 F(QCursor, 0x100a, QCursor) \
0174 QT_FOR_EACH_STATIC_KEYSEQUENCE_CLASS(F) \
0175 F(QPen, 0x100c, QPen) \
0176 F(QTextLength, 0x100d, QTextLength) \
0177 F(QTextFormat, 0x100e, QTextFormat) \
0178 F(QTransform, 0x1010, QTransform) \
0179 F(QMatrix4x4, 0x1011, QMatrix4x4) \
0180 F(QVector2D, 0x1012, QVector2D) \
0181 F(QVector3D, 0x1013, QVector3D) \
0182 F(QVector4D, 0x1014, QVector4D) \
0183 F(QQuaternion, 0x1015, QQuaternion) \
0184 F(QPolygonF, 0x1016, QPolygonF) \
0185 F(QColorSpace, 0x1017, QColorSpace) \
0186
0187
0188 #define QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
0189 F(QSizePolicy, 0x2000, QSizePolicy) \
0190
0191
0192 #define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)\
0193 F(ULong, -1, ulong, "unsigned long") \
0194 F(UInt, -1, uint, "unsigned int") \
0195 F(UShort, -1, ushort, "unsigned short") \
0196 F(UChar, -1, uchar, "unsigned char") \
0197 F(LongLong, -1, qlonglong, "long long") \
0198 F(ULongLong, -1, qulonglong, "unsigned long long") \
0199 F(SChar, -1, signed char, "qint8") \
0200 F(UChar, -1, uchar, "quint8") \
0201 F(Short, -1, short, "qint16") \
0202 F(UShort, -1, ushort, "quint16") \
0203 F(Int, -1, int, "qint32") \
0204 F(UInt, -1, uint, "quint32") \
0205 F(LongLong, -1, qlonglong, "qint64") \
0206 F(ULongLong, -1, qulonglong, "quint64") \
0207 F(QByteArrayList, -1, QByteArrayList, "QList<QByteArray>") \
0208 F(QStringList, -1, QStringList, "QList<QString>") \
0209 QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F)
0210
0211 #ifndef QT_NO_VARIANT
0212 #define QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F) \
0213 F(QVariantList, -1, QVariantList, "QList<QVariant>") \
0214 F(QVariantMap, -1, QVariantMap, "QMap<QString,QVariant>") \
0215 F(QVariantHash, -1, QVariantHash, "QHash<QString,QVariant>") \
0216 F(QVariantPair, -1, QVariantPair, "QPair<QVariant,QVariant>") \
0217
0218 #else
0219 #define QT_FOR_EACH_STATIC_VARIANT_ALIAS_TYPE(F)
0220 #endif
0221
0222 #define QT_FOR_EACH_STATIC_TYPE(F)\
0223 QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)\
0224 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
0225 QT_FOR_EACH_STATIC_CORE_CLASS(F)\
0226 QT_FOR_EACH_STATIC_CORE_POINTER(F)\
0227 QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)\
0228 QT_FOR_EACH_STATIC_GUI_CLASS(F)\
0229 QT_FOR_EACH_STATIC_WIDGETS_CLASS(F)\
0230
0231 #define QT_DEFINE_METATYPE_ID(TypeName, Id, Name) \
0232 TypeName = Id,
0233
0234 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(F) \
0235 F(QList) \
0236 F(QQueue) \
0237 F(QStack) \
0238 F(QSet) \
0239
0240
0241 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \
0242 F(QHash, class) \
0243 F(QMap, class)
0244
0245 #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
0246 F(QSharedPointer) \
0247 F(QWeakPointer) \
0248 F(QPointer)
0249
0250 class QDataStream;
0251 struct QMetaObject;
0252
0253 namespace QtPrivate
0254 {
0255
0256 class QMetaTypeInterface;
0257
0258
0259
0260
0261
0262 #if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED) || !defined(Q_CC_MSVC)
0263 # define QMTI_MUTABLE
0264 using NonConstMetaTypeInterface = QMetaTypeInterface;
0265 #else
0266 # define QMTI_MUTABLE mutable
0267 using NonConstMetaTypeInterface = const QMetaTypeInterface;
0268 #endif
0269
0270 class QMetaTypeInterface
0271 {
0272 public:
0273
0274
0275
0276
0277
0278 static inline constexpr ushort CurrentRevision = 1;
0279
0280 ushort revision;
0281 ushort alignment;
0282 uint size;
0283 uint flags;
0284 QMTI_MUTABLE QBasicAtomicInt typeId;
0285
0286 using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *);
0287 MetaObjectFn metaObjectFn;
0288
0289 const char *name;
0290
0291 using DefaultCtrFn = void (*)(const QMetaTypeInterface *, void *);
0292 DefaultCtrFn defaultCtr;
0293 using CopyCtrFn = void (*)(const QMetaTypeInterface *, void *, const void *);
0294 CopyCtrFn copyCtr;
0295 using MoveCtrFn = void (*)(const QMetaTypeInterface *, void *, void *);
0296 MoveCtrFn moveCtr;
0297 using DtorFn = void (*)(const QMetaTypeInterface *, void *);
0298 DtorFn dtor;
0299 using EqualsFn = bool (*)(const QMetaTypeInterface *, const void *, const void *);
0300 EqualsFn equals;
0301 using LessThanFn = bool (*)(const QMetaTypeInterface *, const void *, const void *);
0302 LessThanFn lessThan;
0303 using DebugStreamFn = void (*)(const QMetaTypeInterface *, QDebug &, const void *);
0304 DebugStreamFn debugStream;
0305 using DataStreamOutFn = void (*)(const QMetaTypeInterface *, QDataStream &, const void *);
0306 DataStreamOutFn dataStreamOut;
0307 using DataStreamInFn = void (*)(const QMetaTypeInterface *, QDataStream &, void *);
0308 DataStreamInFn dataStreamIn;
0309
0310 using LegacyRegisterOp = void (*)();
0311 LegacyRegisterOp legacyRegisterOp;
0312 };
0313 #undef QMTI_MUTABLE
0314
0315
0316
0317
0318
0319 template<typename From, typename To>
0320 To convertImplicit(const From& from)
0321 {
0322 return from;
0323 }
0324
0325 template<typename T, bool>
0326 struct SequentialValueTypeIsMetaType;
0327 template<typename T, bool>
0328 struct AssociativeValueTypeIsMetaType;
0329 template<typename T, bool>
0330 struct IsMetaTypePair;
0331 template<typename, typename>
0332 struct MetaTypeSmartPointerHelper;
0333
0334 template<typename T>
0335 struct IsEnumOrFlags : std::disjunction<std::is_enum<T>, IsQFlags<T>> {};
0336 }
0337
0338 class Q_CORE_EXPORT QMetaType {
0339 public:
0340 #ifndef Q_QDOC
0341
0342 enum Type {
0343
0344 QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
0345
0346 FirstCoreType = Bool,
0347 LastCoreType = Float16,
0348 FirstGuiType = QFont,
0349 LastGuiType = QColorSpace,
0350 FirstWidgetsType = QSizePolicy,
0351 LastWidgetsType = QSizePolicy,
0352 HighestInternalId = LastWidgetsType,
0353
0354 QReal = sizeof(qreal) == sizeof(double) ? Double : Float,
0355
0356 UnknownType = 0,
0357 User = 65536
0358 };
0359 #else
0360
0361 enum Type {
0362 UnknownType = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5,
0363 Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36,
0364 UChar = 37, Float = 38,
0365 VoidStar = 31,
0366 QChar = 7, QString = 10, QStringList = 11, QByteArray = 12,
0367 QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
0368 QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,
0369 QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26,
0370 QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42,
0371 QPersistentModelIndex = 50, QRegularExpression = 44,
0372 QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48,
0373 QByteArrayList = 49, QObjectStar = 39, SChar = 40,
0374 Void = 43,
0375 Nullptr = 51,
0376 QVariantMap = 8, QVariantList = 9, QVariantHash = 28, QVariantPair = 58,
0377 QCborSimpleType = 52, QCborValue = 53, QCborArray = 54, QCborMap = 55,
0378 Char16 = 56, Char32 = 57,
0379 Int128 = 59, UInt128 = 60, Float128 = 61, BFloat16 = 62, Float16 = 63,
0380
0381
0382 QFont = 0x1000, QPixmap = 0x1001, QBrush = 0x1002, QColor = 0x1003, QPalette = 0x1004,
0383 QIcon = 0x1005, QImage = 0x1006, QPolygon = 0x1007, QRegion = 0x1008, QBitmap = 0x1009,
0384 QCursor = 0x100a, QKeySequence = 0x100b, QPen = 0x100c, QTextLength = 0x100d, QTextFormat = 0x100e,
0385 QTransform = 0x1010, QMatrix4x4 = 0x1011, QVector2D = 0x1012,
0386 QVector3D = 0x1013, QVector4D = 0x1014, QQuaternion = 0x1015, QPolygonF = 0x1016, QColorSpace = 0x1017,
0387
0388
0389 QSizePolicy = 0x2000,
0390
0391
0392 User = 65536
0393 };
0394 #endif
0395
0396 enum TypeFlag {
0397 NeedsConstruction = 0x1,
0398 NeedsDestruction = 0x2,
0399 RelocatableType = 0x4,
0400 #if QT_DEPRECATED_SINCE(6, 0)
0401 MovableType Q_DECL_ENUMERATOR_DEPRECATED_X("Use RelocatableType instead.") = RelocatableType,
0402 #endif
0403 PointerToQObject = 0x8,
0404 IsEnumeration = 0x10,
0405 SharedPointerToQObject = 0x20,
0406 WeakPointerToQObject = 0x40,
0407 TrackingPointerToQObject = 0x80,
0408 IsUnsignedEnumeration = 0x100,
0409 IsGadget = 0x200,
0410 PointerToGadget = 0x400,
0411 IsPointer = 0x800,
0412 IsQmlList =0x1000,
0413 IsConst = 0x2000,
0414
0415 NeedsCopyConstruction = 0x4000,
0416 NeedsMoveConstruction = 0x8000,
0417 };
0418 Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
0419
0420 static void registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, QMetaType type);
0421
0422 #if QT_DEPRECATED_SINCE(6, 0)
0423 QT_DEPRECATED_VERSION_6_0
0424 static int type(const char *typeName)
0425 { return QMetaType::fromName(typeName).id(); }
0426 QT_DEPRECATED_VERSION_6_0
0427 static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName)
0428 { return QMetaType::fromName(typeName).id(); }
0429 QT_DEPRECATED_VERSION_6_0
0430 static const char *typeName(int type)
0431 { return QMetaType(type).name(); }
0432 QT_DEPRECATED_VERSION_6_0
0433 static int sizeOf(int type)
0434 { return int(QMetaType(type).sizeOf()); }
0435 QT_DEPRECATED_VERSION_6_0
0436 static TypeFlags typeFlags(int type)
0437 { return QMetaType(type).flags(); }
0438 QT_DEPRECATED_VERSION_6_0
0439 static const QMetaObject *metaObjectForType(int type)
0440 { return QMetaType(type).metaObject(); }
0441 QT_DEPRECATED_VERSION_6_0
0442 static void *create(int type, const void *copy = nullptr)
0443 { return QMetaType(type).create(copy); }
0444 QT_DEPRECATED_VERSION_6_0
0445 static void destroy(int type, void *data)
0446 { return QMetaType(type).destroy(data); }
0447 QT_DEPRECATED_VERSION_6_0
0448 static void *construct(int type, void *where, const void *copy)
0449 { return QMetaType(type).construct(where, copy); }
0450 QT_DEPRECATED_VERSION_6_0
0451 static void destruct(int type, void *where)
0452 { return QMetaType(type).destruct(where); }
0453 #endif
0454 static bool isRegistered(int type);
0455
0456 explicit QMetaType(int type);
0457 explicit constexpr QMetaType(const QtPrivate::QMetaTypeInterface *d) : d_ptr(d) {}
0458 constexpr QMetaType() = default;
0459
0460 #if QT_CORE_REMOVED_SINCE(6, 9)
0461 bool isValid() const;
0462 bool isRegistered() const;
0463 #endif
0464 constexpr bool isValid(QT6_DECL_NEW_OVERLOAD) const noexcept;
0465 inline bool isRegistered(QT6_DECL_NEW_OVERLOAD) const noexcept;
0466 void registerType() const
0467 {
0468
0469 registerHelper();
0470 }
0471 #if QT_CORE_REMOVED_SINCE(6, 1) || defined(Q_QDOC)
0472 int id() const;
0473 #else
0474
0475
0476 int id(int = 0) const
0477 {
0478 return registerHelper();
0479 }
0480 #endif
0481 constexpr qsizetype sizeOf() const;
0482 constexpr qsizetype alignOf() const;
0483 constexpr TypeFlags flags() const;
0484 constexpr const QMetaObject *metaObject() const;
0485 constexpr const char *name() const;
0486
0487 void *create(const void *copy = nullptr) const;
0488 void destroy(void *data) const;
0489 void *construct(void *where, const void *copy = nullptr) const;
0490 void destruct(void *data) const;
0491 QPartialOrdering compare(const void *lhs, const void *rhs) const;
0492 bool equals(const void *lhs, const void *rhs) const;
0493
0494 bool isDefaultConstructible() const noexcept { return d_ptr && isDefaultConstructible(d_ptr); }
0495 bool isCopyConstructible() const noexcept { return d_ptr && isCopyConstructible(d_ptr); }
0496 bool isMoveConstructible() const noexcept { return d_ptr && isMoveConstructible(d_ptr); }
0497 bool isDestructible() const noexcept { return d_ptr && isDestructible(d_ptr); }
0498 bool isEqualityComparable() const;
0499 bool isOrdered() const;
0500
0501 #ifndef QT_NO_DATASTREAM
0502 bool save(QDataStream &stream, const void *data) const;
0503 bool load(QDataStream &stream, void *data) const;
0504 bool hasRegisteredDataStreamOperators() const;
0505
0506 #if QT_DEPRECATED_SINCE(6, 0)
0507 QT_DEPRECATED_VERSION_6_0
0508 static bool save(QDataStream &stream, int type, const void *data)
0509 { return QMetaType(type).save(stream, data); }
0510 QT_DEPRECATED_VERSION_6_0
0511 static bool load(QDataStream &stream, int type, void *data)
0512 { return QMetaType(type).load(stream, data); }
0513 #endif
0514 #endif
0515
0516 QMetaType underlyingType() const;
0517
0518 template<typename T>
0519 constexpr static QMetaType fromType();
0520 static QMetaType fromName(QByteArrayView name);
0521 private:
0522 friend bool comparesEqual(const QMetaType &lhs,
0523 const QMetaType &rhs)
0524 {
0525 if (lhs.d_ptr == rhs.d_ptr)
0526 return true;
0527 if (!lhs.d_ptr || !rhs.d_ptr)
0528 return false;
0529
0530 const int aId = lhs.id();
0531 const int bId = rhs.id();
0532 return aId == bId;
0533 }
0534 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QMetaType)
0535 #ifndef QT_NO_DEBUG_STREAM
0536 private:
0537 friend Q_CORE_EXPORT QDebug operator<<(QDebug d, QMetaType m);
0538 public:
0539 bool debugStream(QDebug& dbg, const void *rhs);
0540 bool hasRegisteredDebugStreamOperator() const;
0541
0542 #if QT_DEPRECATED_SINCE(6, 0)
0543 QT_DEPRECATED_VERSION_6_0
0544 static bool debugStream(QDebug& dbg, const void *rhs, int typeId)
0545 { return QMetaType(typeId).debugStream(dbg, rhs); }
0546 template<typename T>
0547 QT_DEPRECATED_VERSION_6_0
0548 static bool hasRegisteredDebugStreamOperator()
0549 { return QMetaType::fromType<T>().hasRegisteredDebugStreamOperator(); }
0550 QT_DEPRECATED_VERSION_6_0
0551 static bool hasRegisteredDebugStreamOperator(int typeId)
0552 { return QMetaType(typeId).hasRegisteredDebugStreamOperator(); }
0553 #endif
0554 #endif
0555
0556
0557 using ConverterFunction = std::function<bool(const void *src, void *target)>;
0558
0559
0560 using MutableViewFunction = std::function<bool(void *src, void *target)>;
0561
0562
0563 template<typename From, typename To>
0564 static bool registerConverter()
0565 {
0566 return registerConverter<From, To>(QtPrivate::convertImplicit<From, To>);
0567 }
0568
0569
0570 template<typename From, typename To>
0571 static bool registerConverter(To(From::*function)() const)
0572 {
0573 static_assert((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
0574 "QMetaType::registerConverter: At least one of the types must be a custom type.");
0575
0576 const QMetaType fromType = QMetaType::fromType<From>();
0577 const QMetaType toType = QMetaType::fromType<To>();
0578 auto converter = [function](const void *from, void *to) -> bool {
0579 const From *f = static_cast<const From *>(from);
0580 To *t = static_cast<To *>(to);
0581 *t = (f->*function)();
0582 return true;
0583 };
0584 return registerConverterImpl<From, To>(converter, fromType, toType);
0585 }
0586
0587
0588 template<typename From, typename To>
0589 static bool registerMutableView(To(From::*function)())
0590 {
0591 static_assert((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
0592 "QMetaType::registerMutableView: At least one of the types must be a custom type.");
0593
0594 const QMetaType fromType = QMetaType::fromType<From>();
0595 const QMetaType toType = QMetaType::fromType<To>();
0596 auto view = [function](void *from, void *to) -> bool {
0597 From *f = static_cast<From *>(from);
0598 To *t = static_cast<To *>(to);
0599 *t = (f->*function)();
0600 return true;
0601 };
0602 return registerMutableViewImpl<From, To>(view, fromType, toType);
0603 }
0604
0605
0606 template<typename From, typename To>
0607 static bool registerConverter(To(From::*function)(bool*) const)
0608 {
0609 static_assert((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
0610 "QMetaType::registerConverter: At least one of the types must be a custom type.");
0611
0612 const QMetaType fromType = QMetaType::fromType<From>();
0613 const QMetaType toType = QMetaType::fromType<To>();
0614 auto converter = [function](const void *from, void *to) -> bool {
0615 const From *f = static_cast<const From *>(from);
0616 To *t = static_cast<To *>(to);
0617 bool result = true;
0618 *t = (f->*function)(&result);
0619 if (!result)
0620 *t = To();
0621 return result;
0622 };
0623 return registerConverterImpl<From, To>(converter, fromType, toType);
0624 }
0625
0626
0627 template<typename From, typename To, typename UnaryFunction>
0628 static bool registerConverter(UnaryFunction function)
0629 {
0630 static_assert((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
0631 "QMetaType::registerConverter: At least one of the types must be a custom type.");
0632
0633 const QMetaType fromType = QMetaType::fromType<From>();
0634 const QMetaType toType = QMetaType::fromType<To>();
0635 auto converter = [function = std::move(function)](const void *from, void *to) -> bool {
0636 const From *f = static_cast<const From *>(from);
0637 To *t = static_cast<To *>(to);
0638 auto &&r = function(*f);
0639 if constexpr (std::is_same_v<q20::remove_cvref_t<decltype(r)>, std::optional<To>>) {
0640 if (!r)
0641 return false;
0642 *t = *std::forward<decltype(r)>(r);
0643 } else {
0644 *t = std::forward<decltype(r)>(r);
0645 }
0646 return true;
0647 };
0648 return registerConverterImpl<From, To>(std::move(converter), fromType, toType);
0649 }
0650
0651
0652 template<typename From, typename To, typename UnaryFunction>
0653 static bool registerMutableView(UnaryFunction function)
0654 {
0655 static_assert((!QMetaTypeId2<To>::IsBuiltIn || !QMetaTypeId2<From>::IsBuiltIn),
0656 "QMetaType::registerMutableView: At least one of the types must be a custom type.");
0657
0658 const QMetaType fromType = QMetaType::fromType<From>();
0659 const QMetaType toType = QMetaType::fromType<To>();
0660 auto view = [function = std::move(function)](void *from, void *to) -> bool {
0661 From *f = static_cast<From *>(from);
0662 To *t = static_cast<To *>(to);
0663 *t = function(*f);
0664 return true;
0665 };
0666 return registerMutableViewImpl<From, To>(std::move(view), fromType, toType);
0667 }
0668
0669 private:
0670 template<typename From, typename To>
0671 static bool registerConverterImpl(ConverterFunction converter, QMetaType fromType, QMetaType toType)
0672 {
0673 if (registerConverterFunction(std::move(converter), fromType, toType)) {
0674 static const auto unregister = qScopeGuard([=] {
0675 unregisterConverterFunction(fromType, toType);
0676 });
0677 return true;
0678 } else {
0679 return false;
0680 }
0681 }
0682
0683 template<typename From, typename To>
0684 static bool registerMutableViewImpl(MutableViewFunction view, QMetaType fromType, QMetaType toType)
0685 {
0686 if (registerMutableViewFunction(std::move(view), fromType, toType)) {
0687 static const auto unregister = qScopeGuard([=] {
0688 unregisterMutableViewFunction(fromType, toType);
0689 });
0690 return true;
0691 } else {
0692 return false;
0693 }
0694 }
0695 public:
0696
0697 static bool convert(QMetaType fromType, const void *from, QMetaType toType, void *to);
0698 static bool canConvert(QMetaType fromType, QMetaType toType);
0699
0700 static bool view(QMetaType fromType, void *from, QMetaType toType, void *to);
0701 static bool canView(QMetaType fromType, QMetaType toType);
0702 #if QT_DEPRECATED_SINCE(6, 0)
0703 QT_DEPRECATED_VERSION_6_0
0704 static bool convert(const void *from, int fromTypeId, void *to, int toTypeId)
0705 { return convert(QMetaType(fromTypeId), from, QMetaType(toTypeId), to); }
0706 QT_DEPRECATED_VERSION_6_0
0707 static bool compare(const void *lhs, const void *rhs, int typeId, int *result)
0708 {
0709 QMetaType t(typeId);
0710 auto c = t.compare(lhs, rhs);
0711 if (c == QPartialOrdering::Unordered) {
0712 *result = 0;
0713 return false;
0714 } else if (c == QPartialOrdering::Less) {
0715 *result = -1;
0716 return true;
0717 } else if (c == QPartialOrdering::Equivalent) {
0718 *result = 0;
0719 return true;
0720 } else {
0721 *result = 1;
0722 return true;
0723 }
0724 }
0725 QT_DEPRECATED_VERSION_6_0
0726 static bool equals(const void *lhs, const void *rhs, int typeId, int *result)
0727 {
0728 QMetaType t(typeId);
0729 if (!t.isEqualityComparable())
0730 return false;
0731 *result = t.equals(lhs, rhs) ? 0 : -1;
0732 return true;
0733 }
0734 #endif
0735
0736 template<typename From, typename To>
0737 static bool hasRegisteredConverterFunction()
0738 {
0739 return hasRegisteredConverterFunction(
0740 QMetaType::fromType<From>(), QMetaType::fromType<To>());
0741 }
0742
0743 static bool hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType);
0744
0745 template<typename From, typename To>
0746 static bool hasRegisteredMutableViewFunction()
0747 {
0748 return hasRegisteredMutableViewFunction(
0749 QMetaType::fromType<From>(), QMetaType::fromType<To>());
0750 }
0751
0752 static bool hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType);
0753
0754 #ifndef Q_QDOC
0755 template<typename, bool> friend struct QtPrivate::SequentialValueTypeIsMetaType;
0756 template<typename, bool> friend struct QtPrivate::AssociativeValueTypeIsMetaType;
0757 template<typename, bool> friend struct QtPrivate::IsMetaTypePair;
0758 template<typename, typename> friend struct QtPrivate::MetaTypeSmartPointerHelper;
0759 #endif
0760 static bool registerConverterFunction(const ConverterFunction &f, QMetaType from, QMetaType to);
0761 static void unregisterConverterFunction(QMetaType from, QMetaType to);
0762
0763 static bool registerMutableViewFunction(const MutableViewFunction &f, QMetaType from, QMetaType to);
0764 static void unregisterMutableViewFunction(QMetaType from, QMetaType to);
0765
0766 static void unregisterMetaType(QMetaType type);
0767
0768 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
0769 constexpr const QtPrivate::QMetaTypeInterface *iface() { return d_ptr; }
0770 #endif
0771 constexpr const QtPrivate::QMetaTypeInterface *iface() const { return d_ptr; }
0772
0773 private:
0774 static bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION;
0775 static bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION;
0776 static bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION;
0777 static bool isDestructible(const QtPrivate::QMetaTypeInterface *) noexcept Q_DECL_PURE_FUNCTION;
0778
0779 #if QT_CORE_REMOVED_SINCE(6, 5)
0780 int idHelper() const;
0781 #endif
0782 static int registerHelper(const QtPrivate::QMetaTypeInterface *iface);
0783 int registerHelper() const
0784 {
0785 if (d_ptr) {
0786 if (int id = d_ptr->typeId.loadRelaxed())
0787 return id;
0788 return registerHelper(d_ptr);
0789 }
0790 return 0;
0791 }
0792
0793 friend int qRegisterMetaType(QMetaType meta);
0794
0795 friend class QVariant;
0796 const QtPrivate::QMetaTypeInterface *d_ptr = nullptr;
0797 };
0798
0799 #undef QT_DEFINE_METATYPE_ID
0800
0801 Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags)
0802
0803 #define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F) \
0804 } \
0805 Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \
0806 namespace QtMetaTypePrivate {
0807
0808
0809 namespace QtMetaTypePrivate {
0810
0811 class QPairVariantInterfaceImpl
0812 {
0813 public:
0814 const void *_pair;
0815 QMetaType _metaType_first;
0816 QMetaType _metaType_second;
0817
0818 typedef void (*getFunc)(const void * const *p, void *);
0819
0820 getFunc _getFirst;
0821 getFunc _getSecond;
0822
0823 template<class T>
0824 static void getFirstImpl(const void * const *pair, void *dataPtr)
0825 { *static_cast<typename T::first_type *>(dataPtr) = static_cast<const T*>(*pair)->first; }
0826 template<class T>
0827 static void getSecondImpl(const void * const *pair, void *dataPtr)
0828 { *static_cast<typename T::second_type *>(dataPtr) = static_cast<const T*>(*pair)->second; }
0829
0830 public:
0831 template<class T> QPairVariantInterfaceImpl(const T*p)
0832 : _pair(p)
0833 , _metaType_first(QMetaType::fromType<typename T::first_type>())
0834 , _metaType_second(QMetaType::fromType<typename T::second_type>())
0835 , _getFirst(getFirstImpl<T>)
0836 , _getSecond(getSecondImpl<T>)
0837 {
0838 }
0839
0840 constexpr QPairVariantInterfaceImpl()
0841 : _pair(nullptr)
0842 , _getFirst(nullptr)
0843 , _getSecond(nullptr)
0844 {
0845 }
0846
0847 inline void first(void *dataPtr) const { _getFirst(&_pair, dataPtr); }
0848 inline void second(void *dataPtr) const { _getSecond(&_pair, dataPtr); }
0849 };
0850 QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QPairVariantInterfaceImpl, Q_RELOCATABLE_TYPE)
0851
0852 template<typename From>
0853 struct QPairVariantInterfaceConvertFunctor;
0854
0855 template<typename T, typename U>
0856 struct QPairVariantInterfaceConvertFunctor<std::pair<T, U> >
0857 {
0858 QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const
0859 {
0860 return QPairVariantInterfaceImpl(&f);
0861 }
0862 };
0863
0864 }
0865
0866 class QObject;
0867
0868 #define QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER(Name) \
0869 template <class T> class Name; \
0870
0871 QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(QT_FORWARD_DECLARE_SHARED_POINTER_TYPES_ITER)
0872
0873 namespace QtPrivate
0874 {
0875 namespace detail {
0876 template<typename T, typename ODR_VIOLATION_PREVENTER>
0877 struct is_complete_helper
0878 {
0879 template<typename U>
0880 static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
0881 static auto check(...) -> std::false_type;
0882 using type = decltype(check(static_cast<T *>(nullptr)));
0883 };
0884 }
0885
0886 template <typename T, typename ODR_VIOLATION_PREVENTER>
0887 struct is_complete : detail::is_complete_helper<std::remove_reference_t<T>, ODR_VIOLATION_PREVENTER>::type {};
0888
0889 template <typename T> struct MetatypeDecay { using type = T; };
0890 template <typename T> struct MetatypeDecay<const T> { using type = T; };
0891 template <typename T> struct MetatypeDecay<const T &> { using type = T; };
0892
0893 template <typename T> struct IsPointerDeclaredOpaque :
0894 std::disjunction<std::is_member_pointer<T>,
0895 std::is_function<std::remove_pointer_t<T>>>
0896 {};
0897 template <> struct IsPointerDeclaredOpaque<void *> : std::true_type {};
0898 template <> struct IsPointerDeclaredOpaque<const void *> : std::true_type {};
0899
0900
0901
0902
0903 template<typename T>
0904 struct IsPointerToTypeDerivedFromQObject
0905 {
0906 enum { Value = false };
0907 };
0908
0909
0910 template<>
0911 struct IsPointerToTypeDerivedFromQObject<void*>
0912 {
0913 enum { Value = false };
0914 };
0915 template<>
0916 struct IsPointerToTypeDerivedFromQObject<const void*>
0917 {
0918 enum { Value = false };
0919 };
0920 template<>
0921 struct IsPointerToTypeDerivedFromQObject<QObject*>
0922 {
0923 enum { Value = true };
0924 };
0925
0926 template<typename T>
0927 struct IsPointerToTypeDerivedFromQObject<T*>
0928 {
0929 typedef qint8 yes_type;
0930 typedef qint64 no_type;
0931
0932 #ifndef QT_NO_QOBJECT
0933 static yes_type checkType(QObject* );
0934 static yes_type checkType(const QObject* );
0935 #endif
0936 static no_type checkType(...);
0937 enum { Value = sizeof(checkType(static_cast<T*>(nullptr))) == sizeof(yes_type) };
0938 };
0939
0940 template<typename T, typename Enable = void>
0941 struct IsGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; };
0942
0943 template<typename T>
0944 struct IsGadgetHelper<T, typename T::QtGadgetHelper>
0945 {
0946 template <typename X>
0947 static char checkType(void (X::*)());
0948 static void *checkType(void (T::*)());
0949 enum {
0950 IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *),
0951 IsGadgetOrDerivedFrom = true
0952 };
0953 };
0954
0955 template <typename T>
0956 using IsRealGadget = std::bool_constant<IsGadgetHelper<T>::IsRealGadget>;
0957
0958 template<typename T, typename Enable = void>
0959 struct IsPointerToGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; };
0960
0961 template<typename T>
0962 struct IsPointerToGadgetHelper<T*, typename T::QtGadgetHelper>
0963 {
0964 using BaseType = T;
0965 template <typename X>
0966 static char checkType(void (X::*)());
0967 static void *checkType(void (T::*)());
0968 enum {
0969 IsRealGadget = !IsPointerToTypeDerivedFromQObject<T*>::Value && sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *),
0970 IsGadgetOrDerivedFrom = !IsPointerToTypeDerivedFromQObject<T*>::Value
0971 };
0972 };
0973
0974
0975 template<typename T> char qt_getEnumMetaObject(const T&);
0976
0977 template<typename T>
0978 struct IsQEnumHelper {
0979 static const T &declval();
0980
0981
0982
0983
0984 enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
0985 };
0986 template<> struct IsQEnumHelper<void> { enum { Value = false }; };
0987
0988 template<typename T, typename Enable = void>
0989 struct MetaObjectForType
0990 {
0991 static constexpr const QMetaObject *value() { return nullptr; }
0992 using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *);
0993 static constexpr MetaObjectFn metaObjectFunction = nullptr;
0994 };
0995 #ifndef QT_NO_QOBJECT
0996 template<typename T>
0997 struct MetaObjectForType<T*, typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value>::type>
0998 {
0999 static constexpr const QMetaObject *value() { return &T::staticMetaObject; }
1000 static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return &T::staticMetaObject; }
1001 };
1002 template<typename T>
1003 struct MetaObjectForType<T, std::enable_if_t<
1004 std::disjunction_v<
1005 std::bool_constant<IsGadgetHelper<T>::IsGadgetOrDerivedFrom>,
1006 std::is_base_of<QObject, T>
1007 >
1008 >>
1009 {
1010 static constexpr const QMetaObject *value() { return &T::staticMetaObject; }
1011 static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return &T::staticMetaObject; }
1012 };
1013 template<typename T>
1014 struct MetaObjectForType<T, typename std::enable_if<IsPointerToGadgetHelper<T>::IsGadgetOrDerivedFrom>::type>
1015 {
1016 static constexpr const QMetaObject *value()
1017 {
1018 return &IsPointerToGadgetHelper<T>::BaseType::staticMetaObject;
1019 }
1020 static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return value(); }
1021 };
1022 template<typename T>
1023 struct MetaObjectForType<T, typename std::enable_if<IsQEnumHelper<T>::Value>::type >
1024 {
1025 static constexpr const QMetaObject *value() { return qt_getEnumMetaObject(T()); }
1026 static constexpr const QMetaObject *metaObjectFunction(const QMetaTypeInterface *) { return value(); }
1027 };
1028 #endif
1029
1030 template<typename T>
1031 struct IsSharedPointerToTypeDerivedFromQObject
1032 {
1033 enum { Value = false };
1034 };
1035
1036 template<typename T>
1037 struct IsSharedPointerToTypeDerivedFromQObject<QSharedPointer<T> > : IsPointerToTypeDerivedFromQObject<T*>
1038 {
1039 };
1040
1041 template<typename T>
1042 struct IsWeakPointerToTypeDerivedFromQObject
1043 {
1044 enum { Value = false };
1045 };
1046
1047 template<typename T>
1048 struct IsWeakPointerToTypeDerivedFromQObject<QWeakPointer<T> > : IsPointerToTypeDerivedFromQObject<T*>
1049 {
1050 };
1051
1052 template<typename T>
1053 struct IsTrackingPointerToTypeDerivedFromQObject
1054 {
1055 enum { Value = false };
1056 };
1057
1058 template<typename T>
1059 struct IsTrackingPointerToTypeDerivedFromQObject<QPointer<T> >
1060 {
1061 enum { Value = true };
1062 };
1063
1064 template<typename T>
1065 struct IsSequentialContainer
1066 {
1067 enum { Value = false };
1068 };
1069
1070 template<typename T>
1071 struct IsAssociativeContainer
1072 {
1073 enum { Value = false };
1074 };
1075
1076 template<typename T, bool = QtPrivate::IsSequentialContainer<T>::Value>
1077 struct SequentialContainerTransformationHelper
1078 {
1079 static bool registerConverter()
1080 {
1081 return false;
1082 }
1083
1084 static bool registerMutableView()
1085 {
1086 return false;
1087 }
1088 };
1089
1090 template<typename T, bool = QMetaTypeId2<typename T::value_type>::Defined>
1091 struct SequentialValueTypeIsMetaType
1092 {
1093 static bool registerConverter()
1094 {
1095 return false;
1096 }
1097
1098 static bool registerMutableView()
1099 {
1100 return false;
1101 }
1102 };
1103
1104 template<typename T>
1105 struct SequentialContainerTransformationHelper<T, true> : SequentialValueTypeIsMetaType<T>
1106 {
1107 };
1108
1109 template<typename T, bool = QtPrivate::IsAssociativeContainer<T>::Value>
1110 struct AssociativeContainerTransformationHelper
1111 {
1112 static bool registerConverter()
1113 {
1114 return false;
1115 }
1116
1117 static bool registerMutableView()
1118 {
1119 return false;
1120 }
1121 };
1122
1123 template<typename T, bool = QMetaTypeId2<typename T::key_type>::Defined>
1124 struct AssociativeKeyTypeIsMetaType
1125 {
1126 static bool registerConverter()
1127 {
1128 return false;
1129 }
1130
1131 static bool registerMutableView()
1132 {
1133 return false;
1134 }
1135 };
1136
1137 template<typename T, bool = QMetaTypeId2<typename T::mapped_type>::Defined>
1138 struct AssociativeMappedTypeIsMetaType
1139 {
1140 static bool registerConverter()
1141 {
1142 return false;
1143 }
1144
1145 static bool registerMutableView()
1146 {
1147 return false;
1148 }
1149 };
1150
1151 template<typename T>
1152 struct AssociativeContainerTransformationHelper<T, true> : AssociativeKeyTypeIsMetaType<T>
1153 {
1154 };
1155
1156 template<typename T, bool = QMetaTypeId2<typename T::first_type>::Defined
1157 && QMetaTypeId2<typename T::second_type>::Defined>
1158 struct IsMetaTypePair
1159 {
1160 static bool registerConverter()
1161 {
1162 return false;
1163 }
1164 };
1165
1166 template<typename T>
1167 struct IsMetaTypePair<T, true>
1168 {
1169 inline static bool registerConverter();
1170 };
1171
1172 template<typename T>
1173 struct IsPair
1174 {
1175 static bool registerConverter()
1176 {
1177 return false;
1178 }
1179 };
1180 template<typename T, typename U>
1181 struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {};
1182
1183 template<typename T>
1184 struct MetaTypePairHelper : IsPair<T> {};
1185
1186 template<typename T, typename = void>
1187 struct MetaTypeSmartPointerHelper
1188 {
1189 static bool registerConverter() { return false; }
1190 };
1191
1192 #if QT_CONFIG(future)
1193 template<typename T>
1194 struct MetaTypeQFutureHelper
1195 {
1196 static bool registerConverter() { return false; }
1197 };
1198 #endif
1199
1200 template <typename X> static constexpr bool checkTypeIsSuitableForMetaType()
1201 {
1202 using T = typename MetatypeDecay<X>::type;
1203 static_assert(is_complete<T, void>::value || std::is_void_v<T>,
1204 "Meta Types must be fully defined");
1205 static_assert(!std::is_reference_v<T>,
1206 "Meta Types cannot be non-const references or rvalue references.");
1207 if constexpr (std::is_pointer_v<T> && !IsPointerDeclaredOpaque<T>::value) {
1208 using Pointed = std::remove_pointer_t<T>;
1209 static_assert(is_complete<Pointed, void>::value,
1210 "Pointer Meta Types must either point to fully-defined types "
1211 "or be declared with Q_DECLARE_OPAQUE_POINTER(T *)");
1212 }
1213 return true;
1214 }
1215
1216 Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
1217 }
1218
1219 template <typename T, int =
1220 QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject :
1221 QtPrivate::IsRealGadget<T>::value ? QMetaType::IsGadget :
1222 QtPrivate::IsPointerToGadgetHelper<T>::IsRealGadget ? QMetaType::PointerToGadget :
1223 QtPrivate::IsQEnumHelper<T>::Value ? QMetaType::IsEnumeration : 0>
1224 struct QMetaTypeIdQObject
1225 {
1226 enum {
1227 Defined = 0
1228 };
1229 };
1230
1231 template <typename T>
1232 struct QMetaTypeId : public QMetaTypeIdQObject<T>
1233 {
1234 };
1235
1236 template <typename T>
1237 struct QMetaTypeId2
1238 {
1239 using NameAsArrayType = void;
1240 enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
1241 static inline constexpr int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
1242 };
1243
1244 template <typename T>
1245 struct QMetaTypeId2<const T&> : QMetaTypeId2<T> {};
1246
1247 template <typename T>
1248 struct QMetaTypeId2<T&>
1249 {
1250 using NameAsArrayType = void;
1251 enum { Defined = false, IsBuiltIn = false };
1252 static inline constexpr int qt_metatype_id() { return 0; }
1253 };
1254
1255 namespace QtPrivate {
1256 template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
1257 struct QMetaTypeIdHelper {
1258 static inline constexpr int qt_metatype_id()
1259 { return QMetaTypeId2<T>::qt_metatype_id(); }
1260 };
1261 template <typename T> struct QMetaTypeIdHelper<T, false> {
1262 static inline constexpr int qt_metatype_id()
1263 { return -1; }
1264 };
1265
1266
1267 template <typename Result, typename... Args>
1268 struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
1269
1270 template<typename T>
1271 inline constexpr bool IsQmlListType = false;
1272
1273 template<typename T, bool = std::is_enum<T>::value>
1274 constexpr bool IsUnsignedEnum = false;
1275 template<typename T>
1276 constexpr bool IsUnsignedEnum<T, true> = !std::is_signed_v<std::underlying_type_t<T>>;
1277
1278 template<typename T, bool defined>
1279 struct MetaTypeDefinedHelper
1280 {
1281 enum DefinedType { Defined = defined };
1282 };
1283
1284 template<typename SmartPointer>
1285 struct QSmartPointerConvertFunctor
1286 {
1287 QObject* operator()(const SmartPointer &p) const
1288 {
1289 return p.operator->();
1290 }
1291 };
1292
1293
1294
1295 template <typename T>
1296 struct EnableInternalDataWrap;
1297
1298 template<typename T>
1299 struct QSmartPointerConvertFunctor<QWeakPointer<T> >
1300 {
1301 QObject* operator()(const QWeakPointer<T> &p) const
1302 {
1303 return QtPrivate::EnableInternalDataWrap<T>::internalData(p);
1304 }
1305 };
1306 }
1307
1308 template <typename T>
1309 int qRegisterNormalizedMetaTypeImplementation(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
1310 {
1311 #ifndef QT_NO_QOBJECT
1312 Q_ASSERT_X(normalizedTypeName == QMetaObject::normalizedType(normalizedTypeName.constData()),
1313 "qRegisterNormalizedMetaType",
1314 "qRegisterNormalizedMetaType was called with a not normalized type name, "
1315 "please call qRegisterMetaType instead.");
1316 #endif
1317
1318 const QMetaType metaType = QMetaType::fromType<T>();
1319 const int id = metaType.id();
1320
1321 QtPrivate::SequentialContainerTransformationHelper<T>::registerConverter();
1322 QtPrivate::SequentialContainerTransformationHelper<T>::registerMutableView();
1323 QtPrivate::AssociativeContainerTransformationHelper<T>::registerConverter();
1324 QtPrivate::AssociativeContainerTransformationHelper<T>::registerMutableView();
1325 QtPrivate::MetaTypePairHelper<T>::registerConverter();
1326 QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter();
1327 #if QT_CONFIG(future)
1328 QtPrivate::MetaTypeQFutureHelper<T>::registerConverter();
1329 #endif
1330
1331 if (normalizedTypeName != metaType.name())
1332 QMetaType::registerNormalizedTypedef(normalizedTypeName, metaType);
1333
1334 return id;
1335 }
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347 template <typename T>
1348 int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
1349 {
1350 return qRegisterNormalizedMetaTypeImplementation<T>(normalizedTypeName);
1351 }
1352
1353 #define QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TAG, EXPORT) \
1354 QT_BEGIN_NAMESPACE \
1355 EXPORT int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &); \
1356 template <> inline int qRegisterNormalizedMetaType< TYPE >(const QByteArray &name) \
1357 { return qRegisterNormalizedMetaType_ ## TAG (name); } \
1358 QT_END_NAMESPACE \
1359 Q_DECLARE_METATYPE(TYPE) \
1360
1361 #define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG) \
1362 int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &name) \
1363 { return qRegisterNormalizedMetaTypeImplementation< TYPE >(name); } \
1364
1365 #define QT_DECL_METATYPE_EXTERN(TYPE, EXPORT) \
1366 QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TYPE, EXPORT)
1367 #define QT_IMPL_METATYPE_EXTERN(TYPE) \
1368 QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TYPE)
1369
1370 template <typename T>
1371 int qRegisterMetaType(const char *typeName)
1372 {
1373 #ifdef QT_NO_QOBJECT
1374 QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName;
1375 #else
1376 QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
1377 #endif
1378 return qRegisterNormalizedMetaType<T>(normalizedTypeName);
1379 }
1380
1381 template <typename T>
1382 inline constexpr int qMetaTypeId()
1383 {
1384 if constexpr (bool(QMetaTypeId2<T>::IsBuiltIn)) {
1385
1386
1387
1388 return QMetaTypeId2<T>::MetaType;
1389 } else {
1390 return QMetaType::fromType<T>().id();
1391 }
1392 }
1393
1394 template <typename T>
1395 inline constexpr int qRegisterMetaType()
1396 {
1397 int id = qMetaTypeId<T>();
1398 return id;
1399 }
1400
1401 inline int qRegisterMetaType(QMetaType meta)
1402 {
1403 return meta.registerHelper();
1404 }
1405
1406 #ifndef QT_NO_QOBJECT
1407 template <typename T>
1408 struct QMetaTypeIdQObject<T*, QMetaType::PointerToQObject>
1409 {
1410 enum {
1411 Defined = 1
1412 };
1413
1414 static int qt_metatype_id()
1415 {
1416 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1417 if (const int id = metatype_id.loadAcquire())
1418 return id;
1419 const char *const cName = T::staticMetaObject.className();
1420 QByteArray typeName;
1421 typeName.reserve(strlen(cName) + 1);
1422 typeName.append(cName).append('*');
1423 const int newId = qRegisterNormalizedMetaType<T *>(typeName);
1424 metatype_id.storeRelease(newId);
1425 return newId;
1426 }
1427 };
1428
1429 template <typename T>
1430 struct QMetaTypeIdQObject<T, QMetaType::IsGadget>
1431 {
1432 enum {
1433 Defined = std::is_default_constructible<T>::value
1434 };
1435
1436 static int qt_metatype_id()
1437 {
1438 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1439 if (const int id = metatype_id.loadAcquire())
1440 return id;
1441 const char *const cName = T::staticMetaObject.className();
1442 const int newId = qRegisterNormalizedMetaType<T>(cName);
1443 metatype_id.storeRelease(newId);
1444 return newId;
1445 }
1446 };
1447
1448 template <typename T>
1449 struct QMetaTypeIdQObject<T*, QMetaType::PointerToGadget>
1450 {
1451 enum {
1452 Defined = 1
1453 };
1454
1455 static int qt_metatype_id()
1456 {
1457 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1458 if (const int id = metatype_id.loadAcquire())
1459 return id;
1460 const char *const cName = T::staticMetaObject.className();
1461 QByteArray typeName;
1462 typeName.reserve(strlen(cName) + 1);
1463 typeName.append(cName).append('*');
1464 const int newId = qRegisterNormalizedMetaType<T *>(typeName);
1465 metatype_id.storeRelease(newId);
1466 return newId;
1467 }
1468 };
1469
1470 template <typename T>
1471 struct QMetaTypeIdQObject<T, QMetaType::IsEnumeration>
1472 {
1473 enum {
1474 Defined = 1
1475 };
1476
1477 static int qt_metatype_id()
1478 {
1479 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
1480 if (const int id = metatype_id.loadAcquire())
1481 return id;
1482 const char *eName = qt_getEnumName(T());
1483 const char *cName = qt_getEnumMetaObject(T())->className();
1484 QByteArray typeName;
1485 typeName.reserve(strlen(cName) + 2 + strlen(eName));
1486 typeName.append(cName).append("::").append(eName);
1487 const int newId = qRegisterNormalizedMetaType<T>(typeName);
1488 metatype_id.storeRelease(newId);
1489 return newId;
1490 }
1491 };
1492 #endif
1493
1494 #define Q_DECLARE_OPAQUE_POINTER(POINTER) \
1495 QT_BEGIN_NAMESPACE namespace QtPrivate { \
1496 template <> struct IsPointerDeclaredOpaque<POINTER> \
1497 : std::true_type {}; \
1498 } QT_END_NAMESPACE \
1499
1500
1501 #ifndef Q_MOC_RUN
1502 #define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
1503 #define Q_DECLARE_METATYPE_IMPL(TYPE) \
1504 QT_BEGIN_NAMESPACE \
1505 template <> \
1506 struct QMetaTypeId< TYPE > \
1507 { \
1508 enum { Defined = 1 }; \
1509 static_assert(QtPrivate::checkTypeIsSuitableForMetaType<TYPE>()); \
1510 static int qt_metatype_id() \
1511 { \
1512 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1513 if (const int id = metatype_id.loadAcquire()) \
1514 return id; \
1515 constexpr auto arr = QtPrivate::typenameHelper<TYPE>(); \
1516 auto name = arr.data(); \
1517 if (QByteArrayView(name) == (#TYPE)) { \
1518 const int id = qRegisterNormalizedMetaType<TYPE>(name); \
1519 metatype_id.storeRelease(id); \
1520 return id; \
1521 } \
1522 const int newId = qRegisterMetaType< TYPE >(#TYPE); \
1523 metatype_id.storeRelease(newId); \
1524 return newId; \
1525 } \
1526 }; \
1527 QT_END_NAMESPACE
1528 #endif
1529
1530 #define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME) \
1531 QT_BEGIN_NAMESPACE \
1532 template<> struct QMetaTypeId2<NAME> \
1533 { \
1534 using NameAsArrayType = std::array<char, sizeof(#NAME)>; \
1535 enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID }; \
1536 static inline constexpr int qt_metatype_id() { return METATYPEID; } \
1537 static constexpr NameAsArrayType nameAsArray = { #NAME }; \
1538 }; \
1539 QT_END_NAMESPACE
1540
1541 #define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
1542 class Name;
1543
1544 QT_FOR_EACH_STATIC_CORE_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
1545 QT_FOR_EACH_STATIC_GUI_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
1546 QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
1547
1548 #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
1549
1550 #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
1551 QT_BEGIN_NAMESPACE \
1552 template <typename T> \
1553 struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
1554 { \
1555 enum { \
1556 Defined = QMetaTypeId2<T>::Defined \
1557 }; \
1558 static int qt_metatype_id() \
1559 { \
1560 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1561 if (const int id = metatype_id.loadRelaxed()) \
1562 return id; \
1563 const char *tName = QMetaType::fromType<T>().name(); \
1564 Q_ASSERT(tName); \
1565 const size_t tNameLen = qstrlen(tName); \
1566 QByteArray typeName; \
1567 typeName.reserve(sizeof(#SINGLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + 1); \
1568 typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \
1569 .append('<').append(tName, tNameLen); \
1570 typeName.append('>'); \
1571 const int newId = qRegisterNormalizedMetaType< SINGLE_ARG_TEMPLATE<T> >(typeName); \
1572 metatype_id.storeRelease(newId); \
1573 return newId; \
1574 } \
1575 }; \
1576 QT_END_NAMESPACE
1577
1578 #define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
1579 QT_BEGIN_NAMESPACE \
1580 template<typename T, typename U> \
1581 struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
1582 { \
1583 enum { \
1584 Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \
1585 }; \
1586 static int qt_metatype_id() \
1587 { \
1588 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1589 if (const int id = metatype_id.loadAcquire()) \
1590 return id; \
1591 const char *tName = QMetaType::fromType<T>().name(); \
1592 const char *uName = QMetaType::fromType<U>().name(); \
1593 Q_ASSERT(tName); \
1594 Q_ASSERT(uName); \
1595 const size_t tNameLen = qstrlen(tName); \
1596 const size_t uNameLen = qstrlen(uName); \
1597 QByteArray typeName; \
1598 typeName.reserve(sizeof(#DOUBLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
1599 typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \
1600 .append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \
1601 typeName.append('>'); \
1602 const int newId = qRegisterNormalizedMetaType< DOUBLE_ARG_TEMPLATE<T, U> >(typeName); \
1603 metatype_id.storeRelease(newId); \
1604 return newId; \
1605 } \
1606 }; \
1607 QT_END_NAMESPACE
1608
1609 namespace QtPrivate {
1610
1611 template<typename T, bool = false>
1612 struct SharedPointerMetaTypeIdHelper
1613 {
1614 enum {
1615 Defined = 0
1616 };
1617 static int qt_metatype_id()
1618 {
1619 return -1;
1620 }
1621 };
1622
1623 }
1624
1625 #define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
1626 QT_BEGIN_NAMESPACE \
1627 namespace QtPrivate { \
1628 template<typename T> \
1629 struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
1630 { \
1631 enum { \
1632 Defined = 1 \
1633 }; \
1634 static int qt_metatype_id() \
1635 { \
1636 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1637 if (const int id = metatype_id.loadAcquire()) \
1638 return id; \
1639 const char * const cName = T::staticMetaObject.className(); \
1640 QByteArray typeName; \
1641 typeName.reserve(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1); \
1642 typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \
1643 .append('<').append(cName).append('>'); \
1644 const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >(typeName); \
1645 metatype_id.storeRelease(newId); \
1646 return newId; \
1647 } \
1648 }; \
1649 template<typename T> \
1650 struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
1651 typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value && !std::is_const_v<T>>::type> \
1652 { \
1653 static bool registerConverter() \
1654 { \
1655 const QMetaType to = QMetaType(QMetaType::QObjectStar); \
1656 if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<SMART_POINTER<T>>(), to)) { \
1657 QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
1658 return QMetaType::registerConverter<SMART_POINTER<T>, QObject*>(o); \
1659 } \
1660 return true; \
1661 } \
1662 }; \
1663 } \
1664 template <typename T> \
1665 struct QMetaTypeId< SMART_POINTER<T> > \
1666 : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
1667 QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
1668 { \
1669 };\
1670 QT_END_NAMESPACE
1671
1672 #define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(SINGLE_ARG_TEMPLATE) \
1673 QT_BEGIN_NAMESPACE \
1674 namespace QtPrivate { \
1675 template<typename T> \
1676 struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \
1677 { \
1678 enum { Value = true }; \
1679 }; \
1680 } \
1681 QT_END_NAMESPACE \
1682 Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE)
1683
1684 #define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \
1685 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(TEMPLATENAME)
1686
1687 QT_END_NAMESPACE
1688
1689 QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER)
1690
1691 #undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER
1692
1693 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector)
1694 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::list)
1695
1696 #define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \
1697 QT_BEGIN_NAMESPACE \
1698 namespace QtPrivate { \
1699 template<typename T, typename U> \
1700 struct IsAssociativeContainer<TEMPLATENAME<T, U> > \
1701 { \
1702 enum { Value = true }; \
1703 }; \
1704 } \
1705 QT_END_NAMESPACE \
1706 Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
1707
1708 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash)
1709 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap)
1710 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map)
1711
1712 Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair)
1713
1714 #define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
1715 Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
1716
1717 QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER)
1718
1719 QT_BEGIN_NAMESPACE
1720
1721 #undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
1722
1723 QT_END_NAMESPACE
1724
1725 QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
1726
1727
1728 QT_BEGIN_NAMESPACE
1729
1730 namespace QtPrivate {
1731
1732 Q_CORE_EXPORT bool hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m);
1733 Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m);
1734 Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m);
1735 Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m);
1736 Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m);
1737 }
1738
1739 template <typename T>
1740 inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter()
1741 {
1742 if (!QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType::fromType<T>())) {
1743 QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
1744 return QMetaType::registerConverter<T, QtMetaTypePrivate::QPairVariantInterfaceImpl>(o);
1745 }
1746 return true;
1747 }
1748
1749 namespace QtPrivate {
1750
1751 template<typename From>
1752 struct QSequentialIterableConvertFunctor
1753 {
1754 QIterable<QMetaSequence> operator()(const From &f) const
1755 {
1756 return QIterable<QMetaSequence>(QMetaSequence::fromContainer<From>(), &f);
1757 }
1758 };
1759
1760 template<typename From>
1761 struct QSequentialIterableMutableViewFunctor
1762 {
1763 QIterable<QMetaSequence> operator()(From &f) const
1764 {
1765 return QIterable<QMetaSequence>(QMetaSequence::fromContainer<From>(), &f);
1766 }
1767 };
1768
1769 template<typename T>
1770 struct SequentialValueTypeIsMetaType<T, true>
1771 {
1772 static bool registerConverter()
1773 {
1774 if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
1775 QSequentialIterableConvertFunctor<T> o;
1776 return QMetaType::registerConverter<T, QIterable<QMetaSequence>>(o);
1777 }
1778 return true;
1779 }
1780
1781 static bool registerMutableView()
1782 {
1783 if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
1784 QSequentialIterableMutableViewFunctor<T> o;
1785 return QMetaType::registerMutableView<T, QIterable<QMetaSequence>>(o);
1786 }
1787 return true;
1788 }
1789 };
1790
1791 template<typename From>
1792 struct QAssociativeIterableConvertFunctor
1793 {
1794 QIterable<QMetaAssociation> operator()(const From &f) const
1795 {
1796 return QIterable<QMetaAssociation>(QMetaAssociation::fromContainer<From>(), &f);
1797 }
1798 };
1799
1800 template<typename From>
1801 struct QAssociativeIterableMutableViewFunctor
1802 {
1803 QIterable<QMetaAssociation> operator()(From &f) const
1804 {
1805 return QIterable<QMetaAssociation>(QMetaAssociation::fromContainer<From>(), &f);
1806 }
1807 };
1808
1809
1810
1811 template<typename T>
1812 struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T>
1813 {
1814 static bool registerConverter()
1815 {
1816 if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
1817 QAssociativeIterableConvertFunctor<T> o;
1818 return QMetaType::registerConverter<T, QIterable<QMetaAssociation>>(o);
1819 }
1820 return true;
1821 }
1822
1823 static bool registerMutableView()
1824 {
1825 if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
1826 QAssociativeIterableMutableViewFunctor<T> o;
1827 return QMetaType::registerMutableView<T, QIterable<QMetaAssociation>>(o);
1828 }
1829 return true;
1830 }
1831 };
1832
1833 struct QTypeNormalizer
1834 {
1835 char *output;
1836 int len = 0;
1837 char last = 0;
1838
1839 private:
1840 static constexpr bool is_ident_char(char s)
1841 {
1842 return ((s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || (s >= '0' && s <= '9')
1843 || s == '_');
1844 }
1845 static constexpr bool is_space(char s) { return (s == ' ' || s == '\t' || s == '\n'); }
1846 static constexpr bool is_number(char s) { return s >= '0' && s <= '9'; }
1847 static constexpr bool starts_with_token(const char *b, const char *e, const char *token,
1848 bool msvcKw = false)
1849 {
1850 while (b != e && *token && *b == *token) {
1851 b++;
1852 token++;
1853 }
1854 if (*token)
1855 return false;
1856 #ifdef Q_CC_MSVC
1857
1858
1859 if (msvcKw && !is_ident_char(*b))
1860 return true;
1861 #endif
1862 Q_UNUSED(msvcKw);
1863 return b == e || !is_ident_char(*b);
1864 }
1865 static constexpr bool skipToken(const char *&x, const char *e, const char *token,
1866 bool msvcKw = false)
1867 {
1868 if (!starts_with_token(x, e, token, msvcKw))
1869 return false;
1870 while (*token++)
1871 x++;
1872 while (x != e && is_space(*x))
1873 x++;
1874 return true;
1875 }
1876 static constexpr const char *skipString(const char *x, const char *e)
1877 {
1878 char delim = *x;
1879 x++;
1880 while (x != e && *x != delim) {
1881 if (*x == '\\') {
1882 x++;
1883 if (x == e)
1884 return e;
1885 }
1886 x++;
1887 }
1888 if (x != e)
1889 x++;
1890 return x;
1891 }
1892 static constexpr const char *skipTemplate(const char *x, const char *e, bool stopAtComa = false)
1893 {
1894 int scopeDepth = 0;
1895 int templateDepth = 0;
1896 while (x != e) {
1897 switch (*x) {
1898 case '<':
1899 if (!scopeDepth)
1900 templateDepth++;
1901 break;
1902 case ',':
1903 if (stopAtComa && !scopeDepth && !templateDepth)
1904 return x;
1905 break;
1906 case '>':
1907 if (!scopeDepth)
1908 if (--templateDepth < 0)
1909 return x;
1910 break;
1911 case '(':
1912 case '[':
1913 case '{':
1914 scopeDepth++;
1915 break;
1916 case '}':
1917 case ']':
1918 case ')':
1919 scopeDepth--;
1920 break;
1921 case '\'':
1922 if (is_number(x[-1]))
1923 break;
1924 Q_FALLTHROUGH();
1925 case '\"':
1926 x = skipString(x, e);
1927 continue;
1928 }
1929 x++;
1930 }
1931 return x;
1932 }
1933
1934 constexpr void append(char x)
1935 {
1936 last = x;
1937 len++;
1938 if (output)
1939 *output++ = x;
1940 }
1941
1942 constexpr void replaceLast(char x)
1943 {
1944 last = x;
1945 if (output)
1946 *(output - 1) = x;
1947 }
1948
1949 constexpr void appendStr(const char *x)
1950 {
1951 while (*x)
1952 append(*x++);
1953 }
1954
1955 constexpr void normalizeIntegerTypes(const char *&begin, const char *end)
1956 {
1957 int numLong = 0;
1958 int numSigned = 0;
1959 int numUnsigned = 0;
1960 int numInt = 0;
1961 int numShort = 0;
1962 int numChar = 0;
1963 while (begin < end) {
1964 if (skipToken(begin, end, "long")) {
1965 numLong++;
1966 continue;
1967 }
1968 if (skipToken(begin, end, "int")) {
1969 numInt++;
1970 continue;
1971 }
1972 if (skipToken(begin, end, "short")) {
1973 numShort++;
1974 continue;
1975 }
1976 if (skipToken(begin, end, "unsigned")) {
1977 numUnsigned++;
1978 continue;
1979 }
1980 if (skipToken(begin, end, "signed")) {
1981 numSigned++;
1982 continue;
1983 }
1984 if (skipToken(begin, end, "char")) {
1985 numChar++;
1986 continue;
1987 }
1988 #ifdef Q_CC_MSVC
1989 if (skipToken(begin, end, "__int64")) {
1990 numLong = 2;
1991 continue;
1992 }
1993 #endif
1994 break;
1995 }
1996 if (numLong == 2)
1997 append('q');
1998 if (numSigned && numChar)
1999 appendStr("signed ");
2000 else if (numUnsigned)
2001 appendStr("u");
2002 if (numChar)
2003 appendStr("char");
2004 else if (numShort)
2005 appendStr("short");
2006 else if (numLong == 1)
2007 appendStr("long");
2008 else if (numLong == 2)
2009 appendStr("longlong");
2010 else if (numUnsigned || numSigned || numInt)
2011 appendStr("int");
2012 }
2013
2014 constexpr void skipStructClassOrEnum(const char *&begin, const char *end)
2015 {
2016
2017
2018 skipToken(begin, end, "struct", true) || skipToken(begin, end, "class", true)
2019 || skipToken(begin, end, "enum", true);
2020 }
2021
2022 constexpr void skipQtNamespace(const char *&begin, const char *end)
2023 {
2024 #ifdef QT_NAMESPACE
2025 const char *nsbeg = begin;
2026 if (skipToken(nsbeg, end, QT_STRINGIFY(QT_NAMESPACE)) && nsbeg + 2 < end && nsbeg[0] == ':'
2027 && nsbeg[1] == ':') {
2028 begin = nsbeg + 2;
2029 while (begin != end && is_space(*begin))
2030 begin++;
2031 }
2032 #else
2033 Q_UNUSED(begin);
2034 Q_UNUSED(end);
2035 #endif
2036 }
2037
2038 public:
2039 #if defined(Q_CC_CLANG) || defined (Q_CC_GNU)
2040
2041
2042
2043 constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
2044 {
2045
2046 std::string_view name(begin, end-begin);
2047 #if defined (Q_CC_CLANG)
2048 if (name.find("anonymous ") != std::string_view::npos)
2049 return normalizeType(begin, end);
2050 #endif
2051 if (name.find("unnamed ") != std::string_view::npos)
2052 return normalizeType(begin, end);
2053 while (begin < end) {
2054 if (*begin == ' ') {
2055 if (last == ',' || last == '>' || last == '<' || last == '*' || last == '&') {
2056 ++begin;
2057 continue;
2058 }
2059 }
2060 if (last == ' ') {
2061 if (*begin == '*' || *begin == '&' || *begin == '(') {
2062 replaceLast(*begin);
2063 ++begin;
2064 continue;
2065 }
2066 }
2067 if (!is_ident_char(last)) {
2068 skipStructClassOrEnum(begin, end);
2069 if (begin == end)
2070 break;
2071
2072 skipQtNamespace(begin, end);
2073 if (begin == end)
2074 break;
2075
2076 normalizeIntegerTypes(begin, end);
2077 if (begin == end)
2078 break;
2079 }
2080 append(*begin);
2081 ++begin;
2082 }
2083 return len;
2084 }
2085 #else
2086
2087
2088 constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
2089 { return normalizeType(begin, end); }
2090 #endif
2091
2092 constexpr int normalizeType(const char *begin, const char *end, bool adjustConst = true)
2093 {
2094
2095 while (begin != end && is_space(*begin))
2096 begin++;
2097 while (begin != end && is_space(*(end - 1)))
2098 end--;
2099
2100
2101
2102 const char *cst = begin + 1;
2103 if (*begin == '\'' || *begin == '"')
2104 cst = skipString(begin, end);
2105 bool seenStar = false;
2106 bool hasMiddleConst = false;
2107 while (cst < end) {
2108 if (*cst == '\"' || (*cst == '\'' && !is_number(cst[-1]))) {
2109 cst = skipString(cst, end);
2110 if (cst == end)
2111 break;
2112 }
2113
2114
2115
2116 if (*cst == '&' || *cst == '*' || *cst == '[') {
2117 seenStar = *cst != '&' || cst != (end - 1);
2118 break;
2119 }
2120 if (*cst == '<') {
2121 cst = skipTemplate(cst + 1, end);
2122 if (cst == end)
2123 break;
2124 }
2125 cst++;
2126 const char *skipedCst = cst;
2127 if (!is_ident_char(*(cst - 1)) && skipToken(skipedCst, end, "const")) {
2128 const char *testEnd = end;
2129 while (skipedCst < testEnd--) {
2130 if (*testEnd == '*' || *testEnd == '['
2131 || (*testEnd == '&' && testEnd != (end - 1))) {
2132 seenStar = true;
2133 break;
2134 }
2135 if (*testEnd == '>')
2136 break;
2137 }
2138 if (adjustConst && !seenStar) {
2139 if (*(end - 1) == '&')
2140 end--;
2141 } else {
2142 appendStr("const ");
2143 }
2144 normalizeType(begin, cst, false);
2145 begin = skipedCst;
2146 hasMiddleConst = true;
2147 break;
2148 }
2149 }
2150 if (skipToken(begin, end, "const")) {
2151 if (adjustConst && !seenStar) {
2152 if (*(end - 1) == '&')
2153 end--;
2154 } else {
2155 appendStr("const ");
2156 }
2157 }
2158 if (seenStar && adjustConst) {
2159 const char *e = end;
2160 if (*(end - 1) == '&' && *(end - 2) != '&')
2161 e--;
2162 while (begin != e && is_space(*(e - 1)))
2163 e--;
2164 const char *token = "tsnoc";
2165 while (*token && begin != e && *(--e) == *token++)
2166 ;
2167 if (!*token && begin != e && !is_ident_char(*(e - 1))) {
2168 while (begin != e && is_space(*(e - 1)))
2169 e--;
2170 end = e;
2171 }
2172 }
2173
2174 skipStructClassOrEnum(begin, end);
2175 skipQtNamespace(begin, end);
2176
2177 if (skipToken(begin, end, "QVector")) {
2178
2179 appendStr("QList");
2180 }
2181
2182 if (skipToken(begin, end, "QPair")) {
2183
2184 appendStr("std::pair");
2185 }
2186
2187 if (!hasMiddleConst)
2188
2189 normalizeIntegerTypes(begin, end);
2190
2191 bool spaceSkiped = true;
2192 while (begin != end) {
2193 char c = *begin++;
2194 if (is_space(c)) {
2195 spaceSkiped = true;
2196 } else if ((c == '\'' && !is_number(last)) || c == '\"') {
2197 begin--;
2198 auto x = skipString(begin, end);
2199 while (begin < x)
2200 append(*begin++);
2201 } else {
2202 if (spaceSkiped && is_ident_char(last) && is_ident_char(c))
2203 append(' ');
2204 append(c);
2205 spaceSkiped = false;
2206 if (c == '<') {
2207 do {
2208
2209 const char *tpl = skipTemplate(begin, end, true);
2210 normalizeType(begin, tpl, false);
2211 if (tpl == end)
2212 return len;
2213 append(*tpl);
2214 begin = tpl;
2215 } while (*begin++ == ',');
2216 }
2217 }
2218 }
2219 return len;
2220 }
2221 };
2222
2223
2224
2225
2226 constexpr int qNormalizeType(const char *begin, const char *end, char *output)
2227 {
2228 return QTypeNormalizer { output }.normalizeType(begin, end);
2229 }
2230
2231 template<typename T>
2232 struct is_std_pair : std::false_type {};
2233
2234 template <typename T1_, typename T2_>
2235 struct is_std_pair<std::pair<T1_, T2_>> : std::true_type {
2236 using T1 = T1_;
2237 using T2 = T2_;
2238 };
2239
2240 namespace TypeNameHelper {
2241 template<typename T>
2242 constexpr auto typenameHelper()
2243 {
2244 if constexpr (is_std_pair<T>::value) {
2245 using T1 = typename is_std_pair<T>::T1;
2246 using T2 = typename is_std_pair<T>::T2;
2247 std::remove_const_t<std::conditional_t<bool (QMetaTypeId2<T1>::IsBuiltIn), typename QMetaTypeId2<T1>::NameAsArrayType, decltype(typenameHelper<T1>())>> t1Name {};
2248 std::remove_const_t<std::conditional_t<bool (QMetaTypeId2<T2>::IsBuiltIn), typename QMetaTypeId2<T2>::NameAsArrayType, decltype(typenameHelper<T2>())>> t2Name {};
2249 if constexpr (bool (QMetaTypeId2<T1>::IsBuiltIn) ) {
2250 t1Name = QMetaTypeId2<T1>::nameAsArray;
2251 } else {
2252 t1Name = typenameHelper<T1>();
2253 }
2254 if constexpr (bool(QMetaTypeId2<T2>::IsBuiltIn)) {
2255 t2Name = QMetaTypeId2<T2>::nameAsArray;
2256 } else {
2257 t2Name = typenameHelper<T2>();
2258 }
2259 constexpr auto nonTypeDependentLen = sizeof("std::pair<,>");
2260 constexpr auto t1Len = t1Name.size() - 1;
2261 constexpr auto t2Len = t2Name.size() - 1;
2262 constexpr auto length = nonTypeDependentLen + t1Len + t2Len;
2263 std::array<char, length + 1> result {};
2264 constexpr auto prefix = "std::pair<";
2265 int currentLength = 0;
2266 for (; currentLength < int(sizeof("std::pair<") - 1); ++currentLength)
2267 result[currentLength] = prefix[currentLength];
2268 for (int i = 0; i < int(t1Len); ++currentLength, ++i)
2269 result[currentLength] = t1Name[i];
2270 result[currentLength++] = ',';
2271 for (int i = 0; i < int(t2Len); ++currentLength, ++i)
2272 result[currentLength] = t2Name[i];
2273 result[currentLength++] = '>';
2274 result[currentLength++] = '\0';
2275 return result;
2276 } else {
2277 constexpr auto prefix = sizeof(
2278 #ifdef QT_NAMESPACE
2279 QT_STRINGIFY(QT_NAMESPACE) "::"
2280 #endif
2281 #if defined(Q_CC_MSVC) && defined(Q_CC_CLANG)
2282 "auto __cdecl QtPrivate::TypeNameHelper::typenameHelper(void) [T = "
2283 #elif defined(Q_CC_MSVC)
2284 "auto __cdecl QtPrivate::TypeNameHelper::typenameHelper<"
2285 #elif defined(Q_CC_CLANG)
2286 "auto QtPrivate::TypeNameHelper::typenameHelper() [T = "
2287 #elif defined(Q_CC_GHS)
2288 "auto QtPrivate::TypeNameHelper::typenameHelper<T>()[with T="
2289 #else
2290 "constexpr auto QtPrivate::TypeNameHelper::typenameHelper() [with T = "
2291 #endif
2292 ) - 1;
2293 #if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
2294 constexpr int suffix = sizeof(">(void)");
2295 #else
2296 constexpr int suffix = sizeof("]");
2297 #endif
2298
2299 #if defined(Q_CC_GNU_ONLY) && Q_CC_GNU_ONLY < 804
2300 auto func = Q_FUNC_INFO;
2301 const char *begin = func + prefix;
2302 const char *end = func + sizeof(Q_FUNC_INFO) - suffix;
2303
2304 constexpr int len = sizeof(Q_FUNC_INFO) - suffix - prefix;
2305 #else
2306 constexpr auto func = Q_FUNC_INFO;
2307 constexpr const char *begin = func + prefix;
2308 constexpr const char *end = func + sizeof(Q_FUNC_INFO) - suffix;
2309 constexpr int len = QTypeNormalizer{ nullptr }.normalizeTypeFromSignature(begin, end);
2310 #endif
2311 std::array<char, len + 1> result {};
2312 QTypeNormalizer{ result.data() }.normalizeTypeFromSignature(begin, end);
2313 return result;
2314 }
2315 }
2316 }
2317 using TypeNameHelper::typenameHelper;
2318
2319 template<typename T, typename = void>
2320 struct BuiltinMetaType : std::integral_constant<int, 0>
2321 {
2322 };
2323 template<typename T>
2324 struct BuiltinMetaType<T, std::enable_if_t<QMetaTypeId2<T>::IsBuiltIn>>
2325 : std::integral_constant<int, QMetaTypeId2<T>::MetaType>
2326 {
2327 };
2328
2329 template<typename T, bool = (QTypeTraits::has_operator_equal_v<T> && !std::is_pointer_v<T>)>
2330 struct QEqualityOperatorForType
2331 {
2332 QT_WARNING_PUSH
2333 QT_WARNING_DISABLE_FLOAT_COMPARE
2334 static bool equals(const QMetaTypeInterface *, const void *a, const void *b)
2335 { return *reinterpret_cast<const T *>(a) == *reinterpret_cast<const T *>(b); }
2336 QT_WARNING_POP
2337 };
2338
2339 template<typename T>
2340 struct QEqualityOperatorForType <T, false>
2341 {
2342 static constexpr QMetaTypeInterface::EqualsFn equals = nullptr;
2343 };
2344
2345 template<typename T, bool = (QTypeTraits::has_operator_less_than_v<T> && !std::is_pointer_v<T>)>
2346 struct QLessThanOperatorForType
2347 {
2348 static bool lessThan(const QMetaTypeInterface *, const void *a, const void *b)
2349 { return *reinterpret_cast<const T *>(a) < *reinterpret_cast<const T *>(b); }
2350 };
2351
2352 template<typename T>
2353 struct QLessThanOperatorForType <T, false>
2354 {
2355 static constexpr QMetaTypeInterface::LessThanFn lessThan = nullptr;
2356 };
2357
2358 template<typename T, bool = (QTypeTraits::has_ostream_operator_v<QDebug, T> && !std::is_pointer_v<T>)>
2359 struct QDebugStreamOperatorForType
2360 {
2361 static void debugStream(const QMetaTypeInterface *, QDebug &dbg, const void *a)
2362 { dbg << *reinterpret_cast<const T *>(a); }
2363 };
2364
2365 template<typename T>
2366 struct QDebugStreamOperatorForType <T, false>
2367 {
2368 static constexpr QMetaTypeInterface::DebugStreamFn debugStream = nullptr;
2369 };
2370
2371 template<typename T, bool = QTypeTraits::has_stream_operator_v<QDataStream, T>>
2372 struct QDataStreamOperatorForType
2373 {
2374 static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr;
2375 static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
2376 };
2377
2378 #ifndef QT_NO_DATASTREAM
2379 template<typename T>
2380 struct QDataStreamOperatorForType <T, true>
2381 {
2382 static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a)
2383 { ds << *reinterpret_cast<const T *>(a); }
2384 static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a)
2385 { ds >> *reinterpret_cast<T *>(a); }
2386 };
2387 #endif
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399 #if !defined(Q_OS_WIN) && defined(Q_CC_CLANG)
2400 # pragma GCC visibility push(hidden)
2401 #endif
2402
2403
2404
2405 namespace QMetaTypeCopyTraits
2406 {
2407
2408
2409 template <typename T>
2410 using HasDeprecatedCopyConstructorTest = typename T::_q_hasDeprecatedCopyConstructor;
2411
2412 #if !defined(QT_BOOTSTRAPPED)
2413 Q_CORE_EXPORT void warnAboutDeprecatedCopy(const char *name);
2414 #endif
2415 }
2416
2417 template<typename S>
2418 class QMetaTypeForType
2419 {
2420 public:
2421 static constexpr decltype(typenameHelper<S>()) name = typenameHelper<S>();
2422
2423 static constexpr unsigned flags()
2424 {
2425 uint flags = 0;
2426 if constexpr (QTypeInfo<S>::isRelocatable)
2427 flags |= QMetaType::RelocatableType;
2428 if constexpr (!std::is_default_constructible_v<S> || !QTypeInfo<S>::isValueInitializationBitwiseZero)
2429 flags |= QMetaType::NeedsConstruction;
2430 if constexpr (!std::is_trivially_destructible_v<S>)
2431 flags |= QMetaType::NeedsDestruction;
2432 if constexpr (!std::is_trivially_copy_constructible_v<S>)
2433 flags |= QMetaType::NeedsCopyConstruction;
2434 if constexpr (!std::is_trivially_move_constructible_v<S>)
2435 flags |= QMetaType::NeedsMoveConstruction;
2436 if constexpr (IsPointerToTypeDerivedFromQObject<S>::Value)
2437 flags |= QMetaType::PointerToQObject;
2438 if constexpr (IsSharedPointerToTypeDerivedFromQObject<S>::Value)
2439 flags |= QMetaType::SharedPointerToQObject;
2440 if constexpr (IsWeakPointerToTypeDerivedFromQObject<S>::Value)
2441 flags |= QMetaType::WeakPointerToQObject;
2442 if constexpr (IsTrackingPointerToTypeDerivedFromQObject<S>::Value)
2443 flags |= QMetaType::TrackingPointerToQObject;
2444 if constexpr (IsEnumOrFlags<S>::value)
2445 flags |= QMetaType::IsEnumeration;
2446 if constexpr (IsGadgetHelper<S>::IsGadgetOrDerivedFrom)
2447 flags |= QMetaType::IsGadget;
2448 if constexpr (IsPointerToGadgetHelper<S>::IsGadgetOrDerivedFrom)
2449 flags |= QMetaType::PointerToGadget;
2450 if constexpr (std::is_pointer_v<S>)
2451 flags |= QMetaType::IsPointer;
2452 if constexpr (IsUnsignedEnum<S>)
2453 flags |= QMetaType::IsUnsignedEnumeration;
2454 if constexpr (IsQmlListType<S>)
2455 flags |= QMetaType::IsQmlList;
2456 if constexpr (std::is_const_v<std::remove_pointer_t<S>>)
2457 flags |= QMetaType::IsConst;
2458 return flags;
2459 }
2460
2461 static constexpr QMetaTypeInterface::DefaultCtrFn getDefaultCtr()
2462 {
2463 if constexpr (std::is_default_constructible_v<S> && !QTypeInfo<S>::isValueInitializationBitwiseZero) {
2464 return [](const QMetaTypeInterface *, void *addr) { new (addr) S(); };
2465 } else {
2466 return nullptr;
2467 }
2468 }
2469
2470 static constexpr QMetaTypeInterface::CopyCtrFn getCopyCtr()
2471 {
2472 if constexpr (std::is_copy_constructible_v<S> && !std::is_trivially_copy_constructible_v<S>) {
2473 return [](const QMetaTypeInterface *, void *addr, const void *other) {
2474 if constexpr (qxp::is_detected_v<QMetaTypeCopyTraits::HasDeprecatedCopyConstructorTest, S>) {
2475 #if !defined(QT_BOOTSTRAPPED)
2476 QMetaTypeCopyTraits::warnAboutDeprecatedCopy(getName());
2477 #endif
2478 QT_IGNORE_DEPRECATIONS(new (addr) S(*reinterpret_cast<const S *>(other));)
2479 } else {
2480 new (addr) S(*reinterpret_cast<const S *>(other));
2481 }
2482 };
2483 } else {
2484 return nullptr;
2485 }
2486 }
2487
2488 static constexpr QMetaTypeInterface::MoveCtrFn getMoveCtr()
2489 {
2490 if constexpr (std::is_move_constructible_v<S> && !std::is_trivially_move_constructible_v<S>) {
2491 return [](const QMetaTypeInterface *, void *addr, void *other) {
2492 new (addr) S(std::move(*reinterpret_cast<S *>(other)));
2493 };
2494 } else {
2495 return nullptr;
2496 }
2497 }
2498
2499 static constexpr QMetaTypeInterface::DtorFn getDtor()
2500 {
2501 if constexpr (std::is_destructible_v<S> && !std::is_trivially_destructible_v<S>)
2502 return [](const QMetaTypeInterface *, void *addr) {
2503 reinterpret_cast<S *>(addr)->~S();
2504 };
2505 else
2506 return nullptr;
2507 }
2508
2509 static constexpr QMetaTypeInterface::LegacyRegisterOp getLegacyRegister()
2510 {
2511 if constexpr (QMetaTypeId2<S>::Defined && !QMetaTypeId2<S>::IsBuiltIn) {
2512 return []() { QMetaTypeId2<S>::qt_metatype_id(); };
2513 } else {
2514 return nullptr;
2515 }
2516 }
2517
2518 static constexpr const char *getName()
2519 {
2520 if constexpr (bool(QMetaTypeId2<S>::IsBuiltIn)) {
2521 return QMetaTypeId2<S>::nameAsArray.data();
2522 } else {
2523 return name.data();
2524 }
2525 }
2526 };
2527
2528 template<typename T>
2529 struct QMetaTypeInterfaceWrapper
2530 {
2531
2532
2533
2534 static constexpr bool IsConstMetaTypeInterface = !!BuiltinMetaType<T>::value;
2535 using InterfaceType = std::conditional_t<IsConstMetaTypeInterface, const QMetaTypeInterface, NonConstMetaTypeInterface>;
2536
2537 static inline InterfaceType metaType = {
2538 QMetaTypeInterface::CurrentRevision,
2539 alignof(T),
2540 sizeof(T),
2541 QMetaTypeForType<T>::flags(),
2542 BuiltinMetaType<T>::value,
2543 MetaObjectForType<T>::metaObjectFunction,
2544 QMetaTypeForType<T>::getName(),
2545 QMetaTypeForType<T>::getDefaultCtr(),
2546 QMetaTypeForType<T>::getCopyCtr(),
2547 QMetaTypeForType<T>::getMoveCtr(),
2548 QMetaTypeForType<T>::getDtor(),
2549 QEqualityOperatorForType<T>::equals,
2550 QLessThanOperatorForType<T>::lessThan,
2551 QDebugStreamOperatorForType<T>::debugStream,
2552 QDataStreamOperatorForType<T>::dataStreamOut,
2553 QDataStreamOperatorForType<T>::dataStreamIn,
2554 QMetaTypeForType<T>::getLegacyRegister()
2555 };
2556 };
2557 template<typename T> struct QMetaTypeInterfaceWrapper<T &> {};
2558
2559
2560 #if !defined(Q_OS_WIN) && defined(Q_CC_CLANG)
2561 # pragma GCC visibility pop
2562 #endif
2563
2564 template<>
2565 class QMetaTypeInterfaceWrapper<void>
2566 {
2567 public:
2568 static constexpr QMetaTypeInterface metaType =
2569 {
2570 0,
2571 0,
2572 0,
2573 0,
2574 BuiltinMetaType<void>::value,
2575 nullptr,
2576 "void",
2577 nullptr,
2578 nullptr,
2579 nullptr,
2580 nullptr,
2581 nullptr,
2582 nullptr,
2583 nullptr,
2584 nullptr,
2585 nullptr,
2586 nullptr
2587 };
2588 };
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600 #if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
2601
2602 #ifdef QT_NO_DATA_RELOCATION
2603 # define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name) \
2604 extern template class Q_CORE_EXPORT QMetaTypeForType<Name>;
2605 #else
2606 # define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name) \
2607 extern template class Q_CORE_EXPORT QMetaTypeForType<Name>; \
2608 extern template struct Q_CORE_EXPORT QMetaTypeInterfaceWrapper<Name>;
2609 #endif
2610
2611 QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2612 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2613 QT_FOR_EACH_STATIC_CORE_CLASS(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2614 QT_FOR_EACH_STATIC_CORE_POINTER(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2615 QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2616 #undef QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER
2617 #endif
2618
2619 template<typename T>
2620 struct QRemovePointerLike
2621 {
2622 using type = std::remove_pointer_t<T>;
2623 };
2624
2625 #define Q_REMOVE_POINTER_LIKE_IMPL(Pointer) \
2626 template <typename T> \
2627 struct QRemovePointerLike<Pointer<T>> \
2628 { \
2629 using type = T; \
2630 };
2631
2632 QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_REMOVE_POINTER_LIKE_IMPL)
2633 #undef Q_REMOVE_POINTER_LIKE_IMPL
2634
2635 template<typename T>
2636 constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType()
2637 {
2638
2639 using Ty = typename MetatypeDecay<T>::type;
2640 return &QMetaTypeInterfaceWrapper<Ty>::metaType;
2641 }
2642
2643
2644
2645
2646
2647
2648 template<typename Unique, typename T>
2649 constexpr const QMetaTypeInterface *qTryMetaTypeInterfaceForType()
2650 {
2651 using Ty = typename MetatypeDecay<T>::type;
2652 using Tz = typename QRemovePointerLike<Ty>::type;
2653
2654 if constexpr (std::is_void_v<Tz>) {
2655
2656 return &QMetaTypeInterfaceWrapper<Ty>::metaType;
2657 } else if constexpr (std::is_void_v<Unique>) {
2658 checkTypeIsSuitableForMetaType<Ty>();
2659 return &QMetaTypeInterfaceWrapper<Ty>::metaType;
2660 } else if constexpr (std::is_reference_v<Tz>) {
2661 return nullptr;
2662 } else if constexpr (!is_complete<Tz, Unique>::value) {
2663 return nullptr;
2664 } else {
2665
2666 return &QMetaTypeInterfaceWrapper<Ty>::metaType;
2667 }
2668 }
2669
2670 }
2671
2672 template<typename T>
2673 constexpr QMetaType QMetaType::fromType()
2674 {
2675 QtPrivate::checkTypeIsSuitableForMetaType<T>();
2676 return QMetaType(QtPrivate::qMetaTypeInterfaceForType<T>());
2677 }
2678
2679 constexpr bool QMetaType::isValid(QT6_IMPL_NEW_OVERLOAD) const noexcept
2680 {
2681 return d_ptr;
2682 }
2683
2684 bool QMetaType::isRegistered(QT6_IMPL_NEW_OVERLOAD) const noexcept
2685 {
2686 return d_ptr && d_ptr->typeId.loadRelaxed();
2687 }
2688
2689 constexpr qsizetype QMetaType::sizeOf() const
2690 {
2691 return d_ptr ? d_ptr->size : 0;
2692 }
2693
2694 constexpr qsizetype QMetaType::alignOf() const
2695 {
2696 return d_ptr ? d_ptr->alignment : 0;
2697 }
2698
2699 constexpr QMetaType::TypeFlags QMetaType::flags() const
2700 {
2701 return d_ptr ? TypeFlags(d_ptr->flags) : TypeFlags{};
2702 }
2703
2704 constexpr const QMetaObject *QMetaType::metaObject() const
2705 {
2706 return d_ptr && d_ptr->metaObjectFn ? d_ptr->metaObjectFn(d_ptr) : nullptr;
2707 }
2708
2709 constexpr const char *QMetaType::name() const
2710 {
2711 return d_ptr ? d_ptr->name : nullptr;
2712 }
2713
2714 inline size_t qHash(QMetaType type, size_t seed = 0)
2715 {
2716
2717
2718 return qHash(type.id(), seed);
2719 }
2720
2721 QT_END_NAMESPACE
2722
2723 QT_DECL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl,
2724 QPairVariantInterfaceImpl, Q_CORE_EXPORT)
2725
2726 #endif