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#ifndef QT_BOOTSTRAPPED
603
604
605
606int QMetaType::registerHelper(
const QtPrivate::QMetaTypeInterface *iface)
609 auto reg = customTypeRegistry();
611 return reg->registerCustomType(iface);
618
619
620
621
622
623
624
625
626
627
628
629
632
633
634
635
636
637
638
639
640
641
642
643
644
647
648
649
650
651
652
653
654
655
656
657
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
683
684
685
686
687
688
689
690
691
692void *QMetaType::create(
const void *copy)
const
694 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
697 std::unique_ptr<
void, QMetaTypeDeleter> where(
nullptr, {d_ptr});
698 if (d_ptr->alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
699 where.reset(operator
new(d_ptr->size, std::align_val_t(d_ptr->alignment), std::nothrow_t{}));
701 where.reset(operator
new(d_ptr->size, std::nothrow_t{}));
703 QtMetaTypePrivate::construct(d_ptr, where.get(), copy);
704 return where.release();
708
709
710
711
712
713
714
715
716void QMetaType::destroy(
void *data)
const
718 if (data && isDestructible()) {
719 QtMetaTypePrivate::destruct(d_ptr, data);
720 QMetaTypeDeleter{d_ptr}(data);
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750void *QMetaType::construct(
void *where,
const void *copy)
const
754 if (copy ? !isCopyConstructible() : !isDefaultConstructible())
757 QtMetaTypePrivate::construct(d_ptr, where, copy);
762
763
764
765
766
767
768
769
770
771
772void QMetaType::destruct(
void *data)
const
774 if (data && isDestructible())
775 QtMetaTypePrivate::destruct(d_ptr, data);
778static QPartialOrdering threeWayCompare(
const void *ptr1,
const void *ptr2)
780 std::less<
const void *> less;
781 if (less(ptr1, ptr2))
782 return QPartialOrdering::Less;
783 if (less(ptr2, ptr1))
784 return QPartialOrdering::Greater;
785 return QPartialOrdering::Equivalent;
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814QPartialOrdering QMetaType::compare(
const void *lhs,
const void *rhs)
const
817 return QPartialOrdering::Unordered;
818 if (d_ptr && d_ptr->flags & QMetaType::IsPointer)
819 return threeWayCompare(*
reinterpret_cast<
const void *
const *>(lhs),
820 *
reinterpret_cast<
const void *
const *>(rhs));
821 if (d_ptr && d_ptr->lessThan) {
822 if (d_ptr->equals && d_ptr->equals(d_ptr, lhs, rhs))
823 return QPartialOrdering::Equivalent;
824 if (d_ptr->lessThan(d_ptr, lhs, rhs))
825 return QPartialOrdering::Less;
826 if (d_ptr->lessThan(d_ptr, rhs, lhs))
827 return QPartialOrdering::Greater;
829 return QPartialOrdering::Equivalent;
831 return QPartialOrdering::Unordered;
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850bool QMetaType::equals(
const void *lhs,
const void *rhs)
const
855 if (d_ptr->flags & QMetaType::IsPointer)
856 return *
reinterpret_cast<
const void *
const *>(lhs) == *
reinterpret_cast<
const void *
const *>(rhs);
859 return d_ptr->equals(d_ptr, lhs, rhs);
860 if (d_ptr->lessThan && !d_ptr->lessThan(d_ptr, lhs, rhs) && !d_ptr->lessThan(d_ptr, rhs, lhs))
867
868
869
870
871
872
873
874
875
878
879
880
881
882
883
884
885
886
889
890
891
892
893
894
895
896
899
900
901
902
903
904
905
906
908bool QMetaType::isDefaultConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
910 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDefaultConstructible(iface);
913bool QMetaType::isCopyConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
915 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isCopyConstructible(iface);
918bool QMetaType::isMoveConstructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
920 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isMoveConstructible(iface);
923bool QMetaType::isDestructible(
const QtPrivate::QMetaTypeInterface *iface)
noexcept
925 return !isInterfaceFor<
void>(iface) && QtMetaTypePrivate::isDestructible(iface);
929
930
931
932
933
934bool QMetaType::isEqualityComparable()
const
936 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->equals !=
nullptr || d_ptr->lessThan !=
nullptr);
940
941
942
943
944
945bool QMetaType::isOrdered()
const
947 return d_ptr && (d_ptr->flags & QMetaType::IsPointer || d_ptr->lessThan !=
nullptr);
950#ifndef QT_BOOTSTRAPPED
952
953
954void QMetaType::unregisterMetaType(QMetaType type)
956 const QtPrivate::QMetaTypeInterface *d_ptr = type.d_ptr;
960 const int typeId = d_ptr->typeId.loadRelaxed();
961 if (typeId < QMetaType::User)
966 if (
auto reg = customTypeRegistry()) {
967 Q_ASSERT(reg->getCustomType(typeId) == d_ptr);
968 reg->unregisterDynamicType(typeId);
971 const_cast<QtPrivate::QMetaTypeInterface *>(d_ptr)->typeId.storeRelease(0);
976
977
978
979
980
983
984
985
986
987
988
991
992
993
994
995
996
998static constexpr auto createStaticTypeToIdMap()
1000#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
1002#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
1004 constexpr auto staticTypeNames = qOffsetStringArray(
1009 constexpr int Count = staticTypeNames.count();
1010#undef QT_ADD_STATIC_METATYPE
1011#undef QT_ADD_STATIC_METATYPE_ALIASES_ITER
1013#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName)
1015#define QT_ADD_STATIC_METATYPE_ALIASES_ITER(MetaTypeName, MetaTypeId, AliasingName, RealNameStr)
1016 QMetaType::MetaTypeName,
1017 std::array<
int, Count> typeIds = {
1020 QMetaTypeId2<qreal>::MetaType,
1022#undef QT_ADD_STATIC_METATYPE
1023#undef QT_ADD_STATIC_METATYPE_ALIASES_ITER
1025 using Base = std::remove_cv_t<
decltype(staticTypeNames)>;
1026 using Array = std::remove_cv_t<
decltype(typeIds)>;
1028 constexpr Map(
const Base &base,
const Array &typeIdMap)
1029 : Base(base), typeIdMap(typeIdMap)
1031 std::array<
int, Count> typeIdMap;
1034 return Map(staticTypeNames, typeIds);
1036static constexpr auto types = createStaticTypeToIdMap();
1038template <
typename From,
typename To>
1043 static_assert(
std::numeric_limits<From>::is_iec559);
1045 static_assert(
std::is_integral_v<To>);
1046 static_assert(
sizeof(From) <=
sizeof(
double));
1047 const double fromD =
static_cast<
double>(from);
1049 if (qt_is_nan(fromD)) {
1055 convertDoubleTo(std::round(fromD), &result);
1063 template<
typename T,
typename LiteralWrapper =
1064 std::conditional_t<std::is_same_v<T, QString>, QLatin1StringView,
const char *>>
1065 static inline bool convertToBool(
const T &source)
1067 T str = source.toLower();
1068 return !(str.isEmpty() || str == LiteralWrapper(
"0") || str == LiteralWrapper(
"false"));
1084 static bool convert(
const void *from,
int fromTypeId,
void *to,
int toTypeId)
1086 Q_ASSERT(fromTypeId != toTypeId);
1088#ifdef QT_BOOTSTRAPPED
1093 bool onlyCheck = (from ==
nullptr && to ==
nullptr);
1096 Q_ASSERT(onlyCheck || (
bool(from) &&
bool(to)));
1099 using SChar =
signed char;
1100 using UChar =
unsigned char;
1101 using Short =
short;
1102 using UShort =
unsigned short;
1104 using UInt =
unsigned int;
1106 using LongLong = qlonglong;
1107 using ULong =
unsigned long;
1108 using ULongLong = qulonglong;
1110 using Float =
float;
1111 using Double =
double;
1113 using Nullptr =
std::nullptr_t;
1114 using Char16 =
char16_t;
1115 using Char32 =
char32_t;
1117#define QMETATYPE_CONVERTER_ASSIGN_DOUBLE(To, From)
1119#define QMETATYPE_CONVERTER_ASSIGN_NUMBER(To, From)
1121#define CONVERT_CBOR_AND_JSON(To)
1123 if constexpr(std::is_same_v<To, Bool>) {
1124 if (!source.isBool())
1126 result = source.toBool();
1128 if (!source.isInteger() && !source.isDouble())
1130 if constexpr(std::is_integral_v<To>)
1131 result = source.toInteger();
1133 result = To(source.toDouble());
1138 if constexpr(std::is_same_v<To, Bool>) {
1139 if (!source.isBool())
1141 result = source.toBool();
1143 if (!source.isDouble())
1145 if constexpr(std::is_integral_v<To>)
1146 result = source.toInteger();
1148 result = To(source.toDouble());
1153#define INTEGRAL_CONVERTER(To)
1166 QMETATYPE_CONVERTER(To, Float16, return qIntegerConversionFromFPHelper(source, &result););
1172 if constexpr(std::is_same_v<To, bool>)
1173 result = (ok = true, convertToBool(source));
1174 else if constexpr(std::is_signed_v<To>)
1175 result = To(source.toLongLong(&ok));
1177 result = To(source.toULongLong(&ok));
1182 if constexpr(std::is_same_v<To, bool>)
1183 result = (ok = true, convertToBool(source));
1184 else if constexpr(std::is_signed_v<To>)
1185 result = To(source.toLongLong(&ok));
1187 result = To(source.toULongLong(&ok));
1192#define FLOAT_CONVERTER(To)
1210 result = To(source.toDouble(&ok));
1215 result = To(source.toDouble(&ok));
1220 switch (makePair(toTypeId, fromTypeId)) {
1222QT_WARNING_DISABLE_CLANG(
"-Wtautological-compare")
1242 if (source.isUrl()) {
1243 result = source.toUrl();
1248#if QT_CONFIG(itemmodel)
1249 QMETATYPE_CONVERTER_ASSIGN(QModelIndex, QPersistentModelIndex);
1250 QMETATYPE_CONVERTER_ASSIGN(QPersistentModelIndex, QModelIndex);
1254#define QMETATYPE_CONVERTER_ASSIGN_QCHAR(From)
1287 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1291 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1295 result = QString::number(source,
'g', QLocale::FloatingPointShortest);
1299 result = QString::fromLatin1(&source, 1);
1304 result = QString::fromLatin1(&s, 1);
1309 result = QString::fromLatin1(&s, 1);
1313 result = QChar(source);
1317 result = QStringView(QChar::fromUcs4(source)).toString();
1320#if QT_CONFIG(datestring)
1321 QMETATYPE_CONVERTER(QString, QDate, result = source.toString(Qt::ISODate);
return true;);
1322 QMETATYPE_CONVERTER(QString, QTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1323 QMETATYPE_CONVERTER(QString, QDateTime, result = source.toString(Qt::ISODateWithMs);
return true;);
1327 return (source.size() == 1) ? (result = source.at(0),
true) :
false;
1331 if (source.isString() || source.isNull()) {
1332 result = source.toString();
1337 QMETATYPE_CONVERTER(QString, Nullptr, Q_UNUSED(source); result = QString();
return true;);
1342 result = source ?
"true" :
"false";
1357 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1361 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1365 result = QByteArray::number(source,
'g', QLocale::FloatingPointShortest);
1384 QMETATYPE_CONVERTER(QStringList, QString, result = QStringList() << source;
return true;);
1387 result.reserve(source.size());
1388 for (
const auto &v: source)
1389 result.append(v.toByteArray());
1393 result.reserve(source.size());
1394 for (
const auto &v: source)
1395 result.append(QVariant(v));
1400 result.reserve(source.size());
1401 for (
const auto &v: source)
1402 result.append(v.toString());
1406 result.reserve(source.size());
1407 for (
const auto &v: source)
1408 result.append(QVariant(v));
1413 result.reserve(source.size());
1414 for (
auto it = source.begin(); it != source.end(); ++it)
1415 result.insert(it.key(), it.value());
1419 for (
auto it = source.begin(); it != source.end(); ++it)
1420 result.insert(it.key(), it.value());
1425 if (source.isContainer() || source.isTag())
1427 result = source.toVariant().toString();
1432 if (source.isByteArray()) {
1433 result = source.toByteArray();
1440 if (!source.isUuid())
1442 result = source.toUuid();
1447 if (!source.isArray())
1449 result = source.toArray().toVariantList();
1452 QMETATYPE_CONVERTER(QCborValue, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1454 if (!source.isMap())
1456 result = source.toMap().toVariantMap();
1459 QMETATYPE_CONVERTER(QCborValue, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1461 if (!source.isMap())
1463 result = source.toMap().toVariantHash();
1466#if QT_CONFIG(regularexpression)
1467 QMETATYPE_CONVERTER(QCborValue, QRegularExpression, result = QCborValue(source);
return true;);
1468 QMETATYPE_CONVERTER(QRegularExpression, QCborValue,
1469 if (!source.isRegularExpression())
1471 result = source.toRegularExpression();
1478 result = QCborValue(QCborValue::Null);
1483 return source.isNull();
1501 result = QCborArray::fromStringList(source);
1504#if QT_CONFIG(datestring)
1505 QMETATYPE_CONVERTER(QCborValue, QDate,
1506 result = QCborValue(source.startOfDay());
1512 result = QCborValue::fromJsonValue(source);
1516 result = QCborMap::fromJsonObject(source);
1520 result = QCborArray::fromJsonArray(source);
1524 QJsonDocument doc = source;
1526 result = QCborArray::fromJsonArray(doc.array());
1528 result = QCborMap::fromJsonObject(doc.object());
1534#if QT_CONFIG(datestring)
1535 QMETATYPE_CONVERTER_ASSIGN(QCborValue, QDateTime);
1536 QMETATYPE_CONVERTER(QDateTime, QCborValue,
1537 if (source.isDateTime()) {
1538 result = source.toDateTime();
1547 if (source.isSimpleType()) {
1548 result = source.toSimpleType();
1556 QMETATYPE_CONVERTER(QCborArray, QStringList, result = QCborArray::fromStringList(source);
return true;);
1557 QMETATYPE_CONVERTER(QCborMap, QVariantMap, result = QCborMap::fromVariantMap(source);
return true;);
1559 QMETATYPE_CONVERTER(QCborMap, QVariantHash, result = QCborMap::fromVariantHash(source);
return true;);
1560 QMETATYPE_CONVERTER(QVariantHash, QCborMap, result = source.toVariantHash();
return true;);
1563 if (!source.isArray())
1565 result = source.toArray();
1569 if (!source.isArray())
1571 result = QCborArray::fromJsonArray(source.array());
1575 if (!source.isArray())
1577 result = QCborArray::fromJsonArray(source.toArray());
1581 result = QCborArray::fromJsonArray(source);
1585 if (!source.isMap())
1587 result = source.toMap();
1591 if (source.isArray())
1593 result = QCborMap::fromJsonObject(source.object());
1597 if (!source.isObject())
1599 result = QCborMap::fromJsonObject(source.toObject());
1603 result = QCborMap::fromJsonObject(source);
1609 if (!source.isArray())
1611 result = source.toArray().toVariantList();
1616 if (!source.isObject())
1618 result = source.toObject().toVariantMap();
1621 QMETATYPE_CONVERTER(QVariantMap, QJsonObject, result = source.toVariantMap();
return true;);
1623 if (!source.isObject())
1625 result = source.toObject().toVariantHash();
1628 QMETATYPE_CONVERTER(QVariantHash, QJsonObject, result = source.toVariantHash();
return true;);
1631 QMETATYPE_CONVERTER(QJsonArray, QStringList, result = QJsonArray::fromStringList(source);
return true;);
1634 if (!source.isArray())
1636 result = source.toArray();
1640 if (!source.isArray())
1642 result = source.array();
1646 if (!source.isArray())
1648 result = source.toArray().toJsonArray();
1652 QMETATYPE_CONVERTER(QJsonObject, QVariantMap, result = QJsonObject::fromVariantMap(source);
return true;);
1653 QMETATYPE_CONVERTER(QJsonObject, QVariantHash, result = QJsonObject::fromVariantHash(source);
return true;);
1655 if (!source.isObject())
1657 result = source.toObject();
1661 if (source.isArray())
1663 result = source.object();
1667 if (!source.isMap())
1669 result = source.toMap().toJsonObject();
1672 QMETATYPE_CONVERTER(QJsonObject, QCborMap, result = source.toJsonObject();
return true; );
1676 result = QJsonValue(QJsonValue::Null);
1681 return source.isNull();
1684 result = QJsonValue(source);
1702 result = QJsonValue(QJsonArray::fromStringList(source));
1706 result = QJsonValue(QJsonArray::fromVariantList(source));
1710 result = QJsonValue(QJsonObject::fromVariantMap(source));
1714 result = QJsonValue(QJsonObject::fromVariantHash(source));
1726 QJsonDocument doc = source;
1727 result = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
1731 result = source.toJsonValue();
1735 result = source.toJsonObject();
1739 result = source.toJsonArray();
1746#if QT_CONFIG(datestring)
1747 QMETATYPE_CONVERTER(QDate, QString,
1748 result = QDate::fromString(source, Qt::ISODate);
1749 return result.isValid();
1751 QMETATYPE_CONVERTER(QTime, QString,
1752 result = QTime::fromString(source, Qt::ISODate);
1753 return result.isValid();
1755 QMETATYPE_CONVERTER(QDateTime, QString,
1756 result = QDateTime::fromString(source, Qt::ISODate);
1757 return result.isValid();
1769Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeGuiHelper = {};
1770Q_CONSTINIT Q_CORE_EXPORT QMetaTypeModuleHelper qMetaTypeWidgetsHelper = {};
1772#ifndef QT_BOOTSTRAPPED
1775 int type = qMax(fromTypeId, toTypeId);
1776 if (type <= QMetaType::LastCoreType)
1777 return QCoreVariantHelper::convert(from, fromTypeId, to, toTypeId);
1778 if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType)
1779 return qMetaTypeGuiHelper.convert(from, fromTypeId, to, toTypeId);
1780 else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType)
1781 return qMetaTypeWidgetsHelper.convert(from, fromTypeId, to, toTypeId);
1785template<
typename T,
typename Key>
1791 const QWriteLocker locker(&lock);
1797 const QReadLocker locker(&lock);
1798 return map.contains(k);
1803 const QWriteLocker locker(&lock);
1804 auto r = map.tryEmplace(k, f);
1810 const QReadLocker locker(&lock);
1811 auto it = map.find(k);
1812 return it == map.end() ?
nullptr :
std::addressof(*it);
1817 const Key k(from, to);
1818 const QWriteLocker locker(&lock);
1822 mutable QReadWriteLock lock;
1826using QMetaTypeConverterRegistry
1827 = QMetaTypeFunctionRegistry<QMetaType::ConverterFunction, std::pair<
int,
int>>;
1829Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry)
1831using QMetaTypeMutableViewRegistry
1832 = QMetaTypeFunctionRegistry<QMetaType::MutableViewFunction, std::pair<
int,
int>>;
1833Q_GLOBAL_STATIC(QMetaTypeMutableViewRegistry, customTypesMutableViewRegistry)
1836
1837
1838
1839
1840
1841
1842
1845
1846
1847
1848
1849
1850
1851
1852
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1880
1881
1882
1883
1885
1886bool QMetaType::registerConverterFunction(
const ConverterFunction &f, QMetaType from, QMetaType to)
1888 if (!customTypesConversionRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1889 qWarning(
"Type conversion already registered from type %s to type %s",
1890 from.name(), to.name());
1897
1898
1899
1900
1901
1902
1903
1906
1907
1908
1909
1910
1911
1914
1915
1916
1918
1919bool QMetaType::registerMutableViewFunction(
const MutableViewFunction &f, QMetaType from, QMetaType to)
1921 if (!customTypesMutableViewRegistry()->insertIfNotContains({from.id(), to.id()}, f)) {
1922 qWarning(
"Mutable view on type already registered from type %s to type %s",
1923 from.name(), to.name());
1931
1932void QMetaType::unregisterMutableViewFunction(QMetaType from, QMetaType to)
1934 if (customTypesMutableViewRegistry.isDestroyed())
1936 customTypesMutableViewRegistry()->remove(from.id(), to.id());
1940
1941
1943
1944void QMetaType::unregisterConverterFunction(QMetaType from, QMetaType to)
1946 if (customTypesConversionRegistry.isDestroyed())
1948 customTypesConversionRegistry()->remove(from.id(), to.id());
1952#ifndef QT_NO_DEBUG_STREAM
1955
1956
1958
1959QDebug operator<<(QDebug d, QMetaType m)
1961 const QDebugStateSaver saver(d);
1962 return d.nospace() <<
"QMetaType(" << m.name() <<
")";
1966
1967
1969
1970bool QMetaType::debugStream(QDebug& dbg,
const void *rhs)
1972 if (d_ptr && d_ptr->flags & QMetaType::IsPointer) {
1973 dbg << *
reinterpret_cast<
const void *
const *>(rhs);
1976 if (d_ptr && d_ptr->debugStream) {
1977 d_ptr->debugStream(d_ptr, dbg, rhs);
1984
1985
1986
1987
1990
1991
1992
1993
1994
1995
1998
1999
2000
2001
2002
2003
2004
2007
2008
2009
2011
2012bool QMetaType::hasRegisteredDebugStreamOperator()
const
2014 return d_ptr && d_ptr->debugStream !=
nullptr;
2018#ifndef QT_NO_QOBJECT
2020
2022
2023static QMetaEnum metaEnumFromType(QMetaType t)
2025 if (t.flags() & QMetaType::IsEnumeration) {
2026 if (
const QMetaObject *metaObject = t.metaObject()) {
2027 QByteArrayView qflagsNamePrefix =
"QFlags<";
2029 if (enumName.endsWith(
'>') && enumName.startsWith(qflagsNamePrefix)) {
2032 enumName = enumName.sliced(qflagsNamePrefix.size());
2034 if (qsizetype lastColon = enumName.lastIndexOf(
':'); lastColon != -1)
2035 enumName = enumName.sliced(lastColon + 1);
2036 return metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
2043#ifndef QT_BOOTSTRAPPED
2044static bool convertFromEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2047 if (fromType.flags() & QMetaType::IsUnsignedEnumeration) {
2049 switch (fromType.sizeOf()) {
2051 ull = *
static_cast<
const unsigned char *>(from);
2054 ull = *
static_cast<
const unsigned short *>(from);
2057 ull = *
static_cast<
const unsigned int *>(from);
2060 ull = *
static_cast<
const quint64 *>(from);
2065 if (toType.id() == QMetaType::ULongLong) {
2066 *
static_cast<qulonglong *>(to) = ull;
2069 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2070 return QMetaType::convert(QMetaType::fromType<qulonglong>(), &ull, toType, to);
2071 ll = qlonglong(ull);
2073 switch (fromType.sizeOf()) {
2075 ll = *
static_cast<
const signed char *>(from);
2078 ll = *
static_cast<
const short *>(from);
2081 ll = *
static_cast<
const int *>(from);
2084 ll = *
static_cast<
const qint64 *>(from);
2089 if (toType.id() == QMetaType::LongLong) {
2090 *
static_cast<qlonglong *>(to) = ll;
2093 if (toType.id() != QMetaType::QString && toType.id() != QMetaType::QByteArray)
2094 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2096#ifndef QT_NO_QOBJECT
2097 QMetaEnum en = metaEnumFromType(fromType);
2101 if (toType.id() == QMetaType::QString)
2102 *
static_cast<QString *>(to) = QString::fromUtf8(keys);
2106 const char *key = en.valueToKey(ll);
2107 if (toType.id() == QMetaType::QString)
2108 *
static_cast<QString *>(to) = QString::fromUtf8(key);
2115 if (toType.id() == QMetaType::QString || toType.id() == QMetaType::QByteArray)
2116 return QMetaType::convert(QMetaType::fromType<qlonglong>(), &ll, toType, to);
2120static bool convertToEnum(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2122 int fromTypeId = fromType.id();
2123 qlonglong value = -1;
2125#ifndef QT_NO_QOBJECT
2126 if (fromTypeId == QMetaType::QString || fromTypeId == QMetaType::QByteArray) {
2127 QMetaEnum en = metaEnumFromType(toType);
2129 QByteArray keys = (fromTypeId == QMetaType::QString)
2130 ?
static_cast<
const QString *>(from)->toUtf8()
2131 : *
static_cast<
const QByteArray *>(from);
2132 if (
auto v = en.keysToValue64(keys.constData())) {
2140 if (fromTypeId == QMetaType::LongLong) {
2141 value = *
static_cast<
const qlonglong *>(from);
2144 ok = QMetaType::convert(fromType, from, QMetaType::fromType<qlonglong>(), &value);
2151 switch (toType.sizeOf()) {
2153 *
static_cast<
signed char *>(to) = value;
2156 *
static_cast<qint16 *>(to) = value;
2159 *
static_cast<qint32 *>(to) = value;
2162 *
static_cast<qint64 *>(to) = value;
2165 Q_UNREACHABLE_RETURN(
false);
2169template<
typename Iterable>
2170bool convertIterableToVariantList(QMetaType fromType,
const void *from,
void *to)
2173 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &list))
2178 if (list.metaContainer().hasSize())
2179 l.reserve(list.size());
2180 auto end = list.end();
2181 for (
auto it = list.begin(); it != end; ++it)
2186template<
typename Iterable>
2187bool convertIterableToVariantMap(QMetaType fromType,
const void *from,
void *to)
2190 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
2193 QVariantMap &h = *
static_cast<QVariantMap *>(to);
2195 auto end = map.end();
2196 for (
auto it = map.begin(); it != end; ++it)
2197 h.insert(it.key().toString(), it.value());
2201template<
typename Iterable>
2202bool convertIterableToVariantHash(QMetaType fromType,
const void *from,
void *to)
2205 if (!QMetaType::convert(fromType, from, QMetaType::fromType<Iterable>(), &map))
2208 QVariantHash &h = *
static_cast<QVariantHash *>(to);
2210 h.reserve(map.size());
2211 auto end = map.end();
2212 for (
auto it = map.begin(); it != end; ++it)
2213 h.insert(it.key().toString(), it.value());
2217static bool convertIterableToVariantPair(QMetaType fromType,
const void *from,
void *to)
2220 const auto f = customTypesConversionRegistry()->function({fromType.id(), targetId});
2228 QVariant v1(pi._metaType_first);
2230 if (pi._metaType_first == QMetaType::fromType<QVariant>())
2233 dataPtr = v1.data();
2236 QVariant v2(pi._metaType_second);
2237 if (pi._metaType_second == QMetaType::fromType<QVariant>())
2240 dataPtr = v2.data();
2243 *
static_cast<QVariantPair *>(to) = QVariantPair(v1, v2);
2247template<
typename Iterable>
2248static bool convertToSequentialIterable(QMetaType fromType,
const void *from,
void *to)
2251 const int fromTypeId = fromType.id();
2253 Iterable &i = *
static_cast<Iterable *>(to);
2254 switch (fromTypeId) {
2255 case QMetaType::QVariantList:
2256 i = Iterable(
reinterpret_cast<
const QVariantList *>(from));
2258 case QMetaType::QStringList:
2259 i = Iterable(
reinterpret_cast<
const QStringList *>(from));
2261 case QMetaType::QByteArrayList:
2262 i = Iterable(
reinterpret_cast<
const QByteArrayList *>(from));
2264 case QMetaType::QString:
2265 i = Iterable(
reinterpret_cast<
const QString *>(from));
2267 case QMetaType::QByteArray:
2268 i = Iterable(
reinterpret_cast<
const QByteArray *>(from));
2271 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2272 if (QMetaType::convert(
2273 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2283static bool canConvertToSequentialIterable(QMetaType fromType)
2285 switch (fromType.id()) {
2286 case QMetaType::QVariantList:
2287 case QMetaType::QStringList:
2288 case QMetaType::QByteArrayList:
2289 case QMetaType::QString:
2290 case QMetaType::QByteArray:
2293 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2297static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType)
2299 switch (fromType.id()) {
2300 case QMetaType::QVariantList:
2301 case QMetaType::QStringList:
2302 case QMetaType::QByteArrayList:
2303 case QMetaType::QString:
2304 case QMetaType::QByteArray:
2307 return QMetaType::canView(
2308 fromType, QMetaType::fromType<QIterable<QMetaSequence>>());
2312template<
typename Iterable>
2313static bool viewAsSequentialIterable(QMetaType fromType,
void *from,
void *to)
2316 const int fromTypeId = fromType.id();
2318 Iterable &i = *
static_cast<Iterable *>(to);
2319 switch (fromTypeId) {
2320 case QMetaType::QVariantList:
2323 case QMetaType::QStringList:
2324 i = Iterable(
reinterpret_cast<QStringList *>(from));
2326 case QMetaType::QByteArrayList:
2327 i = Iterable(
reinterpret_cast<QByteArrayList *>(from));
2329 case QMetaType::QString:
2330 i = Iterable(
reinterpret_cast<QString *>(from));
2332 case QMetaType::QByteArray:
2333 i = Iterable(
reinterpret_cast<
QByteArray *>(from));
2336 QIterable<QMetaSequence> j(QMetaSequence(),
nullptr);
2337 if (QMetaType::view(
2338 fromType, from, QMetaType::fromType<QIterable<QMetaSequence>>(), &j)) {
2348template<
typename Iterable>
2349static bool convertToAssociativeIterable(QMetaType fromType,
const void *from,
void *to)
2353 Iterable &i = *
static_cast<Iterable *>(to);
2354 if (fromType.id() == QMetaType::QVariantMap) {
2355 i = Iterable(
reinterpret_cast<
const QVariantMap *>(from));
2358 if (fromType.id() == QMetaType::QVariantHash) {
2359 i = Iterable(
reinterpret_cast<
const QVariantHash *>(from));
2363 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2364 if (QMetaType::convert(
2365 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2373static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
2375 if ((fromType.flags() & QMetaType::IsPointer) != (toType.flags() & QMetaType::IsPointer))
2378 const QMetaObject *f = fromType.metaObject();
2379 const QMetaObject *t = toType.metaObject();
2381 return f->inherits(t) || (t->inherits(f));
2386static bool canConvertToAssociativeIterable(QMetaType fromType)
2388 switch (fromType.id()) {
2389 case QMetaType::QVariantMap:
2390 case QMetaType::QVariantHash:
2393 return QMetaType::canConvert(fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2397static bool canImplicitlyViewAsAssociativeIterable(QMetaType fromType)
2399 switch (fromType.id()) {
2400 case QMetaType::QVariantMap:
2401 case QMetaType::QVariantHash:
2404 return QMetaType::canView(
2405 fromType, QMetaType::fromType<QIterable<QMetaAssociation>>());
2409template<
typename Iterable>
2410static bool viewAsAssociativeIterable(QMetaType fromType,
void *from,
void *to)
2413 int fromTypeId = fromType.id();
2415 Iterable &i = *
static_cast<Iterable *>(to);
2416 if (fromTypeId == QMetaType::QVariantMap) {
2417 i = Iterable(
reinterpret_cast<QVariantMap *>(from));
2420 if (fromTypeId == QMetaType::QVariantHash) {
2421 i = Iterable(
reinterpret_cast<QVariantHash *>(from));
2425 QIterable<QMetaAssociation> j(QMetaAssociation(),
nullptr);
2426 if (QMetaType::view(
2427 fromType, from, QMetaType::fromType<QIterable<QMetaAssociation>>(), &j)) {
2435static bool convertMetaObject(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2438 if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
2439 QObject *fromObject = *
static_cast<QObject *
const *>(from);
2441 if (fromObject && fromObject->metaObject()->inherits(toType.metaObject())) {
2442 *
static_cast<QObject **>(to) = toType.metaObject()->cast(fromObject);
2444 }
else if (!fromObject && fromType.metaObject()) {
2446 *
static_cast<
void **>(to) =
nullptr;
2447 return fromType.metaObject()->inherits(toType.metaObject());
2449 }
else if ((fromType.flags() & QMetaType::IsPointer) == (toType.flags() & QMetaType::IsPointer)) {
2451 const QMetaObject *f = fromType.metaObject();
2452 const QMetaObject *t = toType.metaObject();
2453 if (f && t && f->inherits(t)) {
2454 toType.destruct(to);
2455 toType.construct(to, from);
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2475
2476
2477
2478
2479
2481
2482bool QMetaType::convert(QMetaType fromType,
const void *from, QMetaType toType,
void *to)
2484 if (!fromType.isValid() || !toType.isValid())
2487 if (fromType == toType) {
2489 fromType.destruct(to);
2490 fromType.construct(to, from);
2494 int fromTypeId = fromType.id();
2495 int toTypeId = toType.id();
2497 if (tryConvertBuiltinTypes(from, fromTypeId, to, toTypeId))
2499 const auto f = customTypesConversionRegistry()->function({fromTypeId, toTypeId});
2501 return (*f)(from, to);
2503 if (fromType.flags() & QMetaType::IsEnumeration)
2504 return convertFromEnum(fromType, from, toType, to);
2505 if (toType.flags() & QMetaType::IsEnumeration)
2506 return convertToEnum(fromType, from, toType, to);
2507 if (toTypeId == Nullptr) {
2508 *
static_cast<std::nullptr_t *>(to) =
nullptr;
2509 if (fromType.flags() & QMetaType::IsPointer) {
2510 if (*
static_cast<
const void *
const *>(from) ==
nullptr)
2515 if (toTypeId == QVariantPair && convertIterableToVariantPair(fromType, from, to))
2519 if (toTypeId == QVariantList
2520 && convertIterableToVariantList<QMetaSequence::Iterable>(fromType, from, to)) {
2524 if (toTypeId == QVariantMap
2525 && convertIterableToVariantMap<QMetaAssociation::Iterable>(fromType, from, to)) {
2529 if (toTypeId == QVariantHash
2530 && convertIterableToVariantHash<QMetaAssociation::Iterable>(fromType, from, to)) {
2534 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2535 return convertToSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
2537 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2538 return convertToAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
2540#if QT_DEPRECATED_SINCE(6
, 15
)
2542 QT_WARNING_DISABLE_DEPRECATED
2544 if (toTypeId == QVariantList
2545 && convertIterableToVariantList<QSequentialIterable>(fromType, from, to)) {
2549 if (toTypeId == QVariantMap
2550 && convertIterableToVariantMap<QAssociativeIterable>(fromType, from, to)) {
2554 if (toTypeId == QVariantHash
2555 && convertIterableToVariantHash<QAssociativeIterable>(fromType, from, to)) {
2559 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2560 return convertToSequentialIterable<QSequentialIterable>(fromType, from, to);
2562 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2563 return convertToAssociativeIterable<QAssociativeIterable>(fromType, from, to);
2568 return convertMetaObject(fromType, from, toType, to);
2572
2573
2575
2576bool QMetaType::view(QMetaType fromType,
void *from, QMetaType toType,
void *to)
2578 if (!fromType.isValid() || !toType.isValid())
2581 int fromTypeId = fromType.id();
2582 int toTypeId = toType.id();
2584 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2586 return (*f)(from, to);
2588 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2589 return viewAsSequentialIterable<QMetaSequence::Iterable>(fromType, from, to);
2591 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2592 return viewAsAssociativeIterable<QMetaAssociation::Iterable>(fromType, from, to);
2594#if QT_DEPRECATED_SINCE(6
, 15
)
2596 QT_WARNING_DISABLE_DEPRECATED
2598 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2599 return viewAsSequentialIterable<QSequentialIterable>(fromType, from, to);
2601 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2602 return viewAsAssociativeIterable<QAssociativeIterable>(fromType, from, to);
2607 return convertMetaObject(fromType, from, toType, to);
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2626
2627bool QMetaType::canView(QMetaType fromType, QMetaType toType)
2629 int fromTypeId = fromType.id();
2630 int toTypeId = toType.id();
2632 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2635 const auto f = customTypesMutableViewRegistry()->function({fromTypeId, toTypeId});
2639 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2640 return canImplicitlyViewAsSequentialIterable(fromType);
2642 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2643 return canImplicitlyViewAsAssociativeIterable(fromType);
2645#if QT_DEPRECATED_SINCE(6
, 15
)
2647 QT_WARNING_DISABLE_DEPRECATED
2649 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2650 return canImplicitlyViewAsSequentialIterable(fromType);
2652 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2653 return canImplicitlyViewAsAssociativeIterable(fromType);
2658 if (canConvertMetaObject(fromType, toType))
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2748
2749bool QMetaType::canConvert(QMetaType fromType, QMetaType toType)
2751 int fromTypeId = fromType.id();
2752 int toTypeId = toType.id();
2754 if (fromTypeId == UnknownType || toTypeId == UnknownType)
2757 if (fromTypeId == toTypeId)
2760 if (tryConvertBuiltinTypes(
nullptr, fromTypeId,
nullptr, toTypeId))
2763 const ConverterFunction *
const f =
2764 customTypesConversionRegistry()->function(std::make_pair(fromTypeId, toTypeId));
2768 if (toTypeId == qMetaTypeId<QMetaSequence::Iterable>())
2769 return canConvertToSequentialIterable(fromType);
2771 if (toTypeId == qMetaTypeId<QMetaAssociation::Iterable>())
2772 return canConvertToAssociativeIterable(fromType);
2774 if (toTypeId == QVariantList
2775 && canConvert(fromType, QMetaType::fromType<QMetaSequence::Iterable>())) {
2779 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2780 && canConvert(fromType, QMetaType::fromType<QMetaAssociation::Iterable>())) {
2784#if QT_DEPRECATED_SINCE(6
, 15
)
2786 QT_WARNING_DISABLE_DEPRECATED
2788 if (toTypeId == qMetaTypeId<QSequentialIterable>())
2789 return canConvertToSequentialIterable(fromType);
2791 if (toTypeId == qMetaTypeId<QAssociativeIterable>())
2792 return canConvertToAssociativeIterable(fromType);
2794 if (toTypeId == QVariantList
2795 && canConvert(fromType, QMetaType::fromType<QSequentialIterable>())) {
2799 if ((toTypeId == QVariantHash || toTypeId == QVariantMap)
2800 && canConvert(fromType, QMetaType::fromType<QAssociativeIterable>())) {
2807 if (toTypeId == QVariantPair && hasRegisteredConverterFunction(
2808 fromType, QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>()))
2811 if (fromType.flags() & IsEnumeration) {
2812 if (toTypeId == QString || toTypeId == QByteArray)
2814 return canConvert(QMetaType(LongLong), toType);
2816 if (toType.flags() & IsEnumeration) {
2817 if (fromTypeId == QString || fromTypeId == QByteArray)
2819 return canConvert(fromType, QMetaType(LongLong));
2821 if (toTypeId == Nullptr && fromType.flags() & IsPointer)
2823 if (canConvertMetaObject(fromType, toType))
2830
2831
2832
2833
2834
2835
2836
2839
2840
2841
2842
2843
2846
2847
2849
2850bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toType)
2852 return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
2856
2858
2859bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
2861 const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
2862 return QMetaType::hasRegisteredConverterFunction(m, to);
2866
2868
2869bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
2871 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2872 return QMetaType::hasRegisteredConverterFunction(m, to);
2876
2878
2879bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
2881 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2882 return QMetaType::hasRegisteredConverterFunction(m, to);
2886
2887
2888
2889
2890
2893
2894
2896
2897bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType toType)
2899 return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
2903
2905
2906bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
2908 const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
2909 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2913
2915
2916bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
2918 const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
2919 return QMetaType::hasRegisteredMutableViewFunction(m, to);
2924
2925
2926
2927
2928
2929
2930
2931
2932
2935
2936
2937
2938
2939
2940
2941
2942
2943
2947
2948static inline int qMetaTypeStaticType(QByteArrayView name)
2950 for (
int i = 0; i < types.count(); ++i) {
2951 if (types.viewAt(i) == name)
2952 return types.typeIdMap[i];
2954 return QMetaType::UnknownType;
2957#ifndef QT_BOOTSTRAPPED
2959
2960
2961
2962
2964
2965void QMetaType::registerNormalizedTypedef(
const NS(QByteArray) & normalizedTypeName,
2968 if (!metaType.isValid())
2970 if (
auto reg = customTypeRegistry()) {
2971 QWriteLocker lock(®->lock);
2972 auto &al = reg->aliases[normalizedTypeName];
2976 al = QMetaTypeCustomRegistry::Alias(
2977 metaType.d_ptr, QMetaTypeCustomRegistry::HasTypedefs::Yes);
2978 reg->aliases[metaType.name()].setTag(QMetaTypeCustomRegistry::HasTypedefs::Yes);
2985 Q_ASSERT(typeId < QMetaType::User);
2986 if (typeId <= QMetaType::LastCoreType)
2987 return QCoreVariantHelper::interfaceForType(typeId);
2988 if (typeId >= QMetaType::FirstGuiType && typeId <= QMetaType::LastGuiType)
2989 return qMetaTypeGuiHelper.interfaceForType(typeId);
2990 if (typeId >= QMetaType::FirstWidgetsType && typeId <= QMetaType::LastWidgetsType)
2991 return qMetaTypeWidgetsHelper.interfaceForType(typeId);
2998 if (typeId >= QMetaType::User) {
2999#ifndef QT_BOOTSTRAPPED
3000 if (customTypeRegistry.exists())
3001 iface = customTypeRegistry->getCustomType(typeId);
3004 iface = interfaceForStaticType(typeId);
3010
3011
3012
3014
3015bool QMetaType::isRegistered(
int type)
3017 return interfaceForTypeNoWarning(type) !=
nullptr;
3022 Q_PRE(!name.isEmpty());
3023 int type = qMetaTypeStaticType(name);
3024 if (type != QMetaType::UnknownType) {
3025 return interfaceForStaticType(type);
3026#ifndef QT_BOOTSTRAPPED
3027 }
else if (customTypeRegistry.exists()) {
3028 QReadLocker locker(&customTypeRegistry->lock);
3029 auto it = customTypeRegistry->aliases.constFind(name);
3030 if (it != customTypeRegistry->aliases.constEnd())
3031 return it.value().data();
3038
3039
3040
3041
3042
3043
3044
3045
3048
3049
3050
3051
3052
3053
3055
3056int qMetaTypeTypeInternal(QByteArrayView name)
3059 if (!name.isEmpty())
3060 iface = findMetaTypeByName(name);
3061 return iface ? iface->typeId.loadRelaxed() : QMetaType::UnknownType;
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3077#ifndef QT_NO_DATASTREAM
3079
3080
3081
3082
3083
3084
3085
3086
3088
3089bool QMetaType::save(QDataStream &stream,
const void *data)
const
3091 if (!data || !isValid())
3095 if (id() == QMetaType::Long) {
3096 stream << qlonglong(*(
long *)data);
3098 }
else if (id() == QMetaType::ULong) {
3099 stream << qlonglong(*(
unsigned long *)data);
3103 if (!d_ptr->dataStreamOut)
3106 d_ptr->dataStreamOut(d_ptr, stream, data);
3111
3112
3113
3114
3117
3118
3119
3120
3121
3122
3123
3124
3126
3127bool QMetaType::load(QDataStream &stream,
void *data)
const
3129 if (!data || !isValid())
3133 if (id() == QMetaType::Long) {
3136 *(
long *)data =
long(ll);
3138 }
else if (id() == QMetaType::ULong) {
3141 *(
unsigned long *)data = (
unsigned long)(ull);
3144 if (!d_ptr->dataStreamIn)
3147 d_ptr->dataStreamIn(d_ptr, stream, data);
3152
3153
3154
3156
3157bool QMetaType::hasRegisteredDataStreamOperators()
const
3160 if (type == QMetaType::Long || type == QMetaType::ULong)
3162 return d_ptr && d_ptr->dataStreamIn !=
nullptr && d_ptr->dataStreamOut !=
nullptr;
3166
3167
3168
3169
3170
3171
3173
3174QMetaType QMetaType::underlyingType()
const
3176 if (!d_ptr || !(flags() & IsEnumeration))
3179
3180
3181
3182
3183
3184
3185 if (flags() & IsUnsignedEnumeration) {
3188 return QMetaType::fromType<quint8>();
3190 return QMetaType::fromType<quint16>();
3192 return QMetaType::fromType<quint32>();
3194 return QMetaType::fromType<quint64>();
3201 return QMetaType::fromType<qint8>();
3203 return QMetaType::fromType<qint16>();
3205 return QMetaType::fromType<qint32>();
3207 return QMetaType::fromType<qint64>();
3217
3218
3219
3220
3224
3226
3227QMetaType QMetaType::fromName(QByteArrayView typeName)
3229 if (typeName.isEmpty())
3232 const QtPrivate::QMetaTypeInterface *iface = findMetaTypeByName(typeName);
3234 return QMetaType(iface);
3236#if !defined(QT_NO_QOBJECT)
3237 const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName.constData());
3238 if (normalizedTypeName != typeName)
3239 iface = findMetaTypeByName(normalizedTypeName);
3242 return QMetaType(iface);
3246
3247
3248
3249
3250
3251
3252
3253
3256
3257
3258
3259
3260
3261
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3321
3322
3323
3324
3325
3326
3327
3328
3331
3332
3333
3334
3335
3336
3337
3338
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3455 if (!iface && typeId != QMetaType::UnknownType)
3456 qWarning(
"Trying to construct an instance of an invalid type, type id: %i", typeId);
3462
3463
3464
3465
3466
3469
3470
3471
3473
3474QMetaType::QMetaType(
int typeId) : QMetaType(interfaceForType(typeId)) {}
3478
3479
3480
3481
3483namespace QtPrivate {
3484#if !defined(QT_BOOTSTRAPPED)
3485void QMetaTypeCopyTraits::warnAboutDeprecatedCopy(
const char *name)
3487 qCWarning(lcMetatypeDeprecated,
"QMetaType: copy construction of type '%s' is deprecated", name);
3491#if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY)
3494#define QT_METATYPE_DECLARE_TEMPLATE_ITER(TypeName, Id, Name)
3495 template class QMetaTypeForType<Name>;
3496 template struct QMetaTypeInterfaceWrapper<Name>;
3503#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)