Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qmetatype.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
3// Copyright (C) 2021 Intel Corporation.
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#include "qmetatype.h"
7#include "qmetatype_p.h"
8#include "qobjectdefs.h"
9#include "qdatetime.h"
10#include "qbytearray.h"
11#include "qreadwritelock.h"
12#include "qhash.h"
13#include "qmap.h"
14#include "qstring.h"
15#include "qstringlist.h"
16#include "qlist.h"
17#include "qlocale.h"
18#include "qdebug.h"
19#if QT_CONFIG(easingcurve)
20#include "qeasingcurve.h"
21#endif
22#include "quuid.h"
23
24#if QT_CONFIG(regularexpression)
25# include "qregularexpression.h"
26#endif
27
28#ifndef QT_BOOTSTRAPPED
29# include "qdatastream.h"
30
31# include "qbitarray.h"
32# include "qurl.h"
33# include "qvariant.h"
34# include "qjsonvalue.h"
35# include "qjsonobject.h"
36# include "qjsonarray.h"
37# include "qjsondocument.h"
38# include "qcborvalue.h"
39# include "qcborarray.h"
40# include "qcbormap.h"
41# include "qbytearraylist.h"
42# include "qmetaobject.h"
43# include "qsequentialiterable.h"
44# include "qassociativeiterable.h"
45# include "qobject.h"
46#endif
47
48#if QT_CONFIG(itemmodel)
49# include "qabstractitemmodel.h"
50#endif
51
52#ifndef QT_NO_GEOM_VARIANT
53# include "qsize.h"
54# include "qpoint.h"
55# include "qrect.h"
56# include "qline.h"
57#endif
58
59#include <new>
60#include <cstring>
61
63
64#define NS(x) QT_PREPEND_NAMESPACE(x)
65
67
69
70namespace {
71struct QMetaTypeDeleter
72{
74 void operator()(void *data)
75 {
76 if (iface->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
77 operator delete(data, std::align_val_t(iface->alignment));
78 } else {
79 operator delete(data);
80 }
81 }
82};
83
84struct QMetaTypeCustomRegistry
85{
86
87#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
88 QMetaTypeCustomRegistry()
89 {
90 /* qfloat16 was neither a builtin, nor unconditionally registered
91 in QtCore in Qt <= 6.2.
92 Inserting it as an alias ensures that a QMetaType::id call
93 will get the correct built-in type-id (the interface pointers
94 might still not match, but we already deal with that case.
95 */
96 aliases.insert("qfloat16", QtPrivate::qMetaTypeInterfaceForType<qfloat16>());
97 }
98#endif
99
101 QList<const QtPrivate::QMetaTypeInterface *> registry;
102 QHash<QByteArray, const QtPrivate::QMetaTypeInterface *> aliases;
103 // index of first empty (unregistered) type in registry, if any.
104 int firstEmpty = 0;
105
106 int registerCustomType(const QtPrivate::QMetaTypeInterface *cti)
107 {
108 // we got here because cti->typeId is 0, so this is a custom meta type
109 // (not read-only)
110 auto ti = const_cast<QtPrivate::QMetaTypeInterface *>(cti);
111 {
112 QWriteLocker l(&lock);
113 if (int id = ti->typeId.loadRelaxed())
114 return id;
116#ifndef QT_NO_QOBJECT
118#endif
119 (ti->name);
120 if (auto ti2 = aliases.value(name)) {
121 const auto id = ti2->typeId.loadRelaxed();
122 ti->typeId.storeRelaxed(id);
123 return id;
124 }
125 aliases[name] = ti;
126 int size = registry.size();
127 while (firstEmpty < size && registry[firstEmpty])
128 ++firstEmpty;
129 if (firstEmpty < size) {
130 registry[firstEmpty] = ti;
131 ++firstEmpty;
132 } else {
133 registry.append(ti);
134 firstEmpty = registry.size();
135 }
136 ti->typeId.storeRelaxed(firstEmpty + QMetaType::User);
137 }
138 if (ti->legacyRegisterOp)
139 ti->legacyRegisterOp();
140 return ti->typeId.loadRelaxed();
141 };
142
143 void unregisterDynamicType(int id)
144 {
145 if (!id)
146 return;
148 QWriteLocker l(&lock);
149 int idx = id - QMetaType::User - 1;
150 auto &ti = registry[idx];
151
152 // We must unregister all names.
153 aliases.removeIf([ti] (const auto &kv) { return kv.value() == ti; });
154
155 ti = nullptr;
156
157 firstEmpty = std::min(firstEmpty, idx);
158 }
159
160 const QtPrivate::QMetaTypeInterface *getCustomType(int id)
161 {
162 QReadLocker l(&lock);
163 return registry.value(id - QMetaType::User - 1);
164 }
165};
166
167Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry)
168
169} // namespace
170
171// used by QVariant::save(): returns the name used in the Q_DECLARE_METATYPE
172// macro (one of them, indetermine which one)
174{
175 const char *name = nullptr;
176 if (!customTypeRegistry.exists())
177 return name;
178 QMetaTypeCustomRegistry *r = &*customTypeRegistry;
179
180 QByteArrayView officialName(type_d->name);
181 QReadLocker l(&r->lock);
182 auto it = r->aliases.constBegin();
183 auto end = r->aliases.constEnd();
184 for ( ; it != end; ++it) {
185 if (it.value() != type_d)
186 continue;
187 if (it.key() == officialName)
188 continue; // skip the official name
189 name = it.key().constData();
190 ++it;
191 break;
192 }
193
194#ifndef QT_NO_DEBUG
195 QByteArrayList otherNames;
196 for ( ; it != end; ++it) {
197 if (it.value() == type_d && it.key() != officialName)
198 otherNames << it.key();
199 }
200 l.unlock();
201 if (!otherNames.isEmpty())
202 qWarning("QMetaType: type %s has more than one typedef alias: %s, %s",
203 type_d->name, name, otherNames.join(", ").constData());
204#endif
205
206 return name;
207}
208
516{
517 return d_ptr;
518}
519
531{
532 return d_ptr && d_ptr->typeId.loadRelaxed();
533}
534
555int QMetaType::registerHelper(const QtPrivate::QMetaTypeInterface *iface)
556{
558 auto reg = customTypeRegistry();
559 if (reg) {
560 return reg->registerCustomType(iface);
561 }
562 return 0;
563}
564
640void *QMetaType::create(const void *copy) const
641{
643 return nullptr;
644
645 std::unique_ptr<void, QMetaTypeDeleter> where(nullptr, {d_ptr});
646 if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
647 where.reset(operator new(d_ptr->size, std::align_val_t(d_ptr->alignment)));
648 else
649 where.reset(operator new(d_ptr->size));
650
651 QtMetaTypePrivate::construct(d_ptr, where.get(), copy);
652 return where.release();
653}
654
664void QMetaType::destroy(void *data) const
665{
666 if (data && isDestructible()) {
668 QMetaTypeDeleter{d_ptr}(data);
669 }
670}
671
698void *QMetaType::construct(void *where, const void *copy) const
699{
700 if (!where)
701 return nullptr;
703 return nullptr;
704
705 QtMetaTypePrivate::construct(d_ptr, where, copy);
706 return where;
707}
708
720void QMetaType::destruct(void *data) const
721{
722 if (data && isDestructible())
724}
725
726static QPartialOrdering threeWayCompare(const void *ptr1, const void *ptr2)
727{
728 std::less<const void *> less;
729 if (less(ptr1, ptr2))
731 if (less(ptr2, ptr1))
734}
735
762QPartialOrdering QMetaType::compare(const void *lhs, const void *rhs) const
763{
764 if (!lhs || !rhs)
766 if (d_ptr && d_ptr->flags & QMetaType::IsPointer)
767 return threeWayCompare(*reinterpret_cast<const void * const *>(lhs),
768 *reinterpret_cast<const void * const *>(rhs));
769 if (d_ptr && d_ptr->lessThan) {
770 if (d_ptr->equals && d_ptr->equals(d_ptr, lhs, rhs))
772 if (d_ptr->lessThan(d_ptr, lhs, rhs))
774 if (d_ptr->lessThan(d_ptr, rhs, lhs))
776 if (!d_ptr->equals)
778 }
780}
781
798bool QMetaType::equals(const void *lhs, const void *rhs) const
799{
800 if (!lhs || !rhs)
801 return false;
802 if (d_ptr) {
803 if (d_ptr->flags & QMetaType::IsPointer)
804 return *reinterpret_cast<const void * const *>(lhs) == *reinterpret_cast<const void * const *>(rhs);
805
806 if (d_ptr->equals)
807 return d_ptr->equals(d_ptr, lhs, rhs);
808 if (d_ptr->lessThan && !d_ptr->lessThan(d_ptr, lhs, rhs) && !d_ptr->lessThan(d_ptr, rhs, lhs))
809 return true;
810 }
811 return false;
812}
813
857{
858 return !isInterfaceFor<void>(iface) && QtMetaTypePrivate::isDefaultConstructible(iface);
859}
860
862{
863 return !isInterfaceFor<void>(iface) && QtMetaTypePrivate::isCopyConstructible(iface);
864}
865
867{
868 return !isInterfaceFor<void>(iface) && QtMetaTypePrivate::isMoveConstructible(iface);
869}
870
872{
873 return !isInterfaceFor<void>(iface) && QtMetaTypePrivate::isDestructible(iface);
874}
875
883{
884 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->equals != nullptr || d_ptr->lessThan != nullptr);
885}
886
894{
895 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->lessThan != nullptr);
896}
897
898
903{
904 const QtPrivate::QMetaTypeInterface *d_ptr = type.d_ptr;
905 if (!d_ptr)
906 return;
907
908 const int typeId = d_ptr->typeId.loadRelaxed();
909 if (typeId < QMetaType::User)
910 return;
911
912 // this is a custom meta type (not read-only)
913
914 if (auto reg = customTypeRegistry()) {
915 Q_ASSERT(reg->getCustomType(typeId) == d_ptr);
916 reg->unregisterDynamicType(typeId);
917 }
918
919 const_cast<QtPrivate::QMetaTypeInterface *>(d_ptr)->typeId.storeRelease(0);
920}
921
946bool QMetaTypeModuleHelper::convert(const void *, int, void *, int) const
947{
948 return false;
949}
950
951#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
952 { #RealName, sizeof(#RealName) - 1, MetaTypeId },
953
954#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr) \
955 { RealNameStr, sizeof(RealNameStr) - 1, QMetaType::MetaTypeName },
956
957
958
959static const struct { const char * typeName; int typeNameLength; int type; } types[] = {
963 {nullptr, 0, QMetaType::UnknownType}
965
966// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class
967static constexpr struct : QMetaTypeModuleHelper
968{
969 template<typename T, typename LiteralWrapper =
970 std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView, const char *>>
971 static inline bool convertToBool(const T &source)
972 {
973 T str = source.toLower();
974 return !(str.isEmpty() || str == LiteralWrapper("0") || str == LiteralWrapper("false"));
975 }
976
977 const QtPrivate::QMetaTypeInterface *interfaceForType(int type) const override {
978 switch (type) {
984 default:
985 return nullptr;
986 }
987 }
988
989 bool convert(const void *from, int fromTypeId, void *to, int toTypeId) const override
990 {
991 Q_ASSERT(fromTypeId != toTypeId);
992
993 // canConvert calls with two nullptr
994 bool onlyCheck = (from == nullptr && to == nullptr);
995
996 // other callers must provide two valid pointers
997 Q_ASSERT(onlyCheck || (bool(from) && bool(to)));
998
999 using Char = char;
1000 using SChar = signed char;
1001 using UChar = unsigned char;
1002 using Short = short;
1003 using UShort = unsigned short;
1004 using Int = int;
1005 using UInt = unsigned int;
1006 using Long = long;
1007 using LongLong = qlonglong;
1008 using ULong = unsigned long;
1009 using ULongLong = qulonglong;
1010 using Float = float;
1011 using Double = double;
1012 using Bool = bool;
1013 using Nullptr = std::nullptr_t;
1014 using Char16 = char16_t;
1015 using Char32 = char32_t;
1016
1017#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From) \
1018 QMETATYPE_CONVERTER(To, From, result = double(source); return true;)
1019#define QMETATYPE_CONVERTER_ASSIGN_NUMBER(To, From) \
1020 QMETATYPE_CONVERTER(To, From, result = To::number(source); return true;)
1021#ifndef QT_BOOTSTRAPPED
1022#define CONVERT_CBOR_AND_JSON(To) \
1023 QMETATYPE_CONVERTER(To, QCborValue, \
1024 if constexpr(std::is_same_v<To, Bool>) { \
1025 if (!source.isBool()) \
1026 return false; \
1027 result = source.toBool(); \
1028 } else { \
1029 if (!source.isInteger() && !source.isDouble()) \
1030 return false; \
1031 if constexpr(std::is_integral_v<To>) \
1032 result = source.toInteger(); \
1033 else \
1034 result = source.toDouble(); \
1035 } \
1036 return true; \
1037 ); \
1038 QMETATYPE_CONVERTER(To, QJsonValue, \
1039 if constexpr(std::is_same_v<To, Bool>) { \
1040 if (!source.isBool()) \
1041 return false; \
1042 result = source.toBool(); \
1043 } else { \
1044 if (!source.isDouble()) \
1045 return false; \
1046 if constexpr(std::is_integral_v<To>) \
1047 result = source.toInteger(); \
1048 else \
1049 result = source.toDouble(); \
1050 } \
1051 return true; \
1052 )
1053#else
1054#define CONVERT_CBOR_AND_JSON(To)
1055#endif
1056
1057#define INTEGRAL_CONVERTER(To) \
1058 QMETATYPE_CONVERTER_ASSIGN(To, Bool); \
1059 QMETATYPE_CONVERTER_ASSIGN(To, Char); \
1060 QMETATYPE_CONVERTER_ASSIGN(To, UChar); \
1061 QMETATYPE_CONVERTER_ASSIGN(To, SChar); \
1062 QMETATYPE_CONVERTER_ASSIGN(To, Short); \
1063 QMETATYPE_CONVERTER_ASSIGN(To, UShort); \
1064 QMETATYPE_CONVERTER_ASSIGN(To, Int); \
1065 QMETATYPE_CONVERTER_ASSIGN(To, UInt); \
1066 QMETATYPE_CONVERTER_ASSIGN(To, Long); \
1067 QMETATYPE_CONVERTER_ASSIGN(To, ULong); \
1068 QMETATYPE_CONVERTER_ASSIGN(To, LongLong); \
1069 QMETATYPE_CONVERTER_ASSIGN(To, ULongLong); \
1070 QMETATYPE_CONVERTER(To, Float, result = qRound64(source); return true;); \
1071 QMETATYPE_CONVERTER(To, Double, result = qRound64(source); return true;); \
1072 QMETATYPE_CONVERTER(To, QChar, result = source.unicode(); return true;); \
1073 QMETATYPE_CONVERTER(To, QString, \
1074 bool ok = false; \
1075 if constexpr(std::is_same_v<To, bool>) \
1076 result = (ok = true, convertToBool(source)); \
1077 else if constexpr(std::is_signed_v<To>) \
1078 result = To(source.toLongLong(&ok)); \
1079 else \
1080 result = To(source.toULongLong(&ok)); \
1081 return ok; \
1082 ); \
1083 QMETATYPE_CONVERTER(To, QByteArray, \
1084 bool ok = false; \
1085 if constexpr(std::is_same_v<To, bool>) \
1086 result = (ok = true, convertToBool(source)); \
1087 else if constexpr(std::is_signed_v<To>) \
1088 result = To(source.toLongLong(&ok)); \
1089 else \
1090 result = To(source.toULongLong(&ok)); \
1091 return ok; \
1092 ); \
1093 CONVERT_CBOR_AND_JSON(To)
1094
1095#define FLOAT_CONVERTER(To) \
1096 QMETATYPE_CONVERTER_ASSIGN(To, Bool); \
1097 QMETATYPE_CONVERTER_ASSIGN(To, Char); \
1098 QMETATYPE_CONVERTER_ASSIGN(To, UChar); \
1099 QMETATYPE_CONVERTER_ASSIGN(To, SChar); \
1100 QMETATYPE_CONVERTER_ASSIGN(To, Short); \
1101 QMETATYPE_CONVERTER_ASSIGN(To, UShort); \
1102 QMETATYPE_CONVERTER_ASSIGN(To, Int); \
1103 QMETATYPE_CONVERTER_ASSIGN(To, UInt); \
1104 QMETATYPE_CONVERTER_ASSIGN(To, Long); \
1105 QMETATYPE_CONVERTER_ASSIGN(To, ULong); \
1106 QMETATYPE_CONVERTER_ASSIGN(To, LongLong); \
1107 QMETATYPE_CONVERTER_ASSIGN(To, ULongLong); \
1108 QMETATYPE_CONVERTER_ASSIGN(To, Float); \
1109 QMETATYPE_CONVERTER_ASSIGN(To, Double); \
1110 QMETATYPE_CONVERTER(To, QString, \
1111 bool ok = false; \
1112 result = source.toDouble(&ok); \
1113 return ok; \
1114 ); \
1115 QMETATYPE_CONVERTER(To, QByteArray, \
1116 bool ok = false; \
1117 result = source.toDouble(&ok); \
1118 return ok; \
1119 ); \
1120 CONVERT_CBOR_AND_JSON(To)
1121
1122 switch (makePair(toTypeId, fromTypeId)) {
1123
1124 // integral conversions
1125 INTEGRAL_CONVERTER(Bool);
1127 INTEGRAL_CONVERTER(UChar);
1128 INTEGRAL_CONVERTER(SChar);
1129 INTEGRAL_CONVERTER(Short);
1130 INTEGRAL_CONVERTER(UShort);
1131 INTEGRAL_CONVERTER(Int);
1132 INTEGRAL_CONVERTER(UInt);
1133 INTEGRAL_CONVERTER(Long);
1134 INTEGRAL_CONVERTER(ULong);
1135 INTEGRAL_CONVERTER(LongLong);
1136 INTEGRAL_CONVERTER(ULongLong);
1137 FLOAT_CONVERTER(Float);
1138 FLOAT_CONVERTER(Double);
1139
1140#ifndef QT_BOOTSTRAPPED
1143 if (source.isUrl()) {
1144 result = source.toUrl();
1145 return true;
1146 }
1147 return false;
1148 );
1149#endif
1150#if QT_CONFIG(itemmodel)
1153#endif // QT_CONFIG(itemmodel)
1154
1155 // QChar methods
1156#define QMETATYPE_CONVERTER_ASSIGN_QCHAR(From) \
1157 QMETATYPE_CONVERTER(QChar, From, result = QChar::fromUcs2(source); return true;)
1171
1172 QMETATYPE_CONVERTER(Char16, QChar, result = source.unicode(); return true;)
1173
1174 // conversions to QString
1177 result = source ? QStringLiteral("true") : QStringLiteral("false");
1178 return true;
1179 );
1190 return true;
1191 );
1194 return true;
1195 );
1198 return true;
1199 );
1201 char s = source;
1203 return true;
1204 );
1206 char s = source;
1208 return true;
1209 );
1211 result = QChar(source);
1212 return true;
1213 );
1215 result = QChar::fromUcs4(source).operator QStringView().toString();
1216 return true;
1217 );
1218#if QT_CONFIG(datestring)
1219 QMETATYPE_CONVERTER(QString, QDate, result = source.toString(Qt::ISODate); return true;);
1220 QMETATYPE_CONVERTER(QString, QTime, result = source.toString(Qt::ISODateWithMs); return true;);
1222#endif
1225 return (source.size() == 1) ? (result = source.at(0), true) : false;
1226 );
1227#ifndef QT_BOOTSTRAPPED
1230 if (source.isString() || source.isNull()) {
1231 result = source.toString();
1232 return true;
1233 }
1234 return false;
1235 );
1236#endif
1237 QMETATYPE_CONVERTER(QString, Nullptr, Q_UNUSED(source); result = QString(); return true;);
1238
1239 // QByteArray
1242 result = source ? "true" : "false";
1243 return true;
1244 );
1246 QMETATYPE_CONVERTER(QByteArray, SChar, result = QByteArray(source, 1); return true;);
1247 QMETATYPE_CONVERTER(QByteArray, UChar, result = QByteArray(source, 1); return true;);
1258 return true;
1259 );
1262 return true;
1263 );
1264 QMETATYPE_CONVERTER(QByteArray, Nullptr, Q_UNUSED(source); result = QByteArray(); return true;);
1265
1267 QMETATYPE_CONVERTER(QUuid, QString, result = QUuid(source); return true;);
1270
1271#ifndef QT_NO_GEOM_VARIANT
1272 QMETATYPE_CONVERTER(QSize, QSizeF, result = source.toSize(); return true;);
1274 QMETATYPE_CONVERTER(QLine, QLineF, result = source.toLine(); return true;);
1276 QMETATYPE_CONVERTER(QRect, QRectF, result = source.toRect(); return true;);
1280#endif
1281
1283
1284#ifndef QT_NO_VARIANT
1286 result.reserve(source.size());
1287 for (const auto &v: source)
1289 return true;
1290 );
1292 result.reserve(source.size());
1293 for (const auto &v: source)
1295 return true;
1296 );
1297
1299 result.reserve(source.size());
1300 for (const auto &v: source)
1302 return true;
1303 );
1305 result.reserve(source.size());
1306 for (const auto &v: source)
1308 return true;
1309 );
1310
1312 for (auto it = source.begin(); it != source.end(); ++it)
1313 result.insert(it.key(), it.value());
1314 return true;
1315 );
1317 for (auto it = source.begin(); it != source.end(); ++it)
1318 result.insert(it.key(), it.value());
1319 return true;
1320 );
1321#endif // !QT_NO_VARIANT
1322#ifndef QT_BOOTSTRAPPED
1325 if (source.isContainer() || source.isTag())
1326 return false;
1327 result = source.toVariant().toString();
1328 return true;
1329 );
1332 if (source.isByteArray()) {
1333 result = source.toByteArray();
1334 return true;
1335 }
1336 return false;
1337 );
1340 if (!source.isUuid())
1341 return false;
1342 result = source.toUuid();
1343 return true;
1344 );
1347 if (!source.isArray())
1348 return false;
1349 result = source.toArray().toVariantList();
1350 return true;
1351 );
1354 if (!source.isMap())
1355 return false;
1356 result = source.toMap().toVariantMap();
1357 return true;
1358 );
1361 if (!source.isMap())
1362 return false;
1363 result = source.toMap().toVariantHash();
1364 return true;
1365 );
1366#if QT_CONFIG(regularexpression)
1369 if (!source.isRegularExpression())
1370 return false;
1371 result = source.toRegularExpression();
1372 return true;
1373 );
1374#endif
1375
1379 return true;
1380 );
1382 result = nullptr;
1383 return source.isNull();
1384 );
1388 QMETATYPE_CONVERTER(QCborValue, ULong, result = qlonglong(source); return true;);
1389 QMETATYPE_CONVERTER(QCborValue, Long, result = qlonglong(source); return true;);
1391 QMETATYPE_CONVERTER(QCborValue, ULongLong, result = qlonglong(source); return true;);
1401 return true;
1402 );
1404 result = QCborValue(source.startOfDay());
1405 return true;
1406 );
1410 return true;
1411 );
1414 return true;
1415 );
1418 return true;
1419 );
1421 QJsonDocument doc = source;
1422 if (doc.isArray())
1423 result = QCborArray::fromJsonArray(doc.array());
1424 else
1425 result = QCborMap::fromJsonObject(doc.object());
1426 return true;
1427 );
1430
1433 if (source.isDateTime()) {
1434 result = source.toDateTime();
1435 return true;
1436 }
1437 return false;
1438 );
1439
1442 if (source.isSimpleType()) {
1443 result = source.toSimpleType();
1444 return true;
1445 }
1446 return false;
1447 );
1448
1456
1458 if (!source.isArray())
1459 return false;
1460 result = source.toArray();
1461 return true;
1462 );
1464 if (!source.isArray())
1465 return false;
1467 return true;
1468 );
1470 if (!source.isArray())
1471 return false;
1473 return true;
1474 );
1477 return true;
1478 );
1480 if (!source.isMap())
1481 return false;
1482 result = source.toMap();
1483 return true;
1484 );
1486 if (source.isArray())
1487 return false;
1489 return true;
1490 );
1492 if (!source.isObject())
1493 return false;
1495 return true;
1496 );
1499 return true;
1500 );
1501
1502
1504 if (!source.isArray())
1505 return false;
1506 result = source.toArray().toVariantList();
1507 return true;
1508 );
1511 if (!source.isObject())
1512 return false;
1513 result = source.toObject().toVariantMap();
1514 return true;
1515 );
1518 if (!source.isObject())
1519 return false;
1520 result = source.toObject().toVariantHash();
1521 return true;
1522 );
1524
1525
1529 if (!source.isArray())
1530 return false;
1531 result = source.toArray();
1532 return true;
1533 );
1535 if (!source.isArray())
1536 return false;
1537 result = source.array();
1538 return true;
1539 );
1541 if (!source.isArray())
1542 return false;
1543 result = source.toArray().toJsonArray();
1544 return true;
1545 );
1550 if (!source.isObject())
1551 return false;
1552 result = source.toObject();
1553 return true;
1554 );
1556 if (source.isArray())
1557 return false;
1558 result = source.object();
1559 return true;
1560 );
1562 if (!source.isMap())
1563 return false;
1564 result = source.toMap().toJsonObject();
1565 return true;
1566 );
1568
1572 return true;
1573 );
1575 result = nullptr;
1576 return source.isNull();
1577 );
1580 return true;);
1597 return true;
1598 );
1601 return true;
1602 );
1605 return true;
1606 );
1609 return true;
1610 );
1612 result = source;
1613 return true;
1614 );
1616 result = source;
1617 return true;
1618 );
1620 QJsonDocument doc = source;
1621 result = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1622 return true;
1623 );
1626 return true;
1627 );
1630 return true;
1631 );
1634 return true;
1635 );
1636
1637#endif
1638
1639 QMETATYPE_CONVERTER(QDate, QDateTime, result = source.date(); return true;);
1640 QMETATYPE_CONVERTER(QTime, QDateTime, result = source.time(); return true;);
1642#if QT_CONFIG(datestring)
1644 result = QDate::fromString(source, Qt::ISODate);
1645 return result.isValid();
1646 );
1648 result = QTime::fromString(source, Qt::ISODate);
1649 return result.isValid();
1650 );
1652 result = QDateTime::fromString(source, Qt::ISODate);
1653 return result.isValid();
1654 );
1655#endif
1656
1657 }
1658 return false;
1659 }
1661
1662Q_CONSTINIT Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper = nullptr;
1663Q_CONSTINIT Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeWidgetsHelper = nullptr;
1664
1666{
1668 return &metatypeHelper;
1670 return qMetaTypeGuiHelper;
1673 return nullptr;
1674}
1675
1676template<typename T, typename Key>
1678{
1679public:
1681 {
1682 const QWriteLocker locker(&lock);
1683 map.clear();
1684 }
1685
1686 bool contains(Key k) const
1687 {
1688 const QReadLocker locker(&lock);
1689 return map.contains(k);
1690 }
1691
1692 bool insertIfNotContains(Key k, const T &f)
1693 {
1694 const QWriteLocker locker(&lock);
1695 const qsizetype oldSize = map.size();
1696 auto &e = map[k];
1697 if (map.size() == oldSize) // already present
1698 return false;
1699 e = f;
1700 return true;
1701 }
1702
1703 const T *function(Key k) const
1704 {
1705 const QReadLocker locker(&lock);
1706 auto it = map.find(k);
1707 return it == map.end() ? nullptr : std::addressof(*it);
1708 }
1709
1710 void remove(int from, int to)
1711 {
1712 const Key k(from, to);
1713 const QWriteLocker locker(&lock);
1714 map.remove(k);
1715 }
1716private:
1717 mutable QReadWriteLock lock;
1718 QHash<Key, T> map;
1719};
1720
1722 = QMetaTypeFunctionRegistry<QMetaType::ConverterFunction, std::pair<int,int>>;
1723
1724Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
1727 = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, std::pair<int,int>>;
1728Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
1729
1781bool QMetaType::registerConverterFunction(const ConverterFunction &f, QMetaType from, QMetaType to)
1782{
1783 if (!customTypesConversionRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1784 qWarning("Type conversion already registered from type %s to type %s",
1785 from.name(), to.name());
1786 return false;
1787 }
1788 return true;
1789}
1790
1814bool QMetaType::registerMutableViewFunction(const MutableViewFunction &f, QMetaType from, QMetaType to)
1815{
1816 if (!customTypesMutableViewRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1817 qWarning("Mutable view on type already registered from type %s to type %s",
1818 from.name(), to.name());
1819 return false;
1820 }
1821 return true;
1822}
1823
1828{
1829 if (customTypesMutableViewRegistry.isDestroyed())
1830 return;
1831 customTypesMutableViewRegistry()->remove(from.id(), to.id());
1832}
1833
1840{
1841 if (customTypesConversionRegistry.isDestroyed())
1842 return;
1843 customTypesConversionRegistry()->remove(from.id(), to.id());
1844}
1845
1846#ifndef QT_NO_DEBUG_STREAM
1847
1854{
1855 const QDebugStateSaver saver(d);
1856 return d.nospace() << "QMetaType(" << m.name() << ")";
1857}
1858
1864bool QMetaType::debugStream(QDebug& dbg, const void *rhs)
1865{
1866 if (d_ptr && d_ptr->flags & QMetaType::IsPointer) {
1867 dbg << *reinterpret_cast<const void * const *>(rhs);
1868 return true;
1869 }
1870 if (d_ptr && d_ptr->debugStream) {
1871 d_ptr->debugStream(d_ptr, dbg, rhs);
1872 return true;
1873 }
1874 return false;
1875}
1876
1907{
1908 return d_ptr && d_ptr->debugStream != nullptr;
1909}
1910#endif
1911
1912#ifndef QT_NO_QOBJECT
1918{
1919 if (t.flags() & QMetaType::IsEnumeration) {
1920 if (const QMetaObject *metaObject = t.metaObject()) {
1921 QByteArrayView qflagsNamePrefix = "QFlags<";
1922 QByteArray enumName = t.name();
1923 if (enumName.endsWith('>') && enumName.startsWith(qflagsNamePrefix)) {
1924 // extract the template argument
1925 enumName.chop(1);
1926 enumName = enumName.sliced(qflagsNamePrefix.size());
1927 }
1928 if (qsizetype lastColon = enumName.lastIndexOf(':'); lastColon != -1)
1929 enumName = enumName.sliced(lastColon + 1);
1930 return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
1931 }
1932 }
1933 return QMetaEnum();
1934}
1935#endif
1936
1937static bool convertFromEnum(QMetaType fromType, const void *from, QMetaType toType, void *to)
1938{
1939 qlonglong ll;
1940 if (fromType.flags() & QMetaType::IsUnsignedEnumeration) {
1941 qulonglong ull;
1942 switch (fromType.sizeOf()) {
1943 case 1:
1944 ull = *static_cast<const unsigned char *>(from);
1945 break;
1946 case 2:
1947 ull = *static_cast<const unsigned short *>(from);
1948 break;
1949 case 4:
1950 ull = *static_cast<const unsigned int *>(from);
1951 break;
1952 case 8:
1953 ull = *static_cast<const quint64 *>(from);
1954 break;
1955 default:
1956 Q_UNREACHABLE();
1957 }
1958 if (toType.id() == QMetaType::ULongLong) {
1959 *static_cast<qulonglong *>(to) = ull;
1960 return true;
1961 }
1962 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
1963 return QMetaType::convert(QMetaType::fromType<qulonglong>(), &ull, toType, to);
1964 ll = qlonglong(ull);
1965 } else {
1966 switch (fromType.sizeOf()) {
1967 case 1:
1968 ll = *static_cast<const signed char *>(from);
1969 break;
1970 case 2:
1971 ll = *static_cast<const short *>(from);
1972 break;
1973 case 4:
1974 ll = *static_cast<const int *>(from);
1975 break;
1976 case 8:
1977 ll = *static_cast<const qint64 *>(from);
1978 break;
1979 default:
1980 Q_UNREACHABLE();
1981 }
1982 if (toType.id() == QMetaType::LongLong) {
1983 *static_cast<qlonglong *>(to) = ll;
1984 return true;
1985 }
1986 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
1987 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
1988 }
1989#ifndef QT_NO_QOBJECT
1990 QMetaEnum en = metaEnumFromType(fromType);
1991 if (en.isValid()) {
1992 if (en.isFlag()) {
1993 const QByteArray keys = en.valueToKeys(static_cast<int>(ll));
1994 if (toType.id() == QMetaType::QString)
1995 *static_cast<QString *>(to) = QString::fromUtf8(keys);
1996 else
1997 *static_cast<QByteArray *>(to) = keys;
1998 } else {
1999 const char *key = en.valueToKey(static_cast<int>(ll));
2000 if (toType.id() == QMetaType::QString)
2001 *static_cast<QString *>(to) = QString::fromUtf8(key);
2002 else
2003 *static_cast<QByteArray *>(to) = key;
2004 }
2005 return true;
2006 }
2007#endif
2008 if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray)
2009 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2010 return false;
2012
2013static bool convertToEnum(QMetaType fromType, const void *from, QMetaType toType, void *to)
2014{
2015 int fromTypeId = fromType.id();
2016 qlonglong value = -1;
2017 bool ok = false;
2018#ifndef QT_NO_QOBJECT
2019 if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) {
2020 QMetaEnum en = metaEnumFromType(toType);
2021 if (en.isValid()) {
2022 QByteArray keys = (fromTypeId == QMetaType::QString)
2023 ? static_cast<const QString *>(from)->toUtf8()
2024 : *static_cast<const QByteArray *>(from);
2025 value = en.keysToValue(keys.constData(), &ok);
2026 }
2027 }
2028#endif
2029 if (!ok) {
2030 if (fromTypeId == QMetaType::LongLong) {
2031 value = *static_cast<const qlonglong *>(from);
2032 ok = true;
2033 } else {
2034 ok = QMetaType::convert(fromType, from, QMetaType::fromType<qlonglong>(), &value);
2035 }
2036 }
2037
2038 if (!ok)
2039 return false;
2040
2041 switch (toType.sizeOf()) {
2042 case 1:
2043 *static_cast<signed char *>(to) = value;
2044 return true;
2045 case 2:
2046 *static_cast<qint16 *>(to) = value;
2047 return true;
2048 case 4:
2049 *static_cast<qint32 *>(to) = value;
2050 return true;
2051 case 8:
2052 *static_cast<qint64 *>(to) = value;
2053 return true;
2054 default:
2055 Q_UNREACHABLE_RETURN(false);
2056 }
2057}
2059#ifndef QT_BOOTSTRAPPED
2060static bool convertIterableToVariantList(QMetaType fromType, const void *from, void *to)
2061{
2063 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QSequentialIterable>(), &list))
2064 return false;
2065
2066 QVariantList &l = *static_cast<QVariantList *>(to);
2067 l.clear();
2068 l.reserve(list.size());
2069 auto end = list.end();
2070 for (auto it = list.begin(); it != end; ++it)
2071 l << *it;
2072 return true;
2074
2075static bool convertIterableToVariantMap(QMetaType fromType, const void *from, void *to)
2076{
2078 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QAssociativeIterable>(), &map))
2079 return false;
2080
2081 QVariantMap &h = *static_cast<QVariantMap *>(to);
2082 h.clear();
2083 auto end = map.end();
2084 for (auto it = map.begin(); it != end; ++it)
2085 h.insert(it.key().toString(), it.value());
2086 return true;
2088
2089static bool convertIterableToVariantHash(QMetaType fromType, const void *from, void *to)
2090{
2092 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QAssociativeIterable>(), &map))
2093 return false;
2094
2095 QVariantHash &h = *static_cast<QVariantHash *>(to);
2096 h.clear();
2097 h.reserve(map.size());
2098 auto end = map.end();
2099 for (auto it = map.begin(); it != end; ++it)
2100 h.insert(it.key().toString(), it.value());
2101 return true;
2103
2104static bool convertIterableToVariantPair(QMetaType fromType, const void *from, void *to)
2105{
2106 const int targetId = qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2107 const auto f = customTypesConversionRegistry()->function({fromType.id(), targetId});
2108
2109 if (!f)
2110 return false;
2111
2113 (*f)(from, &pi);
2114
2115 QVariant v1(pi._metaType_first);
2116 void *dataPtr;
2117 if (pi._metaType_first == QMetaType::fromType<QVariant>())
2118 dataPtr = &v1;
2119 else
2120 dataPtr = v1.data();
2121 pi.first(dataPtr);
2122
2123 QVariant v2(pi._metaType_second);
2124 if (pi._metaType_second == QMetaType::fromType<QVariant>())
2125 dataPtr = &v2;
2126 else
2127 dataPtr = v2.data();
2128 pi.second(dataPtr);
2129
2130 *static_cast<QVariantPair *>(to) = QVariantPair(v1, v2);
2131 return true;
2133
2134static bool convertToSequentialIterable(QMetaType fromType, const void *from, void *to)
2135{
2136 using namespace QtMetaTypePrivate;
2137 const int fromTypeId = fromType.id();
2138
2139 QSequentialIterable &i = *static_cast<QSequentialIterable *>(to);
2140 switch (fromTypeId) {
2141 case QMetaType::QVariantList:
2142 i = QSequentialIterable(reinterpret_cast<const QVariantList *>(from));
2143 return true;
2144 case QMetaType::QStringList:
2145 i = QSequentialIterable(reinterpret_cast<const QStringList *>(from));
2146 return true;
2147 case QMetaType::QByteArrayList:
2148 i = QSequentialIterable(reinterpret_cast<const QByteArrayList *>(from));
2149 return true;
2150 case QMetaType::QString:
2151 i = QSequentialIterable(reinterpret_cast<const QString *>(from));
2152 return true;
2153 case QMetaType::QByteArray:
2154 i = QSequentialIterable(reinterpret_cast<const QByteArray *>(from));
2155 return true;
2156 default: {
2159 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &impl)) {
2160 i = std::move(impl);
2161 return true;
2162 }
2163 }
2164 }
2165
2166 return false;
2168
2169static bool canConvertToSequentialIterable(QMetaType fromType)
2170{
2171 switch (fromType.id()) {
2172 case QMetaType::QVariantList:
2173 case QMetaType::QStringList:
2174 case QMetaType::QByteArrayList:
2175 case QMetaType::QString:
2176 case QMetaType::QByteArray:
2177 return true;
2178 default:
2179 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2180 }
2182
2184{
2185 switch (fromType.id()) {
2186 case QMetaType::QVariantList:
2187 case QMetaType::QStringList:
2188 case QMetaType::QByteArrayList:
2189 case QMetaType::QString:
2190 case QMetaType::QByteArray:
2191 return true;
2192 default:
2193 return QMetaType::canView(
2194 fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2195 }
2197
2198static bool viewAsSequentialIterable(QMetaType fromType, void *from, void *to)
2199{
2200 using namespace QtMetaTypePrivate;
2201 const int fromTypeId = fromType.id();
2202
2203 QSequentialIterable &i = *static_cast<QSequentialIterable *>(to);
2204 switch (fromTypeId) {
2205 case QMetaType::QVariantList:
2206 i = QSequentialIterable(reinterpret_cast<QVariantList *>(from));
2207 return true;
2208 case QMetaType::QStringList:
2209 i = QSequentialIterable(reinterpret_cast<QStringList *>(from));
2210 return true;
2211 case QMetaType::QByteArrayList:
2212 i = QSequentialIterable(reinterpret_cast<QByteArrayList *>(from));
2213 return true;
2214 case QMetaType::QString:
2215 i = QSequentialIterable(reinterpret_cast<QString *>(from));
2216 return true;
2217 case QMetaType::QByteArray:
2218 i = QSequentialIterable(reinterpret_cast<QByteArray *>(from));
2219 return true;
2220 default: {
2221 QIterable<QMetaSequence> j(QMetaSequence(), nullptr);
2222 if (QMetaType::view(
2223 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2224 i = std::move(j);
2225 return true;
2226 }
2227 }
2228 }
2229
2230 return false;
2232
2233static bool convertToAssociativeIterable(QMetaType fromType, const void *from, void *to)
2234{
2235 using namespace QtMetaTypePrivate;
2236
2237 QAssociativeIterable &i = *static_cast<QAssociativeIterable *>(to);
2238 if (fromType.id() == QMetaType::QVariantMap) {
2239 i = QAssociativeIterable(reinterpret_cast<const QVariantMap *>(from));
2240 return true;
2241 }
2242 if (fromType.id() == QMetaType::QVariantHash) {
2243 i = QAssociativeIterable(reinterpret_cast<const QVariantHash *>(from));
2244 return true;
2245 }
2246
2249 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &impl)) {
2250 i = std::move(impl);
2251 return true;
2252 }
2253
2254 return false;
2256
2257static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
2258{
2259 if ((fromType.flags() & QMetaType::IsPointer) != (toType.flags() & QMetaType::IsPointer))
2260 return false; // Can not convert between pointer and value
2261
2262 const QMetaObject *f = fromType.metaObject();
2263 const QMetaObject *t = toType.metaObject();
2264 if (f && t) {
2265 return f->inherits(t) || (t->inherits(f));
2266 }
2267 return false;
2269
2270static bool canConvertToAssociativeIterable(QMetaType fromType)
2271{
2272 switch (fromType.id()) {
2273 case QMetaType::QVariantMap:
2274 case QMetaType::QVariantHash:
2275 return true;
2276 default:
2277 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2278 }
2280
2282{
2283 switch (fromType.id()) {
2284 case QMetaType::QVariantMap:
2285 case QMetaType::QVariantHash:
2286 return true;
2287 default:
2288 return QMetaType::canView(
2289 fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2290 }
2292
2293static bool viewAsAssociativeIterable(QMetaType fromType, void *from, void *to)
2294{
2295 using namespace QtMetaTypePrivate;
2296 int fromTypeId = fromType.id();
2297
2298 QAssociativeIterable &i = *static_cast<QAssociativeIterable *>(to);
2299 if (fromTypeId == QMetaType::QVariantMap) {
2300 i = QAssociativeIterable(reinterpret_cast<QVariantMap *>(from));
2301 return true;
2302 }
2303 if (fromTypeId == QMetaType::QVariantHash) {
2304 i = QAssociativeIterable(reinterpret_cast<QVariantHash *>(from));
2305 return true;
2306 }
2307
2308 QIterable<QMetaAssociation> j(QMetaAssociation(), nullptr);
2309 if (QMetaType::view(
2310 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2311 i = std::move(j);
2312 return true;
2313 }
2314
2315 return false;
2317
2318static bool convertMetaObject(QMetaType fromType, const void *from, QMetaType toType, void *to)
2319{
2320 // handle QObject conversion
2321 if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
2322 QObject *fromObject = *static_cast<QObject * const *>(from);
2323 // use dynamic metatype of from if possible
2324 if (fromObject && fromObject->metaObject()->inherits(toType.metaObject())) {
2325 *static_cast<QObject **>(to) = toType.metaObject()->cast(fromObject);
2326 return true;
2327 } else if (!fromObject && fromType.metaObject()) {
2328 // if fromObject is null, use static fromType to check if conversion works
2329 *static_cast<void **>(to) = nullptr;
2330 return fromType.metaObject()->inherits(toType.metaObject());
2331 }
2332 } else if ((fromType.flags() & QMetaType::IsPointer) == (toType.flags() & QMetaType::IsPointer)) {
2333 // fromType and toType are of same 'pointedness'
2334 const QMetaObject *f = fromType.metaObject();
2335 const QMetaObject *t = toType.metaObject();
2336 if (f && t && f->inherits(t)) {
2337 toType.destruct(to);
2338 toType.construct(to, from);
2339 return true;
2340 }
2341 }
2342 return false;
2343}
2344#endif // !QT_BOOTSTRAPPED
2345
2366bool QMetaType::convert(QMetaType fromType, const void *from, QMetaType toType, void *to)
2367{
2368 if (!fromType.isValid() || !toType.isValid())
2369 return false;
2370
2371 if (fromType == toType) {
2372 // just make a copy
2373 fromType.destruct(to);
2374 fromType.construct(to, from);
2375 return true;
2376 }
2377
2378 int fromTypeId = fromType.id();
2379 int toTypeId = toType.id();
2380
2381 if (auto moduleHelper = qModuleHelperForType(qMax(fromTypeId, toTypeId))) {
2382 if (moduleHelper->convert(from, fromTypeId, to, toTypeId))
2383 return true;
2384 }
2385 const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId});
2386 if (f)
2387 return (*f)(from, to);
2388
2389 if (fromType.flags() & QMetaType::IsEnumeration)
2390 return convertFromEnum(fromType, from, toType, to);
2391 if (toType.flags() & QMetaType::IsEnumeration)
2392 return convertToEnum(fromType, from, toType, to);
2393 if (toTypeId == Nullptr) {
2394 *static_cast<std::nullptr_t *>(to) = nullptr;
2395 if (fromType.flags() & QMetaType::IsPointer) {
2396 if (*static_cast<const void * const *>(from) == nullptr)
2397 return true;
2398 }
2399 }
2400
2401#ifndef QT_BOOTSTRAPPED
2402# ifndef QT_NO_VARIANT
2403 if (toTypeId == QVariantPair && convertIterableToVariantPair(fromType, from, to))
2404 return true;
2405
2406 // handle iterables
2407 if (toTypeId == QVariantList && convertIterableToVariantList(fromType, from, to))
2408 return true;
2409
2410 if (toTypeId == QVariantMap && convertIterableToVariantMap(fromType, from, to))
2411 return true;
2412
2413 if (toTypeId == QVariantHash && convertIterableToVariantHash(fromType, from, to))
2414 return true;
2415# endif
2416
2417 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2418 return convertToSequentialIterable(fromType, from, to);
2419
2420 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2421 return convertToAssociativeIterable(fromType, from, to);
2422
2423 return convertMetaObject(fromType, from, toType, to);
2424#else
2425 return false;
2426#endif
2427}
2428
2434bool QMetaType::view(QMetaType fromType, void *from, QMetaType toType, void *to)
2435{
2436 if (!fromType.isValid() || !toType.isValid())
2437 return false;
2438
2439 int fromTypeId = fromType.id();
2440 int toTypeId = toType.id();
2441
2442 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2443 if (f)
2444 return (*f)(from, to);
2445
2446#ifndef QT_BOOTSTRAPPED
2447 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2448 return viewAsSequentialIterable(fromType, from, to);
2449
2450 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2451 return viewAsAssociativeIterable(fromType, from, to);
2452
2453 return convertMetaObject(fromType, from, toType, to);
2454#else
2455 return false;
2456#endif
2457}
2458
2476bool QMetaType::canView(QMetaType fromType, QMetaType toType)
2477{
2478 int fromTypeId = fromType.id();
2479 int toTypeId = toType.id();
2480
2481 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2482 return false;
2483
2484 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2485 if (f)
2486 return true;
2487
2488#ifndef QT_BOOTSTRAPPED
2489 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2491
2492 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2494
2495 if (canConvertMetaObject(fromType, toType))
2496 return true;
2497#endif
2498
2499 return false;
2500}
2501
2573bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
2574{
2575 int fromTypeId = fromType.id();
2576 int toTypeId = toType.id();
2577
2578 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2579 return false;
2580
2581 if (fromTypeId == toTypeId)
2582 return true;
2583
2584 if (auto moduleHelper = qModuleHelperForType(qMax(fromTypeId, toTypeId))) {
2585 if (moduleHelper->convert(nullptr, fromTypeId, nullptr, toTypeId))
2586 return true;
2587 }
2588 const ConverterFunction * const f =
2589 customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId));
2590 if (f)
2591 return true;
2592
2593#ifndef QT_BOOTSTRAPPED
2594 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2596
2597 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2599#endif
2600#ifndef QT_NO_VARIANT
2601 if (toTypeId == QVariantList
2602 && canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
2603 return true;
2604 }
2605
2606 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2607 && canConvert(fromType, QMetaType::fromType<QAssociativeIterable>())) {
2608 return true;
2609 }
2610
2612 fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
2613 return true;
2614#endif
2615
2616 if (fromType.flags() & IsEnumeration) {
2617 if (toTypeId == QString || toTypeId == QByteArray)
2618 return true;
2619 return canConvert(QMetaType(LongLong), toType);
2620 }
2621 if (toType.flags() & IsEnumeration) {
2622 if (fromTypeId == QString || fromTypeId == QByteArray)
2623 return true;
2624 return canConvert(fromType, QMetaType(LongLong));
2625 }
2626 if (toTypeId == Nullptr && fromType.flags() & IsPointer)
2627 return true;
2628#ifndef QT_BOOTSTRAPPED
2629 if (canConvertMetaObject(fromType, toType))
2630 return true;
2631#endif
2632
2633 return false;
2634}
2635
2658{
2659 return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
2660}
2661
2667{
2668 const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2670}
2671
2677{
2678 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2680}
2681
2687{
2688 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2690}
2691
2705{
2706 return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
2707}
2708
2714{
2715 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2717}
2718
2724{
2725 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2727}
2728
2751/*
2752 Similar to QMetaType::type(), but only looks in the static set of types.
2753*/
2754static inline int qMetaTypeStaticType(const char *typeName, int length)
2755{
2756 int i = 0;
2757 while (types[i].typeName && ((length != types[i].typeNameLength)
2758 || memcmp(typeName, types[i].typeName, length))) {
2759 ++i;
2760 }
2761 return types[i].type;
2762}
2763
2764/*
2765 Similar to QMetaType::type(), but only looks in the custom set of
2766 types, and doesn't lock the mutex.
2768*/
2769static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
2770{
2771 if (customTypeRegistry.exists()) {
2772 auto reg = &*customTypeRegistry;
2773#if QT_CONFIG(thread)
2774 Q_ASSERT(!reg->lock.tryLockForWrite());
2775#endif
2776 if (auto ti = reg->aliases.value(QByteArray::fromRawData(typeName, length), nullptr)) {
2777 return ti->typeId.loadRelaxed();
2778 }
2779 }
2781}
2782
2790void QMetaType::registerNormalizedTypedef(const NS(QByteArray) & normalizedTypeName,
2791 QMetaType metaType)
2792{
2793 if (!metaType.isValid())
2794 return;
2795 if (auto reg = customTypeRegistry()) {
2796 QWriteLocker lock(&reg->lock);
2797 auto &al = reg->aliases[normalizedTypeName];
2798 if (al)
2799 return;
2800 al = metaType.d_ptr;
2801 }
2802}
2804
2806{
2807 const QtPrivate::QMetaTypeInterface *iface = nullptr;
2808 if (typeId >= QMetaType::User) {
2809 if (customTypeRegistry.exists())
2810 iface = customTypeRegistry->getCustomType(typeId);
2811 } else {
2812 if (auto moduleHelper = qModuleHelperForType(typeId))
2813 iface = moduleHelper->interfaceForType(typeId);
2814 }
2815 return iface;
2816}
2817
2825{
2826 return interfaceForTypeNoWarning(type) != nullptr;
2827}
2829template <bool tryNormalizedType>
2830static inline int qMetaTypeTypeImpl(const char *typeName, int length)
2831{
2832 if (!length)
2836 QReadLocker locker(&customTypeRegistry()->lock);
2838#ifndef QT_NO_QOBJECT
2839 if ((type == QMetaType::UnknownType) && tryNormalizedType) {
2840 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
2841 type = qMetaTypeStaticType(normalizedTypeName.constData(),
2842 normalizedTypeName.size());
2844 type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
2845 normalizedTypeName.size());
2846 }
2847 }
2848#endif
2849 }
2850 return type;
2851}
2852
2870Q_CORE_EXPORT int qMetaTypeTypeInternal(const char *typeName)
2871{
2872 return qMetaTypeTypeImpl</*tryNormalizedType=*/false>(typeName, int(qstrlen(typeName)));
2873}
2874
2888#ifndef QT_NO_DATASTREAM
2900bool QMetaType::save(QDataStream &stream, const void *data) const
2901{
2902 if (!data || !isValid())
2903 return false;
2904
2905 // keep compatibility for long/ulong
2906 if (id() == QMetaType::Long) {
2907 stream << qlonglong(*(long *)data);
2908 return true;
2909 } else if (id() == QMetaType::ULong) {
2910 stream << qlonglong(*(unsigned long *)data);
2911 return true;
2912 }
2913
2914 if (!d_ptr->dataStreamOut)
2915 return false;
2916
2917 d_ptr->dataStreamOut(d_ptr, stream, data);
2918 return true;
2919}
2920
2938bool QMetaType::load(QDataStream &stream, void *data) const
2939{
2940 if (!data || !isValid())
2941 return false;
2942
2943 // keep compatibility for long/ulong
2944 if (id() == QMetaType::Long) {
2945 qlonglong ll;
2946 stream >> ll;
2947 *(long *)data = long(ll);
2948 return true;
2949 } else if (id() == QMetaType::ULong) {
2950 qulonglong ull;
2951 stream >> ull;
2952 *(unsigned long *)data = (unsigned long)(ull);
2953 return true;
2954 }
2955 if (!d_ptr->dataStreamIn)
2956 return false;
2957
2958 d_ptr->dataStreamIn(d_ptr, stream, data);
2959 return true;
2960}
2961
2969{
2970 int type = id();
2971 if (type == QMetaType::Long || type == QMetaType::ULong)
2972 return true;
2973 return d_ptr && d_ptr->dataStreamIn != nullptr && d_ptr->dataStreamOut != nullptr;
2974}
2975
2986{
2987 if (!d_ptr || !(flags() & IsEnumeration))
2988 return {};
2989 /* QFlags has enumeration set so that's handled here (qint32
2990 case), as QFlags uses int as the underlying type
2991 Note that we do some approximation here, as we cannot
2992 differentiate between different underlying types of the
2993 same size and signedness (consider char <-> (un)signed char,
2994 int <-> long <-> long long).
2995
2996 ### TODO PENDING: QTBUG-111926 - QFlags supporting >32 bit int
2997 */
2998 if (flags() & IsUnsignedEnumeration) {
2999 switch (sizeOf()) {
3000 case 1:
3001 return QMetaType::fromType<quint8>();
3002 case 2:
3003 return QMetaType::fromType<quint16>();
3004 case 4:
3005 return QMetaType::fromType<quint32>();
3006 case 8:
3007 return QMetaType::fromType<quint64>();
3008 default:
3009 break;
3010 }
3011 } else {
3012 switch (sizeOf()) {
3013 case 1:
3014 return QMetaType::fromType<qint8>();
3015 case 2:
3016 return QMetaType::fromType<qint16>();
3017 case 4:
3018 return QMetaType::fromType<qint32>();
3019 case 8:
3020 return QMetaType::fromType<qint64>();
3021 default:
3022 break;
3023 }
3024 }
3025 // int128 can be handled above once we have qint128
3026 return QMetaType();
3027}
3028
3034#endif // QT_NO_DATASTREAM
3035
3041{
3042 return QMetaType(qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName.data(), typeName.size()));
3043}
3044
3252static const QtPrivate::QMetaTypeInterface *interfaceForType(int typeId)
3253{
3255 if (!iface && typeId != QMetaType::UnknownType)
3256 qWarning("Trying to construct an instance of an invalid type, type id: %i", typeId);
3257
3258 return iface;
3259}
3260
3274QMetaType::QMetaType(int typeId) : QMetaType(interfaceForType(typeId)) {}
3275
3276
3284namespace QtPrivate {
3285#if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
3287// Explicit instantiation definition
3288#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name) \
3289 template class QMetaTypeForType<Name>; \
3290 template struct QMetaTypeInterfaceWrapper<Name>;
3296
3297#undef QT_METATYPE_DECLARE_TEMPLATE_ITER
3298#endif
3299}
3300
The QAssociativeIterable class is an iterable interface for an associative container in a QVariant.
T loadRelaxed() const noexcept
\inmodule QtCore
\inmodule QtCore
Definition qbytearray.h:57
bool endsWith(char c) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:227
void chop(qsizetype n)
Removes n bytes from the end of the byte array.
bool startsWith(QByteArrayView bv) const
Definition qbytearray.h:223
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
QByteArray sliced(qsizetype pos) const &
Definition qbytearray.h:200
qsizetype lastIndexOf(char c, qsizetype from=-1) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:409
\inmodule QtCore\reentrant
Definition qcborarray.h:20
QVariantList toVariantList() const
Recursively converts each \l QCborValue in this array using QCborValue::toVariant() and returns the Q...
static QCborArray fromJsonArray(const QJsonArray &array)
Converts all JSON items found in the array array to CBOR using QCborValue::fromJson(),...
QJsonArray toJsonArray() const
Recursively converts every \l QCborValue element in this array to JSON using QCborValue::toJsonValue(...
static QCborArray fromStringList(const QStringList &list)
Returns a QCborArray containing all the strings found in the list list.
static QCborArray fromVariantList(const QVariantList &list)
Converts all the items in the list to CBOR using QCborValue::fromVariant() and returns the array comp...
\inmodule QtCore\reentrant
Definition qcbormap.h:21
QVariantMap toVariantMap() const
Converts the CBOR values to QVariant using QCborValue::toVariant() and "stringifies" all the CBOR key...
QVariantHash toVariantHash() const
Converts the CBOR values to QVariant using QCborValue::toVariant() and "stringifies" all the CBOR key...
QJsonObject toJsonObject() const
Recursively converts every \l QCborValue value in this map to JSON using QCborValue::toJsonValue() an...
static QCborMap fromJsonObject(const QJsonObject &o)
Converts all JSON items found in the obj object to CBOR using QCborValue::fromJson(),...
static QCborMap fromVariantMap(const QVariantMap &map)
Converts all the items in map to CBOR using QCborValue::fromVariant() and returns the map composed of...
static QCborMap fromVariantHash(const QVariantHash &hash)
Converts all the items in hash to CBOR using QCborValue::fromVariant() and returns the map composed o...
\inmodule QtCore\reentrant
Definition qcborvalue.h:47
bool isNull() const
Returns true if this QCborValue is of the null type.
Definition qcborvalue.h:164
QJsonValue toJsonValue() const
Converts this QCborValue object to an equivalent representation in JSON and returns it as a QJsonValu...
static QCborValue fromJsonValue(const QJsonValue &v)
Converts the JSON value contained in v into its corresponding CBOR value and returns it.
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qdatastream.h:46
\inmodule QtCore\reentrant
Definition qdatetime.h:283
QTime time() const
Returns the time part of the datetime.
QDate date() const
Returns the date part of the datetime.
\inmodule QtCore \reentrant
Definition qdatetime.h:29
QDateTime startOfDay(const QTimeZone &zone) const
\inmodule QtCore
\inmodule QtCore
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
Definition qhash.h:951
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
\inmodule QtCore\reentrant
Definition qjsonarray.h:18
static QJsonArray fromStringList(const QStringList &list)
Converts the string list list to a QJsonArray.
static QJsonArray fromVariantList(const QVariantList &list)
Converts the variant list list to a QJsonArray.
QVariantList toVariantList() const
Converts this object to a QVariantList.
\inmodule QtCore\reentrant
bool isArray() const
Returns true if the document contains an array.
\inmodule QtCore\reentrant
Definition qjsonobject.h:20
QVariantMap toVariantMap() const
Converts this object to a QVariantMap.
static QJsonObject fromVariantMap(const QVariantMap &map)
Converts the variant map map to a QJsonObject.
QVariantHash toVariantHash() const
Converts this object to a QVariantHash.
static QJsonObject fromVariantHash(const QVariantHash &map)
Converts the variant hash hash to a QJsonObject.
\inmodule QtCore\reentrant
Definition qjsonvalue.h:25
bool isNull() const
Returns true if the value is null.
Definition qjsonvalue.h:72
\inmodule QtCore\compares equality \compareswith equality QLine \endcompareswith
Definition qline.h:192
constexpr QLine toLine() const
Returns an integer-based copy of this line.
Definition qline.h:386
\inmodule QtCore\compares equality \compareswith equality QLineF \endcompareswith
Definition qline.h:18
qsizetype size() const noexcept
Definition qlist.h:397
iterator end()
Definition qlist.h:626
iterator begin()
Definition qlist.h:625
void reserve(qsizetype size)
Definition qlist.h:753
void clear()
Definition qlist.h:434
@ FloatingPointShortest
Definition qlocale.h:890
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
void clear()
Definition qmap.h:289
iterator begin()
Definition qmap.h:598
iterator end()
Definition qmap.h:602
size_type size() const
Definition qmap.h:267
\inmodule QtCore
\inmodule QtCore
void remove(int from, int to)
bool insertIfNotContains(Key k, const T &f)
bool contains(Key k) const
const T * function(Key k) const
virtual bool convert(const void *, int, void *, int) const
\inmodule QtCore
Definition qmetatype.h:341
bool isRegistered() const
static constexpr QMetaType fromType()
Definition qmetatype.h:2642
void destruct(void *data) const
static bool canConvert(QMetaType fromType, QMetaType toType)
Returns true if QMetaType::convert can convert from fromType to toType.
constexpr TypeFlags flags() const
Definition qmetatype.h:2658
static bool canView(QMetaType fromType, QMetaType toType)
Returns true if QMetaType::view can create a mutable view of type toType on type fromType.
const QtPrivate::QMetaTypeInterface * iface() const
Definition qmetatype.h:771
constexpr qsizetype sizeOf() const
Definition qmetatype.h:2648
bool isEqualityComparable() const
Returns true if a less than or equality operator for the type described by this metatype was visible ...
static bool view(QMetaType fromType, void *from, QMetaType toType, void *to)
Creates a mutable view on the object at from of fromType in the preallocated space at to typed toType...
bool debugStream(QDebug &dbg, const void *rhs)
Streams the object at rhs to the debug stream dbg.
QMetaType underlyingType() const
bool hasRegisteredDataStreamOperators() const
static QMetaType fromName(QByteArrayView name)
Returns a QMetaType matching typeName.
bool isMoveConstructible() const noexcept
Definition qmetatype.h:496
bool isValid() const
static bool hasRegisteredConverterFunction()
Returns true, if the meta type system has a registered conversion from type From to type To.
Definition qmetatype.h:737
bool equals(const void *lhs, const void *rhs) const
Compares the objects at lhs and rhs for equality.
void destroy(void *data) const
int id(int=0) const
Definition qmetatype.h:475
static void registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, QMetaType type)
@ IsUnsignedEnumeration
Definition qmetatype.h:411
@ PointerToQObject
Definition qmetatype.h:406
@ IsEnumeration
Definition qmetatype.h:407
@ LastWidgetsType
Definition qmetatype.h:354
@ FirstWidgetsType
Definition qmetatype.h:353
void * create(const void *copy=nullptr) const
std::function< bool(const void *src, void *target)> ConverterFunction
Definition qmetatype.h:557
constexpr const QMetaObject * metaObject() const
Definition qmetatype.h:2663
bool isCopyConstructible() const noexcept
Definition qmetatype.h:495
static bool hasRegisteredMutableViewFunction()
Returns true, if the meta type system has a registered mutable view on type From of type To.
Definition qmetatype.h:746
bool isDefaultConstructible() const noexcept
Definition qmetatype.h:494
constexpr const char * name() const
Definition qmetatype.h:2680
constexpr QMetaType()=default
static bool registerMutableViewFunction(const MutableViewFunction &f, QMetaType from, QMetaType to)
Registers function f as mutable view of type id to on type id from.
static void unregisterMetaType(QMetaType type)
void * construct(void *where, const void *copy=nullptr) const
static void unregisterMutableViewFunction(QMetaType from, QMetaType to)
bool isOrdered() const
Returns true if a less than operator for the type described by this metatype was visible to the metat...
bool load(QDataStream &stream, void *data) const
Reads the object of this type from the given stream into data.
bool save(QDataStream &stream, const void *data) const
Writes the object pointed to by data to the given stream.
QPartialOrdering compare(const void *lhs, const void *rhs) const
Compares the objects at lhs and rhs for ordering.
static bool convert(QMetaType fromType, const void *from, QMetaType toType, void *to)
Converts the object at from from fromType to the preallocated space at to typed toType.
bool hasRegisteredDebugStreamOperator() const
bool isDestructible() const noexcept
Definition qmetatype.h:497
static void unregisterConverterFunction(QMetaType from, QMetaType to)
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:103
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition qobject.h:348
\variable Qt::partial_ordering::less
Definition qcompare.h:679
static const QPartialOrdering Less
Definition qcompare.h:681
static const QPartialOrdering Greater
Definition qcompare.h:683
static const QPartialOrdering Equivalent
Definition qcompare.h:682
static const QPartialOrdering Unordered
Definition qcompare.h:684
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition qpoint.h:404
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr QRect toRect() const noexcept
Returns a QRect based on the values of this rectangle.
Definition qrect.h:859
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore \reentrant
The QSequentialIterable class is an iterable interface for a container in a QVariant.
iterator begin()
Definition qset.h:136
iterator end()
Definition qset.h:140
const_iterator constBegin() const noexcept
Definition qset.h:139
\inmodule QtCore
Definition qsize.h:208
constexpr QSize toSize() const noexcept
Returns an integer based copy of this size.
Definition qsize.h:401
\inmodule QtCore
Definition qsize.h:25
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QString toLower() const &
Definition qstring.h:435
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
QByteArray toUtf8() const &
Definition qstring.h:634
\inmodule QtCore \reentrant
Definition qdatetime.h:215
\inmodule QtCore
Definition qurl.h:94
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2831
\inmodule QtCore
Definition quuid.h:31
QString toString(StringFormat mode=WithBraces) const
Definition quuid.cpp:650
QByteArray toByteArray(StringFormat mode=WithBraces) const
Definition quuid.cpp:691
\inmodule QtCore
Definition qvariant.h:65
\inmodule QtCore
DataStreamOutFn dataStreamOut
Definition qmetatype.h:303
QMTI_MUTABLE QBasicAtomicInt typeId
Definition qmetatype.h:281
QString str
[2]
QMap< QString, QString > map
[6]
list append(new Employee("Blackpool", "Stephen"))
QSet< QString >::iterator it
Combined button and popup list for selecting options.
uint Bool
bool isDestructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
bool isMoveConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
bool isDefaultConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
bool isCopyConstructible(const QtPrivate::QMetaTypeInterface *iface) noexcept
bool isInterfaceFor(const QtPrivate::QMetaTypeInterface *iface)
void destruct(const QtPrivate::QMetaTypeInterface *iface, void *where)
void construct(const QtPrivate::QMetaTypeInterface *iface, void *where, const void *copy)
const char * typedefNameForType(const QtPrivate::QMetaTypeInterface *type_d)
constexpr QBindableInterface iface
Definition qproperty.h:666
\macro QT_NO_KEYWORDS >
Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
Q_CORE_EXPORT bool hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
@ ISODate
@ ISODateWithMs
void toByteArray(QByteArray &)
Definition qctf_p.h:76
static jboolean copy(JNIEnv *, jobject)
size_t qstrlen(const char *str)
QCborSimpleType
Definition qcborcommon.h:23
QList< QString > QStringList
Constructs a string list that contains the given string, str.
std::pair< QVariant, QVariant > QVariantPair
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLStreamKHR stream
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
static bool canConvertToSequentialIterable(QMetaType fromType)
static bool convertIterableToVariantHash(QMetaType fromType, const void *from, void *to)
static bool convertMetaObject(QMetaType fromType, const void *from, QMetaType toType, void *to)
static bool canConvertToAssociativeIterable(QMetaType fromType)
static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
static QPartialOrdering threeWayCompare(const void *ptr1, const void *ptr2)
static QMetaEnum metaEnumFromType(QMetaType t)
#define NS(x)
Definition qmetatype.cpp:64
static const QMetaTypeModuleHelper * qModuleHelperForType(int type)
static bool convertIterableToVariantMap(QMetaType fromType, const void *from, void *to)
QDebug operator<<(QDebug d, QMetaType m)
Q_CONSTINIT Q_CORE_EXPORT const QMetaTypeModuleHelper * qMetaTypeWidgetsHelper
static bool canImplicitlyViewAsAssociativeIterable(QMetaType fromType)
#define QMETATYPE_CONVERTER_ASSIGN_QCHAR(From)
static int qMetaTypeStaticType(const char *typeName, int length)
static bool convertToEnum(QMetaType fromType, const void *from, QMetaType toType, void *to)
static const QtPrivate::QMetaTypeInterface * interfaceForTypeNoWarning(int typeId)
static bool convertToSequentialIterable(QMetaType fromType, const void *from, void *to)
#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From)
static bool viewAsSequentialIterable(QMetaType fromType, void *from, void *to)
#define INTEGRAL_CONVERTER(To)
QMetaTypeFunctionRegistry< QMetaType::MutableViewFunction, std::pair< int, int > > QMetaTypeMutableViewRegistry
static bool convertIterableToVariantList(QMetaType fromType, const void *from, void *to)
static bool convertToAssociativeIterable(QMetaType fromType, const void *from, void *to)
static int qMetaTypeTypeImpl(const char *typeName, int length)
static bool viewAsAssociativeIterable(QMetaType fromType, void *from, void *to)
#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
Q_CONSTINIT Q_CORE_EXPORT const QMetaTypeModuleHelper * qMetaTypeGuiHelper
const char * typeName
#define QMETATYPE_CONVERTER_ASSIGN_NUMBER(To, From)
#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name)
static const QtPrivate::QMetaTypeInterface * interfaceForType(int typeId)
static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType)
int typeNameLength
int type
static bool convertIterableToVariantPair(QMetaType fromType, const void *from, void *to)
static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
metatypeHelper
QMetaTypeFunctionRegistry< QMetaType::ConverterFunction, std::pair< int, int > > QMetaTypeConverterRegistry
Q_CORE_EXPORT int qMetaTypeTypeInternal(const char *typeName)
#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
static bool convertFromEnum(QMetaType fromType, const void *from, QMetaType toType, void *to)
#define FLOAT_CONVERTER(To)
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)
Definition qmetatype.h:134
#define QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(F)
Definition qmetatype.h:67
#define QT_FOR_EACH_STATIC_PRIMITIVE_NON_VOID_TYPE(F)
Definition qmetatype.h:47
#define QT_FOR_EACH_STATIC_CORE_TEMPLATE(F)
Definition qmetatype.h:138
#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)
Definition qmetatype.h:71
#define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG)
Definition qmetatype.h:1384
#define QT_FOR_EACH_STATIC_CORE_CLASS(F)
Definition qmetatype.h:102
#define QT_FOR_EACH_STATIC_ALIAS_TYPE(F)
Definition qmetatype.h:189
#define QT_FOR_EACH_STATIC_TYPE(F)
Definition qmetatype.h:219
#define QT_METATYPE_CONVERT_ID_TO_TYPE(MetaTypeName, MetaTypeId, RealName)
#define QMETATYPE_CONVERTER(To, From, assign_and_return)
Definition qmetatype_p.h:23
#define QMETATYPE_CONVERTER_ASSIGN(To, From)
Definition qmetatype_p.h:32
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLint GLfloat GLfloat GLfloat v2
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLuint GLuint end
GLsizei GLenum GLenum * types
GLenum GLuint GLenum GLsizei length
GLenum GLuint id
[7]
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLenum type
GLint GLfloat GLfloat v1
GLuint name
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
static constexpr To convert(const std::array< Mapping, N > &mapping, From Mapping::*from, To Mapping::*to, From value, To defaultValue)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
#define v1
char Char
#define Q_UNUSED(x)
short qint16
Definition qtypes.h:47
int qint32
Definition qtypes.h:49
quint64 qulonglong
Definition qtypes.h:64
unsigned long long quint64
Definition qtypes.h:61
ptrdiff_t qsizetype
Definition qtypes.h:165
long long qint64
Definition qtypes.h:60
double qreal
Definition qtypes.h:187
qint64 qlonglong
Definition qtypes.h:63
QList< int > list
[14]
QStringList keys
obj metaObject() -> className()
QObject::connect nullptr
QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9))
[0]
QReadWriteLock lock
[0]
char * toString(const MyType &t)
[31]
\inmodule QtCore
bool inherits(const QMetaObject *metaObject) const noexcept
Returns true if the class described by this QMetaObject inherits the type described by metaObject; ot...
static QByteArray normalizedType(const char *type)