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
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 decltype(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
1492
1493 const char *eName = qt_getEnumName(T());
1494 const char *cName = qt_getEnumMetaObject(T())->className();
1495 QByteArray typeName;
1496 constexpr bool isConst = std::is_const_v<T>;
1497 typeName.reserve(strlen(cName) + 2 + strlen(eName) + (isConst ? strlen("const ") : 0));
1498 if constexpr (isConst)
1499 typeName.append("const ");
1500 typeName.append(cName).append("::").append(eName);
1501 const int newId = qRegisterNormalizedMetaType<T>(typeName);
1502 metatype_id.storeRelease(newId);
1503 return newId;
1504 }
1505 };
1506 #endif
1507
1508 #define Q_DECLARE_OPAQUE_POINTER(POINTER) \
1509 QT_BEGIN_NAMESPACE namespace QtPrivate { \
1510 template <> struct IsPointerDeclaredOpaque<POINTER> \
1511 : std::true_type {}; \
1512 } QT_END_NAMESPACE \
1513
1514
1515 #ifndef Q_MOC_RUN
1516 #define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
1517 #define Q_DECLARE_METATYPE_IMPL(TYPE) \
1518 QT_BEGIN_NAMESPACE \
1519 template <> \
1520 struct QMetaTypeId< TYPE > \
1521 { \
1522 enum { Defined = 1 }; \
1523 static_assert(QtPrivate::checkTypeIsSuitableForMetaType<TYPE>()); \
1524 static int qt_metatype_id() \
1525 { \
1526 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1527 if (const int id = metatype_id.loadAcquire()) \
1528 return id; \
1529 constexpr auto arr = QtPrivate::typenameHelper<TYPE>(); \
1530 auto name = arr.data(); \
1531 if (QByteArrayView(name) == (#TYPE)) { \
1532 const int id = qRegisterNormalizedMetaType<TYPE>(name); \
1533 metatype_id.storeRelease(id); \
1534 return id; \
1535 } \
1536 const int newId = qRegisterMetaType< TYPE >(#TYPE); \
1537 metatype_id.storeRelease(newId); \
1538 return newId; \
1539 } \
1540 }; \
1541 QT_END_NAMESPACE
1542 #endif
1543
1544 #define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME) \
1545 QT_BEGIN_NAMESPACE \
1546 template<> struct QMetaTypeId2<NAME> \
1547 { \
1548 using NameAsArrayType = std::array<char, sizeof(#NAME)>; \
1549 enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID }; \
1550 static inline constexpr int qt_metatype_id() { return METATYPEID; } \
1551 static constexpr NameAsArrayType nameAsArray = { #NAME }; \
1552 }; \
1553 QT_END_NAMESPACE
1554
1555 #define QT_FORWARD_DECLARE_STATIC_TYPES_ITER(TypeName, TypeId, Name) \
1556 class Name;
1557
1558 QT_FOR_EACH_STATIC_CORE_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
1559 QT_FOR_EACH_STATIC_GUI_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
1560 QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER)
1561
1562 #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER
1563
1564 #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \
1565 QT_BEGIN_NAMESPACE \
1566 template <typename T> \
1567 struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
1568 { \
1569 enum { \
1570 Defined = QMetaTypeId2<T>::Defined \
1571 }; \
1572 static int qt_metatype_id() \
1573 { \
1574 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1575 if (const int id = metatype_id.loadRelaxed()) \
1576 return id; \
1577 const char *tName = QMetaType::fromType<T>().name(); \
1578 Q_ASSERT(tName); \
1579 const size_t tNameLen = qstrlen(tName); \
1580 QByteArray typeName; \
1581 typeName.reserve(sizeof(#SINGLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + 1); \
1582 typeName.append(#SINGLE_ARG_TEMPLATE, int(sizeof(#SINGLE_ARG_TEMPLATE)) - 1) \
1583 .append('<').append(tName, tNameLen); \
1584 typeName.append('>'); \
1585 const int newId = qRegisterNormalizedMetaType< SINGLE_ARG_TEMPLATE<T> >(typeName); \
1586 metatype_id.storeRelease(newId); \
1587 return newId; \
1588 } \
1589 }; \
1590 QT_END_NAMESPACE
1591
1592 #define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
1593 QT_BEGIN_NAMESPACE \
1594 template<typename T, typename U> \
1595 struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
1596 { \
1597 enum { \
1598 Defined = QMetaTypeId2<T>::Defined && QMetaTypeId2<U>::Defined \
1599 }; \
1600 static int qt_metatype_id() \
1601 { \
1602 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1603 if (const int id = metatype_id.loadAcquire()) \
1604 return id; \
1605 const char *tName = QMetaType::fromType<T>().name(); \
1606 const char *uName = QMetaType::fromType<U>().name(); \
1607 Q_ASSERT(tName); \
1608 Q_ASSERT(uName); \
1609 const size_t tNameLen = qstrlen(tName); \
1610 const size_t uNameLen = qstrlen(uName); \
1611 QByteArray typeName; \
1612 typeName.reserve(sizeof(#DOUBLE_ARG_TEMPLATE) + 1 + tNameLen + 1 + uNameLen + 1 + 1); \
1613 typeName.append(#DOUBLE_ARG_TEMPLATE, int(sizeof(#DOUBLE_ARG_TEMPLATE)) - 1) \
1614 .append('<').append(tName, tNameLen).append(',').append(uName, uNameLen); \
1615 typeName.append('>'); \
1616 const int newId = qRegisterNormalizedMetaType< DOUBLE_ARG_TEMPLATE<T, U> >(typeName); \
1617 metatype_id.storeRelease(newId); \
1618 return newId; \
1619 } \
1620 }; \
1621 QT_END_NAMESPACE
1622
1623 namespace QtPrivate {
1624
1625 template<typename T, bool = false>
1626 struct SharedPointerMetaTypeIdHelper
1627 {
1628 enum {
1629 Defined = 0
1630 };
1631 static int qt_metatype_id()
1632 {
1633 return -1;
1634 }
1635 };
1636
1637 }
1638
1639 #define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
1640 QT_BEGIN_NAMESPACE \
1641 namespace QtPrivate { \
1642 template<typename T> \
1643 struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
1644 { \
1645 enum { \
1646 Defined = 1 \
1647 }; \
1648 static int qt_metatype_id() \
1649 { \
1650 Q_CONSTINIT static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
1651 if (const int id = metatype_id.loadAcquire()) \
1652 return id; \
1653 const char * const cName = T::staticMetaObject.className(); \
1654 QByteArray typeName; \
1655 typeName.reserve(sizeof(#SMART_POINTER) + 1 + strlen(cName) + 1); \
1656 typeName.append(#SMART_POINTER, int(sizeof(#SMART_POINTER)) - 1) \
1657 .append('<').append(cName).append('>'); \
1658 const int newId = qRegisterNormalizedMetaType< SMART_POINTER<T> >(typeName); \
1659 metatype_id.storeRelease(newId); \
1660 return newId; \
1661 } \
1662 }; \
1663 template<typename T> \
1664 struct MetaTypeSmartPointerHelper<SMART_POINTER<T> , \
1665 typename std::enable_if<IsPointerToTypeDerivedFromQObject<T*>::Value && !std::is_const_v<T>>::type> \
1666 { \
1667 static bool registerConverter() \
1668 { \
1669 const QMetaType to = QMetaType(QMetaType::QObjectStar); \
1670 if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<SMART_POINTER<T>>(), to)) { \
1671 QtPrivate::QSmartPointerConvertFunctor<SMART_POINTER<T> > o; \
1672 return QMetaType::registerConverter<SMART_POINTER<T>, QObject*>(o); \
1673 } \
1674 return true; \
1675 } \
1676 }; \
1677 } \
1678 template <typename T> \
1679 struct QMetaTypeId< SMART_POINTER<T> > \
1680 : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
1681 QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
1682 { \
1683 };\
1684 QT_END_NAMESPACE
1685
1686 #define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(SINGLE_ARG_TEMPLATE) \
1687 QT_BEGIN_NAMESPACE \
1688 namespace QtPrivate { \
1689 template<typename T> \
1690 struct IsSequentialContainer<SINGLE_ARG_TEMPLATE<T> > \
1691 { \
1692 enum { Value = true }; \
1693 }; \
1694 } \
1695 QT_END_NAMESPACE \
1696 Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE)
1697
1698 #define Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER(TEMPLATENAME) \
1699 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(TEMPLATENAME)
1700
1701 QT_END_NAMESPACE
1702
1703 QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER)
1704
1705 #undef Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE_ITER
1706
1707 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::vector)
1708 Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::list)
1709
1710 #define Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(TEMPLATENAME) \
1711 QT_BEGIN_NAMESPACE \
1712 namespace QtPrivate { \
1713 template<typename T, typename U> \
1714 struct IsAssociativeContainer<TEMPLATENAME<T, U> > \
1715 { \
1716 enum { Value = true }; \
1717 }; \
1718 } \
1719 QT_END_NAMESPACE \
1720 Q_DECLARE_METATYPE_TEMPLATE_2ARG(TEMPLATENAME)
1721
1722 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash)
1723 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap)
1724 Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map)
1725
1726 Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair)
1727
1728 #define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
1729 Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
1730
1731 QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER)
1732
1733 QT_BEGIN_NAMESPACE
1734
1735 #undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
1736
1737 QT_END_NAMESPACE
1738
1739 QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
1740
1741
1742 QT_BEGIN_NAMESPACE
1743
1744 namespace QtPrivate {
1745
1746 Q_CORE_EXPORT bool hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m);
1747 Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m);
1748 Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m);
1749 Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m);
1750 Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m);
1751 }
1752
1753 template <typename T>
1754 inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter()
1755 {
1756 if (!QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType::fromType<T>())) {
1757 QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
1758 return QMetaType::registerConverter<T, QtMetaTypePrivate::QPairVariantInterfaceImpl>(o);
1759 }
1760 return true;
1761 }
1762
1763 namespace QtPrivate {
1764
1765 template<typename From>
1766 struct QSequentialIterableConvertFunctor
1767 {
1768 QIterable<QMetaSequence> operator()(const From &f) const
1769 {
1770 return QIterable<QMetaSequence>(QMetaSequence::fromContainer<From>(), &f);
1771 }
1772 };
1773
1774 template<typename From>
1775 struct QSequentialIterableMutableViewFunctor
1776 {
1777 QIterable<QMetaSequence> operator()(From &f) const
1778 {
1779 return QIterable<QMetaSequence>(QMetaSequence::fromContainer<From>(), &f);
1780 }
1781 };
1782
1783 template<typename T>
1784 struct SequentialValueTypeIsMetaType<T, true>
1785 {
1786 static bool registerConverter()
1787 {
1788 if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
1789 QSequentialIterableConvertFunctor<T> o;
1790 return QMetaType::registerConverter<T, QIterable<QMetaSequence>>(o);
1791 }
1792 return true;
1793 }
1794
1795 static bool registerMutableView()
1796 {
1797 if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
1798 QSequentialIterableMutableViewFunctor<T> o;
1799 return QMetaType::registerMutableView<T, QIterable<QMetaSequence>>(o);
1800 }
1801 return true;
1802 }
1803 };
1804
1805 template<typename From>
1806 struct QAssociativeIterableConvertFunctor
1807 {
1808 QIterable<QMetaAssociation> operator()(const From &f) const
1809 {
1810 return QIterable<QMetaAssociation>(QMetaAssociation::fromContainer<From>(), &f);
1811 }
1812 };
1813
1814 template<typename From>
1815 struct QAssociativeIterableMutableViewFunctor
1816 {
1817 QIterable<QMetaAssociation> operator()(From &f) const
1818 {
1819 return QIterable<QMetaAssociation>(QMetaAssociation::fromContainer<From>(), &f);
1820 }
1821 };
1822
1823
1824
1825 template<typename T>
1826 struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T>
1827 {
1828 static bool registerConverter()
1829 {
1830 if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
1831 QAssociativeIterableConvertFunctor<T> o;
1832 return QMetaType::registerConverter<T, QIterable<QMetaAssociation>>(o);
1833 }
1834 return true;
1835 }
1836
1837 static bool registerMutableView()
1838 {
1839 if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
1840 QAssociativeIterableMutableViewFunctor<T> o;
1841 return QMetaType::registerMutableView<T, QIterable<QMetaAssociation>>(o);
1842 }
1843 return true;
1844 }
1845 };
1846
1847 struct QTypeNormalizer
1848 {
1849 char *output;
1850 int len = 0;
1851 char last = 0;
1852
1853 private:
1854 static constexpr bool is_ident_char(char s)
1855 {
1856 return ((s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || (s >= '0' && s <= '9')
1857 || s == '_');
1858 }
1859 static constexpr bool is_space(char s) { return (s == ' ' || s == '\t' || s == '\n'); }
1860 static constexpr bool is_number(char s) { return s >= '0' && s <= '9'; }
1861 static constexpr bool starts_with_token(const char *b, const char *e, const char *token,
1862 bool msvcKw = false)
1863 {
1864 while (b != e && *token && *b == *token) {
1865 b++;
1866 token++;
1867 }
1868 if (*token)
1869 return false;
1870 #ifdef Q_CC_MSVC
1871
1872
1873 if (msvcKw && !is_ident_char(*b))
1874 return true;
1875 #endif
1876 Q_UNUSED(msvcKw);
1877 return b == e || !is_ident_char(*b);
1878 }
1879 static constexpr bool skipToken(const char *&x, const char *e, const char *token,
1880 bool msvcKw = false)
1881 {
1882 if (!starts_with_token(x, e, token, msvcKw))
1883 return false;
1884 while (*token++)
1885 x++;
1886 while (x != e && is_space(*x))
1887 x++;
1888 return true;
1889 }
1890 static constexpr const char *skipString(const char *x, const char *e)
1891 {
1892 char delim = *x;
1893 x++;
1894 while (x != e && *x != delim) {
1895 if (*x == '\\') {
1896 x++;
1897 if (x == e)
1898 return e;
1899 }
1900 x++;
1901 }
1902 if (x != e)
1903 x++;
1904 return x;
1905 }
1906 static constexpr const char *skipTemplate(const char *x, const char *e, bool stopAtComa = false)
1907 {
1908 int scopeDepth = 0;
1909 int templateDepth = 0;
1910 while (x != e) {
1911 switch (*x) {
1912 case '<':
1913 if (!scopeDepth)
1914 templateDepth++;
1915 break;
1916 case ',':
1917 if (stopAtComa && !scopeDepth && !templateDepth)
1918 return x;
1919 break;
1920 case '>':
1921 if (!scopeDepth)
1922 if (--templateDepth < 0)
1923 return x;
1924 break;
1925 case '(':
1926 case '[':
1927 case '{':
1928 scopeDepth++;
1929 break;
1930 case '}':
1931 case ']':
1932 case ')':
1933 scopeDepth--;
1934 break;
1935 case '\'':
1936 if (is_number(x[-1]))
1937 break;
1938 Q_FALLTHROUGH();
1939 case '\"':
1940 x = skipString(x, e);
1941 continue;
1942 }
1943 x++;
1944 }
1945 return x;
1946 }
1947
1948 constexpr void append(char x)
1949 {
1950 last = x;
1951 len++;
1952 if (output)
1953 *output++ = x;
1954 }
1955
1956 constexpr void replaceLast(char x)
1957 {
1958 last = x;
1959 if (output)
1960 *(output - 1) = x;
1961 }
1962
1963 constexpr void appendStr(const char *x)
1964 {
1965 while (*x)
1966 append(*x++);
1967 }
1968
1969 constexpr void normalizeIntegerTypes(const char *&begin, const char *end)
1970 {
1971 int numLong = 0;
1972 int numSigned = 0;
1973 int numUnsigned = 0;
1974 int numInt = 0;
1975 int numShort = 0;
1976 int numChar = 0;
1977 while (begin < end) {
1978 if (skipToken(begin, end, "long")) {
1979 numLong++;
1980 continue;
1981 }
1982 if (skipToken(begin, end, "int")) {
1983 numInt++;
1984 continue;
1985 }
1986 if (skipToken(begin, end, "short")) {
1987 numShort++;
1988 continue;
1989 }
1990 if (skipToken(begin, end, "unsigned")) {
1991 numUnsigned++;
1992 continue;
1993 }
1994 if (skipToken(begin, end, "signed")) {
1995 numSigned++;
1996 continue;
1997 }
1998 if (skipToken(begin, end, "char")) {
1999 numChar++;
2000 continue;
2001 }
2002 #ifdef Q_CC_MSVC
2003 if (skipToken(begin, end, "__int64")) {
2004 numLong = 2;
2005 continue;
2006 }
2007 #endif
2008 break;
2009 }
2010 if (numLong == 2)
2011 append('q');
2012 if (numSigned && numChar)
2013 appendStr("signed ");
2014 else if (numUnsigned)
2015 appendStr("u");
2016 if (numChar)
2017 appendStr("char");
2018 else if (numShort)
2019 appendStr("short");
2020 else if (numLong == 1)
2021 appendStr("long");
2022 else if (numLong == 2)
2023 appendStr("longlong");
2024 else if (numUnsigned || numSigned || numInt)
2025 appendStr("int");
2026 }
2027
2028 constexpr void skipStructClassOrEnum(const char *&begin, const char *end)
2029 {
2030
2031
2032 skipToken(begin, end, "struct", true) || skipToken(begin, end, "class", true)
2033 || skipToken(begin, end, "enum", true);
2034 }
2035
2036 constexpr void skipQtNamespace(const char *&begin, const char *end)
2037 {
2038 #ifdef QT_NAMESPACE
2039 const char *nsbeg = begin;
2040 if (skipToken(nsbeg, end, QT_STRINGIFY(QT_NAMESPACE)) && nsbeg + 2 < end && nsbeg[0] == ':'
2041 && nsbeg[1] == ':') {
2042 begin = nsbeg + 2;
2043 while (begin != end && is_space(*begin))
2044 begin++;
2045 }
2046 #else
2047 Q_UNUSED(begin);
2048 Q_UNUSED(end);
2049 #endif
2050 }
2051
2052 public:
2053 #if defined(Q_CC_CLANG) || defined (Q_CC_GNU)
2054
2055
2056
2057 constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
2058 {
2059
2060 std::string_view name(begin, end-begin);
2061 #if defined (Q_CC_CLANG)
2062 if (name.find("anonymous ") != std::string_view::npos)
2063 return normalizeType(begin, end);
2064 #endif
2065 if (name.find("unnamed ") != std::string_view::npos)
2066 return normalizeType(begin, end);
2067 while (begin < end) {
2068 if (*begin == ' ') {
2069 if (last == ',' || last == '>' || last == '<' || last == '*' || last == '&') {
2070 ++begin;
2071 continue;
2072 }
2073 }
2074 if (last == ' ') {
2075 if (*begin == '*' || *begin == '&' || *begin == '(') {
2076 replaceLast(*begin);
2077 ++begin;
2078 continue;
2079 }
2080 }
2081 if (!is_ident_char(last)) {
2082 skipStructClassOrEnum(begin, end);
2083 if (begin == end)
2084 break;
2085
2086 skipQtNamespace(begin, end);
2087 if (begin == end)
2088 break;
2089
2090 normalizeIntegerTypes(begin, end);
2091 if (begin == end)
2092 break;
2093 }
2094 append(*begin);
2095 ++begin;
2096 }
2097 return len;
2098 }
2099 #else
2100
2101
2102 constexpr int normalizeTypeFromSignature(const char *begin, const char *end)
2103 { return normalizeType(begin, end); }
2104 #endif
2105
2106 constexpr int normalizeType(const char *begin, const char *end, bool adjustConst = true)
2107 {
2108
2109 while (begin != end && is_space(*begin))
2110 begin++;
2111 while (begin != end && is_space(*(end - 1)))
2112 end--;
2113
2114 if (begin == end)
2115 return len;
2116
2117
2118
2119 const char *cst = begin + 1;
2120 if (*begin == '\'' || *begin == '"')
2121 cst = skipString(begin, end);
2122 bool seenStar = false;
2123 bool hasMiddleConst = false;
2124 while (cst < end) {
2125 if (*cst == '\"' || (*cst == '\'' && !is_number(cst[-1]))) {
2126 cst = skipString(cst, end);
2127 if (cst == end)
2128 break;
2129 }
2130
2131
2132
2133 if (*cst == '&' || *cst == '*' || *cst == '[') {
2134 seenStar = *cst != '&' || cst != (end - 1);
2135 break;
2136 }
2137 if (*cst == '<') {
2138 cst = skipTemplate(cst + 1, end);
2139 if (cst == end)
2140 break;
2141 }
2142 cst++;
2143 const char *skipedCst = cst;
2144 if (!is_ident_char(*(cst - 1)) && skipToken(skipedCst, end, "const")) {
2145 const char *testEnd = end;
2146 while (skipedCst < testEnd--) {
2147 if (*testEnd == '*' || *testEnd == '['
2148 || (*testEnd == '&' && testEnd != (end - 1))) {
2149 seenStar = true;
2150 break;
2151 }
2152 if (*testEnd == '>')
2153 break;
2154 }
2155 if (adjustConst && !seenStar) {
2156 if (*(end - 1) == '&')
2157 end--;
2158 } else {
2159 appendStr("const ");
2160 }
2161 normalizeType(begin, cst, false);
2162 begin = skipedCst;
2163 hasMiddleConst = true;
2164 break;
2165 }
2166 }
2167 if (skipToken(begin, end, "const")) {
2168 if (adjustConst && !seenStar) {
2169 if (*(end - 1) == '&')
2170 end--;
2171 } else {
2172 appendStr("const ");
2173 }
2174 }
2175 if (seenStar && adjustConst) {
2176 const char *e = end;
2177 if (*(end - 1) == '&' && *(end - 2) != '&')
2178 e--;
2179 while (begin != e && is_space(*(e - 1)))
2180 e--;
2181 const char *token = "tsnoc";
2182 while (*token && begin != e && *(--e) == *token++)
2183 ;
2184 if (!*token && begin != e && !is_ident_char(*(e - 1))) {
2185 while (begin != e && is_space(*(e - 1)))
2186 e--;
2187 end = e;
2188 }
2189 }
2190
2191 skipStructClassOrEnum(begin, end);
2192 skipQtNamespace(begin, end);
2193
2194 if (skipToken(begin, end, "QVector")) {
2195
2196 appendStr("QList");
2197 }
2198
2199 if (skipToken(begin, end, "QPair")) {
2200
2201 appendStr("std::pair");
2202 }
2203
2204 if (!hasMiddleConst)
2205
2206 normalizeIntegerTypes(begin, end);
2207
2208 bool spaceSkiped = true;
2209 while (begin != end) {
2210 char c = *begin++;
2211 if (is_space(c)) {
2212 spaceSkiped = true;
2213 } else if ((c == '\'' && !is_number(last)) || c == '\"') {
2214 begin--;
2215 auto x = skipString(begin, end);
2216 while (begin < x)
2217 append(*begin++);
2218 } else {
2219 if (spaceSkiped && is_ident_char(last) && is_ident_char(c))
2220 append(' ');
2221 append(c);
2222 spaceSkiped = false;
2223 if (c == '<') {
2224 do {
2225
2226 const char *tpl = skipTemplate(begin, end, true);
2227 normalizeType(begin, tpl, false);
2228 if (tpl == end)
2229 return len;
2230 append(*tpl);
2231 begin = tpl;
2232 } while (*begin++ == ',');
2233 }
2234 }
2235 }
2236 return len;
2237 }
2238 };
2239
2240
2241
2242
2243 constexpr int qNormalizeType(const char *begin, const char *end, char *output)
2244 {
2245 return QTypeNormalizer { output }.normalizeType(begin, end);
2246 }
2247
2248 template<typename T>
2249 struct is_std_pair : std::false_type {};
2250
2251 template <typename T1_, typename T2_>
2252 struct is_std_pair<std::pair<T1_, T2_>> : std::true_type {
2253 using T1 = T1_;
2254 using T2 = T2_;
2255 };
2256
2257 namespace TypeNameHelper {
2258 template<typename T>
2259 constexpr auto typenameHelper()
2260 {
2261 if constexpr (is_std_pair<T>::value) {
2262 using T1 = typename is_std_pair<T>::T1;
2263 using T2 = typename is_std_pair<T>::T2;
2264 std::remove_const_t<std::conditional_t<bool (QMetaTypeId2<T1>::IsBuiltIn), typename QMetaTypeId2<T1>::NameAsArrayType, decltype(typenameHelper<T1>())>> t1Name {};
2265 std::remove_const_t<std::conditional_t<bool (QMetaTypeId2<T2>::IsBuiltIn), typename QMetaTypeId2<T2>::NameAsArrayType, decltype(typenameHelper<T2>())>> t2Name {};
2266 if constexpr (bool (QMetaTypeId2<T1>::IsBuiltIn) ) {
2267 t1Name = QMetaTypeId2<T1>::nameAsArray;
2268 } else {
2269 t1Name = typenameHelper<T1>();
2270 }
2271 if constexpr (bool(QMetaTypeId2<T2>::IsBuiltIn)) {
2272 t2Name = QMetaTypeId2<T2>::nameAsArray;
2273 } else {
2274 t2Name = typenameHelper<T2>();
2275 }
2276 constexpr auto nonTypeDependentLen = sizeof("std::pair<,>");
2277 constexpr auto t1Len = t1Name.size() - 1;
2278 constexpr auto t2Len = t2Name.size() - 1;
2279 constexpr auto length = nonTypeDependentLen + t1Len + t2Len;
2280 std::array<char, length + 1> result {};
2281 constexpr auto prefix = "std::pair<";
2282 int currentLength = 0;
2283 for (; currentLength < int(sizeof("std::pair<") - 1); ++currentLength)
2284 result[currentLength] = prefix[currentLength];
2285 for (int i = 0; i < int(t1Len); ++currentLength, ++i)
2286 result[currentLength] = t1Name[i];
2287 result[currentLength++] = ',';
2288 for (int i = 0; i < int(t2Len); ++currentLength, ++i)
2289 result[currentLength] = t2Name[i];
2290 result[currentLength++] = '>';
2291 result[currentLength++] = '\0';
2292 return result;
2293 } else {
2294 constexpr auto prefix = sizeof(
2295 #ifdef QT_NAMESPACE
2296 QT_STRINGIFY(QT_NAMESPACE) "::"
2297 #endif
2298 #if defined(Q_CC_MSVC) && defined(Q_CC_CLANG)
2299 "auto __cdecl QtPrivate::TypeNameHelper::typenameHelper(void) [T = "
2300 #elif defined(Q_CC_MSVC)
2301 "auto __cdecl QtPrivate::TypeNameHelper::typenameHelper<"
2302 #elif defined(Q_CC_CLANG)
2303 "auto QtPrivate::TypeNameHelper::typenameHelper() [T = "
2304 #elif defined(Q_CC_GHS)
2305 "auto QtPrivate::TypeNameHelper::typenameHelper<T>()[with T="
2306 #else
2307 "constexpr auto QtPrivate::TypeNameHelper::typenameHelper() [with T = "
2308 #endif
2309 ) - 1;
2310 #if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
2311 constexpr int suffix = sizeof(">(void)");
2312 #else
2313 constexpr int suffix = sizeof("]");
2314 #endif
2315
2316 #if defined(Q_CC_GNU_ONLY) && Q_CC_GNU_ONLY < 804
2317 auto func = Q_FUNC_INFO;
2318 const char *begin = func + prefix;
2319 const char *end = func + sizeof(Q_FUNC_INFO) - suffix;
2320
2321 constexpr int len = sizeof(Q_FUNC_INFO) - suffix - prefix;
2322 #else
2323 constexpr auto func = Q_FUNC_INFO;
2324 constexpr const char *begin = func + prefix;
2325 constexpr const char *end = func + sizeof(Q_FUNC_INFO) - suffix;
2326 constexpr int len = QTypeNormalizer{ nullptr }.normalizeTypeFromSignature(begin, end);
2327 #endif
2328 std::array<char, len + 1> result {};
2329 QTypeNormalizer{ result.data() }.normalizeTypeFromSignature(begin, end);
2330 return result;
2331 }
2332 }
2333 }
2334 using TypeNameHelper::typenameHelper;
2335
2336 template<typename T, typename = void>
2337 struct BuiltinMetaType : std::integral_constant<int, 0>
2338 {
2339 };
2340 template<typename T>
2341 struct BuiltinMetaType<T, std::enable_if_t<QMetaTypeId2<T>::IsBuiltIn>>
2342 : std::integral_constant<int, QMetaTypeId2<T>::MetaType>
2343 {
2344 };
2345
2346 template<typename T, bool = (QTypeTraits::has_operator_equal_v<T> && !std::is_pointer_v<T>)>
2347 struct QEqualityOperatorForType
2348 {
2349 QT_WARNING_PUSH
2350 QT_WARNING_DISABLE_FLOAT_COMPARE
2351 static bool equals(const QMetaTypeInterface *, const void *a, const void *b)
2352 { return *reinterpret_cast<const T *>(a) == *reinterpret_cast<const T *>(b); }
2353 QT_WARNING_POP
2354 };
2355
2356 template<typename T>
2357 struct QEqualityOperatorForType <T, false>
2358 {
2359 static constexpr QMetaTypeInterface::EqualsFn equals = nullptr;
2360 };
2361
2362 template<typename T, bool = (QTypeTraits::has_operator_less_than_v<T> && !std::is_pointer_v<T>)>
2363 struct QLessThanOperatorForType
2364 {
2365 static bool lessThan(const QMetaTypeInterface *, const void *a, const void *b)
2366 { return *reinterpret_cast<const T *>(a) < *reinterpret_cast<const T *>(b); }
2367 };
2368
2369 template<typename T>
2370 struct QLessThanOperatorForType <T, false>
2371 {
2372 static constexpr QMetaTypeInterface::LessThanFn lessThan = nullptr;
2373 };
2374
2375 template<typename T, bool = (QTypeTraits::has_ostream_operator_v<QDebug, T> && !std::is_pointer_v<T>)>
2376 struct QDebugStreamOperatorForType
2377 {
2378 static constexpr QMetaTypeInterface::DebugStreamFn debugStream = nullptr;
2379 };
2380
2381 #ifndef QT_NO_DEBUG_STREAM
2382 template<typename T>
2383 struct QDebugStreamOperatorForType <T, true>
2384 {
2385 static void debugStream(const QMetaTypeInterface *, QDebug &dbg, const void *a)
2386 { dbg << *reinterpret_cast<const T *>(a); }
2387 };
2388 #endif
2389
2390 template<typename T, bool = QTypeTraits::has_stream_operator_v<QDataStream, T>>
2391 struct QDataStreamOperatorForType
2392 {
2393 static constexpr QMetaTypeInterface::DataStreamOutFn dataStreamOut = nullptr;
2394 static constexpr QMetaTypeInterface::DataStreamInFn dataStreamIn = nullptr;
2395 };
2396
2397 #ifndef QT_NO_DATASTREAM
2398 template<typename T>
2399 struct QDataStreamOperatorForType <T, true>
2400 {
2401 static void dataStreamOut(const QMetaTypeInterface *, QDataStream &ds, const void *a)
2402 { ds << *reinterpret_cast<const T *>(a); }
2403 static void dataStreamIn(const QMetaTypeInterface *, QDataStream &ds, void *a)
2404 { ds >> *reinterpret_cast<T *>(a); }
2405 };
2406 #endif
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418 #if !defined(Q_OS_WIN) && defined(Q_CC_CLANG)
2419 # pragma GCC visibility push(hidden)
2420 #endif
2421
2422
2423
2424 namespace QMetaTypeCopyTraits
2425 {
2426
2427
2428 template <typename T>
2429 using HasDeprecatedCopyConstructorTest = typename T::_q_hasDeprecatedCopyConstructor;
2430
2431 #if !defined(QT_BOOTSTRAPPED)
2432 Q_CORE_EXPORT void warnAboutDeprecatedCopy(const char *name);
2433 #endif
2434 }
2435
2436 template<typename S>
2437 class QMetaTypeForType
2438 {
2439 public:
2440 static constexpr decltype(typenameHelper<S>()) name = typenameHelper<S>();
2441
2442 static constexpr unsigned flags()
2443 {
2444 uint flags = 0;
2445 if constexpr (QTypeInfo<S>::isRelocatable)
2446 flags |= QMetaType::RelocatableType;
2447 if constexpr (!std::is_default_constructible_v<S> || !QTypeInfo<S>::isValueInitializationBitwiseZero)
2448 flags |= QMetaType::NeedsConstruction;
2449 if constexpr (!std::is_trivially_destructible_v<S>)
2450 flags |= QMetaType::NeedsDestruction;
2451 if constexpr (!std::is_trivially_copy_constructible_v<S>)
2452 flags |= QMetaType::NeedsCopyConstruction;
2453 if constexpr (!std::is_trivially_move_constructible_v<S>)
2454 flags |= QMetaType::NeedsMoveConstruction;
2455 if constexpr (IsPointerToTypeDerivedFromQObject<S>::Value)
2456 flags |= QMetaType::PointerToQObject;
2457 if constexpr (IsSharedPointerToTypeDerivedFromQObject<S>::Value)
2458 flags |= QMetaType::SharedPointerToQObject;
2459 if constexpr (IsWeakPointerToTypeDerivedFromQObject<S>::Value)
2460 flags |= QMetaType::WeakPointerToQObject;
2461 if constexpr (IsTrackingPointerToTypeDerivedFromQObject<S>::Value)
2462 flags |= QMetaType::TrackingPointerToQObject;
2463 if constexpr (IsEnumOrFlags<S>::value)
2464 flags |= QMetaType::IsEnumeration;
2465 if constexpr (IsGadgetHelper<S>::IsGadgetOrDerivedFrom)
2466 flags |= QMetaType::IsGadget;
2467 if constexpr (IsPointerToGadgetHelper<S>::IsGadgetOrDerivedFrom)
2468 flags |= QMetaType::PointerToGadget;
2469 if constexpr (std::is_pointer_v<S>)
2470 flags |= QMetaType::IsPointer;
2471 if constexpr (IsUnsignedEnum<S>)
2472 flags |= QMetaType::IsUnsignedEnumeration;
2473 if constexpr (IsQmlListType<S>)
2474 flags |= QMetaType::IsQmlList;
2475 if constexpr (std::is_const_v<std::remove_pointer_t<S>>)
2476 flags |= QMetaType::IsConst;
2477 return flags;
2478 }
2479
2480 static constexpr QMetaTypeInterface::DefaultCtrFn getDefaultCtr()
2481 {
2482 if constexpr (std::is_default_constructible_v<S> && !QTypeInfo<S>::isValueInitializationBitwiseZero) {
2483 return [](const QMetaTypeInterface *, void *addr) { new (addr) S(); };
2484 } else {
2485 return nullptr;
2486 }
2487 }
2488
2489 static constexpr QMetaTypeInterface::CopyCtrFn getCopyCtr()
2490 {
2491 if constexpr (std::is_copy_constructible_v<S> && !std::is_trivially_copy_constructible_v<S>) {
2492 return [](const QMetaTypeInterface *, void *addr, const void *other) {
2493 if constexpr (qxp::is_detected_v<QMetaTypeCopyTraits::HasDeprecatedCopyConstructorTest, S>) {
2494 #if !defined(QT_BOOTSTRAPPED)
2495 QMetaTypeCopyTraits::warnAboutDeprecatedCopy(getName());
2496 #endif
2497 QT_IGNORE_DEPRECATIONS(new (addr) S(*reinterpret_cast<const S *>(other));)
2498 } else {
2499 new (addr) S(*reinterpret_cast<const S *>(other));
2500 }
2501 };
2502 } else {
2503 return nullptr;
2504 }
2505 }
2506
2507 static constexpr QMetaTypeInterface::MoveCtrFn getMoveCtr()
2508 {
2509 if constexpr (std::is_move_constructible_v<S> && !std::is_trivially_move_constructible_v<S>) {
2510 return [](const QMetaTypeInterface *, void *addr, void *other) {
2511 new (addr) S(std::move(*reinterpret_cast<S *>(other)));
2512 };
2513 } else {
2514 return nullptr;
2515 }
2516 }
2517
2518 static constexpr QMetaTypeInterface::DtorFn getDtor()
2519 {
2520 if constexpr (std::is_destructible_v<S> && !std::is_trivially_destructible_v<S>)
2521 return [](const QMetaTypeInterface *, void *addr) {
2522 reinterpret_cast<S *>(addr)->~S();
2523 };
2524 else
2525 return nullptr;
2526 }
2527
2528 static constexpr QMetaTypeInterface::LegacyRegisterOp getLegacyRegister()
2529 {
2530 if constexpr (QMetaTypeId2<S>::Defined && !QMetaTypeId2<S>::IsBuiltIn) {
2531 return []() { QMetaTypeId2<S>::qt_metatype_id(); };
2532 } else {
2533 return nullptr;
2534 }
2535 }
2536
2537 static constexpr const char *getName()
2538 {
2539 if constexpr (bool(QMetaTypeId2<S>::IsBuiltIn)) {
2540 return QMetaTypeId2<S>::nameAsArray.data();
2541 } else {
2542 return name.data();
2543 }
2544 }
2545 };
2546
2547 template<typename T>
2548 struct QMetaTypeInterfaceWrapper
2549 {
2550
2551
2552
2553 static constexpr bool IsConstMetaTypeInterface = !!BuiltinMetaType<T>::value;
2554 using InterfaceType = std::conditional_t<IsConstMetaTypeInterface, const QMetaTypeInterface, NonConstMetaTypeInterface>;
2555
2556 static inline InterfaceType metaType = {
2557 QMetaTypeInterface::CurrentRevision,
2558 alignof(T),
2559 sizeof(T),
2560 QMetaTypeForType<T>::flags(),
2561 BuiltinMetaType<T>::value,
2562 MetaObjectForType<T>::metaObjectFunction,
2563 QMetaTypeForType<T>::getName(),
2564 QMetaTypeForType<T>::getDefaultCtr(),
2565 QMetaTypeForType<T>::getCopyCtr(),
2566 QMetaTypeForType<T>::getMoveCtr(),
2567 QMetaTypeForType<T>::getDtor(),
2568 QEqualityOperatorForType<T>::equals,
2569 QLessThanOperatorForType<T>::lessThan,
2570 QDebugStreamOperatorForType<T>::debugStream,
2571 QDataStreamOperatorForType<T>::dataStreamOut,
2572 QDataStreamOperatorForType<T>::dataStreamIn,
2573 QMetaTypeForType<T>::getLegacyRegister()
2574 };
2575 };
2576 template<typename T> struct QMetaTypeInterfaceWrapper<T &> {};
2577
2578
2579 #if !defined(Q_OS_WIN) && defined(Q_CC_CLANG)
2580 # pragma GCC visibility pop
2581 #endif
2582
2583 template<>
2584 class QMetaTypeInterfaceWrapper<void>
2585 {
2586 public:
2587 static constexpr QMetaTypeInterface metaType =
2588 {
2589 0,
2590 0,
2591 0,
2592 0,
2593 BuiltinMetaType<void>::value,
2594 nullptr,
2595 "void",
2596 nullptr,
2597 nullptr,
2598 nullptr,
2599 nullptr,
2600 nullptr,
2601 nullptr,
2602 nullptr,
2603 nullptr,
2604 nullptr,
2605 nullptr
2606 };
2607 };
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619 #if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
2620
2621 #ifdef QT_NO_DATA_RELOCATION
2622 # define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name) \
2623 extern template class Q_CORE_EXPORT QMetaTypeForType<Name>;
2624 #else
2625 # define QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER(TypeName, Id, Name) \
2626 extern template class Q_CORE_EXPORT QMetaTypeForType<Name>; \
2627 extern template struct Q_CORE_EXPORT QMetaTypeInterfaceWrapper<Name>;
2628 #endif
2629
2630 QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2631 QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2632 QT_FOR_EACH_STATIC_CORE_CLASS(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2633 QT_FOR_EACH_STATIC_CORE_POINTER(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2634 QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER)
2635 #undef QT_METATYPE_DECLARE_EXTERN_TEMPLATE_ITER
2636 #endif
2637
2638 template<typename T>
2639 struct QRemovePointerLike
2640 {
2641 using type = std::remove_pointer_t<T>;
2642 };
2643
2644 #define Q_REMOVE_POINTER_LIKE_IMPL(Pointer) \
2645 template <typename T> \
2646 struct QRemovePointerLike<Pointer<T>> \
2647 { \
2648 using type = T; \
2649 };
2650
2651 QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_REMOVE_POINTER_LIKE_IMPL)
2652 #undef Q_REMOVE_POINTER_LIKE_IMPL
2653
2654 template<typename T>
2655 constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType()
2656 {
2657
2658 using Ty = typename MetatypeDecay<T>::type;
2659 return &QMetaTypeInterfaceWrapper<Ty>::metaType;
2660 }
2661
2662
2663
2664
2665
2666
2667 template<typename Unique, typename T>
2668 constexpr const QMetaTypeInterface *qTryMetaTypeInterfaceForType()
2669 {
2670 using Ty = typename MetatypeDecay<T>::type;
2671 using Tz = typename QRemovePointerLike<Ty>::type;
2672
2673 if constexpr (std::is_void_v<Tz>) {
2674
2675 return &QMetaTypeInterfaceWrapper<Ty>::metaType;
2676 } else if constexpr (std::is_void_v<Unique>) {
2677 checkTypeIsSuitableForMetaType<Ty>();
2678 return &QMetaTypeInterfaceWrapper<Ty>::metaType;
2679 } else if constexpr (std::is_reference_v<Tz>) {
2680 return nullptr;
2681 } else if constexpr (!is_complete<Tz, Unique>::value) {
2682 return nullptr;
2683 } else {
2684
2685 return &QMetaTypeInterfaceWrapper<Ty>::metaType;
2686 }
2687 }
2688
2689 }
2690
2691 template<typename T>
2692 constexpr QMetaType QMetaType::fromType()
2693 {
2694 QtPrivate::checkTypeIsSuitableForMetaType<T>();
2695 return QMetaType(QtPrivate::qMetaTypeInterfaceForType<T>());
2696 }
2697
2698 constexpr bool QMetaType::isValid(QT6_IMPL_NEW_OVERLOAD) const noexcept
2699 {
2700 return d_ptr;
2701 }
2702
2703 bool QMetaType::isRegistered(QT6_IMPL_NEW_OVERLOAD) const noexcept
2704 {
2705 return d_ptr && Q_LIKELY(d_ptr->typeId.loadRelaxed());
2706 }
2707
2708 constexpr qsizetype QMetaType::sizeOf() const
2709 {
2710 return d_ptr ? d_ptr->size : 0;
2711 }
2712
2713 constexpr qsizetype QMetaType::alignOf() const
2714 {
2715 return d_ptr ? d_ptr->alignment : 0;
2716 }
2717
2718 constexpr QMetaType::TypeFlags QMetaType::flags() const
2719 {
2720 return d_ptr ? TypeFlags(d_ptr->flags) : TypeFlags{};
2721 }
2722
2723 constexpr const QMetaObject *QMetaType::metaObject() const
2724 {
2725 return d_ptr && d_ptr->metaObjectFn ? d_ptr->metaObjectFn(d_ptr) : nullptr;
2726 }
2727
2728 constexpr const char *QMetaType::name() const
2729 {
2730 return d_ptr ? d_ptr->name : nullptr;
2731 }
2732
2733 inline size_t qHash(QMetaType type, size_t seed = 0)
2734 {
2735
2736
2737 return qHash(type.id(), seed);
2738 }
2739
2740 QT_END_NAMESPACE
2741
2742 QT_DECL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl,
2743 QPairVariantInterfaceImpl, Q_CORE_EXPORT)
2744
2745 #endif