QThread::create: remove the pre-C++17 codepaths

As we require C++17 now. The configure-time test checking for
future/async is left in for the moment being.

Change-Id: Ifde39d420673f70a2277f5a645bfaad30935a381
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
bb10
Giuseppe D'Angelo 2020-07-03 12:19:08 +02:00
parent 471e4fcb22
commit 1e8d623340
3 changed files with 3 additions and 105 deletions

View File

@ -1078,29 +1078,6 @@ bool QThread::isInterruptionRequested() const
\note the caller acquires ownership of the returned QThread instance.
\note this function is only available when using C++17.
\warning do not call start() on the returned QThread instance more than once;
doing so will result in undefined behavior.
\sa start()
*/
/*!
\fn template <typename Function> QThread *QThread::create(Function &&f)
\since 5.10
Creates a new QThread object that will execute the function \a f.
The new thread is not started -- it must be started by an explicit call
to start(). This allows you to connect to its signals, move QObjects
to the thread, choose the new thread's priority and so on. The function
\a f will be called in the new thread.
Returns the newly created QThread instance.
\note the caller acquires ownership of the returned QThread instance.
\warning do not call start() on the returned QThread instance more than once;
doing so will result in undefined behavior.

View File

@ -44,18 +44,10 @@
#include <QtCore/qobject.h>
#include <QtCore/qdeadlinetimer.h>
// For QThread::create. The configure-time test just checks for the availability
// of std::future and std::async; for the C++17 codepath we perform some extra
// checks here (for std::invoke and C++14 lambdas).
// For QThread::create
#if QT_CONFIG(cxx11_future)
# include <future> // for std::async
# include <functional> // for std::invoke; no guard needed as it's a C++98 header
# if defined(__cpp_lib_invoke) && __cpp_lib_invoke >= 201411 \
&& defined(__cpp_init_captures) && __cpp_init_captures >= 201304 \
&& defined(__cpp_generic_lambdas) && __cpp_generic_lambdas >= 201304
# define QTHREAD_HAS_VARIADIC_CREATE
# endif
#endif
QT_BEGIN_NAMESPACE
@ -111,22 +103,10 @@ public:
bool event(QEvent *event) override;
int loopLevel() const;
#ifdef Q_CLANG_QDOC
#if QT_CONFIG(cxx11_future) || defined(Q_CLANG_QDOC)
template <typename Function, typename... Args>
static QThread *create(Function &&f, Args &&... args);
template <typename Function>
static QThread *create(Function &&f);
#else
# if QT_CONFIG(cxx11_future)
# ifdef QTHREAD_HAS_VARIADIC_CREATE
template <typename Function, typename... Args>
static QThread *create(Function &&f, Args &&... args);
# else
template <typename Function>
static QThread *create(Function &&f);
# endif // QTHREAD_HAS_VARIADIC_CREATE
# endif // QT_CONFIG(cxx11_future)
#endif // Q_CLANG_QDOC
#endif
public Q_SLOTS:
void start(Priority = InheritPriority);
@ -168,9 +148,6 @@ private:
};
#if QT_CONFIG(cxx11_future)
#if defined(QTHREAD_HAS_VARIADIC_CREATE) || defined(Q_CLANG_QDOC)
// C++17: std::thread's constructor complying call
template <typename Function, typename... Args>
QThread *QThread::create(Function &&f, Args &&... args)
{
@ -185,56 +162,6 @@ QThread *QThread::create(Function &&f, Args &&... args)
std::move(threadFunction),
std::forward<Args>(args)...));
}
#elif defined(__cpp_init_captures) && __cpp_init_captures >= 201304
// C++14: implementation for just one callable
template <typename Function>
QThread *QThread::create(Function &&f)
{
using DecayedFunction = typename std::decay<Function>::type;
auto threadFunction =
[f = static_cast<DecayedFunction>(std::forward<Function>(f))]() mutable -> void
{
(void)f();
};
return createThreadImpl(std::async(std::launch::deferred, std::move(threadFunction)));
}
#else
// C++11: same as C++14, but with a workaround for not having generalized lambda captures
namespace QtPrivate {
template <typename Function>
struct Callable
{
explicit Callable(Function &&f)
: m_function(std::forward<Function>(f))
{
}
// Apply the same semantics of a lambda closure type w.r.t. the special
// member functions, if possible: delete the copy assignment operator,
// bring back all the others as per the RO5 (cf. §8.1.5.1/11 [expr.prim.lambda.closure])
~Callable() = default;
Callable(const Callable &) = default;
Callable(Callable &&) = default;
Callable &operator=(const Callable &) = delete;
Callable &operator=(Callable &&) = default;
void operator()()
{
(void)m_function();
}
typename std::decay<Function>::type m_function;
};
} // namespace QtPrivate
template <typename Function>
QThread *QThread::create(Function &&f)
{
return createThreadImpl(std::async(std::launch::deferred, QtPrivate::Callable<Function>(std::forward<Function>(f))));
}
#endif // QTHREAD_HAS_VARIADIC_CREATE
#endif // QT_CONFIG(cxx11_future)
/*

View File

@ -1449,7 +1449,6 @@ void tst_QThread::create()
QCOMPARE(i, 42);
}
#if defined(__cpp_init_captures) && __cpp_init_captures >= 201304
{
int i = 0;
MoveOnlyValue mo(123);
@ -1461,9 +1460,7 @@ void tst_QThread::create()
QVERIFY(thread->wait());
QCOMPARE(i, 123);
}
#endif // __cpp_init_captures
#ifdef QTHREAD_HAS_VARIADIC_CREATE
{
int i = 0;
const auto &function = [&i](MoveOnlyValue &&mo) { i = mo.v; };
@ -1486,10 +1483,8 @@ void tst_QThread::create()
QVERIFY(thread->wait());
QCOMPARE(i, -1);
}
#endif // QTHREAD_HAS_VARIADIC_CREATE
}
#ifdef QTHREAD_HAS_VARIADIC_CREATE
{
// simple parameter passing
int i = 0;
@ -1587,7 +1582,6 @@ void tst_QThread::create()
QVERIFY(!thread);
}
#endif // QT_NO_EXCEPTIONS
#endif // QTHREAD_HAS_VARIADIC_CREATE
#endif // QT_CONFIG(cxx11_future)
}