diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 78ade68a2c..859a8946a4 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1951,27 +1951,33 @@ static bool convertIterableToVariantPair(QMetaType fromType, const void *from, v static bool convertToSequentialIterable(QMetaType fromType, const void *from, void *to) { using namespace QtMetaTypePrivate; - int fromTypeId = fromType.id(); + const int fromTypeId = fromType.id(); QSequentialIterable &i = *static_cast(to); - if (fromTypeId == QMetaType::QVariantList) { + switch (fromTypeId) { + case QMetaType::QVariantList: i = QSequentialIterable(reinterpret_cast(from)); return true; - } - if (fromTypeId == QMetaType::QStringList) { + case QMetaType::QStringList: i = QSequentialIterable(reinterpret_cast(from)); return true; - } - else if (fromTypeId == QMetaType::QByteArrayList) { + case QMetaType::QByteArrayList: i = QSequentialIterable(reinterpret_cast(from)); return true; - } - - QSequentialIterable impl; - if (QMetaType::convert( - fromType, from, QMetaType::fromType>(), &impl)) { - i = std::move(impl); + case QMetaType::QString: + i = QSequentialIterable(reinterpret_cast(from)); return true; + case QMetaType::QByteArray: + i = QSequentialIterable(reinterpret_cast(from)); + return true; + default: { + QSequentialIterable impl; + if (QMetaType::convert( + fromType, from, QMetaType::fromType>(), &impl)) { + i = std::move(impl); + return true; + } + } } return false; @@ -1983,6 +1989,8 @@ static bool canConvertToSequentialIterable(QMetaType fromType) case QMetaType::QVariantList: case QMetaType::QStringList: case QMetaType::QByteArrayList: + case QMetaType::QString: + case QMetaType::QByteArray: return true; default: return QMetaType::canConvert(fromType, QMetaType::fromType>()); @@ -1995,6 +2003,8 @@ static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType) case QMetaType::QVariantList: case QMetaType::QStringList: case QMetaType::QByteArrayList: + case QMetaType::QString: + case QMetaType::QByteArray: return true; default: return QMetaType::canView( @@ -2005,27 +2015,33 @@ static bool canImplicitlyViewAsSequentialIterable(QMetaType fromType) static bool viewAsSequentialIterable(QMetaType fromType, void *from, void *to) { using namespace QtMetaTypePrivate; - int fromTypeId = fromType.id(); + const int fromTypeId = fromType.id(); QSequentialIterable &i = *static_cast(to); - if (fromTypeId == QMetaType::QVariantList) { + switch (fromTypeId) { + case QMetaType::QVariantList: i = QSequentialIterable(reinterpret_cast(from)); return true; - } - if (fromTypeId == QMetaType::QStringList) { + case QMetaType::QStringList: i = QSequentialIterable(reinterpret_cast(from)); return true; - } - else if (fromTypeId == QMetaType::QByteArrayList) { + case QMetaType::QByteArrayList: i = QSequentialIterable(reinterpret_cast(from)); return true; - } - - QIterable j(QMetaSequence(), nullptr); - if (QMetaType::view( - fromType, from, QMetaType::fromType>(), &j)) { - i = std::move(j); + case QMetaType::QString: + i = QSequentialIterable(reinterpret_cast(from)); return true; + case QMetaType::QByteArray: + i = QSequentialIterable(reinterpret_cast(from)); + return true; + default: { + QIterable j(QMetaSequence(), nullptr); + if (QMetaType::view( + fromType, from, QMetaType::fromType>(), &j)) { + i = std::move(j); + return true; + } + } } return false; diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 366d07cfa0..6b30419bb8 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -474,7 +474,7 @@ void tst_QVariant::canConvert_data() << var << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N; var = QVariant(QByteArray()); QTest::newRow("ByteArray") - << var << N << N << Y << N << Y << Y << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; + << var << N << N << Y << N << Y << Y << N << N << N << Y << N << N << Y << N << N << Y << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; var = QVariant(QDate()); QTest::newRow("Date") << var << N << N << N << N << N << N << N << Y << Y << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N; @@ -513,7 +513,7 @@ void tst_QVariant::canConvert_data() << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N; var = QVariant(QString()); QTest::newRow("String") - << var << N << N << Y << N << Y << Y << N << Y << Y << Y << Y << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << Y << Y << Y << Y; + << var << N << N << Y << N << Y << Y << N << Y << Y << Y << Y << N << Y << N << Y << Y << Y << N << N << N << N << N << N << N << N << N << Y << Y << Y << Y << Y; var = QVariant(QStringList("entry")); QTest::newRow("StringList") << var << N << N << N << N << N << N << N << N << N << N << N << N << N << N << N << Y << N << N << N << N << N << N << N << N << N << N << Y << Y << N << N << N; @@ -4074,6 +4074,42 @@ struct ContainerAPI } }; +template +struct ContainerAPI +{ + static void insert(Container &container, int value) + { + container.push_back(QChar::fromLatin1(char(value) + '0')); + } + + static bool compare(const QVariant &variant, QChar value) + { + return variant.value() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template +struct ContainerAPI +{ + static void insert(Container &container, int value) + { + container.push_back(char(value) + '0'); + } + + static bool compare(const QVariant &variant, char value) + { + return variant.value() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + #ifdef __has_include # if __has_include() # define TEST_FORWARD_LIST @@ -4287,14 +4323,20 @@ void testSequentialIteration() QCOMPARE(listIter.at(4), third); QCOMPARE(listIter.at(5), third); - listIter.removeValue(); - compareLists(); - QCOMPARE(listIter.size(), 5); - QCOMPARE(listIter.at(0), first); - QCOMPARE(listIter.at(1), first); - QCOMPARE(listIter.at(2), second); - QCOMPARE(listIter.at(3), second); - QCOMPARE(listIter.at(4), third); + if (listIter.metaContainer().canRemoveValue()) { + listIter.removeValue(); + compareLists(); + QCOMPARE(listIter.size(), 5); + QCOMPARE(listIter.at(0), first); + QCOMPARE(listIter.at(1), first); + QCOMPARE(listIter.at(2), second); + QCOMPARE(listIter.at(3), second); + QCOMPARE(listIter.at(4), third); + } else { + // QString and QByteArray have no pop_back or pop_front and it's unclear what other + // method we should use to remove an item. + QVERIFY((std::is_same_v || std::is_same_v)); + } auto i = listIter.mutableBegin(); QVERIFY(i != listIter.mutableEnd()); @@ -4404,6 +4446,8 @@ void tst_QVariant::iterateContainerElements() testSequentialIteration>(); testSequentialIteration(); testSequentialIteration(); + testSequentialIteration(); + testSequentialIteration(); #ifdef TEST_FORWARD_LIST testSequentialIteration>();