16#include "private/qnumeric_p.h"
18#include "private/qoffsetstringarray_p.h"
23#if QT_CONFIG(easingcurve)
24#include "qeasingcurve.h"
27#if QT_CONFIG(regularexpression)
28# include "qregularexpression.h"
31#ifndef QT_BOOTSTRAPPED
57#if QT_CONFIG(itemmodel)
58# include "qabstractitemmodel.h"
66#ifndef QT_BOOTSTRAPPED
70#define NS(x) QT_PREPEND_NAMESPACE(x)
77struct QMetaTypeDeleter
80 void operator()(
void *data)
const
82 if (iface->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
83#ifdef __cpp_sized_deallocation
84 operator
delete(data, iface->size,
std::align_val_t(iface->alignment));
86 operator
delete(data, std::align_val_t(iface->alignment));
89#ifdef __cpp_sized_deallocation
90 operator
delete(data, iface->size);
92 operator
delete(data);
99#ifndef QT_BOOTSTRAPPED
101struct QMetaTypeCustomRegistry
107 enum class HasTypedefs :
bool { No, Yes };
110#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
111 QMetaTypeCustomRegistry()
114
115
116
117
118
120 "qfloat16", Alias(QtPrivate::qMetaTypeInterfaceForType<qfloat16>(), HasTypedefs::No));
136 QWriteLocker l(&lock);
137 if (
int id = ti->typeId.loadRelaxed())
141 QMetaObject::normalizedType
144 if (
auto ti2 = aliases.value(name)) {
145 const auto id = ti2->typeId.loadRelaxed();
146 ti->typeId.storeRelaxed(id);
149 aliases[name] = Alias(ti, HasTypedefs::No);
150 int size = registry.size();
151 while (firstEmpty < size && registry[firstEmpty])
153 if (firstEmpty < size) {
154 registry[firstEmpty] = ti;
158 firstEmpty = registry.size();
160 ti->typeId.storeRelaxed(firstEmpty + QMetaType::User);
164 return ti->typeId.loadRelaxed();
167 void unregisterDynamicType(
int id)
171 Q_ASSERT(id > QMetaType::User);
172 QWriteLocker l(&lock);
173 int idx = id - QMetaType::User - 1;
174 auto &ti = registry[idx];
177 auto it = aliases.find(ti->name);
178 if (it->data() == ti) {
180 case HasTypedefs::Yes:
181 aliases.removeIf([ti] (
const auto &kv) {
return kv->data() == ti; });
183 case HasTypedefs::No:
191 firstEmpty =
std::min(firstEmpty, idx);
196 QReadLocker l(&lock);
197 return registry.value(id - QMetaType::User - 1);
201Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry)
206const char *QtMetaTypePrivate::typedefNameForType(
const QtPrivate::QMetaTypeInterface *type_d)
208 const char *name =
nullptr;
209 if (!customTypeRegistry.exists())
211 QMetaTypeCustomRegistry *r = &*customTypeRegistry;
213 QByteArrayView officialName(type_d->name);
214 QReadLocker l(&r->lock);
215 auto it = r->aliases.constBegin();
216 auto end = r->aliases.constEnd();
217 for ( ; it != end; ++it) {
218 if (it->data() != type_d)
220 if (it.key() == officialName)
222 name = it.key().constData();
228 QByteArrayList otherNames;
229 for ( ; it != end; ++it) {
230 if (it->data() == type_d && it.key() != officialName)
231 otherNames << it.key();
234 if (!otherNames.isEmpty())
235 qWarning(
"QMetaType: type %s has more than one typedef alias: %s, %s",
236 type_d->name, name, otherNames.join(
", ").constData());
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
364
365
366
367
368
369
370
371
372
373
374
375
376
377
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
441
442
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
473
474
475
476
477
478
479
480
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
509
510
511
512
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
551
552
553
554
555
556
557
558
561
562
563
564
565
566
567
568
569
572
573
574
575
576
579
580
581
582
583
584
585
586
587#ifndef QT_BOOTSTRAPPED
589
590
591
592int QMetaType::registerHelper(
const QtPrivate::QMetaTypeInterface *iface)
595 auto reg = customTypeRegistry();
597 return reg->registerCustomType(iface);
604
605
606
607
608
609
610
611
612
613
614
615
618
619
620
621
622
623
624
625
626
627
628
629
630
633
634
635
636
637
638
639
640
641
642
643
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
669
670
671
672
673
674
675
676
677
678void *QMetaType::create(
const void *copy)
const
680 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
683 std::unique_ptr<
void, QMetaTypeDeleter> where(
nullptr, {d_ptr});
684 if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
685 where.reset(operator
new(d_ptr->size, std::align_val_t(d_ptr->alignment), std::nothrow_t{}));
687 where.reset(operator
new(d_ptr->size, std::nothrow_t{}));
689 QtMetaTypePrivate::construct(d_ptr, where.get(), copy);
690 return where.release();
694
695
696
697
698
699
700
701
702void QMetaType::destroy(
void *data)
const
704 if (data && isDestructible()) {
705 QtMetaTypePrivate::destruct(d_ptr, data);
706 QMetaTypeDeleter{d_ptr}(data);
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736void *QMetaType::construct(
void *where,
const void *copy)
const
740 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
743 QtMetaTypePrivate::construct(d_ptr, where, copy);
748
749
750
751
752
753
754
755
756
757
758void QMetaType::destruct(
void *data)
const
760 if (data && isDestructible())
761 QtMetaTypePrivate::destruct(d_ptr, data);
764static QPartialOrdering threeWayCompare(
const void *ptr1,
const void *ptr2)
766 std::less<
const void *> less;
767 if (less(ptr1, ptr2))
768 return QPartialOrdering::Less;
769 if (less(ptr2, ptr1))
770 return QPartialOrdering::Greater;
771 return QPartialOrdering::Equivalent;
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800QPartialOrdering QMetaType::compare(
const void *lhs,
const void *rhs)
const
803 return QPartialOrdering::Unordered;
804 if (d_ptr && d_ptr->flags & QMetaType::IsPointer)
805 return threeWayCompare(*
reinterpret_cast<
const void *
const *>(lhs),
806 *
reinterpret_cast<
const void *
const *>(rhs));
807 if (d_ptr && d_ptr->lessThan) {
808 if (d_ptr->equals && d_ptr->equals(d_ptr, lhs, rhs))
809 return QPartialOrdering::Equivalent;
810 if (d_ptr->lessThan(d_ptr, lhs, rhs))
811 return QPartialOrdering::Less;
812 if (d_ptr->lessThan(d_ptr, rhs, lhs))
813 return QPartialOrdering::Greater;
815 return QPartialOrdering::Equivalent;
817 return QPartialOrdering::Unordered;
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836bool QMetaType::equals(
const void *lhs,
const void *rhs)
const
841 if (d_ptr->flags & QMetaType::IsPointer)
842 return *
reinterpret_cast<
const void *
const *>(lhs) == *
reinterpret_cast<
const void *
const *>(rhs);
845 return d_ptr->equals(d_ptr, lhs, rhs);
846 if (d_ptr->lessThan && !d_ptr->lessThan(d_ptr, lhs, rhs) && !d_ptr->lessThan(d_ptr, rhs, lhs))
853
854
855
856
857
858
859
860
861
864
865
866
867
868
869
870
871
872
875
876
877
878
879
880
881
882
885
886
887
888
889
890
891
892
894bool QMetaType::isDefaultConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
896 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDefaultConstructible(iface);
899bool QMetaType::isCopyConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
901 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isCopyConstructible(iface);
904bool QMetaType::isMoveConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
906 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isMoveConstructible(iface);
909bool QMetaType::isDestructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
911 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDestructible(iface);
915
916
917
918
919
920bool QMetaType::isEqualityComparable()
const
922 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->equals !=
nullptr || d_ptr->lessThan !=
nullptr);
926
927
928
929
930
931bool QMetaType::isOrdered()
const
933 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->lessThan !=
nullptr);
936#ifndef QT_BOOTSTRAPPED
938
939
940void QMetaType::unregisterMetaType(QMetaType type)
942 const QtPrivate::QMetaTypeInterface *d_ptr = type.d_ptr;
946 const int typeId = d_ptr->typeId.loadRelaxed();
947 if (typeId < QMetaType::User)
952 if (
auto reg = customTypeRegistry()) {
953 Q_ASSERT(reg->getCustomType(typeId) == d_ptr);
954 reg->unregisterDynamicType(typeId);
957 const_cast<QtPrivate::QMetaTypeInterface *>(d_ptr)->typeId.storeRelease(0);
962
963
964
965
966
969
970
971
972
973
974
977
978
979
980
981
982
984static constexpr auto createStaticTypeToIdMap()
986#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
988#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
990 constexpr auto staticTypeNames = qOffsetStringArray(
995 constexpr int Count = staticTypeNames.count();
996#undef QT_ADD_STATIC_METATYPE
997#undef QT_ADD_STATIC_METATYPE_ALIASES_ITER
999#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
1001#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
1002 QMetaType::MetaTypeName,
1003 std::array<
int, Count> typeIds = {
1006 QMetaTypeId2<qreal>::MetaType,
1008#undef QT_ADD_STATIC_METATYPE
1009#undef QT_ADD_STATIC_METATYPE_ALIASES_ITER
1011 using Base = std::remove_cv_t<
decltype(staticTypeNames)>;
1012 using Array = std::remove_cv_t<
decltype(typeIds)>;
1014 constexpr Map(
const Base &base,
const Array &typeIdMap)
1015 : Base(base), typeIdMap(typeIdMap)
1017 std::array<
int, Count> typeIdMap;
1020 return Map(staticTypeNames, typeIds);
1022static constexpr auto types = createStaticTypeToIdMap();
1024template <
typename From,
typename To>
1029 static_assert(
std::numeric_limits<From>::is_iec559);
1031 static_assert(
std::is_integral_v<To>);
1032 static_assert(
sizeof(From) <=
sizeof(
double));
1033 const double fromD =
static_cast<
double>(from);
1035 if (qt_is_nan(fromD)) {
1041 convertDoubleTo(std::round(fromD), &result);
1049 template<
typename T,
typename LiteralWrapper =
1050 std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView,
const char *>>
1051 static inline bool convertToBool(
const T &source)
1053 T str = source.toLower();
1054 return !(str.isEmpty() || str == LiteralWrapper(
"0") || str == LiteralWrapper(
"false"));
1070 static bool convert(
const void *from,
int fromTypeId,
void *to,
int toTypeId)
1072 Q_ASSERT(fromTypeId != toTypeId);
1074#ifdef QT_BOOTSTRAPPED
1079 bool onlyCheck = (from ==
nullptr && to ==
nullptr);
1082 Q_ASSERT(onlyCheck || (
bool(from) &&
bool(to)));
1085 using SChar =
signed char;
1086 using UChar =
unsigned char;
1087 using Short =
short;
1088 using UShort =
unsigned short;
1090 using UInt =
unsigned int;
1092 using LongLong = qlonglong;
1093 using ULong =
unsigned long;
1094 using ULongLong = qulonglong;
1096 using Float =
float;
1097 using Double =
double;
1099 using Nullptr =
std::nullptr_t;
1100 using Char16 =
char16_t;
1101 using Char32 =
char32_t;
1103#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From)
1105#define QMETATYPE_CONVERTER_ASSIGN_NUMBER(To, From)
1107#define CONVERT_CBOR_AND_JSON(To)
1109 if constexpr(std::is_same_v<To, Bool>) {
1110 if (!source.isBool())
1112 result = source.toBool();
1114 if (!source.isInteger() && !source.isDouble())
1116 if constexpr(std::is_integral_v<To>)
1117 result = source.toInteger();
1119 result = To(source.toDouble());
1124 if constexpr(std::is_same_v<To, Bool>) {
1125 if (!source.isBool())
1127 result = source.toBool();
1129 if (!source.isDouble())
1131 if constexpr(std::is_integral_v<To>)
1132 result = source.toInteger();
1134 result = To(source.toDouble());
1139#define INTEGRAL_CONVERTER(To)
1152 QMETATYPE_CONVERTER(To, Float16, return qIntegerConversionFromFPHelper(source, &result););
1158 if constexpr(std::is_same_v<To, bool>)
1159 result = (ok = true, convertToBool(source));
1160 else if constexpr(std::is_signed_v<To>)
1161 result = To(source.toLongLong(&ok));
1163 result = To(source.toULongLong(&ok));
1168 if constexpr(std::is_same_v<To, bool>)
1169 result = (ok = true, convertToBool(source));
1170 else if constexpr(std::is_signed_v<To>)
1171 result = To(source.toLongLong(&ok));
1173 result = To(source.toULongLong(&ok));
1178#define FLOAT_CONVERTER(To)
1196 result = To(source.toDouble(&ok));
1201 result = To(source.toDouble(&ok));
1206 switch (makePair(toTypeId, fromTypeId)) {
1208QT_WARNING_DISABLE_CLANG(
"-Wtautological-compare")
1228 if (source.isUrl()) {
1229 result = source.toUrl();
1234#if QT_CONFIG(itemmodel)
1235 QMETATYPE_CONVERTER_ASSIGN(QModelIndex, QPersistentModelIndex);
1236 QMETATYPE_CONVERTER_ASSIGN(QPersistentModelIndex, QModelIndex);
1240#define QMETATYPE_CONVERTER_ASSIGN_QCHAR(From)
1273 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1277 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1281 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1285 result = QString::fromLatin1(&source, 1);
1290 result = QString::fromLatin1(&s, 1);
1295 result = QString::fromLatin1(&s, 1);
1299 result = QChar(source);
1303 result = QChar::fromUcs4(source).operator QStringView().toString();
1306#if QT_CONFIG(datestring)
1307 QMETATYPE_CONVERTER(QString, QDate, result = source.toString(Qt::ISODate);
return true;);
1308 QMETATYPE_CONVERTER(QString, QTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1309 QMETATYPE_CONVERTER(QString, QDateTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1313 return (source.size() == 1) ? (result = source.at(0),
true) :
false;
1317 if (source.isString() || source.isNull()) {
1318 result = source.toString();
1323 QMETATYPE_CONVERTER(QString, Nullptr, Q_UNUSED(source); result = QString();
return true;);
1328 result = source ?
"true" :
"false";
1343 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1347 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1351 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1370 QMETATYPE_CONVERTER(QStringList, QString, result = QStringList() << source;
return true;);
1373 result.reserve(source.size());
1374 for (
const auto &v: source)
1375 result.append(v.toByteArray());
1379 result.reserve(source.size());
1380 for (
const auto &v: source)
1381 result.append(QVariant(v));
1386 result.reserve(source.size());
1387 for (
const auto &v: source)
1388 result.append(v.toString());
1392 result.reserve(source.size());
1393 for (
const auto &v: source)
1394 result.append(QVariant(v));
1399 for (
auto it = source.begin(); it != source.end(); ++it)
1400 result.insert(it.key(), it.value());
1404 for (
auto it = source.begin(); it != source.end(); ++it)
1405 result.insert(it.key(), it.value());
1410 if (source.isContainer() || source.isTag())
1412 result = source.toVariant().toString();
1417 if (source.isByteArray()) {
1418 result = source.toByteArray();
1425 if (!source.isUuid())
1427 result = source.toUuid();
1432 if (!source.isArray())
1434 result = source.toArray().toVariantList();
1437 QMETATYPE_CONVERTER(QCborValue, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1439 if (!source.isMap())
1441 result = source.toMap().toVariantMap();
1444 QMETATYPE_CONVERTER(QCborValue, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1446 if (!source.isMap())
1448 result = source.toMap().toVariantHash();
1451#if QT_CONFIG(regularexpression)
1452 QMETATYPE_CONVERTER(QCborValue, QRegularExpression, result = QCborValue(source);
return true;);
1453 QMETATYPE_CONVERTER(QRegularExpression, QCborValue,
1454 if (!source.isRegularExpression())
1456 result = source.toRegularExpression();
1463 result = QCborValue(QCborValue::Null);
1468 return source.isNull();
1486 result = QCborArray::fromStringList(source);
1489#if QT_CONFIG(datestring)
1490 QMETATYPE_CONVERTER(QCborValue, QDate,
1491 result = QCborValue(source.startOfDay());
1497 result = QCborValue::fromJsonValue(source);
1501 result = QCborMap::fromJsonObject(source);
1505 result = QCborArray::fromJsonArray(source);
1509 QJsonDocument doc = source;
1511 result = QCborArray::fromJsonArray(doc.array());
1513 result = QCborMap::fromJsonObject(doc.object());
1519#if QT_CONFIG(datestring)
1520 QMETATYPE_CONVERTER_ASSIGN(QCborValue, QDateTime);
1521 QMETATYPE_CONVERTER(QDateTime, QCborValue,
1522 if (source.isDateTime()) {
1523 result = source.toDateTime();
1532 if (source.isSimpleType()) {
1533 result = source.toSimpleType();
1541 QMETATYPE_CONVERTER(QCborArray, QStringList, result = QCborArray::fromStringList(source);
return true;);
1542 QMETATYPE_CONVERTER(QCborMap, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1544 QMETATYPE_CONVERTER(QCborMap, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1545 QMETATYPE_CONVERTER(QVariantHash, QCborMap, result = source.toVariantHash();
return true;);
1548 if (!source.isArray())
1550 result = source.toArray();
1554 if (!source.isArray())
1556 result = QCborArray::fromJsonArray(source.array());
1560 if (!source.isArray())
1562 result = QCborArray::fromJsonArray(source.toArray());
1566 result = QCborArray::fromJsonArray(source);
1570 if (!source.isMap())
1572 result = source.toMap();
1576 if (source.isArray())
1578 result = QCborMap::fromJsonObject(source.object());
1582 if (!source.isObject())
1584 result = QCborMap::fromJsonObject(source.toObject());
1588 result = QCborMap::fromJsonObject(source);
1594 if (!source.isArray())
1596 result = source.toArray().toVariantList();
1601 if (!source.isObject())
1603 result = source.toObject().toVariantMap();
1606 QMETATYPE_CONVERTER(QVariantMap, QJsonObject, result = source.toVariantMap();
return true;);
1608 if (!source.isObject())
1610 result = source.toObject().toVariantHash();
1613 QMETATYPE_CONVERTER(QVariantHash, QJsonObject, result = source.toVariantHash();
return true;);
1616 QMETATYPE_CONVERTER(QJsonArray, QStringList, result = QJsonArray::fromStringList(source);
return true;);
1619 if (!source.isArray())
1621 result = source.toArray();
1625 if (!source.isArray())
1627 result = source.array();
1631 if (!source.isArray())
1633 result = source.toArray().toJsonArray();
1637 QMETATYPE_CONVERTER(QJsonObject, QVariantMap, result = QJsonObject::fromVariantMap(source);
return true;);
1638 QMETATYPE_CONVERTER(QJsonObject, QVariantHash, result = QJsonObject::fromVariantHash(source);
return true;);
1640 if (!source.isObject())
1642 result = source.toObject();
1646 if (source.isArray())
1648 result = source.object();
1652 if (!source.isMap())
1654 result = source.toMap().toJsonObject();
1657 QMETATYPE_CONVERTER(QJsonObject, QCborMap, result = source.toJsonObject();
return true; );
1661 result = QJsonValue(QJsonValue::Null);
1666 return source.isNull();
1669 result = QJsonValue(source);
1687 result = QJsonValue(QJsonArray::fromStringList(source));
1691 result = QJsonValue(QJsonArray::fromVariantList(source));
1695 result = QJsonValue(QJsonObject::fromVariantMap(source));
1699 result = QJsonValue(QJsonObject::fromVariantHash(source));
1711 QJsonDocument doc = source;
1712 result = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1716 result = source.toJsonValue();
1720 result = source.toJsonObject();
1724 result = source.toJsonArray();
1731#if QT_CONFIG(datestring)
1732 QMETATYPE_CONVERTER(QDate, QString,
1733 result = QDate::fromString(source, Qt::ISODate);
1734 return result.isValid();
1736 QMETATYPE_CONVERTER(QTime, QString,
1737 result = QTime::fromString(source, Qt::ISODate);
1738 return result.isValid();
1740 QMETATYPE_CONVERTER(QDateTime, QString,
1741 result = QDateTime::fromString(source, Qt::ISODate);
1742 return result.isValid();
1754Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeGuiHelper = {};
1755Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeWidgetsHelper = {};
1757#ifndef QT_BOOTSTRAPPED
1760 int type = qMax(fromTypeId, toTypeId);
1761 if (type <= QMetaType::LastCoreType)
1762 return QCoreVariantHelper::convert(from, fromTypeId, to, toTypeId);
1763 if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType)
1764 return qMetaTypeGuiHelper.convert(from, fromTypeId, to, toTypeId);
1765 else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType)
1766 return qMetaTypeWidgetsHelper.convert(from, fromTypeId, to, toTypeId);
1770template<
typename T,
typename Key>
1776 const QWriteLocker locker(&lock);
1782 const QReadLocker locker(&lock);
1783 return map.contains(k);
1788 const QWriteLocker locker(&lock);
1789 auto r = map.tryEmplace(k, f);
1795 const QReadLocker locker(&lock);
1796 auto it = map.find(k);
1797 return it == map.end() ?
nullptr :
std::addressof(*it);
1802 const Key k(from, to);
1803 const QWriteLocker locker(&lock);
1807 mutable QReadWriteLock lock;
1811using QMetaTypeConverterRegistry
1812 = QMetaTypeFunctionRegistry<QMetaType::ConverterFunction, std::pair<
int,
int>>;
1814Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
1816using QMetaTypeMutableViewRegistry
1817 = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, std::pair<
int,
int>>;
1818Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
1821
1822
1823
1824
1825
1826
1827
1830
1831
1832
1833
1834
1835
1836
1837
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1865
1866
1867
1868
1870
1871bool QMetaType::registerConverterFunction(
const ConverterFunction &f, QMetaType from, QMetaType to)
1873 if (!customTypesConversionRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1874 qWarning(
"Type conversion already registered from type %s to type %s",
1875 from.name(), to.name());
1882
1883
1884
1885
1886
1887
1888
1891
1892
1893
1894
1895
1896
1899
1900
1901
1903
1904bool QMetaType::registerMutableViewFunction(
const MutableViewFunction &f, QMetaType from, QMetaType to)
1906 if (!customTypesMutableViewRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1907 qWarning(
"Mutable view on type already registered from type %s to type %s",
1908 from.name(), to.name());
1916
1917void QMetaType::unregisterMutableViewFunction(QMetaType from, QMetaType to)
1919 if (customTypesMutableViewRegistry.isDestroyed())
1921 customTypesMutableViewRegistry()->remove(from.id(), to.id());
1925
1926
1928
1929void QMetaType::unregisterConverterFunction(QMetaType from, QMetaType to)
1931 if (customTypesConversionRegistry.isDestroyed())
1933 customTypesConversionRegistry()->remove(from.id(), to.id());
1937#ifndef QT_NO_DEBUG_STREAM
1940
1941
1943
1944QDebug operator<<(QDebug d, QMetaType m)
1946 const QDebugStateSaver saver(d);
1947 return d.nospace() <<
"QMetaType(" << m.name() <<
")";
1951
1952
1954
1955bool QMetaType::debugStream(QDebug& dbg,
const void *rhs)
1957 if (d_ptr && d_ptr->flags & QMetaType::IsPointer) {
1958 dbg << *
reinterpret_cast<
const void *
const *>(rhs);
1961 if (d_ptr && d_ptr->debugStream) {
1962 d_ptr->debugStream(d_ptr, dbg, rhs);
1969
1970
1971
1972
1975
1976
1977
1978
1979
1980
1983
1984
1985
1986
1987
1988
1989
1992
1993
1994
1996
1997bool QMetaType::hasRegisteredDebugStreamOperator()
const
1999 return d_ptr && d_ptr->debugStream !=
nullptr;
2003#ifndef QT_NO_QOBJECT
2005
2007
2008static QMetaEnum metaEnumFromType(QMetaType t)
2010 if (t.flags() & QMetaType::IsEnumeration) {
2011 if (
const QMetaObject *metaObject = t.metaObject()) {
2012 QByteArrayView qflagsNamePrefix =
"QFlags<";
2014 if (enumName.endsWith(
'>') && enumName.startsWith(qflagsNamePrefix)) {
2017 enumName = enumName.sliced(qflagsNamePrefix.size());
2019 if (qsizetype lastColon = enumName.lastIndexOf(
':'); lastColon != -1)
2020 enumName = enumName.sliced(lastColon + 1);
2021 return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
2028#ifndef QT_BOOTSTRAPPED
2029static bool convertFromEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2032 if (fromType.flags() & QMetaType::IsUnsignedEnumeration) {
2034 switch (fromType.sizeOf()) {
2036 ull = *
static_cast<
const unsigned char *>(from);
2039 ull = *
static_cast<
const unsigned short *>(from);
2042 ull = *
static_cast<
const unsigned int *>(from);
2045 ull = *
static_cast<
const quint64 *>(from);
2050 if (toType.id() == QMetaType::ULongLong) {
2051 *
static_cast<qulonglong *>(to) = ull;
2054 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2055 return QMetaType::convert(QMetaType::fromType<qulonglong>(), &ull, toType, to);
2056 ll = qlonglong(ull);
2058 switch (fromType.sizeOf()) {
2060 ll = *
static_cast<
const signed char *>(from);
2063 ll = *
static_cast<
const short *>(from);
2066 ll = *
static_cast<
const int *>(from);
2069 ll = *
static_cast<
const qint64 *>(from);
2074 if (toType.id() == QMetaType::LongLong) {
2075 *
static_cast<qlonglong *>(to) = ll;
2078 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2079 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2081#ifndef QT_NO_QOBJECT
2082 QMetaEnum en = metaEnumFromType(fromType);
2086 if (toType.id() == QMetaType::QString)
2087 *
static_cast<QString *>(to) = QString::fromUtf8(keys);
2091 const char *key = en.valueToKey(ll);
2092 if (toType.id() == QMetaType::QString)
2093 *
static_cast<QString *>(to) = QString::fromUtf8(key);
2100 if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray)
2101 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2105static bool convertToEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2107 int fromTypeId = fromType.id();
2108 qlonglong value = -1;
2110#ifndef QT_NO_QOBJECT
2111 if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) {
2112 QMetaEnum en = metaEnumFromType(toType);
2114 QByteArray keys = (fromTypeId == QMetaType::QString)
2115 ?
static_cast<
const QString *>(from)->toUtf8()
2116 : *
static_cast<
const QByteArray *>(from);
2117 if (
auto v = en.keysToValue64(keys.constData())) {
2125 if (fromTypeId == QMetaType::LongLong) {
2126 value = *
static_cast<
const qlonglong *>(from);
2129 ok = QMetaType::convert(fromType, from, QMetaType::fromType<qlonglong>(), &value);
2136 switch (toType.sizeOf()) {
2138 *
static_cast<
signed char *>(to) = value;
2141 *
static_cast<qint16 *>(to) = value;
2144 *
static_cast<qint32 *>(to) = value;
2147 *
static_cast<qint64 *>(to) = value;
2150 Q_UNREACHABLE_RETURN(
false);
2154static bool convertIterableToVariantList(QMetaType fromType,
const void *from,
void *to)
2157 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QSequentialIterable>(), &list))
2162 l.reserve(list.size());
2163 auto end = list.end();
2164 for (
auto it = list.begin(); it != end; ++it)
2169static bool convertIterableToVariantMap(QMetaType fromType,
const void *from,
void *to)
2172 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QAssociativeIterable>(), &map))
2175 QVariantMap &h = *
static_cast<QVariantMap *>(to);
2177 auto end = map.end();
2178 for (
auto it = map.begin(); it != end; ++it)
2179 h.insert(it.key().toString(), it.value());
2183static bool convertIterableToVariantHash(QMetaType fromType,
const void *from,
void *to)
2186 if (!QMetaType::convert(fromType, from, QMetaType::fromType<QAssociativeIterable>(), &map))
2189 QVariantHash &h = *
static_cast<QVariantHash *>(to);
2191 h.reserve(map.size());
2192 auto end = map.end();
2193 for (
auto it = map.begin(); it != end; ++it)
2194 h.insert(it.key().toString(), it.value());
2198static bool convertIterableToVariantPair(QMetaType fromType,
const void *from,
void *to)
2201 const auto f = customTypesConversionRegistry()->function({fromType.id(), targetId});
2209 QVariant v1(pi._metaType_first);
2211 if (pi._metaType_first == QMetaType::fromType<QVariant>())
2214 dataPtr = v1.data();
2217 QVariant v2(pi._metaType_second);
2218 if (pi._metaType_second == QMetaType::fromType<QVariant>())
2221 dataPtr = v2.data();
2224 *
static_cast<QVariantPair *>(to) = QVariantPair(v1, v2);
2228static bool convertToSequentialIterable(QMetaType fromType,
const void *from,
void *to)
2231 const int fromTypeId = fromType.id();
2233 QSequentialIterable &i = *
static_cast<QSequentialIterable *>(to);
2234 switch (fromTypeId) {
2235 case QMetaType::QVariantList:
2236 i = QSequentialIterable(
reinterpret_cast<
const QVariantList *>(from));
2238 case QMetaType::QStringList:
2239 i = QSequentialIterable(
reinterpret_cast<
const QStringList *>(from));
2241 case QMetaType::QByteArrayList:
2242 i = QSequentialIterable(
reinterpret_cast<
const QByteArrayList *>(from));
2244 case QMetaType::QString:
2245 i = QSequentialIterable(
reinterpret_cast<
const QString *>(from));
2247 case QMetaType::QByteArray:
2248 i = QSequentialIterable(
reinterpret_cast<
const QByteArray *>(from));
2252 if (QMetaType::convert(
2253 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &impl)) {
2254 i = std::move(impl);
2263static bool canConvertToSequentialIterable(QMetaType fromType)
2265 switch (fromType.id()) {
2266 case QMetaType::QVariantList:
2267 case QMetaType::QStringList:
2268 case QMetaType::QByteArrayList:
2269 case QMetaType::QString:
2270 case QMetaType::QByteArray:
2273 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2277static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType)
2279 switch (fromType.id()) {
2280 case QMetaType::QVariantList:
2281 case QMetaType::QStringList:
2282 case QMetaType::QByteArrayList:
2283 case QMetaType::QString:
2284 case QMetaType::QByteArray:
2287 return QMetaType::canView(
2288 fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2292static bool viewAsSequentialIterable(QMetaType fromType,
void *from,
void *to)
2295 const int fromTypeId = fromType.id();
2297 QSequentialIterable &i = *
static_cast<QSequentialIterable *>(to);
2298 switch (fromTypeId) {
2299 case QMetaType::QVariantList:
2300 i = QSequentialIterable(
reinterpret_cast<QVariantList *>(from));
2302 case QMetaType::QStringList:
2303 i = QSequentialIterable(
reinterpret_cast<QStringList *>(from));
2305 case QMetaType::QByteArrayList:
2306 i = QSequentialIterable(
reinterpret_cast<QByteArrayList *>(from));
2308 case QMetaType::QString:
2309 i = QSequentialIterable(
reinterpret_cast<QString *>(from));
2311 case QMetaType::QByteArray:
2312 i = QSequentialIterable(
reinterpret_cast<QByteArray *>(from));
2315 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2316 if (QMetaType::view(
2317 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2327static bool convertToAssociativeIterable(QMetaType fromType,
const void *from,
void *to)
2331 QAssociativeIterable &i = *
static_cast<QAssociativeIterable *>(to);
2332 if (fromType.id() == QMetaType::QVariantMap) {
2333 i = QAssociativeIterable(
reinterpret_cast<
const QVariantMap *>(from));
2336 if (fromType.id() == QMetaType::QVariantHash) {
2337 i = QAssociativeIterable(
reinterpret_cast<
const QVariantHash *>(from));
2342 if (QMetaType::convert(
2343 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &impl)) {
2344 i = std::move(impl);
2351static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
2353 if ((fromType.flags() & QMetaType::IsPointer) != (toType.flags() & QMetaType::IsPointer))
2356 const QMetaObject *f = fromType.metaObject();
2357 const QMetaObject *t = toType.metaObject();
2359 return f->inherits(t) || (t->inherits(f));
2364static bool canConvertToAssociativeIterable(QMetaType fromType)
2366 switch (fromType.id()) {
2367 case QMetaType::QVariantMap:
2368 case QMetaType::QVariantHash:
2371 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2375static bool canImplicitlyViewAsAssociativeIterable(QMetaType fromType)
2377 switch (fromType.id()) {
2378 case QMetaType::QVariantMap:
2379 case QMetaType::QVariantHash:
2382 return QMetaType::canView(
2383 fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2387static bool viewAsAssociativeIterable(QMetaType fromType,
void *from,
void *to)
2390 int fromTypeId = fromType.id();
2392 QAssociativeIterable &i = *
static_cast<QAssociativeIterable *>(to);
2393 if (fromTypeId == QMetaType::QVariantMap) {
2394 i = QAssociativeIterable(
reinterpret_cast<QVariantMap *>(from));
2397 if (fromTypeId == QMetaType::QVariantHash) {
2398 i = QAssociativeIterable(
reinterpret_cast<QVariantHash *>(from));
2402 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2403 if (QMetaType::view(
2404 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2412static bool convertMetaObject(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2415 if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
2416 QObject *fromObject = *
static_cast<QObject *
const *>(from);
2418 if (fromObject && fromObject->metaObject()->inherits(toType.metaObject())) {
2419 *
static_cast<QObject **>(to) = toType.metaObject()->cast(fromObject);
2421 }
else if (!fromObject && fromType.metaObject()) {
2423 *
static_cast<
void **>(to) =
nullptr;
2424 return fromType.metaObject()->inherits(toType.metaObject());
2426 }
else if ((fromType.flags() & QMetaType::IsPointer) == (toType.flags() & QMetaType::IsPointer)) {
2428 const QMetaObject *f = fromType.metaObject();
2429 const QMetaObject *t = toType.metaObject();
2430 if (f && t && f->inherits(t)) {
2431 toType.destruct(to);
2432 toType.construct(to, from);
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2452
2453
2454
2455
2456
2458
2459bool QMetaType::convert(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2461 if (!fromType.isValid() || !toType.isValid())
2464 if (fromType == toType) {
2466 fromType.destruct(to);
2467 fromType.construct(to, from);
2471 int fromTypeId = fromType.id();
2472 int toTypeId = toType.id();
2474 if (tryConvertBuiltinTypes(from, fromTypeId, to, toTypeId))
2476 const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId});
2478 return (*f)(from, to);
2480 if (fromType.flags() & QMetaType::IsEnumeration)
2481 return convertFromEnum(fromType, from, toType, to);
2482 if (toType.flags() & QMetaType::IsEnumeration)
2483 return convertToEnum(fromType, from, toType, to);
2484 if (toTypeId == Nullptr) {
2485 *
static_cast<std::nullptr_t *>(to) =
nullptr;
2486 if (fromType.flags() & QMetaType::IsPointer) {
2487 if (*
static_cast<
const void *
const *>(from) ==
nullptr)
2492 if (toTypeId == QVariantPair && convertIterableToVariantPair(fromType, from, to))
2496 if (toTypeId == QVariantList && convertIterableToVariantList(fromType, from, to))
2499 if (toTypeId == QVariantMap && convertIterableToVariantMap(fromType, from, to))
2502 if (toTypeId == QVariantHash && convertIterableToVariantHash(fromType, from, to))
2505 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2506 return convertToSequentialIterable(fromType, from, to);
2508 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2509 return convertToAssociativeIterable(fromType, from, to);
2511 return convertMetaObject(fromType, from, toType, to);
2515
2516
2518
2519bool QMetaType::view(QMetaType fromType,
void *from, QMetaType toType,
void *to)
2521 if (!fromType.isValid() || !toType.isValid())
2524 int fromTypeId = fromType.id();
2525 int toTypeId = toType.id();
2527 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2529 return (*f)(from, to);
2531 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2532 return viewAsSequentialIterable(fromType, from, to);
2534 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2535 return viewAsAssociativeIterable(fromType, from, to);
2537 return convertMetaObject(fromType, from, toType, to);
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2556
2557bool QMetaType::canView(QMetaType fromType, QMetaType toType)
2559 int fromTypeId = fromType.id();
2560 int toTypeId = toType.id();
2562 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2565 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2569 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2570 return canImplicitlyViewAsSequentialIterable(fromType);
2572 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2573 return canImplicitlyViewAsAssociativeIterable(fromType);
2575 if (canConvertMetaObject(fromType, toType))
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2665
2666bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
2668 int fromTypeId = fromType.id();
2669 int toTypeId = toType.id();
2671 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2674 if (fromTypeId == toTypeId)
2677 if (tryConvertBuiltinTypes(
nullptr, fromTypeId,
nullptr, toTypeId))
2680 const ConverterFunction *
const f =
2681 customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId));
2685 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2686 return canConvertToSequentialIterable(fromType);
2688 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2689 return canConvertToAssociativeIterable(fromType);
2690 if (toTypeId == QVariantList
2691 && canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
2695 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2696 && canConvert(fromType, QMetaType::fromType<QAssociativeIterable>())) {
2700 if (toTypeId == QVariantPair && hasRegisteredConverterFunction(
2701 fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
2704 if (fromType.flags() & IsEnumeration) {
2705 if (toTypeId == QString || toTypeId == QByteArray)
2707 return canConvert(QMetaType(LongLong), toType);
2709 if (toType.flags() & IsEnumeration) {
2710 if (fromTypeId == QString || fromTypeId == QByteArray)
2712 return canConvert(fromType, QMetaType(LongLong));
2714 if (toTypeId == Nullptr && fromType.flags() & IsPointer)
2716 if (canConvertMetaObject(fromType, toType))
2723
2724
2725
2726
2727
2728
2729
2732
2733
2734
2735
2736
2739
2740
2742
2743bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType)
2745 return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
2749
2751
2752bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
2754 const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2755 return QMetaType::hasRegisteredConverterFunction(m, to);
2759
2761
2762bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
2764 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2765 return QMetaType::hasRegisteredConverterFunction(m, to);
2769
2771
2772bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
2774 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2775 return QMetaType::hasRegisteredConverterFunction(m, to);
2779
2780
2781
2782
2783
2786
2787
2789
2790bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType)
2792 return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
2796
2798
2799bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
2801 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2802 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2806
2808
2809bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
2811 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2812 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2817
2818
2819
2820
2821
2822
2823
2824
2825
2828
2829
2830
2831
2832
2833
2834
2835
2836
2840
2841static inline int qMetaTypeStaticType(QByteArrayView name)
2843 for (
int i = 0; i < types.count(); ++i) {
2844 if (types.viewAt(i) == name)
2845 return types.typeIdMap[i];
2847 return QMetaType::UnknownType;
2850#ifndef QT_BOOTSTRAPPED
2852
2853
2854
2855
2857
2858void QMetaType::registerNormalizedTypedef(
const NS(QByteArray) & normalizedTypeName,
2861 if (!metaType.isValid())
2863 if (
auto reg = customTypeRegistry()) {
2864 QWriteLocker lock(®->lock);
2865 auto &al = reg->aliases[normalizedTypeName];
2869 al = QMetaTypeCustomRegistry::Alias(
2870 metaType.d_ptr, QMetaTypeCustomRegistry::HasTypedefs::Yes);
2871 reg->aliases[metaType.name()].setTag(QMetaTypeCustomRegistry::HasTypedefs::Yes);
2878 Q_ASSERT(typeId < QMetaType::User);
2879 if (typeId <= QMetaType::LastCoreType)
2880 return QCoreVariantHelper::interfaceForType(typeId);
2881 if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType)
2882 return qMetaTypeGuiHelper.interfaceForType(typeId);
2883 if (typeId >= QMetaType::FirstWidgetsType && typeId <= QMetaType::LastWidgetsType)
2884 return qMetaTypeWidgetsHelper.interfaceForType(typeId);
2891 if (typeId >= QMetaType::User) {
2892#ifndef QT_BOOTSTRAPPED
2893 if (customTypeRegistry.exists())
2894 iface = customTypeRegistry->getCustomType(typeId);
2897 iface = interfaceForStaticType(typeId);
2903
2904
2905
2907
2908bool QMetaType::isRegistered(
int type)
2910 return interfaceForTypeNoWarning(type) !=
nullptr;
2915 Q_PRE(!name.isEmpty());
2916 int type = qMetaTypeStaticType(name);
2917 if (type != QMetaType::UnknownType) {
2918 return interfaceForStaticType(type);
2919#ifndef QT_BOOTSTRAPPED
2920 }
else if (customTypeRegistry.exists()) {
2921 QReadLocker locker(&customTypeRegistry->lock);
2922 auto it = customTypeRegistry->aliases.constFind(name);
2923 if (it != customTypeRegistry->aliases.constEnd())
2924 return it.value().data();
2931
2932
2933
2934
2935
2936
2937
2938
2941
2942
2943
2944
2945
2946
2948
2949int qMetaTypeTypeInternal(QByteArrayView name)
2952 if (!name.isEmpty())
2953 iface = findMetaTypeByName(name);
2954 return iface ? iface->typeId.loadRelaxed() : QMetaType::UnknownType;
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2970#ifndef QT_NO_DATASTREAM
2972
2973
2974
2975
2976
2977
2978
2979
2981
2982bool QMetaType::save(QDataStream &stream,
const void *data)
const
2984 if (!data || !isValid())
2988 if (id() == QMetaType::Long) {
2989 stream << qlonglong(*(
long *)data);
2991 }
else if (id() == QMetaType::ULong) {
2992 stream << qlonglong(*(
unsigned long *)data);
2996 if (!d_ptr->dataStreamOut)
2999 d_ptr->dataStreamOut(d_ptr, stream, data);
3004
3005
3006
3007
3010
3011
3012
3013
3014
3015
3016
3017
3019
3020bool QMetaType::load(QDataStream &stream,
void *data)
const
3022 if (!data || !isValid())
3026 if (id() == QMetaType::Long) {
3029 *(
long *)data =
long(ll);
3031 }
else if (id() == QMetaType::ULong) {
3034 *(
unsigned long *)data = (
unsigned long)(ull);
3037 if (!d_ptr->dataStreamIn)
3040 d_ptr->dataStreamIn(d_ptr, stream, data);
3045
3046
3047
3049
3050bool QMetaType::hasRegisteredDataStreamOperators()
const
3053 if (type == QMetaType::Long || type == QMetaType::ULong)
3055 return d_ptr && d_ptr->dataStreamIn !=
nullptr && d_ptr->dataStreamOut !=
nullptr;
3059
3060
3061
3062
3063
3064
3066
3067QMetaType QMetaType::underlyingType()
const
3069 if (!d_ptr || !(flags() & IsEnumeration))
3072
3073
3074
3075
3076
3077
3078 if (flags() & IsUnsignedEnumeration) {
3081 return QMetaType::fromType<quint8>();
3083 return QMetaType::fromType<quint16>();
3085 return QMetaType::fromType<quint32>();
3087 return QMetaType::fromType<quint64>();
3094 return QMetaType::fromType<qint8>();
3096 return QMetaType::fromType<qint16>();
3098 return QMetaType::fromType<qint32>();
3100 return QMetaType::fromType<qint64>();
3110
3111
3112
3113
3117
3119
3120QMetaType QMetaType::fromName(QByteArrayView typeName)
3122 if (typeName.isEmpty())
3125 const QtPrivate::QMetaTypeInterface *iface = findMetaTypeByName(typeName);
3127 return QMetaType(iface);
3129#if !defined(QT_NO_QOBJECT)
3130 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName.constData());
3131 if (normalizedTypeName != typeName)
3132 iface = findMetaTypeByName(normalizedTypeName);
3135 return QMetaType(iface);
3139
3140
3141
3142
3143
3144
3145
3146
3149
3150
3151
3152
3153
3154
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3214
3215
3216
3217
3218
3219
3220
3221
3224
3225
3226
3227
3228
3229
3230
3231
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3348 if (!iface && typeId != QMetaType::UnknownType)
3349 qWarning(
"Trying to construct an instance of an invalid type, type id: %i", typeId);
3355
3356
3357
3358
3359
3362
3363
3364
3366
3367QMetaType::QMetaType(
int typeId) : QMetaType(interfaceForType(typeId)) {}
3371
3372
3373
3374
3376namespace QtPrivate {
3377#if !defined(QT_BOOTSTRAPPED)
3378void QMetaTypeCopyTraits::warnAboutDeprecatedCopy(
const char *name)
3380 qCWarning(lcMetatypeDeprecated,
"QMetaType: copy construction of type '%s' is deprecated", name);
3384#if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
3387#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name)
3388 template class QMetaTypeForType<Name>;
3389 template struct QMetaTypeInterfaceWrapper<Name>;
3396#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.
\keyword 16-bit Floating Point Support\inmodule QtCore \inheaderfile QFloat16
QList< QVariant > QVariantList
#define qCWarning(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
#define QStringLiteral(str)