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
59#if QT_CONFIG(itemmodel)
60# include "qabstractitemmodel.h"
68#ifndef QT_BOOTSTRAPPED
72#define NS(x) QT_PREPEND_NAMESPACE(x)
79struct QMetaTypeDeleter
82 void operator()(
void *data)
const
84 if (iface->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
85#ifdef __cpp_sized_deallocation
86 operator
delete(data, iface->size,
std::align_val_t(iface->alignment));
88 operator
delete(data, std::align_val_t(iface->alignment));
91#ifdef __cpp_sized_deallocation
92 operator
delete(data, iface->size);
94 operator
delete(data);
101#ifndef QT_BOOTSTRAPPED
103struct QMetaTypeCustomRegistry
109 enum class HasTypedefs :
bool { No, Yes };
112#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
113 QMetaTypeCustomRegistry()
116
117
118
119
120
122 "qfloat16", Alias(QtPrivate::qMetaTypeInterfaceForType<qfloat16>(), HasTypedefs::No));
138 QWriteLocker l(&lock);
139 if (
int id = ti->typeId.loadRelaxed())
143 QMetaObject::normalizedType
146 if (
auto ti2 = aliases.value(name)) {
147 const auto id = ti2->typeId.loadRelaxed();
148 ti->typeId.storeRelaxed(id);
151 aliases[name] = Alias(ti, HasTypedefs::No);
152 int size = registry.size();
153 while (firstEmpty < size && registry[firstEmpty])
155 if (firstEmpty < size) {
156 registry[firstEmpty] = ti;
160 firstEmpty = registry.size();
162 ti->typeId.storeRelaxed(firstEmpty + QMetaType::User);
166 return ti->typeId.loadRelaxed();
169 void unregisterDynamicType(
int id)
173 Q_ASSERT(id > QMetaType::User);
174 QWriteLocker l(&lock);
175 int idx = id - QMetaType::User - 1;
176 auto &ti = registry[idx];
179 auto it = aliases.find(ti->name);
180 if (it->data() == ti) {
182 case HasTypedefs::Yes:
183 aliases.removeIf([ti] (
const auto &kv) {
return kv->data() == ti; });
185 case HasTypedefs::No:
193 firstEmpty =
std::min(firstEmpty, idx);
198 QReadLocker l(&lock);
199 return registry.value(id - QMetaType::User - 1);
203Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry)
208const char *QtMetaTypePrivate::typedefNameForType(
const QtPrivate::QMetaTypeInterface *type_d)
210 const char *name =
nullptr;
211 if (!customTypeRegistry.exists())
213 QMetaTypeCustomRegistry *r = &*customTypeRegistry;
215 QByteArrayView officialName(type_d->name);
216 QReadLocker l(&r->lock);
217 auto it = r->aliases.constBegin();
218 auto end = r->aliases.constEnd();
219 for ( ; it != end; ++it) {
220 if (it->data() != type_d)
222 if (it.key() == officialName)
224 name = it.key().constData();
230 QByteArrayList otherNames;
231 for ( ; it != end; ++it) {
232 if (it->data() == type_d && it.key() != officialName)
233 otherNames << it.key();
236 if (!otherNames.isEmpty())
237 qWarning(
"QMetaType: type %s has more than one typedef alias: %s, %s",
238 type_d->name, name, otherNames.join(
", ").constData());
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
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
328
329
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
366
367
368
369
370
371
372
373
374
375
376
377
378
379
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
481
482
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
513
514
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
549
550
553
554
555
556
557
558
559
560
563
564
565
566
567
568
569
570
571
574
575
576
577
578
581
582
583
584
585
586
587
588
589#ifndef QT_BOOTSTRAPPED
591
592
593
594int QMetaType::registerHelper(
const QtPrivate::QMetaTypeInterface *iface)
597 auto reg = customTypeRegistry();
599 return reg->registerCustomType(iface);
606
607
608
609
610
611
612
613
614
615
616
617
620
621
622
623
624
625
626
627
628
629
630
631
632
635
636
637
638
639
640
641
642
643
644
645
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
671
672
673
674
675
676
677
678
679
680void *QMetaType::create(
const void *copy)
const
682 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
685 std::unique_ptr<
void, QMetaTypeDeleter> where(
nullptr, {d_ptr});
686 if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
687 where.reset(operator
new(d_ptr->size, std::align_val_t(d_ptr->alignment), std::nothrow_t{}));
689 where.reset(operator
new(d_ptr->size, std::nothrow_t{}));
691 QtMetaTypePrivate::construct(d_ptr, where.get(), copy);
692 return where.release();
696
697
698
699
700
701
702
703
704void QMetaType::destroy(
void *data)
const
706 if (data && isDestructible()) {
707 QtMetaTypePrivate::destruct(d_ptr, data);
708 QMetaTypeDeleter{d_ptr}(data);
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738void *QMetaType::construct(
void *where,
const void *copy)
const
742 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
745 QtMetaTypePrivate::construct(d_ptr, where, copy);
750
751
752
753
754
755
756
757
758
759
760void QMetaType::destruct(
void *data)
const
762 if (data && isDestructible())
763 QtMetaTypePrivate::destruct(d_ptr, data);
766static QPartialOrdering threeWayCompare(
const void *ptr1,
const void *ptr2)
768 std::less<
const void *> less;
769 if (less(ptr1, ptr2))
770 return QPartialOrdering::Less;
771 if (less(ptr2, ptr1))
772 return QPartialOrdering::Greater;
773 return QPartialOrdering::Equivalent;
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802QPartialOrdering QMetaType::compare(
const void *lhs,
const void *rhs)
const
805 return QPartialOrdering::Unordered;
806 if (d_ptr && d_ptr->flags & QMetaType::IsPointer)
807 return threeWayCompare(*
reinterpret_cast<
const void *
const *>(lhs),
808 *
reinterpret_cast<
const void *
const *>(rhs));
809 if (d_ptr && d_ptr->lessThan) {
810 if (d_ptr->equals && d_ptr->equals(d_ptr, lhs, rhs))
811 return QPartialOrdering::Equivalent;
812 if (d_ptr->lessThan(d_ptr, lhs, rhs))
813 return QPartialOrdering::Less;
814 if (d_ptr->lessThan(d_ptr, rhs, lhs))
815 return QPartialOrdering::Greater;
817 return QPartialOrdering::Equivalent;
819 return QPartialOrdering::Unordered;
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838bool QMetaType::equals(
const void *lhs,
const void *rhs)
const
843 if (d_ptr->flags & QMetaType::IsPointer)
844 return *
reinterpret_cast<
const void *
const *>(lhs) == *
reinterpret_cast<
const void *
const *>(rhs);
847 return d_ptr->equals(d_ptr, lhs, rhs);
848 if (d_ptr->lessThan && !d_ptr->lessThan(d_ptr, lhs, rhs) && !d_ptr->lessThan(d_ptr, rhs, lhs))
855
856
857
858
859
860
861
862
863
866
867
868
869
870
871
872
873
874
877
878
879
880
881
882
883
884
887
888
889
890
891
892
893
894
896bool QMetaType::isDefaultConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
898 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDefaultConstructible(iface);
901bool QMetaType::isCopyConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
903 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isCopyConstructible(iface);
906bool QMetaType::isMoveConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
908 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isMoveConstructible(iface);
911bool QMetaType::isDestructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
913 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDestructible(iface);
917
918
919
920
921
922bool QMetaType::isEqualityComparable()
const
924 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->equals !=
nullptr || d_ptr->lessThan !=
nullptr);
928
929
930
931
932
933bool QMetaType::isOrdered()
const
935 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->lessThan !=
nullptr);
938#ifndef QT_BOOTSTRAPPED
940
941
942void QMetaType::unregisterMetaType(QMetaType type)
944 const QtPrivate::QMetaTypeInterface *d_ptr = type.d_ptr;
948 const int typeId = d_ptr->typeId.loadRelaxed();
949 if (typeId < QMetaType::User)
954 if (
auto reg = customTypeRegistry()) {
955 Q_ASSERT(reg->getCustomType(typeId) == d_ptr);
956 reg->unregisterDynamicType(typeId);
959 const_cast<QtPrivate::QMetaTypeInterface *>(d_ptr)->typeId.storeRelease(0);
964
965
966
967
968
971
972
973
974
975
976
979
980
981
982
983
984
986static constexpr auto createStaticTypeToIdMap()
988#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
990#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
992 constexpr auto staticTypeNames = qOffsetStringArray(
997 constexpr int Count = staticTypeNames.count();
998#undef QT_ADD_STATIC_METATYPE
999#undef QT_ADD_STATIC_METATYPE_ALIASES_ITER
1001#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
1003#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
1004 QMetaType::MetaTypeName,
1005 std::array<
int, Count> typeIds = {
1008 QMetaTypeId2<qreal>::MetaType,
1010#undef QT_ADD_STATIC_METATYPE
1011#undef QT_ADD_STATIC_METATYPE_ALIASES_ITER
1013 using Base = std::remove_cv_t<
decltype(staticTypeNames)>;
1014 using Array = std::remove_cv_t<
decltype(typeIds)>;
1016 constexpr Map(
const Base &base,
const Array &typeIdMap)
1017 : Base(base), typeIdMap(typeIdMap)
1019 std::array<
int, Count> typeIdMap;
1022 return Map(staticTypeNames, typeIds);
1024static constexpr auto types = createStaticTypeToIdMap();
1026template <
typename From,
typename To>
1031 static_assert(
std::numeric_limits<From>::is_iec559);
1033 static_assert(
std::is_integral_v<To>);
1034 static_assert(
sizeof(From) <=
sizeof(
double));
1035 const double fromD =
static_cast<
double>(from);
1037 if (qt_is_nan(fromD)) {
1043 convertDoubleTo(std::round(fromD), &result);
1051 template<
typename T,
typename LiteralWrapper =
1052 std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView,
const char *>>
1053 static inline bool convertToBool(
const T &source)
1055 T str = source.toLower();
1056 return !(str.isEmpty() || str == LiteralWrapper(
"0") || str == LiteralWrapper(
"false"));
1072 static bool convert(
const void *from,
int fromTypeId,
void *to,
int toTypeId)
1074 Q_ASSERT(fromTypeId != toTypeId);
1076#ifdef QT_BOOTSTRAPPED
1081 bool onlyCheck = (from ==
nullptr && to ==
nullptr);
1084 Q_ASSERT(onlyCheck || (
bool(from) &&
bool(to)));
1087 using SChar =
signed char;
1088 using UChar =
unsigned char;
1089 using Short =
short;
1090 using UShort =
unsigned short;
1092 using UInt =
unsigned int;
1094 using LongLong = qlonglong;
1095 using ULong =
unsigned long;
1096 using ULongLong = qulonglong;
1098 using Float =
float;
1099 using Double =
double;
1101 using Nullptr =
std::nullptr_t;
1102 using Char16 =
char16_t;
1103 using Char32 =
char32_t;
1105#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From)
1107#define QMETATYPE_CONVERTER_ASSIGN_NUMBER(To, From)
1109#define CONVERT_CBOR_AND_JSON(To)
1111 if constexpr(std::is_same_v<To, Bool>) {
1112 if (!source.isBool())
1114 result = source.toBool();
1116 if (!source.isInteger() && !source.isDouble())
1118 if constexpr(std::is_integral_v<To>)
1119 result = source.toInteger();
1121 result = To(source.toDouble());
1126 if constexpr(std::is_same_v<To, Bool>) {
1127 if (!source.isBool())
1129 result = source.toBool();
1131 if (!source.isDouble())
1133 if constexpr(std::is_integral_v<To>)
1134 result = source.toInteger();
1136 result = To(source.toDouble());
1141#define INTEGRAL_CONVERTER(To)
1154 QMETATYPE_CONVERTER(To, Float16, return qIntegerConversionFromFPHelper(source, &result););
1160 if constexpr(std::is_same_v<To, bool>)
1161 result = (ok = true, convertToBool(source));
1162 else if constexpr(std::is_signed_v<To>)
1163 result = To(source.toLongLong(&ok));
1165 result = To(source.toULongLong(&ok));
1170 if constexpr(std::is_same_v<To, bool>)
1171 result = (ok = true, convertToBool(source));
1172 else if constexpr(std::is_signed_v<To>)
1173 result = To(source.toLongLong(&ok));
1175 result = To(source.toULongLong(&ok));
1180#define FLOAT_CONVERTER(To)
1198 result = To(source.toDouble(&ok));
1203 result = To(source.toDouble(&ok));
1208 switch (makePair(toTypeId, fromTypeId)) {
1210QT_WARNING_DISABLE_CLANG(
"-Wtautological-compare")
1230 if (source.isUrl()) {
1231 result = source.toUrl();
1236#if QT_CONFIG(itemmodel)
1237 QMETATYPE_CONVERTER_ASSIGN(QModelIndex, QPersistentModelIndex);
1238 QMETATYPE_CONVERTER_ASSIGN(QPersistentModelIndex, QModelIndex);
1242#define QMETATYPE_CONVERTER_ASSIGN_QCHAR(From)
1275 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1279 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1283 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1287 result = QString::fromLatin1(&source, 1);
1292 result = QString::fromLatin1(&s, 1);
1297 result = QString::fromLatin1(&s, 1);
1301 result = QChar(source);
1305 result = QStringView(QChar::fromUcs4(source)).toString();
1308#if QT_CONFIG(datestring)
1309 QMETATYPE_CONVERTER(QString, QDate, result = source.toString(Qt::ISODate);
return true;);
1310 QMETATYPE_CONVERTER(QString, QTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1311 QMETATYPE_CONVERTER(QString, QDateTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1315 return (source.size() == 1) ? (result = source.at(0),
true) :
false;
1319 if (source.isString() || source.isNull()) {
1320 result = source.toString();
1325 QMETATYPE_CONVERTER(QString, Nullptr, Q_UNUSED(source); result = QString();
return true;);
1330 result = source ?
"true" :
"false";
1345 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1349 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1353 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1372 QMETATYPE_CONVERTER(QStringList, QString, result = QStringList() << source;
return true;);
1375 result.reserve(source.size());
1376 for (
const auto &v: source)
1377 result.append(v.toByteArray());
1381 result.reserve(source.size());
1382 for (
const auto &v: source)
1383 result.append(QVariant(v));
1388 result.reserve(source.size());
1389 for (
const auto &v: source)
1390 result.append(v.toString());
1394 result.reserve(source.size());
1395 for (
const auto &v: source)
1396 result.append(QVariant(v));
1401 result.reserve(source.size());
1402 for (
auto it = source.begin(); it != source.end(); ++it)
1403 result.insert(it.key(), it.value());
1407 for (
auto it = source.begin(); it != source.end(); ++it)
1408 result.insert(it.key(), it.value());
1413 if (source.isContainer() || source.isTag())
1415 result = source.toVariant().toString();
1420 if (source.isByteArray()) {
1421 result = source.toByteArray();
1428 if (!source.isUuid())
1430 result = source.toUuid();
1435 if (!source.isArray())
1437 result = source.toArray().toVariantList();
1440 QMETATYPE_CONVERTER(QCborValue, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1442 if (!source.isMap())
1444 result = source.toMap().toVariantMap();
1447 QMETATYPE_CONVERTER(QCborValue, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1449 if (!source.isMap())
1451 result = source.toMap().toVariantHash();
1454#if QT_CONFIG(regularexpression)
1455 QMETATYPE_CONVERTER(QCborValue, QRegularExpression, result = QCborValue(source);
return true;);
1456 QMETATYPE_CONVERTER(QRegularExpression, QCborValue,
1457 if (!source.isRegularExpression())
1459 result = source.toRegularExpression();
1466 result = QCborValue(QCborValue::Null);
1471 return source.isNull();
1489 result = QCborArray::fromStringList(source);
1492#if QT_CONFIG(datestring)
1493 QMETATYPE_CONVERTER(QCborValue, QDate,
1494 result = QCborValue(source.startOfDay());
1500 result = QCborValue::fromJsonValue(source);
1504 result = QCborMap::fromJsonObject(source);
1508 result = QCborArray::fromJsonArray(source);
1512 QJsonDocument doc = source;
1514 result = QCborArray::fromJsonArray(doc.array());
1516 result = QCborMap::fromJsonObject(doc.object());
1522#if QT_CONFIG(datestring)
1523 QMETATYPE_CONVERTER_ASSIGN(QCborValue, QDateTime);
1524 QMETATYPE_CONVERTER(QDateTime, QCborValue,
1525 if (source.isDateTime()) {
1526 result = source.toDateTime();
1535 if (source.isSimpleType()) {
1536 result = source.toSimpleType();
1544 QMETATYPE_CONVERTER(QCborArray, QStringList, result = QCborArray::fromStringList(source);
return true;);
1545 QMETATYPE_CONVERTER(QCborMap, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1547 QMETATYPE_CONVERTER(QCborMap, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1548 QMETATYPE_CONVERTER(QVariantHash, QCborMap, result = source.toVariantHash();
return true;);
1551 if (!source.isArray())
1553 result = source.toArray();
1557 if (!source.isArray())
1559 result = QCborArray::fromJsonArray(source.array());
1563 if (!source.isArray())
1565 result = QCborArray::fromJsonArray(source.toArray());
1569 result = QCborArray::fromJsonArray(source);
1573 if (!source.isMap())
1575 result = source.toMap();
1579 if (source.isArray())
1581 result = QCborMap::fromJsonObject(source.object());
1585 if (!source.isObject())
1587 result = QCborMap::fromJsonObject(source.toObject());
1591 result = QCborMap::fromJsonObject(source);
1597 if (!source.isArray())
1599 result = source.toArray().toVariantList();
1604 if (!source.isObject())
1606 result = source.toObject().toVariantMap();
1609 QMETATYPE_CONVERTER(QVariantMap, QJsonObject, result = source.toVariantMap();
return true;);
1611 if (!source.isObject())
1613 result = source.toObject().toVariantHash();
1616 QMETATYPE_CONVERTER(QVariantHash, QJsonObject, result = source.toVariantHash();
return true;);
1619 QMETATYPE_CONVERTER(QJsonArray, QStringList, result = QJsonArray::fromStringList(source);
return true;);
1622 if (!source.isArray())
1624 result = source.toArray();
1628 if (!source.isArray())
1630 result = source.array();
1634 if (!source.isArray())
1636 result = source.toArray().toJsonArray();
1640 QMETATYPE_CONVERTER(QJsonObject, QVariantMap, result = QJsonObject::fromVariantMap(source);
return true;);
1641 QMETATYPE_CONVERTER(QJsonObject, QVariantHash, result = QJsonObject::fromVariantHash(source);
return true;);
1643 if (!source.isObject())
1645 result = source.toObject();
1649 if (source.isArray())
1651 result = source.object();
1655 if (!source.isMap())
1657 result = source.toMap().toJsonObject();
1660 QMETATYPE_CONVERTER(QJsonObject, QCborMap, result = source.toJsonObject();
return true; );
1664 result = QJsonValue(QJsonValue::Null);
1669 return source.isNull();
1672 result = QJsonValue(source);
1690 result = QJsonValue(QJsonArray::fromStringList(source));
1694 result = QJsonValue(QJsonArray::fromVariantList(source));
1698 result = QJsonValue(QJsonObject::fromVariantMap(source));
1702 result = QJsonValue(QJsonObject::fromVariantHash(source));
1714 QJsonDocument doc = source;
1715 result = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1719 result = source.toJsonValue();
1723 result = source.toJsonObject();
1727 result = source.toJsonArray();
1734#if QT_CONFIG(datestring)
1735 QMETATYPE_CONVERTER(QDate, QString,
1736 result = QDate::fromString(source, Qt::ISODate);
1737 return result.isValid();
1739 QMETATYPE_CONVERTER(QTime, QString,
1740 result = QTime::fromString(source, Qt::ISODate);
1741 return result.isValid();
1743 QMETATYPE_CONVERTER(QDateTime, QString,
1744 result = QDateTime::fromString(source, Qt::ISODate);
1745 return result.isValid();
1757Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeGuiHelper = {};
1758Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeWidgetsHelper = {};
1760#ifndef QT_BOOTSTRAPPED
1763 int type = qMax(fromTypeId, toTypeId);
1764 if (type <= QMetaType::LastCoreType)
1765 return QCoreVariantHelper::convert(from, fromTypeId, to, toTypeId);
1766 if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType)
1767 return qMetaTypeGuiHelper.convert(from, fromTypeId, to, toTypeId);
1768 else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType)
1769 return qMetaTypeWidgetsHelper.convert(from, fromTypeId, to, toTypeId);
1773template<
typename T,
typename Key>
1779 const QWriteLocker locker(&lock);
1785 const QReadLocker locker(&lock);
1786 return map.contains(k);
1791 const QWriteLocker locker(&lock);
1792 auto r = map.tryEmplace(k, f);
1798 const QReadLocker locker(&lock);
1799 auto it = map.find(k);
1800 return it == map.end() ?
nullptr :
std::addressof(*it);
1805 const Key k(from, to);
1806 const QWriteLocker locker(&lock);
1810 mutable QReadWriteLock lock;
1814using QMetaTypeConverterRegistry
1815 = QMetaTypeFunctionRegistry<QMetaType::ConverterFunction, std::pair<
int,
int>>;
1817Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
1819using QMetaTypeMutableViewRegistry
1820 = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, std::pair<
int,
int>>;
1821Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
1824
1825
1826
1827
1828
1829
1830
1833
1834
1835
1836
1837
1838
1839
1840
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1868
1869
1870
1871
1873
1874bool QMetaType::registerConverterFunction(
const ConverterFunction &f, QMetaType from, QMetaType to)
1876 if (!customTypesConversionRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1877 qWarning(
"Type conversion already registered from type %s to type %s",
1878 from.name(), to.name());
1885
1886
1887
1888
1889
1890
1891
1894
1895
1896
1897
1898
1899
1902
1903
1904
1906
1907bool QMetaType::registerMutableViewFunction(
const MutableViewFunction &f, QMetaType from, QMetaType to)
1909 if (!customTypesMutableViewRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1910 qWarning(
"Mutable view on type already registered from type %s to type %s",
1911 from.name(), to.name());
1919
1920void QMetaType::unregisterMutableViewFunction(QMetaType from, QMetaType to)
1922 if (customTypesMutableViewRegistry.isDestroyed())
1924 customTypesMutableViewRegistry()->remove(from.id(), to.id());
1928
1929
1931
1932void QMetaType::unregisterConverterFunction(QMetaType from, QMetaType to)
1934 if (customTypesConversionRegistry.isDestroyed())
1936 customTypesConversionRegistry()->remove(from.id(), to.id());
1940#ifndef QT_NO_DEBUG_STREAM
1943
1944
1946
1947QDebug operator<<(QDebug d, QMetaType m)
1949 const QDebugStateSaver saver(d);
1950 return d.nospace() <<
"QMetaType(" << m.name() <<
")";
1954
1955
1957
1958bool QMetaType::debugStream(QDebug& dbg,
const void *rhs)
1960 if (d_ptr && d_ptr->flags & QMetaType::IsPointer) {
1961 dbg << *
reinterpret_cast<
const void *
const *>(rhs);
1964 if (d_ptr && d_ptr->debugStream) {
1965 d_ptr->debugStream(d_ptr, dbg, rhs);
1972
1973
1974
1975
1978
1979
1980
1981
1982
1983
1986
1987
1988
1989
1990
1991
1992
1995
1996
1997
1999
2000bool QMetaType::hasRegisteredDebugStreamOperator()
const
2002 return d_ptr && d_ptr->debugStream !=
nullptr;
2006#ifndef QT_NO_QOBJECT
2008
2010
2011static QMetaEnum metaEnumFromType(QMetaType t)
2013 if (t.flags() & QMetaType::IsEnumeration) {
2014 if (
const QMetaObject *metaObject = t.metaObject()) {
2015 QByteArrayView qflagsNamePrefix =
"QFlags<";
2017 if (enumName.endsWith(
'>') && enumName.startsWith(qflagsNamePrefix)) {
2020 enumName = enumName.sliced(qflagsNamePrefix.size());
2022 if (qsizetype lastColon = enumName.lastIndexOf(
':'); lastColon != -1)
2023 enumName = enumName.sliced(lastColon + 1);
2024 return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
2031#ifndef QT_BOOTSTRAPPED
2032static bool convertFromEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2035 if (fromType.flags() & QMetaType::IsUnsignedEnumeration) {
2037 switch (fromType.sizeOf()) {
2039 ull = *
static_cast<
const unsigned char *>(from);
2042 ull = *
static_cast<
const unsigned short *>(from);
2045 ull = *
static_cast<
const unsigned int *>(from);
2048 ull = *
static_cast<
const quint64 *>(from);
2053 if (toType.id() == QMetaType::ULongLong) {
2054 *
static_cast<qulonglong *>(to) = ull;
2057 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2058 return QMetaType::convert(QMetaType::fromType<qulonglong>(), &ull, toType, to);
2059 ll = qlonglong(ull);
2061 switch (fromType.sizeOf()) {
2063 ll = *
static_cast<
const signed char *>(from);
2066 ll = *
static_cast<
const short *>(from);
2069 ll = *
static_cast<
const int *>(from);
2072 ll = *
static_cast<
const qint64 *>(from);
2077 if (toType.id() == QMetaType::LongLong) {
2078 *
static_cast<qlonglong *>(to) = ll;
2081 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2082 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2084#ifndef QT_NO_QOBJECT
2085 QMetaEnum en = metaEnumFromType(fromType);
2089 if (toType.id() == QMetaType::QString)
2090 *
static_cast<QString *>(to) = QString::fromUtf8(keys);
2094 const char *key = en.valueToKey(ll);
2095 if (toType.id() == QMetaType::QString)
2096 *
static_cast<QString *>(to) = QString::fromUtf8(key);
2103 if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray)
2104 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2108static bool convertToEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2110 int fromTypeId = fromType.id();
2111 qlonglong value = -1;
2113#ifndef QT_NO_QOBJECT
2114 if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) {
2115 QMetaEnum en = metaEnumFromType(toType);
2117 QByteArray keys = (fromTypeId == QMetaType::QString)
2118 ?
static_cast<
const QString *>(from)->toUtf8()
2119 : *
static_cast<
const QByteArray *>(from);
2120 if (
auto v = en.keysToValue64(keys.constData())) {
2128 if (fromTypeId == QMetaType::LongLong) {
2129 value = *
static_cast<
const qlonglong *>(from);
2132 ok = QMetaType::convert(fromType, from, QMetaType::fromType<qlonglong>(), &value);
2139 switch (toType.sizeOf()) {
2141 *
static_cast<
signed char *>(to) = value;
2144 *
static_cast<qint16 *>(to) = value;
2147 *
static_cast<qint32 *>(to) = value;
2150 *
static_cast<qint64 *>(to) = value;
2153 Q_UNREACHABLE_RETURN(
false);
2157template<
typename Iterable>
2158bool convertIterableToVariantList(QMetaType fromType,
const void *from,
void *to)
2161 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &list))
2166 if (list.metaContainer().hasSize())
2167 l.reserve(list.size());
2168 auto end = list.end();
2169 for (
auto it = list.begin(); it != end; ++it)
2174template<
typename Iterable>
2175bool convertIterableToVariantMap(QMetaType fromType,
const void *from,
void *to)
2178 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
2181 QVariantMap &h = *
static_cast<QVariantMap *>(to);
2183 auto end = map.end();
2184 for (
auto it = map.begin(); it != end; ++it)
2185 h.insert(it.key().toString(), it.value());
2189template<
typename Iterable>
2190bool convertIterableToVariantHash(QMetaType fromType,
const void *from,
void *to)
2193 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
2196 QVariantHash &h = *
static_cast<QVariantHash *>(to);
2198 h.reserve(map.size());
2199 auto end = map.end();
2200 for (
auto it = map.begin(); it != end; ++it)
2201 h.insert(it.key().toString(), it.value());
2205static bool convertIterableToVariantPair(QMetaType fromType,
const void *from,
void *to)
2208 const auto f = customTypesConversionRegistry()->function({fromType.id(), targetId});
2216 QVariant v1(pi._metaType_first);
2218 if (pi._metaType_first == QMetaType::fromType<QVariant>())
2221 dataPtr = v1.data();
2224 QVariant v2(pi._metaType_second);
2225 if (pi._metaType_second == QMetaType::fromType<QVariant>())
2228 dataPtr = v2.data();
2231 *
static_cast<QVariantPair *>(to) = QVariantPair(v1, v2);
2235template<
typename Iterable>
2236static bool convertToSequentialIterable(QMetaType fromType,
const void *from,
void *to)
2239 const int fromTypeId = fromType.id();
2241 Iterable &i = *
static_cast<Iterable *>(to);
2242 switch (fromTypeId) {
2243 case QMetaType::QVariantList:
2244 i = Iterable(
reinterpret_cast<
const QVariantList *>(from));
2246 case QMetaType::QStringList:
2247 i = Iterable(
reinterpret_cast<
const QStringList *>(from));
2249 case QMetaType::QByteArrayList:
2250 i = Iterable(
reinterpret_cast<
const QByteArrayList *>(from));
2252 case QMetaType::QString:
2253 i = Iterable(
reinterpret_cast<
const QString *>(from));
2255 case QMetaType::QByteArray:
2256 i = Iterable(
reinterpret_cast<
const QByteArray *>(from));
2259 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2260 if (QMetaType::convert(
2261 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2271static bool canConvertToSequentialIterable(QMetaType fromType)
2273 switch (fromType.id()) {
2274 case QMetaType::QVariantList:
2275 case QMetaType::QStringList:
2276 case QMetaType::QByteArrayList:
2277 case QMetaType::QString:
2278 case QMetaType::QByteArray:
2281 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2285static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType)
2287 switch (fromType.id()) {
2288 case QMetaType::QVariantList:
2289 case QMetaType::QStringList:
2290 case QMetaType::QByteArrayList:
2291 case QMetaType::QString:
2292 case QMetaType::QByteArray:
2295 return QMetaType::canView(
2296 fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2300template<
typename Iterable>
2301static bool viewAsSequentialIterable(QMetaType fromType,
void *from,
void *to)
2304 const int fromTypeId = fromType.id();
2306 Iterable &i = *
static_cast<Iterable *>(to);
2307 switch (fromTypeId) {
2308 case QMetaType::QVariantList:
2311 case QMetaType::QStringList:
2312 i = Iterable(
reinterpret_cast<QStringList *>(from));
2314 case QMetaType::QByteArrayList:
2315 i = Iterable(
reinterpret_cast<QByteArrayList *>(from));
2317 case QMetaType::QString:
2318 i = Iterable(
reinterpret_cast<QString *>(from));
2320 case QMetaType::QByteArray:
2321 i = Iterable(
reinterpret_cast<
QByteArray *>(from));
2324 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2325 if (QMetaType::view(
2326 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2336template<
typename Iterable>
2337static bool convertToAssociativeIterable(QMetaType fromType,
const void *from,
void *to)
2341 Iterable &i = *
static_cast<Iterable *>(to);
2342 if (fromType.id() == QMetaType::QVariantMap) {
2343 i = Iterable(
reinterpret_cast<
const QVariantMap *>(from));
2346 if (fromType.id() == QMetaType::QVariantHash) {
2347 i = Iterable(
reinterpret_cast<
const QVariantHash *>(from));
2351 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2352 if (QMetaType::convert(
2353 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2361static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
2363 if ((fromType.flags() & QMetaType::IsPointer) != (toType.flags() & QMetaType::IsPointer))
2366 const QMetaObject *f = fromType.metaObject();
2367 const QMetaObject *t = toType.metaObject();
2369 return f->inherits(t) || (t->inherits(f));
2374static bool canConvertToAssociativeIterable(QMetaType fromType)
2376 switch (fromType.id()) {
2377 case QMetaType::QVariantMap:
2378 case QMetaType::QVariantHash:
2381 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2385static bool canImplicitlyViewAsAssociativeIterable(QMetaType fromType)
2387 switch (fromType.id()) {
2388 case QMetaType::QVariantMap:
2389 case QMetaType::QVariantHash:
2392 return QMetaType::canView(
2393 fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2397template<
typename Iterable>
2398static bool viewAsAssociativeIterable(QMetaType fromType,
void *from,
void *to)
2401 int fromTypeId = fromType.id();
2403 Iterable &i = *
static_cast<Iterable *>(to);
2404 if (fromTypeId == QMetaType::QVariantMap) {
2405 i = Iterable(
reinterpret_cast<QVariantMap *>(from));
2408 if (fromTypeId == QMetaType::QVariantHash) {
2409 i = Iterable(
reinterpret_cast<QVariantHash *>(from));
2413 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2414 if (QMetaType::view(
2415 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2423static bool convertMetaObject(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2426 if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
2427 QObject *fromObject = *
static_cast<QObject *
const *>(from);
2429 if (fromObject && fromObject->metaObject()->inherits(toType.metaObject())) {
2430 *
static_cast<QObject **>(to) = toType.metaObject()->cast(fromObject);
2432 }
else if (!fromObject && fromType.metaObject()) {
2434 *
static_cast<
void **>(to) =
nullptr;
2435 return fromType.metaObject()->inherits(toType.metaObject());
2437 }
else if ((fromType.flags() & QMetaType::IsPointer) == (toType.flags() & QMetaType::IsPointer)) {
2439 const QMetaObject *f = fromType.metaObject();
2440 const QMetaObject *t = toType.metaObject();
2441 if (f && t && f->inherits(t)) {
2442 toType.destruct(to);
2443 toType.construct(to, from);
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2463
2464
2465
2466
2467
2469
2470bool QMetaType::convert(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2472 if (!fromType.isValid() || !toType.isValid())
2475 if (fromType == toType) {
2477 fromType.destruct(to);
2478 fromType.construct(to, from);
2482 int fromTypeId = fromType.id();
2483 int toTypeId = toType.id();
2485 if (tryConvertBuiltinTypes(from, fromTypeId, to, toTypeId))
2487 const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId});
2489 return (*f)(from, to);
2491 if (fromType.flags() & QMetaType::IsEnumeration)
2492 return convertFromEnum(fromType, from, toType, to);
2493 if (toType.flags() & QMetaType::IsEnumeration)
2494 return convertToEnum(fromType, from, toType, to);
2495 if (toTypeId == Nullptr) {
2496 *
static_cast<std::nullptr_t *>(to) =
nullptr;
2497 if (fromType.flags() & QMetaType::IsPointer) {
2498 if (*
static_cast<
const void *
const *>(from) ==
nullptr)
2503 if (toTypeId == QVariantPair && convertIterableToVariantPair(fromType, from, to))
2507 if (toTypeId == QVariantList
2508 && convertIterableToVariantList<QMetaSequence::Iterable>(fromType, from, to)) {
2512 if (toTypeId == QVariantMap
2513 && convertIterableToVariantMap<QMetaAssociation::Iterable>(fromType, from, to)) {
2517 if (toTypeId == QVariantHash
2518 && convertIterableToVariantHash<QMetaAssociation::Iterable>(fromType, from, to)) {
2522 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2523 return convertToSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
2525 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2526 return convertToAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
2528#if QT_DEPRECATED_SINCE(6
, 15
)
2530 QT_WARNING_DISABLE_DEPRECATED
2532 if (toTypeId == QVariantList
2533 && convertIterableToVariantList<QSequentialIterable>(fromType, from, to)) {
2537 if (toTypeId == QVariantMap
2538 && convertIterableToVariantMap<QAssociativeIterable>(fromType, from, to)) {
2542 if (toTypeId == QVariantHash
2543 && convertIterableToVariantHash<QAssociativeIterable>(fromType, from, to)) {
2547 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2548 return convertToSequentialIterable<QSequentialIterable>(fromType, from, to);
2550 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2551 return convertToAssociativeIterable<QAssociativeIterable>(fromType, from, to);
2556 return convertMetaObject(fromType, from, toType, to);
2560
2561
2563
2564bool QMetaType::view(QMetaType fromType,
void *from, QMetaType toType,
void *to)
2566 if (!fromType.isValid() || !toType.isValid())
2569 int fromTypeId = fromType.id();
2570 int toTypeId = toType.id();
2572 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2574 return (*f)(from, to);
2576 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2577 return viewAsSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
2579 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2580 return viewAsAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
2582#if QT_DEPRECATED_SINCE(6
, 15
)
2584 QT_WARNING_DISABLE_DEPRECATED
2586 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2587 return viewAsSequentialIterable<QSequentialIterable>(fromType, from, to);
2589 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2590 return viewAsAssociativeIterable<QAssociativeIterable>(fromType, from, to);
2595 return convertMetaObject(fromType, from, toType, to);
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2614
2615bool QMetaType::canView(QMetaType fromType, QMetaType toType)
2617 int fromTypeId = fromType.id();
2618 int toTypeId = toType.id();
2620 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2623 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2627 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2628 return canImplicitlyViewAsSequentialIterable(fromType);
2630 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2631 return canImplicitlyViewAsAssociativeIterable(fromType);
2633#if QT_DEPRECATED_SINCE(6
, 15
)
2635 QT_WARNING_DISABLE_DEPRECATED
2637 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2638 return canImplicitlyViewAsSequentialIterable(fromType);
2640 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2641 return canImplicitlyViewAsAssociativeIterable(fromType);
2646 if (canConvertMetaObject(fromType, toType))
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2736
2737bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
2739 int fromTypeId = fromType.id();
2740 int toTypeId = toType.id();
2742 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2745 if (fromTypeId == toTypeId)
2748 if (tryConvertBuiltinTypes(
nullptr, fromTypeId,
nullptr, toTypeId))
2751 const ConverterFunction *
const f =
2752 customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId));
2756 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2757 return canConvertToSequentialIterable(fromType);
2759 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2760 return canConvertToAssociativeIterable(fromType);
2762 if (toTypeId == QVariantList
2763 && canConvert(fromType, QMetaType::fromType<QMetaSequence::Iterable>())) {
2767 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2768 && canConvert(fromType, QMetaType::fromType<QMetaAssociation::Iterable>())) {
2772#if QT_DEPRECATED_SINCE(6
, 15
)
2774 QT_WARNING_DISABLE_DEPRECATED
2776 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2777 return canConvertToSequentialIterable(fromType);
2779 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2780 return canConvertToAssociativeIterable(fromType);
2782 if (toTypeId == QVariantList
2783 && canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
2787 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2788 && canConvert(fromType, QMetaType::fromType<QAssociativeIterable>())) {
2795 if (toTypeId == QVariantPair && hasRegisteredConverterFunction(
2796 fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
2799 if (fromType.flags() & IsEnumeration) {
2800 if (toTypeId == QString || toTypeId == QByteArray)
2802 return canConvert(QMetaType(LongLong), toType);
2804 if (toType.flags() & IsEnumeration) {
2805 if (fromTypeId == QString || fromTypeId == QByteArray)
2807 return canConvert(fromType, QMetaType(LongLong));
2809 if (toTypeId == Nullptr && fromType.flags() & IsPointer)
2811 if (canConvertMetaObject(fromType, toType))
2818
2819
2820
2821
2822
2823
2824
2827
2828
2829
2830
2831
2834
2835
2837
2838bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType)
2840 return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
2844
2846
2847bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
2849 const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2850 return QMetaType::hasRegisteredConverterFunction(m, to);
2854
2856
2857bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
2859 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2860 return QMetaType::hasRegisteredConverterFunction(m, to);
2864
2866
2867bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
2869 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2870 return QMetaType::hasRegisteredConverterFunction(m, to);
2874
2875
2876
2877
2878
2881
2882
2884
2885bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType)
2887 return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
2891
2893
2894bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
2896 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2897 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2901
2903
2904bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
2906 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2907 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2912
2913
2914
2915
2916
2917
2918
2919
2920
2923
2924
2925
2926
2927
2928
2929
2930
2931
2935
2936static inline int qMetaTypeStaticType(QByteArrayView name)
2938 for (
int i = 0; i < types.count(); ++i) {
2939 if (types.viewAt(i) == name)
2940 return types.typeIdMap[i];
2942 return QMetaType::UnknownType;
2945#ifndef QT_BOOTSTRAPPED
2947
2948
2949
2950
2952
2953void QMetaType::registerNormalizedTypedef(
const NS(QByteArray) & normalizedTypeName,
2956 if (!metaType.isValid())
2958 if (
auto reg = customTypeRegistry()) {
2959 QWriteLocker lock(®->lock);
2960 auto &al = reg->aliases[normalizedTypeName];
2964 al = QMetaTypeCustomRegistry::Alias(
2965 metaType.d_ptr, QMetaTypeCustomRegistry::HasTypedefs::Yes);
2966 reg->aliases[metaType.name()].setTag(QMetaTypeCustomRegistry::HasTypedefs::Yes);
2973 Q_ASSERT(typeId < QMetaType::User);
2974 if (typeId <= QMetaType::LastCoreType)
2975 return QCoreVariantHelper::interfaceForType(typeId);
2976 if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType)
2977 return qMetaTypeGuiHelper.interfaceForType(typeId);
2978 if (typeId >= QMetaType::FirstWidgetsType && typeId <= QMetaType::LastWidgetsType)
2979 return qMetaTypeWidgetsHelper.interfaceForType(typeId);
2986 if (typeId >= QMetaType::User) {
2987#ifndef QT_BOOTSTRAPPED
2988 if (customTypeRegistry.exists())
2989 iface = customTypeRegistry->getCustomType(typeId);
2992 iface = interfaceForStaticType(typeId);
2998
2999
3000
3002
3003bool QMetaType::isRegistered(
int type)
3005 return interfaceForTypeNoWarning(type) !=
nullptr;
3010 Q_PRE(!name.isEmpty());
3011 int type = qMetaTypeStaticType(name);
3012 if (type != QMetaType::UnknownType) {
3013 return interfaceForStaticType(type);
3014#ifndef QT_BOOTSTRAPPED
3015 }
else if (customTypeRegistry.exists()) {
3016 QReadLocker locker(&customTypeRegistry->lock);
3017 auto it = customTypeRegistry->aliases.constFind(name);
3018 if (it != customTypeRegistry->aliases.constEnd())
3019 return it.value().data();
3026
3027
3028
3029
3030
3031
3032
3033
3036
3037
3038
3039
3040
3041
3043
3044int qMetaTypeTypeInternal(QByteArrayView name)
3047 if (!name.isEmpty())
3048 iface = findMetaTypeByName(name);
3049 return iface ? iface->typeId.loadRelaxed() : QMetaType::UnknownType;
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3065#ifndef QT_NO_DATASTREAM
3067
3068
3069
3070
3071
3072
3073
3074
3076
3077bool QMetaType::save(QDataStream &stream,
const void *data)
const
3079 if (!data || !isValid())
3083 if (id() == QMetaType::Long) {
3084 stream << qlonglong(*(
long *)data);
3086 }
else if (id() == QMetaType::ULong) {
3087 stream << qlonglong(*(
unsigned long *)data);
3091 if (!d_ptr->dataStreamOut)
3094 d_ptr->dataStreamOut(d_ptr, stream, data);
3099
3100
3101
3102
3105
3106
3107
3108
3109
3110
3111
3112
3114
3115bool QMetaType::load(QDataStream &stream,
void *data)
const
3117 if (!data || !isValid())
3121 if (id() == QMetaType::Long) {
3124 *(
long *)data =
long(ll);
3126 }
else if (id() == QMetaType::ULong) {
3129 *(
unsigned long *)data = (
unsigned long)(ull);
3132 if (!d_ptr->dataStreamIn)
3135 d_ptr->dataStreamIn(d_ptr, stream, data);
3140
3141
3142
3144
3145bool QMetaType::hasRegisteredDataStreamOperators()
const
3148 if (type == QMetaType::Long || type == QMetaType::ULong)
3150 return d_ptr && d_ptr->dataStreamIn !=
nullptr && d_ptr->dataStreamOut !=
nullptr;
3154
3155
3156
3157
3158
3159
3161
3162QMetaType QMetaType::underlyingType()
const
3164 if (!d_ptr || !(flags() & IsEnumeration))
3167
3168
3169
3170
3171
3172
3173 if (flags() & IsUnsignedEnumeration) {
3176 return QMetaType::fromType<quint8>();
3178 return QMetaType::fromType<quint16>();
3180 return QMetaType::fromType<quint32>();
3182 return QMetaType::fromType<quint64>();
3189 return QMetaType::fromType<qint8>();
3191 return QMetaType::fromType<qint16>();
3193 return QMetaType::fromType<qint32>();
3195 return QMetaType::fromType<qint64>();
3205
3206
3207
3208
3212
3214
3215QMetaType QMetaType::fromName(QByteArrayView typeName)
3217 if (typeName.isEmpty())
3220 const QtPrivate::QMetaTypeInterface *iface = findMetaTypeByName(typeName);
3222 return QMetaType(iface);
3224#if !defined(QT_NO_QOBJECT)
3225 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName.constData());
3226 if (normalizedTypeName != typeName)
3227 iface = findMetaTypeByName(normalizedTypeName);
3230 return QMetaType(iface);
3234
3235
3236
3237
3238
3239
3240
3241
3244
3245
3246
3247
3248
3249
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3309
3310
3311
3312
3313
3314
3315
3316
3319
3320
3321
3322
3323
3324
3325
3326
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3443 if (!iface && typeId != QMetaType::UnknownType)
3444 qWarning(
"Trying to construct an instance of an invalid type, type id: %i", typeId);
3450
3451
3452
3453
3454
3457
3458
3459
3461
3462QMetaType::QMetaType(
int typeId) : QMetaType(interfaceForType(typeId)) {}
3466
3467
3468
3469
3471namespace QtPrivate {
3472#if !defined(QT_BOOTSTRAPPED)
3473void QMetaTypeCopyTraits::warnAboutDeprecatedCopy(
const char *name)
3475 qCWarning(lcMetatypeDeprecated,
"QMetaType: copy construction of type '%s' is deprecated", name);
3479#if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
3482#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name)
3483 template class QMetaTypeForType<Name>;
3484 template struct QMetaTypeInterfaceWrapper<Name>;
3491#undef QT_METATYPE_DECLARE_TEMPLATE_ITER
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\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)