From 620f788f8690b10ef101f883d4cdacd2a277f948 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 5 Apr 2013 13:26:35 +0200 Subject: [PATCH] Add QVariantList extraction from a QVariant with a sequential container. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id9fac7bf47ed3fbb385222b25941215ac24b8b88 Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qvariant.cpp | 7 +++ src/corelib/kernel/qvariant.h | 16 ++++++ .../corelib/kernel/qvariant/tst_qvariant.cpp | 51 +++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 7001e5b077..985433d83a 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3085,6 +3085,13 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro. + If the QVariant contains a sequential container and \c{T} is QVariantList, the + elements of the container will be converted into QVariants and returned as a QVariantList. + + \snippet code/src_corelib_kernel_qvariant.cpp 9 + + The qRegisterSequentialConverter method must first be called for the container. + \sa setValue(), fromValue(), canConvert() */ diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 97fb8089a4..5588cdb27c 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -674,6 +674,22 @@ namespace QtPrivate { return QSequentialIterable(v.value()); } }; + template<> + struct QVariantValueHelperInterface + { + static QVariantList invoke(const QVariant &v) + { + if (v.userType() == qMetaTypeId() || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId())) { + QSequentialIterable iter = QVariantValueHelperInterface::invoke(v); + QVariantList l; + l.reserve(iter.size()); + for (QSequentialIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it) + l << *it; + return l; + } + return QVariantValueHelper::invoke(v); + } + }; } template inline T qvariant_cast(const QVariant &v) diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 29d5725d76..3f5a05eb5d 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -3364,6 +3364,24 @@ struct ContainerAPI { 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(QVariant::fromValue(value)); + } + + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } }; template @@ -3378,6 +3396,10 @@ struct ContainerAPI { return variant.value() == value; } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } }; // We have no built-in defines to check the stdlib features. @@ -3400,7 +3422,26 @@ struct ContainerAPI > { return variant.value() == value; } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } }; + +template<> +struct ContainerAPI > +{ + static void insert(std::forward_list &container, int value) + { + container.push_front(QVariant::fromValue(value)); + } + + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + template<> struct ContainerAPI > { @@ -3412,6 +3453,10 @@ struct ContainerAPI > { return variant.value() == value; } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } }; #endif @@ -3424,6 +3469,7 @@ void tst_QVariant::iterateContainerElements() containerIter = intList.begin(); \ for (QVariant v : listIter) { \ QVERIFY(ContainerAPI >::compare(v, *containerIter)); \ + QVERIFY(ContainerAPI >::compare(v, varList.at(numSeen))); \ ++containerIter; \ ++numSeen; \ } \ @@ -3445,13 +3491,17 @@ void tst_QVariant::iterateContainerElements() \ QVariant listVariant = QVariant::fromValue(intList); \ QVERIFY(listVariant.canConvert()); \ + QVariantList varList = listVariant.value(); \ + QCOMPARE(varList.size(), (int)std::distance(intList.begin(), intList.end())); \ QSequentialIterable listIter = listVariant.value(); \ + QCOMPARE(varList.size(), listIter.size()); \ \ CONTAINER::iterator containerIter = intList.begin(); \ const CONTAINER::iterator containerEnd = intList.end(); \ for (int i = 0; i < listIter.size(); ++i, ++containerIter, ++numSeen) \ { \ QVERIFY(ContainerAPI >::compare(listIter.at(i), *containerIter)); \ + QVERIFY(ContainerAPI >::compare(listIter.at(i), varList.at(i))); \ } \ QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \ QCOMPARE(containerIter, containerEnd); \ @@ -3460,6 +3510,7 @@ void tst_QVariant::iterateContainerElements() numSeen = 0; \ Q_FOREACH (const QVariant &v, listIter) { \ QVERIFY(ContainerAPI >::compare(v, *containerIter)); \ + QVERIFY(ContainerAPI >::compare(v, varList.at(numSeen))); \ ++containerIter; \ ++numSeen; \ } \