Forbid implicit conversions between QFuture and other types
- Remove the casting operator of QFuture<T> to T. It calls QFuture::result(), which may lead to undefined behavior if the user has moved the results from QFuture via QFuture::takeResult() before trying to do the conversion. - Disable implicit conversion of QFuture<T> to QFuture<void>, by making the constructor explicit. If the users really intend to do the conversion, they should do it explicitly. [ChangeLog][Source-Incompatible Changes][QFuture] Implicit conversions of QFuture<T> to T and to QFuture<void> have been disabled. Use QFuture::result() or QFuture::takeResult() where you need to convert QFuture<T> to T. Use the explicit QFuture<void>(const QFuture<T> &) constructor to convert QFuture<T> to QFuture<void>. Change-Id: I153d4137d36365b1611ac934fb3ac2eb667fdd6c Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
parent
48a13327c6
commit
ff0ba7e2d7
@ -157,7 +157,7 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
QElapsedTimer timer;
|
QElapsedTimer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
WordCount total = mappedReduced(files, countWords, reduce);
|
WordCount total = mappedReduced(files, countWords, reduce).result();
|
||||||
mapReduceTime = timer.elapsed();
|
mapReduceTime = timer.elapsed();
|
||||||
qDebug() << "MapReduce" << mapReduceTime;
|
qDebug() << "MapReduce" << mapReduceTime;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename V = T, typename = QtPrivate::EnableForVoid<V>>
|
template<typename U, typename V = T, typename = QtPrivate::EnableForVoid<V>>
|
||||||
QFuture(const QFuture<U> &other) : d(other.d)
|
explicit QFuture(const QFuture<U> &other) : d(other.d)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,9 +96,6 @@ public:
|
|||||||
~QFuture() { }
|
~QFuture() { }
|
||||||
QFuture(const QFuture<T> &) { }
|
QFuture(const QFuture<T> &) { }
|
||||||
QFuture<T> & operator=(const QFuture<T> &) { }
|
QFuture<T> & operator=(const QFuture<T> &) { }
|
||||||
|
|
||||||
// This is required to allow QDoc to find the declaration of operator T().
|
|
||||||
operator T() const;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void cancel() { d.cancel(); }
|
void cancel() { d.cancel(); }
|
||||||
@ -150,10 +147,6 @@ QT_WARNING_POP
|
|||||||
template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
|
template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
|
||||||
bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); }
|
bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); }
|
||||||
|
|
||||||
// operator T()
|
|
||||||
template<typename U = T>
|
|
||||||
operator typename std::enable_if_t<!std::is_same_v<U, void>, U>() const { return result(); }
|
|
||||||
|
|
||||||
template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
|
template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
|
||||||
QList<T> results() const { return d.results(); }
|
QList<T> results() const { return d.results(); }
|
||||||
|
|
||||||
|
@ -433,19 +433,6 @@
|
|||||||
\sa resultAt(), resultCount(), takeResult()
|
\sa resultAt(), resultCount(), takeResult()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \fn template <typename T> QFuture<T>::operator T() const
|
|
||||||
|
|
||||||
Returns the first result in the future. If the result is not immediately
|
|
||||||
available, this function will block and wait for the result to become
|
|
||||||
available. This is a convenience method for calling result() or
|
|
||||||
resultAt(0).
|
|
||||||
|
|
||||||
\note Calling this function leads to undefined behavior if isValid()
|
|
||||||
returns \c false for this QFuture.
|
|
||||||
|
|
||||||
\sa result(), resultAt(), results(), takeResult(), isValid()
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \fn template <typename T> QList<T> QFuture<T>::results() const
|
/*! \fn template <typename T> QList<T> QFuture<T>::results() const
|
||||||
|
|
||||||
Returns all results from the future. If the results are not immediately available,
|
Returns all results from the future. If the results are not immediately available,
|
||||||
|
@ -333,12 +333,12 @@ void testFilteredReduced(const QList<SourceObject> &sourceObjectList,
|
|||||||
ReduceObject reduceObject)
|
ReduceObject reduceObject)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::filteredReduced<ResultObject>(
|
const ResultObject result1 = QtConcurrent::filteredReduced<ResultObject>(
|
||||||
sourceObjectList, filterObject, reduceObject);
|
sourceObjectList, filterObject, reduceObject).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::filteredReduced<ResultObject>(
|
const ResultObject result2 = QtConcurrent::filteredReduced<ResultObject>(
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
||||||
filterObject, reduceObject);
|
filterObject, reduceObject).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
|
|
||||||
const ResultObject result3 = QtConcurrent::blockingFilteredReduced<ResultObject>(
|
const ResultObject result3 = QtConcurrent::blockingFilteredReduced<ResultObject>(
|
||||||
@ -362,12 +362,13 @@ void testFilteredReduced(const QList<SourceObject> &sourceObjectList,
|
|||||||
QtConcurrent::ReduceOptions options)
|
QtConcurrent::ReduceOptions options)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::filteredReduced(
|
const ResultObject result1 = QtConcurrent::filteredReduced(
|
||||||
sourceObjectList, filterObject, reduceObject, options);
|
sourceObjectList, filterObject, reduceObject, options).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::filteredReduced(
|
const ResultObject result2 =
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(), filterObject,
|
QtConcurrent::filteredReduced(sourceObjectList.constBegin(),
|
||||||
reduceObject, options);
|
sourceObjectList.constEnd(),
|
||||||
|
filterObject, reduceObject, options).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
|
|
||||||
const ResultObject result3 = QtConcurrent::blockingFilteredReduced(
|
const ResultObject result3 = QtConcurrent::blockingFilteredReduced(
|
||||||
@ -492,13 +493,14 @@ void testFilteredReducedThreadPool(QThreadPool *pool,
|
|||||||
ReduceObject reduceObject)
|
ReduceObject reduceObject)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::filteredReduced<ResultObject>(
|
const ResultObject result1 = QtConcurrent::filteredReduced<ResultObject>(
|
||||||
pool, sourceObjectList, filterObject, reduceObject);
|
pool, sourceObjectList, filterObject, reduceObject).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::filteredReduced<ResultObject>(
|
const ResultObject result2 =
|
||||||
pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
QtConcurrent::filteredReduced<ResultObject>(pool, sourceObjectList.constBegin(),
|
||||||
filterObject, reduceObject);
|
sourceObjectList.constEnd(), filterObject,
|
||||||
|
reduceObject).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
||||||
|
|
||||||
@ -640,12 +642,12 @@ void testFilteredReducedInitialValue(const QList<SourceObject> &sourceObjectList
|
|||||||
InitialObject &&initialObject)
|
InitialObject &&initialObject)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::filteredReduced<ResultObject>(
|
const ResultObject result1 = QtConcurrent::filteredReduced<ResultObject>(
|
||||||
sourceObjectList, filterObject, reduceObject, initialObject);
|
sourceObjectList, filterObject, reduceObject, initialObject).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::filteredReduced<ResultObject>(
|
const ResultObject result2 = QtConcurrent::filteredReduced<ResultObject>(
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
||||||
filterObject, reduceObject, initialObject);
|
filterObject, reduceObject, initialObject).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
|
|
||||||
const ResultObject result3 = QtConcurrent::blockingFilteredReduced<ResultObject>(
|
const ResultObject result3 = QtConcurrent::blockingFilteredReduced<ResultObject>(
|
||||||
@ -671,12 +673,13 @@ void testFilteredReducedInitialValue(const QList<SourceObject> &sourceObjectList
|
|||||||
QtConcurrent::ReduceOptions options)
|
QtConcurrent::ReduceOptions options)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::filteredReduced(
|
const ResultObject result1 = QtConcurrent::filteredReduced(
|
||||||
sourceObjectList, filterObject, reduceObject, initialObject, options);
|
sourceObjectList, filterObject, reduceObject, initialObject, options).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::filteredReduced(
|
const ResultObject result2 =
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
QtConcurrent::filteredReduced(sourceObjectList.constBegin(),
|
||||||
filterObject, reduceObject, initialObject, options);
|
sourceObjectList.constEnd(), filterObject, reduceObject,
|
||||||
|
initialObject, options).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
|
|
||||||
const ResultObject result3 = QtConcurrent::blockingFilteredReduced(
|
const ResultObject result3 = QtConcurrent::blockingFilteredReduced(
|
||||||
@ -810,13 +813,14 @@ void testFilteredReducedInitialValueThreadPool(QThreadPool *pool,
|
|||||||
InitialObject &&initialObject)
|
InitialObject &&initialObject)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::filteredReduced<ResultObject>(
|
const ResultObject result1 = QtConcurrent::filteredReduced<ResultObject>(
|
||||||
pool, sourceObjectList, filterObject, reduceObject, initialObject);
|
pool, sourceObjectList, filterObject, reduceObject, initialObject).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::filteredReduced<ResultObject>(
|
const ResultObject result2 =
|
||||||
pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
QtConcurrent::filteredReduced<ResultObject>(pool, sourceObjectList.constBegin(),
|
||||||
filterObject, reduceObject, initialObject);
|
sourceObjectList.constEnd(), filterObject,
|
||||||
|
reduceObject, initialObject).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
||||||
|
|
||||||
|
@ -674,11 +674,12 @@ template <typename SourceObject, typename ResultObject, typename MapObject, type
|
|||||||
void testMappedReduced(const QList<SourceObject> &sourceObjectList, const ResultObject &expectedResult, MapObject mapObject, ReduceObject reduceObject)
|
void testMappedReduced(const QList<SourceObject> &sourceObjectList, const ResultObject &expectedResult, MapObject mapObject, ReduceObject reduceObject)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::mappedReduced<ResultObject>(
|
const ResultObject result1 = QtConcurrent::mappedReduced<ResultObject>(
|
||||||
sourceObjectList, mapObject, reduceObject);
|
sourceObjectList, mapObject, reduceObject).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::mappedReduced<ResultObject>(
|
const ResultObject result2 = QtConcurrent::mappedReduced<ResultObject>(
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject, reduceObject);
|
sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
||||||
|
mapObject, reduceObject).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
|
|
||||||
const ResultObject result3 = QtConcurrent::blockingMappedReduced<ResultObject>(
|
const ResultObject result3 = QtConcurrent::blockingMappedReduced<ResultObject>(
|
||||||
@ -694,11 +695,12 @@ template <typename SourceObject, typename ResultObject, typename MapObject, type
|
|||||||
void testMappedReduced(const QList<SourceObject> &sourceObjectList, const ResultObject &expectedResult, MapObject mapObject, ReduceObject reduceObject, QtConcurrent::ReduceOptions options)
|
void testMappedReduced(const QList<SourceObject> &sourceObjectList, const ResultObject &expectedResult, MapObject mapObject, ReduceObject reduceObject, QtConcurrent::ReduceOptions options)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::mappedReduced(
|
const ResultObject result1 = QtConcurrent::mappedReduced(
|
||||||
sourceObjectList, mapObject, reduceObject, options);
|
sourceObjectList, mapObject, reduceObject, options).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::mappedReduced(
|
const ResultObject result2 =
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject, reduceObject, options);
|
QtConcurrent::mappedReduced(sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
||||||
|
mapObject, reduceObject, options).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
|
|
||||||
const ResultObject result3 = QtConcurrent::blockingMappedReduced(
|
const ResultObject result3 = QtConcurrent::blockingMappedReduced(
|
||||||
@ -796,13 +798,15 @@ void testMappedReducedThreadPool(QThreadPool *pool,
|
|||||||
MapObject mapObject,
|
MapObject mapObject,
|
||||||
ReduceObject reduceObject)
|
ReduceObject reduceObject)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::mappedReduced<ResultObject>(pool,
|
const ResultObject result1 = QtConcurrent::mappedReduced<ResultObject>(
|
||||||
sourceObjectList, mapObject, reduceObject);
|
pool, sourceObjectList, mapObject, reduceObject).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::mappedReduced<ResultObject>(pool,
|
const ResultObject result2 =
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject, reduceObject);
|
QtConcurrent::mappedReduced<ResultObject>(pool, sourceObjectList.constBegin(),
|
||||||
|
sourceObjectList.constEnd(), mapObject,
|
||||||
|
reduceObject).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
||||||
|
|
||||||
@ -954,12 +958,14 @@ void testMappedReducedInitialValue(const QList<SourceObject> &sourceObjectList,
|
|||||||
ReduceObject reduceObject,
|
ReduceObject reduceObject,
|
||||||
InitialObject &&initialObject)
|
InitialObject &&initialObject)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::mappedReduced<ResultObject>(
|
const ResultObject result1 =
|
||||||
sourceObjectList, mapObject, reduceObject, initialObject);
|
QtConcurrent::mappedReduced<ResultObject>(sourceObjectList, mapObject, reduceObject,
|
||||||
|
initialObject).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::mappedReduced<ResultObject>(
|
const ResultObject result2 = QtConcurrent::mappedReduced<ResultObject>(
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject, reduceObject, initialObject);
|
sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
||||||
|
mapObject, reduceObject, initialObject).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
|
|
||||||
const ResultObject result3 = QtConcurrent::blockingMappedReduced<ResultObject>(
|
const ResultObject result3 = QtConcurrent::blockingMappedReduced<ResultObject>(
|
||||||
@ -980,11 +986,12 @@ void testMappedReducedInitialValue(const QList<SourceObject> &sourceObjectList,
|
|||||||
QtConcurrent::ReduceOptions options)
|
QtConcurrent::ReduceOptions options)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::mappedReduced(
|
const ResultObject result1 = QtConcurrent::mappedReduced(
|
||||||
sourceObjectList, mapObject, reduceObject, initialObject, options);
|
sourceObjectList, mapObject, reduceObject, initialObject, options).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::mappedReduced(
|
const ResultObject result2 =
|
||||||
sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject, reduceObject, initialObject, options);
|
QtConcurrent::mappedReduced(sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
||||||
|
mapObject, reduceObject, initialObject, options).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
|
|
||||||
const ResultObject result3 = QtConcurrent::blockingMappedReduced(
|
const ResultObject result3 = QtConcurrent::blockingMappedReduced(
|
||||||
@ -1090,13 +1097,14 @@ void testMappedReducedInitialValueThreadPool(QThreadPool *pool,
|
|||||||
InitialObject &&initialObject)
|
InitialObject &&initialObject)
|
||||||
{
|
{
|
||||||
const ResultObject result1 = QtConcurrent::mappedReduced<ResultObject>(
|
const ResultObject result1 = QtConcurrent::mappedReduced<ResultObject>(
|
||||||
pool, sourceObjectList, mapObject, reduceObject, initialObject);
|
pool, sourceObjectList, mapObject, reduceObject, initialObject).result();
|
||||||
QCOMPARE(result1, expectedResult);
|
QCOMPARE(result1, expectedResult);
|
||||||
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
||||||
|
|
||||||
const ResultObject result2 = QtConcurrent::mappedReduced<ResultObject>(
|
const ResultObject result2 =
|
||||||
pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(),
|
QtConcurrent::mappedReduced<ResultObject>(pool, sourceObjectList.constBegin(),
|
||||||
mapObject, reduceObject, initialObject);
|
sourceObjectList.constEnd(), mapObject,
|
||||||
|
reduceObject, initialObject).result();
|
||||||
QCOMPARE(result2, expectedResult);
|
QCOMPARE(result2, expectedResult);
|
||||||
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
QCOMPARE(threadCount(), 1); // ensure the only one thread was working
|
||||||
|
|
||||||
|
@ -127,14 +127,14 @@ void tst_QtConcurrentRun::runLightFunction()
|
|||||||
|
|
||||||
void (*f3)(QPromise<int> &) = lightOverloaded;
|
void (*f3)(QPromise<int> &) = lightOverloaded;
|
||||||
qDebug("starting function with promise");
|
qDebug("starting function with promise");
|
||||||
QFuture<void> future3 = run(f3);
|
QFuture<int> future3 = run(f3);
|
||||||
qDebug("waiting");
|
qDebug("waiting");
|
||||||
future3.waitForFinished();
|
future3.waitForFinished();
|
||||||
qDebug("done");
|
qDebug("done");
|
||||||
|
|
||||||
void (*f4)(QPromise<double> &, int v) = lightOverloaded;
|
void (*f4)(QPromise<double> &, int v) = lightOverloaded;
|
||||||
qDebug("starting function with promise and with arg");
|
qDebug("starting function with promise and with arg");
|
||||||
QFuture<void> future4 = run(f4, 2);
|
QFuture<double> future4 = run(f4, 2);
|
||||||
qDebug("waiting");
|
qDebug("waiting");
|
||||||
future4.waitForFinished();
|
future4.waitForFinished();
|
||||||
qDebug("done");
|
qDebug("done");
|
||||||
|
@ -249,7 +249,7 @@ void tst_QLockFile::waitForLock()
|
|||||||
if (!releaseEarly) // only let the thread release the lock now
|
if (!releaseEarly) // only let the thread release the lock now
|
||||||
semMainThreadDone.release();
|
semMainThreadDone.release();
|
||||||
|
|
||||||
QVERIFY(ret); // waits for the thread to finish
|
QVERIFY(ret.result()); // waits for the thread to finish
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QLockFile::staleLockFromCrashedProcess_data()
|
void tst_QLockFile::staleLockFromCrashedProcess_data()
|
||||||
|
@ -99,6 +99,7 @@ class tst_QFuture: public QObject
|
|||||||
private slots:
|
private slots:
|
||||||
void resultStore();
|
void resultStore();
|
||||||
void future();
|
void future();
|
||||||
|
void futureToVoid();
|
||||||
void futureInterface();
|
void futureInterface();
|
||||||
void refcounting();
|
void refcounting();
|
||||||
void cancel();
|
void cancel();
|
||||||
@ -109,7 +110,6 @@ private slots:
|
|||||||
void progressText();
|
void progressText();
|
||||||
void resultsAfterFinished();
|
void resultsAfterFinished();
|
||||||
void resultsAsList();
|
void resultsAsList();
|
||||||
void implicitConversions();
|
|
||||||
void iterators();
|
void iterators();
|
||||||
void iteratorsThread();
|
void iteratorsThread();
|
||||||
#if QT_DEPRECATED_SINCE(6, 0)
|
#if QT_DEPRECATED_SINCE(6, 0)
|
||||||
@ -609,6 +609,19 @@ void tst_QFuture::future()
|
|||||||
QCOMPARE(intFuture2.isFinished(), true);
|
QCOMPARE(intFuture2.isFinished(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QFuture::futureToVoid()
|
||||||
|
{
|
||||||
|
QPromise<int> p;
|
||||||
|
QFuture<int> future = p.future();
|
||||||
|
|
||||||
|
p.start();
|
||||||
|
p.setProgressValue(42);
|
||||||
|
p.finish();
|
||||||
|
|
||||||
|
QFuture<void> voidFuture = QFuture<void>(future);
|
||||||
|
QCOMPARE(voidFuture.progressValue(), 42);
|
||||||
|
}
|
||||||
|
|
||||||
class IntResult : public QFutureInterface<int>
|
class IntResult : public QFutureInterface<int>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -1067,25 +1080,6 @@ void tst_QFuture::resultsAsList()
|
|||||||
QCOMPARE(results, QList<int>() << 1 << 2);
|
QCOMPARE(results, QList<int>() << 1 << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Test that QFuture<T> can be implicitly converted to T
|
|
||||||
*/
|
|
||||||
void tst_QFuture::implicitConversions()
|
|
||||||
{
|
|
||||||
QFutureInterface<QString> iface;
|
|
||||||
iface.reportStarted();
|
|
||||||
|
|
||||||
QFuture<QString> f(&iface);
|
|
||||||
|
|
||||||
const QString input("FooBar 2000");
|
|
||||||
iface.reportFinished(&input);
|
|
||||||
|
|
||||||
const QString result = f;
|
|
||||||
QCOMPARE(result, input);
|
|
||||||
QCOMPARE(QString(f), input);
|
|
||||||
QCOMPARE(static_cast<QString>(f), input);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QFuture::iterators()
|
void tst_QFuture::iterators()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -864,7 +864,7 @@ void tst_QFutureWatcher::suspendEvents()
|
|||||||
|
|
||||||
void tst_QFutureWatcher::suspended()
|
void tst_QFutureWatcher::suspended()
|
||||||
{
|
{
|
||||||
QFutureWatcher<void> watcher;
|
QFutureWatcher<int> watcher;
|
||||||
QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
|
QSignalSpy resultReadySpy(&watcher, &QFutureWatcher<int>::resultReadyAt);
|
||||||
#if QT_DEPRECATED_SINCE(6, 0)
|
#if QT_DEPRECATED_SINCE(6, 0)
|
||||||
QT_WARNING_PUSH
|
QT_WARNING_PUSH
|
||||||
|
Loading…
x
Reference in New Issue
Block a user