diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp index 60d276cde6f..bf39119c517 100644 --- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp +++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp @@ -147,7 +147,7 @@ QtConcurrent::run(&o, 42).waitForFinished(); // compilation error //! [9] extern void aFunction(QPromise &promise); -QFuture future = QtConcurrent::runWithPromise(aFunction); +QFuture future = QtConcurrent::run(aFunction); //! [9] //! [10] @@ -156,7 +156,7 @@ extern void aFunction(QPromise &promise, int arg1, const QString &arg2); int integer = ...; QString string = ...; -QFuture future = QtConcurrent::runWithPromise(aFunction, integer, string); +QFuture future = QtConcurrent::run(aFunction, integer, string); //! [10] //! [11] @@ -166,7 +166,7 @@ void helloWorldFunction(QPromise &promise) promise.addResult("world"); } -QFuture future = QtConcurrent::runWithPromise(helloWorldFunction); +QFuture future = QtConcurrent::run(helloWorldFunction); ... QList results = future.results(); //! [11] @@ -185,7 +185,7 @@ void aFunction(QPromise &promise) } } -QFuture future = QtConcurrent::runWithPromise(aFunction); +QFuture future = QtConcurrent::run(aFunction); ... // user pressed a pause button after 10 seconds future.suspend(); @@ -216,7 +216,7 @@ QObject::connect(&watcher, &QFutureWatcher::progressValueChanged, [](int progres ... ; // update GUI with a progress qDebug() << "current progress:" << progress; }); -watcher.setFuture(QtConcurrent::runWithPromise(aFunction)); +watcher.setFuture(QtConcurrent::run(aFunction)); //! [13] //! [14] @@ -226,7 +226,7 @@ struct Functor { }; Functor f; -runWithPromise(f); // this will select the 2nd overload -// runWithPromise(f); // error, both candidate overloads potentially match +run(f); // this will select the 2nd overload +// run(f); // error, both candidate overloads potentially match //! [14] diff --git a/src/concurrent/doc/src/qtconcurrent-index.qdoc b/src/concurrent/doc/src/qtconcurrent-index.qdoc index f9b6375b4eb..8507d77f9d6 100644 --- a/src/concurrent/doc/src/qtconcurrent-index.qdoc +++ b/src/concurrent/doc/src/qtconcurrent-index.qdoc @@ -81,15 +81,10 @@ folded into a single result. \endlist - \li \l {Concurrent Run and Run With Promise} + \li \l {Concurrent Run} \list \li \l {QtConcurrent::run}{QtConcurrent::run()} runs a function in another thread. - \li \l {QtConcurrent::runWithPromise}{QtConcurrent::runWithPromise()} - is like run(), except that the function to run accepts additional - argument of QPromise type that enables more control over the function - execution, like suspending or canceling the execution when requested, - progress reporting or reporting multiple results. \endlist \li \l {Concurrent Task} diff --git a/src/concurrent/qtconcurrentrun.cpp b/src/concurrent/qtconcurrentrun.cpp index fecbb484ff9..978bc8cd8dc 100644 --- a/src/concurrent/qtconcurrentrun.cpp +++ b/src/concurrent/qtconcurrentrun.cpp @@ -39,22 +39,25 @@ /*! \page qtconcurrentrun.html - \title Concurrent Run and Run With Promise + \title Concurrent Run \ingroup thread - The QtConcurrent::run() and QtConcurrent::runWithPromise() - functions run a function in a separate thread. + The QtConcurrent::run() function runs a function in a separate thread. The return value of the function is made available through the QFuture API. - The function passed to QtConcurrent::run() is able to report merely - a single computation result to its caller, while the function passed to - QtConcurrent::runWithPromise() can make use of the additional + + QtConcurrent::run() is an overloaded method. You can think of these overloads as slightly + different \e modes. + In \l {Concurrent Run (basic mode)} {basic mode}, the function passed to QtConcurrent::run() + is able to report merely a single computation result to its caller. + In \l {Concurrent Run With Promise} {run with promise mode}, the function passed to + QtConcurrent::run() can make use of the additional QPromise API, which enables multiple result reporting, progress reporting, suspending the computation when requested by the caller, or stopping the computation on the caller's demand. - These functions are part of the Qt Concurrent framework. + This function is a part of the Qt Concurrent framework. - \section1 Concurrent Run + \section1 Concurrent Run (basic mode) The function passed to QtConcurrent::run() may report the result through its return value. @@ -65,7 +68,7 @@ \snippet code/src_concurrent_qtconcurrentrun.cpp 0 - This will run \e aFunction in a separate thread obtained from the default + This will run \c aFunction in a separate thread obtained from the default QThreadPool. You can use the QFuture and QFutureWatcher classes to monitor the status of the function. @@ -135,8 +138,8 @@ \section1 Concurrent Run With Promise - The QtConcurrent::runWithPromise() enables more control - for the running task comparing to QtConcurrent::run(). + The \e {Run With Promise} mode enables more control for the running + task compared to \e basic mode of QtConcurrent::run(). It allows progress reporting of the running task, reporting multiple results, suspending the execution if it was requested, or canceling the task on caller's @@ -144,16 +147,16 @@ \section2 The mandatory QPromise argument - The function passed to QtConcurrent::runWithPromise() is expected - to have an additional argument of \e {QPromise &} type, where + The function passed to QtConcurrent::run() in \e {Run With Promise} mode is expected + to have an additional argument of \c {QPromise &} type, where T is the type of the computation result (it should match the type T of QFuture returned by the QtConcurrent::runWithPromise()), like e.g.: \snippet code/src_concurrent_qtconcurrentrun.cpp 9 - The \e promise argument is instantiated inside the - QtConcurrent::runWithPromise() function, and its reference - is passed to the invoked \e aFunction, so the user + The \c promise argument is instantiated inside the + QtConcurrent::run() function, and its reference + is passed to the invoked \c aFunction, so the user doesn't need to instantiate it by himself, nor pass it explicitly when calling QtConcurrent::runWithPromise(). @@ -164,8 +167,8 @@ \section2 Reporting results - In contrast to QtConcurrent::run(), the function passed to - QtConcurrent::runWithPromise() is expected to always return void type. + In contrast to \e basic mode of QtConcurrent::run(), the function passed to + QtConcurrent::run() in \e {Run With Promise} mode is expected to always return void type. Result reporting is done through the additional argument of QPromise type. It also enables multiple result reporting, like: @@ -177,20 +180,20 @@ \snippet code/src_concurrent_qtconcurrentrun.cpp 12 - The call to \e future.suspend() requests the running task to + The call to \c future.suspend() requests the running task to hold its execution. After calling this method, the running task - will suspend after the next call to \e promise.suspendIfRequested() + will suspend after the next call to \c promise.suspendIfRequested() in its iteration loop. In this case the running task will - block on a call to \e promise.suspendIfRequested(). The blocked - call will unblock after the \e future.resume() is called. + block on a call to \c promise.suspendIfRequested(). The blocked + call will unblock after the \c future.resume() is called. Note, that internally suspendIfRequested() uses wait condition in order to unblock, so the running thread goes into an idle state instead of wasting its resources when blocked in order to periodically check if the resume request came from the caller's thread. - The call to \e future.cancel() from the last line causes that the next - call to \e promise.isCanceled() will return \c true and - \e aFunction will return immediately without any further result reporting. + The call to \c future.cancel() from the last line causes that the next + call to \c promise.isCanceled() will return \c true and + \c aFunction will return immediately without any further result reporting. \section2 Progress reporting @@ -199,17 +202,17 @@ \snippet code/src_concurrent_qtconcurrentrun.cpp 13 - The caller installs the \e QFutureWatcher for the \e QFuture - returned by QtConcurrent::runWithPromise() in order to - connect to its \e progressValueChanged() signal and update + The caller installs the \c QFutureWatcher for the \c QFuture + returned by QtConcurrent::run() in order to + connect to its \c progressValueChanged() signal and update e.g. the graphical user interface accordingly. \section2 Invoking functions with overloaded operator()() - By default, QtConcurrent::runWithPromise() doesn't support functors with - overloaded operator()(). In case of overloaded functors the user - needs to explicitly specify the result type - as a template parameter passed to runWithPromise, like: + By default, QtConcurrent::run() doesn't support functors with + overloaded operator()() in \e {Run With Promise} mode. In case of overloaded + functors the user needs to explicitly specify the result type + as a template parameter passed to QtConcurrent::run(), like: \snippet code/src_concurrent_qtconcurrentrun.cpp 14 */ @@ -235,15 +238,28 @@ QThreadPool. Note that \a function may not run immediately; \a function will only be run once a thread becomes available. - T is the same type as the return value of \a function. Non-void return - values can be accessed via the QFuture::result() function. +//! [run-description] + In \l {Concurrent Run (basic mode)} {basic mode} T is the same type as the return value + of \a function. Non-void return values can be accessed via the QFuture::result() function. - \note The QFuture returned can only be used to query for the - running/finished status and the return value of the function. In particular, + In \l {Concurrent Run (basic mode)} {basic mode} the QFuture returned can only be used to + query for the running/finished status and the return value of the function. In particular, canceling or pausing can be issued only if the computations behind the future has not been started. - \sa {Concurrent Run} + In \l {Concurrent Run With Promise} {run with promise mode}, the \a function is expected + to return void and must take an additional argument of \c {QPromise &} type, + placed as a first argument in function's argument list. T is the result type + and it is the same for the returned \c QFuture. + + In \l {Concurrent Run With Promise} {run with promise mode}, similar to \e basic mode, the + QFuture returned can be used to query for the running/finished status and the value reported + by the function. In addition, it may be used for suspending or canceling the + running task, fetching multiple results from the called \a function or + monitoring progress reported by the \a function. + + \sa {Concurrent Run (basic mode)}, {Concurrent Run With Promise} +//! [run-description] */ /*! @@ -254,62 +270,6 @@ QThreadPool \a pool. Note that \a function may not run immediately; \a function will only be run once a thread becomes available. - T is the same type as the return value of \a function. Non-void return - values can be accessed via the QFuture::result() function. - - \note The QFuture returned can only be used to query for the - running/finished status and the return value of the function. In particular, - canceling or pausing can be issued only if the computations behind the future - has not been started. - - \sa {Concurrent Run} + \include qtconcurrentrun.cpp run-description */ -/*! - \since 6.0 - \fn QFuture QtConcurrent::runWithPromise(Function function, ...); - - Equivalent to - \code - QtConcurrent::runWithPromise(QThreadPool::globalInstance(), function, ...); - \endcode - - Runs \a function in a separate thread. The thread is taken from the global - QThreadPool. Note that \a function may not run immediately; \a function - will only be run once a thread becomes available. - - The \a function is expected to return void - and must take an additional argument of \e {QPromise &} type, - placed as a first argument in function's argument list. T is the result type - and it is the same for the returned \e QFuture. - - Similar to QtConcurrent::run(), the QFuture returned can be used to query for the - running/finished status and the value reported by the function. In addition, - it may be used for suspending or canceling the running task, fetching - multiple results from the called /a function or monitoring progress - reported by the \a function. - - \sa {Concurrent Run With Promise} -*/ - -/*! - \since 6.0 - \fn QFuture QtConcurrent::runWithPromise(QThreadPool *pool, Function function, ...); - - Runs \a function in a separate thread. The thread is taken from the - QThreadPool \a pool. Note that \a function may not run immediately; \a function - will only be run once a thread becomes available. - - The \a function is expected to return void - and must take an additional argument of \e {QPromise &} type, - placed as a first argument in function's argument list. T is the result type - and it is the same for the returned \e QFuture. - - Similar to QtConcurrent::run(), the QFuture returned can be used to query for the - running/finished status and the value reported by the function. In addition, - it may be used for suspending or canceling the running task, fetching - multiple results from the called /a function or monitoring progress - reported by the \a function. - - \sa {Concurrent Run With Promise} -*/ diff --git a/src/concurrent/qtconcurrentrun.h b/src/concurrent/qtconcurrentrun.h index 79322b925fe..4ce8d6ae05e 100644 --- a/src/concurrent/qtconcurrentrun.h +++ b/src/concurrent/qtconcurrentrun.h @@ -77,55 +77,45 @@ template [[nodiscard]] auto run(QThreadPool *pool, Function &&f, Args &&...args) { - return (new StoredFunctionCall( - std::forward(f), std::forward(args)...))->start(pool); + DecayedTuple tuple { std::forward(f), + std::forward(args)... }; + return TaskResolver, std::decay_t...>::run( + std::move(tuple), TaskStartParameters { pool }); +} + +template +[[nodiscard]] +auto run(QThreadPool *pool, std::reference_wrapper &&functionWrapper, + Args &&...args) +{ + return run(pool, std::forward(functionWrapper.get()), + std::forward(args)...); } template [[nodiscard]] auto run(Function &&f, Args &&...args) { - return run(QThreadPool::globalInstance(), std::forward(f), std::forward(args)...); + return run(QThreadPool::globalInstance(), std::forward(f), + std::forward(args)...); } +// overload with a Promise Type hint, takes thread pool template [[nodiscard]] -auto runWithPromise(QThreadPool *pool, Function &&f, Args &&...args) +auto run(QThreadPool *pool, Function &&f, Args &&...args) { return (new StoredFunctionCallWithPromise( std::forward(f), std::forward(args)...))->start(pool); } -template -[[nodiscard]] -auto runWithPromise(QThreadPool *pool, Function &&f, Args &&...args) -{ - static_assert(QtPrivate::ArgResolver::IsPromise, "The first argument of passed callable object isn't a QPromise & type."); - using PromiseType = typename QtPrivate::ArgResolver::PromiseType; - return runWithPromise(pool, std::forward(f), std::forward(args)...); -} - -template -[[nodiscard]] -auto runWithPromise(QThreadPool *pool, std::reference_wrapper &&functionWrapper, Args &&...args) -{ - static_assert(QtPrivate::ArgResolver::IsPromise, "The first argument of passed callable object isn't a QPromise & type."); - using PromiseType = typename QtPrivate::ArgResolver::PromiseType; - return runWithPromise(pool, std::forward(functionWrapper.get()), std::forward(args)...); -} - +// overload with a Promise Type hint, uses global thread pool template [[nodiscard]] -auto runWithPromise(Function &&f, Args &&...args) +auto run(Function &&f, Args &&...args) { - return runWithPromise(QThreadPool::globalInstance(), std::forward(f), std::forward(args)...); -} - -template -[[nodiscard]] -auto runWithPromise(Function &&f, Args &&...args) -{ - return runWithPromise(QThreadPool::globalInstance(), std::forward(f), std::forward(args)...); + return run(QThreadPool::globalInstance(), std::forward(f), + std::forward(args)...); } } //namespace QtConcurrent diff --git a/src/concurrent/qtconcurrentstoredfunctioncall.h b/src/concurrent/qtconcurrentstoredfunctioncall.h index 1257d70b829..f52b6e2efc0 100644 --- a/src/concurrent/qtconcurrentstoredfunctioncall.h +++ b/src/concurrent/qtconcurrentstoredfunctioncall.h @@ -102,17 +102,21 @@ template struct FunctionResolverHelper; template -struct FunctionResolverHelper : public NonMemberFunctionResolver +struct FunctionResolverHelper + : public NonMemberFunctionResolver { }; template -struct FunctionResolverHelper : public MemberFunctionResolver +struct FunctionResolverHelper + : public MemberFunctionResolver { }; template -struct FunctionResolver : public FunctionResolverHelper>::type, Function, PromiseType, Args...> +struct FunctionResolver + : public FunctionResolverHelper>::type, Function, PromiseType, Args...> { }; @@ -134,10 +138,6 @@ using DecayedTuple = std::tuple...>; template struct StoredFunctionCall : public RunFunctionTask> { - StoredFunctionCall(Function &&f, Args &&...args) - : data{std::forward(f), std::forward(args)...} - {} - StoredFunctionCall(DecayedTuple &&_data) : data(std::move(_data)) {} @@ -165,11 +165,13 @@ struct StoredFunctionCallWithPromise : public RunFunctionTaskBase using DataType = typename Resolver::Type; StoredFunctionCallWithPromise(Function &&f, Args &&...args) : prom(this->promise), - data(std::move(Resolver::initData(std::forward(f), std::ref(prom), std::forward(args)...))) + data(std::move(Resolver::initData(std::forward(f), std::ref(prom), + std::forward(args)...))) {} - StoredFunctionCallWithPromise(DataType &&_data) - : data(std::move(_data)) + StoredFunctionCallWithPromise(DecayedTuple &&_data) + : StoredFunctionCallWithPromise(std::move(_data), + std::index_sequence_for, std::decay_t...>()) {} protected: @@ -179,10 +181,69 @@ protected: } private: + // helper to pack back the tuple into parameter pack + template + StoredFunctionCallWithPromise(DecayedTuple &&_data, + std::index_sequence) + : StoredFunctionCallWithPromise(std::move(std::get(_data))...) + {} + QPromise prom; DataType data; }; +template +struct NonPromiseTaskResolver; + +template +struct NonPromiseTaskResolver +{ + using TaskWithArgs = DecayedTuple; + static auto run(TaskWithArgs &&args, const TaskStartParameters &startParameters) { + return (new StoredFunctionCall(std::move(args))) + ->start(startParameters); + } +}; + +template +struct PromiseTaskResolver; + +template +struct PromiseTaskResolver +{ + static_assert(QtPrivate::ArgResolver::IsPromise::value, + "The first argument of passed callable object isn't a QPromise & type. " + "Did you intend to pass a callable which takes a QPromise & type as a first argument? " + "Otherwise it's not possible to invoke the function with passed arguments."); + using TaskWithArgs = DecayedTuple; + static auto run(TaskWithArgs &&args, const TaskStartParameters &startParameters) { + using PromiseType = typename QtPrivate::ArgResolver::PromiseType; + return (new StoredFunctionCallWithPromise(std::move(args))) + ->start(startParameters); + } +}; + +template +struct TaskResolverHelper; + +template +struct TaskResolverHelper + : public NonPromiseTaskResolver +{ +}; + +template +struct TaskResolverHelper + : public PromiseTaskResolver +{ +}; + +template +struct TaskResolver : public TaskResolverHelper, + std::decay_t...>::type, Function, Args...> +{ +}; + } //namespace QtConcurrent #endif // Q_QDOC diff --git a/src/corelib/thread/qfuture_impl.h b/src/corelib/thread/qfuture_impl.h index bd3976f9909..b8b9f399512 100644 --- a/src/corelib/thread/qfuture_impl.h +++ b/src/corelib/thread/qfuture_impl.h @@ -124,7 +124,7 @@ struct ArgsType { using First = Arg; using PromiseType = void; - static const bool IsPromise = false; + using IsPromise = std::false_type; static const bool HasExtraArgs = (sizeof...(Args) > 0); using AllArgs = std::conditional_t, std::decay_t...>, @@ -139,7 +139,7 @@ struct ArgsType &, Args...> { using First = QPromise &; using PromiseType = Arg; - static const bool IsPromise = true; + using IsPromise = std::true_type; static const bool HasExtraArgs = (sizeof...(Args) > 0); using AllArgs = std::conditional_t &>, std::decay_t...>, @@ -154,7 +154,7 @@ struct ArgsType<> { using First = void; using PromiseType = void; - static const bool IsPromise = false; + using IsPromise = std::false_type; static const bool HasExtraArgs = false; using AllArgs = void; diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index ae1edb54a5f..1132954a821 100644 --- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -57,6 +57,7 @@ private slots: void withPromiseInThreadPool(); void moveOnlyType(); void crefFunction(); + void customPromise(); }; void light() @@ -122,14 +123,14 @@ void tst_QtConcurrentRun::runLightFunction() void (*f3)(QPromise &) = lightOverloaded; qDebug("starting function with promise"); - QFuture future3 = runWithPromise(f3); + QFuture future3 = run(f3); qDebug("waiting"); future3.waitForFinished(); qDebug("done"); void (*f4)(QPromise &, int v) = lightOverloaded; qDebug("starting function with promise and with arg"); - QFuture future4 = runWithPromise(f4, 2); + QFuture future4 = run(f4, 2); qDebug("waiting"); future4.waitForFinished(); qDebug("done"); @@ -429,141 +430,141 @@ void tst_QtConcurrentRun::reportValueWithPromise() QThreadPool pool; QFuture f; - f = runWithPromise(reportInt0); + f = run(reportInt0); QCOMPARE(f.result(), 0); - f = runWithPromise(&pool, reportInt0); + f = run(&pool, reportInt0); QCOMPARE(f.result(), 0); - f = runWithPromise(reportIntPlusOne, 5); + f = run(reportIntPlusOne, 5); QCOMPARE(f.result(), 6); - f = runWithPromise(&pool, reportIntPlusOne, 5); + f = run(&pool, reportIntPlusOne, 5); QCOMPARE(f.result(), 6); AWithPromise a; - f = runWithPromise(&AWithPromise::member0, &a); + f = run(&AWithPromise::member0, &a); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, &AWithPromise::member0, &a); + f = run(&pool, &AWithPromise::member0, &a); QCOMPARE(f.result(), 10); - f = runWithPromise(&AWithPromise::member1, &a, 20); + f = run(&AWithPromise::member1, &a, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&pool, &AWithPromise::member1, &a, 20); + f = run(&pool, &AWithPromise::member1, &a, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&AWithPromise::member0, a); + f = run(&AWithPromise::member0, a); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, &AWithPromise::member0, a); + f = run(&pool, &AWithPromise::member0, a); QCOMPARE(f.result(), 10); - f = runWithPromise(&AWithPromise::member1, a, 20); + f = run(&AWithPromise::member1, a, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&pool, &AWithPromise::member1, a, 20); + f = run(&pool, &AWithPromise::member1, a, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(a); + f = run(a); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, a); + f = run(&pool, a); QCOMPARE(f.result(), 10); - f = runWithPromise(std::ref(a)); + f = run(std::ref(a)); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, std::ref(a)); + f = run(&pool, std::ref(a)); QCOMPARE(f.result(), 10); const AConstWithPromise aConst = AConstWithPromise(); - f = runWithPromise(&AConstWithPromise::member0, &aConst); + f = run(&AConstWithPromise::member0, &aConst); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, &AConstWithPromise::member0, &aConst); + f = run(&pool, &AConstWithPromise::member0, &aConst); QCOMPARE(f.result(), 10); - f = runWithPromise(&AConstWithPromise::member1, &aConst, 20); + f = run(&AConstWithPromise::member1, &aConst, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&pool, &AConstWithPromise::member1, &aConst, 20); + f = run(&pool, &AConstWithPromise::member1, &aConst, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&AConstWithPromise::member0, aConst); + f = run(&AConstWithPromise::member0, aConst); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, &AConstWithPromise::member0, aConst); + f = run(&pool, &AConstWithPromise::member0, aConst); QCOMPARE(f.result(), 10); - f = runWithPromise(&AConstWithPromise::member1, aConst, 20); + f = run(&AConstWithPromise::member1, aConst, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&pool, &AConstWithPromise::member1, aConst, 20); + f = run(&pool, &AConstWithPromise::member1, aConst, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(aConst); + f = run(aConst); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, aConst); + f = run(&pool, aConst); QCOMPARE(f.result(), 10); - f = runWithPromise(std::ref(a)); + f = run(std::ref(a)); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, std::ref(a)); + f = run(&pool, std::ref(a)); QCOMPARE(f.result(), 10); ANoExceptWithPromise aNoExcept; - f = runWithPromise(&ANoExceptWithPromise::member0, &aNoExcept); + f = run(&ANoExceptWithPromise::member0, &aNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, &ANoExceptWithPromise::member0, &aNoExcept); + f = run(&pool, &ANoExceptWithPromise::member0, &aNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&ANoExceptWithPromise::member1, &aNoExcept, 20); + f = run(&ANoExceptWithPromise::member1, &aNoExcept, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&pool, &ANoExceptWithPromise::member1, &aNoExcept, 20); + f = run(&pool, &ANoExceptWithPromise::member1, &aNoExcept, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&ANoExceptWithPromise::member0, aNoExcept); + f = run(&ANoExceptWithPromise::member0, aNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, &ANoExceptWithPromise::member0, aNoExcept); + f = run(&pool, &ANoExceptWithPromise::member0, aNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&ANoExceptWithPromise::member1, aNoExcept, 20); + f = run(&ANoExceptWithPromise::member1, aNoExcept, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&pool, &ANoExceptWithPromise::member1, aNoExcept, 20); + f = run(&pool, &ANoExceptWithPromise::member1, aNoExcept, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(aNoExcept); + f = run(aNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, aNoExcept); + f = run(&pool, aNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(std::ref(aNoExcept)); + f = run(std::ref(aNoExcept)); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, std::ref(aNoExcept)); + f = run(&pool, std::ref(aNoExcept)); QCOMPARE(f.result(), 10); const AConstNoExceptWithPromise aConstNoExcept = AConstNoExceptWithPromise(); - f = runWithPromise(&AConstNoExceptWithPromise::member0, &aConstNoExcept); + f = run(&AConstNoExceptWithPromise::member0, &aConstNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, &AConstNoExceptWithPromise::member0, &aConstNoExcept); + f = run(&pool, &AConstNoExceptWithPromise::member0, &aConstNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&AConstNoExceptWithPromise::member1, &aConstNoExcept, 20); + f = run(&AConstNoExceptWithPromise::member1, &aConstNoExcept, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&pool, &AConstNoExceptWithPromise::member1, &aConstNoExcept, 20); + f = run(&pool, &AConstNoExceptWithPromise::member1, &aConstNoExcept, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&AConstNoExceptWithPromise::member0, aConstNoExcept); + f = run(&AConstNoExceptWithPromise::member0, aConstNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, &AConstNoExceptWithPromise::member0, aConstNoExcept); + f = run(&pool, &AConstNoExceptWithPromise::member0, aConstNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&AConstNoExceptWithPromise::member1, aConstNoExcept, 20); + f = run(&AConstNoExceptWithPromise::member1, aConstNoExcept, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(&pool, &AConstNoExceptWithPromise::member1, aConstNoExcept, 20); + f = run(&pool, &AConstNoExceptWithPromise::member1, aConstNoExcept, 20); QCOMPARE(f.result(), 20); - f = runWithPromise(aConstNoExcept); + f = run(aConstNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, aConstNoExcept); + f = run(&pool, aConstNoExcept); QCOMPARE(f.result(), 10); - f = runWithPromise(std::ref(aConstNoExcept)); + f = run(std::ref(aConstNoExcept)); QCOMPARE(f.result(), 10); - f = runWithPromise(&pool, std::ref(aConstNoExcept)); + f = run(&pool, std::ref(aConstNoExcept)); QCOMPARE(f.result(), 10); } @@ -960,14 +961,14 @@ void tst_QtConcurrentRun::functor() } FunctorWithPromise fWithPromise; { - QtConcurrent::runWithPromise(fWithPromise, 1.5).waitForFinished(); + QtConcurrent::run(fWithPromise, 1.5).waitForFinished(); } OverloadedFunctorWithPromise ofWithPromise; { - QtConcurrent::runWithPromise(ofWithPromise).waitForFinished(); - QtConcurrent::runWithPromise(ofWithPromise).waitForFinished(); - QtConcurrent::runWithPromise(ofWithPromise, 1).waitForFinished(); - QtConcurrent::runWithPromise(ofWithPromise, 1).waitForFinished(); + QtConcurrent::run(ofWithPromise).waitForFinished(); + QtConcurrent::run(ofWithPromise).waitForFinished(); + QtConcurrent::run(ofWithPromise, 1).waitForFinished(); + QtConcurrent::run(ofWithPromise, 1).waitForFinished(); } // and now with explicit pool: QThreadPool pool; @@ -995,13 +996,17 @@ void tst_QtConcurrentRun::functor() // Compiler supports lambda void tst_QtConcurrentRun::lambda() { - QCOMPARE(QtConcurrent::run([](){ return 45; }).result(), 45); - QCOMPARE(QtConcurrent::run([](int a){ return a+15; }, 12).result(), 12+15); - QCOMPARE(QtConcurrent::run([](int a, double b){ return a + b; }, 12, 15).result(), double(12+15)); - QCOMPARE(QtConcurrent::run([](int a , int, int, int, int b){ return a + b; }, 1, 2, 3, 4, 5).result(), 1 + 5); + QCOMPARE(QtConcurrent::run([]() { return 45; }).result(), 45); + QCOMPARE(QtConcurrent::run([](int a) { return a+15; }, 12).result(), 12+15); + QCOMPARE(QtConcurrent::run([](int a, double b) { return a + b; }, 12, 15).result(), + double(12+15)); + QCOMPARE(QtConcurrent::run([](int a , int, int, int, int b) + { return a + b; }, 1, 2, 3, 4, 5).result(), 1 + 5); - QCOMPARE(QtConcurrent::runWithPromise([](QPromise &promise){ promise.addResult(45); }).result(), 45); - QCOMPARE(QtConcurrent::runWithPromise([](QPromise &promise, double input){ promise.addResult(input / 2.0); }, 15.0).result(), 7); + QCOMPARE(QtConcurrent::run([](QPromise &promise) + { promise.addResult(45); }).result(), 45); + QCOMPARE(QtConcurrent::run([](QPromise &promise, double input) + { promise.addResult(input / 2.0); }, 15.0).result(), 7); { QString str { "Hello World Foo" }; @@ -1012,10 +1017,12 @@ void tst_QtConcurrentRun::lambda() // and now with explicit pool: QThreadPool pool; - QCOMPARE(QtConcurrent::run(&pool, [](){ return 45; }).result(), 45); - QCOMPARE(QtConcurrent::run(&pool, [](int a){ return a+15; }, 12).result(), 12+15); - QCOMPARE(QtConcurrent::run(&pool, [](int a, double b){ return a + b; }, 12, 15).result(), double(12+15)); - QCOMPARE(QtConcurrent::run(&pool, [](int a , int, int, int, int b){ return a + b; }, 1, 2, 3, 4, 5).result(), 1 + 5); + QCOMPARE(QtConcurrent::run(&pool, []() { return 45; }).result(), 45); + QCOMPARE(QtConcurrent::run(&pool, [](int a) { return a + 15; }, 12).result(), 12 + 15); + QCOMPARE(QtConcurrent::run(&pool, [](int a, double b) + { return a + b; }, 12, 15).result(), double(12 + 15)); + QCOMPARE(QtConcurrent::run(&pool, [](int a , int, int, int, int b) + { return a + b; }, 1, 2, 3, 4, 5).result(), 1 + 5); { QString str { "Hello World Foo" }; @@ -1065,19 +1072,20 @@ void tst_QtConcurrentRun::callableObjectWithState() CallableWithStateWithPromise oWithPromise; // Run method setNewState explicitly - runWithPromise(&CallableWithStateWithPromise::setNewState, &oWithPromise, CallableWithStateWithPromise::defaultState() + 1).waitForFinished(); + run(&CallableWithStateWithPromise::setNewState, &oWithPromise, + CallableWithStateWithPromise::defaultState() + 1).waitForFinished(); QCOMPARE(oWithPromise.state, CallableWithStateWithPromise::defaultState() + 1); // Run operator()(int) explicitly - runWithPromise(std::ref(oWithPromise), CallableWithStateWithPromise::defaultState() + 2).waitForFinished(); + run(std::ref(oWithPromise), CallableWithStateWithPromise::defaultState() + 2).waitForFinished(); QCOMPARE(oWithPromise.state, CallableWithStateWithPromise::defaultState() + 2); // Run on a copy of object (original object remains unchanged) - runWithPromise(oWithPromise, CallableWithStateWithPromise::defaultState() + 3).waitForFinished(); + run(oWithPromise, CallableWithStateWithPromise::defaultState() + 3).waitForFinished(); QCOMPARE(oWithPromise.state, CallableWithStateWithPromise::defaultState() + 2); // Explicitly run on a temporary object - QCOMPARE(runWithPromise(CallableWithStateWithPromise(), 15).result(), 15); + QCOMPARE(run(CallableWithStateWithPromise(), 15).result(), 15); } void report3(QPromise &promise) @@ -1161,40 +1169,40 @@ public: void tst_QtConcurrentRun::withPromise() { // free function pointer - QCOMPARE(runWithPromise(&report3).results(), + QCOMPARE(run(&report3).results(), QList({0, 2, 1})); - QCOMPARE(runWithPromise(report3).results(), + QCOMPARE(run(report3).results(), QList({0, 2, 1})); - QCOMPARE(runWithPromise(reportN, 4).results(), + QCOMPARE(run(reportN, 4).results(), QList({0, 0, 0, 0})); - QCOMPARE(runWithPromise(reportN, 2).results(), + QCOMPARE(run(reportN, 2).results(), QList({0, 0})); QString s = QLatin1String("string"); const QString &crs = QLatin1String("cr string"); const QString cs = QLatin1String("c string"); - QCOMPARE(runWithPromise(reportString1, s).results(), + QCOMPARE(run(reportString1, s).results(), QList({s})); - QCOMPARE(runWithPromise(reportString1, crs).results(), + QCOMPARE(run(reportString1, crs).results(), QList({crs})); - QCOMPARE(runWithPromise(reportString1, cs).results(), + QCOMPARE(run(reportString1, cs).results(), QList({cs})); - QCOMPARE(runWithPromise(reportString1, QString(QLatin1String("rvalue"))).results(), + QCOMPARE(run(reportString1, QString(QLatin1String("rvalue"))).results(), QList({QString(QLatin1String("rvalue"))})); - QCOMPARE(runWithPromise(reportString2, s).results(), + QCOMPARE(run(reportString2, s).results(), QList({s})); - QCOMPARE(runWithPromise(reportString2, crs).results(), + QCOMPARE(run(reportString2, crs).results(), QList({crs})); - QCOMPARE(runWithPromise(reportString2, cs).results(), + QCOMPARE(run(reportString2, cs).results(), QList({cs})); - QCOMPARE(runWithPromise(reportString2, QString(QLatin1String("rvalue"))).results(), + QCOMPARE(run(reportString2, QString(QLatin1String("rvalue"))).results(), QList({QString(QLatin1String("rvalue"))})); // lambda - QCOMPARE(runWithPromise([](QPromise &promise, int n) { + QCOMPARE(run([](QPromise &promise, int n) { for (int i = 0; i < n; ++i) promise.addResult(0); }, 3).results(), @@ -1205,46 +1213,46 @@ void tst_QtConcurrentRun::withPromise() for (int i = 0; i < n; ++i) promise.addResult(0); }; - QCOMPARE(runWithPromise(fun, 2).results(), + QCOMPARE(run(fun, 2).results(), QList({0, 0})); // operator() - QCOMPARE(runWithPromise(Callable(), 3).results(), + QCOMPARE(run(Callable(), 3).results(), QList({0, 0, 0})); const Callable c{}; - QCOMPARE(runWithPromise(c, 2).results(), + QCOMPARE(run(c, 2).results(), QList({0, 0})); // static member functions - QCOMPARE(runWithPromise(&MyObject::staticMember0).results(), + QCOMPARE(run(&MyObject::staticMember0).results(), QList({0, 2, 1})); - QCOMPARE(runWithPromise(&MyObject::staticMember1, 2).results(), + QCOMPARE(run(&MyObject::staticMember1, 2).results(), QList({0, 0})); // member functions const MyObject obj{}; - QCOMPARE(runWithPromise(&MyObject::member0, &obj).results(), + QCOMPARE(run(&MyObject::member0, &obj).results(), QList({0, 2, 1})); - QCOMPARE(runWithPromise(&MyObject::member1, &obj, 4).results(), + QCOMPARE(run(&MyObject::member1, &obj, 4).results(), QList({0, 0, 0, 0})); - QCOMPARE(runWithPromise(&MyObject::memberString1, &obj, s).results(), + QCOMPARE(run(&MyObject::memberString1, &obj, s).results(), QList({s})); - QCOMPARE(runWithPromise(&MyObject::memberString1, &obj, crs).results(), + QCOMPARE(run(&MyObject::memberString1, &obj, crs).results(), QList({crs})); - QCOMPARE(runWithPromise(&MyObject::memberString1, &obj, cs).results(), + QCOMPARE(run(&MyObject::memberString1, &obj, cs).results(), QList({cs})); - QCOMPARE(runWithPromise(&MyObject::memberString1, &obj, QString(QLatin1String("rvalue"))).results(), + QCOMPARE(run(&MyObject::memberString1, &obj, QString(QLatin1String("rvalue"))).results(), QList({QString(QLatin1String("rvalue"))})); - QCOMPARE(runWithPromise(&MyObject::memberString2, &obj, s).results(), + QCOMPARE(run(&MyObject::memberString2, &obj, s).results(), QList({s})); - QCOMPARE(runWithPromise(&MyObject::memberString2, &obj, crs).results(), + QCOMPARE(run(&MyObject::memberString2, &obj, crs).results(), QList({crs})); - QCOMPARE(runWithPromise(&MyObject::memberString2, &obj, cs).results(), + QCOMPARE(run(&MyObject::memberString2, &obj, cs).results(), QList({cs})); - QCOMPARE(runWithPromise(&MyObject::memberString2, &obj, QString(QLatin1String("rvalue"))).results(), + QCOMPARE(run(&MyObject::memberString2, &obj, QString(QLatin1String("rvalue"))).results(), QList({QString(QLatin1String("rvalue"))})); MyObject nonConstObj{}; - QCOMPARE(runWithPromise(&MyObject::nonConstMember, &nonConstObj).results(), + QCOMPARE(run(&MyObject::nonConstMember, &nonConstObj).results(), QList({0, 2, 1})); } @@ -1252,40 +1260,40 @@ void tst_QtConcurrentRun::withPromiseInThreadPool() { QScopedPointer pool(new QThreadPool); // free function pointer - QCOMPARE(runWithPromise(pool.data(), &report3).results(), + QCOMPARE(run(pool.data(), &report3).results(), QList({0, 2, 1})); - QCOMPARE(runWithPromise(pool.data(), report3).results(), + QCOMPARE(run(pool.data(), report3).results(), QList({0, 2, 1})); - QCOMPARE(runWithPromise(pool.data(), reportN, 4).results(), + QCOMPARE(run(pool.data(), reportN, 4).results(), QList({0, 0, 0, 0})); - QCOMPARE(runWithPromise(pool.data(), reportN, 2).results(), + QCOMPARE(run(pool.data(), reportN, 2).results(), QList({0, 0})); QString s = QLatin1String("string"); const QString &crs = QLatin1String("cr string"); const QString cs = QLatin1String("c string"); - QCOMPARE(runWithPromise(pool.data(), reportString1, s).results(), + QCOMPARE(run(pool.data(), reportString1, s).results(), QList({s})); - QCOMPARE(runWithPromise(pool.data(), reportString1, crs).results(), + QCOMPARE(run(pool.data(), reportString1, crs).results(), QList({crs})); - QCOMPARE(runWithPromise(pool.data(), reportString1, cs).results(), + QCOMPARE(run(pool.data(), reportString1, cs).results(), QList({cs})); - QCOMPARE(runWithPromise(pool.data(), reportString1, QString(QLatin1String("rvalue"))).results(), + QCOMPARE(run(pool.data(), reportString1, QString(QLatin1String("rvalue"))).results(), QList({QString(QLatin1String("rvalue"))})); - QCOMPARE(runWithPromise(pool.data(), reportString2, s).results(), + QCOMPARE(run(pool.data(), reportString2, s).results(), QList({s})); - QCOMPARE(runWithPromise(pool.data(), reportString2, crs).results(), + QCOMPARE(run(pool.data(), reportString2, crs).results(), QList({crs})); - QCOMPARE(runWithPromise(pool.data(), reportString2, cs).results(), + QCOMPARE(run(pool.data(), reportString2, cs).results(), QList({cs})); - QCOMPARE(runWithPromise(pool.data(), reportString2, QString(QLatin1String("rvalue"))).results(), + QCOMPARE(run(pool.data(), reportString2, QString(QLatin1String("rvalue"))).results(), QList({QString(QLatin1String("rvalue"))})); // lambda - QCOMPARE(runWithPromise(pool.data(), [](QPromise &promise, int n) { + QCOMPARE(run(pool.data(), [](QPromise &promise, int n) { for (int i = 0; i < n; ++i) promise.addResult(0); }, 3).results(), @@ -1296,43 +1304,45 @@ void tst_QtConcurrentRun::withPromiseInThreadPool() for (int i = 0; i < n; ++i) promise.addResult(0); }; - QCOMPARE(runWithPromise(pool.data(), fun, 2).results(), + QCOMPARE(run(pool.data(), fun, 2).results(), QList({0, 0})); // operator() - QCOMPARE(runWithPromise(pool.data(), Callable(), 3).results(), + QCOMPARE(run(pool.data(), Callable(), 3).results(), QList({0, 0, 0})); const Callable c{}; - QCOMPARE(runWithPromise(pool.data(), c, 2).results(), + QCOMPARE(run(pool.data(), c, 2).results(), QList({0, 0})); // static member functions - QCOMPARE(runWithPromise(pool.data(), &MyObject::staticMember0).results(), + QCOMPARE(run(pool.data(), &MyObject::staticMember0).results(), QList({0, 2, 1})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::staticMember1, 2).results(), + QCOMPARE(run(pool.data(), &MyObject::staticMember1, 2).results(), QList({0, 0})); // member functions const MyObject obj{}; - QCOMPARE(runWithPromise(pool.data(), &MyObject::member0, &obj).results(), + QCOMPARE(run(pool.data(), &MyObject::member0, &obj).results(), QList({0, 2, 1})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::member1, &obj, 4).results(), + QCOMPARE(run(pool.data(), &MyObject::member1, &obj, 4).results(), QList({0, 0, 0, 0})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::memberString1, &obj, s).results(), + QCOMPARE(run(pool.data(), &MyObject::memberString1, &obj, s).results(), QList({s})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::memberString1, &obj, crs).results(), + QCOMPARE(run(pool.data(), &MyObject::memberString1, &obj, crs).results(), QList({crs})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::memberString1, &obj, cs).results(), + QCOMPARE(run(pool.data(), &MyObject::memberString1, &obj, cs).results(), QList({cs})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::memberString1, &obj, QString(QLatin1String("rvalue"))).results(), + QCOMPARE(run(pool.data(), &MyObject::memberString1, &obj, + QString(QLatin1String("rvalue"))).results(), QList({QString(QLatin1String("rvalue"))})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::memberString2, &obj, s).results(), + QCOMPARE(run(pool.data(), &MyObject::memberString2, &obj, s).results(), QList({s})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::memberString2, &obj, crs).results(), + QCOMPARE(run(pool.data(), &MyObject::memberString2, &obj, crs).results(), QList({crs})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::memberString2, &obj, cs).results(), + QCOMPARE(run(pool.data(), &MyObject::memberString2, &obj, cs).results(), QList({cs})); - QCOMPARE(runWithPromise(pool.data(), &MyObject::memberString2, &obj, QString(QLatin1String("rvalue"))).results(), + QCOMPARE(run(pool.data(), &MyObject::memberString2, &obj, + QString(QLatin1String("rvalue"))).results(), QList({QString(QLatin1String("rvalue"))})); } @@ -1357,44 +1367,92 @@ public: void tst_QtConcurrentRun::moveOnlyType() { - QCOMPARE(runWithPromise(MoveOnlyCallable(), MoveOnlyType()).results(), + QCOMPARE(run(MoveOnlyCallable(), MoveOnlyType()).results(), QList({1})); } void tst_QtConcurrentRun::crefFunction() { - // free function pointer with promise - auto fun = &report3; - QCOMPARE(runWithPromise(std::cref(fun)).results(), - QList({0, 2, 1})); + { + // free function pointer with promise + auto fun = &returnInt0; + QCOMPARE(run(std::cref(fun)).result(), 10); - // lambda with promise - auto lambda = [](QPromise &promise, int n) { - for (int i = 0; i < n; ++i) - promise.addResult(0); - }; - QCOMPARE(runWithPromise(std::cref(lambda), 3).results(), - QList({0, 0, 0})); + // lambda with promise + auto lambda = [](int n) { + return 2 * n; + }; + QCOMPARE(run(std::cref(lambda), 3).result(), 6); - // std::function with promise - const std::function &, int)> funObj = [](QPromise &promise, int n) { - for (int i = 0; i < n; ++i) - promise.addResult(0); - }; - QCOMPARE(runWithPromise(std::cref(funObj), 2).results(), - QList({0, 0})); + // std::function with promise + const std::function funObj = [](int n) { + return 2 * n; + }; + QCOMPARE(run(std::cref(funObj), 2).result(), 4); - // callable with promise - const Callable c{}; - QCOMPARE(runWithPromise(std::cref(c), 2).results(), - QList({0, 0})); + // callable with promise + const AConst c{}; + QCOMPARE(run(std::cref(c), 2).result(), 2); - // member functions with promise - auto member = &MyObject::member0; - const MyObject obj{}; - QCOMPARE(runWithPromise(std::cref(member), &obj).results(), - QList({0, 2, 1})); + // member functions with promise + auto member = &AConst::member0; + const AConst obj{}; + QCOMPARE(run(std::cref(member), &obj).result(), 10); + } + + { + // free function pointer with promise + auto fun = &report3; + QCOMPARE(run(std::cref(fun)).results(), + QList({0, 2, 1})); + + // lambda with promise + auto lambda = [](QPromise &promise, int n) { + for (int i = 0; i < n; ++i) + promise.addResult(0); + }; + QCOMPARE(run(std::cref(lambda), 3).results(), + QList({0, 0, 0})); + + // std::function with promise + const std::function &, int)> funObj = + [](QPromise &promise, int n) { + for (int i = 0; i < n; ++i) + promise.addResult(0); + }; + QCOMPARE(run(std::cref(funObj), 2).results(), + QList({0, 0})); + + // callable with promise + const Callable c{}; + QCOMPARE(run(std::cref(c), 2).results(), + QList({0, 0})); + + // member functions with promise + auto member = &MyObject::member0; + const MyObject obj{}; + QCOMPARE(run(std::cref(member), &obj).results(), + QList({0, 2, 1})); + } } +int explicitPromise(QPromise &promise, int &i) +{ + promise.setProgressRange(-10, 10); + ++i; + return i * 2; +} + +void tst_QtConcurrentRun::customPromise() +{ + QPromise p; + int i = 4; + QCOMPARE(QtConcurrent::run(explicitPromise, std::ref(p), std::ref(i)).result(), 10); + QCOMPARE(i, 5); + QCOMPARE(p.future().progressMinimum(), -10); + QCOMPARE(p.future().progressMaximum(), 10); +} + + QTEST_MAIN(tst_QtConcurrentRun) #include "tst_qtconcurrentrun.moc"