19#if QT_CONFIG(easingcurve)
20#include "qeasingcurve.h"
23#if QT_CONFIG(regularexpression)
24# include "qregularexpression.h"
27#ifndef QT_BOOTSTRAPPED
53#if QT_CONFIG(itemmodel)
54# include "qabstractitemmodel.h"
62#ifndef QT_BOOTSTRAPPED
66#define NS(x) QT_PREPEND_NAMESPACE(x)
73struct QMetaTypeDeleter
76 void operator()(
void *data)
78 if (iface->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
79 operator
delete(data,
std::align_val_t(iface->alignment));
81 operator
delete(data);
87#ifndef QT_BOOTSTRAPPED
89struct QMetaTypeCustomRegistry
91#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
92 QMetaTypeCustomRegistry()
95
96
97
98
99
100 aliases.insert(
"qfloat16", QtPrivate::qMetaTypeInterfaceForType<qfloat16>());
116 QWriteLocker l(&lock);
117 if (
int id = ti->typeId.loadRelaxed())
121 QMetaObject::normalizedType
124 if (
auto ti2 = aliases.value(name)) {
125 const auto id = ti2->typeId.loadRelaxed();
126 ti->typeId.storeRelaxed(id);
130 int size = registry.size();
131 while (firstEmpty < size && registry[firstEmpty])
133 if (firstEmpty < size) {
134 registry[firstEmpty] = ti;
138 firstEmpty = registry.size();
140 ti->typeId.storeRelaxed(firstEmpty + QMetaType::User);
144 return ti->typeId.loadRelaxed();
147 void unregisterDynamicType(
int id)
151 Q_ASSERT(id > QMetaType::User);
152 QWriteLocker l(&lock);
153 int idx = id - QMetaType::User - 1;
154 auto &ti = registry[idx];
157 aliases.removeIf([ti] (
const auto &kv) {
return kv.value() == ti; });
161 firstEmpty =
std::min(firstEmpty, idx);
166 QReadLocker l(&lock);
167 return registry.value(id - QMetaType::User - 1);
171Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry)
176const char *QtMetaTypePrivate::typedefNameForType(
const QtPrivate::QMetaTypeInterface *type_d)
178 const char *name =
nullptr;
179 if (!customTypeRegistry.exists())
181 QMetaTypeCustomRegistry *r = &*customTypeRegistry;
183 QByteArrayView officialName(type_d->name);
184 QReadLocker l(&r->lock);
185 auto it = r->aliases.constBegin();
186 auto end = r->aliases.constEnd();
187 for ( ; it != end; ++it) {
188 if (it.value() != type_d)
190 if (it.key() == officialName)
192 name = it.key().constData();
198 QByteArrayList otherNames;
199 for ( ; it != end; ++it) {
200 if (it.value() == type_d && it.key() != officialName)
201 otherNames << it.key();
204 if (!otherNames.isEmpty())
205 qWarning(
"QMetaType: type %s has more than one typedef alias: %s, %s",
206 type_d->name, name, otherNames.join(
", ").constData());
214
215
216
217
218
219
220
221
222
223
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
324
325
326
327
328
329
330
331
332
333
334
335
336
337
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
511
512
513
514
515
516
517
518
521
522
523
524
525
526
527
528
529
532
533
534
535
536
539
540
541
542
543
544
545
546
547#ifndef QT_BOOTSTRAPPED
549
550
551
552int QMetaType::registerHelper(
const QtPrivate::QMetaTypeInterface *iface)
555 auto reg = customTypeRegistry();
557 return reg->registerCustomType(iface);
564
565
566
567
568
569
570
571
572
573
574
575
578
579
580
581
582
583
584
585
586
587
588
589
590
593
594
595
596
597
598
599
600
601
602
603
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
629
630
631
632
633
634
635
636
637
638void *QMetaType::create(
const void *copy)
const
640 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
643 std::unique_ptr<
void, QMetaTypeDeleter> where(
nullptr, {d_ptr});
644 if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
645 where.reset(operator
new(d_ptr->size, std::align_val_t(d_ptr->alignment)));
647 where.reset(operator
new(d_ptr->size));
649 QtMetaTypePrivate::construct(d_ptr, where.get(), copy);
650 return where.release();
654
655
656
657
658
659
660
661
662void QMetaType::destroy(
void *data)
const
664 if (data && isDestructible()) {
665 QtMetaTypePrivate::destruct(d_ptr, data);
666 QMetaTypeDeleter{d_ptr}(data);
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696void *QMetaType::construct(
void *where,
const void *copy)
const
700 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
703 QtMetaTypePrivate::construct(d_ptr, where, copy);
708
709
710
711
712
713
714
715
716
717
718void QMetaType::destruct(
void *data)
const
720 if (data && isDestructible())
721 QtMetaTypePrivate::destruct(d_ptr, data);
724static QPartialOrdering threeWayCompare(
const void *ptr1,
const void *ptr2)
726 std::less<
const void *> less;
727 if (less(ptr1, ptr2))
728 return QPartialOrdering::Less;
729 if (less(ptr2, ptr1))
730 return QPartialOrdering::Greater;
731 return QPartialOrdering::Equivalent;
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760QPartialOrdering QMetaType::compare(
const void *lhs,
const void *rhs)
const
763 return QPartialOrdering::Unordered;
764 if (d_ptr && d_ptr->flags & QMetaType::IsPointer)
765 return threeWayCompare(*
reinterpret_cast<
const void *
const *>(lhs),
766 *
reinterpret_cast<
const void *
const *>(rhs));
767 if (d_ptr && d_ptr->lessThan) {
768 if (d_ptr->equals && d_ptr->equals(d_ptr, lhs, rhs))
769 return QPartialOrdering::Equivalent;
770 if (d_ptr->lessThan(d_ptr, lhs, rhs))
771 return QPartialOrdering::Less;
772 if (d_ptr->lessThan(d_ptr, rhs, lhs))
773 return QPartialOrdering::Greater;
775 return QPartialOrdering::Equivalent;
777 return QPartialOrdering::Unordered;
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796bool QMetaType::equals(
const void *lhs,
const void *rhs)
const
801 if (d_ptr->flags & QMetaType::IsPointer)
802 return *
reinterpret_cast<
const void *
const *>(lhs) == *
reinterpret_cast<
const void *
const *>(rhs);
805 return d_ptr->equals(d_ptr, lhs, rhs);
806 if (d_ptr->lessThan && !d_ptr->lessThan(d_ptr, lhs, rhs) && !d_ptr->lessThan(d_ptr, rhs, lhs))
813
814
815
816
817
818
819
820
821
824
825
826
827
828
829
830
831
832
835
836
837
838
839
840
841
842
845
846
847
848
849
850
851
852
854bool QMetaType::isDefaultConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
856 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDefaultConstructible(iface);
859bool QMetaType::isCopyConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
861 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isCopyConstructible(iface);
864bool QMetaType::isMoveConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
866 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isMoveConstructible(iface);
869bool QMetaType::isDestructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
871 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDestructible(iface);
875
876
877
878
879
880bool QMetaType::isEqualityComparable()
const
882 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->equals !=
nullptr || d_ptr->lessThan !=
nullptr);
886
887
888
889
890
891bool QMetaType::isOrdered()
const
893 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->lessThan !=
nullptr);
896#ifndef QT_BOOTSTRAPPED
898
899
900void QMetaType::unregisterMetaType(QMetaType type)
902 const QtPrivate::QMetaTypeInterface *d_ptr = type.d_ptr;
906 const int typeId = d_ptr->typeId.loadRelaxed();
907 if (typeId < QMetaType::User)
912 if (
auto reg = customTypeRegistry()) {
913 Q_ASSERT(reg->getCustomType(typeId) == d_ptr);
914 reg->unregisterDynamicType(typeId);
917 const_cast<QtPrivate::QMetaTypeInterface *>(d_ptr)->typeId.storeRelease(0);
922
923
924
925
926
929
930
931
932
933
934
937
938
939
940
941
942
945bool QMetaTypeModuleHelper::convert(
const void *,
int,
void *,
int)
const
950#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
951 { #RealName, sizeof(#RealName) - 1
, MetaTypeId },
953#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
954 { RealNameStr, sizeof(RealNameStr) - 1
, QMetaType::MetaTypeName },
958static const struct {
const char * typeName;
int typeNameLength;
int type; } types[] = {
962 {
nullptr, 0, QMetaType::UnknownType}
966static constexpr struct : QMetaTypeModuleHelper
968 template<
typename T,
typename LiteralWrapper =
969 std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView,
const char *>>
970 static inline bool convertToBool(
const T &source)
972 T str = source.toLower();
973 return !(str.isEmpty() || str == LiteralWrapper(
"0") || str == LiteralWrapper(
"false"));
988#ifndef QT_BOOTSTRAPPED
989 bool convert(
const void *from,
int fromTypeId,
void *to,
int toTypeId)
const override
991 Q_ASSERT(fromTypeId != toTypeId);
994 bool onlyCheck = (from ==
nullptr && to ==
nullptr);
997 Q_ASSERT(onlyCheck || (
bool(from) &&
bool(to)));
1000 using SChar =
signed char;
1001 using UChar =
unsigned char;
1002 using Short =
short;
1003 using UShort =
unsigned short;
1005 using UInt =
unsigned int;
1007 using LongLong = qlonglong;
1008 using ULong =
unsigned long;
1009 using ULongLong = qulonglong;
1010 using Float =
float;
1011 using Double =
double;
1013 using Nullptr =
std::nullptr_t;
1014 using Char16 =
char16_t;
1015 using Char32 =
char32_t;
1017#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From)
1019#define QMETATYPE_CONVERTER_ASSIGN_NUMBER(To, From)
1021#define CONVERT_CBOR_AND_JSON(To)
1023 if constexpr(std::is_same_v<To, Bool>) {
1024 if (!source.isBool())
1026 result = source.toBool();
1028 if (!source.isInteger() && !source.isDouble())
1030 if constexpr(std::is_integral_v<To>)
1031 result = source.toInteger();
1033 result = source.toDouble();
1038 if constexpr(std::is_same_v<To, Bool>) {
1039 if (!source.isBool())
1041 result = source.toBool();
1043 if (!source.isDouble())
1045 if constexpr(std::is_integral_v<To>)
1046 result = source.toInteger();
1048 result = source.toDouble();
1053#define INTEGRAL_CONVERTER(To)
1071 if constexpr(std::is_same_v<To, bool>)
1072 result = (ok = true, convertToBool(source));
1073 else if constexpr(std::is_signed_v<To>)
1074 result = To(source.toLongLong(&ok));
1076 result = To(source.toULongLong(&ok));
1081 if constexpr(std::is_same_v<To, bool>)
1082 result = (ok = true, convertToBool(source));
1083 else if constexpr(std::is_signed_v<To>)
1084 result = To(source.toLongLong(&ok));
1086 result = To(source.toULongLong(&ok));
1091#define FLOAT_CONVERTER(To)
1108 result = source.toDouble(&ok);
1113 result = source.toDouble(&ok);
1118 switch (makePair(toTypeId, fromTypeId)) {
1138 if (source.isUrl()) {
1139 result = source.toUrl();
1144#if QT_CONFIG(itemmodel)
1145 QMETATYPE_CONVERTER_ASSIGN(QModelIndex, QPersistentModelIndex);
1146 QMETATYPE_CONVERTER_ASSIGN(QPersistentModelIndex, QModelIndex);
1150#define QMETATYPE_CONVERTER_ASSIGN_QCHAR(From)
1171 result = source ? QStringLiteral(
"true") : QStringLiteral(
"false");
1183 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1187 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1191 result = QString::fromLatin1(&source, 1);
1196 result = QString::fromLatin1(&s, 1);
1201 result = QString::fromLatin1(&s, 1);
1205 result = QChar(source);
1209 result = QChar::fromUcs4(source).operator QStringView().toString();
1212#if QT_CONFIG(datestring)
1213 QMETATYPE_CONVERTER(QString, QDate, result = source.toString(Qt::ISODate);
return true;);
1214 QMETATYPE_CONVERTER(QString, QTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1215 QMETATYPE_CONVERTER(QString, QDateTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1219 return (source.size() == 1) ? (result = source.at(0),
true) :
false;
1223 if (source.isString() || source.isNull()) {
1224 result = source.toString();
1229 QMETATYPE_CONVERTER(QString, Nullptr, Q_UNUSED(source); result = QString();
return true;);
1234 result = source ?
"true" :
"false";
1249 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1253 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1272 QMETATYPE_CONVERTER(QStringList, QString, result = QStringList() << source;
return true;);
1275 result.reserve(source.size());
1276 for (
const auto &v: source)
1277 result.append(v.toByteArray());
1281 result.reserve(source.size());
1282 for (
const auto &v: source)
1283 result.append(QVariant(v));
1288 result.reserve(source.size());
1289 for (
const auto &v: source)
1290 result.append(v.toString());
1294 result.reserve(source.size());
1295 for (
const auto &v: source)
1296 result.append(QVariant(v));
1301 for (
auto it = source.begin(); it != source.end(); ++it)
1302 result.insert(it.key(), it.value());
1306 for (
auto it = source.begin(); it != source.end(); ++it)
1307 result.insert(it.key(), it.value());
1312 if (source.isContainer() || source.isTag())
1314 result = source.toVariant().toString();
1319 if (source.isByteArray()) {
1320 result = source.toByteArray();
1327 if (!source.isUuid())
1329 result = source.toUuid();
1334 if (!source.isArray())
1336 result = source.toArray().toVariantList();
1339 QMETATYPE_CONVERTER(QCborValue, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1341 if (!source.isMap())
1343 result = source.toMap().toVariantMap();
1346 QMETATYPE_CONVERTER(QCborValue, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1348 if (!source.isMap())
1350 result = source.toMap().toVariantHash();
1353#if QT_CONFIG(regularexpression)
1354 QMETATYPE_CONVERTER(QCborValue, QRegularExpression, result = QCborValue(source);
return true;);
1355 QMETATYPE_CONVERTER(QRegularExpression, QCborValue,
1356 if (!source.isRegularExpression())
1358 result = source.toRegularExpression();
1365 result = QCborValue(QCborValue::Null);
1370 return source.isNull();
1387 result = QCborArray::fromStringList(source);
1390#if QT_CONFIG(datestring)
1391 QMETATYPE_CONVERTER(QCborValue, QDate,
1392 result = QCborValue(source.startOfDay());
1398 result = QCborValue::fromJsonValue(source);
1402 result = QCborMap::fromJsonObject(source);
1406 result = QCborArray::fromJsonArray(source);
1410 QJsonDocument doc = source;
1412 result = QCborArray::fromJsonArray(doc.array());
1414 result = QCborMap::fromJsonObject(doc.object());
1420#if QT_CONFIG(datestring)
1421 QMETATYPE_CONVERTER_ASSIGN(QCborValue, QDateTime);
1422 QMETATYPE_CONVERTER(QDateTime, QCborValue,
1423 if (source.isDateTime()) {
1424 result = source.toDateTime();
1433 if (source.isSimpleType()) {
1434 result = source.toSimpleType();
1442 QMETATYPE_CONVERTER(QCborArray, QStringList, result = QCborArray::fromStringList(source);
return true;);
1443 QMETATYPE_CONVERTER(QCborMap, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1445 QMETATYPE_CONVERTER(QCborMap, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1446 QMETATYPE_CONVERTER(QVariantHash, QCborMap, result = source.toVariantHash();
return true;);
1449 if (!source.isArray())
1451 result = source.toArray();
1455 if (!source.isArray())
1457 result = QCborArray::fromJsonArray(source.array());
1461 if (!source.isArray())
1463 result = QCborArray::fromJsonArray(source.toArray());
1467 result = QCborArray::fromJsonArray(source);
1471 if (!source.isMap())
1473 result = source.toMap();
1477 if (source.isArray())
1479 result = QCborMap::fromJsonObject(source.object());
1483 if (!source.isObject())
1485 result = QCborMap::fromJsonObject(source.toObject());
1489 result = QCborMap::fromJsonObject(source);
1495 if (!source.isArray())
1497 result = source.toArray().toVariantList();
1502 if (!source.isObject())
1504 result = source.toObject().toVariantMap();
1507 QMETATYPE_CONVERTER(QVariantMap, QJsonObject, result = source.toVariantMap();
return true;);
1509 if (!source.isObject())
1511 result = source.toObject().toVariantHash();
1514 QMETATYPE_CONVERTER(QVariantHash, QJsonObject, result = source.toVariantHash();
return true;);
1517 QMETATYPE_CONVERTER(QJsonArray, QStringList, result = QJsonArray::fromStringList(source);
return true;);
1520 if (!source.isArray())
1522 result = source.toArray();
1526 if (!source.isArray())
1528 result = source.array();
1532 if (!source.isArray())
1534 result = source.toArray().toJsonArray();
1538 QMETATYPE_CONVERTER(QJsonObject, QVariantMap, result = QJsonObject::fromVariantMap(source);
return true;);
1539 QMETATYPE_CONVERTER(QJsonObject, QVariantHash, result = QJsonObject::fromVariantHash(source);
return true;);
1541 if (!source.isObject())
1543 result = source.toObject();
1547 if (source.isArray())
1549 result = source.object();
1553 if (!source.isMap())
1555 result = source.toMap().toJsonObject();
1558 QMETATYPE_CONVERTER(QJsonObject, QCborMap, result = source.toJsonObject();
return true; );
1562 result = QJsonValue(QJsonValue::Null);
1567 return source.isNull();
1570 result = QJsonValue(source);
1587 result = QJsonValue(QJsonArray::fromStringList(source));
1591 result = QJsonValue(QJsonArray::fromVariantList(source));
1595 result = QJsonValue(QJsonObject::fromVariantMap(source));
1599 result = QJsonValue(QJsonObject::fromVariantHash(source));
1611 QJsonDocument doc = source;
1612 result = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1616 result = source.toJsonValue();
1620 result = source.toJsonObject();
1624 result = source.toJsonArray();
1631#if QT_CONFIG(datestring)
1632 QMETATYPE_CONVERTER(QDate, QString,
1633 result = QDate::fromString(source, Qt::ISODate);
1634 return result.isValid();
1636 QMETATYPE_CONVERTER(QTime, QString,
1637 result = QTime::fromString(source, Qt::ISODate);
1638 return result.isValid();
1640 QMETATYPE_CONVERTER(QDateTime, QString,
1641 result = QDateTime::fromString(source, Qt::ISODate);
1642 return result.isValid();
1650} metatypeHelper = {};
1657 if (type <= QMetaType::LastCoreType)
1658 return &metatypeHelper;
1659 if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType)
1660 return qMetaTypeGuiHelper;
1661 else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType)
1662 return qMetaTypeWidgetsHelper;
1666#ifndef QT_BOOTSTRAPPED
1667template<
typename T,
typename Key>
1673 const QWriteLocker locker(&lock);
1679 const QReadLocker locker(&lock);
1680 return map.contains(k);
1685 const QWriteLocker locker(&lock);
1686 auto r = map.tryEmplace(k, f);
1692 const QReadLocker locker(&lock);
1693 auto it = map.find(k);
1694 return it == map.end() ?
nullptr :
std::addressof(*it);
1699 const Key k(from, to);
1700 const QWriteLocker locker(&lock);
1704 mutable QReadWriteLock lock;
1708using QMetaTypeConverterRegistry
1709 = QMetaTypeFunctionRegistry<QMetaType::ConverterFunction, std::pair<
int,
int>>;
1711Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
1713using QMetaTypeMutableViewRegistry
1714 = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, std::pair<
int,
int>>;
1715Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
1718
1719
1720
1721
1722
1723
1724
1727
1728
1729
1730
1731
1732
1733
1734
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1762
1763
1764
1765
1767
1768bool QMetaType::registerConverterFunction(
const ConverterFunction &f, QMetaType from, QMetaType to)
1770 if (!customTypesConversionRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1771 qWarning(
"Type conversion already registered from type %s to type %s",
1772 from.name(), to.name());
1779
1780
1781
1782
1783
1784
1785
1788
1789
1790
1791
1792
1793
1796
1797
1798
1800
1801bool QMetaType::registerMutableViewFunction(
const MutableViewFunction &f, QMetaType from, QMetaType to)
1803 if (!customTypesMutableViewRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1804 qWarning(
"Mutable view on type already registered from type %s to type %s",
1805 from.name(), to.name());
1813
1814void QMetaType::unregisterMutableViewFunction(QMetaType from, QMetaType to)
1816 if (customTypesMutableViewRegistry.isDestroyed())
1818 customTypesMutableViewRegistry()->remove(from.id(), to.id());
1822
1823
1825
1826void QMetaType::unregisterConverterFunction(QMetaType from, QMetaType to)
1828 if (customTypesConversionRegistry.isDestroyed())
1830 customTypesConversionRegistry()->remove(from.id(), to.id());
1834#ifndef QT_NO_DEBUG_STREAM
1837
1838
1840
1841QDebug operator<<(QDebug d, QMetaType m)
1843 const QDebugStateSaver saver(d);
1844 return d.nospace() <<
"QMetaType(" << m.name() <<
")";
1848
1849
1851
1852bool QMetaType::debugStream(QDebug& dbg,
const void *rhs)
1854 if (d_ptr && d_ptr->flags & QMetaType::IsPointer) {
1855 dbg << *
reinterpret_cast<
const void *
const *>(rhs);
1858 if (d_ptr && d_ptr->debugStream) {
1859 d_ptr->debugStream(d_ptr, dbg, rhs);
1866
1867
1868
1869
1872
1873
1874
1875
1876
1877
1880
1881
1882
1883
1884
1885
1886
1889
1890
1891
1893
1894bool QMetaType::hasRegisteredDebugStreamOperator()
const
1896 return d_ptr && d_ptr->debugStream !=
nullptr;
1900#ifndef QT_NO_QOBJECT
1902
1904
1905static QMetaEnum metaEnumFromType(QMetaType t)
1907 if (t.flags() & QMetaType::IsEnumeration) {
1908 if (
const QMetaObject *metaObject = t.metaObject()) {
1909 QByteArrayView qflagsNamePrefix =
"QFlags<";
1911 if (enumName.endsWith(
'>') && enumName.startsWith(qflagsNamePrefix)) {
1914 enumName = enumName.sliced(qflagsNamePrefix.size());
1916 if (qsizetype lastColon = enumName.lastIndexOf(
':'); lastColon != -1)
1917 enumName = enumName.sliced(lastColon + 1);
1918 return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
1925#ifndef QT_BOOTSTRAPPED
1926static bool convertFromEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
1929 if (fromType.flags() & QMetaType::IsUnsignedEnumeration) {
1931 switch (fromType.sizeOf()) {
1933 ull = *
static_cast<
const unsigned char *>(from);
1936 ull = *
static_cast<
const unsigned short *>(from);
1939 ull = *
static_cast<
const unsigned int *>(from);
1942 ull = *
static_cast<
const quint64 *>(from);
1947 if (toType.id() == QMetaType::ULongLong) {
1948 *
static_cast<qulonglong *>(to) = ull;
1951 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
1952 return QMetaType::convert(QMetaType::fromType<qulonglong>(), &ull, toType, to);
1953 ll = qlonglong(ull);
1955 switch (fromType.sizeOf()) {
1957 ll = *
static_cast<
const signed char *>(from);
1960 ll = *
static_cast<
const short *>(from);
1963 ll = *
static_cast<
const int *>(from);
1966 ll = *
static_cast<
const qint64 *>(from);
1971 if (toType.id() == QMetaType::LongLong) {
1972 *
static_cast<qlonglong *>(to) = ll;
1975 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
1976 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
1978#ifndef QT_NO_QOBJECT
1979 QMetaEnum en = metaEnumFromType(fromType);
1983 if (toType.id() == QMetaType::QString)
1984 *
static_cast<QString *>(to) = QString::fromUtf8(keys);
1988 const char *key = en.valueToKey(ll);
1989 if (toType.id() == QMetaType::QString)
1990 *
static_cast<QString *>(to) = QString::fromUtf8(key);
1997 if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray)
1998 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2002static bool convertToEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2004 int fromTypeId = fromType.id();
2005 qlonglong value = -1;
2007#ifndef QT_NO_QOBJECT
2008 if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) {
2009 QMetaEnum en = metaEnumFromType(toType);
2011 QByteArray keys = (fromTypeId == QMetaType::QString)
2012 ?
static_cast<
const QString *>(from)->toUtf8()
2013 : *
static_cast<
const QByteArray *>(from);
2014 if (
auto v = en.keysToValue64(keys.constData())) {
2022 if (fromTypeId == QMetaType::LongLong) {
2023 value = *
static_cast<
const qlonglong *>(from);
2026 ok = QMetaType::convert(fromType, from, QMetaType::fromType<qlonglong>(), &value);
2033 switch (toType.sizeOf()) {
2035 *
static_cast<
signed char *>(to) = value;
2038 *
static_cast<qint16 *>(to) = value;
2041 *
static_cast<qint32 *>(to) = value;
2044 *
static_cast<qint64 *>(to) = value;
2047 Q_UNREACHABLE_RETURN(
false);
2051static bool convertIterableToVariantList(QMetaType fromType,
const void *from,
void *to)
2054 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QSequentialIterable>(), &list))
2059 l.reserve(list.size());
2060 auto end = list.end();
2061 for (
auto it = list.begin(); it != end; ++it)
2066static bool convertIterableToVariantMap(QMetaType fromType,
const void *from,
void *to)
2069 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QAssociativeIterable>(), &map))
2072 QVariantMap &h = *
static_cast<QVariantMap *>(to);
2074 auto end = map.end();
2075 for (
auto it = map.begin(); it != end; ++it)
2076 h.insert(it.key().toString(), it.value());
2080static bool convertIterableToVariantHash(QMetaType fromType,
const void *from,
void *to)
2083 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QAssociativeIterable>(), &map))
2086 QVariantHash &h = *
static_cast<QVariantHash *>(to);
2088 h.reserve(map.size());
2089 auto end = map.end();
2090 for (
auto it = map.begin(); it != end; ++it)
2091 h.insert(it.key().toString(), it.value());
2095static bool convertIterableToVariantPair(QMetaType fromType,
const void *from,
void *to)
2098 const auto f = customTypesConversionRegistry()->function({fromType.id(), targetId});
2106 QVariant v1(pi._metaType_first);
2108 if (pi._metaType_first == QMetaType::fromType<QVariant>())
2111 dataPtr = v1.data();
2114 QVariant v2(pi._metaType_second);
2115 if (pi._metaType_second == QMetaType::fromType<QVariant>())
2118 dataPtr = v2.data();
2121 *
static_cast<QVariantPair *>(to) = QVariantPair(v1, v2);
2125static bool convertToSequentialIterable(QMetaType fromType,
const void *from,
void *to)
2128 const int fromTypeId = fromType.id();
2130 QSequentialIterable &i = *
static_cast<QSequentialIterable *>(to);
2131 switch (fromTypeId) {
2132 case QMetaType::QVariantList:
2133 i = QSequentialIterable(
reinterpret_cast<
const QVariantList *>(from));
2135 case QMetaType::QStringList:
2136 i = QSequentialIterable(
reinterpret_cast<
const QStringList *>(from));
2138 case QMetaType::QByteArrayList:
2139 i = QSequentialIterable(
reinterpret_cast<
const QByteArrayList *>(from));
2141 case QMetaType::QString:
2142 i = QSequentialIterable(
reinterpret_cast<
const QString *>(from));
2144 case QMetaType::QByteArray:
2145 i = QSequentialIterable(
reinterpret_cast<
const QByteArray *>(from));
2149 if (QMetaType::convert(
2150 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &impl)) {
2151 i = std::move(impl);
2160static bool canConvertToSequentialIterable(QMetaType fromType)
2162 switch (fromType.id()) {
2163 case QMetaType::QVariantList:
2164 case QMetaType::QStringList:
2165 case QMetaType::QByteArrayList:
2166 case QMetaType::QString:
2167 case QMetaType::QByteArray:
2170 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2174static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType)
2176 switch (fromType.id()) {
2177 case QMetaType::QVariantList:
2178 case QMetaType::QStringList:
2179 case QMetaType::QByteArrayList:
2180 case QMetaType::QString:
2181 case QMetaType::QByteArray:
2184 return QMetaType::canView(
2185 fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2189static bool viewAsSequentialIterable(QMetaType fromType,
void *from,
void *to)
2192 const int fromTypeId = fromType.id();
2194 QSequentialIterable &i = *
static_cast<QSequentialIterable *>(to);
2195 switch (fromTypeId) {
2196 case QMetaType::QVariantList:
2197 i = QSequentialIterable(
reinterpret_cast<QVariantList *>(from));
2199 case QMetaType::QStringList:
2200 i = QSequentialIterable(
reinterpret_cast<QStringList *>(from));
2202 case QMetaType::QByteArrayList:
2203 i = QSequentialIterable(
reinterpret_cast<QByteArrayList *>(from));
2205 case QMetaType::QString:
2206 i = QSequentialIterable(
reinterpret_cast<QString *>(from));
2208 case QMetaType::QByteArray:
2209 i = QSequentialIterable(
reinterpret_cast<QByteArray *>(from));
2212 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2213 if (QMetaType::view(
2214 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2224static bool convertToAssociativeIterable(QMetaType fromType,
const void *from,
void *to)
2228 QAssociativeIterable &i = *
static_cast<QAssociativeIterable *>(to);
2229 if (fromType.id() == QMetaType::QVariantMap) {
2230 i = QAssociativeIterable(
reinterpret_cast<
const QVariantMap *>(from));
2233 if (fromType.id() == QMetaType::QVariantHash) {
2234 i = QAssociativeIterable(
reinterpret_cast<
const QVariantHash *>(from));
2239 if (QMetaType::convert(
2240 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &impl)) {
2241 i = std::move(impl);
2248static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
2250 if ((fromType.flags() & QMetaType::IsPointer) != (toType.flags() & QMetaType::IsPointer))
2253 const QMetaObject *f = fromType.metaObject();
2254 const QMetaObject *t = toType.metaObject();
2256 return f->inherits(t) || (t->inherits(f));
2261static bool canConvertToAssociativeIterable(QMetaType fromType)
2263 switch (fromType.id()) {
2264 case QMetaType::QVariantMap:
2265 case QMetaType::QVariantHash:
2268 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2272static bool canImplicitlyViewAsAssociativeIterable(QMetaType fromType)
2274 switch (fromType.id()) {
2275 case QMetaType::QVariantMap:
2276 case QMetaType::QVariantHash:
2279 return QMetaType::canView(
2280 fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2284static bool viewAsAssociativeIterable(QMetaType fromType,
void *from,
void *to)
2287 int fromTypeId = fromType.id();
2289 QAssociativeIterable &i = *
static_cast<QAssociativeIterable *>(to);
2290 if (fromTypeId == QMetaType::QVariantMap) {
2291 i = QAssociativeIterable(
reinterpret_cast<QVariantMap *>(from));
2294 if (fromTypeId == QMetaType::QVariantHash) {
2295 i = QAssociativeIterable(
reinterpret_cast<QVariantHash *>(from));
2299 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2300 if (QMetaType::view(
2301 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2309static bool convertMetaObject(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2312 if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
2313 QObject *fromObject = *
static_cast<QObject *
const *>(from);
2315 if (fromObject && fromObject->metaObject()->inherits(toType.metaObject())) {
2316 *
static_cast<QObject **>(to) = toType.metaObject()->cast(fromObject);
2318 }
else if (!fromObject && fromType.metaObject()) {
2320 *
static_cast<
void **>(to) =
nullptr;
2321 return fromType.metaObject()->inherits(toType.metaObject());
2323 }
else if ((fromType.flags() & QMetaType::IsPointer) == (toType.flags() & QMetaType::IsPointer)) {
2325 const QMetaObject *f = fromType.metaObject();
2326 const QMetaObject *t = toType.metaObject();
2327 if (f && t && f->inherits(t)) {
2328 toType.destruct(to);
2329 toType.construct(to, from);
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2349
2350
2351
2352
2353
2355
2356bool QMetaType::convert(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2358 if (!fromType.isValid() || !toType.isValid())
2361 if (fromType == toType) {
2363 fromType.destruct(to);
2364 fromType.construct(to, from);
2368 int fromTypeId = fromType.id();
2369 int toTypeId = toType.id();
2371 if (
auto moduleHelper = qModuleHelperForType(qMax(fromTypeId, toTypeId))) {
2372 if (moduleHelper->convert(from, fromTypeId, to, toTypeId))
2375 const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId});
2377 return (*f)(from, to);
2379 if (fromType.flags() & QMetaType::IsEnumeration)
2380 return convertFromEnum(fromType, from, toType, to);
2381 if (toType.flags() & QMetaType::IsEnumeration)
2382 return convertToEnum(fromType, from, toType, to);
2383 if (toTypeId == Nullptr) {
2384 *
static_cast<std::nullptr_t *>(to) =
nullptr;
2385 if (fromType.flags() & QMetaType::IsPointer) {
2386 if (*
static_cast<
const void *
const *>(from) ==
nullptr)
2391 if (toTypeId == QVariantPair && convertIterableToVariantPair(fromType, from, to))
2395 if (toTypeId == QVariantList && convertIterableToVariantList(fromType, from, to))
2398 if (toTypeId == QVariantMap && convertIterableToVariantMap(fromType, from, to))
2401 if (toTypeId == QVariantHash && convertIterableToVariantHash(fromType, from, to))
2404 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2405 return convertToSequentialIterable(fromType, from, to);
2407 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2408 return convertToAssociativeIterable(fromType, from, to);
2410 return convertMetaObject(fromType, from, toType, to);
2414
2415
2417
2418bool QMetaType::view(QMetaType fromType,
void *from, QMetaType toType,
void *to)
2420 if (!fromType.isValid() || !toType.isValid())
2423 int fromTypeId = fromType.id();
2424 int toTypeId = toType.id();
2426 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2428 return (*f)(from, to);
2430 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2431 return viewAsSequentialIterable(fromType, from, to);
2433 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2434 return viewAsAssociativeIterable(fromType, from, to);
2436 return convertMetaObject(fromType, from, toType, to);
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2455
2456bool QMetaType::canView(QMetaType fromType, QMetaType toType)
2458 int fromTypeId = fromType.id();
2459 int toTypeId = toType.id();
2461 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2464 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2468 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2469 return canImplicitlyViewAsSequentialIterable(fromType);
2471 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2472 return canImplicitlyViewAsAssociativeIterable(fromType);
2474 if (canConvertMetaObject(fromType, toType))
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2550
2551bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
2553 int fromTypeId = fromType.id();
2554 int toTypeId = toType.id();
2556 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2559 if (fromTypeId == toTypeId)
2562 if (
auto moduleHelper = qModuleHelperForType(qMax(fromTypeId, toTypeId))) {
2563 if (moduleHelper->convert(
nullptr, fromTypeId,
nullptr, toTypeId))
2566 const ConverterFunction *
const f =
2567 customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId));
2571 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2572 return canConvertToSequentialIterable(fromType);
2574 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2575 return canConvertToAssociativeIterable(fromType);
2576 if (toTypeId == QVariantList
2577 && canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
2581 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2582 && canConvert(fromType, QMetaType::fromType<QAssociativeIterable>())) {
2586 if (toTypeId == QVariantPair && hasRegisteredConverterFunction(
2587 fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
2590 if (fromType.flags() & IsEnumeration) {
2591 if (toTypeId == QString || toTypeId == QByteArray)
2593 return canConvert(QMetaType(LongLong), toType);
2595 if (toType.flags() & IsEnumeration) {
2596 if (fromTypeId == QString || fromTypeId == QByteArray)
2598 return canConvert(fromType, QMetaType(LongLong));
2600 if (toTypeId == Nullptr && fromType.flags() & IsPointer)
2602 if (canConvertMetaObject(fromType, toType))
2609
2610
2611
2612
2613
2614
2615
2618
2619
2620
2621
2622
2625
2626
2628
2629bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType)
2631 return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
2635
2637
2638bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
2640 const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2641 return QMetaType::hasRegisteredConverterFunction(m, to);
2645
2647
2648bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
2650 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2651 return QMetaType::hasRegisteredConverterFunction(m, to);
2655
2657
2658bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
2660 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2661 return QMetaType::hasRegisteredConverterFunction(m, to);
2665
2666
2667
2668
2669
2672
2673
2675
2676bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType)
2678 return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
2682
2684
2685bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
2687 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2688 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2692
2694
2695bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
2697 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2698 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2703
2704
2705
2706
2707
2708
2709
2710
2711
2714
2715
2716
2717
2718
2719
2720
2721
2722
2726
2727static inline int qMetaTypeStaticType(
const char *typeName,
int length)
2730 while (types[i].typeName && ((length != types[i].typeNameLength)
2731 || memcmp(typeName, types[i].typeName, length))) {
2734 return types[i].type;
2737#ifndef QT_BOOTSTRAPPED
2739
2740
2742
2743static int qMetaTypeCustomType_unlocked(
const char *typeName,
int length)
2746#ifdef __cpp_concepts
2747 return QByteArrayView(typeName, length);
2749 return QByteArray::fromRawData(typeName, length);
2752 if (customTypeRegistry.exists()) {
2753 auto reg = &*customTypeRegistry;
2754#if QT_CONFIG(thread)
2755 Q_ASSERT(!reg->lock.tryLockForWrite());
2757 if (
auto ti = reg->aliases.value(type(),
nullptr)) {
2758 return ti->typeId.loadRelaxed();
2761 return QMetaType::UnknownType;
2765
2766
2767
2768
2770
2771void QMetaType::registerNormalizedTypedef(
const NS(QByteArray) & normalizedTypeName,
2774 if (!metaType.isValid())
2776 if (
auto reg = customTypeRegistry()) {
2777 QWriteLocker lock(®->lock);
2778 auto &al = reg->aliases[normalizedTypeName];
2781 al = metaType.d_ptr;
2789 if (typeId >= QMetaType::User) {
2790#ifndef QT_BOOTSTRAPPED
2791 if (customTypeRegistry.exists())
2792 iface = customTypeRegistry->getCustomType(typeId);
2795 if (
auto moduleHelper = qModuleHelperForType(typeId))
2796 iface = moduleHelper->interfaceForType(typeId);
2802
2803
2804
2806
2807bool QMetaType::isRegistered(
int type)
2809 return interfaceForTypeNoWarning(type) !=
nullptr;
2813enum NormalizeTypeMode {
2818template <NormalizeTypeMode tryNormalizedType>
2819static inline int qMetaTypeTypeImpl(
const char *typeName,
int length)
2822 return QMetaType::UnknownType;
2823 int type = qMetaTypeStaticType(typeName, length);
2824 if (type == QMetaType::UnknownType) {
2825#ifndef QT_BOOTSTRAPPED
2826 QReadLocker locker(&customTypeRegistry()->lock);
2827 type = qMetaTypeCustomType_unlocked(typeName, length);
2828#ifndef QT_NO_QOBJECT
2829 if ((type == QMetaType::UnknownType) && tryNormalizedType) {
2830 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
2831 type = qMetaTypeStaticType(normalizedTypeName.constData(),
2832 normalizedTypeName.size());
2833 if (type == QMetaType::UnknownType) {
2834 type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
2835 normalizedTypeName.size());
2845
2846
2847
2848
2849
2850
2851
2852
2855
2856
2857
2858
2860
2861Q_CORE_EXPORT
int qMetaTypeTypeInternal(
const char *typeName)
2863 return qMetaTypeTypeImpl<DontNormalizeType>(typeName,
int(qstrlen(typeName)));
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2879#ifndef QT_NO_DATASTREAM
2881
2882
2883
2884
2885
2886
2887
2888
2890
2891bool QMetaType::save(QDataStream &stream,
const void *data)
const
2893 if (!data || !isValid())
2897 if (id() == QMetaType::Long) {
2898 stream << qlonglong(*(
long *)data);
2900 }
else if (id() == QMetaType::ULong) {
2901 stream << qlonglong(*(
unsigned long *)data);
2905 if (!d_ptr->dataStreamOut)
2908 d_ptr->dataStreamOut(d_ptr, stream, data);
2913
2914
2915
2916
2919
2920
2921
2922
2923
2924
2925
2926
2928
2929bool QMetaType::load(QDataStream &stream,
void *data)
const
2931 if (!data || !isValid())
2935 if (id() == QMetaType::Long) {
2938 *(
long *)data =
long(ll);
2940 }
else if (id() == QMetaType::ULong) {
2943 *(
unsigned long *)data = (
unsigned long)(ull);
2946 if (!d_ptr->dataStreamIn)
2949 d_ptr->dataStreamIn(d_ptr, stream, data);
2954
2955
2956
2958
2959bool QMetaType::hasRegisteredDataStreamOperators()
const
2962 if (type == QMetaType::Long || type == QMetaType::ULong)
2964 return d_ptr && d_ptr->dataStreamIn !=
nullptr && d_ptr->dataStreamOut !=
nullptr;
2968
2969
2970
2971
2972
2973
2975
2976QMetaType QMetaType::underlyingType()
const
2978 if (!d_ptr || !(flags() & IsEnumeration))
2981
2982
2983
2984
2985
2986
2987 if (flags() & IsUnsignedEnumeration) {
2990 return QMetaType::fromType<quint8>();
2992 return QMetaType::fromType<quint16>();
2994 return QMetaType::fromType<quint32>();
2996 return QMetaType::fromType<quint64>();
3003 return QMetaType::fromType<qint8>();
3005 return QMetaType::fromType<qint16>();
3007 return QMetaType::fromType<qint32>();
3009 return QMetaType::fromType<qint64>();
3019
3020
3021
3022
3026
3028
3029QMetaType QMetaType::fromName(QByteArrayView typeName)
3031 return QMetaType(qMetaTypeTypeImpl<TryNormalizeType>(typeName.data(), typeName.size()));
3035
3036
3037
3038
3039
3040
3041
3042
3045
3046
3047
3048
3049
3050
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3110
3111
3112
3113
3114
3115
3116
3117
3120
3121
3122
3123
3124
3125
3126
3127
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3244 if (!iface && typeId != QMetaType::UnknownType)
3245 qWarning(
"Trying to construct an instance of an invalid type, type id: %i", typeId);
3251
3252
3253
3254
3255
3258
3259
3260
3262
3263QMetaType::QMetaType(
int typeId) : QMetaType(interfaceForType(typeId)) {}
3267
3268
3269
3270
3272namespace QtPrivate {
3273#if !defined(QT_BOOTSTRAPPED)
3274void QMetaTypeCopyTraits::warnAboutDeprecatedCopy(
const char *name)
3276 qCWarning(lcMetatypeDeprecated,
"QMetaType: copy construction of type '%s' is deprecated", name);
3280#if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
3283#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name)
3284 template class QMetaTypeForType<Name>;
3285 template struct QMetaTypeInterfaceWrapper<Name>;
3292#undef QT_METATYPE_DECLARE_TEMPLATE_ITER
The QAssociativeIterable class is an iterable interface for an associative container in a QVariant.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
The QSequentialIterable class is an iterable interface for a container in a QVariant.
QList< QVariant > QVariantList
#define qCWarning(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)