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