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