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)) {
1064 }
else if constexpr (
std::is_same_v<To,
bool>) {
1070 convertDoubleTo(std::round(fromD), &result);
1078 template<
typename T,
typename LiteralWrapper =
1079 std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView,
const char *>>
1080 static inline bool convertToBool(
const T &source)
1082 T str = source.toLower();
1083 return !(str.isEmpty() || str == LiteralWrapper(
"0") || str == LiteralWrapper(
"false"));
1099 static bool convert(
const void *from,
int fromTypeId,
void *to,
int toTypeId)
1101 Q_ASSERT(fromTypeId != toTypeId);
1103#ifdef QT_BOOTSTRAPPED
1108 bool onlyCheck = (from ==
nullptr && to ==
nullptr);
1111 Q_ASSERT(onlyCheck || (
bool(from) &&
bool(to)));
1114 using SChar =
signed char;
1115 using UChar =
unsigned char;
1116 using Short =
short;
1117 using UShort =
unsigned short;
1119 using UInt =
unsigned int;
1121 using LongLong = qlonglong;
1122 using ULong =
unsigned long;
1123 using ULongLong = qulonglong;
1125 using Float =
float;
1126 using Double =
double;
1128 using Nullptr =
std::nullptr_t;
1129 using Char16 =
char16_t;
1130 using Char32 =
char32_t;
1132#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From)
1134#define QMETATYPE_CONVERTER_ASSIGN_NUMBER(To, From)
1136#define CONVERT_CBOR_AND_JSON(To)
1138 if constexpr(std::is_same_v<To, Bool>) {
1139 if (!source.isBool())
1141 result = source.toBool();
1143 if (!source.isInteger() && !source.isDouble())
1145 if constexpr(std::is_integral_v<To>)
1146 result = source.toInteger();
1148 result = To(source.toDouble());
1153 if constexpr(std::is_same_v<To, Bool>) {
1154 if (!source.isBool())
1156 result = source.toBool();
1158 if (!source.isDouble())
1160 if constexpr(std::is_integral_v<To>)
1161 result = source.toInteger();
1163 result = To(source.toDouble());
1168#define INTEGRAL_CONVERTER(To)
1181 QMETATYPE_CONVERTER(To, Float16, return qIntegerConversionFromFPHelper(source, &result););
1187 if constexpr(std::is_same_v<To, bool>)
1188 result = (ok = true, convertToBool(source));
1189 else if constexpr(std::is_signed_v<To>)
1190 result = To(source.toLongLong(&ok));
1192 result = To(source.toULongLong(&ok));
1197 if constexpr(std::is_same_v<To, bool>)
1198 result = (ok = true, convertToBool(source));
1199 else if constexpr(std::is_signed_v<To>)
1200 result = To(source.toLongLong(&ok));
1202 result = To(source.toULongLong(&ok));
1207#define FLOAT_CONVERTER(To)
1225 result = To(source.toDouble(&ok));
1230 result = To(source.toDouble(&ok));
1235 switch (makePair(toTypeId, fromTypeId)) {
1237QT_WARNING_DISABLE_CLANG(
"-Wtautological-compare")
1257 if (source.isUrl()) {
1258 result = source.toUrl();
1263#if QT_CONFIG(itemmodel)
1264 QMETATYPE_CONVERTER_ASSIGN(QModelIndex, QPersistentModelIndex);
1265 QMETATYPE_CONVERTER_ASSIGN(QPersistentModelIndex, QModelIndex);
1269#define QMETATYPE_CONVERTER_ASSIGN_QCHAR(From)
1302 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1306 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1310 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1314 result = QString::fromLatin1(&source, 1);
1319 result = QString::fromLatin1(&s, 1);
1324 result = QString::fromLatin1(&s, 1);
1328 result = QChar(source);
1332 result = QStringView(QChar::fromUcs4(source)).toString();
1335#if QT_CONFIG(datestring)
1336 QMETATYPE_CONVERTER(QString, QDate, result = source.toString(Qt::ISODate);
return true;);
1337 QMETATYPE_CONVERTER(QString, QTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1338 QMETATYPE_CONVERTER(QString, QDateTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1342 return (source.size() == 1) ? (result = source.at(0),
true) :
false;
1346 if (source.isString() || source.isNull()) {
1347 result = source.toString();
1352 QMETATYPE_CONVERTER(QString, Nullptr, Q_UNUSED(source); result = QString();
return true;);
1357 result = source ?
"true" :
"false";
1372 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1376 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1380 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1399 QMETATYPE_CONVERTER(QStringList, QString, result = QStringList() << source;
return true;);
1402 result.reserve(source.size());
1403 for (
const auto &v: source)
1404 result.append(v.toByteArray());
1408 result.reserve(source.size());
1409 for (
const auto &v: source)
1410 result.append(QVariant(v));
1415 result.reserve(source.size());
1416 for (
const auto &v: source)
1417 result.append(v.toString());
1421 result.reserve(source.size());
1422 for (
const auto &v: source)
1423 result.append(QVariant(v));
1428 result.reserve(source.size());
1429 for (
auto it = source.begin(); it != source.end(); ++it)
1430 result.insert(it.key(), it.value());
1434 for (
auto it = source.begin(); it != source.end(); ++it)
1435 result.insert(it.key(), it.value());
1440 if (source.isContainer() || source.isTag())
1442 result = source.toVariant().toString();
1447 if (source.isByteArray()) {
1448 result = source.toByteArray();
1455 if (!source.isUuid())
1457 result = source.toUuid();
1462 if (!source.isArray())
1464 result = source.toArray().toVariantList();
1467 QMETATYPE_CONVERTER(QCborValue, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1469 if (!source.isMap())
1471 result = source.toMap().toVariantMap();
1474 QMETATYPE_CONVERTER(QCborValue, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1476 if (!source.isMap())
1478 result = source.toMap().toVariantHash();
1481#if QT_CONFIG(regularexpression)
1482 QMETATYPE_CONVERTER(QCborValue, QRegularExpression, result = QCborValue(source);
return true;);
1483 QMETATYPE_CONVERTER(QRegularExpression, QCborValue,
1484 if (!source.isRegularExpression())
1486 result = source.toRegularExpression();
1493 result = QCborValue(QCborValue::Null);
1498 return source.isNull();
1516 result = QCborArray::fromStringList(source);
1519#if QT_CONFIG(datestring)
1520 QMETATYPE_CONVERTER(QCborValue, QDate,
1521 result = QCborValue(source.startOfDay());
1527 result = QCborValue::fromJsonValue(source);
1531 result = QCborMap::fromJsonObject(source);
1535 result = QCborArray::fromJsonArray(source);
1539 QJsonDocument doc = source;
1541 result = QCborArray::fromJsonArray(doc.array());
1543 result = QCborMap::fromJsonObject(doc.object());
1549#if QT_CONFIG(datestring)
1550 QMETATYPE_CONVERTER_ASSIGN(QCborValue, QDateTime);
1551 QMETATYPE_CONVERTER(QDateTime, QCborValue,
1552 if (source.isDateTime()) {
1553 result = source.toDateTime();
1562 if (source.isSimpleType()) {
1563 result = source.toSimpleType();
1571 QMETATYPE_CONVERTER(QCborArray, QStringList, result = QCborArray::fromStringList(source);
return true;);
1572 QMETATYPE_CONVERTER(QCborMap, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1574 QMETATYPE_CONVERTER(QCborMap, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1575 QMETATYPE_CONVERTER(QVariantHash, QCborMap, result = source.toVariantHash();
return true;);
1578 if (!source.isArray())
1580 result = source.toArray();
1584 if (!source.isArray())
1586 result = QCborArray::fromJsonArray(source.array());
1590 if (!source.isArray())
1592 result = QCborArray::fromJsonArray(source.toArray());
1596 result = QCborArray::fromJsonArray(source);
1600 if (!source.isMap())
1602 result = source.toMap();
1606 if (source.isArray())
1608 result = QCborMap::fromJsonObject(source.object());
1612 if (!source.isObject())
1614 result = QCborMap::fromJsonObject(source.toObject());
1618 result = QCborMap::fromJsonObject(source);
1624 if (!source.isArray())
1626 result = source.toArray().toVariantList();
1631 if (!source.isObject())
1633 result = source.toObject().toVariantMap();
1636 QMETATYPE_CONVERTER(QVariantMap, QJsonObject, result = source.toVariantMap();
return true;);
1638 if (!source.isObject())
1640 result = source.toObject().toVariantHash();
1643 QMETATYPE_CONVERTER(QVariantHash, QJsonObject, result = source.toVariantHash();
return true;);
1646 QMETATYPE_CONVERTER(QJsonArray, QStringList, result = QJsonArray::fromStringList(source);
return true;);
1649 if (!source.isArray())
1651 result = source.toArray();
1655 if (!source.isArray())
1657 result = source.array();
1661 if (!source.isArray())
1663 result = source.toArray().toJsonArray();
1667 QMETATYPE_CONVERTER(QJsonObject, QVariantMap, result = QJsonObject::fromVariantMap(source);
return true;);
1668 QMETATYPE_CONVERTER(QJsonObject, QVariantHash, result = QJsonObject::fromVariantHash(source);
return true;);
1670 if (!source.isObject())
1672 result = source.toObject();
1676 if (source.isArray())
1678 result = source.object();
1682 if (!source.isMap())
1684 result = source.toMap().toJsonObject();
1687 QMETATYPE_CONVERTER(QJsonObject, QCborMap, result = source.toJsonObject();
return true; );
1691 result = QJsonValue(QJsonValue::Null);
1696 return source.isNull();
1699 result = QJsonValue(source);
1717 result = QJsonValue(QJsonArray::fromStringList(source));
1721 result = QJsonValue(QJsonArray::fromVariantList(source));
1725 result = QJsonValue(QJsonObject::fromVariantMap(source));
1729 result = QJsonValue(QJsonObject::fromVariantHash(source));
1741 QJsonDocument doc = source;
1742 result = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1746 result = source.toJsonValue();
1750 result = source.toJsonObject();
1754 result = source.toJsonArray();
1761#if QT_CONFIG(datestring)
1762 QMETATYPE_CONVERTER(QDate, QString,
1763 result = QDate::fromString(source, Qt::ISODate);
1764 return result.isValid();
1766 QMETATYPE_CONVERTER(QTime, QString,
1767 result = QTime::fromString(source, Qt::ISODate);
1768 return result.isValid();
1770 QMETATYPE_CONVERTER(QDateTime, QString,
1771 result = QDateTime::fromString(source, Qt::ISODate);
1772 return result.isValid();
1784Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeGuiHelper = {};
1785Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeWidgetsHelper = {};
1787#ifndef QT_BOOTSTRAPPED
1790 int type = qMax(fromTypeId, toTypeId);
1791 if (type <= QMetaType::LastCoreType)
1792 return QCoreVariantHelper::convert(from, fromTypeId, to, toTypeId);
1793 if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType)
1794 return qMetaTypeGuiHelper.convert(from, fromTypeId, to, toTypeId);
1795 else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType)
1796 return qMetaTypeWidgetsHelper.convert(from, fromTypeId, to, toTypeId);
1800template<
typename T,
typename Key>
1806 const QWriteLocker locker(&lock);
1812 const QReadLocker locker(&lock);
1813 return map.contains(k);
1818 const QWriteLocker locker(&lock);
1819 auto r = map.tryEmplace(k, f);
1825 const QReadLocker locker(&lock);
1826 auto it = map.find(k);
1827 return it == map.end() ?
nullptr :
std::addressof(*it);
1832 const Key k(from, to);
1833 const QWriteLocker locker(&lock);
1837 mutable QReadWriteLock lock;
1841using QMetaTypeConverterRegistry
1842 = QMetaTypeFunctionRegistry<QMetaType::ConverterFunction, std::pair<
int,
int>>;
1844Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
1846using QMetaTypeMutableViewRegistry
1847 = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, std::pair<
int,
int>>;
1848Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
1851
1852
1853
1854
1855
1856
1857
1860
1861
1862
1863
1864
1865
1866
1867
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1895
1896
1897
1898
1900
1901bool QMetaType::registerConverterFunction(
const ConverterFunction &f, QMetaType from, QMetaType to)
1903 if (!customTypesConversionRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1904 qWarning(
"Type conversion already registered from type %s to type %s",
1905 from.name(), to.name());
1912
1913
1914
1915
1916
1917
1918
1921
1922
1923
1924
1925
1926
1929
1930
1931
1933
1934bool QMetaType::registerMutableViewFunction(
const MutableViewFunction &f, QMetaType from, QMetaType to)
1936 if (!customTypesMutableViewRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1937 qWarning(
"Mutable view on type already registered from type %s to type %s",
1938 from.name(), to.name());
1946
1947void QMetaType::unregisterMutableViewFunction(QMetaType from, QMetaType to)
1949 if (customTypesMutableViewRegistry.isDestroyed())
1951 customTypesMutableViewRegistry()->remove(from.id(), to.id());
1955
1956
1958
1959void QMetaType::unregisterConverterFunction(QMetaType from, QMetaType to)
1961 if (customTypesConversionRegistry.isDestroyed())
1963 customTypesConversionRegistry()->remove(from.id(), to.id());
1967#ifndef QT_NO_DEBUG_STREAM
1970
1971
1973
1974QDebug operator<<(QDebug d, QMetaType m)
1976 const QDebugStateSaver saver(d);
1977 return d.nospace() <<
"QMetaType(" << m.name() <<
")";
1981
1982
1984
1985bool QMetaType::debugStream(QDebug& dbg,
const void *rhs)
1987 if (d_ptr && d_ptr->flags & QMetaType::IsPointer) {
1988 dbg << *
reinterpret_cast<
const void *
const *>(rhs);
1991 if (d_ptr && d_ptr->debugStream) {
1992 d_ptr->debugStream(d_ptr, dbg, rhs);
1999
2000
2001
2002
2005
2006
2007
2008
2009
2010
2013
2014
2015
2016
2017
2018
2019
2022
2023
2024
2026
2027bool QMetaType::hasRegisteredDebugStreamOperator()
const
2029 return d_ptr && d_ptr->debugStream !=
nullptr;
2033#ifndef QT_NO_QOBJECT
2035
2037
2038static QMetaEnum metaEnumFromType(QMetaType t)
2040 if (t.flags() & QMetaType::IsEnumeration) {
2041 if (
const QMetaObject *metaObject = t.metaObject()) {
2042 QByteArrayView qflagsNamePrefix =
"QFlags<";
2044 if (enumName.endsWith(
'>') && enumName.startsWith(qflagsNamePrefix)) {
2047 enumName = enumName.sliced(qflagsNamePrefix.size());
2049 if (qsizetype lastColon = enumName.lastIndexOf(
':'); lastColon != -1)
2050 enumName = enumName.sliced(lastColon + 1);
2051 return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
2058#ifndef QT_BOOTSTRAPPED
2059static bool convertFromEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2062 if (fromType.flags() & QMetaType::IsUnsignedEnumeration) {
2064 switch (fromType.sizeOf()) {
2066 ull = *
static_cast<
const unsigned char *>(from);
2069 ull = *
static_cast<
const unsigned short *>(from);
2072 ull = *
static_cast<
const unsigned int *>(from);
2075 ull = *
static_cast<
const quint64 *>(from);
2080 if (toType.id() == QMetaType::ULongLong) {
2081 *
static_cast<qulonglong *>(to) = ull;
2084 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2085 return QMetaType::convert(QMetaType::fromType<qulonglong>(), &ull, toType, to);
2086 ll = qlonglong(ull);
2088 switch (fromType.sizeOf()) {
2090 ll = *
static_cast<
const signed char *>(from);
2093 ll = *
static_cast<
const short *>(from);
2096 ll = *
static_cast<
const int *>(from);
2099 ll = *
static_cast<
const qint64 *>(from);
2104 if (toType.id() == QMetaType::LongLong) {
2105 *
static_cast<qlonglong *>(to) = ll;
2108 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2109 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2111#ifndef QT_NO_QOBJECT
2112 QMetaEnum en = metaEnumFromType(fromType);
2116 if (toType.id() == QMetaType::QString)
2117 *
static_cast<QString *>(to) = QString::fromUtf8(keys);
2121 const char *key = en.valueToKey(ll);
2122 if (toType.id() == QMetaType::QString)
2123 *
static_cast<QString *>(to) = QString::fromUtf8(key);
2130 if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray)
2131 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2135static bool convertToEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2137 int fromTypeId = fromType.id();
2138 qlonglong value = -1;
2140#ifndef QT_NO_QOBJECT
2141 if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) {
2142 QMetaEnum en = metaEnumFromType(toType);
2144 QByteArray keys = (fromTypeId == QMetaType::QString)
2145 ?
static_cast<
const QString *>(from)->toUtf8()
2146 : *
static_cast<
const QByteArray *>(from);
2147 if (
auto v = en.keysToValue64(keys.constData())) {
2155 if (fromTypeId == QMetaType::LongLong) {
2156 value = *
static_cast<
const qlonglong *>(from);
2159 ok = QMetaType::convert(fromType, from, QMetaType::fromType<qlonglong>(), &value);
2166 switch (toType.sizeOf()) {
2168 *
static_cast<
signed char *>(to) = value;
2171 *
static_cast<qint16 *>(to) = value;
2174 *
static_cast<qint32 *>(to) = value;
2177 *
static_cast<qint64 *>(to) = value;
2180 Q_UNREACHABLE_RETURN(
false);
2184template<
typename Iterable>
2185bool convertIterableToVariantList(QMetaType fromType,
const void *from,
void *to)
2188 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &list))
2193 if (list.metaContainer().hasSize())
2194 l.reserve(list.size());
2195 auto end = list.end();
2196 for (
auto it = list.begin(); it != end; ++it)
2201template<
typename Iterable>
2202bool convertIterableToVariantMap(QMetaType fromType,
const void *from,
void *to)
2205 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
2208 QVariantMap &h = *
static_cast<QVariantMap *>(to);
2210 auto end = map.end();
2211 for (
auto it = map.begin(); it != end; ++it)
2212 h.insert(it.key().toString(), it.value());
2216template<
typename Iterable>
2217bool convertIterableToVariantHash(QMetaType fromType,
const void *from,
void *to)
2220 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
2223 QVariantHash &h = *
static_cast<QVariantHash *>(to);
2225 h.reserve(map.size());
2226 auto end = map.end();
2227 for (
auto it = map.begin(); it != end; ++it)
2228 h.insert(it.key().toString(), it.value());
2232static bool convertIterableToVariantPair(QMetaType fromType,
const void *from,
void *to)
2235 const auto f = customTypesConversionRegistry()->function({fromType.id(), targetId});
2243 QVariant v1(pi._metaType_first);
2245 if (pi._metaType_first == QMetaType::fromType<QVariant>())
2248 dataPtr = v1.data();
2251 QVariant v2(pi._metaType_second);
2252 if (pi._metaType_second == QMetaType::fromType<QVariant>())
2255 dataPtr = v2.data();
2258 *
static_cast<QVariantPair *>(to) = QVariantPair(v1, v2);
2262template<
typename Iterable>
2263static bool convertToSequentialIterable(QMetaType fromType,
const void *from,
void *to)
2266 const int fromTypeId = fromType.id();
2268 Iterable &i = *
static_cast<Iterable *>(to);
2269 switch (fromTypeId) {
2270 case QMetaType::QVariantList:
2271 i = Iterable(
reinterpret_cast<
const QVariantList *>(from));
2273 case QMetaType::QStringList:
2274 i = Iterable(
reinterpret_cast<
const QStringList *>(from));
2276 case QMetaType::QByteArrayList:
2277 i = Iterable(
reinterpret_cast<
const QByteArrayList *>(from));
2279 case QMetaType::QString:
2280 i = Iterable(
reinterpret_cast<
const QString *>(from));
2282 case QMetaType::QByteArray:
2283 i = Iterable(
reinterpret_cast<
const QByteArray *>(from));
2286 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2287 if (QMetaType::convert(
2288 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2298static bool canConvertToSequentialIterable(QMetaType fromType)
2300 switch (fromType.id()) {
2301 case QMetaType::QVariantList:
2302 case QMetaType::QStringList:
2303 case QMetaType::QByteArrayList:
2304 case QMetaType::QString:
2305 case QMetaType::QByteArray:
2308 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2312static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType)
2314 switch (fromType.id()) {
2315 case QMetaType::QVariantList:
2316 case QMetaType::QStringList:
2317 case QMetaType::QByteArrayList:
2318 case QMetaType::QString:
2319 case QMetaType::QByteArray:
2322 return QMetaType::canView(
2323 fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2327template<
typename Iterable>
2328static bool viewAsSequentialIterable(QMetaType fromType,
void *from,
void *to)
2331 const int fromTypeId = fromType.id();
2333 Iterable &i = *
static_cast<Iterable *>(to);
2334 switch (fromTypeId) {
2335 case QMetaType::QVariantList:
2338 case QMetaType::QStringList:
2339 i = Iterable(
reinterpret_cast<QStringList *>(from));
2341 case QMetaType::QByteArrayList:
2342 i = Iterable(
reinterpret_cast<QByteArrayList *>(from));
2344 case QMetaType::QString:
2345 i = Iterable(
reinterpret_cast<QString *>(from));
2347 case QMetaType::QByteArray:
2348 i = Iterable(
reinterpret_cast<
QByteArray *>(from));
2351 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2352 if (QMetaType::view(
2353 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2363template<
typename Iterable>
2364static bool convertToAssociativeIterable(QMetaType fromType,
const void *from,
void *to)
2368 Iterable &i = *
static_cast<Iterable *>(to);
2369 if (fromType.id() == QMetaType::QVariantMap) {
2370 i = Iterable(
reinterpret_cast<
const QVariantMap *>(from));
2373 if (fromType.id() == QMetaType::QVariantHash) {
2374 i = Iterable(
reinterpret_cast<
const QVariantHash *>(from));
2378 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2379 if (QMetaType::convert(
2380 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2388static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
2390 if ((fromType.flags() & QMetaType::IsPointer) != (toType.flags() & QMetaType::IsPointer))
2393 const QMetaObject *f = fromType.metaObject();
2394 const QMetaObject *t = toType.metaObject();
2396 return f->inherits(t) || (t->inherits(f));
2401static bool canConvertToAssociativeIterable(QMetaType fromType)
2403 switch (fromType.id()) {
2404 case QMetaType::QVariantMap:
2405 case QMetaType::QVariantHash:
2408 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2412static bool canImplicitlyViewAsAssociativeIterable(QMetaType fromType)
2414 switch (fromType.id()) {
2415 case QMetaType::QVariantMap:
2416 case QMetaType::QVariantHash:
2419 return QMetaType::canView(
2420 fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2424template<
typename Iterable>
2425static bool viewAsAssociativeIterable(QMetaType fromType,
void *from,
void *to)
2428 int fromTypeId = fromType.id();
2430 Iterable &i = *
static_cast<Iterable *>(to);
2431 if (fromTypeId == QMetaType::QVariantMap) {
2432 i = Iterable(
reinterpret_cast<QVariantMap *>(from));
2435 if (fromTypeId == QMetaType::QVariantHash) {
2436 i = Iterable(
reinterpret_cast<QVariantHash *>(from));
2440 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2441 if (QMetaType::view(
2442 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2450static bool convertMetaObject(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2453 if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
2454 QObject *fromObject = *
static_cast<QObject *
const *>(from);
2456 if (fromObject && fromObject->metaObject()->inherits(toType.metaObject())) {
2457 *
static_cast<QObject **>(to) = toType.metaObject()->cast(fromObject);
2459 }
else if (!fromObject && fromType.metaObject()) {
2461 *
static_cast<
void **>(to) =
nullptr;
2462 return fromType.metaObject()->inherits(toType.metaObject());
2464 }
else if ((fromType.flags() & QMetaType::IsPointer) == (toType.flags() & QMetaType::IsPointer)) {
2466 const QMetaObject *f = fromType.metaObject();
2467 const QMetaObject *t = toType.metaObject();
2468 if (f && t && f->inherits(t)) {
2469 toType.destruct(to);
2470 toType.construct(to, from);
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2490
2491
2492
2493
2494
2496
2497bool QMetaType::convert(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2499 if (!fromType.isValid() || !toType.isValid())
2502 if (fromType == toType) {
2504 fromType.destruct(to);
2505 fromType.construct(to, from);
2509 int fromTypeId = fromType.id();
2510 int toTypeId = toType.id();
2512 if (tryConvertBuiltinTypes(from, fromTypeId, to, toTypeId))
2514 const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId});
2516 return (*f)(from, to);
2518 if (fromType.flags() & QMetaType::IsEnumeration)
2519 return convertFromEnum(fromType, from, toType, to);
2520 if (toType.flags() & QMetaType::IsEnumeration)
2521 return convertToEnum(fromType, from, toType, to);
2522 if (toTypeId == Nullptr) {
2523 *
static_cast<std::nullptr_t *>(to) =
nullptr;
2524 if (fromType.flags() & QMetaType::IsPointer) {
2525 if (*
static_cast<
const void *
const *>(from) ==
nullptr)
2530 if (toTypeId == QVariantPair && convertIterableToVariantPair(fromType, from, to))
2534 if (toTypeId == QVariantList
2535 && convertIterableToVariantList<QMetaSequence::Iterable>(fromType, from, to)) {
2539 if (toTypeId == QVariantMap
2540 && convertIterableToVariantMap<QMetaAssociation::Iterable>(fromType, from, to)) {
2544 if (toTypeId == QVariantHash
2545 && convertIterableToVariantHash<QMetaAssociation::Iterable>(fromType, from, to)) {
2549 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2550 return convertToSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
2552 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2553 return convertToAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
2555#if QT_DEPRECATED_SINCE(6
, 15
)
2557 QT_WARNING_DISABLE_DEPRECATED
2559 if (toTypeId == QVariantList
2560 && convertIterableToVariantList<QSequentialIterable>(fromType, from, to)) {
2564 if (toTypeId == QVariantMap
2565 && convertIterableToVariantMap<QAssociativeIterable>(fromType, from, to)) {
2569 if (toTypeId == QVariantHash
2570 && convertIterableToVariantHash<QAssociativeIterable>(fromType, from, to)) {
2574 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2575 return convertToSequentialIterable<QSequentialIterable>(fromType, from, to);
2577 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2578 return convertToAssociativeIterable<QAssociativeIterable>(fromType, from, to);
2583 return convertMetaObject(fromType, from, toType, to);
2587
2588
2590
2591bool QMetaType::view(QMetaType fromType,
void *from, QMetaType toType,
void *to)
2593 if (!fromType.isValid() || !toType.isValid())
2596 int fromTypeId = fromType.id();
2597 int toTypeId = toType.id();
2599 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2601 return (*f)(from, to);
2603 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2604 return viewAsSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
2606 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2607 return viewAsAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
2609#if QT_DEPRECATED_SINCE(6
, 15
)
2611 QT_WARNING_DISABLE_DEPRECATED
2613 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2614 return viewAsSequentialIterable<QSequentialIterable>(fromType, from, to);
2616 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2617 return viewAsAssociativeIterable<QAssociativeIterable>(fromType, from, to);
2622 return convertMetaObject(fromType, from, toType, to);
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2641
2642bool QMetaType::canView(QMetaType fromType, QMetaType toType)
2644 int fromTypeId = fromType.id();
2645 int toTypeId = toType.id();
2647 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2650 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2654 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2655 return canImplicitlyViewAsSequentialIterable(fromType);
2657 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2658 return canImplicitlyViewAsAssociativeIterable(fromType);
2660#if QT_DEPRECATED_SINCE(6
, 15
)
2662 QT_WARNING_DISABLE_DEPRECATED
2664 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2665 return canImplicitlyViewAsSequentialIterable(fromType);
2667 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2668 return canImplicitlyViewAsAssociativeIterable(fromType);
2673 if (canConvertMetaObject(fromType, toType))
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
2759
2760
2761
2763
2764bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
2766 int fromTypeId = fromType.id();
2767 int toTypeId = toType.id();
2769 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2772 if (fromTypeId == toTypeId)
2775 if (tryConvertBuiltinTypes(
nullptr, fromTypeId,
nullptr, toTypeId))
2778 const ConverterFunction *
const f =
2779 customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId));
2783 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2784 return canConvertToSequentialIterable(fromType);
2786 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2787 return canConvertToAssociativeIterable(fromType);
2789 if (toTypeId == QVariantList
2790 && canConvert(fromType, QMetaType::fromType<QMetaSequence::Iterable>())) {
2794 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2795 && canConvert(fromType, QMetaType::fromType<QMetaAssociation::Iterable>())) {
2799#if QT_DEPRECATED_SINCE(6
, 15
)
2801 QT_WARNING_DISABLE_DEPRECATED
2803 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2804 return canConvertToSequentialIterable(fromType);
2806 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2807 return canConvertToAssociativeIterable(fromType);
2809 if (toTypeId == QVariantList
2810 && canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
2814 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2815 && canConvert(fromType, QMetaType::fromType<QAssociativeIterable>())) {
2822 if (toTypeId == QVariantPair && hasRegisteredConverterFunction(
2823 fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
2826 if (fromType.flags() & IsEnumeration) {
2827 if (toTypeId == QString || toTypeId == QByteArray)
2829 return canConvert(QMetaType(LongLong), toType);
2831 if (toType.flags() & IsEnumeration) {
2832 if (fromTypeId == QString || fromTypeId == QByteArray)
2834 return canConvert(fromType, QMetaType(LongLong));
2836 if (toTypeId == Nullptr && fromType.flags() & IsPointer)
2838 if (canConvertMetaObject(fromType, toType))
2845
2846
2847
2848
2849
2850
2851
2854
2855
2856
2857
2858
2861
2862
2864
2865bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType)
2867 return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
2871
2873
2874bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
2876 const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2877 return QMetaType::hasRegisteredConverterFunction(m, to);
2881
2883
2884bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
2886 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2887 return QMetaType::hasRegisteredConverterFunction(m, to);
2891
2893
2894bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
2896 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2897 return QMetaType::hasRegisteredConverterFunction(m, to);
2901
2902
2903
2904
2905
2908
2909
2911
2912bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType)
2914 return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
2918
2920
2921bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
2923 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2924 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2928
2930
2931bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
2933 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2934 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2939
2940
2941
2942
2943
2944
2945
2946
2947
2950
2951
2952
2953
2954
2955
2956
2957
2958
2962
2963static inline int qMetaTypeStaticType(QByteArrayView name)
2965 for (
int i = 0; i < types.count(); ++i) {
2966 if (types.viewAt(i) == name)
2967 return types.typeIdMap[i];
2969 return QMetaType::UnknownType;
2972#ifndef QT_BOOTSTRAPPED
2974
2975
2976
2977
2979
2980void QMetaType::registerNormalizedTypedef(
const NS(QByteArray) & normalizedTypeName,
2983 if (!metaType.isValid())
2985 if (
auto reg = customTypeRegistry()) {
2986 QWriteLocker lock(®->lock);
2987 auto &al = reg->aliases[normalizedTypeName];
2991 al = QMetaTypeCustomRegistry::Alias(
2992 metaType.d_ptr, QMetaTypeCustomRegistry::HasTypedefs::Yes);
2993 reg->aliases[metaType.name()].setTag(QMetaTypeCustomRegistry::HasTypedefs::Yes);
3000 Q_ASSERT(typeId < QMetaType::User);
3001 if (typeId <= QMetaType::LastCoreType)
3002 return QCoreVariantHelper::interfaceForType(typeId);
3003 if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType)
3004 return qMetaTypeGuiHelper.interfaceForType(typeId);
3005 if (typeId >= QMetaType::FirstWidgetsType && typeId <= QMetaType::LastWidgetsType)
3006 return qMetaTypeWidgetsHelper.interfaceForType(typeId);
3013 if (typeId >= QMetaType::User) {
3014#ifndef QT_BOOTSTRAPPED
3015 if (customTypeRegistry.exists())
3016 iface = customTypeRegistry->getCustomType(typeId);
3019 iface = interfaceForStaticType(typeId);
3025
3026
3027
3029
3030bool QMetaType::isRegistered(
int type)
3032 return interfaceForTypeNoWarning(type) !=
nullptr;
3037 Q_PRE(!name.isEmpty());
3038 int type = qMetaTypeStaticType(name);
3039 if (type != QMetaType::UnknownType) {
3040 return interfaceForStaticType(type);
3041#ifndef QT_BOOTSTRAPPED
3042 }
else if (customTypeRegistry.exists()) {
3043 QReadLocker locker(&customTypeRegistry->lock);
3044 auto it = customTypeRegistry->aliases.constFind(name);
3045 if (it != customTypeRegistry->aliases.constEnd())
3046 return it.value().data();
3053
3054
3055
3056
3057
3058
3059
3060
3063
3064
3065
3066
3067
3068
3070
3071int qMetaTypeTypeInternal(QByteArrayView name)
3074 if (!name.isEmpty())
3075 iface = findMetaTypeByName(name);
3076 return iface ? iface->typeId.loadRelaxed() : QMetaType::UnknownType;
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3092#ifndef QT_NO_DATASTREAM
3094
3095
3096
3097
3098
3099
3100
3101
3103
3104bool QMetaType::save(QDataStream &stream,
const void *data)
const
3106 if (!data || !isValid())
3110 if (id() == QMetaType::Long) {
3111 stream << qlonglong(*(
long *)data);
3113 }
else if (id() == QMetaType::ULong) {
3114 stream << qlonglong(*(
unsigned long *)data);
3118 if (!d_ptr->dataStreamOut)
3121 d_ptr->dataStreamOut(d_ptr, stream, data);
3126
3127
3128
3129
3132
3133
3134
3135
3136
3137
3138
3139
3141
3142bool QMetaType::load(QDataStream &stream,
void *data)
const
3144 if (!data || !isValid())
3148 if (id() == QMetaType::Long) {
3151 *(
long *)data =
long(ll);
3153 }
else if (id() == QMetaType::ULong) {
3156 *(
unsigned long *)data = (
unsigned long)(ull);
3159 if (!d_ptr->dataStreamIn)
3162 d_ptr->dataStreamIn(d_ptr, stream, data);
3167
3168
3169
3171
3172bool QMetaType::hasRegisteredDataStreamOperators()
const
3175 if (type == QMetaType::Long || type == QMetaType::ULong)
3177 return d_ptr && d_ptr->dataStreamIn !=
nullptr && d_ptr->dataStreamOut !=
nullptr;
3181
3182
3183
3184
3185
3186
3188
3189QMetaType QMetaType::underlyingType()
const
3191 if (!d_ptr || !(flags() & IsEnumeration))
3194
3195
3196
3197
3198
3199
3200 if (flags() & IsUnsignedEnumeration) {
3203 return QMetaType::fromType<quint8>();
3205 return QMetaType::fromType<quint16>();
3207 return QMetaType::fromType<quint32>();
3209 return QMetaType::fromType<quint64>();
3216 return QMetaType::fromType<qint8>();
3218 return QMetaType::fromType<qint16>();
3220 return QMetaType::fromType<qint32>();
3222 return QMetaType::fromType<qint64>();
3232
3233
3234
3235
3239
3241
3242QMetaType QMetaType::fromName(QByteArrayView typeName)
3244 if (typeName.isEmpty())
3247 const QtPrivate::QMetaTypeInterface *iface = findMetaTypeByName(typeName);
3249 return QMetaType(iface);
3251#if !defined(QT_NO_QOBJECT)
3252 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName.constData());
3253 if (normalizedTypeName != typeName)
3254 iface = findMetaTypeByName(normalizedTypeName);
3257 return QMetaType(iface);
3261
3262
3263
3264
3265
3266
3267
3268
3271
3272
3273
3274
3275
3276
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3336
3337
3338
3339
3340
3341
3342
3343
3346
3347
3348
3349
3350
3351
3352
3353
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
3385
3386
3387
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
3416
3417
3418
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3462 if (!iface && typeId != QMetaType::UnknownType)
3463 qWarning(
"Trying to construct an instance of an invalid type, type id: %i", typeId);
3469
3470
3471
3472
3473
3476
3477
3478
3480
3481QMetaType::QMetaType(
int typeId) : QMetaType(interfaceForType(typeId)) {}
3485
3486
3487
3488
3490namespace QtPrivate {
3491#if !defined(QT_BOOTSTRAPPED)
3492void QMetaTypeCopyTraits::warnAboutDeprecatedCopy(
const char *name)
3494 qCWarning(lcMetatypeDeprecated,
"QMetaType: copy construction of type '%s' is deprecated", name);
3498#if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
3501#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name)
3502 template class QMetaTypeForType<Name>;
3503 template struct QMetaTypeInterfaceWrapper<Name>;
3510#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)