Move detection of <future> to a configure test

<future> is needed by QThread::create. Instead of a fragile series
of preprocessor tests, move its detection to a configure test.
This dramatically simplifies the code, but on the other hand ties
the availability of QThread::create() to the system used to compile
Qt (rather the one used to compile an application).

Change-Id: If1b06363379bf29126cfa68f2a0651cbb78a67f7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Giuseppe D'Angelo 2017-09-16 12:54:45 +01:00
parent db1027bc36
commit cb08b40976
4 changed files with 36 additions and 25 deletions

View File

@ -251,6 +251,18 @@
]
}
},
"cxx11_future": {
"label": "C++11 <future>",
"type": "compile",
"test": {
"include": "future",
"main": [
"std::future<int> f = std::async([]() { return 42; });",
"(void)f.get();"
],
"qmake": "unix:LIBS += -lpthread"
}
},
"cxx11_random": {
"label": "C++11 <random>",
"type": "compile",
@ -442,6 +454,11 @@
"condition": "features.doubleconversion && libs.doubleconversion",
"output": [ "privateFeature" ]
},
"cxx11_future": {
"label": "C++11 <future>",
"condition": "tests.cxx11_future",
"output": [ "publicFeature" ]
},
"cxx11_random": {
"label": "C++11 <random>",
"condition": "tests.cxx11_random",

View File

@ -925,7 +925,7 @@ bool QThread::isInterruptionRequested() const
\sa start()
*/
#ifdef QTHREAD_HAS_CREATE
#if QT_CONFIG(cxx11_future)
class QThreadCreateThread : public QThread
{
public:
@ -947,7 +947,7 @@ QThread *QThread::createThreadImpl(std::future<void> &&future)
{
return new QThreadCreateThread(std::move(future));
}
#endif // QTHREAD_HAS_CREATE
#endif // QT_CONFIG(cxx11_future)
/*!
\class QDaemonThread

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -42,17 +43,10 @@
#include <QtCore/qobject.h>
// The implementation of QThread::create uses various C++14/C++17 facilities;
// we must check for their presence. Specifically for glibcxx bundled in MinGW
// with win32 threads, we check the condition found in its <future> header
// since _GLIBCXX_HAS_GTHREADS might then not be defined.
// For std::async (used in all codepaths)
// there is no SG10 feature macro; just test for the header presence.
// For the C++17 codepath do some more throughout checks for std::invoke and
// C++14 lambdas availability.
#if QT_HAS_INCLUDE(<future>) \
&& (!defined(__GLIBCXX__) || (defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)))
# define QTHREAD_HAS_CREATE
// 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).
#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
@ -125,16 +119,16 @@ public:
template <typename Function>
static QThread *create(Function &&f);
#else
#ifdef QTHREAD_HAS_CREATE
#ifdef QTHREAD_HAS_VARIADIC_CREATE
# if QT_CONFIG(cxx11_future)
# ifdef QTHREAD_HAS_VARIADIC_CREATE
template <typename Function, typename... Args>
static QThread *create(Function &&f, Args &&... args);
#else
# else
template <typename Function>
static QThread *create(Function &&f);
#endif
#endif
#endif
# endif // QTHREAD_HAS_VARIADIC_CREATE
# endif // QT_CONFIG(cxx11_future)
#endif // Q_QDOC
public Q_SLOTS:
void start(Priority = InheritPriority);
@ -165,7 +159,7 @@ protected:
private:
Q_DECLARE_PRIVATE(QThread)
#ifdef QTHREAD_HAS_CREATE
#if QT_CONFIG(cxx11_future)
static QThread *createThreadImpl(std::future<void> &&future);
#endif
@ -173,9 +167,9 @@ private:
friend class QThreadData;
};
#ifdef QTHREAD_HAS_CREATE
#if QT_CONFIG(cxx11_future)
#ifdef QTHREAD_HAS_VARIADIC_CREATE
#if defined(QTHREAD_HAS_VARIADIC_CREATE)
// C++17: std::thread's constructor complying call
template <typename Function, typename... Args>
QThread *QThread::create(Function &&f, Args &&... args)
@ -243,7 +237,7 @@ QThread *QThread::create(Function &&f)
}
#endif // QTHREAD_HAS_VARIADIC_CREATE
#endif // QTHREAD_HAS_CREATE
#endif // QT_CONFIG(cxx11_future)
#else // QT_NO_THREAD

View File

@ -1338,7 +1338,7 @@ void tst_QThread::quitLock()
void tst_QThread::create()
{
#ifndef QTHREAD_HAS_CREATE
#if !QT_CONFIG(cxx11_future)
QSKIP("This test requires QThread::create");
#else
{
@ -1586,7 +1586,7 @@ void tst_QThread::create()
}
#endif // QT_NO_EXCEPTIONS
#endif // QTHREAD_HAS_VARIADIC_CREATE
#endif // QTHREAD_HAS_CREATE
#endif // QT_CONFIG(cxx11_future)
}
class StopableJob : public QObject