diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-09-10 18:30:22 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-09-19 11:14:36 +0200 |
commit | 217a25a6bf59bb9ce0845267f46244fedd8bcaaa (patch) | |
tree | ae54c75f951553001472d5d8bb0f54e5a4f9056c /tests | |
parent | 5c808073af5b8f1290602fcccf60666c9a3682f8 (diff) |
QMetaType: Allow registration of mutable views and register iterables
In order to modify a container through an iterable, we need the original
container to be mutable. The iterable, then, is not a conversion of the
container, but rather a view on the container. The concept may be
extended to other types.
In order to facilitate this, provide a set of methods in QMetaType and
QVariant similar to the convert family. The new methods are non-const
and expect the original value to stay available during the life time of
the view.
Change-Id: I363621033f7fc600edcea2acb786820ccba49c86
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 4190a0cb9f..8122220b88 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -278,6 +278,7 @@ private slots: void sequentialIterableAppend(); void preferDirectConversionOverInterfaces(); + void mutableView(); private: void dataStream_data(QDataStream::Version version); @@ -4173,7 +4174,7 @@ void testSequentialIteration() QVERIFY(listVariant.canConvert<QVariantList>()); QVariantList varList = listVariant.value<QVariantList>(); QCOMPARE(varList.size(), (int)std::distance(sequence.begin(), sequence.end())); - QSequentialIterable listIter = listVariant.value<QSequentialIterable>(); + QSequentialIterable listIter = listVariant.view<QSequentialIterable>(); QCOMPARE(varList.size(), listIter.size()); typename Container::iterator containerIter = sequence.begin(); @@ -4758,7 +4759,7 @@ void tst_QVariant::sequentialIterableAppend() QList<int> container { 1, 2 }; auto variant = QVariant::fromValue(container); QVERIFY(variant.canConvert<QIterable<QMetaSequence>>()); - QSequentialIterable asIterable = variant.value<QIterable<QMetaSequence>>(); + QSequentialIterable asIterable = variant.view<QIterable<QMetaSequence>>(); const int i = 3, j = 4; void *mutableIterable = asIterable.mutableIterable(); asIterable.metaContainer().addValueAtEnd(mutableIterable, &i); @@ -4778,7 +4779,7 @@ void tst_QVariant::sequentialIterableAppend() QSet<QByteArray> container { QByteArray{"hello"}, QByteArray{"world"} }; auto variant = QVariant::fromValue(std::move(container)); QVERIFY(variant.canConvert<QIterable<QMetaSequence>>()); - QSequentialIterable asIterable = variant.value<QIterable<QMetaSequence>>(); + QSequentialIterable asIterable = variant.view<QIterable<QMetaSequence>>(); QByteArray qba1 {"goodbye"}; QByteArray qba2 { "moon" }; void *mutableIterable = asIterable.mutableIterable(); @@ -4834,5 +4835,43 @@ void tst_QVariant::preferDirectConversionOverInterfaces() QVERIFY(calledCorrectConverter); } +struct MyTypeView +{ + MyType *data; +}; + +void tst_QVariant::mutableView() +{ + bool calledView = false; + const bool success = QMetaType::registerMutableView<MyType, MyTypeView>([&](MyType &data) { + calledView = true; + return MyTypeView { &data }; + }); + QVERIFY(success); + + QTest::ignoreMessage( + QtWarningMsg, + "Mutable view on type already registered from type MyType to type MyTypeView"); + const bool shouldFail = QMetaType::registerMutableView<MyType, MyTypeView>([&](MyType &) { + return MyTypeView { nullptr }; + }); + QVERIFY(!shouldFail); + + auto original = QVariant::fromValue(MyType {}); + + QVERIFY(original.canView<MyTypeView>()); + QVERIFY(!original.canConvert<MyTypeView>()); + + MyTypeView view = original.view<MyTypeView>(); + QVERIFY(calledView); + const char *txt = "lll"; + view.data->number = 113; + view.data->text = txt; + + MyType extracted = original.view<MyType>(); + QCOMPARE(extracted.number, 0); + QCOMPARE(extracted.text, nullptr); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" |