17#include "private/qnumeric_p.h"
19#include "private/qoffsetstringarray_p.h"
24#if QT_CONFIG(easingcurve)
25#include "qeasingcurve.h"
28#if QT_CONFIG(regularexpression)
29# include "qregularexpression.h"
32#ifndef QT_BOOTSTRAPPED
60#if QT_CONFIG(itemmodel)
61# include "qabstractitemmodel.h"
69#ifndef QT_BOOTSTRAPPED
73#define NS(x) QT_PREPEND_NAMESPACE(x)
80struct QMetaTypeDeleter
83 void operator()(
void *data)
const
85 if (iface->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
86#ifdef __cpp_sized_deallocation
87 operator
delete(data, iface->size,
std::align_val_t(iface->alignment));
89 operator
delete(data, std::align_val_t(iface->alignment));
92#ifdef __cpp_sized_deallocation
93 operator
delete(data, iface->size);
95 operator
delete(data);
102#ifndef QT_BOOTSTRAPPED
104struct QMetaTypeCustomRegistry
110 enum class HasTypedefs :
bool { No, Yes };
113#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
114 QMetaTypeCustomRegistry()
117
118
119
120
121
123 "qfloat16", Alias(QtPrivate::qMetaTypeInterfaceForType<qfloat16>(), HasTypedefs::No));
139 QWriteLocker l(&lock);
140 if (
int id = ti->typeId.loadRelaxed())
144 QMetaObject::normalizedType
147 if (
auto ti2 = aliases.value(name)) {
148 const auto id = ti2->typeId.loadRelaxed();
149 ti->typeId.storeRelaxed(id);
152 aliases[name] = Alias(ti, HasTypedefs::No);
153 int size = registry.size();
154 while (firstEmpty < size && registry[firstEmpty])
156 if (firstEmpty < size) {
157 registry[firstEmpty] = ti;
161 firstEmpty = registry.size();
163 ti->typeId.storeRelaxed(firstEmpty + QMetaType::User);
167 return ti->typeId.loadRelaxed();
170 void unregisterDynamicType(
int id)
174 Q_ASSERT(id > QMetaType::User);
175 QWriteLocker l(&lock);
176 int idx = id - QMetaType::User - 1;
177 auto &ti = registry[idx];
180 auto it = aliases.find(ti->name);
181 if (it->data() == ti) {
183 case HasTypedefs::Yes:
184 aliases.removeIf([ti] (
const auto &kv) {
return kv->data() == ti; });
186 case HasTypedefs::No:
194 firstEmpty =
std::min(firstEmpty, idx);
199 QReadLocker l(&lock);
200 return registry.value(id - QMetaType::User - 1);
204Q_GLOBAL_STATIC(QMetaTypeCustomRegistry, customTypeRegistry)
209const char *QtMetaTypePrivate::typedefNameForType(
const QtPrivate::QMetaTypeInterface *type_d)
211 const char *name =
nullptr;
212 if (!customTypeRegistry.exists())
214 QMetaTypeCustomRegistry *r = &*customTypeRegistry;
216 QByteArrayView officialName(type_d->name);
217 QReadLocker l(&r->lock);
218 auto it = r->aliases.constBegin();
219 auto end = r->aliases.constEnd();
220 for ( ; it != end; ++it) {
221 if (it->data() != type_d)
223 if (it.key() == officialName)
225 name = it.key().constData();
231 QByteArrayList otherNames;
232 for ( ; it != end; ++it) {
233 if (it->data() == type_d && it.key() != officialName)
234 otherNames << it.key();
237 if (!otherNames.isEmpty())
238 qWarning(
"QMetaType: type %s has more than one typedef alias: %s, %s",
239 type_d->name, name, otherNames.join(
", ").constData());
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
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
330
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
367
368
369
370
371
372
373
374
375
376
377
378
379
380
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
483
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
515
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
551
554
555
556
557
558
559
560
561
564
565
566
567
568
569
570
571
572
575
576
577
578
579
582
583
584
585
586
587
588
589
590
593
594
595
596
597
598
599
600
601
602
605
606
607
608
609
610
611
612
613#ifndef QT_BOOTSTRAPPED
615
616
617
618int QMetaType::registerHelper(
const QtPrivate::QMetaTypeInterface *iface)
621 auto reg = customTypeRegistry();
623 return reg->registerCustomType(iface);
630
631
632
633
634
635
636
637
638
639
640
641
644
645
646
647
648
649
650
651
652
653
654
655
656
659
660
661
662
663
664
665
666
667
668
669
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
695
696
697
698
699
700
701
702
703
704void *QMetaType::create(
const void *copy)
const
706 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
709 std::unique_ptr<
void, QMetaTypeDeleter> where(
nullptr, {d_ptr});
710 if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
711 where.reset(operator
new(d_ptr->size, std::align_val_t(d_ptr->alignment), std::nothrow_t{}));
713 where.reset(operator
new(d_ptr->size, std::nothrow_t{}));
715 QtMetaTypePrivate::construct(d_ptr, where.get(), copy);
716 return where.release();
720
721
722
723
724
725
726
727
728void QMetaType::destroy(
void *data)
const
730 if (data && isDestructible()) {
731 QtMetaTypePrivate::destruct(d_ptr, data);
732 QMetaTypeDeleter{d_ptr}(data);
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762void *QMetaType::construct(
void *where,
const void *copy)
const
766 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
769 QtMetaTypePrivate::construct(d_ptr, where, copy);
774
775
776
777
778
779
780
781
782
783
784void QMetaType::destruct(
void *data)
const
786 if (data && isDestructible())
787 QtMetaTypePrivate::destruct(d_ptr, data);
790static QPartialOrdering threeWayCompare(
const void *ptr1,
const void *ptr2)
792 std::less<
const void *> less;
793 if (less(ptr1, ptr2))
794 return QPartialOrdering::Less;
795 if (less(ptr2, ptr1))
796 return QPartialOrdering::Greater;
797 return QPartialOrdering::Equivalent;
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826QPartialOrdering QMetaType::compare(
const void *lhs,
const void *rhs)
const
829 return QPartialOrdering::Unordered;
830 if (d_ptr && d_ptr->flags & QMetaType::IsPointer)
831 return threeWayCompare(*
reinterpret_cast<
const void *
const *>(lhs),
832 *
reinterpret_cast<
const void *
const *>(rhs));
833 if (d_ptr && d_ptr->lessThan) {
834 if (d_ptr->equals && d_ptr->equals(d_ptr, lhs, rhs))
835 return QPartialOrdering::Equivalent;
836 if (d_ptr->lessThan(d_ptr, lhs, rhs))
837 return QPartialOrdering::Less;
838 if (d_ptr->lessThan(d_ptr, rhs, lhs))
839 return QPartialOrdering::Greater;
841 return QPartialOrdering::Equivalent;
843 return QPartialOrdering::Unordered;
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862bool QMetaType::equals(
const void *lhs,
const void *rhs)
const
867 if (d_ptr->flags & QMetaType::IsPointer)
868 return *
reinterpret_cast<
const void *
const *>(lhs) == *
reinterpret_cast<
const void *
const *>(rhs);
871 return d_ptr->equals(d_ptr, lhs, rhs);
872 if (d_ptr->lessThan && !d_ptr->lessThan(d_ptr, lhs, rhs) && !d_ptr->lessThan(d_ptr, rhs, lhs))
879
880
881
882
883
884
885
886
887
890
891
892
893
894
895
896
897
898
901
902
903
904
905
906
907
908
911
912
913
914
915
916
917
918
920bool QMetaType::isDefaultConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
922 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDefaultConstructible(iface);
925bool QMetaType::isCopyConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
927 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isCopyConstructible(iface);
930bool QMetaType::isMoveConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
932 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isMoveConstructible(iface);
935bool QMetaType::isDestructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
937 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDestructible(iface);
941
942
943
944
945
946bool QMetaType::isEqualityComparable()
const
948 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->equals !=
nullptr || d_ptr->lessThan !=
nullptr);
952
953
954
955
956
957bool QMetaType::isOrdered()
const
959 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->lessThan !=
nullptr);
962#ifndef QT_BOOTSTRAPPED
964
965
966void QMetaType::unregisterMetaType(QMetaType type)
968 const QtPrivate::QMetaTypeInterface *d_ptr = type.d_ptr;
972 const int typeId = d_ptr->typeId.loadRelaxed();
973 if (typeId < QMetaType::User)
978 if (
auto reg = customTypeRegistry()) {
979 Q_ASSERT(reg->getCustomType(typeId) == d_ptr);
980 reg->unregisterDynamicType(typeId);
983 const_cast<QtPrivate::QMetaTypeInterface *>(d_ptr)->typeId.storeRelease(0);
988
989
990
991
992
995
996
997
998
999
1000
1003
1004
1005
1006
1007
1008
1010static constexpr auto createStaticTypeToIdMap()
1012#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
1014#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
1016 constexpr auto staticTypeNames = qOffsetStringArray(
1021 constexpr int Count = staticTypeNames.count();
1022#undef QT_ADD_STATIC_METATYPE
1023#undef QT_ADD_STATIC_METATYPE_ALIASES_ITER
1025#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
1027#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
1028 QMetaType::MetaTypeName,
1029 std::array<
int, Count> typeIds = {
1032 QMetaTypeId2<qreal>::MetaType,
1034#undef QT_ADD_STATIC_METATYPE
1035#undef QT_ADD_STATIC_METATYPE_ALIASES_ITER
1037 using Base = std::remove_cv_t<
decltype(staticTypeNames)>;
1038 using Array = std::remove_cv_t<
decltype(typeIds)>;
1040 constexpr Map(
const Base &base,
const Array &typeIdMap)
1041 : Base(base), typeIdMap(typeIdMap)
1043 std::array<
int, Count> typeIdMap;
1046 return Map(staticTypeNames, typeIds);
1048static constexpr auto types = createStaticTypeToIdMap();
1050template <
typename From,
typename To>
1055 static_assert(
std::numeric_limits<From>::is_iec559);
1057 static_assert(
std::is_integral_v<To>);
1058 static_assert(
sizeof(From) <=
sizeof(
double));
1059 const double fromD =
static_cast<
double>(from);
1061 if (qt_is_nan(fromD)) {
1067 convertDoubleTo(std::round(fromD), &result);
1075 template<
typename T,
typename LiteralWrapper =
1076 std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView,
const char *>>
1077 static inline bool convertToBool(
const T &source)
1079 T str = source.toLower();
1080 return !(str.isEmpty() || str == LiteralWrapper(
"0") || str == LiteralWrapper(
"false"));
1096 static bool convert(
const void *from,
int fromTypeId,
void *to,
int toTypeId)
1098 Q_ASSERT(fromTypeId != toTypeId);
1100#ifdef QT_BOOTSTRAPPED
1105 bool onlyCheck = (from ==
nullptr && to ==
nullptr);
1108 Q_ASSERT(onlyCheck || (
bool(from) &&
bool(to)));
1111 using SChar =
signed char;
1112 using UChar =
unsigned char;
1113 using Short =
short;
1114 using UShort =
unsigned short;
1116 using UInt =
unsigned int;
1118 using LongLong = qlonglong;
1119 using ULong =
unsigned long;
1120 using ULongLong = qulonglong;
1122 using Float =
float;
1123 using Double =
double;
1125 using Nullptr =
std::nullptr_t;
1126 using Char16 =
char16_t;
1127 using Char32 =
char32_t;
1129#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From)
1131#define QMETATYPE_CONVERTER_ASSIGN_NUMBER(To, From)
1133#define CONVERT_CBOR_AND_JSON(To)
1135 if constexpr(std::is_same_v<To, Bool>) {
1136 if (!source.isBool())
1138 result = source.toBool();
1140 if (!source.isInteger() && !source.isDouble())
1142 if constexpr(std::is_integral_v<To>)
1143 result = source.toInteger();
1145 result = To(source.toDouble());
1150 if constexpr(std::is_same_v<To, Bool>) {
1151 if (!source.isBool())
1153 result = source.toBool();
1155 if (!source.isDouble())
1157 if constexpr(std::is_integral_v<To>)
1158 result = source.toInteger();
1160 result = To(source.toDouble());
1165#define INTEGRAL_CONVERTER(To)
1178 QMETATYPE_CONVERTER(To, Float16, return qIntegerConversionFromFPHelper(source, &result););
1184 if constexpr(std::is_same_v<To, bool>)
1185 result = (ok = true, convertToBool(source));
1186 else if constexpr(std::is_signed_v<To>)
1187 result = To(source.toLongLong(&ok));
1189 result = To(source.toULongLong(&ok));
1194 if constexpr(std::is_same_v<To, bool>)
1195 result = (ok = true, convertToBool(source));
1196 else if constexpr(std::is_signed_v<To>)
1197 result = To(source.toLongLong(&ok));
1199 result = To(source.toULongLong(&ok));
1204#define FLOAT_CONVERTER(To)
1222 result = To(source.toDouble(&ok));
1227 result = To(source.toDouble(&ok));
1232 switch (makePair(toTypeId, fromTypeId)) {
1234QT_WARNING_DISABLE_CLANG(
"-Wtautological-compare")
1254 if (source.isUrl()) {
1255 result = source.toUrl();
1260#if QT_CONFIG(itemmodel)
1261 QMETATYPE_CONVERTER_ASSIGN(QModelIndex, QPersistentModelIndex);
1262 QMETATYPE_CONVERTER_ASSIGN(QPersistentModelIndex, QModelIndex);
1266#define QMETATYPE_CONVERTER_ASSIGN_QCHAR(From)
1299 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1303 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1307 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1311 result = QString::fromLatin1(&source, 1);
1316 result = QString::fromLatin1(&s, 1);
1321 result = QString::fromLatin1(&s, 1);
1325 result = QChar(source);
1329 result = QStringView(QChar::fromUcs4(source)).toString();
1332#if QT_CONFIG(datestring)
1333 QMETATYPE_CONVERTER(QString, QDate, result = source.toString(Qt::ISODate);
return true;);
1334 QMETATYPE_CONVERTER(QString, QTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1335 QMETATYPE_CONVERTER(QString, QDateTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1339 return (source.size() == 1) ? (result = source.at(0),
true) :
false;
1343 if (source.isString() || source.isNull()) {
1344 result = source.toString();
1349 QMETATYPE_CONVERTER(QString, Nullptr, Q_UNUSED(source); result = QString();
return true;);
1354 result = source ?
"true" :
"false";
1369 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1373 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1377 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1396 QMETATYPE_CONVERTER(QStringList, QString, result = QStringList() << source;
return true;);
1399 result.reserve(source.size());
1400 for (
const auto &v: source)
1401 result.append(v.toByteArray());
1405 result.reserve(source.size());
1406 for (
const auto &v: source)
1407 result.append(QVariant(v));
1412 result.reserve(source.size());
1413 for (
const auto &v: source)
1414 result.append(v.toString());
1418 result.reserve(source.size());
1419 for (
const auto &v: source)
1420 result.append(QVariant(v));
1425 result.reserve(source.size());
1426 for (
auto it = source.begin(); it != source.end(); ++it)
1427 result.insert(it.key(), it.value());
1431 for (
auto it = source.begin(); it != source.end(); ++it)
1432 result.insert(it.key(), it.value());
1437 if (source.isContainer() || source.isTag())
1439 result = source.toVariant().toString();
1444 if (source.isByteArray()) {
1445 result = source.toByteArray();
1452 if (!source.isUuid())
1454 result = source.toUuid();
1459 if (!source.isArray())
1461 result = source.toArray().toVariantList();
1464 QMETATYPE_CONVERTER(QCborValue, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1466 if (!source.isMap())
1468 result = source.toMap().toVariantMap();
1471 QMETATYPE_CONVERTER(QCborValue, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1473 if (!source.isMap())
1475 result = source.toMap().toVariantHash();
1478#if QT_CONFIG(regularexpression)
1479 QMETATYPE_CONVERTER(QCborValue, QRegularExpression, result = QCborValue(source);
return true;);
1480 QMETATYPE_CONVERTER(QRegularExpression, QCborValue,
1481 if (!source.isRegularExpression())
1483 result = source.toRegularExpression();
1490 result = QCborValue(QCborValue::Null);
1495 return source.isNull();
1513 result = QCborArray::fromStringList(source);
1516#if QT_CONFIG(datestring)
1517 QMETATYPE_CONVERTER(QCborValue, QDate,
1518 result = QCborValue(source.startOfDay());
1524 result = QCborValue::fromJsonValue(source);
1528 result = QCborMap::fromJsonObject(source);
1532 result = QCborArray::fromJsonArray(source);
1536 QJsonDocument doc = source;
1538 result = QCborArray::fromJsonArray(doc.array());
1540 result = QCborMap::fromJsonObject(doc.object());
1546#if QT_CONFIG(datestring)
1547 QMETATYPE_CONVERTER_ASSIGN(QCborValue, QDateTime);
1548 QMETATYPE_CONVERTER(QDateTime, QCborValue,
1549 if (source.isDateTime()) {
1550 result = source.toDateTime();
1559 if (source.isSimpleType()) {
1560 result = source.toSimpleType();
1568 QMETATYPE_CONVERTER(QCborArray, QStringList, result = QCborArray::fromStringList(source);
return true;);
1569 QMETATYPE_CONVERTER(QCborMap, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1571 QMETATYPE_CONVERTER(QCborMap, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1572 QMETATYPE_CONVERTER(QVariantHash, QCborMap, result = source.toVariantHash();
return true;);
1575 if (!source.isArray())
1577 result = source.toArray();
1581 if (!source.isArray())
1583 result = QCborArray::fromJsonArray(source.array());
1587 if (!source.isArray())
1589 result = QCborArray::fromJsonArray(source.toArray());
1593 result = QCborArray::fromJsonArray(source);
1597 if (!source.isMap())
1599 result = source.toMap();
1603 if (source.isArray())
1605 result = QCborMap::fromJsonObject(source.object());
1609 if (!source.isObject())
1611 result = QCborMap::fromJsonObject(source.toObject());
1615 result = QCborMap::fromJsonObject(source);
1621 if (!source.isArray())
1623 result = source.toArray().toVariantList();
1628 if (!source.isObject())
1630 result = source.toObject().toVariantMap();
1633 QMETATYPE_CONVERTER(QVariantMap, QJsonObject, result = source.toVariantMap();
return true;);
1635 if (!source.isObject())
1637 result = source.toObject().toVariantHash();
1640 QMETATYPE_CONVERTER(QVariantHash, QJsonObject, result = source.toVariantHash();
return true;);
1643 QMETATYPE_CONVERTER(QJsonArray, QStringList, result = QJsonArray::fromStringList(source);
return true;);
1646 if (!source.isArray())
1648 result = source.toArray();
1652 if (!source.isArray())
1654 result = source.array();
1658 if (!source.isArray())
1660 result = source.toArray().toJsonArray();
1664 QMETATYPE_CONVERTER(QJsonObject, QVariantMap, result = QJsonObject::fromVariantMap(source);
return true;);
1665 QMETATYPE_CONVERTER(QJsonObject, QVariantHash, result = QJsonObject::fromVariantHash(source);
return true;);
1667 if (!source.isObject())
1669 result = source.toObject();
1673 if (source.isArray())
1675 result = source.object();
1679 if (!source.isMap())
1681 result = source.toMap().toJsonObject();
1684 QMETATYPE_CONVERTER(QJsonObject, QCborMap, result = source.toJsonObject();
return true; );
1688 result = QJsonValue(QJsonValue::Null);
1693 return source.isNull();
1696 result = QJsonValue(source);
1714 result = QJsonValue(QJsonArray::fromStringList(source));
1718 result = QJsonValue(QJsonArray::fromVariantList(source));
1722 result = QJsonValue(QJsonObject::fromVariantMap(source));
1726 result = QJsonValue(QJsonObject::fromVariantHash(source));
1738 QJsonDocument doc = source;
1739 result = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1743 result = source.toJsonValue();
1747 result = source.toJsonObject();
1751 result = source.toJsonArray();
1758#if QT_CONFIG(datestring)
1759 QMETATYPE_CONVERTER(QDate, QString,
1760 result = QDate::fromString(source, Qt::ISODate);
1761 return result.isValid();
1763 QMETATYPE_CONVERTER(QTime, QString,
1764 result = QTime::fromString(source, Qt::ISODate);
1765 return result.isValid();
1767 QMETATYPE_CONVERTER(QDateTime, QString,
1768 result = QDateTime::fromString(source, Qt::ISODate);
1769 return result.isValid();
1781Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeGuiHelper = {};
1782Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeWidgetsHelper = {};
1784#ifndef QT_BOOTSTRAPPED
1787 int type = qMax(fromTypeId, toTypeId);
1788 if (type <= QMetaType::LastCoreType)
1789 return QCoreVariantHelper::convert(from, fromTypeId, to, toTypeId);
1790 if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType)
1791 return qMetaTypeGuiHelper.convert(from, fromTypeId, to, toTypeId);
1792 else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType)
1793 return qMetaTypeWidgetsHelper.convert(from, fromTypeId, to, toTypeId);
1797template<
typename T,
typename Key>
1803 const QWriteLocker locker(&lock);
1809 const QReadLocker locker(&lock);
1810 return map.contains(k);
1815 const QWriteLocker locker(&lock);
1816 auto r = map.tryEmplace(k, f);
1822 const QReadLocker locker(&lock);
1823 auto it = map.find(k);
1824 return it == map.end() ?
nullptr :
std::addressof(*it);
1829 const Key k(from, to);
1830 const QWriteLocker locker(&lock);
1834 mutable QReadWriteLock lock;
1838using QMetaTypeConverterRegistry
1839 = QMetaTypeFunctionRegistry<QMetaType::ConverterFunction, std::pair<
int,
int>>;
1841Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
1843using QMetaTypeMutableViewRegistry
1844 = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, std::pair<
int,
int>>;
1845Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
1848
1849
1850
1851
1852
1853
1854
1857
1858
1859
1860
1861
1862
1863
1864
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1892
1893
1894
1895
1897
1898bool QMetaType::registerConverterFunction(
const ConverterFunction &f, QMetaType from, QMetaType to)
1900 if (!customTypesConversionRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1901 qWarning(
"Type conversion already registered from type %s to type %s",
1902 from.name(), to.name());
1909
1910
1911
1912
1913
1914
1915
1918
1919
1920
1921
1922
1923
1926
1927
1928
1930
1931bool QMetaType::registerMutableViewFunction(
const MutableViewFunction &f, QMetaType from, QMetaType to)
1933 if (!customTypesMutableViewRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1934 qWarning(
"Mutable view on type already registered from type %s to type %s",
1935 from.name(), to.name());
1943
1944void QMetaType::unregisterMutableViewFunction(QMetaType from, QMetaType to)
1946 if (customTypesMutableViewRegistry.isDestroyed())
1948 customTypesMutableViewRegistry()->remove(from.id(), to.id());
1952
1953
1955
1956void QMetaType::unregisterConverterFunction(QMetaType from, QMetaType to)
1958 if (customTypesConversionRegistry.isDestroyed())
1960 customTypesConversionRegistry()->remove(from.id(), to.id());
1964#ifndef QT_NO_DEBUG_STREAM
1967
1968
1970
1971QDebug operator<<(QDebug d, QMetaType m)
1973 const QDebugStateSaver saver(d);
1974 return d.nospace() <<
"QMetaType(" << m.name() <<
")";
1978
1979
1981
1982bool QMetaType::debugStream(QDebug& dbg,
const void *rhs)
1984 if (d_ptr && d_ptr->flags & QMetaType::IsPointer) {
1985 dbg << *
reinterpret_cast<
const void *
const *>(rhs);
1988 if (d_ptr && d_ptr->debugStream) {
1989 d_ptr->debugStream(d_ptr, dbg, rhs);
1996
1997
1998
1999
2002
2003
2004
2005
2006
2007
2010
2011
2012
2013
2014
2015
2016
2019
2020
2021
2023
2024bool QMetaType::hasRegisteredDebugStreamOperator()
const
2026 return d_ptr && d_ptr->debugStream !=
nullptr;
2030#ifndef QT_NO_QOBJECT
2032
2034
2035static QMetaEnum metaEnumFromType(QMetaType t)
2037 if (t.flags() & QMetaType::IsEnumeration) {
2038 if (
const QMetaObject *metaObject = t.metaObject()) {
2039 QByteArrayView qflagsNamePrefix =
"QFlags<";
2041 if (enumName.endsWith(
'>') && enumName.startsWith(qflagsNamePrefix)) {
2044 enumName = enumName.sliced(qflagsNamePrefix.size());
2046 if (qsizetype lastColon = enumName.lastIndexOf(
':'); lastColon != -1)
2047 enumName = enumName.sliced(lastColon + 1);
2048 return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
2055#ifndef QT_BOOTSTRAPPED
2056static bool convertFromEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2059 if (fromType.flags() & QMetaType::IsUnsignedEnumeration) {
2061 switch (fromType.sizeOf()) {
2063 ull = *
static_cast<
const unsigned char *>(from);
2066 ull = *
static_cast<
const unsigned short *>(from);
2069 ull = *
static_cast<
const unsigned int *>(from);
2072 ull = *
static_cast<
const quint64 *>(from);
2077 if (toType.id() == QMetaType::ULongLong) {
2078 *
static_cast<qulonglong *>(to) = ull;
2081 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2082 return QMetaType::convert(QMetaType::fromType<qulonglong>(), &ull, toType, to);
2083 ll = qlonglong(ull);
2085 switch (fromType.sizeOf()) {
2087 ll = *
static_cast<
const signed char *>(from);
2090 ll = *
static_cast<
const short *>(from);
2093 ll = *
static_cast<
const int *>(from);
2096 ll = *
static_cast<
const qint64 *>(from);
2101 if (toType.id() == QMetaType::LongLong) {
2102 *
static_cast<qlonglong *>(to) = ll;
2105 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2106 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2108#ifndef QT_NO_QOBJECT
2109 QMetaEnum en = metaEnumFromType(fromType);
2113 if (toType.id() == QMetaType::QString)
2114 *
static_cast<QString *>(to) = QString::fromUtf8(keys);
2118 const char *key = en.valueToKey(ll);
2119 if (toType.id() == QMetaType::QString)
2120 *
static_cast<QString *>(to) = QString::fromUtf8(key);
2127 if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray)
2128 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2132static bool convertToEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2134 int fromTypeId = fromType.id();
2135 qlonglong value = -1;
2137#ifndef QT_NO_QOBJECT
2138 if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) {
2139 QMetaEnum en = metaEnumFromType(toType);
2141 QByteArray keys = (fromTypeId == QMetaType::QString)
2142 ?
static_cast<
const QString *>(from)->toUtf8()
2143 : *
static_cast<
const QByteArray *>(from);
2144 if (
auto v = en.keysToValue64(keys.constData())) {
2152 if (fromTypeId == QMetaType::LongLong) {
2153 value = *
static_cast<
const qlonglong *>(from);
2156 ok = QMetaType::convert(fromType, from, QMetaType::fromType<qlonglong>(), &value);
2163 switch (toType.sizeOf()) {
2165 *
static_cast<
signed char *>(to) = value;
2168 *
static_cast<qint16 *>(to) = value;
2171 *
static_cast<qint32 *>(to) = value;
2174 *
static_cast<qint64 *>(to) = value;
2177 Q_UNREACHABLE_RETURN(
false);
2181template<
typename Iterable>
2182bool convertIterableToVariantList(QMetaType fromType,
const void *from,
void *to)
2185 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &list))
2190 if (list.metaContainer().hasSize())
2191 l.reserve(list.size());
2192 auto end = list.end();
2193 for (
auto it = list.begin(); it != end; ++it)
2198template<
typename Iterable>
2199bool convertIterableToVariantMap(QMetaType fromType,
const void *from,
void *to)
2202 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
2205 QVariantMap &h = *
static_cast<QVariantMap *>(to);
2207 auto end = map.end();
2208 for (
auto it = map.begin(); it != end; ++it)
2209 h.insert(it.key().toString(), it.value());
2213template<
typename Iterable>
2214bool convertIterableToVariantHash(QMetaType fromType,
const void *from,
void *to)
2217 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
2220 QVariantHash &h = *
static_cast<QVariantHash *>(to);
2222 h.reserve(map.size());
2223 auto end = map.end();
2224 for (
auto it = map.begin(); it != end; ++it)
2225 h.insert(it.key().toString(), it.value());
2229static bool convertIterableToVariantPair(QMetaType fromType,
const void *from,
void *to)
2232 const auto f = customTypesConversionRegistry()->function({fromType.id(), targetId});
2240 QVariant v1(pi._metaType_first);
2242 if (pi._metaType_first == QMetaType::fromType<QVariant>())
2245 dataPtr = v1.data();
2248 QVariant v2(pi._metaType_second);
2249 if (pi._metaType_second == QMetaType::fromType<QVariant>())
2252 dataPtr = v2.data();
2255 *
static_cast<QVariantPair *>(to) = QVariantPair(v1, v2);
2259template<
typename Iterable>
2260static bool convertToSequentialIterable(QMetaType fromType,
const void *from,
void *to)
2263 const int fromTypeId = fromType.id();
2265 Iterable &i = *
static_cast<Iterable *>(to);
2266 switch (fromTypeId) {
2267 case QMetaType::QVariantList:
2268 i = Iterable(
reinterpret_cast<
const QVariantList *>(from));
2270 case QMetaType::QStringList:
2271 i = Iterable(
reinterpret_cast<
const QStringList *>(from));
2273 case QMetaType::QByteArrayList:
2274 i = Iterable(
reinterpret_cast<
const QByteArrayList *>(from));
2276 case QMetaType::QString:
2277 i = Iterable(
reinterpret_cast<
const QString *>(from));
2279 case QMetaType::QByteArray:
2280 i = Iterable(
reinterpret_cast<
const QByteArray *>(from));
2283 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2284 if (QMetaType::convert(
2285 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2295static bool canConvertToSequentialIterable(QMetaType fromType)
2297 switch (fromType.id()) {
2298 case QMetaType::QVariantList:
2299 case QMetaType::QStringList:
2300 case QMetaType::QByteArrayList:
2301 case QMetaType::QString:
2302 case QMetaType::QByteArray:
2305 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2309static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType)
2311 switch (fromType.id()) {
2312 case QMetaType::QVariantList:
2313 case QMetaType::QStringList:
2314 case QMetaType::QByteArrayList:
2315 case QMetaType::QString:
2316 case QMetaType::QByteArray:
2319 return QMetaType::canView(
2320 fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2324template<
typename Iterable>
2325static bool viewAsSequentialIterable(QMetaType fromType,
void *from,
void *to)
2328 const int fromTypeId = fromType.id();
2330 Iterable &i = *
static_cast<Iterable *>(to);
2331 switch (fromTypeId) {
2332 case QMetaType::QVariantList:
2335 case QMetaType::QStringList:
2336 i = Iterable(
reinterpret_cast<QStringList *>(from));
2338 case QMetaType::QByteArrayList:
2339 i = Iterable(
reinterpret_cast<QByteArrayList *>(from));
2341 case QMetaType::QString:
2342 i = Iterable(
reinterpret_cast<QString *>(from));
2344 case QMetaType::QByteArray:
2345 i = Iterable(
reinterpret_cast<
QByteArray *>(from));
2348 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2349 if (QMetaType::view(
2350 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2360template<
typename Iterable>
2361static bool convertToAssociativeIterable(QMetaType fromType,
const void *from,
void *to)
2365 Iterable &i = *
static_cast<Iterable *>(to);
2366 if (fromType.id() == QMetaType::QVariantMap) {
2367 i = Iterable(
reinterpret_cast<
const QVariantMap *>(from));
2370 if (fromType.id() == QMetaType::QVariantHash) {
2371 i = Iterable(
reinterpret_cast<
const QVariantHash *>(from));
2375 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2376 if (QMetaType::convert(
2377 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2385static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
2387 if ((fromType.flags() & QMetaType::IsPointer) != (toType.flags() & QMetaType::IsPointer))
2390 const QMetaObject *f = fromType.metaObject();
2391 const QMetaObject *t = toType.metaObject();
2393 return f->inherits(t) || (t->inherits(f));
2398static bool canConvertToAssociativeIterable(QMetaType fromType)
2400 switch (fromType.id()) {
2401 case QMetaType::QVariantMap:
2402 case QMetaType::QVariantHash:
2405 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2409static bool canImplicitlyViewAsAssociativeIterable(QMetaType fromType)
2411 switch (fromType.id()) {
2412 case QMetaType::QVariantMap:
2413 case QMetaType::QVariantHash:
2416 return QMetaType::canView(
2417 fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2421template<
typename Iterable>
2422static bool viewAsAssociativeIterable(QMetaType fromType,
void *from,
void *to)
2425 int fromTypeId = fromType.id();
2427 Iterable &i = *
static_cast<Iterable *>(to);
2428 if (fromTypeId == QMetaType::QVariantMap) {
2429 i = Iterable(
reinterpret_cast<QVariantMap *>(from));
2432 if (fromTypeId == QMetaType::QVariantHash) {
2433 i = Iterable(
reinterpret_cast<QVariantHash *>(from));
2437 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2438 if (QMetaType::view(
2439 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2447static bool convertMetaObject(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2450 if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
2451 QObject *fromObject = *
static_cast<QObject *
const *>(from);
2453 if (fromObject && fromObject->metaObject()->inherits(toType.metaObject())) {
2454 *
static_cast<QObject **>(to) = toType.metaObject()->cast(fromObject);
2456 }
else if (!fromObject && fromType.metaObject()) {
2458 *
static_cast<
void **>(to) =
nullptr;
2459 return fromType.metaObject()->inherits(toType.metaObject());
2461 }
else if ((fromType.flags() & QMetaType::IsPointer) == (toType.flags() & QMetaType::IsPointer)) {
2463 const QMetaObject *f = fromType.metaObject();
2464 const QMetaObject *t = toType.metaObject();
2465 if (f && t && f->inherits(t)) {
2466 toType.destruct(to);
2467 toType.construct(to, from);
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2487
2488
2489
2490
2491
2493
2494bool QMetaType::convert(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2496 if (!fromType.isValid() || !toType.isValid())
2499 if (fromType == toType) {
2501 fromType.destruct(to);
2502 fromType.construct(to, from);
2506 int fromTypeId = fromType.id();
2507 int toTypeId = toType.id();
2509 if (tryConvertBuiltinTypes(from, fromTypeId, to, toTypeId))
2511 const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId});
2513 return (*f)(from, to);
2515 if (fromType.flags() & QMetaType::IsEnumeration)
2516 return convertFromEnum(fromType, from, toType, to);
2517 if (toType.flags() & QMetaType::IsEnumeration)
2518 return convertToEnum(fromType, from, toType, to);
2519 if (toTypeId == Nullptr) {
2520 *
static_cast<std::nullptr_t *>(to) =
nullptr;
2521 if (fromType.flags() & QMetaType::IsPointer) {
2522 if (*
static_cast<
const void *
const *>(from) ==
nullptr)
2527 if (toTypeId == QVariantPair && convertIterableToVariantPair(fromType, from, to))
2531 if (toTypeId == QVariantList
2532 && convertIterableToVariantList<QMetaSequence::Iterable>(fromType, from, to)) {
2536 if (toTypeId == QVariantMap
2537 && convertIterableToVariantMap<QMetaAssociation::Iterable>(fromType, from, to)) {
2541 if (toTypeId == QVariantHash
2542 && convertIterableToVariantHash<QMetaAssociation::Iterable>(fromType, from, to)) {
2546 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2547 return convertToSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
2549 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2550 return convertToAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
2552#if QT_DEPRECATED_SINCE(6
, 15
)
2554 QT_WARNING_DISABLE_DEPRECATED
2556 if (toTypeId == QVariantList
2557 && convertIterableToVariantList<QSequentialIterable>(fromType, from, to)) {
2561 if (toTypeId == QVariantMap
2562 && convertIterableToVariantMap<QAssociativeIterable>(fromType, from, to)) {
2566 if (toTypeId == QVariantHash
2567 && convertIterableToVariantHash<QAssociativeIterable>(fromType, from, to)) {
2571 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2572 return convertToSequentialIterable<QSequentialIterable>(fromType, from, to);
2574 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2575 return convertToAssociativeIterable<QAssociativeIterable>(fromType, from, to);
2580 return convertMetaObject(fromType, from, toType, to);
2584
2585
2587
2588bool QMetaType::view(QMetaType fromType,
void *from, QMetaType toType,
void *to)
2590 if (!fromType.isValid() || !toType.isValid())
2593 int fromTypeId = fromType.id();
2594 int toTypeId = toType.id();
2596 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2598 return (*f)(from, to);
2600 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2601 return viewAsSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
2603 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2604 return viewAsAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
2606#if QT_DEPRECATED_SINCE(6
, 15
)
2608 QT_WARNING_DISABLE_DEPRECATED
2610 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2611 return viewAsSequentialIterable<QSequentialIterable>(fromType, from, to);
2613 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2614 return viewAsAssociativeIterable<QAssociativeIterable>(fromType, from, to);
2619 return convertMetaObject(fromType, from, toType, to);
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2638
2639bool QMetaType::canView(QMetaType fromType, QMetaType toType)
2641 int fromTypeId = fromType.id();
2642 int toTypeId = toType.id();
2644 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2647 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2651 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2652 return canImplicitlyViewAsSequentialIterable(fromType);
2654 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2655 return canImplicitlyViewAsAssociativeIterable(fromType);
2657#if QT_DEPRECATED_SINCE(6
, 15
)
2659 QT_WARNING_DISABLE_DEPRECATED
2661 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2662 return canImplicitlyViewAsSequentialIterable(fromType);
2664 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2665 return canImplicitlyViewAsAssociativeIterable(fromType);
2670 if (canConvertMetaObject(fromType, toType))
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
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2760
2761bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
2763 int fromTypeId = fromType.id();
2764 int toTypeId = toType.id();
2766 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2769 if (fromTypeId == toTypeId)
2772 if (tryConvertBuiltinTypes(
nullptr, fromTypeId,
nullptr, toTypeId))
2775 const ConverterFunction *
const f =
2776 customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId));
2780 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2781 return canConvertToSequentialIterable(fromType);
2783 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2784 return canConvertToAssociativeIterable(fromType);
2786 if (toTypeId == QVariantList
2787 && canConvert(fromType, QMetaType::fromType<QMetaSequence::Iterable>())) {
2791 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2792 && canConvert(fromType, QMetaType::fromType<QMetaAssociation::Iterable>())) {
2796#if QT_DEPRECATED_SINCE(6
, 15
)
2798 QT_WARNING_DISABLE_DEPRECATED
2800 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2801 return canConvertToSequentialIterable(fromType);
2803 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2804 return canConvertToAssociativeIterable(fromType);
2806 if (toTypeId == QVariantList
2807 && canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
2811 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2812 && canConvert(fromType, QMetaType::fromType<QAssociativeIterable>())) {
2819 if (toTypeId == QVariantPair && hasRegisteredConverterFunction(
2820 fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
2823 if (fromType.flags() & IsEnumeration) {
2824 if (toTypeId == QString || toTypeId == QByteArray)
2826 return canConvert(QMetaType(LongLong), toType);
2828 if (toType.flags() & IsEnumeration) {
2829 if (fromTypeId == QString || fromTypeId == QByteArray)
2831 return canConvert(fromType, QMetaType(LongLong));
2833 if (toTypeId == Nullptr && fromType.flags() & IsPointer)
2835 if (canConvertMetaObject(fromType, toType))
2842
2843
2844
2845
2846
2847
2848
2851
2852
2853
2854
2855
2858
2859
2861
2862bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType)
2864 return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
2868
2870
2871bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
2873 const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2874 return QMetaType::hasRegisteredConverterFunction(m, to);
2878
2880
2881bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
2883 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2884 return QMetaType::hasRegisteredConverterFunction(m, to);
2888
2890
2891bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
2893 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2894 return QMetaType::hasRegisteredConverterFunction(m, to);
2898
2899
2900
2901
2902
2905
2906
2908
2909bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType)
2911 return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
2915
2917
2918bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
2920 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2921 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2925
2927
2928bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
2930 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2931 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2936
2937
2938
2939
2940
2941
2942
2943
2944
2947
2948
2949
2950
2951
2952
2953
2954
2955
2959
2960static inline int qMetaTypeStaticType(QByteArrayView name)
2962 for (
int i = 0; i < types.count(); ++i) {
2963 if (types.viewAt(i) == name)
2964 return types.typeIdMap[i];
2966 return QMetaType::UnknownType;
2969#ifndef QT_BOOTSTRAPPED
2971
2972
2973
2974
2976
2977void QMetaType::registerNormalizedTypedef(
const NS(QByteArray) & normalizedTypeName,
2980 if (!metaType.isValid())
2982 if (
auto reg = customTypeRegistry()) {
2983 QWriteLocker lock(®->lock);
2984 auto &al = reg->aliases[normalizedTypeName];
2988 al = QMetaTypeCustomRegistry::Alias(
2989 metaType.d_ptr, QMetaTypeCustomRegistry::HasTypedefs::Yes);
2990 reg->aliases[metaType.name()].setTag(QMetaTypeCustomRegistry::HasTypedefs::Yes);
2997 Q_ASSERT(typeId < QMetaType::User);
2998 if (typeId <= QMetaType::LastCoreType)
2999 return QCoreVariantHelper::interfaceForType(typeId);
3000 if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType)
3001 return qMetaTypeGuiHelper.interfaceForType(typeId);
3002 if (typeId >= QMetaType::FirstWidgetsType && typeId <= QMetaType::LastWidgetsType)
3003 return qMetaTypeWidgetsHelper.interfaceForType(typeId);
3010 if (typeId >= QMetaType::User) {
3011#ifndef QT_BOOTSTRAPPED
3012 if (customTypeRegistry.exists())
3013 iface = customTypeRegistry->getCustomType(typeId);
3016 iface = interfaceForStaticType(typeId);
3022
3023
3024
3026
3027bool QMetaType::isRegistered(
int type)
3029 return interfaceForTypeNoWarning(type) !=
nullptr;
3034 Q_PRE(!name.isEmpty());
3035 int type = qMetaTypeStaticType(name);
3036 if (type != QMetaType::UnknownType) {
3037 return interfaceForStaticType(type);
3038#ifndef QT_BOOTSTRAPPED
3039 }
else if (customTypeRegistry.exists()) {
3040 QReadLocker locker(&customTypeRegistry->lock);
3041 auto it = customTypeRegistry->aliases.constFind(name);
3042 if (it != customTypeRegistry->aliases.constEnd())
3043 return it.value().data();
3050
3051
3052
3053
3054
3055
3056
3057
3060
3061
3062
3063
3064
3065
3067
3068int qMetaTypeTypeInternal(QByteArrayView name)
3071 if (!name.isEmpty())
3072 iface = findMetaTypeByName(name);
3073 return iface ? iface->typeId.loadRelaxed() : QMetaType::UnknownType;
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3089#ifndef QT_NO_DATASTREAM
3091
3092
3093
3094
3095
3096
3097
3098
3100
3101bool QMetaType::save(QDataStream &stream,
const void *data)
const
3103 if (!data || !isValid())
3107 if (id() == QMetaType::Long) {
3108 stream << qlonglong(*(
long *)data);
3110 }
else if (id() == QMetaType::ULong) {
3111 stream << qlonglong(*(
unsigned long *)data);
3115 if (!d_ptr->dataStreamOut)
3118 d_ptr->dataStreamOut(d_ptr, stream, data);
3123
3124
3125
3126
3129
3130
3131
3132
3133
3134
3135
3136
3138
3139bool QMetaType::load(QDataStream &stream,
void *data)
const
3141 if (!data || !isValid())
3145 if (id() == QMetaType::Long) {
3148 *(
long *)data =
long(ll);
3150 }
else if (id() == QMetaType::ULong) {
3153 *(
unsigned long *)data = (
unsigned long)(ull);
3156 if (!d_ptr->dataStreamIn)
3159 d_ptr->dataStreamIn(d_ptr, stream, data);
3164
3165
3166
3168
3169bool QMetaType::hasRegisteredDataStreamOperators()
const
3172 if (type == QMetaType::Long || type == QMetaType::ULong)
3174 return d_ptr && d_ptr->dataStreamIn !=
nullptr && d_ptr->dataStreamOut !=
nullptr;
3178
3179
3180
3181
3182
3183
3185
3186QMetaType QMetaType::underlyingType()
const
3188 if (!d_ptr || !(flags() & IsEnumeration))
3191
3192
3193
3194
3195
3196
3197 if (flags() & IsUnsignedEnumeration) {
3200 return QMetaType::fromType<quint8>();
3202 return QMetaType::fromType<quint16>();
3204 return QMetaType::fromType<quint32>();
3206 return QMetaType::fromType<quint64>();
3213 return QMetaType::fromType<qint8>();
3215 return QMetaType::fromType<qint16>();
3217 return QMetaType::fromType<qint32>();
3219 return QMetaType::fromType<qint64>();
3229
3230
3231
3232
3236
3238
3239QMetaType QMetaType::fromName(QByteArrayView typeName)
3241 if (typeName.isEmpty())
3244 const QtPrivate::QMetaTypeInterface *iface = findMetaTypeByName(typeName);
3246 return QMetaType(iface);
3248#if !defined(QT_NO_QOBJECT)
3249 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName.constData());
3250 if (normalizedTypeName != typeName)
3251 iface = findMetaTypeByName(normalizedTypeName);
3254 return QMetaType(iface);
3258
3259
3260
3261
3262
3263
3264
3265
3268
3269
3270
3271
3272
3273
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3333
3334
3335
3336
3337
3338
3339
3340
3343
3344
3345
3346
3347
3348
3349
3350
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3459 if (!iface && typeId != QMetaType::UnknownType)
3460 qWarning(
"Trying to construct an instance of an invalid type, type id: %i", typeId);
3466
3467
3468
3469
3470
3473
3474
3475
3477
3478QMetaType::QMetaType(
int typeId) : QMetaType(interfaceForType(typeId)) {}
3482
3483
3484
3485
3487namespace QtPrivate {
3488#if !defined(QT_BOOTSTRAPPED)
3489void QMetaTypeCopyTraits::warnAboutDeprecatedCopy(
const char *name)
3491 qCWarning(lcMetatypeDeprecated,
"QMetaType: copy construction of type '%s' is deprecated", name);
3495#if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
3498#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name)
3499 template class QMetaTypeForType<Name>;
3500 template struct QMetaTypeInterfaceWrapper<Name>;
3507#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)