QMetaType: Support converting any QFuture<T> to QFuture<void>

QMetaType now implicitly knows how to convert any QFuture<T> to
QFuture<void> without needing to manually register a converter
function.

QtWebChannel will make use of this to transparently support QFuture<T>
return types.

[ChangeLog][QtCore][QMetaType] QMetaType now supports converting any
QFuture<T> to QFuture<void>.

Task-number: QTBUG-92903
Change-Id: Ied7e71be37c346cc3d2c274ffb0d91a6821ab4d4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Arno Rehn 2021-07-09 16:22:18 +02:00
parent ac40875ba7
commit 90d9a86c2e
3 changed files with 49 additions and 0 deletions

View File

@ -1092,6 +1092,14 @@ namespace QtPrivate
static bool registerConverter() { return false; }
};
#if QT_CONFIG(future)
template<typename T>
struct MetaTypeQFutureHelper
{
static bool registerConverter() { return false; }
};
#endif
Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type);
} // namespace QtPrivate
@ -1218,6 +1226,9 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
QtPrivate::AssociativeContainerTransformationHelper<T>::registerMutableView();
QtPrivate::MetaTypePairHelper<T>::registerConverter();
QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter();
#if QT_CONFIG(future)
QtPrivate::MetaTypeQFutureHelper<T>::registerConverter();
#endif
if (normalizedTypeName != metaType.name())
QMetaType::registerNormalizedTypedef(normalizedTypeName, metaType);

View File

@ -43,6 +43,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qfutureinterface.h>
#include <QtCore/qmetatype.h>
#include <QtCore/qstring.h>
#include <QtCore/qfuture_impl.h>
@ -438,8 +439,27 @@ QFutureInterfaceBase QFutureInterfaceBase::get(const QFuture<T> &future)
return future.d;
}
namespace QtPrivate
{
template<typename T>
struct MetaTypeQFutureHelper<QFuture<T>>
{
static bool registerConverter() {
if constexpr (std::is_same_v<T, void>)
return false;
return QMetaType::registerConverter<QFuture<T>, QFuture<void>>(
[](const QFuture<T> &future) { return QFuture<void>(future); });
}
};
} // namespace QtPrivate
Q_DECLARE_SEQUENTIAL_ITERATOR(Future)
QT_END_NAMESPACE
Q_DECLARE_METATYPE_TEMPLATE_1ARG(QFuture)
#endif // QFUTURE_H

View File

@ -164,6 +164,7 @@ private slots:
void createReadyFutures();
void getFutureInterface();
void convertQMetaType();
private:
using size_type = std::vector<int>::size_type;
@ -3532,5 +3533,22 @@ void tst_QFuture::getFutureInterface()
QCOMPARE(interface.resultCount(), 1);
}
void tst_QFuture::convertQMetaType()
{
const auto intType = QMetaType::fromType<QFuture<int>>();
const auto voidType = QMetaType::fromType<QFuture<void>>();
QVERIFY(QMetaType::canConvert(intType, voidType));
const int val = 42;
QFuture<int> f = QtFuture::makeReadyFuture(val);
auto variant = QVariant::fromValue(f);
QVERIFY(variant.convert(voidType));
const auto voidFuture = variant.value<QFuture<void>>();
QVERIFY(voidFuture.isValid());
QVERIFY(voidFuture.isFinished());
}
QTEST_MAIN(tst_QFuture)
#include "tst_qfuture.moc"