summaryrefslogtreecommitdiffstats
path: root/src/concurrent
diff options
context:
space:
mode:
Diffstat (limited to 'src/concurrent')
-rw-r--r--src/concurrent/CMakeLists.txt52
-rw-r--r--src/concurrent/concurrent.pro40
-rw-r--r--src/concurrent/doc/qtconcurrent.qdocconf22
-rw-r--r--src/concurrent/doc/snippets/CMakeLists.txt7
-rw-r--r--src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp121
-rw-r--r--src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp100
-rw-r--r--src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp191
-rw-r--r--src/concurrent/doc/snippets/code/src_concurrent_qtconcurrenttask.cpp93
-rw-r--r--src/concurrent/doc/snippets/snippets.pro3
-rw-r--r--src/concurrent/doc/src/qt6-changes.qdoc57
-rw-r--r--src/concurrent/doc/src/qtconcurrent-examples.qdoc14
-rw-r--r--src/concurrent/doc/src/qtconcurrent-index.qdoc96
-rw-r--r--src/concurrent/doc/src/qtconcurrent-module.qdoc46
-rw-r--r--src/concurrent/qtaskbuilder.h135
-rw-r--r--src/concurrent/qtaskbuilder.qdoc77
-rw-r--r--src/concurrent/qtconcurrent_global.h55
-rw-r--r--src/concurrent/qtconcurrentcompilertest.h70
-rw-r--r--src/concurrent/qtconcurrentexception.h65
-rw-r--r--src/concurrent/qtconcurrentfilter.cpp478
-rw-r--r--src/concurrent/qtconcurrentfilter.h747
-rw-r--r--src/concurrent/qtconcurrentfilterkernel.h228
-rw-r--r--src/concurrent/qtconcurrentfunctionwrappers.h373
-rw-r--r--src/concurrent/qtconcurrentiteratekernel.cpp120
-rw-r--r--src/concurrent/qtconcurrentiteratekernel.h187
-rw-r--r--src/concurrent/qtconcurrentmap.cpp461
-rw-r--r--src/concurrent/qtconcurrentmap.h876
-rw-r--r--src/concurrent/qtconcurrentmapkernel.h246
-rw-r--r--src/concurrent/qtconcurrentmedian.h123
-rw-r--r--src/concurrent/qtconcurrentreducekernel.h95
-rw-r--r--src/concurrent/qtconcurrentrun.cpp235
-rw-r--r--src/concurrent/qtconcurrentrun.h909
-rw-r--r--src/concurrent/qtconcurrentrunbase.h124
-rw-r--r--src/concurrent/qtconcurrentstoredfunctioncall.h2291
-rw-r--r--src/concurrent/qtconcurrenttask.h39
-rw-r--r--src/concurrent/qtconcurrenttask.qdoc146
-rw-r--r--src/concurrent/qtconcurrentthreadengine.cpp115
-rw-r--r--src/concurrent/qtconcurrentthreadengine.h88
37 files changed, 4025 insertions, 5100 deletions
diff --git a/src/concurrent/CMakeLists.txt b/src/concurrent/CMakeLists.txt
new file mode 100644
index 0000000000..504f854534
--- /dev/null
+++ b/src/concurrent/CMakeLists.txt
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## Concurrent Module:
+#####################################################################
+
+qt_internal_add_module(Concurrent
+ EXCEPTIONS
+ SOURCES
+ qtaskbuilder.h
+ qtconcurrent_global.h
+ qtconcurrentcompilertest.h
+ qtconcurrentfilter.cpp qtconcurrentfilter.h
+ qtconcurrentfilterkernel.h
+ qtconcurrentfunctionwrappers.h
+ qtconcurrentiteratekernel.cpp qtconcurrentiteratekernel.h
+ qtconcurrentmap.cpp qtconcurrentmap.h
+ qtconcurrentmapkernel.h
+ qtconcurrentmedian.h
+ qtconcurrentreducekernel.h
+ qtconcurrentrun.cpp qtconcurrentrun.h
+ qtconcurrentrunbase.h
+ qtconcurrentstoredfunctioncall.h
+ qtconcurrenttask.h
+ qtconcurrentthreadengine.cpp qtconcurrentthreadengine.h
+ DEFINES
+ QT_NO_CONTEXTLESS_CONNECT
+ QT_NO_FOREACH
+ QT_NO_USING_NAMESPACE
+ QT_USE_NODISCARD_FILE_OPEN
+ LIBRARIES
+ Qt::CorePrivate
+ PUBLIC_LIBRARIES
+ Qt::Core
+ PRIVATE_MODULE_INTERFACE
+ Qt::CorePrivate
+ PRECOMPILED_HEADER
+ "../corelib/global/qt_pch.h"
+ GENERATE_CPP_EXPORTS
+)
+
+## Scopes:
+#####################################################################
+
+qt_internal_extend_target(Concurrent CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i386")
+ LINK_OPTIONS
+ "/BASE:0x66000000"
+)
+qt_internal_add_docs(Concurrent
+ doc/qtconcurrent.qdocconf
+)
diff --git a/src/concurrent/concurrent.pro b/src/concurrent/concurrent.pro
deleted file mode 100644
index 18510e38a1..0000000000
--- a/src/concurrent/concurrent.pro
+++ /dev/null
@@ -1,40 +0,0 @@
-TARGET = QtConcurrent
-QT = core-private
-CONFIG += exceptions
-
-DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-
-msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000
-
-QMAKE_DOCS = $$PWD/doc/qtconcurrent.qdocconf
-
-PRECOMPILED_HEADER = ../corelib/global/qt_pch.h
-
-SOURCES += \
- qtconcurrentfilter.cpp \
- qtconcurrentmap.cpp \
- qtconcurrentrun.cpp \
- qtconcurrentthreadengine.cpp \
- qtconcurrentiteratekernel.cpp \
-
-HEADERS += \
- qtconcurrent_global.h \
- qtconcurrentcompilertest.h \
- qtconcurrentexception.h \
- qtconcurrentfilter.h \
- qtconcurrentfilterkernel.h \
- qtconcurrentfunctionwrappers.h \
- qtconcurrentiteratekernel.h \
- qtconcurrentmap.h \
- qtconcurrentmapkernel.h \
- qtconcurrentmedian.h \
- qtconcurrentreducekernel.h \
- qtconcurrentrun.h \
- qtconcurrentrunbase.h \
- qtconcurrentstoredfunctioncall.h \
- qtconcurrentthreadengine.h
-
-# private headers
-HEADERS += \
-
-load(qt_module)
diff --git a/src/concurrent/doc/qtconcurrent.qdocconf b/src/concurrent/doc/qtconcurrent.qdocconf
index 610dca2a7e..c4efe64d0a 100644
--- a/src/concurrent/doc/qtconcurrent.qdocconf
+++ b/src/concurrent/doc/qtconcurrent.qdocconf
@@ -15,33 +15,33 @@ qhp.QtConcurrent.virtualFolder = qtconcurrent
qhp.QtConcurrent.indexTitle = Qt Concurrent
qhp.QtConcurrent.indexRoot =
-qhp.QtConcurrent.filterAttributes = qtconcurrent $QT_VERSION qtrefdoc
-qhp.QtConcurrent.customFilters.Qt.name = QtConcurrent $QT_VERSION
-qhp.QtConcurrent.customFilters.Qt.filterAttributes = qtconcurrent $QT_VERSION
-
-qhp.QtConcurrent.subprojects = classes
+qhp.QtConcurrent.subprojects = classes examples
qhp.QtConcurrent.subprojects.classes.title = C++ Classes
qhp.QtConcurrent.subprojects.classes.indexTitle = Qt Concurrent C++ Classes
qhp.QtConcurrent.subprojects.classes.selectors = class fake:headerfile
qhp.QtConcurrent.subprojects.classes.sortPages = true
+qhp.QtConcurrent.subprojects.examples.title = Qt Concurrent Examples
+qhp.QtConcurrent.subprojects.examples.indexTitle = Qt Concurrent Examples
+qhp.QtConcurrent.subprojects.examples.selectors = fake:example
tagfile = ../../../doc/qtconcurrent/qtconcurrent.tags
-depends += qtcore qtdoc
+depends += qtcore qtnetwork qtdoc qmake qtcmake
headerdirs += ..
sourcedirs += ..
exampledirs += ../../../examples/qtconcurrent \
- ../ \
- snippets
-
-manifestmeta.highlighted.names = "QtConcurrent/QtConcurrent Progress Dialog Example"
+ snippets \
+ .
-excludedirs += ../../../examples/widgets/doc
+excludedirs += snippets
imagedirs += images
navigation.landingpage = "Qt Concurrent"
navigation.cppclassespage = "Qt Concurrent C++ Classes"
+
+# Enforce zero documentation warnings
+warninglimit = 0
diff --git a/src/concurrent/doc/snippets/CMakeLists.txt b/src/concurrent/doc/snippets/CMakeLists.txt
new file mode 100644
index 0000000000..03ebb75a2e
--- /dev/null
+++ b/src/concurrent/doc/snippets/CMakeLists.txt
@@ -0,0 +1,7 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#! [cmake_use]
+find_package(Qt6 REQUIRED COMPONENTS Concurrent)
+target_link_libraries(mytarget PRIVATE Qt6::Concurrent)
+#! [cmake_use]
diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp
index 3cc1fe836c..1ea7deace5 100644
--- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp
+++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
//! [0]
bool function(const T &t);
@@ -82,7 +35,7 @@ void addToDictionary(QSet<QString> &dictionary, const QString &string)
}
QStringList strings = ...;
-QFuture<QSet<QString> > dictionary = QtConcurrent::filteredReduced(strings, allLowerCase, addToDictionary);
+QFuture<QSet<QString>> dictionary = QtConcurrent::filteredReduced(strings, allLowerCase, addToDictionary);
//! [4]
@@ -93,7 +46,7 @@ QFuture<QString> lowerCaseStrings = QtConcurrent::filtered(strings.constBegin(),
// filter in-place only works on non-const iterators
QFuture<void> future = QtConcurrent::filter(strings.begin(), strings.end(), allLowerCase);
-QFuture<QSet<QString> > dictionary = QtConcurrent::filteredReduced(strings.constBegin(), strings.constEnd(), allLowerCase, addToDictionary);
+QFuture<QSet<QString>> dictionary = QtConcurrent::filteredReduced(strings.constBegin(), strings.constEnd(), allLowerCase, addToDictionary);
//! [5]
@@ -121,7 +74,8 @@ QFuture<QImage> grayscaleImages = QtConcurrent::filtered(images, &QImage::isGray
// create a set of all printable characters
QList<QChar> characters = ...;
-QFuture<QSet<QChar> > set = QtConcurrent::filteredReduced(characters, &QChar::isPrint, &QSet<QChar>::insert);
+QFuture<QSet<QChar>> set = QtConcurrent::filteredReduced(characters, qOverload<>(&QChar::isPrint),
+ qOverload<const QChar&>(&QSet<QChar>::insert));
//! [7]
@@ -131,7 +85,8 @@ QFuture<QSet<QChar> > set = QtConcurrent::filteredReduced(characters, &QChar::is
// create a dictionary of all lower cased strings
extern bool allLowerCase(const QString &string);
QStringList strings = ...;
-QFuture<QSet<int> > averageWordLength = QtConcurrent::filteredReduced(strings, allLowerCase, QSet<QString>::insert);
+QFuture<QSet<QString>> lowerCase = QtConcurrent::filteredReduced(strings, allLowerCase,
+ qOverload<const QString&>(&QSet<QString>::insert));
// create a collage of all gray scale images
extern void addToCollage(QImage &collage, const QImage &grayscaleImage);
@@ -158,8 +113,6 @@ struct StartsWith
StartsWith(const QString &string)
: m_string(string) { }
- typedef bool result_type;
-
bool operator()(const QString &testString)
{
return testString.startsWith(m_string);
@@ -179,7 +132,59 @@ struct StringTransform
};
QFuture<QString> fooString =
- QtConcurrent::filteredReduced<QString>(strings,
- StartsWith(QLatin1String("Foo")),
- StringTransform());
+ QtConcurrent::filteredReduced(strings, StartsWith(QLatin1String("Foo")), StringTransform());
//! [14]
+
+//! [15]
+// keep only even integers
+QList<int> list { 1, 2, 3, 4 };
+QtConcurrent::blockingFilter(list, [](int n) { return (n & 1) == 0; });
+
+// retrieve only even integers
+QList<int> list2 { 1, 2, 3, 4 };
+QFuture<int> future = QtConcurrent::filtered(list2, [](int x) {
+ return (x & 1) == 0;
+});
+QList<int> results = future.results();
+
+// add up all even integers
+QList<int> list3 { 1, 2, 3, 4 };
+QFuture<int> sum = QtConcurrent::filteredReduced(list3,
+ [](int x) {
+ return (x & 1) == 0;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+);
+//! [15]
+
+//! [16]
+void intSumReduce(int &sum, int x)
+{
+ sum += x;
+}
+
+QList<int> list { 1, 2, 3, 4 };
+QFuture<int> sum = QtConcurrent::filteredReduced(list,
+ [] (int x) {
+ return (x & 1) == 0;
+ },
+ intSumReduce
+);
+//! [16]
+
+//! [17]
+bool keepEvenIntegers(int x)
+{
+ return (x & 1) == 0;
+}
+
+QList<int> list { 1, 2, 3, 4 };
+QFuture<int> sum = QtConcurrent::filteredReduced(list,
+ keepEvenIntegers,
+ [](int &sum, int x) {
+ sum += x;
+ }
+);
+//! [17]
diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp
index fc574302d2..35345c6f24 100644
--- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp
+++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
//! [0]
U function(const T &t);
@@ -130,11 +83,13 @@ QFuture<void> squeezedStrings = QtConcurrent::map(strings, &QString::squeeze);
// Swap the rgb values of all pixels on a list of images.
QList<QImage> images = ...;
-QFuture<QImage> bgrImages = QtConcurrent::mapped(images, &QImage::rgbSwapped);
+QFuture<QImage> bgrImages = QtConcurrent::mapped(images,
+ static_cast<QImage (QImage::*)() const &>(&QImage::rgbSwapped));
// Create a set of the lengths of all strings in a list.
QStringList strings = ...;
-QFuture<QSet<int> > wordLengths = QtConcurrent::mappedReduced(strings, &QString::length, &QSet<int>::insert);
+QFuture<QSet<int>> wordLengths = QtConcurrent::mappedReduced(strings, &QString::length,
+ qOverload<const int&>(&QSet<int>::insert));
//! [8]
@@ -149,7 +104,8 @@ QFuture<int> averageWordLength = QtConcurrent::mappedReduced(strings, &QString::
// Create a set of the color distribution of all images in a list.
extern int colorDistribution(const QImage &string);
QList<QImage> images = ...;
-QFuture<QSet<int> > totalColorDistribution = QtConcurrent::mappedReduced(images, colorDistribution, QSet<int>::insert);
+QFuture<QSet<int>> totalColorDistribution = QtConcurrent::mappedReduced(images, colorDistribution,
+ qOverload<const int&>(&QSet<int>::insert));
//! [9]
@@ -164,10 +120,8 @@ struct ImageTransform
};
QFuture<QImage> thumbNails =
- QtConcurrent::mappedReduced<QImage>(images,
- Scaled(100),
- ImageTransform(),
- QtConcurrent::SequentialReduce);
+ QtConcurrent::mappedReduced(images, Scaled(100), ImageTransform(),
+ QtConcurrent::SequentialReduce);
//! [11]
//! [13]
@@ -197,3 +151,37 @@ struct Scaled
QList<QImage> images = ...;
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, Scaled(100));
//! [14]
+
+//! [15]
+QList<int> vector { 1, 2, 3, 4 };
+QtConcurrent::blockingMap(vector, [](int &x) { x *= 2; });
+
+int size = 100;
+QList<QImage> images = ...;
+
+QList<QImage> thumbnails = QtConcurrent::mapped(images,
+ [&size](const QImage &image) {
+ return image.scaled(size, size);
+ }
+ ).results();
+//! [15]
+
+//! [16]
+QList<QImage> collage = QtConcurrent::mappedReduced(images,
+ [&size](const QImage &image) {
+ return image.scaled(size, size);
+ },
+ addToCollage
+ ).results();
+//! [16]
+
+//! [17]
+QList<QImage> collage = QtConcurrent::mappedReduced(images,
+ [&size](const QImage &image) {
+ return image.scaled(size, size);
+ },
+ [](QImage &result, const QImage &value) {
+ // do some transformation
+ }
+ ).results();
+//! [17]
diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp
index 5437822842..f934abdd9e 100644
--- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp
+++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp
@@ -1,52 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
//! [0]
extern void aFunction();
@@ -93,7 +46,7 @@ QString result = future.result();
//! [4]
// call 'QList<QByteArray> QByteArray::split(char sep) const' in a separate thread
QByteArray bytearray = "hello world";
-QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split, ',');
+QFuture<QList<QByteArray> > future = QtConcurrent::run(&QByteArray::split, bytearray, ' ');
...
QList<QByteArray> result = future.result();
//! [4]
@@ -101,16 +54,150 @@ QList<QByteArray> result = future.result();
//! [5]
// call 'void QImage::invertPixels(InvertMode mode)' in a separate thread
QImage image = ...;
-QFuture<void> future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba);
+QFuture<void> future = QtConcurrent::run(&QImage::invertPixels, &image, QImage::InvertRgba);
...
future.waitForFinished();
// At this point, the pixels in 'image' have been inverted
//! [5]
-
//! [6]
QFuture<void> future = QtConcurrent::run([=]() {
// Code in this block will run in another thread
});
...
//! [6]
+
+//! [7]
+static void addOne(int &n) { ++n; }
+...
+int n = 42;
+QtConcurrent::run(&addOne, std::ref(n)).waitForFinished(); // n == 43
+//! [7]
+
+//! [8]
+struct TestClass
+{
+ void operator()(int s1) { s = s1; }
+ int s = 42;
+};
+
+...
+
+TestClass o;
+
+// Modify original object
+QtConcurrent::run(std::ref(o), 15).waitForFinished(); // o.s == 15
+
+// Modify a copy of the original object
+QtConcurrent::run(o, 42).waitForFinished(); // o.s == 15
+
+// Use a temporary object
+QtConcurrent::run(TestClass(), 42).waitForFinished();
+
+// Ill-formed
+QtConcurrent::run(&o, 42).waitForFinished(); // compilation error
+//! [8]
+
+//! [9]
+extern void aFunction(QPromise<void> &promise);
+QFuture<void> future = QtConcurrent::run(aFunction);
+//! [9]
+
+//! [10]
+extern void aFunction(QPromise<void> &promise, int arg1, const QString &arg2);
+
+int integer = ...;
+QString string = ...;
+
+QFuture<void> future = QtConcurrent::run(aFunction, integer, string);
+//! [10]
+
+//! [11]
+void helloWorldFunction(QPromise<QString> &promise)
+{
+ promise.addResult("Hello");
+ promise.addResult("world");
+}
+
+QFuture<QString> future = QtConcurrent::run(helloWorldFunction);
+...
+QList<QString> results = future.results();
+//! [11]
+
+//! [12]
+void aFunction(QPromise<int> &promise)
+{
+ for (int i = 0; i < 100; ++i) {
+ promise.suspendIfRequested();
+ if (promise.isCanceled())
+ return;
+
+ // computes the next result, may be time consuming like 1 second
+ const int res = ... ;
+ promise.addResult(res);
+ }
+}
+
+QFuture<int> future = QtConcurrent::run(aFunction);
+
+... // user pressed a pause button after 10 seconds
+future.suspend();
+
+... // user pressed a resume button after 10 seconds
+future.resume();
+
+... // user pressed a cancel button after 10 seconds
+future.cancel();
+//! [12]
+
+//! [13]
+void aFunction(QPromise<int> &promise)
+{
+ promise.setProgressRange(0, 100);
+ int result = 0;
+ for (int i = 0; i < 100; ++i) {
+ // computes some part of the task
+ const int part = ... ;
+ result += part;
+ promise.setProgressValue(i);
+ }
+ promise.addResult(result);
+}
+
+QFutureWatcher<int> watcher;
+QObject::connect(&watcher, &QFutureWatcher::progressValueChanged, [](int progress){
+ ... ; // update GUI with a progress
+ qDebug() << "current progress:" << progress;
+});
+watcher.setFuture(QtConcurrent::run(aFunction));
+//! [13]
+
+//! [14]
+struct Functor {
+ void operator()(QPromise<int> &) { }
+ void operator()(QPromise<double> &) { }
+};
+
+Functor f;
+run<double>(f); // this will select the 2nd overload
+// run(f); // error, both candidate overloads potentially match
+//! [14]
+
+//! [15]
+void foo(int arg);
+void foo(int arg1, int arg2);
+...
+QFuture<void> future = QtConcurrent::run(foo, 42);
+//! [15]
+
+//! [16]
+QFuture<void> future = QtConcurrent::run([] { foo(42); });
+//! [16]
+
+//! [17]
+QFuture<void> future = QtConcurrent::run(static_cast<void(*)(int)>(foo), 42);
+//! [17]
+
+//! [18]
+QFuture<void> future = QtConcurrent::run(qOverload<int>(foo), 42);
+//! [18]
diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrenttask.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrenttask.cpp
new file mode 100644
index 0000000000..cb1889afb6
--- /dev/null
+++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrenttask.cpp
@@ -0,0 +1,93 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//! [0]
+QtConcurrent::task([]{ qDebug("Hello, world!"); }).spawn();
+//! [0]
+
+//! [1]
+auto task = [](const QString &s){ qDebug() << ("Hello, " + s); };
+QtConcurrent::task(std::move(task))
+ .withArguments("world!")
+ .spawn();
+//! [1]
+
+//! [2]
+QString s("Hello, ");
+QtConcurrent::task([](QString &s){ s.append("world!"); })
+ .withArguments(std::ref(s))
+ .spawn();
+//! [2]
+
+//! [3]
+auto future = QtConcurrent::task([]{ return 42; }).spawn();
+auto result = future.result(); // result == 42
+//! [3]
+
+//! [4]
+std::is_invocable_v<std::decay_t<Task>, std::decay_t<Args>...>
+//! [4]
+
+//! [5]
+QVariant value(42);
+auto result = QtConcurrent::task([](const QVariant &var){return qvariant_cast<int>(var);})
+ .withArguments(value)
+ .spawn()
+ .result(); // result == 42
+//! [5]
+
+//! [6]
+QString result("Hello, world!");
+
+QtConcurrent::task(&QString::chop)
+ .withArguments(&result, 8)
+ .spawn()
+ .waitForFinished(); // result == "Hello"
+//! [6]
+
+//! [7]
+auto result = QtConcurrent::task(std::plus<int>())
+ .withArguments(40, 2)
+ .spawn()
+ .result() // result == 42
+//! [7]
+
+//! [8]
+struct CallableWithState
+{
+ void operator()(int newState) { state = newState; }
+
+ // ...
+};
+
+// ...
+
+CallableWithState object;
+
+QtConcurrent::task(std::ref(object))
+ .withArguments(42)
+ .spawn()
+ .waitForFinished(); // The object's state is set to 42
+//! [8]
+
+//! [9]
+QThreadPool pool;
+QtConcurrent::task([]{ return 42; }).onThreadPool(pool).spawn();
+//! [9]
+
+//! [10]
+QtConcurrent::task([]{ return 42; }).withPriority(10).spawn();
+//! [10]
+
+//! [11]
+QtConcurrent::task([]{ qDebug("Hello, world!"); }).spawn(FutureResult::Ignore);
+//! [11]
+
+//! [12]
+void increment(QPromise<int> &promise, int i)
+{
+ promise.addResult(i + 1);
+}
+
+int result = QtConcurrent::task(&increment).withArguments(10).spawn().result(); // result == 11
+//! [12]
diff --git a/src/concurrent/doc/snippets/snippets.pro b/src/concurrent/doc/snippets/snippets.pro
new file mode 100644
index 0000000000..6e99051951
--- /dev/null
+++ b/src/concurrent/doc/snippets/snippets.pro
@@ -0,0 +1,3 @@
+#! [qmake_use]
+QT += concurrent
+#! [qmake_use]
diff --git a/src/concurrent/doc/src/qt6-changes.qdoc b/src/concurrent/doc/src/qt6-changes.qdoc
new file mode 100644
index 0000000000..fa23ee21a7
--- /dev/null
+++ b/src/concurrent/doc/src/qt6-changes.qdoc
@@ -0,0 +1,57 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page concurrent-changes-qt6.html
+ \title Changes to Qt Concurrent
+ \ingroup changes-qt-5-to-6
+ \brief Improved to work with a variable number of arguments.
+
+ Qt 6 is a result of the conscious effort to make the framework more
+ efficient and easy to use.
+
+ We try to maintain binary and source compatibility for all the public
+ APIs in each release. But some changes were inevitable in an effort to
+ make Qt a better framework.
+
+ In this topic we summarize those changes in Qt Concurrent, and provide
+ guidance to handle them.
+
+ \section1 QtConcurrent::run()
+
+ QtConcurrent::run() has been improved to work with a variable number
+ of arguments, so the signatures are changed to:
+
+ \code
+ // run
+ template <typename T>
+ QFuture<T> run(Function &&f, Args &&...args)
+
+ // run with a QThreadPool argument
+ template <typename T>
+ QFuture<T> run(QThreadPool *pool, Function &&f, Args &&...args)
+ \endcode
+
+ As a side effect, if \c f is a pointer to a member function, the first
+ argument of \c args should be the object for which that member is defined
+ (or a reference, or a pointer to it). So instead of writing:
+
+ \code
+ QImage image = ...;
+ QFuture<void> future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba);
+ \endcode
+
+ You have to write:
+
+ \code
+ QFuture<void> future = QtConcurrent::run(&QImage::invertPixels, &image, QImage::InvertRgba);
+ \endcode
+
+ Another side effect is that \c QtConcurrent::run() will not work with
+ overloaded functions anymore. For example, the code below won't compile:
+
+ \include qtconcurrentrun.cpp run-with-overload-calls
+
+ Other methods of QtConcurrent have no behavioral changes and do not introduce
+ source compatibility breaks.
+*/
diff --git a/src/concurrent/doc/src/qtconcurrent-examples.qdoc b/src/concurrent/doc/src/qtconcurrent-examples.qdoc
new file mode 100644
index 0000000000..06705cca1b
--- /dev/null
+++ b/src/concurrent/doc/src/qtconcurrent-examples.qdoc
@@ -0,0 +1,14 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \group qtconcurrentexamples
+ \title Qt Concurrent Examples
+ \brief Examples for the Qt Concurrent module
+ \ingroup all-examples
+ \ingroup qtconcurrent
+
+ The list of \l {Qt Concurrent} examples demonstrating how to use
+ Qt Concurrent API from C++.
+
+*/
diff --git a/src/concurrent/doc/src/qtconcurrent-index.qdoc b/src/concurrent/doc/src/qtconcurrent-index.qdoc
index 3e4aa791f1..5acf19e134 100644
--- a/src/concurrent/doc/src/qtconcurrent-index.qdoc
+++ b/src/concurrent/doc/src/qtconcurrent-index.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtconcurrent-index.html
@@ -31,18 +7,17 @@
\brief The Qt Concurrent module contains functionality to support concurrent execution of program code.
- \section1 Getting Started
- The QtConcurrent namespace provides high-level APIs that make it
+ The Qt Concurrent module provides high-level APIs that make it
possible to write multi-threaded programs without using low-level
threading primitives such as mutexes, read-write locks, wait
- conditions, or semaphores. Programs written with QtConcurrent
+ conditions, or semaphores. Programs written with Qt Concurrent
automatically adjust the number of threads used according to the
number of processor cores available. This means that applications
written today will continue to scale when deployed on multi-core
systems in the future.
- QtConcurrent includes functional programming style APIs for
+ Qt Concurrent includes functional programming style APIs for
parallel list processing, including a MapReduce and FilterReduce
implementation for shared-memory (non-distributed) systems, and
classes for managing asynchronous computations in GUI
@@ -79,6 +54,13 @@
another thread.
\endlist
+ \li \l {Concurrent Task}
+ \list
+ \li \l {QtConcurrent::task}{QtConcurrent::task()} creates an instance
+ of QtConcurrent::QTaskBuilder. This object can be used for adjusting
+ parameters and for kicking off a task in a separate thread.
+ \endlist
+
\li QFuture represents the result of an asynchronous computation.
\li QFutureIterator allows iterating through results available via QFuture.
@@ -88,11 +70,16 @@
\li QFutureSynchronizer is a convenience class that automatically
synchronizes several QFutures.
+ \li QPromise provides a way to report progress and results of the
+ asynchronous computation to QFuture. Allows suspending or canceling the task
+ when requested by QFuture.
+
\endlist
Qt Concurrent supports several STL-compatible container and iterator types,
but works best with Qt containers that have random-access iterators, such as
- QList or QVector. The map and filter functions accept both containers and begin/end iterators.
+ QList. The map and filter functions accept both containers and begin/end
+ iterators.
STL Iterator support overview:
@@ -115,31 +102,50 @@
\li Supported
\row
\li Bidirectional Iterator
- \li QLinkedList, std::list
+ \li std::list
\li Supported
\row
\li Random Access Iterator
- \li QList, QVector, std::vector
+ \li QList, std::vector
\li Supported and Recommended
\endtable
- Random access iterators can be faster in cases where Qt Concurrent is iterating
- over a large number of lightweight items, since they allow skipping to any point
- in the container. In addition, using random access iterators allows Qt Concurrent
- to provide progress information trough QFuture::progressValue() and
- QFutureWatcher::progressValueChanged().
+ Random access iterators can be faster in cases where Qt Concurrent is
+ iterating over a large number of lightweight items, since they allow
+ skipping to any point in the container. In addition, using random access
+ iterators allows Qt Concurrent to provide progress information through
+ QFuture::progressValue() and QFutureWatcher::progressValueChanged().
The non in-place modifying functions such as mapped() and filtered() makes a
- copy of the container when called. If you are using STL containers this copy operation
- might take some time, in this case we recommend specifying the begin and end iterators
- for the container instead.
+ copy of the container when called. If you are using STL containers this copy
+ operation might take some time, in this case we recommend specifying the
+ begin and end iterators for the container instead.
+
+
+ \include module-use.qdocinc using qt module
+ \snippet snippets/CMakeLists.txt cmake_use
+
+ See also the \l {Build with CMake} overview.
+
+ \include module-use.qdocinc building with qmake
+ \snippet snippets/snippets.pro qmake_use
+
+ \section1 Examples
+
+ \list
+ \li \l {Qt Concurrent Examples}
+ \endlist
+
+ \section1 Module Evolution
+ \l{Changes to Qt Concurrent} lists important changes in the module API
+ and functionality that were done for the Qt 6 series of Qt.
\section1 Licenses
- The Qt Concurrent module is available under commercial licenses from \l{The Qt Company}.
- In addition, it is available under free software licenses. Since Qt 5.4,
- these free software licenses are
- \l{GNU Lesser General Public License, version 3}, or
+ The Qt Concurrent module is available under commercial licenses from
+ \l{The Qt Company}.
+ In addition, it is available under free software licenses:
+ The \l{GNU Lesser General Public License, version 3}, or
the \l{GNU General Public License, version 2}.
See \l{Qt Licensing} for further details.
*/
diff --git a/src/concurrent/doc/src/qtconcurrent-module.qdoc b/src/concurrent/doc/src/qtconcurrent-module.qdoc
index 9289b4bfa8..ce132c13b7 100644
--- a/src/concurrent/doc/src/qtconcurrent-module.qdoc
+++ b/src/concurrent/doc/src/qtconcurrent-module.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\module QtConcurrent
@@ -31,22 +7,8 @@
\brief The Qt Concurrent module contains functionality to support concurrent execution of program code.
\ingroup modules
+ \qtcmakepackage Concurrent
\qtvariable concurrent
- The Qt Concurrent module extends the basic threading support found in \l{Qt Core} module and
- simplifies the development of code that can be executed in parallel on all available CPU cores.
-*/
-
-/*!
- \typedef QtConcurrent::Exception
- \obsolete
-
- Use QException from \l{Qt Core} instead.
-*/
-
-/*!
- \typedef QtConcurrent::UnhandledException
- \obsolete
-
- Use QUnhandledException from \l{Qt Core} instead.
+ The \l{Qt Concurrent} page contains information about how to use the module.
*/
diff --git a/src/concurrent/qtaskbuilder.h b/src/concurrent/qtaskbuilder.h
new file mode 100644
index 0000000000..95ab8021e7
--- /dev/null
+++ b/src/concurrent/qtaskbuilder.h
@@ -0,0 +1,135 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTBASE_QTTASKBUILDER_H
+#define QTBASE_QTTASKBUILDER_H
+
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
+
+#include <QtConcurrent/qtconcurrentstoredfunctioncall.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_QDOC
+
+namespace QtConcurrent {
+
+enum class FutureResult { Ignore };
+
+using InvokeResultType = int;
+
+template <class Task, class ...Args>
+class QTaskBuilder
+{
+public:
+ [[nodiscard]]
+ QFuture<InvokeResultType> spawn();
+
+ void spawn(FutureResult);
+
+ template <class ...ExtraArgs>
+ [[nodiscard]]
+ QTaskBuilder<Task, ExtraArgs...> withArguments(ExtraArgs &&...args);
+
+ [[nodiscard]]
+ QTaskBuilder<Task, Args...> &onThreadPool(QThreadPool &newThreadPool);
+
+ [[nodiscard]]
+ QTaskBuilder<Task, Args...> &withPriority(int newPriority);
+};
+
+} // namespace QtConcurrent
+
+#else
+
+namespace QtConcurrent {
+
+enum class FutureResult { Ignore };
+
+template <class Task, class ...Args>
+class QTaskBuilder
+{
+public:
+ [[nodiscard]]
+ auto spawn()
+ {
+ return TaskResolver<std::decay_t<Task>, std::decay_t<Args>...>::run(
+ std::move(taskWithArgs), startParameters);
+ }
+
+ // We don't want to run with promise when we don't return a QFuture
+ void spawn(FutureResult)
+ {
+ (new StoredFunctionCall<Task, Args...>(std::move(taskWithArgs)))
+ ->start(startParameters);
+ }
+
+ template <class ...ExtraArgs>
+ [[nodiscard]]
+ constexpr auto withArguments(ExtraArgs &&...args)
+ {
+ static_assert(std::tuple_size_v<TaskWithArgs> == 1,
+ "This function cannot be invoked if "
+ "arguments have already been passed.");
+
+ static_assert(sizeof...(ExtraArgs) >= 1,
+ "One or more arguments must be passed.");
+
+ // We have to re-create a builder, because the type has changed
+ return QTaskBuilder<Task, ExtraArgs...>(
+ startParameters,
+ std::get<0>(std::move(taskWithArgs)),
+ std::forward<ExtraArgs>(args)...
+ );
+ }
+
+ [[nodiscard]]
+ constexpr auto &onThreadPool(QThreadPool &newThreadPool)
+ {
+ startParameters.threadPool = &newThreadPool;
+ return *this;
+ }
+
+ [[nodiscard]]
+ constexpr auto &withPriority(int newPriority)
+ {
+ startParameters.priority = newPriority;
+ return *this;
+ }
+
+protected: // Methods
+ constexpr explicit QTaskBuilder(Task &&task, Args &&...arguments)
+ : taskWithArgs{std::forward<Task>(task), std::forward<Args>(arguments)...}
+ {}
+
+ constexpr QTaskBuilder(
+ const TaskStartParameters &parameters, Task &&task, Args &&...arguments)
+ : taskWithArgs{std::forward<Task>(task), std::forward<Args>(arguments)...}
+ , startParameters{parameters}
+ {}
+
+private: // Methods
+ // Required for creating a builder from "task" function
+ template <class T>
+ friend constexpr auto task(T &&t);
+
+ // Required for creating a new builder from "withArguments" function
+ template <class T, class ...A>
+ friend class QTaskBuilder;
+
+private: // Data
+ using TaskWithArgs = DecayedTuple<Task, Args...>;
+
+ TaskWithArgs taskWithArgs;
+ TaskStartParameters startParameters;
+};
+
+} // namespace QtConcurrent
+
+#endif // Q_QDOC
+
+QT_END_NAMESPACE
+
+#endif // !defined(QT_NO_CONCURRENT)
+
+#endif //QTBASE_QTTASKBUILDER_H
diff --git a/src/concurrent/qtaskbuilder.qdoc b/src/concurrent/qtaskbuilder.qdoc
new file mode 100644
index 0000000000..811a48f62b
--- /dev/null
+++ b/src/concurrent/qtaskbuilder.qdoc
@@ -0,0 +1,77 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \class QtConcurrent::QTaskBuilder
+ \inmodule QtConcurrent
+ \brief The QTaskBuilder class is used for adjusting task parameters.
+ \since 6.0
+
+ \ingroup thread
+
+ It's not possible to create an object of this class manually. See
+ \l {Concurrent Task} for more details and usage examples.
+*/
+
+/*!
+ \fn template <class Task, class ...Args> [[nodiscard]] QFuture<InvokeResultType> QtConcurrent::QTaskBuilder<Task, Args...>::spawn()
+
+ Runs the task in a separate thread and returns a future object immediately.
+ This is a non-blocking call. The task might not start immediately.
+*/
+
+/*!
+ \fn template <class Task, class ...Args> void QtConcurrent::QTaskBuilder<Task, Args...>::spawn(QtConcurrent::FutureResult)
+
+ Runs the task in a separate thread. This is a non-blocking call.
+ The task might not start immediately.
+*/
+
+/*!
+ \fn template <class Task, class ...Args> template <class ...ExtraArgs> [[nodiscard]] QTaskBuilder<Task, ExtraArgs...> QtConcurrent::QTaskBuilder<Task, Args...>::withArguments(ExtraArgs &&...args)
+
+ Sets the arguments \a args the task will be invoked with. The code is ill-formed
+ (causes compilation errors) if:
+ \list
+ \li This function is invoked more than once.
+ \li The arguments count is zero.
+ \endlist
+*/
+
+/*!
+ \fn template <class Task, class ...Args> [[nodiscard]] QTaskBuilder<Task, Args...> &QtConcurrent::QTaskBuilder<Task, Args...>::onThreadPool(QThreadPool &newThreadPool)
+
+ Sets the thread pool \a newThreadPool that the task will be invoked on.
+*/
+
+/*!
+ \fn template <class Task, class ...Args> [[nodiscard]] QTaskBuilder<Task, Args...> &QtConcurrent::QTaskBuilder<Task, Args...>::withPriority(int newPriority)
+
+ Sets the priority \a newPriority that the task will be invoked with.
+*/
+
+/*!
+ \typedef QtConcurrent::InvokeResultType
+ \relates QtConcurrent::QTaskBuilder
+
+ The simplified definition of this type looks like this:
+ \code
+ template <class Task, class ...Args>
+ using InvokeResultType = std::invoke_result_t<std::decay_t<Task>, std::decay_t<Args>...>;
+ \endcode
+
+ The real implementation also contains a compile-time check for
+ whether the task can be invoked with the specified arguments or not.
+*/
+
+/*!
+ \enum QtConcurrent::FutureResult
+
+ This enum type is used to invoke a special overload of
+ QtConcurrent::QTaskBuilder::spawn(QtConcurrent::FutureResult)
+ that doesn't return a future object.
+
+ \value Ignore
+ An auxiliary tag which introduced to improve code
+ readability.
+*/
diff --git a/src/concurrent/qtconcurrent_global.h b/src/concurrent/qtconcurrent_global.h
index 83c6028e20..0d5e310c84 100644
--- a/src/concurrent/qtconcurrent_global.h
+++ b/src/concurrent/qtconcurrent_global.h
@@ -1,59 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_GLOBAL_H
#define QTCONCURRENT_GLOBAL_H
#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_STATIC
-# if defined(QT_BUILD_CONCURRENT_LIB)
-# define Q_CONCURRENT_EXPORT Q_DECL_EXPORT
-# else
-# define Q_CONCURRENT_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define Q_CONCURRENT_EXPORT
-#endif
-
-QT_END_NAMESPACE
+#include <QtConcurrent/qtconcurrentexports.h>
#endif // include guard
diff --git a/src/concurrent/qtconcurrentcompilertest.h b/src/concurrent/qtconcurrentcompilertest.h
index 72cf1670a0..df2e30d222 100644
--- a/src/concurrent/qtconcurrentcompilertest.h
+++ b/src/concurrent/qtconcurrentcompilertest.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_COMPILERTEST_H
#define QTCONCURRENT_COMPILERTEST_H
@@ -48,16 +12,26 @@ QT_BEGIN_NAMESPACE
namespace QtPrivate {
-template<class T>
-class HasResultType {
- typedef char Yes;
- typedef void *No;
- template<typename U> static Yes test(int, const typename U::result_type * = nullptr);
- template<typename U> static No test(double);
-public:
- enum { Value = (sizeof(test<T>(0)) == sizeof(Yes)) };
-};
-
+ template <class T, typename = void>
+ struct IsIterable : std::false_type {};
+ template <class T>
+ struct IsIterable<T, std::void_t<decltype(std::declval<T>().begin()),
+ decltype(std::declval<T>().end())>>
+ : std::true_type
+ { };
+
+ template <class T>
+ inline constexpr bool IsIterableValue = IsIterable<T>::value;
+
+ template <class T, typename = void>
+ struct IsDereferenceable : std::false_type {};
+ template <class T>
+ struct IsDereferenceable<T, std::void_t<decltype(*std::declval<T>())>>
+ : std::true_type
+ { };
+
+ template <class T>
+ inline constexpr bool IsDereferenceableValue = IsDereferenceable<T>::value;
}
QT_END_NAMESPACE
diff --git a/src/concurrent/qtconcurrentexception.h b/src/concurrent/qtconcurrentexception.h
deleted file mode 100644
index 8a3986a1a3..0000000000
--- a/src/concurrent/qtconcurrentexception.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTCONCURRENT_EXCEPTION_H
-#define QTCONCURRENT_EXCEPTION_H
-
-#include <QtConcurrent/qtconcurrent_global.h>
-#include <QtCore/qexception.h>
-
-QT_REQUIRE_CONFIG(concurrent);
-
-QT_BEGIN_NAMESPACE
-
-
-namespace QtConcurrent
-{
-
-#if !defined(QT_NO_EXCEPTIONS) || defined(Q_CLANG_QDOC)
-
-typedef Q_DECL_DEPRECATED QException Exception;
-typedef Q_DECL_DEPRECATED QUnhandledException UnhandledException;
-
-#endif
-
-} // namespace QtConcurrent
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/concurrent/qtconcurrentfilter.cpp b/src/concurrent/qtconcurrentfilter.cpp
index 606a9dbe03..35141d2d7e 100644
--- a/src/concurrent/qtconcurrentfilter.cpp
+++ b/src/concurrent/qtconcurrentfilter.cpp
@@ -1,55 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/*!
\page qtconcurrentfilter.html
\title Concurrent Filter and Filter-Reduce
+ \brief Selecting values from a sequence and combining them, all in parallel.
\ingroup thread
The QtConcurrent::filter(), QtConcurrent::filtered() and
QtConcurrent::filteredReduced() functions filter items in a sequence such
- as a QList or a QVector in parallel. QtConcurrent::filter() modifies a
+ as a QList in parallel. QtConcurrent::filter() modifies a
sequence in-place, QtConcurrent::filtered() returns a new sequence
containing the filtered content, and QtConcurrent::filteredReduced()
returns a single result.
- These functions are a part of the \l {Qt Concurrent} framework.
+ These functions are part of the \l {Qt Concurrent} framework.
Each of the above functions have a blocking variant that returns the final
result instead of a QFuture. You use them in the same way as the
@@ -93,7 +58,7 @@
\section1 Concurrent Filter-Reduce
QtConcurrent::filteredReduced() is similar to QtConcurrent::filtered(),
- but instead of returing a sequence with the filtered results, the results
+ but instead of returning a sequence with the filtered results, the results
are combined into a single value using a reduce function.
The reduce function must be of the form:
@@ -134,7 +99,10 @@
\snippet code/src_concurrent_qtconcurrentfilter.cpp 7
- Note that when using QtConcurrent::filteredReduced(), you can mix the use of
+ Note the use of qOverload. It is needed to resolve the ambiguity for the
+ methods, that have multiple overloads.
+
+ Also note that when using QtConcurrent::filteredReduced(), you can mix the use of
normal and member functions freely:
\snippet code/src_concurrent_qtconcurrentfilter.cpp 8
@@ -144,17 +112,32 @@
QtConcurrent::filter(), QtConcurrent::filtered(), and
QtConcurrent::filteredReduced() accept function objects
for the filter function. These function objects can be used to
- add state to a function call. The result_type typedef must define the
- result type of the function call operator:
+ add state to a function call:
\snippet code/src_concurrent_qtconcurrentfilter.cpp 13
- For the reduce function, function objects are not directly
- supported. Function objects can, however, be used
- when the type of the reduction result is explicitly specified:
+ Function objects are also supported for the reduce function:
\snippet code/src_concurrent_qtconcurrentfilter.cpp 14
+ \section2 Using Lambda Expressions
+
+ QtConcurrent::filter(), QtConcurrent::filtered(), and
+ QtConcurrent::filteredReduced() accept lambda expressions for the filter and
+ reduce function:
+
+ \snippet code/src_concurrent_qtconcurrentfilter.cpp 15
+
+ When using QtConcurrent::filteredReduced() or
+ QtConcurrent::blockingFilteredReduced(), you can mix the use of normal
+ functions, member functions and lambda expressions freely.
+
+ \snippet code/src_concurrent_qtconcurrentfilter.cpp 16
+
+ You can also pass a lambda as a reduce object:
+
+ \snippet code/src_concurrent_qtconcurrentfilter.cpp 17
+
\section2 Wrapping Functions that Take Multiple Arguments
If you want to use a filter function takes more than one argument, you can
@@ -212,22 +195,51 @@
*/
/*!
- \fn [QtConcurrent-1] template <typename Sequence, typename KeepFunctor, typename ReduceFunctor> ThreadEngineStarter<void> QtConcurrent::filterInternal(Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce)
+ \fn [QtConcurrent-1] template <typename Sequence, typename KeepFunctor, typename ReduceFunctor> ThreadEngineStarter<void> QtConcurrent::filterInternal(Sequence &sequence, KeepFunctor &&keep, ReduceFunctor &&reduce)
\internal
*/
/*!
- \fn template <typename Sequence, typename KeepFunctor> QFuture<void> QtConcurrent::filter(Sequence &sequence, KeepFunctor filterFunction)
+ \fn template <typename Sequence, typename KeepFunctor> QFuture<void> QtConcurrent::filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
+
+ Calls \a filterFunction once for each item in \a sequence.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true, the item is kept in \a sequence;
+ otherwise, the item is removed from \a sequence.
+
+ Note that this method doesn't have an overload working with iterators, because
+ it invalidates the iterators of the sequence it operates on.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename KeepFunctor> QFuture<void> QtConcurrent::filter(Sequence &sequence, KeepFunctor &&filterFunction)
Calls \a filterFunction once for each item in \a sequence. If
\a filterFunction returns \c true, the item is kept in \a sequence;
otherwise, the item is removed from \a sequence.
+ Note that this method doesn't have an overload working with iterators, because
+ it invalidates the iterators of the sequence it operates on.
+
\sa {Concurrent Filter and Filter-Reduce}
*/
/*!
- \fn template <typename Sequence, typename KeepFunctor> QFuture<Sequence::value_type> QtConcurrent::filtered(const Sequence &sequence, KeepFunctor filterFunction)
+ \fn template <typename Sequence, typename KeepFunctor> QFuture<Sequence::value_type> QtConcurrent::filtered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&filterFunction)
+
+ Calls \a filterFunction once for each item in \a sequence and returns a
+ new Sequence of kept items. All calls to \a filterFunction are invoked from the threads
+ taken from the QThreadPool \a pool. If \a filterFunction returns \c true, a copy of
+ the item is put in the new Sequence. Otherwise, the item will \e not
+ appear in the new Sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename KeepFunctor> QFuture<Sequence::value_type> QtConcurrent::filtered(Sequence &&sequence, KeepFunctor &&filterFunction)
Calls \a filterFunction once for each item in \a sequence and returns a
new Sequence of kept items. If \a filterFunction returns \c true, a copy of
@@ -238,7 +250,19 @@
*/
/*!
- \fn template <typename Iterator, typename KeepFunctor> QFuture<typename QtConcurrent::qValueType<Iterator>::value_type> QtConcurrent::filtered(Iterator begin, Iterator end, KeepFunctor filterFunction)
+ \fn template <typename Iterator, typename KeepFunctor> QFuture<typename QtConcurrent::qValueType<Iterator>::value_type> QtConcurrent::filtered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&filterFunction)
+
+ Calls \a filterFunction once for each item from \a begin to \a end and
+ returns a new Sequence of kept items. All calls to \a filterFunction are invoked from the threads
+ taken from the QThreadPool \a pool. If \a filterFunction returns \c true, a
+ copy of the item is put in the new Sequence. Otherwise, the item will
+ \e not appear in the new Sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename Iterator, typename KeepFunctor> QFuture<typename QtConcurrent::qValueType<Iterator>::value_type> QtConcurrent::filtered(Iterator begin, Iterator end, KeepFunctor &&filterFunction)
Calls \a filterFunction once for each item from \a begin to \a end and
returns a new Sequence of kept items. If \a filterFunction returns \c true, a
@@ -249,7 +273,26 @@
*/
/*!
- \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::filteredReduced(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::filteredReduced(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item in \a sequence.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which \a reduceFunction
+ is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of
+ the original sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::filteredReduced(Sequence &&sequence, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a filterFunction once for each item in \a sequence. If
\a filterFunction returns \c true for an item, that item is then passed to
@@ -267,7 +310,69 @@
*/
/*!
- \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::filteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::filteredReduced(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item in \a sequence.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which \a reduceFunction
+ is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of
+ the original sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::filteredReduced(Sequence &&sequence, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item in \a sequence. If
+ \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which \a reduceFunction
+ is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of
+ the original sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::filteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item from \a begin to \a end.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which
+ \a reduceFunction is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order
+ of the original sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::filteredReduced(Iterator begin, Iterator end, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a filterFunction once for each item from \a begin to \a end. If
\a filterFunction returns \c true for an item, that item is then passed to
@@ -285,19 +390,95 @@
*/
/*!
- \fn template <typename Sequence, typename KeepFunctor> void QtConcurrent::blockingFilter(Sequence &sequence, KeepFunctor filterFunction)
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::filteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
- Calls \a filterFunction once for each item in \a sequence. If
- \a filterFunction returns \c true, the item is kept in \a sequence;
- otherwise, the item is removed from \a sequence.
+ Calls \a filterFunction once for each item from \a begin to \a end.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
- \note This function will block until all items in the sequence have been processed.
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which
+ \a reduceFunction is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order
+ of the original sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::filteredReduced(Iterator begin, Iterator end, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item from \a begin to \a end. If
+ \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which
+ \a reduceFunction is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order
+ of the original sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename KeepFunctor> void QtConcurrent::blockingFilter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
+
+ Calls \a filterFunction once for each item in \a sequence.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true, the item is kept in \a sequence;
+ otherwise, the item is removed from \a sequence.
+
+ Note that this method doesn't have an overload working with iterators, because
+ it invalidates the iterators of the sequence it operates on.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename KeepFunctor> void QtConcurrent::blockingFilter(Sequence &sequence, KeepFunctor &&filterFunction)
+
+ Calls \a filterFunction once for each item in \a sequence. If
+ \a filterFunction returns \c true, the item is kept in \a sequence;
+ otherwise, the item is removed from \a sequence.
+
+ Note that this method doesn't have an overload working with iterators, because
+ it invalidates the iterators of the sequence it operates on.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename KeepFunctor> Sequence QtConcurrent::blockingFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&filterFunction)
+
+ Calls \a filterFunction once for each item in \a sequence and returns a
+ new Sequence of kept items. All calls to \a filterFunction are invoked from the threads
+ taken from the QThreadPool \a pool. If \a filterFunction returns \c true, a copy of
+ the item is put in the new Sequence. Otherwise, the item will \e not
+ appear in the new Sequence.
+
+ \note This function will block until all items in the sequence have been processed.
- \sa {Concurrent Filter and Filter-Reduce}
+ \sa filtered(), {Concurrent Filter and Filter-Reduce}
*/
/*!
- \fn template <typename Sequence, typename KeepFunctor> Sequence QtConcurrent::blockingFiltered(const Sequence &sequence, KeepFunctor filterFunction)
+ \fn template <typename Sequence, typename KeepFunctor> Sequence QtConcurrent::blockingFiltered(Sequence &&sequence, KeepFunctor &&filterFunction)
Calls \a filterFunction once for each item in \a sequence and returns a
new Sequence of kept items. If \a filterFunction returns \c true, a copy of
@@ -310,7 +491,22 @@
*/
/*!
- \fn template <typename OutputSequence, typename Iterator, typename KeepFunctor> OutputSequence QtConcurrent::blockingFiltered(Iterator begin, Iterator end, KeepFunctor filterFunction)
+ \fn template <typename OutputSequence, typename Iterator, typename KeepFunctor> OutputSequence QtConcurrent::blockingFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&filterFunction)
+
+ Calls \a filterFunction once for each item from \a begin to \a end and
+ returns a new Sequence of kept items. All calls to \a filterFunction are invoked from the threads
+ taken from the QThreadPool \a pool. If \a filterFunction returns \c true, a
+ copy of the item is put in the new Sequence. Otherwise, the item will
+ \e not appear in the new Sequence.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa filtered(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename OutputSequence, typename Iterator, typename KeepFunctor> OutputSequence QtConcurrent::blockingFiltered(Iterator begin, Iterator end, KeepFunctor &&filterFunction)
Calls \a filterFunction once for each item from \a begin to \a end and
returns a new Sequence of kept items. If \a filterFunction returns \c true, a
@@ -324,7 +520,28 @@
*/
/*!
- \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingFilteredReduced(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingFilteredReduced(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item in \a sequence.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which \a reduceFunction
+ is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of
+ the original sequence.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingFilteredReduced(Sequence &&sequence, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a filterFunction once for each item in \a sequence. If
\a filterFunction returns \c true for an item, that item is then passed to
@@ -344,7 +561,76 @@
*/
/*!
- \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingFilteredReduced(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item in \a sequence.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which \a reduceFunction
+ is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of
+ the original sequence.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingFilteredReduced(Sequence &&sequence, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item in \a sequence. If
+ \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which \a reduceFunction
+ is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of
+ the original sequence.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item from \a begin to \a end.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which
+ \a reduceFunction is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order
+ of the original sequence.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a filterFunction once for each item from \a begin to \a end. If
\a filterFunction returns \c true for an item, that item is then passed to
@@ -365,22 +651,80 @@
*/
/*!
- \fn [QtConcurrent-2] ThreadEngineStarter<typename qValueType<Iterator>::value_type> QtConcurrent::startFiltered(Iterator begin, Iterator end, KeepFunctor functor)
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item from \a begin to \a end.
+ All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool.
+ If \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which
+ \a reduceFunction is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order
+ of the original sequence.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor &&filterFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item from \a begin to \a end. If
+ \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which
+ \a reduceFunction is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order
+ of the original sequence.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
+ \fn [QtConcurrent-2] ThreadEngineStarter<typename qValueType<Iterator>::value_type> QtConcurrent::startFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&functor)
+ \internal
+*/
+
+/*!
+ \fn [QtConcurrent-3] ThreadEngineStarter<typename Sequence::value_type> QtConcurrent::startFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&functor)
\internal
*/
/*!
- \fn [QtConcurrent-3] ThreadEngineStarter<typename Sequence::value_type> QtConcurrent::startFiltered(const Sequence &sequence, KeepFunctor functor)
+ \fn [QtConcurrent-4] ThreadEngineStarter<ResultType> QtConcurrent::startFilteredReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ReduceOptions options)
\internal
*/
/*!
- \fn [QtConcurrent-4] ThreadEngineStarter<ResultType> QtConcurrent::startFilteredReduced(const Sequence & sequence, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options)
+ \fn [QtConcurrent-5] ThreadEngineStarter<ResultType> QtConcurrent::startFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ReduceOptions options)
\internal
*/
/*!
- \fn [QtConcurrent-5] ThreadEngineStarter<ResultType> QtConcurrent::startFilteredReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options)
+ \fn [QtConcurrent-6] ThreadEngineStarter<ResultType> QtConcurrent::startFilteredReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ResultType &&initialValue, ReduceOptions options)
\internal
*/
+/*!
+ \fn [QtConcurrent-7] ThreadEngineStarter<ResultType> QtConcurrent::startFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ResultType &&initialValue, ReduceOptions options)
+ \internal
+*/
diff --git a/src/concurrent/qtconcurrentfilter.h b/src/concurrent/qtconcurrentfilter.h
index d01b351ad0..d9fbc1b019 100644
--- a/src/concurrent/qtconcurrentfilter.h
+++ b/src/concurrent/qtconcurrentfilter.h
@@ -1,48 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_FILTER_H
#define QTCONCURRENT_FILTER_H
+#if 0
+#pragma qt_class(QtConcurrentFilter)
+#endif
+
#include <QtConcurrent/qtconcurrent_global.h>
-#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtConcurrent/qtconcurrentfilterkernel.h>
#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
@@ -53,166 +21,693 @@ namespace QtConcurrent {
//! [QtConcurrent-1]
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
-ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce)
+ThreadEngineStarter<void> filterInternal(QThreadPool *pool, Sequence &sequence,
+ KeepFunctor &&keep, ReduceFunctor &&reduce)
{
- typedef FilterKernel<Sequence, KeepFunctor, ReduceFunctor> KernelType;
- return startThreadEngine(new KernelType(sequence, keep, reduce));
+ typedef FilterKernel<Sequence, std::decay_t<KeepFunctor>, std::decay_t<ReduceFunctor>>
+ KernelType;
+ return startThreadEngine(new KernelType(pool, sequence, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce)));
}
// filter() on sequences
template <typename Sequence, typename KeepFunctor>
-QFuture<void> filter(Sequence &sequence, KeepFunctor keep)
+QFuture<void> filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&keep)
{
- return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper());
+ return filterInternal(pool, sequence, std::forward<KeepFunctor>(keep),
+ QtPrivate::PushBackWrapper());
+}
+
+template <typename Sequence, typename KeepFunctor>
+QFuture<void> filter(Sequence &sequence, KeepFunctor &&keep)
+{
+ return filterInternal(QThreadPool::globalInstance(),
+ sequence, std::forward<KeepFunctor>(keep), QtPrivate::PushBackWrapper());
}
// filteredReduced() on sequences
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
-QFuture<ResultType> filteredReduced(const Sequence &sequence,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+QFuture<ResultType> filteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return startFilteredReduced<ResultType>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options);
+ return startFilteredReduced<ResultType>(pool, std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
}
-#ifndef Q_CLANG_QDOC
-template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
-QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filteredReduced(const Sequence &sequence,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
+QFuture<ResultType> filteredReduced(Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
- (sequence,
- QtPrivate::createFunctionWrapper(keep),
- QtPrivate::createFunctionWrapper(reduce),
- options);
+ return startFilteredReduced<ResultType>(
+ QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce), options);
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> filteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> filteredReduced(Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+#ifndef Q_QDOC
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+QFuture<ResultType> filteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(pool, std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+}
+
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+QFuture<ResultType> filteredReduced(Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce), options);
+}
+
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+QFuture<ResultType> filteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+QFuture<ResultType> filteredReduced(Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#endif
// filteredReduced() on iterators
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
+QFuture<ResultType> filteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+}
+
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
QFuture<ResultType> filteredReduced(Iterator begin,
Iterator end,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return startFilteredReduced<ResultType>(begin, end, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options);
+ return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end,
+ std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
}
-#ifndef Q_CLANG_QDOC
-template <typename Iterator, typename KeepFunctor, typename ReduceFunctor>
-QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filteredReduced(Iterator begin,
+#ifdef Q_QDOC
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> filteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> filteredReduced(Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ QThreadPool::globalInstance(), begin, end, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+#ifndef Q_QDOC
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+QFuture<ResultType> filteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+}
+
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+QFuture<ResultType> filteredReduced(Iterator begin,
Iterator end,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
- (begin, end,
- QtPrivate::createFunctionWrapper(keep),
- QtPrivate::createFunctionWrapper(reduce),
- options);
+ return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end,
+ std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+}
+
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+QFuture<ResultType> filteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+QFuture<ResultType> filteredReduced(Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ QThreadPool::globalInstance(), begin, end, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
}
#endif
// filtered() on sequences
template <typename Sequence, typename KeepFunctor>
-QFuture<typename Sequence::value_type> filtered(const Sequence &sequence, KeepFunctor keep)
+QFuture<typename std::decay_t<Sequence>::value_type> filtered(QThreadPool *pool,Sequence &&sequence,
+ KeepFunctor &&keep)
+{
+ return startFiltered(pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep));
+}
+
+template <typename Sequence, typename KeepFunctor>
+QFuture<typename std::decay_t<Sequence>::value_type> filtered(Sequence &&sequence,
+ KeepFunctor &&keep)
{
- return startFiltered(sequence, QtPrivate::createFunctionWrapper(keep));
+ return startFiltered(QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(keep));
}
// filtered() on iterators
template <typename Iterator, typename KeepFunctor>
-QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, Iterator end, KeepFunctor keep)
+QFuture<typename qValueType<Iterator>::value_type> filtered(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep)
{
- return startFiltered(begin, end, QtPrivate::createFunctionWrapper(keep));
+ return startFiltered(pool, begin, end, std::forward<KeepFunctor>(keep));
+}
+
+template <typename Iterator, typename KeepFunctor>
+QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep)
+{
+ return startFiltered(QThreadPool::globalInstance(), begin, end,
+ std::forward<KeepFunctor>(keep));
}
// blocking filter() on sequences
template <typename Sequence, typename KeepFunctor>
-void blockingFilter(Sequence &sequence, KeepFunctor keep)
+void blockingFilter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&keep)
+{
+ QFuture<void> future = filter(pool, sequence, std::forward<KeepFunctor>(keep));
+ future.waitForFinished();
+}
+
+template <typename Sequence, typename KeepFunctor>
+void blockingFilter(Sequence &sequence, KeepFunctor &&keep)
{
- filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()).startBlocking();
+ QFuture<void> future = filter(sequence, std::forward<KeepFunctor>(keep));
+ future.waitForFinished();
}
// blocking filteredReduced() on sequences
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
-ResultType blockingFilteredReduced(const Sequence &sequence,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+ResultType blockingFilteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return startFilteredReduced<ResultType>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options)
- .startBlocking();
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
}
-#ifndef Q_CLANG_QDOC
-template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
-typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFilteredReduced(const Sequence &sequence,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
+ResultType blockingFilteredReduced(Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingFilteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingFilteredReduced(Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+#ifndef Q_QDOC
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+ResultType blockingFilteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+ResultType blockingFilteredReduced(Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+ResultType blockingFilteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return blockingFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
- (sequence,
- QtPrivate::createFunctionWrapper(keep),
- QtPrivate::createFunctionWrapper(reduce),
- options);
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInvocable<KeepFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+ResultType blockingFilteredReduced(Sequence &&sequence,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
}
#endif
// blocking filteredReduced() on iterators
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
+ResultType blockingFilteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future =
+ filteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
ResultType blockingFilteredReduced(Iterator begin,
Iterator end,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return startFilteredReduced<ResultType>
- (begin, end,
- QtPrivate::createFunctionWrapper(keep),
- QtPrivate::createFunctionWrapper(reduce),
- options)
- .startBlocking();
+ QFuture<ResultType> future =
+ filteredReduced<ResultType>(begin, end, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
}
-#ifndef Q_CLANG_QDOC
-template <typename Iterator, typename KeepFunctor, typename ReduceFunctor>
-typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFilteredReduced(Iterator begin,
+#ifdef Q_QDOC
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingFilteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingFilteredReduced(Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+#ifndef Q_QDOC
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+ResultType blockingFilteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future =
+ filteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+ResultType blockingFilteredReduced(Iterator begin,
Iterator end,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
- (begin, end,
- QtPrivate::createFunctionWrapper(keep),
- QtPrivate::createFunctionWrapper(reduce),
- options)
- .startBlocking();
+ QFuture<ResultType> future =
+ filteredReduced<ResultType>(begin, end, std::forward<KeepFunctor>(keep),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+ResultType blockingFilteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end, KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+ResultType blockingFilteredReduced(Iterator begin,
+ Iterator end,
+ KeepFunctor &&keep,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = filteredReduced<ResultType>(
+ begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
}
#endif
// blocking filtered() on sequences
template <typename Sequence, typename KeepFunctor>
-Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep)
+std::decay_t<Sequence> blockingFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep)
{
- return startFilteredReduced<Sequence>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking();
+ return blockingFilteredReduced<std::decay_t<Sequence>>(
+ pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
+}
+
+template <typename Sequence, typename KeepFunctor>
+std::decay_t<Sequence> blockingFiltered(Sequence &&sequence, KeepFunctor &&keep)
+{
+ return blockingFilteredReduced<std::decay_t<Sequence>>(
+ QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(keep), QtPrivate::PushBackWrapper(), OrderedReduce);
}
// blocking filtered() on iterators
template <typename OutputSequence, typename Iterator, typename KeepFunctor>
-OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep)
+OutputSequence blockingFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&keep)
+{
+ return blockingFilteredReduced<OutputSequence>(pool, begin, end,
+ std::forward<KeepFunctor>(keep),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
+}
+
+template <typename OutputSequence, typename Iterator, typename KeepFunctor>
+OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor &&keep)
{
- return startFilteredReduced<OutputSequence>(begin, end,
- QtPrivate::createFunctionWrapper(keep),
- QtPrivate::PushBackWrapper(),
- OrderedReduce).startBlocking();
+ return blockingFilteredReduced<OutputSequence>(QThreadPool::globalInstance(), begin, end,
+ std::forward<KeepFunctor>(keep),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
}
} // namespace QtConcurrent
diff --git a/src/concurrent/qtconcurrentfilterkernel.h b/src/concurrent/qtconcurrentfilterkernel.h
index e921a3d51a..68664c7f52 100644
--- a/src/concurrent/qtconcurrentfilterkernel.h
+++ b/src/concurrent/qtconcurrentfilterkernel.h
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_FILTERKERNEL_H
#define QTCONCURRENT_FILTERKERNEL_H
#include <QtConcurrent/qtconcurrent_global.h>
-#if !defined(QT_NO_CONCURRENT) || defined (Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined (Q_QDOC)
#include <QtConcurrent/qtconcurrentiteratekernel.h>
#include <QtConcurrent/qtconcurrentmapkernel.h>
@@ -78,7 +42,7 @@ class FilterKernel : public IterateKernel<typename Sequence::const_iterator, voi
{
typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
- typedef typename ReduceFunctor::result_type T;
+ typedef void T;
Sequence reducedResult;
Sequence &sequence;
@@ -87,12 +51,14 @@ class FilterKernel : public IterateKernel<typename Sequence::const_iterator, voi
Reducer reducer;
public:
- FilterKernel(Sequence &_sequence, KeepFunctor _keep, ReduceFunctor _reduce)
- : IterateKernelType(const_cast<const Sequence &>(_sequence).begin(), const_cast<const Sequence &>(_sequence).end()), reducedResult(),
+ template <typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
+ FilterKernel(QThreadPool *pool, Sequence &_sequence, Keep &&_keep, Reduce &&_reduce)
+ : IterateKernelType(pool, const_cast<const Sequence &>(_sequence).begin(),
+ const_cast<const Sequence &>(_sequence).end()), reducedResult(),
sequence(_sequence),
- keep(_keep),
- reduce(_reduce),
- reducer(OrderedReduce)
+ keep(std::forward<Keep>(_keep)),
+ reduce(std::forward<Reduce>(_reduce)),
+ reducer(pool, OrderedReduce)
{ }
bool runIteration(typename Sequence::const_iterator it, int index, T *) override
@@ -101,11 +67,11 @@ public:
results.begin = index;
results.end = index + 1;
- if (keep(*it))
- results.vector.append(*it);
+ if (std::invoke(keep, *it))
+ results.vector.append(*it);
- reducer.runReduce(reduce, reducedResult, results);
- return false;
+ reducer.runReduce(reduce, reducedResult, results);
+ return false;
}
bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *) override
@@ -119,7 +85,7 @@ public:
typename Sequence::const_iterator it = sequenceBeginIterator;
std::advance(it, begin);
for (int i = begin; i < end; ++i) {
- if (keep(*it))
+ if (std::invoke(keep, *it))
results.vector.append(*it);
std::advance(it, 1);
}
@@ -131,7 +97,7 @@ public:
void finish() override
{
reducer.finish(reduce, reducedResult);
- sequence = reducedResult;
+ sequence = std::move(reducedResult);
}
inline bool shouldThrottleThread() override
@@ -158,29 +124,34 @@ template <typename ReducedResultType,
typename qValueType<Iterator>::value_type> >
class FilteredReducedKernel : public IterateKernel<Iterator, ReducedResultType>
{
- ReducedResultType reducedResult;
+ ReducedResultType &reducedResult;
KeepFunctor keep;
ReduceFunctor reduce;
Reducer reducer;
typedef IterateKernel<Iterator, ReducedResultType> IterateKernelType;
public:
- FilteredReducedKernel(Iterator begin,
- Iterator end,
- KeepFunctor _keep,
- ReduceFunctor _reduce,
- ReduceOptions reduceOption)
- : IterateKernelType(begin, end), reducedResult(), keep(_keep), reduce(_reduce), reducer(reduceOption)
+ template<typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
+ FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep,
+ Reduce &&_reduce, ReduceOptions reduceOption)
+ : IterateKernelType(pool, begin, end),
+ reducedResult(this->defaultValue.value),
+ keep(std::forward<Keep>(_keep)),
+ reduce(std::forward<Reduce>(_reduce)),
+ reducer(pool, reduceOption)
{ }
-#if 0
- FilteredReducedKernel(ReducedResultType initialValue,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOption reduceOption)
- : reducedResult(initialValue), keep(keep), reduce(reduce), reducer(reduceOption)
- { }
-#endif
+ template <typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
+ FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep,
+ Reduce &&_reduce, ReducedResultType &&initialValue,
+ ReduceOptions reduceOption)
+ : IterateKernelType(pool, begin, end, std::forward<ReducedResultType>(initialValue)),
+ reducedResult(this->defaultValue.value),
+ keep(std::forward<Keep>(_keep)),
+ reduce(std::forward<Reduce>(_reduce)),
+ reducer(pool, reduceOption)
+ {
+ }
bool runIteration(Iterator it, int index, ReducedResultType *) override
{
@@ -188,7 +159,7 @@ public:
results.begin = index;
results.end = index + 1;
- if (keep(*it))
+ if (std::invoke(keep, *it))
results.vector.append(*it);
reducer.runReduce(reduce, reducedResult, results);
@@ -205,7 +176,7 @@ public:
Iterator it = sequenceBeginIterator;
std::advance(it, begin);
for (int i = begin; i < end; ++i) {
- if (keep(*it))
+ if (std::invoke(keep, *it))
results.vector.append(*it);
std::advance(it, 1);
}
@@ -250,8 +221,9 @@ public:
typedef T ReturnType;
typedef T ResultType;
- FilteredEachKernel(Iterator begin, Iterator end, KeepFunctor _keep)
- : IterateKernelType(begin, end), keep(_keep)
+ template <typename Keep = KeepFunctor>
+ FilteredEachKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep)
+ : IterateKernelType(pool, begin, end), keep(std::forward<Keep>(_keep))
{ }
void start() override
@@ -263,7 +235,7 @@ public:
bool runIteration(Iterator it, int index, T *) override
{
- if (keep(*it))
+ if (std::invoke(keep, *it))
this->reportResult(&(*it), index);
else
this->reportResult(nullptr, index);
@@ -281,7 +253,7 @@ public:
Iterator it = sequenceBeginIterator;
std::advance(it, begin);
for (int i = begin; i < end; ++i) {
- if (keep(*it))
+ if (std::invoke(keep, *it))
results.vector.append(*it);
std::advance(it, 1);
}
@@ -295,46 +267,112 @@ public:
template <typename Iterator, typename KeepFunctor>
inline
ThreadEngineStarter<typename qValueType<Iterator>::value_type>
-startFiltered(Iterator begin, Iterator end, KeepFunctor functor)
+startFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&functor)
{
- return startThreadEngine(new FilteredEachKernel<Iterator, KeepFunctor>(begin, end, functor));
+ return startThreadEngine(new FilteredEachKernel<Iterator, std::decay_t<KeepFunctor>>
+ (pool, begin, end, std::forward<KeepFunctor>(functor)));
}
//! [QtConcurrent-3]
template <typename Sequence, typename KeepFunctor>
-inline ThreadEngineStarter<typename Sequence::value_type>
-startFiltered(const Sequence &sequence, KeepFunctor functor)
+inline decltype(auto) startFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&functor)
{
- typedef SequenceHolder1<Sequence,
- FilteredEachKernel<typename Sequence::const_iterator, KeepFunctor>,
- KeepFunctor>
- SequenceHolderType;
- return startThreadEngine(new SequenceHolderType(sequence, functor));
+ using DecayedSequence = std::decay_t<Sequence>;
+ using DecayedFunctor = std::decay_t<KeepFunctor>;
+ using SequenceHolderType = SequenceHolder1<DecayedSequence,
+ FilteredEachKernel<typename DecayedSequence::const_iterator, DecayedFunctor>,
+ DecayedFunctor>;
+ return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
+ std::forward<KeepFunctor>(functor)));
}
//! [QtConcurrent-4]
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
-inline ThreadEngineStarter<ResultType> startFilteredReduced(const Sequence & sequence,
- MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
- ReduceOptions options)
+inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&mapFunctor,
+ ReduceFunctor &&reduceFunctor,
+ ReduceOptions options)
{
- typedef typename Sequence::const_iterator Iterator;
- typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type > Reducer;
- typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
- typedef SequenceHolder2<Sequence, FilteredReduceType, MapFunctor, ReduceFunctor> SequenceHolderType;
- return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, options));
+ using DecayedSequence = std::decay_t<Sequence>;
+ using DecayedMapFunctor = std::decay_t<MapFunctor>;
+ using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
+ using Iterator = typename DecayedSequence::const_iterator;
+ using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType,
+ typename qValueType<Iterator>::value_type>;
+ using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, DecayedMapFunctor,
+ DecayedReduceFunctor, Reducer>;
+ using SequenceHolderType = SequenceHolder2<DecayedSequence, FilteredReduceType,
+ DecayedMapFunctor, DecayedReduceFunctor>;
+ return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(mapFunctor),
+ std::forward<ReduceFunctor>(reduceFunctor),
+ options));
}
//! [QtConcurrent-5]
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
-inline ThreadEngineStarter<ResultType> startFilteredReduced(Iterator begin, Iterator end,
- MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
- ReduceOptions options)
+inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&mapFunctor,
+ ReduceFunctor &&reduceFunctor,
+ ReduceOptions options)
+{
+ using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType,
+ typename qValueType<Iterator>::value_type>;
+ using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
+ std::decay_t<ReduceFunctor>, Reducer>;
+ return startThreadEngine(
+ new FilteredReduceType(pool, begin, end, std::forward<MapFunctor>(mapFunctor),
+ std::forward<ReduceFunctor>(reduceFunctor), options));
+}
+
+// Repeat the two functions above, but now with an initial value!
+//! [QtConcurrent-6]
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&mapFunctor,
+ ReduceFunctor &&reduceFunctor,
+ ResultType &&initialValue,
+ ReduceOptions options)
+{
+ using DecayedSequence = std::decay_t<Sequence>;
+ using DecayedMapFunctor = std::decay_t<MapFunctor>;
+ using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
+ using Iterator = typename DecayedSequence::const_iterator;
+ using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType,
+ typename qValueType<Iterator>::value_type>;
+ using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, DecayedMapFunctor,
+ DecayedReduceFunctor, Reducer>;
+ using SequenceHolderType = SequenceHolder2<DecayedSequence, FilteredReduceType,
+ DecayedMapFunctor, DecayedReduceFunctor>;
+ return startThreadEngine(new SequenceHolderType(
+ pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(mapFunctor),
+ std::forward<ReduceFunctor>(reduceFunctor), std::forward<ResultType>(initialValue),
+ options));
+}
+
+//! [QtConcurrent-7]
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&mapFunctor,
+ ReduceFunctor &&reduceFunctor,
+ ResultType &&initialValue,
+ ReduceOptions options)
{
- typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type> Reducer;
- typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
- return startThreadEngine(new FilteredReduceType(begin, end, mapFunctor, reduceFunctor, options));
+ using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType,
+ typename qValueType<Iterator>::value_type>;
+ using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
+ std::decay_t<ReduceFunctor>, Reducer>;
+ return startThreadEngine(
+ new FilteredReduceType(pool, begin, end, std::forward<MapFunctor>(mapFunctor),
+ std::forward<ReduceFunctor>(reduceFunctor),
+ std::forward<ResultType>(initialValue), options));
}
diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h
index 7ba6720e03..78900c239b 100644
--- a/src/concurrent/qtconcurrentfunctionwrappers.h
+++ b/src/concurrent/qtconcurrentfunctionwrappers.h
@@ -1,241 +1,71 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_FUNCTIONWRAPPERS_H
#define QTCONCURRENT_FUNCTIONWRAPPERS_H
#include <QtConcurrent/qtconcurrentcompilertest.h>
-#include <QtCore/QStringList>
+#include <QtConcurrent/qtconcurrentreducekernel.h>
+#include <QtCore/qfuture.h>
-#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
+#include <tuple>
+
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
QT_BEGIN_NAMESPACE
-namespace QtConcurrent {
+namespace QtPrivate {
-template <typename T>
-class FunctionWrapper0
+struct PushBackWrapper
{
-public:
- typedef T (*FunctionPointerType)();
- typedef T result_type;
- inline FunctionWrapper0(FunctionPointerType _functionPointer)
- :functionPointer(_functionPointer) { }
-
- inline T operator()()
+ template <class C, class U>
+ inline void operator()(C &c, const U &u) const
{
- return functionPointer();
+ return c.push_back(u);
}
-private:
- FunctionPointerType functionPointer;
-};
-
-template <typename T, typename U>
-class FunctionWrapper1
-{
-public:
- typedef T (*FunctionPointerType)(U u);
- typedef T result_type;
- inline FunctionWrapper1(FunctionPointerType _functionPointer)
- :functionPointer(_functionPointer) { }
- inline T operator()(U u)
+ template <class C, class U>
+ inline void operator()(C &c, U &&u) const
{
- return functionPointer(u);
+ return c.push_back(u);
}
-
-private:
- FunctionPointerType functionPointer;
};
-template <typename T, typename U, typename V>
-class FunctionWrapper2
-{
-public:
- typedef T (*FunctionPointerType)(U u, V v);
- typedef T result_type;
- inline FunctionWrapper2(FunctionPointerType _functionPointer)
- :functionPointer(_functionPointer) { }
+// -- MapResultType
- inline T operator()(U u, V v)
- {
- return functionPointer(u, v);
- }
-private:
- FunctionPointerType functionPointer;
-};
-
-template <typename T, typename C>
-class MemberFunctionWrapper
+template <class T, class Enable = void>
+struct Argument
{
-public:
- typedef T (C::*FunctionPointerType)();
- typedef T result_type;
- inline MemberFunctionWrapper(FunctionPointerType _functionPointer)
- :functionPointer(_functionPointer) { }
-
- inline T operator()(C &c)
- {
- return (c.*functionPointer)();
- }
-private:
- FunctionPointerType functionPointer;
+ using Type = void;
};
-template <typename T, typename C, typename U>
-class MemberFunctionWrapper1
+template <class Sequence>
+struct Argument<Sequence, typename std::enable_if<IsIterableValue<Sequence>>::type>
{
-public:
- typedef T (C::*FunctionPointerType)(U);
- typedef T result_type;
-
- inline MemberFunctionWrapper1(FunctionPointerType _functionPointer)
- : functionPointer(_functionPointer)
- { }
-
- inline T operator()(C &c, U u)
- {
- return (c.*functionPointer)(u);
- }
-
-private:
- FunctionPointerType functionPointer;
+ using Type = std::decay_t<decltype(*std::declval<Sequence>().begin())>;
};
-template <typename T, typename C>
-class ConstMemberFunctionWrapper
+template <class Iterator>
+struct Argument<Iterator, typename std::enable_if<IsDereferenceableValue<Iterator>>::type>
{
-public:
- typedef T (C::*FunctionPointerType)() const;
- typedef T result_type;
- inline ConstMemberFunctionWrapper(FunctionPointerType _functionPointer)
- :functionPointer(_functionPointer) { }
-
- inline T operator()(const C &c) const
- {
- return (c.*functionPointer)();
- }
-private:
- FunctionPointerType functionPointer;
+ using Type = std::decay_t<decltype(*std::declval<Iterator>())>;
};
-} // namespace QtConcurrent.
-
-namespace QtPrivate {
-
-template <typename T>
-const T& createFunctionWrapper(const T& t)
-{
- return t;
-}
-
-template <typename T, typename U>
-QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U))
-{
- return QtConcurrent::FunctionWrapper1<T, U>(func);
-}
-
-template <typename T, typename C>
-QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)())
-{
- return QtConcurrent::MemberFunctionWrapper<T, C>(func);
-}
-
-template <typename T, typename C, typename U>
-QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U))
-{
- return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func);
-}
-
-template <typename T, typename C>
-QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const)
-{
- return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func);
-}
-
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T, typename U>
-QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U) noexcept)
-{
- return QtConcurrent::FunctionWrapper1<T, U>(func);
-}
-
-template <typename T, typename C>
-QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() noexcept)
-{
- return QtConcurrent::MemberFunctionWrapper<T, C>(func);
-}
-
-template <typename T, typename C, typename U>
-QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U) noexcept)
-{
- return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func);
-}
-
-template <typename T, typename C>
-QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const noexcept)
-{
- return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func);
-}
-#endif
+template <class T>
+using ArgumentType = typename Argument<T>::Type;
-struct PushBackWrapper
+template <class T, class MapFunctor>
+struct MapResult
{
- typedef void result_type;
-
- template <class C, class U>
- inline void operator()(C &c, const U &u) const
- {
- return c.push_back(u);
- }
-
- template <class C, class U>
- inline void operator()(C &c, U &&u) const
- {
- return c.push_back(u);
- }
+ static_assert(std::is_invocable_v<std::decay_t<MapFunctor>, ArgumentType<T>>,
+ "It's not possible to invoke the function with passed argument.");
+ using Type = std::invoke_result_t<std::decay_t<MapFunctor>, ArgumentType<T>>;
};
-template <typename Functor, bool foo = HasResultType<Functor>::Value>
-struct LazyResultType { typedef typename Functor::result_type Type; };
-template <typename Functor>
-struct LazyResultType<Functor, false> { typedef void Type; };
+template <class T, class MapFunctor>
+using MapResultType = typename MapResult<T, MapFunctor>::Type;
+
+// -- ReduceResultType
template <class T>
struct ReduceResultType;
@@ -243,130 +73,101 @@ struct ReduceResultType;
template <class U, class V>
struct ReduceResultType<void(*)(U&,V)>
{
- typedef U ResultType;
+ using ResultType = U;
};
template <class T, class C, class U>
struct ReduceResultType<T(C::*)(U)>
{
- typedef C ResultType;
+ using ResultType = C;
};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
template <class U, class V>
-struct ReduceResultType<void(*)(U&,V) noexcept>
+struct ReduceResultType<std::function<void(U&, V)>>
{
- typedef U ResultType;
+ using ResultType = U;
};
-template <class T, class C, class U>
-struct ReduceResultType<T(C::*)(U) noexcept>
+template <typename R, typename ...A>
+struct ReduceResultType<R(*)(A...)>
{
- typedef C ResultType;
-};
-#endif
-
-template <class InputSequence, class MapFunctor>
-struct MapResultType
-{
- typedef typename LazyResultType<MapFunctor>::Type ResultType;
+ using ResultType = typename std::tuple_element<0, std::tuple<A...>>::type;
};
template <class U, class V>
-struct MapResultType<void, U (*)(V)>
-{
- typedef U ResultType;
-};
-
-template <class T, class C>
-struct MapResultType<void, T(C::*)() const>
+struct ReduceResultType<void(*)(U&,V) noexcept>
{
- typedef T ResultType;
+ using ResultType = U;
};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <class U, class V>
-struct MapResultType<void, U (*)(V) noexcept>
+template <class T, class C, class U>
+struct ReduceResultType<T(C::*)(U) noexcept>
{
- typedef U ResultType;
+ using ResultType = C;
};
-template <class T, class C>
-struct MapResultType<void, T(C::*)() const noexcept>
-{
- typedef T ResultType;
-};
-#endif
+template<class T, class Enable = void>
+inline constexpr bool hasCallOperator_v = false;
-#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
+template<class T>
+inline constexpr bool hasCallOperator_v<T, std::void_t<decltype(&T::operator())>> = true;
-template <template <typename> class InputSequence, typename MapFunctor, typename T>
-struct MapResultType<InputSequence<T>, MapFunctor>
-{
- typedef InputSequence<typename LazyResultType<MapFunctor>::Type> ResultType;
-};
+template<class T, class Enable = void>
+inline constexpr bool isIterator_v = false;
-template <template <typename> class InputSequence, class T, class U, class V>
-struct MapResultType<InputSequence<T>, U (*)(V)>
-{
- typedef InputSequence<U> ResultType;
-};
+template<class T>
+inline constexpr bool isIterator_v<T, std::void_t<typename std::iterator_traits<T>::value_type>> =
+ true;
-template <template <typename> class InputSequence, class T, class U, class C>
-struct MapResultType<InputSequence<T>, U(C::*)() const>
-{
- typedef InputSequence<U> ResultType;
-};
+template <class Callable, class Sequence>
+using isInvocable = std::is_invocable<Callable, typename std::decay_t<Sequence>::value_type>;
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
+template <class InitialValueType, class ResultType>
+inline constexpr bool isInitialValueCompatible_v = std::conjunction_v<
+ std::is_convertible<InitialValueType, ResultType>,
+ std::negation<std::is_same<std::decay_t<InitialValueType>, QtConcurrent::ReduceOption>>>;
-template <template <typename> class InputSequence, class T, class U, class V>
-struct MapResultType<InputSequence<T>, U (*)(V) noexcept>
+template<class Callable, class Enable = void>
+struct ReduceResultTypeHelper
{
- typedef InputSequence<U> ResultType;
};
-template <template <typename> class InputSequence, class T, class U, class C>
-struct MapResultType<InputSequence<T>, U(C::*)() const noexcept>
+template <class Callable>
+struct ReduceResultTypeHelper<Callable,
+ typename std::enable_if_t<std::is_function_v<std::remove_pointer_t<std::decay_t<Callable>>>
+ || std::is_member_function_pointer_v<std::decay_t<Callable>>>>
{
- typedef InputSequence<U> ResultType;
+ using type = typename QtPrivate::ReduceResultType<std::decay_t<Callable>>::ResultType;
};
-#endif
-
-#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER
-template <class MapFunctor>
-struct MapResultType<QStringList, MapFunctor>
+template <class Callable>
+struct ReduceResultTypeHelper<Callable,
+ typename std::enable_if_t<!std::is_function_v<std::remove_pointer_t<std::decay_t<Callable>>>
+ && hasCallOperator_v<std::decay_t<Callable>>>>
{
- typedef QList<typename LazyResultType<MapFunctor>::Type> ResultType;
+ using type = std::decay_t<typename QtPrivate::ArgResolver<Callable>::First>;
};
-template <class U, class V>
-struct MapResultType<QStringList, U (*)(V)>
-{
- typedef QList<U> ResultType;
-};
+// -- MapSequenceResultType
-template <class U, class C>
-struct MapResultType<QStringList, U(C::*)() const>
+template <class InputSequence, class MapFunctor>
+struct MapSequenceResultType
{
- typedef QList<U> ResultType;
+ static_assert(std::is_same_v<typename InputSequence::value_type,
+ QtPrivate::MapResultType<InputSequence, MapFunctor>>,
+ "Couldn't deduce the output sequence type, you must specify it explicitly.");
+ typedef InputSequence ResultType;
};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
+#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
-template <class U, class V>
-struct MapResultType<QStringList, U (*)(V) noexcept>
+template <template <typename...> class InputSequence, typename MapFunctor, typename ...T>
+struct MapSequenceResultType<InputSequence<T...>, MapFunctor>
{
- typedef QList<U> ResultType;
+ typedef InputSequence<QtPrivate::MapResultType<InputSequence<T...>, MapFunctor>> ResultType;
};
-template <class U, class C>
-struct MapResultType<QStringList, U(C::*)() const noexcept>
-{
- typedef QList<U> ResultType;
-};
-#endif
+#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER
} // namespace QtPrivate.
diff --git a/src/concurrent/qtconcurrentiteratekernel.cpp b/src/concurrent/qtconcurrentiteratekernel.cpp
index b65f712547..00228f181c 100644
--- a/src/concurrent/qtconcurrentiteratekernel.cpp
+++ b/src/concurrent/qtconcurrentiteratekernel.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtconcurrentiteratekernel.h"
@@ -43,13 +7,12 @@
#include "private/qfunctions_p.h"
-#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
QT_BEGIN_NAMESPACE
enum {
- TargetRatio = 100,
- MedianSize = 7
+ TargetRatio = 100
};
static qint64 getticks()
@@ -71,24 +34,12 @@ namespace QtConcurrent {
*/
/*!
- \class QtConcurrent::MedianDouble
- \inmodule QtConcurrent
- \internal
- */
-
-/*!
\class QtConcurrent::BlockSizeManager
\inmodule QtConcurrent
\internal
*/
/*!
- \class QtConcurrent::BlockSizeManagerV2
- \inmodule QtConcurrent
- \internal
- */
-
-/*!
\class QtConcurrent::ResultReporter
\inmodule QtConcurrent
\internal
@@ -115,11 +66,10 @@ namespace QtConcurrent {
/*! \internal
*/
-BlockSizeManager::BlockSizeManager(int iterationCount)
-: maxBlockSize(iterationCount / (QThreadPool::globalInstance()->maxThreadCount() * 2)),
- beforeUser(0), afterUser(0),
- controlPartElapsed(MedianSize), userPartElapsed(MedianSize),
- m_blockSize(1)
+BlockSizeManager::BlockSizeManager(QThreadPool *pool, int iterationCount)
+ : maxBlockSize(iterationCount / (std::max(pool->maxThreadCount(), 1) * 2)),
+ beforeUser(0), afterUser(0),
+ m_blockSize(1)
{ }
// Records the time before user code.
@@ -145,7 +95,7 @@ void BlockSizeManager::timeAfterUser()
if (controlPartElapsed.isMedianValid() == false)
return;
- if (controlPartElapsed.median() * TargetRatio < userPartElapsed.median())
+ if (controlPartElapsed.median() * int(TargetRatio) < userPartElapsed.median())
return;
m_blockSize = qMin(m_blockSize * 2, maxBlockSize);
@@ -165,58 +115,6 @@ int BlockSizeManager::blockSize()
return m_blockSize;
}
-/*! \internal
-
-*/
-BlockSizeManagerV2::BlockSizeManagerV2(int iterationCount)
- : maxBlockSize(iterationCount / (QThreadPool::globalInstance()->maxThreadCount() * 2)),
- beforeUser(0), afterUser(0),
- m_blockSize(1)
-{ }
-
-// Records the time before user code.
-void BlockSizeManagerV2::timeBeforeUser()
-{
- if (blockSizeMaxed())
- return;
-
- beforeUser = getticks();
- controlPartElapsed.addValue(elapsed(beforeUser, afterUser));
-}
-
- // Records the time after user code and adjust the block size if we are spending
- // to much time in the for control code compared with the user code.
-void BlockSizeManagerV2::timeAfterUser()
-{
- if (blockSizeMaxed())
- return;
-
- afterUser = getticks();
- userPartElapsed.addValue(elapsed(afterUser, beforeUser));
-
- if (controlPartElapsed.isMedianValid() == false)
- return;
-
- if (controlPartElapsed.median() * TargetRatio < userPartElapsed.median())
- return;
-
- m_blockSize = qMin(m_blockSize * 2, maxBlockSize);
-
-#ifdef QTCONCURRENT_FOR_DEBUG
- qDebug() << QThread::currentThread() << "adjusting block size" << controlPartElapsed.median() << userPartElapsed.median() << m_blockSize;
-#endif
-
- // Reset the medians after adjusting the block size so we get
- // new measurements with the new block size.
- controlPartElapsed.reset();
- userPartElapsed.reset();
-}
-
-int BlockSizeManagerV2::blockSize()
-{
- return m_blockSize;
-}
-
} // namespace QtConcurrent
QT_END_NAMESPACE
diff --git a/src/concurrent/qtconcurrentiteratekernel.h b/src/concurrent/qtconcurrentiteratekernel.h
index 3095c9ff52..232f4c8bfe 100644
--- a/src/concurrent/qtconcurrentiteratekernel.h
+++ b/src/concurrent/qtconcurrentiteratekernel.h
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_ITERATEKERNEL_H
#define QTCONCURRENT_ITERATEKERNEL_H
#include <QtConcurrent/qtconcurrent_global.h>
-#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtCore/qatomic.h>
#include <QtConcurrent/qtconcurrentmedian.h>
@@ -61,37 +25,13 @@ namespace QtConcurrent {
reserve and process at a time. This is done by measuring the time spent
in the user code versus the control part code, and then increasing
the block size if the ratio between them is to small. The block size
- management is done on the basis of the median of several timing measuremens,
- and it is done induvidualy for each thread.
+ management is done on the basis of the median of several timing measurements,
+ and it is done individually for each thread.
*/
class Q_CONCURRENT_EXPORT BlockSizeManager
{
public:
- BlockSizeManager(int iterationCount);
- void timeBeforeUser();
- void timeAfterUser();
- int blockSize();
-private:
- inline bool blockSizeMaxed()
- {
- return (m_blockSize >= maxBlockSize);
- }
-
- const int maxBlockSize;
- qint64 beforeUser;
- qint64 afterUser;
- Median<double> controlPartElapsed;
- Median<double> userPartElapsed;
- int m_blockSize;
-
- Q_DISABLE_COPY(BlockSizeManager)
-};
-
-// ### Qt6: Replace BlockSizeManager with V2 implementation
-class Q_CONCURRENT_EXPORT BlockSizeManagerV2
-{
-public:
- explicit BlockSizeManagerV2(int iterationCount);
+ explicit BlockSizeManager(QThreadPool *pool, int iterationCount);
void timeBeforeUser();
void timeAfterUser();
@@ -106,34 +46,33 @@ private:
const int maxBlockSize;
qint64 beforeUser;
qint64 afterUser;
- MedianDouble controlPartElapsed;
- MedianDouble userPartElapsed;
+ Median controlPartElapsed;
+ Median userPartElapsed;
int m_blockSize;
- Q_DISABLE_COPY(BlockSizeManagerV2)
+ Q_DISABLE_COPY(BlockSizeManager)
};
template <typename T>
class ResultReporter
{
public:
- ResultReporter(ThreadEngine<T> *_threadEngine)
- :threadEngine(_threadEngine)
+ ResultReporter(ThreadEngine<T> *_threadEngine, T &_defaultValue)
+ : threadEngine(_threadEngine), defaultValue(_defaultValue)
{
-
}
void reserveSpace(int resultCount)
{
currentResultCount = resultCount;
- vector.resize(qMax(resultCount, vector.count()));
+ resizeList(qMax(resultCount, vector.size()));
}
void reportResults(int begin)
{
const int useVectorThreshold = 4; // Tunable parameter.
if (currentResultCount > useVectorThreshold) {
- vector.resize(currentResultCount);
+ resizeList(currentResultCount);
threadEngine->reportResults(vector, begin);
} else {
for (int i = 0; i < currentResultCount; ++i)
@@ -146,9 +85,20 @@ public:
return vector.data();
}
- int currentResultCount;
+ int currentResultCount = 0;
ThreadEngine<T> *threadEngine;
- QVector<T> vector;
+ QList<T> vector;
+
+private:
+ void resizeList(qsizetype size)
+ {
+ if constexpr (std::is_default_constructible_v<T>)
+ vector.resize(size);
+ else
+ vector.resize(size, defaultValue);
+ }
+
+ T &defaultValue;
};
template <>
@@ -161,6 +111,22 @@ public:
inline void * getPointer() { return nullptr; }
};
+template<typename T>
+struct DefaultValueContainer
+{
+ template<typename U = T>
+ DefaultValueContainer(U &&_value) : value(std::forward<U>(_value))
+ {
+ }
+
+ T value;
+};
+
+template<>
+struct DefaultValueContainer<void>
+{
+};
+
inline bool selectIteration(std::bidirectional_iterator_tag)
{
return false; // while
@@ -179,22 +145,53 @@ inline bool selectIteration(std::random_access_iterator_tag)
template <typename Iterator, typename T>
class IterateKernel : public ThreadEngine<T>
{
+ using IteratorCategory = typename std::iterator_traits<Iterator>::iterator_category;
+
public:
typedef T ResultType;
- IterateKernel(Iterator _begin, Iterator _end)
- : begin(_begin), end(_end), current(_begin), currentIndex(0),
- forIteration(selectIteration(typename std::iterator_traits<Iterator>::iterator_category())), progressReportingEnabled(true)
+ template<typename U = T, std::enable_if_t<std::is_same_v<U, void>, bool> = true>
+ IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end)
+ : ThreadEngine<U>(pool),
+ begin(_begin),
+ end(_end),
+ current(_begin),
+ iterationCount(selectIteration(IteratorCategory()) ? static_cast<int>(std::distance(_begin, _end)) : 0),
+ forIteration(selectIteration(IteratorCategory())),
+ progressReportingEnabled(true)
+ {
+ }
+
+ template<typename U = T, std::enable_if_t<!std::is_same_v<U, void>, bool> = true>
+ IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end)
+ : ThreadEngine<U>(pool),
+ begin(_begin),
+ end(_end),
+ current(_begin),
+ iterationCount(selectIteration(IteratorCategory()) ? static_cast<int>(std::distance(_begin, _end)) : 0),
+ forIteration(selectIteration(IteratorCategory())),
+ progressReportingEnabled(true),
+ defaultValue(U())
+ {
+ }
+
+ template<typename U = T, std::enable_if_t<!std::is_same_v<U, void>, bool> = true>
+ IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end, U &&_defaultValue)
+ : ThreadEngine<U>(pool),
+ begin(_begin),
+ end(_end),
+ current(_begin),
+ iterationCount(selectIteration(IteratorCategory()) ? static_cast<int>(std::distance(_begin, _end)) : 0),
+ forIteration(selectIteration(IteratorCategory())),
+ progressReportingEnabled(true),
+ defaultValue(std::forward<U>(_defaultValue))
{
- iterationCount = forIteration ? std::distance(_begin, _end) : 0;
}
virtual ~IterateKernel() { }
- virtual bool runIteration(Iterator it, int index , T *result)
- { Q_UNUSED(it); Q_UNUSED(index); Q_UNUSED(result); return false; }
- virtual bool runIterations(Iterator _begin, int beginIndex, int endIndex, T *results)
- { Q_UNUSED(_begin); Q_UNUSED(beginIndex); Q_UNUSED(endIndex); Q_UNUSED(results); return false; }
+ virtual bool runIteration(Iterator, int , T *) { return false; }
+ virtual bool runIterations(Iterator, int, int, T *) { return false; }
void start() override
{
@@ -221,8 +218,8 @@ public:
ThreadFunctionResult forThreadFunction()
{
- BlockSizeManagerV2 blockSizeManager(iterationCount);
- ResultReporter<T> resultReporter(this);
+ BlockSizeManager blockSizeManager(ThreadEngineBase::threadPool, iterationCount);
+ ResultReporter<T> resultReporter = createResultsReporter();
for(;;) {
if (this->isCanceled())
@@ -275,7 +272,7 @@ public:
if (iteratorThreads.testAndSetAcquire(0, 1) == false)
return ThreadFinished;
- ResultReporter<T> resultReporter(this);
+ ResultReporter<T> resultReporter = createResultsReporter();
resultReporter.reserveSpace(1);
while (current != end) {
@@ -306,18 +303,26 @@ public:
return ThreadFinished;
}
+private:
+ ResultReporter<T> createResultsReporter()
+ {
+ if constexpr (!std::is_same_v<T, void>)
+ return ResultReporter<T>(this, defaultValue.value);
+ else
+ return ResultReporter<T>(this);
+ }
public:
const Iterator begin;
const Iterator end;
Iterator current;
QAtomicInt currentIndex;
- bool forIteration;
QAtomicInt iteratorThreads;
- int iterationCount;
-
- bool progressReportingEnabled;
QAtomicInt completed;
+ const int iterationCount;
+ const bool forIteration;
+ bool progressReportingEnabled;
+ DefaultValueContainer<ResultType> defaultValue;
};
} // namespace QtConcurrent
diff --git a/src/concurrent/qtconcurrentmap.cpp b/src/concurrent/qtconcurrentmap.cpp
index 157ea14b32..222c8cd639 100644
--- a/src/concurrent/qtconcurrentmap.cpp
+++ b/src/concurrent/qtconcurrentmap.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/*!
\namespace QtConcurrent
@@ -94,27 +58,37 @@
*/
/*!
- \fn [qtconcurrentmapkernel-1] ThreadEngineStarter<void> QtConcurrent::startMap(Iterator begin, Iterator end, Functor functor)
+ \fn [qtconcurrentmapkernel-1] ThreadEngineStarter<void> QtConcurrent::startMap(Iterator begin, Iterator end, Functor &&functor)
\internal
*/
/*!
- \fn [qtconcurrentmapkernel-2] ThreadEngineStarter<T> QtConcurrent::startMapped(Iterator begin, Iterator end, Functor functor)
+ \fn [qtconcurrentmapkernel-2] ThreadEngineStarter<T> QtConcurrent::startMapped(Iterator begin, Iterator end, Functor &&functor)
\internal
*/
/*!
- \fn [qtconcurrentmapkernel-3] ThreadEngineStarter<T> QtConcurrent::startMapped(const Sequence &sequence, Functor functor)
+ \fn [qtconcurrentmapkernel-3] ThreadEngineStarter<T> QtConcurrent::startMapped(Sequence &&sequence, Functor &&functor)
\internal
*/
/*!
- \fn [qtconcurrentmapkernel-4] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(const Sequence & sequence, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options)
+ \fn [qtconcurrentmapkernel-4] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(Sequence &&sequence, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ReduceOptions options)
\internal
*/
/*!
- \fn [qtconcurrentmapkernel-5] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options)
+ \fn [qtconcurrentmapkernel-5] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(Iterator begin, Iterator end, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ReduceOptions options)
+ \internal
+*/
+
+/*!
+ \fn [qtconcurrentmapkernel-6] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(Sequence &&sequence, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ResultType &&initialValue, ReduceOptions options)
+ \internal
+*/
+
+/*!
+ \fn [qtconcurrentmapkernel-7] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(Iterator begin, Iterator end, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ResultType &&initialValue, ReduceOptions options)
\internal
*/
@@ -134,16 +108,17 @@
/*!
\page qtconcurrentmap.html
\title Concurrent Map and Map-Reduce
+ \brief Transforming values from a sequence and combining them, all in parallel.
\ingroup thread
The QtConcurrent::map(), QtConcurrent::mapped() and
QtConcurrent::mappedReduced() functions run computations in parallel on
- the items in a sequence such as a QList or a QVector. QtConcurrent::map()
+ the items in a sequence such as a QList. QtConcurrent::map()
modifies a sequence in-place, QtConcurrent::mapped() returns a new
sequence containing the modified content, and QtConcurrent::mappedReduced()
returns a single result.
- These functions are a part of the \l {Qt Concurrent} framework.
+ These functions are part of the \l {Qt Concurrent} framework.
Each of the above functions has a blocking variant that returns
the final result instead of a QFuture. You use them in the same
@@ -250,7 +225,10 @@
\snippet code/src_concurrent_qtconcurrentmap.cpp 8
- Note that when using QtConcurrent::mappedReduced(), you can mix the use of
+ Note the use of qOverload. It is needed to resolve the ambiguity for the
+ methods, that have multiple overloads.
+
+ Also note that when using QtConcurrent::mappedReduced(), you can mix the use of
normal and member functions freely:
\snippet code/src_concurrent_qtconcurrentmap.cpp 9
@@ -260,17 +238,32 @@
QtConcurrent::map(), QtConcurrent::mapped(), and
QtConcurrent::mappedReduced() accept function objects
for the map function. These function objects can be used to
- add state to a function call. The result_type typedef must define the
- result type of the function call operator:
+ add state to a function call:
\snippet code/src_concurrent_qtconcurrentmap.cpp 14
- For the reduce function, function objects are not directly
- supported. Function objects can, however, be used
- when the type of the reduction result is explicitly specified:
+ Function objects are also supported for the reduce function:
\snippet code/src_concurrent_qtconcurrentmap.cpp 11
+ \section2 Using Lambda Expressions
+
+ QtConcurrent::map(), QtConcurrent::mapped(), and
+ QtConcurrent::mappedReduced() accept lambda expressions for the map and
+ reduce function:
+
+ \snippet code/src_concurrent_qtconcurrentmap.cpp 15
+
+ When using QtConcurrent::mappedReduced() or
+ QtConcurrent::blockingMappedReduced(), you can mix the use of normal
+ functions, member functions and lambda expressions freely.
+
+ \snippet code/src_concurrent_qtconcurrentmap.cpp 16
+
+ You can also pass a lambda as a reduce object:
+
+ \snippet code/src_concurrent_qtconcurrentmap.cpp 17
+
\section2 Wrapping Functions that Take Multiple Arguments
If you want to use a map function that takes more than one argument you can
@@ -291,27 +284,60 @@
*/
/*!
- \fn template <typename Sequence, typename MapFunctor> QFuture<void> QtConcurrent::map(Sequence &sequence, MapFunctor function)
+ \fn template <typename Sequence, typename MapFunctor> QFuture<void> QtConcurrent::map(QThreadPool *pool, Sequence &&sequence, MapFunctor &&function)
+
+ Calls \a function once for each item in \a sequence.
+ All calls to \a function are invoked from the threads taken from the QThreadPool \a pool.
+ The \a function takes a reference to the item, so that any modifications done to the item
+ will appear in \a sequence.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename MapFunctor> QFuture<void> QtConcurrent::map(Sequence &&sequence, MapFunctor &&function)
- Calls \a function once for each item in \a sequence. The \a function is
- passed a reference to the item, so that any modifications done to the item
+ Calls \a function once for each item in \a sequence. The \a function takes
+ a reference to the item, so that any modifications done to the item
will appear in \a sequence.
\sa {Concurrent Map and Map-Reduce}
*/
/*!
- \fn template <typename Iterator, typename MapFunctor> QFuture<void> QtConcurrent::map(Iterator begin, Iterator end, MapFunctor function)
+ \fn template <typename Iterator, typename MapFunctor> QFuture<void> QtConcurrent::map(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&function)
+
+ Calls \a function once for each item from \a begin to \a end.
+ All calls to \a function are invoked from the threads taken from the QThreadPool \a pool.
+ The \a function takes a reference to the item, so that any modifications
+ done to the item will appear in the sequence which the iterators belong to.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename Iterator, typename MapFunctor> QFuture<void> QtConcurrent::map(Iterator begin, Iterator end, MapFunctor &&function)
Calls \a function once for each item from \a begin to \a end. The
- \a function is passed a reference to the item, so that any modifications
+ \a function takes a reference to the item, so that any modifications
done to the item will appear in the sequence which the iterators belong to.
\sa {Concurrent Map and Map-Reduce}
*/
/*!
- \fn template <typename Sequence, typename MapFunctor> QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> QtConcurrent::mapped(const Sequence &sequence, MapFunctor function)
+ \fn template <typename Sequence, typename MapFunctor> QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> QtConcurrent::mapped(QThreadPool *pool, Sequence &&sequence, MapFunctor &&function)
+
+ Calls \a function once for each item in \a sequence and returns a future
+ with each mapped item as a result. All calls to \a function are invoked from the
+ threads taken from the QThreadPool \a pool. You can use QFuture::const_iterator or
+ QFutureIterator to iterate through the results.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename MapFunctor> QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> QtConcurrent::mapped(Sequence &&sequence, MapFunctor &&function)
Calls \a function once for each item in \a sequence and returns a future
with each mapped item as a result. You can use QFuture::const_iterator or
@@ -321,7 +347,18 @@
*/
/*!
- \fn template <typename Iterator, typename MapFunctor> QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> QtConcurrent::mapped(Iterator begin, Iterator end, MapFunctor function)
+ \fn template <typename Iterator, typename MapFunctor> QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> QtConcurrent::mapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&function)
+
+ Calls \a function once for each item from \a begin to \a end and returns a
+ future with each mapped item as a result. All calls to \a function are invoked from the
+ threads taken from the QThreadPool \a pool. You can use
+ QFuture::const_iterator or QFutureIterator to iterate through the results.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename Iterator, typename MapFunctor> QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> QtConcurrent::mapped(Iterator begin, Iterator end, MapFunctor &&function)
Calls \a function once for each item from \a begin to \a end and returns a
future with each mapped item as a result. You can use
@@ -331,10 +368,57 @@
*/
/*!
- \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item in \a sequence.
+ All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool.
+ The return value of each \a mapFunction is passed to \a reduceFunction.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is determined by \a reduceOptions.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(Sequence &&sequence, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item in \a sequence. The return value of
+ each \a mapFunction is passed to \a reduceFunction.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is determined by \a reduceOptions.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::mappedReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item in \a sequence.
+ All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool.
+ The return value of each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is determined by \a reduceOptions.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::mappedReduced(Sequence &&sequence, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
Calls \a mapFunction once for each item in \a sequence. The return value of
each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
Note that while \a mapFunction is called concurrently, only one thread at a
time will call \a reduceFunction. The order in which \a reduceFunction is
@@ -344,10 +428,63 @@
*/
/*!
- \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item from \a begin to \a end.
+ All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool.
+ The return value of each \a mapFunction is passed to \a reduceFunction.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. By default, the order in which
+ \a reduceFunction is called is undefined.
+
+ \note QtConcurrent::OrderedReduce results in the ordered reduction.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item from \a begin to \a end. The return
+ value of each \a mapFunction is passed to \a reduceFunction.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. By default, the order in which
+ \a reduceFunction is called is undefined.
+
+ \note QtConcurrent::OrderedReduce results in the ordered reduction.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::mappedReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item from \a begin to \a end.
+ All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool.
+ The return value of each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. By default, the order in which
+ \a reduceFunction is called is undefined.
+
+ \note QtConcurrent::OrderedReduce results in the ordered reduction.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
Calls \a mapFunction once for each item from \a begin to \a end. The return
value of each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
Note that while \a mapFunction is called concurrently, only one thread at a
time will call \a reduceFunction. By default, the order in which
@@ -359,10 +496,23 @@
*/
/*!
- \fn template <typename Sequence, typename MapFunctor> void QtConcurrent::blockingMap(Sequence &sequence, MapFunctor function)
+ \fn template <typename Sequence, typename MapFunctor> void QtConcurrent::blockingMap(QThreadPool *pool, Sequence &&sequence, MapFunctor function)
+
+ Calls \a function once for each item in \a sequence.
+ All calls to \a function are invoked from the threads taken from the QThreadPool \a pool.
+ The \a function takes a reference to the item, so that any modifications done to the item
+ will appear in \a sequence.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa map(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename MapFunctor> void QtConcurrent::blockingMap(Sequence &&sequence, MapFunctor &&function)
- Calls \a function once for each item in \a sequence. The \a function is
- passed a reference to the item, so that any modifications done to the item
+ Calls \a function once for each item in \a sequence. The \a function takes
+ a reference to the item, so that any modifications done to the item
will appear in \a sequence.
\note This function will block until all items in the sequence have been processed.
@@ -371,10 +521,24 @@
*/
/*!
- \fn template <typename Iterator, typename MapFunctor> void QtConcurrent::blockingMap(Iterator begin, Iterator end, MapFunctor function)
+ \fn template <typename Iterator, typename MapFunctor> void QtConcurrent::blockingMap(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&function)
+
+ Calls \a function once for each item from \a begin to \a end.
+ All calls to \a function are invoked from the threads taken from the QThreadPool \a pool.
+ The \a function takes a reference to the item, so that any modifications
+ done to the item will appear in the sequence which the iterators belong to.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa map(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename Iterator, typename MapFunctor> void QtConcurrent::blockingMap(Iterator begin, Iterator end, MapFunctor &&function)
Calls \a function once for each item from \a begin to \a end. The
- \a function is passed a reference to the item, so that any modifications
+ \a function takes a reference to the item, so that any modifications
done to the item will appear in the sequence which the iterators belong to.
\note This function will block until the iterator reaches the end of the
@@ -384,10 +548,22 @@
*/
/*!
- \fn template <typename OutputSequence, typename InputSequence, typename MapFunctor> OutputSequence QtConcurrent::blockingMapped(const InputSequence &sequence, MapFunctor function)
+ \fn template <typename OutputSequence, typename InputSequence, typename MapFunctor> OutputSequence QtConcurrent::blockingMapped(QThreadPool *pool, InputSequence &&sequence, MapFunctor &&function)
+
+ Calls \a function once for each item in \a sequence and returns an OutputSequence containing
+ the results. All calls to \a function are invoked from the threads taken from the QThreadPool
+ \a pool. The type of the results will match the type returned by the MapFunctor.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa mapped(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename OutputSequence, typename InputSequence, typename MapFunctor> OutputSequence QtConcurrent::blockingMapped(InputSequence &&sequence, MapFunctor &&function)
Calls \a function once for each item in \a sequence and returns an OutputSequence containing
- the results. The type of the results will match the type returned my the MapFunctor.
+ the results. The type of the results will match the type returned by the MapFunctor.
\note This function will block until all items in the sequence have been processed.
@@ -395,10 +571,28 @@
*/
/*!
- \fn template <typename Sequence, typename Iterator, typename MapFunctor> Sequence QtConcurrent::blockingMapped(Iterator begin, Iterator end, MapFunctor function)
+ \fn template <typename Sequence, typename Iterator, typename MapFunctor> Sequence QtConcurrent::blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&function)
+
+ Calls \a function once for each item from \a begin to \a end and returns a
+ container with the results. All calls to \a function are invoked from the threads
+ taken from the QThreadPool \a pool. You can specify the type of container as the a template
+ argument, like this:
+
+ \code
+ QList<int> ints = QtConcurrent::blockingMapped<QList<int> >(beginIterator, endIterator, fn);
+ \endcode
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa mapped(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename Sequence, typename Iterator, typename MapFunctor> Sequence QtConcurrent::blockingMapped(Iterator begin, Iterator end, MapFunctor &&function)
Calls \a function once for each item from \a begin to \a end and returns a
- container with the results. Specify the type of container as the a template
+ container with the results. You can specify the type of container as the a template
argument, like this:
\code
@@ -412,7 +606,23 @@
*/
/*!
- \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item in \a sequence.
+ All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool.
+ The return value of each \a mapFunction is passed to \a reduceFunction.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is determined by \a reduceOptions.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa mapped(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(Sequence &&sequence, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a mapFunction once for each item in \a sequence. The return value of
each \a mapFunction is passed to \a reduceFunction.
@@ -427,7 +637,61 @@
*/
/*!
- \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingMappedReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item in \a sequence.
+ All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool.
+ The return value of each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is determined by \a reduceOptions.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa mapped(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingMappedReduced(Sequence &&sequence, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item in \a sequence. The return value of
+ each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is determined by \a reduceOptions.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa mapped(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item from \a begin to \a end.
+ All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool.
+ The return value of each \a mapFunction is passed to \a reduceFunction.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is undefined.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a mapFunction once for each item from \a begin to \a end. The return
value of each \a mapFunction is passed to \a reduceFunction.
@@ -443,37 +707,40 @@
*/
/*!
- \class QtConcurrent::FunctionWrapper0
- \inmodule QtConcurrent
- \internal
-*/
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingMappedReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
-/*!
- \class QtConcurrent::FunctionWrapper1
- \inmodule QtConcurrent
- \internal
-*/
+ Calls \a mapFunction once for each item from \a begin to \a end.
+ All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool.
+ The return value of each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
-/*!
- \class QtConcurrent::FunctionWrapper2
- \inmodule QtConcurrent
- \internal
-*/
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is undefined.
-/*!
- \class QtConcurrent::MemberFunctionWrapper
- \inmodule QtConcurrent
- \internal
-*/
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
-/*!
- \class QtConcurrent::MemberFunctionWrapper1
- \inmodule QtConcurrent
- \internal
+ \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce}
*/
/*!
- \class QtConcurrent::ConstMemberFunctionWrapper
- \inmodule QtConcurrent
- \internal
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor &&mapFunction, ReduceFunctor &&reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item from \a begin to \a end. The return
+ value of each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is undefined.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce}
*/
diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h
index 151f03cf56..bd959f44d3 100644
--- a/src/concurrent/qtconcurrentmap.h
+++ b/src/concurrent/qtconcurrentmap.h
@@ -1,53 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_MAP_H
#define QTCONCURRENT_MAP_H
+#if 0
+#pragma qt_class(QtConcurrentMap)
+#endif
+
#include <QtConcurrent/qtconcurrent_global.h>
-#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtConcurrent/qtconcurrentmapkernel.h>
#include <QtConcurrent/qtconcurrentreducekernel.h>
#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
-#include <QtCore/qstringlist.h>
QT_BEGIN_NAMESPACE
@@ -57,204 +24,793 @@ namespace QtConcurrent {
// map() on sequences
template <typename Sequence, typename MapFunctor>
-QFuture<void> map(Sequence &sequence, MapFunctor map)
+QFuture<void> map(QThreadPool *pool, Sequence &&sequence, MapFunctor &&map)
+{
+ return startMap(pool, sequence.begin(), sequence.end(), std::forward<MapFunctor>(map));
+}
+
+template <typename Sequence, typename MapFunctor>
+QFuture<void> map(Sequence &&sequence, MapFunctor &&map)
{
- return startMap(sequence.begin(), sequence.end(), QtPrivate::createFunctionWrapper(map));
+ return startMap(QThreadPool::globalInstance(), sequence.begin(), sequence.end(),
+ std::forward<MapFunctor>(map));
}
// map() on iterators
template <typename Iterator, typename MapFunctor>
-QFuture<void> map(Iterator begin, Iterator end, MapFunctor map)
+QFuture<void> map(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
{
- return startMap(begin, end, QtPrivate::createFunctionWrapper(map));
+ return startMap(pool, begin, end, std::forward<MapFunctor>(map));
+}
+
+template <typename Iterator, typename MapFunctor>
+QFuture<void> map(Iterator begin, Iterator end, MapFunctor &&map)
+{
+ return startMap(QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map));
}
// mappedReduced() for sequences.
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
-QFuture<ResultType> mappedReduced(const Sequence &sequence,
- MapFunctor map,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
-{
- return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>
- (sequence,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::createFunctionWrapper(reduce),
- options);
+QFuture<ResultType> mappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
+ (pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
}
-template <typename Sequence, typename MapFunctor, typename ReduceFunctor>
-QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedReduced(const Sequence &sequence,
- MapFunctor map,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
+QFuture<ResultType> mappedReduced(Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
- (sequence,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::createFunctionWrapper(reduce),
- options);
+ return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
+ (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce), options);
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> mappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+#ifdef Q_QDOC
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> mappedReduced(Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
+ (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+QFuture<ResultType> mappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
+ (pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+}
+
+template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+QFuture<ResultType> mappedReduced(Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
+ (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce), options);
+}
+
+#ifdef Q_QDOC
+template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename ResultType,
+ typename InitialValueType>
+#else
+template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> mappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+#ifdef Q_QDOC
+template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename ResultType,
+ typename InitialValueType>
+#else
+template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> mappedReduced(Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
+ (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
}
// mappedReduced() for iterators
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
-QFuture<ResultType> mappedReduced(Iterator begin,
+QFuture<ResultType> mappedReduced(QThreadPool *pool,
+ Iterator begin,
Iterator end,
- MapFunctor map,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
-{
- return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>
- (begin, end,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::createFunctionWrapper(reduce),
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
+ (pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
options);
}
-template <typename Iterator, typename MapFunctor, typename ReduceFunctor>
-QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedReduced(Iterator begin,
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
+QFuture<ResultType> mappedReduced(Iterator begin,
Iterator end,
- MapFunctor map,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
-{
- return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
- (begin, end,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::createFunctionWrapper(reduce),
- options);
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
+ (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> mappedReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
+ (pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> mappedReduced(Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
+ (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+QFuture<ResultType> mappedReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>(
+ pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ options);
+}
+
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+QFuture<ResultType> mappedReduced(Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
+ (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+}
+
+#ifdef Q_QDOC
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
+ typename InitialValueType>
+#else
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> mappedReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
+ (pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
+#ifdef Q_QDOC
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
+ typename InitialValueType>
+#else
+template<typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+QFuture<ResultType> mappedReduced(Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
+ (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
}
// mapped() for sequences
template <typename Sequence, typename MapFunctor>
-QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(const Sequence &sequence, MapFunctor map)
+QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> mapped(
+ QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map)
+{
+ return startMapped<QtPrivate::MapResultType<Sequence, MapFunctor>>(
+ pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map));
+}
+
+template <typename Sequence, typename MapFunctor>
+QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> mapped(
+ Sequence &&sequence,
+ MapFunctor &&map)
{
- return startMapped<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType>(sequence, QtPrivate::createFunctionWrapper(map));
+ return startMapped<QtPrivate::MapResultType<Sequence, MapFunctor>>
+ (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map));
}
// mapped() for iterator ranges.
template <typename Iterator, typename MapFunctor>
-QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(Iterator begin, Iterator end, MapFunctor map)
+QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> mapped(
+ QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&map)
+{
+ return startMapped<QtPrivate::MapResultType<Iterator, MapFunctor>>(
+ pool, begin, end, std::forward<MapFunctor>(map));
+}
+
+template <typename Iterator, typename MapFunctor>
+QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> mapped(
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&map)
{
- return startMapped<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType>(begin, end, QtPrivate::createFunctionWrapper(map));
+ return startMapped<QtPrivate::MapResultType<Iterator, MapFunctor>>
+ (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map));
}
// blockingMap() for sequences
template <typename Sequence, typename MapFunctor>
-void blockingMap(Sequence &sequence, MapFunctor map)
+void blockingMap(QThreadPool *pool, Sequence &&sequence, MapFunctor map)
+{
+ QFuture<void> future =
+ startMap(pool, sequence.begin(), sequence.end(), std::forward<MapFunctor>(map));
+ future.waitForFinished();
+}
+
+template <typename Sequence, typename MapFunctor>
+void blockingMap(Sequence &&sequence, MapFunctor &&map)
{
- startMap(sequence.begin(), sequence.end(), QtPrivate::createFunctionWrapper(map)).startBlocking();
+ QFuture<void> future = startMap(QThreadPool::globalInstance(), sequence.begin(), sequence.end(),
+ std::forward<MapFunctor>(map));
+ future.waitForFinished();
}
// blockingMap() for iterator ranges
template <typename Iterator, typename MapFunctor>
-void blockingMap(Iterator begin, Iterator end, MapFunctor map)
+void blockingMap(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
{
- startMap(begin, end, QtPrivate::createFunctionWrapper(map)).startBlocking();
+ QFuture<void> future = startMap(pool, begin, end, map);
+ future.waitForFinished();
+}
+
+template <typename Iterator, typename MapFunctor>
+void blockingMap(Iterator begin, Iterator end, MapFunctor &&map)
+{
+ QFuture<void> future = startMap(QThreadPool::globalInstance(), begin, end,
+ std::forward<MapFunctor>(map));
+ future.waitForFinished();
}
// blockingMappedReduced() for sequences
template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
-ResultType blockingMappedReduced(const Sequence &sequence,
- MapFunctor map,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+ResultType blockingMappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future =
+ mappedReduced<ResultType>(pool, std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
+ResultType blockingMappedReduced(Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future =
+ mappedReduced<ResultType>(std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingMappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = mappedReduced<ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingMappedReduced(Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>
- (sequence,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::createFunctionWrapper(reduce),
- options)
- .startBlocking();
+ QFuture<ResultType> future = mappedReduced<ResultType>(
+ std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
}
-template <typename MapFunctor, typename ReduceFunctor, typename Sequence>
-typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedReduced(const Sequence &sequence,
- MapFunctor map,
- ReduceFunctor reduce,
- ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+template <typename MapFunctor, typename ReduceFunctor, typename Sequence,
+ std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+ResultType blockingMappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
- (sequence,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::createFunctionWrapper(reduce),
- options)
- .startBlocking();
+ QFuture<ResultType> future =
+ mappedReduced<ResultType>(pool, std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename MapFunctor, typename ReduceFunctor, typename Sequence,
+ std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+ResultType blockingMappedReduced(Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future =
+ mappedReduced<ResultType>(std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename ResultType,
+ typename InitialValueType>
+#else
+template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingMappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = mappedReduced<ResultType>(
+ pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename ResultType,
+ typename InitialValueType>
+#else
+template<typename MapFunctor, typename ReduceFunctor, typename Sequence, typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInvocable<MapFunctor, Sequence>::value, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingMappedReduced(Sequence &&sequence,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = mappedReduced<ResultType>(
+ std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
}
// blockingMappedReduced() for iterator ranges
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
+ResultType blockingMappedReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future =
+ mappedReduced<ResultType>(pool, begin, end, std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
ResultType blockingMappedReduced(Iterator begin,
Iterator end,
- MapFunctor map,
- ReduceFunctor reduce,
- QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce))
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>
- (begin, end,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::createFunctionWrapper(reduce),
- options)
- .startBlocking();
+ QFuture<ResultType> future =
+ mappedReduced<ResultType>(begin, end, std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
}
-template <typename Iterator, typename MapFunctor, typename ReduceFunctor>
-typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedReduced(Iterator begin,
+#ifdef Q_QDOC
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingMappedReduced(QThreadPool *pool,
+ Iterator begin,
Iterator end,
- MapFunctor map,
- ReduceFunctor reduce,
- QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce))
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
{
- return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
- (begin, end,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::createFunctionWrapper(reduce),
- options)
- .startBlocking();
+ QFuture<ResultType> future = mappedReduced<ResultType>(
+ pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)),
+ options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType>
+#else
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingMappedReduced(Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = mappedReduced<ResultType>(
+ begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)),
+ options);
+ return future.takeResult();
+}
+
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+ResultType blockingMappedReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future =
+ mappedReduced<ResultType>(pool, begin, end, std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type>
+ResultType blockingMappedReduced(Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future =
+ mappedReduced<ResultType>(begin, end, std::forward<MapFunctor>(map),
+ std::forward<ReduceFunctor>(reduce), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
+ typename InitialValueType>
+#else
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingMappedReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = mappedReduced<ResultType>(
+ pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
+}
+
+#ifdef Q_QDOC
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
+ typename InitialValueType>
+#else
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0,
+ typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type,
+ typename InitialValueType,
+ std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>,
+ int> = 0>
+#endif
+ResultType blockingMappedReduced(Iterator begin,
+ Iterator end,
+ MapFunctor &&map,
+ ReduceFunctor &&reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ QFuture<ResultType> future = mappedReduced<ResultType>(
+ begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+ return future.takeResult();
}
// mapped() for sequences with a different putput sequence type.
template <typename OutputSequence, typename InputSequence, typename MapFunctor>
-OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map)
+OutputSequence blockingMapped(QThreadPool *pool, InputSequence &&sequence, MapFunctor &&map)
+{
+ return blockingMappedReduced<OutputSequence>(pool, std::forward<InputSequence>(sequence),
+ std::forward<MapFunctor>(map),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
+}
+
+template <typename OutputSequence, typename InputSequence, typename MapFunctor>
+OutputSequence blockingMapped(InputSequence &&sequence, MapFunctor &&map)
+{
+ return blockingMappedReduced<OutputSequence>(
+ QThreadPool::globalInstance(), std::forward<InputSequence>(sequence),
+ std::forward<MapFunctor>(map), QtPrivate::PushBackWrapper(), OrderedReduce);
+}
+
+template <typename MapFunctor, typename InputSequence>
+auto blockingMapped(QThreadPool *pool, InputSequence &&sequence, MapFunctor &&map)
{
- return blockingMappedReduced<OutputSequence>
- (sequence,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::PushBackWrapper(),
- QtConcurrent::OrderedReduce);
+ using OutputSequence = typename QtPrivate::MapSequenceResultType<std::decay_t<InputSequence>,
+ MapFunctor>::ResultType;
+ return blockingMappedReduced<OutputSequence>(pool, std::forward<InputSequence>(sequence),
+ std::forward<MapFunctor>(map),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename MapFunctor, typename InputSequence>
-typename QtPrivate::MapResultType<InputSequence, MapFunctor>::ResultType blockingMapped(const InputSequence &sequence, MapFunctor map)
+auto blockingMapped(InputSequence &&sequence, MapFunctor &&map)
{
- typedef typename QtPrivate::MapResultType<InputSequence, MapFunctor>::ResultType OutputSequence;
- return blockingMappedReduced<OutputSequence>
- (sequence,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::PushBackWrapper(),
- QtConcurrent::OrderedReduce);
+ using OutputSequence = typename QtPrivate::MapSequenceResultType<std::decay_t<InputSequence>,
+ MapFunctor>::ResultType;
+ return blockingMappedReduced<OutputSequence>(QThreadPool::globalInstance(),
+ std::forward<InputSequence>(sequence),
+ std::forward<MapFunctor>(map),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
}
// mapped() for iterator ranges
template <typename Sequence, typename Iterator, typename MapFunctor>
-Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor map)
+Sequence blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
+{
+ return blockingMappedReduced<Sequence>(pool, begin, end, std::forward<MapFunctor>(map),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
+}
+
+template <typename Sequence, typename Iterator, typename MapFunctor>
+Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor &&map)
{
- return blockingMappedReduced<Sequence>
- (begin, end,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::PushBackWrapper(),
- QtConcurrent::OrderedReduce);
+ return blockingMappedReduced<Sequence>(QThreadPool::globalInstance(), begin, end,
+ std::forward<MapFunctor>(map),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
}
template <typename Iterator, typename MapFunctor>
-typename QtPrivate::MapResultType<Iterator, MapFunctor>::ResultType blockingMapped(Iterator begin, Iterator end, MapFunctor map)
-{
- typedef typename QtPrivate::MapResultType<Iterator, MapFunctor>::ResultType OutputSequence;
- return blockingMappedReduced<OutputSequence>
- (begin, end,
- QtPrivate::createFunctionWrapper(map),
- QtPrivate::PushBackWrapper(),
- QtConcurrent::OrderedReduce);
+auto blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
+{
+ using OutputSequence = QtPrivate::MapResultType<Iterator, MapFunctor>;
+ return blockingMappedReduced<OutputSequence>(pool, begin, end, std::forward<MapFunctor>(map),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
+}
+
+template <typename Iterator, typename MapFunctor>
+auto blockingMapped(Iterator begin, Iterator end, MapFunctor &&map)
+{
+ using OutputSequence = QtPrivate::MapResultType<Iterator, MapFunctor>;
+ return blockingMappedReduced<OutputSequence>(QThreadPool::globalInstance(), begin, end,
+ std::forward<MapFunctor>(map),
+ QtPrivate::PushBackWrapper(), OrderedReduce);
}
} // namespace QtConcurrent
diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h
index 7c9538a015..61b18e5438 100644
--- a/src/concurrent/qtconcurrentmapkernel.h
+++ b/src/concurrent/qtconcurrentmapkernel.h
@@ -1,51 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_MAPKERNEL_H
#define QTCONCURRENT_MAPKERNEL_H
#include <QtConcurrent/qtconcurrent_global.h>
-#if !defined(QT_NO_CONCURRENT) || defined (Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined (Q_QDOC)
#include <QtConcurrent/qtconcurrentiteratekernel.h>
#include <QtConcurrent/qtconcurrentreducekernel.h>
+#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
QT_BEGIN_NAMESPACE
@@ -59,13 +24,14 @@ class MapKernel : public IterateKernel<Iterator, void>
MapFunctor map;
public:
typedef void ReturnType;
- MapKernel(Iterator begin, Iterator end, MapFunctor _map)
- : IterateKernel<Iterator, void>(begin, end), map(_map)
+ template <typename F = MapFunctor>
+ MapKernel(QThreadPool *pool, Iterator begin, Iterator end, F &&_map)
+ : IterateKernel<Iterator, void>(pool, begin, end), map(std::forward<F>(_map))
{ }
bool runIteration(Iterator it, int, void *) override
{
- map(*it);
+ std::invoke(map, *it);
return false;
}
@@ -88,39 +54,54 @@ template <typename ReducedResultType,
typename ReduceFunctor,
typename Reducer = ReduceKernel<ReduceFunctor,
ReducedResultType,
- typename MapFunctor::result_type> >
+ QtPrivate::MapResultType<Iterator, MapFunctor>>>
class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType>
{
- ReducedResultType reducedResult;
+ ReducedResultType &reducedResult;
MapFunctor map;
ReduceFunctor reduce;
Reducer reducer;
+ using IntermediateResultsType = QtPrivate::MapResultType<Iterator, MapFunctor>;
+
public:
typedef ReducedResultType ReturnType;
- MappedReducedKernel(Iterator begin, Iterator end, MapFunctor _map, ReduceFunctor _reduce, ReduceOptions reduceOptions)
- : IterateKernel<Iterator, ReducedResultType>(begin, end), reducedResult(), map(_map), reduce(_reduce), reducer(reduceOptions)
- { }
- MappedReducedKernel(ReducedResultType initialValue,
- MapFunctor _map,
- ReduceFunctor _reduce)
- : reducedResult(initialValue), map(_map), reduce(_reduce)
+ template<typename F1 = MapFunctor, typename F2 = ReduceFunctor>
+ MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, F1 &&_map, F2 &&_reduce,
+ ReduceOptions reduceOptions)
+ : IterateKernel<Iterator, ReducedResultType>(pool, begin, end),
+ reducedResult(this->defaultValue.value),
+ map(std::forward<F1>(_map)),
+ reduce(std::forward<F2>(_reduce)),
+ reducer(pool, reduceOptions)
{ }
+ template<typename F1 = MapFunctor, typename F2 = ReduceFunctor>
+ MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, F1 &&_map, F2 &&_reduce,
+ ReducedResultType &&initialValue, ReduceOptions reduceOptions)
+ : IterateKernel<Iterator, ReducedResultType>(pool, begin, end,
+ std::forward<ReducedResultType>(initialValue)),
+ reducedResult(this->defaultValue.value),
+ map(std::forward<F1>(_map)),
+ reduce(std::forward<F2>(_reduce)),
+ reducer(pool, reduceOptions)
+ {
+ }
+
bool runIteration(Iterator it, int index, ReducedResultType *) override
{
- IntermediateResults<typename MapFunctor::result_type> results;
+ IntermediateResults<IntermediateResultsType> results;
results.begin = index;
results.end = index + 1;
- results.vector.append(map(*it));
+ results.vector.append(std::invoke(map, *it));
reducer.runReduce(reduce, reducedResult, results);
return false;
}
bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, ReducedResultType *) override
{
- IntermediateResults<typename MapFunctor::result_type> results;
+ IntermediateResults<IntermediateResultsType> results;
results.begin = beginIndex;
results.end = endIndex;
results.vector.reserve(endIndex - beginIndex);
@@ -128,7 +109,7 @@ public:
Iterator it = sequenceBeginIterator;
std::advance(it, beginIndex);
for (int i = beginIndex; i < endIndex; ++i) {
- results.vector.append(map(*(it)));
+ results.vector.append(std::invoke(map, *it));
std::advance(it, 1);
}
@@ -159,20 +140,20 @@ public:
};
template <typename Iterator, typename MapFunctor>
-class MappedEachKernel : public IterateKernel<Iterator, typename MapFunctor::result_type>
+class MappedEachKernel : public IterateKernel<Iterator, QtPrivate::MapResultType<Iterator, MapFunctor>>
{
MapFunctor map;
- typedef typename MapFunctor::result_type T;
-public:
- typedef T ReturnType;
- typedef T ResultType;
+ using T = QtPrivate::MapResultType<Iterator, MapFunctor>;
- MappedEachKernel(Iterator begin, Iterator end, MapFunctor _map)
- : IterateKernel<Iterator, T>(begin, end), map(_map) { }
+public:
+ template <typename F = MapFunctor>
+ MappedEachKernel(QThreadPool *pool, Iterator begin, Iterator end, F &&_map)
+ : IterateKernel<Iterator, T>(pool, begin, end), map(std::forward<F>(_map))
+ { }
bool runIteration(Iterator it, int, T *result) override
{
- *result = map(*it);
+ *result = std::invoke(map, *it);
return true;
}
@@ -192,16 +173,20 @@ public:
//! [qtconcurrentmapkernel-1]
template <typename Iterator, typename Functor>
-inline ThreadEngineStarter<void> startMap(Iterator begin, Iterator end, Functor functor)
+inline ThreadEngineStarter<void> startMap(QThreadPool *pool, Iterator begin,
+ Iterator end, Functor &&functor)
{
- return startThreadEngine(new MapKernel<Iterator, Functor>(begin, end, functor));
+ return startThreadEngine(new MapKernel<Iterator, std::decay_t<Functor>>(
+ pool, begin, end, std::forward<Functor>(functor)));
}
//! [qtconcurrentmapkernel-2]
template <typename T, typename Iterator, typename Functor>
-inline ThreadEngineStarter<T> startMapped(Iterator begin, Iterator end, Functor functor)
+inline ThreadEngineStarter<T> startMapped(QThreadPool *pool, Iterator begin,
+ Iterator end, Functor &&functor)
{
- return startThreadEngine(new MappedEachKernel<Iterator, Functor>(begin, end, functor));
+ return startThreadEngine(new MappedEachKernel<Iterator, std::decay_t<Functor>>(
+ pool, begin, end, std::forward<Functor>(functor)));
}
/*
@@ -209,56 +194,127 @@ inline ThreadEngineStarter<T> startMapped(Iterator begin, Iterator end, Functor
sequence we are working on.
*/
template <typename Sequence, typename Base, typename Functor>
-struct SequenceHolder1 : public Base
+struct SequenceHolder1 : private QtPrivate::SequenceHolder<Sequence>, public Base
{
- SequenceHolder1(const Sequence &_sequence, Functor functor)
- : Base(_sequence.begin(), _sequence.end(), functor), sequence(_sequence)
+ template<typename S = Sequence, typename F = Functor>
+ SequenceHolder1(QThreadPool *pool, S &&_sequence, F &&functor)
+ : QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
+ Base(pool, this->sequence.cbegin(), this->sequence.cend(), std::forward<F>(functor))
{ }
- Sequence sequence;
-
void finish() override
{
Base::finish();
// Clear the sequence to make sure all temporaries are destroyed
// before finished is signaled.
- sequence = Sequence();
+ this->sequence = Sequence();
}
};
//! [qtconcurrentmapkernel-3]
template <typename T, typename Sequence, typename Functor>
-inline ThreadEngineStarter<T> startMapped(const Sequence &sequence, Functor functor)
+inline ThreadEngineStarter<T> startMapped(QThreadPool *pool, Sequence &&sequence,
+ Functor &&functor)
{
- typedef SequenceHolder1<Sequence,
- MappedEachKernel<typename Sequence::const_iterator , Functor>, Functor>
- SequenceHolderType;
-
- return startThreadEngine(new SequenceHolderType(sequence, functor));
+ using DecayedSequence = std::decay_t<Sequence>;
+ using DecayedFunctor = std::decay_t<Functor>;
+ using SequenceHolderType = SequenceHolder1<
+ DecayedSequence,
+ MappedEachKernel<typename DecayedSequence::const_iterator, DecayedFunctor>,
+ DecayedFunctor>;
+
+ return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
+ std::forward<Functor>(functor)));
}
//! [qtconcurrentmapkernel-4]
-template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
-inline ThreadEngineStarter<ResultType> startMappedReduced(const Sequence & sequence,
- MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
- ReduceOptions options)
+template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor,
+ typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&mapFunctor,
+ ReduceFunctor &&reduceFunctor,
+ ReduceOptions options)
{
- typedef typename Sequence::const_iterator Iterator;
- typedef ReduceKernel<ReduceFunctor, ResultType, IntermediateType> Reducer;
- typedef MappedReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> MappedReduceType;
- typedef SequenceHolder2<Sequence, MappedReduceType, MapFunctor, ReduceFunctor> SequenceHolderType;
- return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, options));
+ using DecayedSequence = std::decay_t<Sequence>;
+ using DecayedMapFunctor = std::decay_t<MapFunctor>;
+ using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
+ using Iterator = typename DecayedSequence::const_iterator;
+ using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType, IntermediateType>;
+ using MappedReduceType = MappedReducedKernel<ResultType, Iterator, DecayedMapFunctor,
+ DecayedReduceFunctor, Reducer>;
+ using SequenceHolderType = SequenceHolder2<DecayedSequence, MappedReduceType, DecayedMapFunctor,
+ DecayedReduceFunctor>;
+ return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(mapFunctor),
+ std::forward<ReduceFunctor>(reduceFunctor),
+ options));
}
//! [qtconcurrentmapkernel-5]
-template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
-inline ThreadEngineStarter<ResultType> startMappedReduced(Iterator begin, Iterator end,
- MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
- ReduceOptions options)
+template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor,
+ typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&mapFunctor,
+ ReduceFunctor &&reduceFunctor,
+ ReduceOptions options)
+{
+ using Reducer =
+ ReduceKernel<std::decay_t<ReduceFunctor>, std::decay_t<ResultType>, IntermediateType>;
+ using MappedReduceType = MappedReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
+ std::decay_t<ReduceFunctor>, Reducer>;
+ return startThreadEngine(new MappedReduceType(pool, begin, end,
+ std::forward<MapFunctor>(mapFunctor),
+ std::forward<ReduceFunctor>(reduceFunctor),
+ options));
+}
+
+//! [qtconcurrentmapkernel-6]
+template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor,
+ typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
+ Sequence &&sequence,
+ MapFunctor &&mapFunctor,
+ ReduceFunctor &&reduceFunctor,
+ ResultType &&initialValue,
+ ReduceOptions options)
+{
+ using DecayedSequence = std::decay_t<Sequence>;
+ using DecayedMapFunctor = std::decay_t<MapFunctor>;
+ using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
+ using Iterator = typename DecayedSequence::const_iterator;
+ using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType, IntermediateType>;
+ using MappedReduceType = MappedReducedKernel<ResultType, Iterator, DecayedMapFunctor,
+ DecayedReduceFunctor, Reducer>;
+ using SequenceHolderType = SequenceHolder2<DecayedSequence, MappedReduceType, DecayedMapFunctor,
+ DecayedReduceFunctor>;
+ return startThreadEngine(
+ new SequenceHolderType(pool, std::forward<Sequence>(sequence),
+ std::forward<MapFunctor>(mapFunctor),
+ std::forward<ReduceFunctor>(reduceFunctor),
+ std::forward<ResultType>(initialValue), options));
+}
+
+//! [qtconcurrentmapkernel-7]
+template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor,
+ typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
+ Iterator begin,
+ Iterator end,
+ MapFunctor &&mapFunctor,
+ ReduceFunctor &&reduceFunctor,
+ ResultType &&initialValue,
+ ReduceOptions options)
{
- typedef ReduceKernel<ReduceFunctor, ResultType, IntermediateType> Reducer;
- typedef MappedReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> MappedReduceType;
- return startThreadEngine(new MappedReduceType(begin, end, mapFunctor, reduceFunctor, options));
+ using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType, IntermediateType>;
+ using MappedReduceType = MappedReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
+ std::decay_t<ReduceFunctor>, Reducer>;
+ return startThreadEngine(new MappedReduceType(pool, begin, end,
+ std::forward<MapFunctor>(mapFunctor),
+ std::forward<ReduceFunctor>(reduceFunctor),
+ std::forward<ResultType>(initialValue), options));
}
} // namespace QtConcurrent
diff --git a/src/concurrent/qtconcurrentmedian.h b/src/concurrent/qtconcurrentmedian.h
index cec2431d6f..01cb8b93e0 100644
--- a/src/concurrent/qtconcurrentmedian.h
+++ b/src/concurrent/qtconcurrentmedian.h
@@ -1,138 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_MEDIAN_H
#define QTCONCURRENT_MEDIAN_H
#include <QtConcurrent/qtconcurrent_global.h>
-#if !defined(QT_NO_CONCURRENT) ||defined(Q_CLANG_QDOC)
-
-#include <QtCore/qvector.h>
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <algorithm>
+#include <cstring>
QT_BEGIN_NAMESPACE
-
-
namespace QtConcurrent {
-template <typename T>
class Median
{
public:
- Median(int _bufferSize)
- : currentMedian(), bufferSize(_bufferSize), currentIndex(0), valid(false), dirty(true)
- {
- values.resize(bufferSize);
- }
-
- void reset()
- {
- values.fill(0);
- currentIndex = 0;
- valid = false;
- dirty = true;
- }
-
- void addValue(T value)
- {
- currentIndex = ((currentIndex + 1) % bufferSize);
- if (valid == false && currentIndex % bufferSize == 0)
- valid = true;
-
- // Only update the cached median value when we have to, that
- // is when the new value is on then other side of the median
- // compared to the current value at the index.
- const T currentIndexValue = values[currentIndex];
- if ((currentIndexValue > currentMedian && currentMedian > value)
- || (currentMedian > currentIndexValue && value > currentMedian)) {
- dirty = true;
- }
-
- values[currentIndex] = value;
- }
-
- bool isMedianValid() const
- {
- return valid;
- }
-
- T median()
- {
- if (dirty) {
- dirty = false;
-
-// This is a workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58800
-// Avoid using std::nth_element for the affected stdlibc++ releases 4.7.3 and 4.8.2.
-// Note that the official __GLIBCXX__ value of the releases is not used since that
-// one might be patched on some GNU/Linux distributions.
-#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20140107
- QVector<T> sorted = values;
- std::sort(sorted.begin(), sorted.end());
- currentMedian = sorted.at(bufferSize / 2);
-#else
- QVector<T> copy = values;
- typename QVector<T>::iterator begin = copy.begin(), mid = copy.begin() + bufferSize/2, end = copy.end();
- std::nth_element(begin, mid, end);
- currentMedian = *mid;
-#endif
- }
- return currentMedian;
- }
-private:
- QVector<T> values;
- T currentMedian;
- int bufferSize;
- int currentIndex;
- bool valid;
- bool dirty;
-};
-
-// ### Qt6: Drop Median<double> in favor of this faster MedianDouble
-class MedianDouble
-{
-public:
enum { BufferSize = 7 };
- MedianDouble()
+ Median()
: currentMedian(), currentIndex(0), valid(false), dirty(true)
{
std::fill_n(values, static_cast<int>(BufferSize), 0.0);
@@ -195,7 +83,6 @@ private:
} // namespace QtConcurrent
-
QT_END_NAMESPACE
#endif // QT_NO_CONCURRENT
diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h
index 8f9a938952..c337a9192f 100644
--- a/src/concurrent/qtconcurrentreducekernel.h
+++ b/src/concurrent/qtconcurrentreducekernel.h
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_REDUCEKERNEL_H
#define QTCONCURRENT_REDUCEKERNEL_H
#include <QtConcurrent/qtconcurrent_global.h>
-#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtCore/qatomic.h>
#include <QtCore/qlist.h>
@@ -50,12 +14,22 @@
#include <QtCore/qmutex.h>
#include <QtCore/qthread.h>
#include <QtCore/qthreadpool.h>
-#include <QtCore/qvector.h>
#include <mutex>
QT_BEGIN_NAMESPACE
+namespace QtPrivate {
+
+template<typename Sequence>
+struct SequenceHolder
+{
+ SequenceHolder(const Sequence &s) : sequence(s) { }
+ SequenceHolder(Sequence &&s) : sequence(std::move(s)) { }
+ Sequence sequence;
+};
+
+}
namespace QtConcurrent {
@@ -66,7 +40,7 @@ namespace QtConcurrent {
MapReduce won't start any new threads, and when it exceeds
ReduceQueueThrottleLimit running threads will be stopped.
*/
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
enum ReduceQueueLimits {
ReduceQueueStartLimit = 20,
ReduceQueueThrottleLimit = 30
@@ -86,7 +60,7 @@ class IntermediateResults
{
public:
int begin, end;
- QVector<T> vector;
+ QList<T> vector;
};
enum ReduceOption {
@@ -96,7 +70,7 @@ enum ReduceOption {
// ParallelReduce = 0x8
};
Q_DECLARE_FLAGS(ReduceOptions, ReduceOption)
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
Q_DECLARE_OPERATORS_FOR_FLAGS(ReduceOptions)
#endif
// supports both ordered and out-of-order reduction
@@ -108,7 +82,8 @@ class ReduceKernel
const ReduceOptions reduceOptions;
QMutex mutex;
- int progress, resultsMapSize, threadCount;
+ int progress, resultsMapSize;
+ const int threadCount;
ResultsMap resultsMap;
bool canReduce(int begin) const
@@ -124,7 +99,7 @@ class ReduceKernel
const IntermediateResults<T> &result)
{
for (int i = 0; i < result.vector.size(); ++i) {
- reduce(r, result.vector.at(i));
+ std::invoke(reduce, r, result.vector.at(i));
}
}
@@ -140,9 +115,9 @@ class ReduceKernel
}
public:
- ReduceKernel(ReduceOptions _reduceOptions)
+ ReduceKernel(QThreadPool *pool, ReduceOptions _reduceOptions)
: reduceOptions(_reduceOptions), progress(0), resultsMapSize(0),
- threadCount(QThreadPool::globalInstance()->maxThreadCount())
+ threadCount(std::max(pool->maxThreadCount(), 1))
{ }
void runReduce(ReduceFunctor &reduce,
@@ -212,34 +187,44 @@ public:
inline bool shouldThrottle()
{
+ std::lock_guard<QMutex> locker(mutex);
return (resultsMapSize > (ReduceQueueThrottleLimit * threadCount));
}
inline bool shouldStartThread()
{
+ std::lock_guard<QMutex> locker(mutex);
return (resultsMapSize <= (ReduceQueueStartLimit * threadCount));
}
};
template <typename Sequence, typename Base, typename Functor1, typename Functor2>
-struct SequenceHolder2 : public Base
+struct SequenceHolder2 : private QtPrivate::SequenceHolder<Sequence>, public Base
{
- SequenceHolder2(const Sequence &_sequence,
- Functor1 functor1,
- Functor2 functor2,
+ template<typename S = Sequence, typename F1 = Functor1, typename F2 = Functor2>
+ SequenceHolder2(QThreadPool *pool, S &&_sequence, F1 &&functor1, F2 &&functor2,
ReduceOptions reduceOptions)
- : Base(_sequence.begin(), _sequence.end(), functor1, functor2, reduceOptions),
- sequence(_sequence)
+ : QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
+ Base(pool, this->sequence.cbegin(), this->sequence.cend(),
+ std::forward<F1>(functor1), std::forward<F2>(functor2), reduceOptions)
{ }
- Sequence sequence;
+ template<typename InitialValueType, typename S = Sequence,
+ typename F1 = Functor1, typename F2 = Functor2>
+ SequenceHolder2(QThreadPool *pool, S &&_sequence, F1 &&functor1, F2 &&functor2,
+ InitialValueType &&initialValue, ReduceOptions reduceOptions)
+ : QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
+ Base(pool, this->sequence.cbegin(), this->sequence.cend(),
+ std::forward<F1>(functor1), std::forward<F2>(functor2),
+ std::forward<InitialValueType>(initialValue), reduceOptions)
+ { }
void finish() override
{
Base::finish();
// Clear the sequence to make sure all temporaries are destroyed
// before finished is signaled.
- sequence = Sequence();
+ this->sequence = Sequence();
}
};
diff --git a/src/concurrent/qtconcurrentrun.cpp b/src/concurrent/qtconcurrentrun.cpp
index d9867e1f1a..017f2df480 100644
--- a/src/concurrent/qtconcurrentrun.cpp
+++ b/src/concurrent/qtconcurrentrun.cpp
@@ -1,59 +1,39 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/*!
\page qtconcurrentrun.html
\title Concurrent Run
+ \brief A simple way to run a task in a separate thread.
\ingroup 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.
- This function is a part of the \l {Qt Concurrent} framework.
+ 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.
- \section1 Running a Function in a Separate Thread
+ This function is a part of the Qt Concurrent framework.
+
+ \section1 Concurrent Run (basic mode)
+
+ The function passed to QtConcurrent::run() may report the result
+ through its return value.
+
+ \section2 Running a Function in a Separate Thread
To run a function in another thread, use QtConcurrent::run():
\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.
@@ -62,7 +42,7 @@
\snippet code/src_concurrent_qtconcurrentrun.cpp explicit-pool-0
- \section1 Passing Arguments to the Function
+ \section2 Passing Arguments to the Function
Passing arguments to the function is done by adding them to the
QtConcurrent::run() call immediately after the function name. For example:
@@ -74,12 +54,36 @@
the function. Changes made to the arguments after calling
QtConcurrent::run() are \e not visible to the thread.
- \section1 Returning Values from the Function
+ Note that QtConcurrent::run does not support calling overloaded functions
+ directly. For example, the code below won't compile:
+
+//! [run-with-overload-calls]
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 15
+
+ The easiest workaround is to call the overloaded function through lambda:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 16
+
+ Or you can tell the compiler which overload to choose by using a
+ \c static_cast:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 17
+
+ Or qOverload:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 18
+//! [run-with-overload-calls]
+
+ \section2 Returning Values from the Function
Any return value from the function is available via QFuture:
\snippet code/src_concurrent_qtconcurrentrun.cpp 2
+ If you don't need the result (for example, because the function returns
+ \c{void}), using the QThreadPool::start() overload taking a function object
+ is more efficient.
+
As documented above, passing arguments is done like this:
\snippet code/src_concurrent_qtconcurrentrun.cpp 3
@@ -88,9 +92,9 @@
to become available. Use QFutureWatcher to get notification when the
function has finished execution and the result is available.
- \section1 Additional API Features
+ \section2 Additional API Features
- \section2 Using Member Functions
+ \section3 Using Member Functions
QtConcurrent::run() also accepts pointers to member functions. The first
argument must be either a const reference or a pointer to an instance of
@@ -107,11 +111,107 @@
\snippet code/src_concurrent_qtconcurrentrun.cpp 5
- \section2 Using Lambda Functions
+ \section3 Using Lambda Functions
Calling a lambda function is done like this:
\snippet code/src_concurrent_qtconcurrentrun.cpp 6
+
+ Calling a function modifies an object passed by reference is done like this:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 7
+
+ Using callable object is done like this:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 8
+
+ \section1 Concurrent Run With Promise
+
+ 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
+ demand.
+
+ \section2 The mandatory QPromise argument
+
+ The function passed to QtConcurrent::run() in \e {Run With Promise} mode
+ is expected to have an additional argument of \c {QPromise<T> &} type, where
+ \c T is the type of the computation result (it should match the type \c T
+ of QFuture<T> returned by QtConcurrent::run()), like e.g.:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 9
+
+ 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, nor pass it explicitly
+ when calling QtConcurrent::run() in this mode.
+
+ The additional argument of QPromise type always needs to appear
+ as a first argument on function's arguments list, like:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 10
+
+ \section2 Reporting results
+
+ 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:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 11
+
+ \note There's no need to call QPromise::start() and QPromise::finish() to
+ indicate the beginning and the end of computation (like you would normally do when
+ using QPromise). QtConcurrent::run() will always call them before starting and
+ after finishing the execution.
+
+ \section2 Suspending and canceling the execution
+
+ The QPromise API also enables suspending and canceling the computation, if requested:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 12
+
+ 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 \c promise.suspendIfRequested()
+ in its iteration loop. In this case the running task will
+ 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 \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.
+
+ \note There's no need to call QPromise::finish() to stop the computation
+ after the cancellation (like you would normally do when using QPromise).
+ QtConcurrent::run() will always call it after finishing the execution.
+
+ \section2 Progress reporting
+
+ It's also possible to report the progress of a task
+ independently of result reporting, like:
+
+ \snippet code/src_concurrent_qtconcurrentrun.cpp 13
+
+ 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::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
*/
/*!
@@ -124,7 +224,7 @@
*/
/*!
- \fn QFuture<T> QtConcurrent::run(Function function, ...);
+ \fn template <typename T> QFuture<T> QtConcurrent::run(Function function, ...);
Equivalent to
\code
@@ -135,32 +235,37 @@
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<T> &} 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<T>.
+
+ 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}, QThreadPool::start()
+//! [run-description]
*/
/*!
\since 5.4
- \fn QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...);
+ \fn template <typename T> QFuture<T> QtConcurrent::run(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.
-
- 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.
+ Schedules \a function on \a pool. Note that \a function may not run
+ immediately; \a function will only be run once a thread becomes available.
- \sa {Concurrent Run}
+ \include qtconcurrentrun.cpp run-description
*/
+
diff --git a/src/concurrent/qtconcurrentrun.h b/src/concurrent/qtconcurrentrun.h
index 22dae70460..cbc750de84 100644
--- a/src/concurrent/qtconcurrentrun.h
+++ b/src/concurrent/qtconcurrentrun.h
@@ -1,56 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Generated code, do not edit! Use generator at tools/qtconcurrent/generaterun/
#ifndef QTCONCURRENT_RUN_H
#define QTCONCURRENT_RUN_H
+#if 0
+#pragma qt_class(QtConcurrentRun)
+#endif
+
#include <QtConcurrent/qtconcurrentcompilertest.h>
-#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
#include <QtConcurrent/qtconcurrentrunbase.h>
#include <QtConcurrent/qtconcurrentstoredfunctioncall.h>
QT_BEGIN_NAMESPACE
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
typedef int Function;
@@ -68,851 +35,59 @@ namespace QtConcurrent {
namespace QtConcurrent {
-template <typename T>
-QFuture<T> run(T (*functionPointer)())
-{
- return (new StoredFunctorCall0<T, T (*)()>(functionPointer))->start();
-}
-template <typename T, typename Param1, typename Arg1>
-QFuture<T> run(T (*functionPointer)(Param1), const Arg1 &arg1)
-{
- return (new StoredFunctorCall1<T, T (*)(Param1), Arg1>(functionPointer, arg1))->start();
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(T (*functionPointer)(Param1, Param2), const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new StoredFunctorCall2<T, T (*)(Param1, Param2), Arg1, Arg2>(functionPointer, arg1, arg2))->start();
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new StoredFunctorCall3<T, T (*)(Param1, Param2, Param3), Arg1, Arg2, Arg3>(functionPointer, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3, Param4), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new StoredFunctorCall4<T, T (*)(Param1, Param2, Param3, Param4), Arg1, Arg2, Arg3, Arg4>(functionPointer, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3, Param4, Param5), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new StoredFunctorCall5<T, T (*)(Param1, Param2, Param3, Param4, Param5), Arg1, Arg2, Arg3, Arg4, Arg5>(functionPointer, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-template <typename Functor>
-auto run(Functor functor) -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor())>>::type
-{
- typedef decltype(functor()) result_type;
- return (new StoredFunctorCall0<result_type, Functor>(functor))->start();
-}
-
-template <typename Functor, typename Arg1>
-auto run(Functor functor, const Arg1 &arg1)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1))>>::type
-{
- typedef decltype(functor(arg1)) result_type;
- return (new StoredFunctorCall1<result_type, Functor, Arg1>(functor, arg1))->start();
-}
-
-template <typename Functor, typename Arg1, typename Arg2>
-auto run(Functor functor, const Arg1 &arg1, const Arg2 &arg2)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2))>>::type
-{
- typedef decltype(functor(arg1, arg2)) result_type;
- return (new StoredFunctorCall2<result_type, Functor, Arg1, Arg2>(functor, arg1, arg2))->start();
-}
-
-template <typename Functor, typename Arg1, typename Arg2, typename Arg3>
-auto run(Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3))>>::type
-{
- typedef decltype(functor(arg1, arg2, arg3)) result_type;
- return (new StoredFunctorCall3<result_type, Functor, Arg1, Arg2, Arg3>(functor, arg1, arg2, arg3))->start();
-}
-
-template <typename Functor, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-auto run(Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3, arg4))>>::type
-{
- typedef decltype(functor(arg1, arg2, arg3, arg4)) result_type;
- return (new StoredFunctorCall4<result_type, Functor, Arg1, Arg2, Arg3, Arg4>(functor, arg1, arg2, arg3, arg4))->start();
-}
-
-template <typename Functor, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-auto run(Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3, arg4, arg5))>>::type
-{
- typedef decltype(functor(arg1, arg2, arg3, arg4, arg5)) result_type;
- return (new StoredFunctorCall5<result_type, Functor, Arg1, Arg2, Arg3, Arg4, Arg5>(functor, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-template <typename FunctionObject>
-QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject)
-{
- return (new StoredFunctorCall0<typename FunctionObject::result_type, FunctionObject>(functionObject))->start();
-}
-template <typename FunctionObject, typename Arg1>
-QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1)
-{
- return (new StoredFunctorCall1<typename FunctionObject::result_type, FunctionObject, Arg1>(functionObject, arg1))->start();
-}
-template <typename FunctionObject, typename Arg1, typename Arg2>
-QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new StoredFunctorCall2<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2>(functionObject, arg1, arg2))->start();
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3>
-QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new StoredFunctorCall3<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3>(functionObject, arg1, arg2, arg3))->start();
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new StoredFunctorCall4<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4>(functionObject, arg1, arg2, arg3, arg4))->start();
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-QFuture<typename FunctionObject::result_type> run(FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new StoredFunctorCall5<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4, Arg5>(functionObject, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-template <typename FunctionObject>
-QFuture<typename FunctionObject::result_type> run(FunctionObject *functionObject)
-{
- return (new typename SelectStoredFunctorPointerCall0<typename FunctionObject::result_type, FunctionObject>::type(functionObject))->start();
-}
-template <typename FunctionObject, typename Arg1>
-QFuture<typename FunctionObject::result_type> run(FunctionObject *functionObject, const Arg1 &arg1)
-{
- return (new typename SelectStoredFunctorPointerCall1<typename FunctionObject::result_type, FunctionObject, Arg1>::type(functionObject, arg1))->start();
-}
-template <typename FunctionObject, typename Arg1, typename Arg2>
-QFuture<typename FunctionObject::result_type> run(FunctionObject *functionObject, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredFunctorPointerCall2<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2>::type(functionObject, arg1, arg2))->start();
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3>
-QFuture<typename FunctionObject::result_type> run(FunctionObject *functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredFunctorPointerCall3<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3>::type(functionObject, arg1, arg2, arg3))->start();
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-QFuture<typename FunctionObject::result_type> run(FunctionObject *functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredFunctorPointerCall4<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4>::type(functionObject, arg1, arg2, arg3, arg4))->start();
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-QFuture<typename FunctionObject::result_type> run(FunctionObject *functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredFunctorPointerCall5<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4, Arg5>::type(functionObject, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-template <typename T, typename Class>
-QFuture<T> run(const Class &object, T (Class::*fn)())
-{
- return (new typename SelectStoredMemberFunctionCall0<T, Class>::type(fn, object))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1), const Arg1 &arg1)
-{
- return (new typename SelectStoredMemberFunctionCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2), const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-template <typename T, typename Class>
-QFuture<T> run(const Class &object, T (Class::*fn)() const)
-{
- return (new typename SelectStoredConstMemberFunctionCall0<T, Class>::type(fn, object))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1) const, const Arg1 &arg1)
-{
- return (new typename SelectStoredConstMemberFunctionCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2) const, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredConstMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredConstMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredConstMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredConstMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-template <typename T, typename Class>
-QFuture<T> run(Class *object, T (Class::*fn)())
-{
- return (new typename SelectStoredMemberFunctionPointerCall0<T, Class>::type(fn, object))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1), const Arg1 &arg1)
-{
- return (new typename SelectStoredMemberFunctionPointerCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1, Param2), const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1, Param2, Param3), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-template <typename T, typename Class>
-QFuture<T> run(const Class *object, T (Class::*fn)() const)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall0<T, Class>::type(fn, object))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1) const, const Arg1 &arg1)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1, Param2) const, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1, Param2, Param3) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-// ...and the same with a QThreadPool *pool argument...
-// generate from the above by c'n'p and s/run(/run(QThreadPool *pool, / and s/start()/start(pool)/
-
-template <typename T>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)())
-{
- return (new StoredFunctorCall0<T, T (*)()>(functionPointer))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1), const Arg1 &arg1)
-{
- return (new StoredFunctorCall1<T, T (*)(Param1), Arg1>(functionPointer, arg1))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1, Param2), const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new StoredFunctorCall2<T, T (*)(Param1, Param2), Arg1, Arg2>(functionPointer, arg1, arg2))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1, Param2, Param3), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new StoredFunctorCall3<T, T (*)(Param1, Param2, Param3), Arg1, Arg2, Arg3>(functionPointer, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1, Param2, Param3, Param4), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new StoredFunctorCall4<T, T (*)(Param1, Param2, Param3, Param4), Arg1, Arg2, Arg3, Arg4>(functionPointer, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1, Param2, Param3, Param4, Param5), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new StoredFunctorCall5<T, T (*)(Param1, Param2, Param3, Param4, Param5), Arg1, Arg2, Arg3, Arg4, Arg5>(functionPointer, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename Functor>
-auto run(QThreadPool *pool, Functor functor) -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor())>>::type
-{
- typedef decltype(functor()) result_type;
- return (new StoredFunctorCall0<result_type, Functor>(functor))->start(pool);
-}
-
-template <typename Functor, typename Arg1>
-auto run(QThreadPool *pool, Functor functor, const Arg1 &arg1)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1))>>::type
-{
- typedef decltype(functor(arg1)) result_type;
- return (new StoredFunctorCall1<result_type, Functor, Arg1>(functor, arg1))->start(pool);
-}
-
-template <typename Functor, typename Arg1, typename Arg2>
-auto run(QThreadPool *pool, Functor functor, const Arg1 &arg1, const Arg2 &arg2)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2))>>::type
-{
- typedef decltype(functor(arg1, arg2)) result_type;
- return (new StoredFunctorCall2<result_type, Functor, Arg1, Arg2>(functor, arg1, arg2))->start(pool);
-}
-
-template <typename Functor, typename Arg1, typename Arg2, typename Arg3>
-auto run(QThreadPool *pool, Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3))>>::type
-{
- typedef decltype(functor(arg1, arg2, arg3)) result_type;
- return (new StoredFunctorCall3<result_type, Functor, Arg1, Arg2, Arg3>(functor, arg1, arg2, arg3))->start(pool);
-}
-
-template <typename Functor, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-auto run(QThreadPool *pool, Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3, arg4))>>::type
-{
- typedef decltype(functor(arg1, arg2, arg3, arg4)) result_type;
- return (new StoredFunctorCall4<result_type, Functor, Arg1, Arg2, Arg3, Arg4>(functor, arg1, arg2, arg3, arg4))->start(pool);
-}
-
-template <typename Functor, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-auto run(QThreadPool *pool, Functor functor, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
- -> typename std::enable_if<!QtPrivate::HasResultType<Functor>::Value, QFuture<decltype(functor(arg1, arg2, arg3, arg4, arg5))>>::type
-{
- typedef decltype(functor(arg1, arg2, arg3, arg4, arg5)) result_type;
- return (new StoredFunctorCall5<result_type, Functor, Arg1, Arg2, Arg3, Arg4, Arg5>(functor, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename FunctionObject>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject functionObject)
-{
- return (new StoredFunctorCall0<typename FunctionObject::result_type, FunctionObject>(functionObject))->start(pool);
-}
-template <typename FunctionObject, typename Arg1>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject functionObject, const Arg1 &arg1)
-{
- return (new StoredFunctorCall1<typename FunctionObject::result_type, FunctionObject, Arg1>(functionObject, arg1))->start(pool);
-}
-template <typename FunctionObject, typename Arg1, typename Arg2>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new StoredFunctorCall2<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2>(functionObject, arg1, arg2))->start(pool);
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new StoredFunctorCall3<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3>(functionObject, arg1, arg2, arg3))->start(pool);
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new StoredFunctorCall4<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4>(functionObject, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new StoredFunctorCall5<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4, Arg5>(functionObject, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename FunctionObject>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject *functionObject)
-{
- return (new typename SelectStoredFunctorPointerCall0<typename FunctionObject::result_type, FunctionObject>::type(functionObject))->start(pool);
-}
-template <typename FunctionObject, typename Arg1>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject *functionObject, const Arg1 &arg1)
-{
- return (new typename SelectStoredFunctorPointerCall1<typename FunctionObject::result_type, FunctionObject, Arg1>::type(functionObject, arg1))->start(pool);
-}
-template <typename FunctionObject, typename Arg1, typename Arg2>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject *functionObject, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredFunctorPointerCall2<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2>::type(functionObject, arg1, arg2))->start(pool);
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject *functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredFunctorPointerCall3<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3>::type(functionObject, arg1, arg2, arg3))->start(pool);
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject *functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredFunctorPointerCall4<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4>::type(functionObject, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename FunctionObject, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-QFuture<typename FunctionObject::result_type> run(QThreadPool *pool, FunctionObject *functionObject, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredFunctorPointerCall5<typename FunctionObject::result_type, FunctionObject, Arg1, Arg2, Arg3, Arg4, Arg5>::type(functionObject, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename T, typename Class>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)())
-{
- return (new typename SelectStoredMemberFunctionCall0<T, Class>::type(fn, object))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1), const Arg1 &arg1)
-{
- return (new typename SelectStoredMemberFunctionCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2), const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename T, typename Class>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)() const)
-{
- return (new typename SelectStoredConstMemberFunctionCall0<T, Class>::type(fn, object))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1) const, const Arg1 &arg1)
-{
- return (new typename SelectStoredConstMemberFunctionCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2) const, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredConstMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredConstMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredConstMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredConstMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
+#define QTCONCURRENT_RUN_NODISCARD \
+ Q_NODISCARD_X("Use QThreadPool::start(Callable&&) if you don't need the returned QFuture")
-template <typename T, typename Class>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)())
+template <class Function, class ...Args>
+QTCONCURRENT_RUN_NODISCARD
+auto run(QThreadPool *pool, Function &&f, Args &&...args)
{
- return (new typename SelectStoredMemberFunctionPointerCall0<T, Class>::type(fn, object))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1), const Arg1 &arg1)
-{
- return (new typename SelectStoredMemberFunctionPointerCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1, Param2), const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1, Param2, Param3), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5), const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start(pool);
+ DecayedTuple<Function, Args...> tuple { std::forward<Function>(f),
+ std::forward<Args>(args)... };
+ return TaskResolver<std::decay_t<Function>, std::decay_t<Args>...>::run(
+ std::move(tuple), TaskStartParameters { pool });
}
-template <typename T, typename Class>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)() const)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall0<T, Class>::type(fn, object))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1) const, const Arg1 &arg1)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1, Param2) const, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1, Param2, Param3) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
+template <class Function, class ...Args>
+QTCONCURRENT_RUN_NODISCARD
+auto run(QThreadPool *pool, std::reference_wrapper<const Function> &&functionWrapper,
+ Args &&...args)
{
- return (new typename SelectStoredConstMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredConstMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start(pool);
+ return run(pool, std::forward<const Function>(functionWrapper.get()),
+ std::forward<Args>(args)...);
}
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T>
-QFuture<T> run(T (*functionPointer)() noexcept)
-{
- return (new StoredFunctorCall0<T, T (*)() noexcept>(functionPointer))->start();
-}
-template <typename T, typename Param1, typename Arg1>
-QFuture<T> run(T (*functionPointer)(Param1) noexcept, const Arg1 &arg1)
-{
- return (new StoredFunctorCall1<T, T (*)(Param1) noexcept, Arg1>(functionPointer, arg1))->start();
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(T (*functionPointer)(Param1, Param2) noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new StoredFunctorCall2<T, T (*)(Param1, Param2) noexcept, Arg1, Arg2>(functionPointer, arg1, arg2))->start();
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
+template <class Function, class ...Args>
+QTCONCURRENT_RUN_NODISCARD
+auto run(Function &&f, Args &&...args)
{
- return (new StoredFunctorCall3<T, T (*)(Param1, Param2, Param3) noexcept, Arg1, Arg2, Arg3>(functionPointer, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3, Param4) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new StoredFunctorCall4<T, T (*)(Param1, Param2, Param3, Param4) noexcept, Arg1, Arg2, Arg3, Arg4>(functionPointer, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(T (*functionPointer)(Param1, Param2, Param3, Param4, Param5) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new StoredFunctorCall5<T, T (*)(Param1, Param2, Param3, Param4, Param5) noexcept, Arg1, Arg2, Arg3, Arg4, Arg5>(functionPointer, arg1, arg2, arg3, arg4, arg5))->start();
+ return run(QThreadPool::globalInstance(), std::forward<Function>(f),
+ std::forward<Args>(args)...);
}
-template <typename T, typename Class>
-QFuture<T> run(const Class &object, T (Class::*fn)() noexcept)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall0<T, Class>::type(fn, object))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1) noexcept, const Arg1 &arg1)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2) noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
+// overload with a Promise Type hint, takes thread pool
+template <class PromiseType, class Function, class ...Args>
+QTCONCURRENT_RUN_NODISCARD
+auto run(QThreadPool *pool, Function &&f, Args &&...args)
{
- return (new typename SelectStoredNoExceptMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start();
+ return (new StoredFunctionCallWithPromise<Function, PromiseType, Args...>(
+ std::forward<Function>(f), std::forward<Args>(args)...))->start(pool);
}
-template <typename T, typename Class>
-QFuture<T> run(const Class &object, T (Class::*fn)() const noexcept)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall0<T, Class>::type(fn, object))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1) const noexcept, const Arg1 &arg1)
+// overload with a Promise Type hint, uses global thread pool
+template <class PromiseType, class Function, class ...Args>
+QTCONCURRENT_RUN_NODISCARD
+auto run(Function &&f, Args &&...args)
{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2) const noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start();
+ return run<PromiseType>(QThreadPool::globalInstance(), std::forward<Function>(f),
+ std::forward<Args>(args)...);
}
-template <typename T, typename Class>
-QFuture<T> run(Class *object, T (Class::*fn)() noexcept)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall0<T, Class>::type(fn, object))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1) noexcept, const Arg1 &arg1)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1, Param2) noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1, Param2, Param3) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start();
-}
-
-template <typename T, typename Class>
-QFuture<T> run(const Class *object, T (Class::*fn)() const noexcept)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall0<T, Class>::type(fn, object))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1) const noexcept, const Arg1 &arg1)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1, Param2) const noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1, Param2, Param3) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start();
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(const Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start();
-}
-template <typename T>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)() noexcept)
-{
- return (new StoredFunctorCall0<T, T (*)() noexcept>(functionPointer))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1) noexcept, const Arg1 &arg1)
-{
- return (new StoredFunctorCall1<T, T (*)(Param1) noexcept, Arg1>(functionPointer, arg1))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1, Param2) noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new StoredFunctorCall2<T, T (*)(Param1, Param2) noexcept, Arg1, Arg2>(functionPointer, arg1, arg2))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1, Param2, Param3) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new StoredFunctorCall3<T, T (*)(Param1, Param2, Param3) noexcept, Arg1, Arg2, Arg3>(functionPointer, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1, Param2, Param3, Param4) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new StoredFunctorCall4<T, T (*)(Param1, Param2, Param3, Param4) noexcept, Arg1, Arg2, Arg3, Arg4>(functionPointer, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, T (*functionPointer)(Param1, Param2, Param3, Param4, Param5) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new StoredFunctorCall5<T, T (*)(Param1, Param2, Param3, Param4, Param5) noexcept, Arg1, Arg2, Arg3, Arg4, Arg5>(functionPointer, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename T, typename Class>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)() noexcept)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall0<T, Class>::type(fn, object))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1) noexcept, const Arg1 &arg1)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2) noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredNoExceptMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename T, typename Class>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)() const noexcept)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall0<T, Class>::type(fn, object))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1) const noexcept, const Arg1 &arg1)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2) const noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, const Class &object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename T, typename Class>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)() noexcept)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall0<T, Class>::type(fn, object))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1) noexcept, const Arg1 &arg1)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1, Param2) noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1, Param2, Param3) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredNoExceptMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-
-template <typename T, typename Class>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)() const noexcept)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall0<T, Class>::type(fn, object))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1) const noexcept, const Arg1 &arg1)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall1<T, Class, Param1, Arg1>::type(fn, object, arg1))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1, Param2) const noexcept, const Arg1 &arg1, const Arg2 &arg2)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2>::type(fn, object, arg1, arg2))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1, Param2, Param3) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>::type(fn, object, arg1, arg2, arg3))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>::type(fn, object, arg1, arg2, arg3, arg4))->start(pool);
-}
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-QFuture<T> run(QThreadPool *pool, const Class *object, T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const noexcept, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
-{
- return (new typename SelectStoredConstNoExceptMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>::type(fn, object, arg1, arg2, arg3, arg4, arg5))->start(pool);
-}
-#endif
+#undef QTCONCURRENT_RUN_NODISCARD
} //namespace QtConcurrent
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
QT_END_NAMESPACE
diff --git a/src/concurrent/qtconcurrentrunbase.h b/src/concurrent/qtconcurrentrunbase.h
index aaa1245856..d687cc4c9e 100644
--- a/src/concurrent/qtconcurrentrunbase.h
+++ b/src/concurrent/qtconcurrentrunbase.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_RUNBASE_H
#define QTCONCURRENT_RUNBASE_H
@@ -48,6 +12,9 @@
#include <QtCore/qrunnable.h>
#include <QtCore/qthreadpool.h>
+#include <type_traits>
+#include <utility>
+
QT_BEGIN_NAMESPACE
@@ -69,80 +36,65 @@ struct SelectSpecialization<void>
struct Type { typedef Void type; };
};
+struct TaskStartParameters
+{
+ QThreadPool *threadPool = QThreadPool::globalInstance();
+ int priority = 0;
+};
+
template <typename T>
-class RunFunctionTaskBase : public QFutureInterface<T> , public QRunnable
+class RunFunctionTaskBase : public QRunnable
{
public:
QFuture<T> start()
{
- return start(QThreadPool::globalInstance());
+ return start(TaskStartParameters());
}
- QFuture<T> start(QThreadPool *pool)
+ QFuture<T> start(const TaskStartParameters &parameters)
{
- this->setThreadPool(pool);
- this->setRunnable(this);
- this->reportStarted();
- QFuture<T> theFuture = this->future();
- pool->start(this, /*m_priority*/ 0);
+ promise.setThreadPool(parameters.threadPool);
+ promise.setRunnable(this);
+ promise.reportStarted();
+ QFuture<T> theFuture = promise.future();
+
+ if (parameters.threadPool) {
+ parameters.threadPool->start(this, parameters.priority);
+ } else {
+ promise.reportCanceled();
+ promise.reportFinished();
+ delete this;
+ }
return theFuture;
}
- void run() override {}
- virtual void runFunctor() = 0;
-};
+ // For backward compatibility
+ QFuture<T> start(QThreadPool *pool) { return start({pool, 0}); }
-template <typename T>
-class RunFunctionTask : public RunFunctionTaskBase<T>
-{
-public:
void run() override
{
- if (this->isCanceled()) {
- this->reportFinished();
+ if (promise.isCanceled()) {
+ promise.reportFinished();
return;
}
#ifndef QT_NO_EXCEPTIONS
try {
#endif
- this->runFunctor();
+ runFunctor();
#ifndef QT_NO_EXCEPTIONS
} catch (QException &e) {
- QFutureInterface<T>::reportException(e);
+ promise.reportException(e);
} catch (...) {
- QFutureInterface<T>::reportException(QUnhandledException());
+ promise.reportException(QUnhandledException(std::current_exception()));
}
#endif
-
- this->reportResult(result);
- this->reportFinished();
+ promise.reportFinished();
}
- T result;
-};
-template <>
-class RunFunctionTask<void> : public RunFunctionTaskBase<void>
-{
-public:
- void run() override
- {
- if (this->isCanceled()) {
- this->reportFinished();
- return;
- }
-#ifndef QT_NO_EXCEPTIONS
- try {
-#endif
- this->runFunctor();
-#ifndef QT_NO_EXCEPTIONS
- } catch (QException &e) {
- QFutureInterface<void>::reportException(e);
- } catch (...) {
- QFutureInterface<void>::reportException(QUnhandledException());
- }
-#endif
- this->reportFinished();
- }
+protected:
+ virtual void runFunctor() = 0;
+
+ QFutureInterface<T> promise;
};
} //namespace QtConcurrent
diff --git a/src/concurrent/qtconcurrentstoredfunctioncall.h b/src/concurrent/qtconcurrentstoredfunctioncall.h
index 209832e5bb..e9c66a63ff 100644
--- a/src/concurrent/qtconcurrentstoredfunctioncall.h
+++ b/src/concurrent/qtconcurrentstoredfunctioncall.h
@@ -1,43 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Generated code, do not edit! Use generator at tools/qtconcurrent/generaterun/
#ifndef QTCONCURRENT_STOREDFUNCTIONCALL_H
#define QTCONCURRENT_STOREDFUNCTIONCALL_H
@@ -45,2211 +8,217 @@
#ifndef QT_NO_CONCURRENT
#include <QtConcurrent/qtconcurrentrunbase.h>
+#include <QtCore/qpromise.h>
-QT_BEGIN_NAMESPACE
+#include <type_traits>
+QT_BEGIN_NAMESPACE
#ifndef Q_QDOC
namespace QtConcurrent {
-template <typename T, typename FunctionPointer>
-struct StoredFunctorCall0: public RunFunctionTask<T>
-{
- inline StoredFunctorCall0(FunctionPointer _function)
- : function(_function) {}
- void runFunctor() override { this->result = function(); }
- FunctionPointer function;
-
-};
-
-template <typename FunctionPointer>
-struct StoredFunctorCall0<void, FunctionPointer>: public RunFunctionTask<void>
-{
- inline StoredFunctorCall0(FunctionPointer _function)
- : function(_function) {}
- void runFunctor() override { function(); }
- FunctionPointer function;
-
-};
-
-template <typename T, typename FunctionPointer>
-struct StoredFunctorPointerCall0: public RunFunctionTask<T>
-{
- inline StoredFunctorPointerCall0(FunctionPointer * _function)
- : function(_function) {}
- void runFunctor() override { this->result =(*function)(); }
- FunctionPointer * function;
-
-};
-
-template <typename T, typename FunctionPointer>
-struct VoidStoredFunctorPointerCall0: public RunFunctionTask<T>
-{
- inline VoidStoredFunctorPointerCall0(FunctionPointer * _function)
- : function(_function) {}
- void runFunctor() override { (*function)(); }
- FunctionPointer * function;
-
-};
-
-template <typename T, typename FunctionPointer>
-struct SelectStoredFunctorPointerCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredFunctorPointerCall0 <T, FunctionPointer>,
- VoidStoredFunctorPointerCall0<T, FunctionPointer> >::type type;
-};
-template <typename T, typename Class>
-class StoredMemberFunctionCall0 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionCall0(T (Class::*_fn)(), const Class &_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)();
- }
-private:
- T (Class::*fn)();
- Class object;
-
-};
-template <typename T, typename Class>
-class VoidStoredMemberFunctionCall0 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionCall0(T (Class::*_fn)(), const Class &_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- (object.*fn)();
- }
-private:
- T (Class::*fn)();
- Class object;
-
-};
-template <typename T, typename Class>
-struct SelectStoredMemberFunctionCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionCall0 <T, Class>,
- VoidStoredMemberFunctionCall0<T, Class> >::type type;
-};
-template <typename T, typename Class>
-class StoredConstMemberFunctionCall0 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionCall0(T (Class::*_fn)() const, const Class &_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)();
- }
-private:
- T (Class::*fn)() const;
- const Class object;
-
-};
-template <typename T, typename Class>
-class VoidStoredConstMemberFunctionCall0 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionCall0(T (Class::*_fn)() const, const Class &_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- (object.*fn)();
- }
-private:
- T (Class::*fn)() const;
- const Class object;
-
-};
-template <typename T, typename Class>
-struct SelectStoredConstMemberFunctionCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionCall0 <T, Class>,
- VoidStoredConstMemberFunctionCall0<T, Class> >::type type;
-};
-template <typename T, typename Class>
-class StoredMemberFunctionPointerCall0 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionPointerCall0(T (Class::*_fn)(), Class *_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)();
- }
-private:
- T (Class::*fn)();
- Class *object;
-
-};
-template <typename T, typename Class>
-class VoidStoredMemberFunctionPointerCall0 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionPointerCall0(T (Class::*_fn)(), Class *_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- (object->*fn)();
- }
-private:
- T (Class::*fn)();
- Class *object;
-
-};
-template <typename T, typename Class>
-struct SelectStoredMemberFunctionPointerCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionPointerCall0 <T, Class>,
- VoidStoredMemberFunctionPointerCall0<T, Class> >::type type;
-};
-template <typename T, typename Class>
-class StoredConstMemberFunctionPointerCall0 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionPointerCall0(T (Class::*_fn)() const, Class const *_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)();
- }
-private:
- T (Class::*fn)() const;
- Class const *object;
-
-};
-template <typename T, typename Class>
-class VoidStoredConstMemberFunctionPointerCall0 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionPointerCall0(T (Class::*_fn)() const, Class const *_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- (object->*fn)();
- }
-private:
- T (Class::*fn)() const;
- Class const *object;
-
-};
-template <typename T, typename Class>
-struct SelectStoredConstMemberFunctionPointerCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionPointerCall0 <T, Class>,
- VoidStoredConstMemberFunctionPointerCall0<T, Class> >::type type;
-};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T, typename Class>
-class StoredNoExceptMemberFunctionCall0 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionCall0(T (Class::*_fn)() noexcept, const Class &_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)();
- }
-private:
- T (Class::*fn)() noexcept;
- Class object;
-
-};
-template <typename T, typename Class>
-class VoidStoredNoExceptMemberFunctionCall0 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionCall0(T (Class::*_fn)() noexcept, const Class &_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- (object.*fn)();
- }
-private:
- T (Class::*fn)() noexcept;
- Class object;
-
-};
-template <typename T, typename Class>
-struct SelectStoredNoExceptMemberFunctionCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionCall0 <T, Class>,
- VoidStoredNoExceptMemberFunctionCall0<T, Class> >::type type;
-};
-template <typename T, typename Class>
-class StoredConstNoExceptMemberFunctionCall0 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionCall0(T (Class::*_fn)() const noexcept, const Class &_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)();
- }
-private:
- T (Class::*fn)() const noexcept;
- const Class object;
-
-};
-template <typename T, typename Class>
-class VoidStoredConstNoExceptMemberFunctionCall0 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionCall0(T (Class::*_fn)() const noexcept, const Class &_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- (object.*fn)();
- }
-private:
- T (Class::*fn)() const noexcept;
- const Class object;
-
-};
-template <typename T, typename Class>
-struct SelectStoredConstNoExceptMemberFunctionCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionCall0 <T, Class>,
- VoidStoredConstNoExceptMemberFunctionCall0<T, Class> >::type type;
-};
-template <typename T, typename Class>
-class StoredNoExceptMemberFunctionPointerCall0 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionPointerCall0(T (Class::*_fn)() noexcept, Class *_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)();
- }
-private:
- T (Class::*fn)() noexcept;
- Class *object;
-
-};
-template <typename T, typename Class>
-class VoidStoredNoExceptMemberFunctionPointerCall0 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionPointerCall0(T (Class::*_fn)() noexcept, Class *_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- (object->*fn)();
- }
-private:
- T (Class::*fn)() noexcept;
- Class *object;
-
-};
-template <typename T, typename Class>
-struct SelectStoredNoExceptMemberFunctionPointerCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionPointerCall0 <T, Class>,
- VoidStoredNoExceptMemberFunctionPointerCall0<T, Class> >::type type;
-};
-template <typename T, typename Class>
-class StoredConstNoExceptMemberFunctionPointerCall0 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionPointerCall0(T (Class::*_fn)() const noexcept, Class const *_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)();
- }
-private:
- T (Class::*fn)() const noexcept;
- Class const *object;
-
-};
-template <typename T, typename Class>
-class VoidStoredConstNoExceptMemberFunctionPointerCall0 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionPointerCall0(T (Class::*_fn)() const noexcept, Class const *_object)
- : fn(_fn), object(_object){ }
-
- void runFunctor() override
- {
- (object->*fn)();
- }
-private:
- T (Class::*fn)() const noexcept;
- Class const *object;
-
-};
-template <typename T, typename Class>
-struct SelectStoredConstNoExceptMemberFunctionPointerCall0
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionPointerCall0 <T, Class>,
- VoidStoredConstNoExceptMemberFunctionPointerCall0<T, Class> >::type type;
-};
-#endif
-
-template <typename T, typename FunctionPointer, typename Arg1>
-struct StoredFunctorCall1: public RunFunctionTask<T>
-{
- inline StoredFunctorCall1(FunctionPointer _function, const Arg1 &_arg1)
- : function(_function), arg1(_arg1) {}
- void runFunctor() override { this->result = function(arg1); }
- FunctionPointer function;
- Arg1 arg1;
-};
-
-template <typename FunctionPointer, typename Arg1>
-struct StoredFunctorCall1<void, FunctionPointer, Arg1>: public RunFunctionTask<void>
-{
- inline StoredFunctorCall1(FunctionPointer _function, const Arg1 &_arg1)
- : function(_function), arg1(_arg1) {}
- void runFunctor() override { function(arg1); }
- FunctionPointer function;
- Arg1 arg1;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1>
-struct StoredFunctorPointerCall1: public RunFunctionTask<T>
-{
- inline StoredFunctorPointerCall1(FunctionPointer * _function, const Arg1 &_arg1)
- : function(_function), arg1(_arg1) {}
- void runFunctor() override { this->result =(*function)(arg1); }
- FunctionPointer * function;
- Arg1 arg1;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1>
-struct VoidStoredFunctorPointerCall1: public RunFunctionTask<T>
-{
- inline VoidStoredFunctorPointerCall1(FunctionPointer * _function, const Arg1 &_arg1)
- : function(_function), arg1(_arg1) {}
- void runFunctor() override { (*function)(arg1); }
- FunctionPointer * function;
- Arg1 arg1;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1>
-struct SelectStoredFunctorPointerCall1
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredFunctorPointerCall1 <T, FunctionPointer, Arg1>,
- VoidStoredFunctorPointerCall1<T, FunctionPointer, Arg1> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class StoredMemberFunctionCall1 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionCall1(T (Class::*_fn)(Param1), const Class &_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1);
- Class object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class VoidStoredMemberFunctionCall1 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionCall1(T (Class::*_fn)(Param1), const Class &_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1);
- Class object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-struct SelectStoredMemberFunctionCall1
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionCall1 <T, Class, Param1, Arg1>,
- VoidStoredMemberFunctionCall1<T, Class, Param1, Arg1> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class StoredConstMemberFunctionCall1 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionCall1(T (Class::*_fn)(Param1) const, const Class &_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1) const;
- const Class object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class VoidStoredConstMemberFunctionCall1 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionCall1(T (Class::*_fn)(Param1) const, const Class &_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1) const;
- const Class object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-struct SelectStoredConstMemberFunctionCall1
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionCall1 <T, Class, Param1, Arg1>,
- VoidStoredConstMemberFunctionCall1<T, Class, Param1, Arg1> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class StoredMemberFunctionPointerCall1 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionPointerCall1(T (Class::*_fn)(Param1), Class *_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1);
- Class *object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class VoidStoredMemberFunctionPointerCall1 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionPointerCall1(T (Class::*_fn)(Param1), Class *_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
+template<typename...>
+struct NonMemberFunctionResolver;
- void runFunctor() override
- {
- (object->*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1);
- Class *object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-struct SelectStoredMemberFunctionPointerCall1
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionPointerCall1 <T, Class, Param1, Arg1>,
- VoidStoredMemberFunctionPointerCall1<T, Class, Param1, Arg1> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class StoredConstMemberFunctionPointerCall1 : public RunFunctionTask<T>
+template <class Function, class PromiseType, class... Args>
+struct NonMemberFunctionResolver<Function, PromiseType, Args...>
{
-public:
- StoredConstMemberFunctionPointerCall1(T (Class::*_fn)(Param1) const, Class const *_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
+ using Type = std::tuple<std::decay_t<Function>, QPromise<PromiseType> &, std::decay_t<Args>...>;
+ static_assert(std::is_invocable_v<std::decay_t<Function>, QPromise<PromiseType> &, std::decay_t<Args>...>,
+ "It's not possible to invoke the function with passed arguments.");
+ static_assert(std::is_void_v<std::invoke_result_t<std::decay_t<Function>, QPromise<PromiseType> &, std::decay_t<Args>...>>,
+ "The function must return void type.");
- void runFunctor() override
+ static constexpr void invoke(std::decay_t<Function> function, QPromise<PromiseType> &promise,
+ std::decay_t<Args>... args)
{
- this->result = (object->*fn)(arg1);
+ std::invoke(function, promise, args...);
}
-private:
- T (Class::*fn)(Param1) const;
- Class const *object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class VoidStoredConstMemberFunctionPointerCall1 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionPointerCall1(T (Class::*_fn)(Param1) const, Class const *_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
-
- void runFunctor() override
+ static Type initData(Function &&f, QPromise<PromiseType> &promise, Args &&...args)
{
- (object->*fn)(arg1);
+ return Type { std::forward<Function>(f), std::ref(promise), std::forward<Args>(args)... };
}
-private:
- T (Class::*fn)(Param1) const;
- Class const *object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-struct SelectStoredConstMemberFunctionPointerCall1
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionPointerCall1 <T, Class, Param1, Arg1>,
- VoidStoredConstMemberFunctionPointerCall1<T, Class, Param1, Arg1> >::type type;
};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T, typename Class, typename Param1, typename Arg1>
-class StoredNoExceptMemberFunctionCall1 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionCall1(T (Class::*_fn)(Param1) noexcept, const Class &_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1) noexcept;
- Class object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class VoidStoredNoExceptMemberFunctionCall1 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionCall1(T (Class::*_fn)(Param1) noexcept, const Class &_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
+template<typename...>
+struct MemberFunctionResolver;
- void runFunctor() override
- {
- (object.*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1) noexcept;
- Class object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-struct SelectStoredNoExceptMemberFunctionCall1
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionCall1 <T, Class, Param1, Arg1>,
- VoidStoredNoExceptMemberFunctionCall1<T, Class, Param1, Arg1> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class StoredConstNoExceptMemberFunctionCall1 : public RunFunctionTask<T>
+template <typename Function, typename PromiseType, typename Arg, typename ... Args>
+struct MemberFunctionResolver<Function, PromiseType, Arg, Args...>
{
-public:
- StoredConstNoExceptMemberFunctionCall1(T (Class::*_fn)(Param1) const noexcept, const Class &_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
+ using Type = std::tuple<std::decay_t<Function>, std::decay_t<Arg>, QPromise<PromiseType> &, std::decay_t<Args>...>;
+ static_assert(std::is_invocable_v<std::decay_t<Function>, std::decay_t<Arg>, QPromise<PromiseType> &, std::decay_t<Args>...>,
+ "It's not possible to invoke the function with passed arguments.");
+ static_assert(std::is_void_v<std::invoke_result_t<std::decay_t<Function>, std::decay_t<Arg>, QPromise<PromiseType> &, std::decay_t<Args>...>>,
+ "The function must return void type.");
- void runFunctor() override
+ static constexpr void invoke(std::decay_t<Function> function, std::decay_t<Arg> object,
+ QPromise<PromiseType> &promise, std::decay_t<Args>... args)
{
- this->result = (object.*fn)(arg1);
+ std::invoke(function, object, promise, args...);
}
-private:
- T (Class::*fn)(Param1) const noexcept;
- const Class object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class VoidStoredConstNoExceptMemberFunctionCall1 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionCall1(T (Class::*_fn)(Param1) const noexcept, const Class &_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
-
- void runFunctor() override
+ static Type initData(Function &&f, QPromise<PromiseType> &promise, Arg &&fa, Args &&...args)
{
- (object.*fn)(arg1);
+ return Type { std::forward<Function>(f), std::forward<Arg>(fa), std::ref(promise), std::forward<Args>(args)... };
}
-private:
- T (Class::*fn)(Param1) const noexcept;
- const Class object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-struct SelectStoredConstNoExceptMemberFunctionCall1
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionCall1 <T, Class, Param1, Arg1>,
- VoidStoredConstNoExceptMemberFunctionCall1<T, Class, Param1, Arg1> >::type type;
};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class StoredNoExceptMemberFunctionPointerCall1 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionPointerCall1(T (Class::*_fn)(Param1) noexcept, Class *_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1) noexcept;
- Class *object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class VoidStoredNoExceptMemberFunctionPointerCall1 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionPointerCall1(T (Class::*_fn)(Param1) noexcept, Class *_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
+template <class IsMember, class Function, class PromiseType, class... Args>
+struct FunctionResolverHelper;
- void runFunctor() override
- {
- (object->*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1) noexcept;
- Class *object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-struct SelectStoredNoExceptMemberFunctionPointerCall1
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionPointerCall1 <T, Class, Param1, Arg1>,
- VoidStoredNoExceptMemberFunctionPointerCall1<T, Class, Param1, Arg1> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class StoredConstNoExceptMemberFunctionPointerCall1 : public RunFunctionTask<T>
+template <class Function, class PromiseType, class... Args>
+struct FunctionResolverHelper<std::false_type, Function, PromiseType, Args...>
+ : public NonMemberFunctionResolver<Function, PromiseType, Args...>
{
-public:
- StoredConstNoExceptMemberFunctionPointerCall1(T (Class::*_fn)(Param1) const noexcept, Class const *_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1) const noexcept;
- Class const *object;
- Arg1 arg1;
};
-template <typename T, typename Class, typename Param1, typename Arg1>
-class VoidStoredConstNoExceptMemberFunctionPointerCall1 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionPointerCall1(T (Class::*_fn)(Param1) const noexcept, Class const *_object, const Arg1 &_arg1)
- : fn(_fn), object(_object), arg1(_arg1){ }
- void runFunctor() override
- {
- (object->*fn)(arg1);
- }
-private:
- T (Class::*fn)(Param1) const noexcept;
- Class const *object;
- Arg1 arg1;
-};
-template <typename T, typename Class, typename Param1, typename Arg1>
-struct SelectStoredConstNoExceptMemberFunctionPointerCall1
+template <class Function, class PromiseType, class... Args>
+struct FunctionResolverHelper<std::true_type, Function, PromiseType, Args...>
+ : public MemberFunctionResolver<Function, PromiseType, Args...>
{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionPointerCall1 <T, Class, Param1, Arg1>,
- VoidStoredConstNoExceptMemberFunctionPointerCall1<T, Class, Param1, Arg1> >::type type;
};
-#endif
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2>
-struct StoredFunctorCall2: public RunFunctionTask<T>
+template <class Function, class PromiseType, class... Args>
+struct FunctionResolver
+ : public FunctionResolverHelper<typename std::is_member_function_pointer<
+ std::decay_t<Function>>::type, Function, PromiseType, Args...>
{
- inline StoredFunctorCall2(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2)
- : function(_function), arg1(_arg1), arg2(_arg2) {}
- void runFunctor() override { this->result = function(arg1, arg2); }
- FunctionPointer function;
- Arg1 arg1; Arg2 arg2;
};
-template <typename FunctionPointer, typename Arg1, typename Arg2>
-struct StoredFunctorCall2<void, FunctionPointer, Arg1, Arg2>: public RunFunctionTask<void>
+template <class Function, class ...Args>
+struct InvokeResult
{
- inline StoredFunctorCall2(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2)
- : function(_function), arg1(_arg1), arg2(_arg2) {}
- void runFunctor() override { function(arg1, arg2); }
- FunctionPointer function;
- Arg1 arg1; Arg2 arg2;
-};
+ static_assert(std::is_invocable_v<std::decay_t<Function>, std::decay_t<Args>...>,
+ "It's not possible to invoke the function with passed arguments.");
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2>
-struct StoredFunctorPointerCall2: public RunFunctionTask<T>
-{
- inline StoredFunctorPointerCall2(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2)
- : function(_function), arg1(_arg1), arg2(_arg2) {}
- void runFunctor() override { this->result =(*function)(arg1, arg2); }
- FunctionPointer * function;
- Arg1 arg1; Arg2 arg2;
+ using Type = std::invoke_result_t<std::decay_t<Function>, std::decay_t<Args>...>;
};
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2>
-struct VoidStoredFunctorPointerCall2: public RunFunctionTask<T>
-{
- inline VoidStoredFunctorPointerCall2(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2)
- : function(_function), arg1(_arg1), arg2(_arg2) {}
- void runFunctor() override { (*function)(arg1, arg2); }
- FunctionPointer * function;
- Arg1 arg1; Arg2 arg2;
-};
+template <class Function, class ...Args>
+using InvokeResultType = typename InvokeResult<Function, Args...>::Type;
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2>
-struct SelectStoredFunctorPointerCall2
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredFunctorPointerCall2 <T, FunctionPointer, Arg1, Arg2>,
- VoidStoredFunctorPointerCall2<T, FunctionPointer, Arg1, Arg2> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class StoredMemberFunctionCall2 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionCall2(T (Class::*_fn)(Param1, Param2), const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+template <class ...Types>
+using DecayedTuple = std::tuple<std::decay_t<Types>...>;
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2);
- Class object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class VoidStoredMemberFunctionCall2 : public RunFunctionTask<T>
+template <class Function, class ...Args>
+struct StoredFunctionCall : public RunFunctionTaskBase<InvokeResultType<Function, Args...>>
{
-public:
- VoidStoredMemberFunctionCall2(T (Class::*_fn)(Param1, Param2), const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+ StoredFunctionCall(DecayedTuple<Function, Args...> &&_data)
+ : data(std::move(_data))
+ {}
+protected:
void runFunctor() override
{
- (object.*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2);
- Class object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-struct SelectStoredMemberFunctionCall2
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionCall2 <T, Class, Param1, Arg1, Param2, Arg2>,
- VoidStoredMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class StoredConstMemberFunctionCall2 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionCall2(T (Class::*_fn)(Param1, Param2) const, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+ constexpr auto invoke = [] (std::decay_t<Function> function,
+ std::decay_t<Args>... args) -> auto {
+ return std::invoke(function, args...);
+ };
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2) const;
- const Class object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class VoidStoredConstMemberFunctionCall2 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionCall2(T (Class::*_fn)(Param1, Param2) const, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+ if constexpr (std::is_void_v<InvokeResultType<Function, Args...>>) {
+ std::apply(invoke, std::move(data));
+ } else {
+ auto result = std::apply(invoke, std::move(data));
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2);
+ using T = InvokeResultType<Function, Args...>;
+ if constexpr (std::is_move_constructible_v<T>)
+ this->promise.reportAndMoveResult(std::move(result));
+ else if constexpr (std::is_copy_constructible_v<T>)
+ this->promise.reportResult(result);
+ }
}
-private:
- T (Class::*fn)(Param1, Param2) const;
- const Class object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-struct SelectStoredConstMemberFunctionCall2
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionCall2 <T, Class, Param1, Arg1, Param2, Arg2>,
- VoidStoredConstMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class StoredMemberFunctionPointerCall2 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionPointerCall2(T (Class::*_fn)(Param1, Param2), Class *_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2);
- }
private:
- T (Class::*fn)(Param1, Param2);
- Class *object;
- Arg1 arg1; Arg2 arg2;
+ DecayedTuple<Function, Args...> data;
};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class VoidStoredMemberFunctionPointerCall2 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionPointerCall2(T (Class::*_fn)(Param1, Param2), Class *_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2);
- Class *object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-struct SelectStoredMemberFunctionPointerCall2
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionPointerCall2 <T, Class, Param1, Arg1, Param2, Arg2>,
- VoidStoredMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class StoredConstMemberFunctionPointerCall2 : public RunFunctionTask<T>
+template <class Function, class PromiseType, class ...Args>
+struct StoredFunctionCallWithPromise : public RunFunctionTaskBase<PromiseType>
{
-public:
- StoredConstMemberFunctionPointerCall2(T (Class::*_fn)(Param1, Param2) const, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+ using Resolver = FunctionResolver<Function, PromiseType, Args...>;
+ using DataType = typename Resolver::Type;
+ StoredFunctionCallWithPromise(Function &&f, Args &&...args)
+ : prom(this->promise),
+ data(std::move(Resolver::initData(std::forward<Function>(f), std::ref(prom),
+ std::forward<Args>(args)...)))
+ {}
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2) const;
- Class const *object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class VoidStoredConstMemberFunctionPointerCall2 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionPointerCall2(T (Class::*_fn)(Param1, Param2) const, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+ StoredFunctionCallWithPromise(DecayedTuple<Function, Args...> &&_data)
+ : StoredFunctionCallWithPromise(std::move(_data),
+ std::index_sequence_for<std::decay_t<Function>, std::decay_t<Args>...>())
+ {}
+protected:
void runFunctor() override
{
- (object->*fn)(arg1, arg2);
+ std::apply(Resolver::invoke, std::move(data));
}
-private:
- T (Class::*fn)(Param1, Param2) const;
- Class const *object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-struct SelectStoredConstMemberFunctionPointerCall2
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionPointerCall2 <T, Class, Param1, Arg1, Param2, Arg2>,
- VoidStoredConstMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2> >::type type;
-};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class StoredNoExceptMemberFunctionCall2 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionCall2(T (Class::*_fn)(Param1, Param2) noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2);
- }
private:
- T (Class::*fn)(Param1, Param2) noexcept;
- Class object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class VoidStoredNoExceptMemberFunctionCall2 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionCall2(T (Class::*_fn)(Param1, Param2) noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+ // helper to pack back the tuple into parameter pack
+ template<std::size_t... Is>
+ StoredFunctionCallWithPromise(DecayedTuple<Function, Args...> &&_data,
+ std::index_sequence<Is...>)
+ : StoredFunctionCallWithPromise(std::move(std::get<Is>(_data))...)
+ {}
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2) noexcept;
- Class object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-struct SelectStoredNoExceptMemberFunctionCall2
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionCall2 <T, Class, Param1, Arg1, Param2, Arg2>,
- VoidStoredNoExceptMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2> >::type type;
+ QPromise<PromiseType> prom;
+ DataType data;
};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class StoredConstNoExceptMemberFunctionCall2 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionCall2(T (Class::*_fn)(Param1, Param2) const noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2) const noexcept;
- const Class object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class VoidStoredConstNoExceptMemberFunctionCall2 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionCall2(T (Class::*_fn)(Param1, Param2) const noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+template<typename...>
+struct NonPromiseTaskResolver;
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2) const noexcept;
- const Class object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-struct SelectStoredConstNoExceptMemberFunctionCall2
+template <typename Function, typename ... Args>
+struct NonPromiseTaskResolver<Function, Args...>
{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionCall2 <T, Class, Param1, Arg1, Param2, Arg2>,
- VoidStoredConstNoExceptMemberFunctionCall2<T, Class, Param1, Arg1, Param2, Arg2> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class StoredNoExceptMemberFunctionPointerCall2 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionPointerCall2(T (Class::*_fn)(Param1, Param2) noexcept, Class *_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2);
+ using TaskWithArgs = DecayedTuple<Function, Args...>;
+ static auto run(TaskWithArgs &&args, const TaskStartParameters &startParameters) {
+ return (new StoredFunctionCall<Function, Args...>(std::move(args)))
+ ->start(startParameters);
}
-private:
- T (Class::*fn)(Param1, Param2) noexcept;
- Class *object;
- Arg1 arg1; Arg2 arg2;
};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class VoidStoredNoExceptMemberFunctionPointerCall2 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionPointerCall2(T (Class::*_fn)(Param1, Param2) noexcept, Class *_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2) noexcept;
- Class *object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-struct SelectStoredNoExceptMemberFunctionPointerCall2
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionPointerCall2 <T, Class, Param1, Arg1, Param2, Arg2>,
- VoidStoredNoExceptMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class StoredConstNoExceptMemberFunctionPointerCall2 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionPointerCall2(T (Class::*_fn)(Param1, Param2) const noexcept, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
+template<typename...>
+struct PromiseTaskResolver;
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2);
- }
-private:
- T (Class::*fn)(Param1, Param2) const noexcept;
- Class const *object;
- Arg1 arg1; Arg2 arg2;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-class VoidStoredConstNoExceptMemberFunctionPointerCall2 : public RunFunctionTask<T>
+template <typename Function, typename ... Args>
+struct PromiseTaskResolver<Function, Args...>
{
-public:
- VoidStoredConstNoExceptMemberFunctionPointerCall2(T (Class::*_fn)(Param1, Param2) const noexcept, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2);
+ static_assert(QtPrivate::ArgResolver<Function>::IsPromise::value,
+ "The first argument of passed callable object isn't a QPromise<T> & type. "
+ "Did you intend to pass a callable which takes a QPromise<T> & type as a first argument? "
+ "Otherwise it's not possible to invoke the function with passed arguments.");
+ using TaskWithArgs = DecayedTuple<Function, Args...>;
+ static auto run(TaskWithArgs &&args, const TaskStartParameters &startParameters) {
+ using PromiseType = typename QtPrivate::ArgResolver<Function>::PromiseType;
+ return (new StoredFunctionCallWithPromise<Function, PromiseType, Args...>(std::move(args)))
+ ->start(startParameters);
}
-private:
- T (Class::*fn)(Param1, Param2) const noexcept;
- Class const *object;
- Arg1 arg1; Arg2 arg2;
};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2>
-struct SelectStoredConstNoExceptMemberFunctionPointerCall2
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionPointerCall2 <T, Class, Param1, Arg1, Param2, Arg2>,
- VoidStoredConstNoExceptMemberFunctionPointerCall2<T, Class, Param1, Arg1, Param2, Arg2> >::type type;
-};
-#endif
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3>
-struct StoredFunctorCall3: public RunFunctionTask<T>
-{
- inline StoredFunctorCall3(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3) {}
- void runFunctor() override { this->result = function(arg1, arg2, arg3); }
- FunctionPointer function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
+template <class IsDirectlyInvocable, class Function, class... Args>
+struct TaskResolverHelper;
-template <typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3>
-struct StoredFunctorCall3<void, FunctionPointer, Arg1, Arg2, Arg3>: public RunFunctionTask<void>
+template <class Function, class... Args>
+struct TaskResolverHelper<std::true_type, Function, Args...>
+ : public NonPromiseTaskResolver<Function, Args...>
{
- inline StoredFunctorCall3(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3) {}
- void runFunctor() override { function(arg1, arg2, arg3); }
- FunctionPointer function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
};
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3>
-struct StoredFunctorPointerCall3: public RunFunctionTask<T>
+template <class Function, class... Args>
+struct TaskResolverHelper<std::false_type, Function, Args...>
+ : public PromiseTaskResolver<Function, Args...>
{
- inline StoredFunctorPointerCall3(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3) {}
- void runFunctor() override { this->result =(*function)(arg1, arg2, arg3); }
- FunctionPointer * function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
};
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3>
-struct VoidStoredFunctorPointerCall3: public RunFunctionTask<T>
+template <class Function, class... Args>
+struct TaskResolver : public TaskResolverHelper<typename std::is_invocable<std::decay_t<Function>,
+ std::decay_t<Args>...>::type, Function, Args...>
{
- inline VoidStoredFunctorPointerCall3(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3) {}
- void runFunctor() override { (*function)(arg1, arg2, arg3); }
- FunctionPointer * function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
};
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3>
-struct SelectStoredFunctorPointerCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredFunctorPointerCall3 <T, FunctionPointer, Arg1, Arg2, Arg3>,
- VoidStoredFunctorPointerCall3<T, FunctionPointer, Arg1, Arg2, Arg3> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class StoredMemberFunctionCall3 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionCall3(T (Class::*_fn)(Param1, Param2, Param3), const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3);
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class VoidStoredMemberFunctionCall3 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionCall3(T (Class::*_fn)(Param1, Param2, Param3), const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3);
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-struct SelectStoredMemberFunctionCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionCall3 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>,
- VoidStoredMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class StoredConstMemberFunctionCall3 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionCall3(T (Class::*_fn)(Param1, Param2, Param3) const, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) const;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class VoidStoredConstMemberFunctionCall3 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionCall3(T (Class::*_fn)(Param1, Param2, Param3) const, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) const;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-struct SelectStoredConstMemberFunctionCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionCall3 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>,
- VoidStoredConstMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class StoredMemberFunctionPointerCall3 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionPointerCall3(T (Class::*_fn)(Param1, Param2, Param3), Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3);
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class VoidStoredMemberFunctionPointerCall3 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionPointerCall3(T (Class::*_fn)(Param1, Param2, Param3), Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3);
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-struct SelectStoredMemberFunctionPointerCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionPointerCall3 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>,
- VoidStoredMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class StoredConstMemberFunctionPointerCall3 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionPointerCall3(T (Class::*_fn)(Param1, Param2, Param3) const, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) const;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class VoidStoredConstMemberFunctionPointerCall3 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionPointerCall3(T (Class::*_fn)(Param1, Param2, Param3) const, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) const;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-struct SelectStoredConstMemberFunctionPointerCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionPointerCall3 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>,
- VoidStoredConstMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3> >::type type;
-};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class StoredNoExceptMemberFunctionCall3 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionCall3(T (Class::*_fn)(Param1, Param2, Param3) noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) noexcept;
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class VoidStoredNoExceptMemberFunctionCall3 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionCall3(T (Class::*_fn)(Param1, Param2, Param3) noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) noexcept;
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-struct SelectStoredNoExceptMemberFunctionCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionCall3 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>,
- VoidStoredNoExceptMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class StoredConstNoExceptMemberFunctionCall3 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionCall3(T (Class::*_fn)(Param1, Param2, Param3) const noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) const noexcept;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class VoidStoredConstNoExceptMemberFunctionCall3 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionCall3(T (Class::*_fn)(Param1, Param2, Param3) const noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) const noexcept;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-struct SelectStoredConstNoExceptMemberFunctionCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionCall3 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>,
- VoidStoredConstNoExceptMemberFunctionCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class StoredNoExceptMemberFunctionPointerCall3 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionPointerCall3(T (Class::*_fn)(Param1, Param2, Param3) noexcept, Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) noexcept;
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class VoidStoredNoExceptMemberFunctionPointerCall3 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionPointerCall3(T (Class::*_fn)(Param1, Param2, Param3) noexcept, Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) noexcept;
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-struct SelectStoredNoExceptMemberFunctionPointerCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionPointerCall3 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>,
- VoidStoredNoExceptMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class StoredConstNoExceptMemberFunctionPointerCall3 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionPointerCall3(T (Class::*_fn)(Param1, Param2, Param3) const noexcept, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) const noexcept;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-class VoidStoredConstNoExceptMemberFunctionPointerCall3 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionPointerCall3(T (Class::*_fn)(Param1, Param2, Param3) const noexcept, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3) const noexcept;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3>
-struct SelectStoredConstNoExceptMemberFunctionPointerCall3
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionPointerCall3 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3>,
- VoidStoredConstNoExceptMemberFunctionPointerCall3<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3> >::type type;
-};
-#endif
-
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-struct StoredFunctorCall4: public RunFunctionTask<T>
-{
- inline StoredFunctorCall4(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4) {}
- void runFunctor() override { this->result = function(arg1, arg2, arg3, arg4); }
- FunctionPointer function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-
-template <typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-struct StoredFunctorCall4<void, FunctionPointer, Arg1, Arg2, Arg3, Arg4>: public RunFunctionTask<void>
-{
- inline StoredFunctorCall4(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4) {}
- void runFunctor() override { function(arg1, arg2, arg3, arg4); }
- FunctionPointer function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-struct StoredFunctorPointerCall4: public RunFunctionTask<T>
-{
- inline StoredFunctorPointerCall4(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4) {}
- void runFunctor() override { this->result =(*function)(arg1, arg2, arg3, arg4); }
- FunctionPointer * function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-struct VoidStoredFunctorPointerCall4: public RunFunctionTask<T>
-{
- inline VoidStoredFunctorPointerCall4(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4) {}
- void runFunctor() override { (*function)(arg1, arg2, arg3, arg4); }
- FunctionPointer * function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-struct SelectStoredFunctorPointerCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredFunctorPointerCall4 <T, FunctionPointer, Arg1, Arg2, Arg3, Arg4>,
- VoidStoredFunctorPointerCall4<T, FunctionPointer, Arg1, Arg2, Arg3, Arg4> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class StoredMemberFunctionCall4 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4), const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4);
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class VoidStoredMemberFunctionCall4 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4), const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4);
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-struct SelectStoredMemberFunctionCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionCall4 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>,
- VoidStoredMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class StoredConstMemberFunctionCall4 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) const, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) const;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class VoidStoredConstMemberFunctionCall4 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) const, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) const;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-struct SelectStoredConstMemberFunctionCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionCall4 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>,
- VoidStoredConstMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class StoredMemberFunctionPointerCall4 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionPointerCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4), Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4);
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class VoidStoredMemberFunctionPointerCall4 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionPointerCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4), Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4);
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-struct SelectStoredMemberFunctionPointerCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionPointerCall4 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>,
- VoidStoredMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class StoredConstMemberFunctionPointerCall4 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionPointerCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) const, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) const;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class VoidStoredConstMemberFunctionPointerCall4 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionPointerCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) const, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) const;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-struct SelectStoredConstMemberFunctionPointerCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionPointerCall4 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>,
- VoidStoredConstMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4> >::type type;
-};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class StoredNoExceptMemberFunctionCall4 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) noexcept;
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class VoidStoredNoExceptMemberFunctionCall4 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) noexcept;
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-struct SelectStoredNoExceptMemberFunctionCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionCall4 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>,
- VoidStoredNoExceptMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class StoredConstNoExceptMemberFunctionCall4 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) const noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) const noexcept;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class VoidStoredConstNoExceptMemberFunctionCall4 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) const noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) const noexcept;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-struct SelectStoredConstNoExceptMemberFunctionCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionCall4 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>,
- VoidStoredConstNoExceptMemberFunctionCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class StoredNoExceptMemberFunctionPointerCall4 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionPointerCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) noexcept, Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) noexcept;
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class VoidStoredNoExceptMemberFunctionPointerCall4 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionPointerCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) noexcept, Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) noexcept;
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-struct SelectStoredNoExceptMemberFunctionPointerCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionPointerCall4 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>,
- VoidStoredNoExceptMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class StoredConstNoExceptMemberFunctionPointerCall4 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionPointerCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) const noexcept, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) const noexcept;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-class VoidStoredConstNoExceptMemberFunctionPointerCall4 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionPointerCall4(T (Class::*_fn)(Param1, Param2, Param3, Param4) const noexcept, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3, arg4);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4) const noexcept;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4>
-struct SelectStoredConstNoExceptMemberFunctionPointerCall4
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionPointerCall4 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4>,
- VoidStoredConstNoExceptMemberFunctionPointerCall4<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4> >::type type;
-};
-#endif
-
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-struct StoredFunctorCall5: public RunFunctionTask<T>
-{
- inline StoredFunctorCall5(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5) {}
- void runFunctor() override { this->result = function(arg1, arg2, arg3, arg4, arg5); }
- FunctionPointer function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-
-template <typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-struct StoredFunctorCall5<void, FunctionPointer, Arg1, Arg2, Arg3, Arg4, Arg5>: public RunFunctionTask<void>
-{
- inline StoredFunctorCall5(FunctionPointer _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5) {}
- void runFunctor() override { function(arg1, arg2, arg3, arg4, arg5); }
- FunctionPointer function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-struct StoredFunctorPointerCall5: public RunFunctionTask<T>
-{
- inline StoredFunctorPointerCall5(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5) {}
- void runFunctor() override { this->result =(*function)(arg1, arg2, arg3, arg4, arg5); }
- FunctionPointer * function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-struct VoidStoredFunctorPointerCall5: public RunFunctionTask<T>
-{
- inline VoidStoredFunctorPointerCall5(FunctionPointer * _function, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : function(_function), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5) {}
- void runFunctor() override { (*function)(arg1, arg2, arg3, arg4, arg5); }
- FunctionPointer * function;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-
-template <typename T, typename FunctionPointer, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-struct SelectStoredFunctorPointerCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredFunctorPointerCall5 <T, FunctionPointer, Arg1, Arg2, Arg3, Arg4, Arg5>,
- VoidStoredFunctorPointerCall5<T, FunctionPointer, Arg1, Arg2, Arg3, Arg4, Arg5> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class StoredMemberFunctionCall5 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5), const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5);
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class VoidStoredMemberFunctionCall5 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5), const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5);
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-struct SelectStoredMemberFunctionCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>,
- VoidStoredMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class StoredConstMemberFunctionCall5 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) const, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class VoidStoredConstMemberFunctionCall5 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) const, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-struct SelectStoredConstMemberFunctionCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>,
- VoidStoredConstMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class StoredMemberFunctionPointerCall5 : public RunFunctionTask<T>
-{
-public:
- StoredMemberFunctionPointerCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5), Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5);
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class VoidStoredMemberFunctionPointerCall5 : public RunFunctionTask<T>
-{
-public:
- VoidStoredMemberFunctionPointerCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5), Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5);
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-struct SelectStoredMemberFunctionPointerCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredMemberFunctionPointerCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>,
- VoidStoredMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class StoredConstMemberFunctionPointerCall5 : public RunFunctionTask<T>
-{
-public:
- StoredConstMemberFunctionPointerCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) const, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class VoidStoredConstMemberFunctionPointerCall5 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstMemberFunctionPointerCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) const, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-struct SelectStoredConstMemberFunctionPointerCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstMemberFunctionPointerCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>,
- VoidStoredConstMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type;
-};
-#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class StoredNoExceptMemberFunctionCall5 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) noexcept;
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class VoidStoredNoExceptMemberFunctionCall5 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) noexcept;
- Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-struct SelectStoredNoExceptMemberFunctionCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>,
- VoidStoredNoExceptMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class StoredConstNoExceptMemberFunctionCall5 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) const noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- this->result = (object.*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const noexcept;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class VoidStoredConstNoExceptMemberFunctionCall5 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) const noexcept, const Class &_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- (object.*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const noexcept;
- const Class object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-struct SelectStoredConstNoExceptMemberFunctionCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>,
- VoidStoredConstNoExceptMemberFunctionCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class StoredNoExceptMemberFunctionPointerCall5 : public RunFunctionTask<T>
-{
-public:
- StoredNoExceptMemberFunctionPointerCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) noexcept, Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) noexcept;
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class VoidStoredNoExceptMemberFunctionPointerCall5 : public RunFunctionTask<T>
-{
-public:
- VoidStoredNoExceptMemberFunctionPointerCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) noexcept, Class *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) noexcept;
- Class *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-struct SelectStoredNoExceptMemberFunctionPointerCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredNoExceptMemberFunctionPointerCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>,
- VoidStoredNoExceptMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class StoredConstNoExceptMemberFunctionPointerCall5 : public RunFunctionTask<T>
-{
-public:
- StoredConstNoExceptMemberFunctionPointerCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) const noexcept, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- this->result = (object->*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const noexcept;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-class VoidStoredConstNoExceptMemberFunctionPointerCall5 : public RunFunctionTask<T>
-{
-public:
- VoidStoredConstNoExceptMemberFunctionPointerCall5(T (Class::*_fn)(Param1, Param2, Param3, Param4, Param5) const noexcept, Class const *_object, const Arg1 &_arg1, const Arg2 &_arg2, const Arg3 &_arg3, const Arg4 &_arg4, const Arg5 &_arg5)
- : fn(_fn), object(_object), arg1(_arg1), arg2(_arg2), arg3(_arg3), arg4(_arg4), arg5(_arg5){ }
-
- void runFunctor() override
- {
- (object->*fn)(arg1, arg2, arg3, arg4, arg5);
- }
-private:
- T (Class::*fn)(Param1, Param2, Param3, Param4, Param5) const noexcept;
- Class const *object;
- Arg1 arg1; Arg2 arg2; Arg3 arg3; Arg4 arg4; Arg5 arg5;
-};
-template <typename T, typename Class, typename Param1, typename Arg1, typename Param2, typename Arg2, typename Param3, typename Arg3, typename Param4, typename Arg4, typename Param5, typename Arg5>
-struct SelectStoredConstNoExceptMemberFunctionPointerCall5
-{
- typedef typename SelectSpecialization<T>::template
- Type<StoredConstNoExceptMemberFunctionPointerCall5 <T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5>,
- VoidStoredConstNoExceptMemberFunctionPointerCall5<T, Class, Param1, Arg1, Param2, Arg2, Param3, Arg3, Param4, Arg4, Param5, Arg5> >::type type;
-};
-#endif
-
-template <typename T, typename Functor>
-class StoredFunctorCall : public RunFunctionTask<T>
-{
-public:
- StoredFunctorCall(const Functor &f) : functor(f) { }
- void runFunctor() override
- {
- this->result = functor();
- }
-private:
- Functor functor;
-};
-template <typename Functor>
-class StoredFunctorCall<void, Functor> : public RunFunctionTask<void>
-{
-public:
- StoredFunctorCall(const Functor &f) : functor(f) { }
- void runFunctor() override
- {
- functor();
- }
-private:
- Functor functor;
-};
-
-
} //namespace QtConcurrent
#endif // Q_QDOC
diff --git a/src/concurrent/qtconcurrenttask.h b/src/concurrent/qtconcurrenttask.h
new file mode 100644
index 0000000000..40a47918d7
--- /dev/null
+++ b/src/concurrent/qtconcurrenttask.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTCONCURRENTTASK_H
+#define QTCONCURRENTTASK_H
+
+#if !defined(QT_NO_CONCURRENT)
+
+#include <QtConcurrent/qtaskbuilder.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_QDOC
+
+namespace QtConcurrent {
+
+template <class Task>
+[[nodiscard]]
+QTaskBuilder<Task> task(Task &&task);
+
+} // namespace QtConcurrent
+
+#else
+
+namespace QtConcurrent {
+
+template <class Task>
+[[nodiscard]]
+constexpr auto task(Task &&t) { return QTaskBuilder(std::forward<Task>(t)); }
+
+} // namespace QtConcurrent
+
+#endif // Q_QDOC
+
+QT_END_NAMESPACE
+
+#endif // !defined(QT_NO_CONCURRENT)
+
+#endif // QTCONCURRENTTASK_H
diff --git a/src/concurrent/qtconcurrenttask.qdoc b/src/concurrent/qtconcurrenttask.qdoc
new file mode 100644
index 0000000000..d3828b59c2
--- /dev/null
+++ b/src/concurrent/qtconcurrenttask.qdoc
@@ -0,0 +1,146 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page qtconcurrenttask.html
+ \title Concurrent Task
+ \brief A configurable way to run a task in a separate thread.
+ \ingroup thread
+
+ QtConcurrent::task provides an alternative interface for running a
+ task in a separate thread. The return value of the function is made
+ available through the QFuture API.
+
+ If you want to just run a function in a separate thread without adjusting
+ any parameters, use QtConcurrent::run as that lets you write less code.
+ The QtConcurrent::task is designed for cases where you need to perform
+ extra configurations steps.
+
+ This function is a part of the \l {Qt Concurrent} framework.
+
+ \section1 Fluent interface
+
+ The QtConcurrent::task returns an instance of an auxiliary class called
+ QtConcurrent::QTaskBuilder. Normally, you don't need to create an instance
+ of this class manually. The QtConcurrent::QTaskBuilder provides an interface
+ to adjust different task parameters in a chain-like manner. This approach
+ is known as a
+ \l {https://en.wikipedia.org/wiki/Fluent_interface}{fluent interface}.
+
+ You can just set the parameters you need and then kick a task off.
+ In order to finalize the configuration of a task you must invoke
+ QtConcurrent::QTaskBuilder::spawn. This function is non-blocking (i.e.
+ returns a future object immediately), but it's not guaranteed that the
+ task starts immediately. You can use the QFuture and QFutureWatcher classes
+ to monitor the status of the task.
+
+ See more examples and explanations below.
+
+ \section1 Running a task in a separate thread
+
+ To run a function in another thread, use QtConcurrent::QTaskBuilder::spawn:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 0
+
+ This will run a lambda function in a separate thread obtained from
+ the default QThreadPool.
+
+ \section1 Passing arguments to the task
+
+ Invoking a function with arguments is done by passing them to
+ QtConcurrent::QTaskBuilder::withArguments:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 1
+
+ A copy of each argument is made at the point where
+ QtConcurrent::QTaskBuilder::withArguments is called, and these values
+ are passed to the thread when it begins executing the task. Changes made
+ to the arguments after calling QtConcurrent::QTaskBuilder::withArguments
+ are not visible to the thread.
+
+ If you want to run a function that accepts arguments by reference, you
+ should use \l {https://en.cppreference.com/w/cpp/utility/functional/ref}
+ {std::ref/cref} auxiliary functions. These functions create thin wrappers
+ around passed arguments:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 2
+
+ Make sure that all wrapped objects live long enough. It is possible to
+ get undefined behavior if a task outlives the object wrapped by
+ std::ref/cref.
+
+ \section1 Returning values from the task
+
+ You can obtain the result of a task with the QFuture API:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 3
+
+ Note that QFuture::result() is a blocking call, it waits for the
+ result to become available. Use QFutureWatcher to get a notification
+ when the task has finished execution and the result is available.
+
+ In case you want to pass a result to another asynchronous task, you can
+ use QFuture::then() to create a chain of dependent tasks. See the QFuture
+ documentation for more details.
+
+ \section1 Additional API features
+
+ \section2 Using different types of callable objects
+
+ Strictly speaking, you can use any type of tasks and arguments that
+ satisfy the following condition:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 4
+
+ You can use a free function:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 5
+
+ You can use a member function:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 6
+
+ You can use a callable object with an operator():
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 7
+
+ If you want to use an existing callable object, you need to either
+ copy/move it to QtConcurrent::task or wrap it with std::ref/cref:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 8
+
+ \section2 Using custom thread pool
+
+ You can specify a custom thread pool:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 9
+
+ \section2 Setting priority for a task
+
+ You can set the priority for a task:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 10
+
+ If you don't need a future object, you can call
+ QtConcurrent::QTaskBuilder::spawn(QtConcurrent::FutureResult::Ignore):
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 11
+
+ You can access the promise object associated with the task by defining an
+ additional argument of \c {QPromise<T> &} type inside the function.
+ This additional argument must be the first argument passed to the function, and
+ like in \l {Concurrent Run With Promise} mode, the function is expected to return void type.
+ Result reporting is done through QPromise API:
+
+ \snippet code/src_concurrent_qtconcurrenttask.cpp 12
+*/
+
+/*!
+ \fn template <typename Task> [[nodiscard]] QTaskBuilder<Task> QtConcurrent::task(Task &&task);
+ \since 6.0
+
+ Creates an instance of QtConcurrent::QTaskBuilder. This object can be used
+ to adjust some parameters and run \a task in a separate thread.
+
+ \sa {Concurrent Task}, QtConcurrent::QTaskBuilder
+*/
diff --git a/src/concurrent/qtconcurrentthreadengine.cpp b/src/concurrent/qtconcurrentthreadengine.cpp
index 7f91a2ba68..ce02d0c2c9 100644
--- a/src/concurrent/qtconcurrentthreadengine.cpp
+++ b/src/concurrent/qtconcurrentthreadengine.cpp
@@ -1,45 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtconcurrentthreadengine.h"
-#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
QT_BEGIN_NAMESPACE
@@ -99,6 +63,7 @@ void ThreadEngineBarrier::acquire()
if (count.testAndSetOrdered(localCount, localCount + 1))
return;
}
+ qYieldCpu();
}
}
@@ -118,6 +83,7 @@ int ThreadEngineBarrier::release()
if (count.testAndSetOrdered(localCount, localCount - 1))
return localCount - 1;
}
+ qYieldCpu();
}
}
@@ -134,6 +100,7 @@ void ThreadEngineBarrier::wait()
semaphore.acquire();
return;
}
+ qYieldCpu();
}
}
@@ -157,11 +124,12 @@ bool ThreadEngineBarrier::releaseUnlessLast()
if (count.testAndSetOrdered(localCount, localCount - 1))
return true;
}
+ qYieldCpu();
}
}
-ThreadEngineBase::ThreadEngineBase()
-:futureInterface(0), threadPool(QThreadPool::globalInstance())
+ThreadEngineBase::ThreadEngineBase(QThreadPool *pool)
+ : futureInterface(nullptr), threadPool(pool)
{
setAutoDelete(false);
}
@@ -176,39 +144,6 @@ void ThreadEngineBase::startSingleThreaded()
finish();
}
-void ThreadEngineBase::startBlocking()
-{
- start();
- barrier.acquire();
- startThreads();
-
- bool throttled = false;
-#ifndef QT_NO_EXCEPTIONS
- try {
-#endif
- while (threadFunction() == ThrottleThread) {
- if (threadThrottleExit()) {
- throttled = true;
- break;
- }
- }
-#ifndef QT_NO_EXCEPTIONS
- } catch (QException &e) {
- handleException(e);
- } catch (...) {
- handleException(QUnhandledException());
- }
-#endif
-
- if (throttled == false) {
- barrier.release();
- }
-
- barrier.wait();
- finish();
- exceptionStore.throwPossibleException();
-}
-
void ThreadEngineBase::startThread()
{
startThreadInternal();
@@ -219,6 +154,12 @@ void ThreadEngineBase::acquireBarrierSemaphore()
barrier.acquire();
}
+void ThreadEngineBase::reportIfSuspensionDone() const
+{
+ if (futureInterface && futureInterface->isSuspending())
+ futureInterface->reportSuspended();
+}
+
bool ThreadEngineBase::isCanceled()
{
if (futureInterface)
@@ -236,7 +177,7 @@ void ThreadEngineBase::waitForResume()
bool ThreadEngineBase::isProgressReportingEnabled()
{
// If we don't have a QFuture, there is no-one to report the progress to.
- return (futureInterface != 0);
+ return (futureInterface != nullptr);
}
void ThreadEngineBase::setProgressValue(int progress)
@@ -272,7 +213,7 @@ void ThreadEngineBase::startThreads()
void ThreadEngineBase::threadExit()
{
- const bool asynchronous = futureInterface != 0;
+ const bool asynchronous = (futureInterface != nullptr);
const int lastThread = (barrier.release() == 0);
if (lastThread && asynchronous)
@@ -304,15 +245,22 @@ void ThreadEngineBase::run() // implements QRunnable.
// struct wants to be throttled by making a worker thread exit.
// Respect that request unless this is the only worker thread left
// running, in which case it has to keep going.
- if (threadThrottleExit())
+ if (threadThrottleExit()) {
return;
+ } else {
+ // If the last worker thread is throttled and the state is "suspending",
+ // it means that suspension has been requested, and it is already
+ // in effect (because all previous threads have already exited).
+ // Report the "Suspended" state.
+ reportIfSuspensionDone();
+ }
}
#ifndef QT_NO_EXCEPTIONS
} catch (QException &e) {
handleException(e);
} catch (...) {
- handleException(QUnhandledException());
+ handleException(QUnhandledException(std::current_exception()));
}
#endif
threadExit();
@@ -322,15 +270,18 @@ void ThreadEngineBase::run() // implements QRunnable.
void ThreadEngineBase::handleException(const QException &exception)
{
- if (futureInterface)
+ if (futureInterface) {
futureInterface->reportException(exception);
- else
- exceptionStore.setException(exception);
+ } else {
+ QMutexLocker lock(&mutex);
+ if (!exceptionStore.hasException())
+ exceptionStore.setException(exception);
+ }
}
#endif
-} // namepsace QtConcurrent
+} // namespace QtConcurrent
QT_END_NAMESPACE
diff --git a/src/concurrent/qtconcurrentthreadengine.h b/src/concurrent/qtconcurrentthreadengine.h
index af413707e4..14e1cf375b 100644
--- a/src/concurrent/qtconcurrentthreadengine.h
+++ b/src/concurrent/qtconcurrentthreadengine.h
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtConcurrent module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTCONCURRENT_THREADENGINE_H
#define QTCONCURRENT_THREADENGINE_H
#include <QtConcurrent/qtconcurrent_global.h>
-#if !defined(QT_NO_CONCURRENT) ||defined(Q_CLANG_QDOC)
+#if !defined(QT_NO_CONCURRENT) ||defined(Q_QDOC)
#include <QtCore/qthreadpool.h>
#include <QtCore/qfuture.h>
@@ -88,10 +52,9 @@ class Q_CONCURRENT_EXPORT ThreadEngineBase: public QRunnable
{
public:
// Public API:
- ThreadEngineBase();
+ ThreadEngineBase(QThreadPool *pool);
virtual ~ThreadEngineBase();
void startSingleThreaded();
- void startBlocking();
void startThread();
bool isCanceled();
void waitForResume();
@@ -99,13 +62,19 @@ public:
void setProgressValue(int progress);
void setProgressRange(int minimum, int maximum);
void acquireBarrierSemaphore();
+ void reportIfSuspensionDone() const;
protected: // The user overrides these:
virtual void start() {}
virtual void finish() {}
virtual ThreadFunctionResult threadFunction() { return ThreadFinished; }
- virtual bool shouldStartThread() { return futureInterface ? !futureInterface->isPaused() : true; }
- virtual bool shouldThrottleThread() { return futureInterface ? futureInterface->isPaused() : false; }
+ virtual bool shouldStartThread() { return !shouldThrottleThread(); }
+ virtual bool shouldThrottleThread()
+ {
+ return futureInterface ? (futureInterface->isSuspending() || futureInterface->isSuspended())
+ : false;
+ }
+
private:
bool startThreadInternal();
void startThreads();
@@ -121,15 +90,18 @@ protected:
QThreadPool *threadPool;
ThreadEngineBarrier barrier;
QtPrivate::ExceptionStore exceptionStore;
+ QBasicMutex mutex;
};
template <typename T>
-class ThreadEngine : public virtual ThreadEngineBase
+class ThreadEngine : public ThreadEngineBase
{
public:
typedef T ResultType;
+ ThreadEngine(QThreadPool *pool) : ThreadEngineBase(pool) {}
+
virtual T *result() { return nullptr; }
QFutureInterface<T> *futureInterfaceTyped()
@@ -145,15 +117,6 @@ public:
}
// Runs the user algorithm using multiple threads.
- // This function blocks until the algorithm is finished,
- // and then returns the result.
- T *startBlocking()
- {
- ThreadEngineBase::startBlocking();
- return result();
- }
-
- // Runs the user algorithm using multiple threads.
// Does not block, returns a future.
QFuture<T> startAsynchronously()
{
@@ -186,7 +149,7 @@ public:
futureInterfaceTyped()->reportResult(_result, index);
}
- void reportResults(const QVector<T> &_result, int index = -1, int count = -1)
+ void reportResults(const QList<T> &_result, int index = -1, int count = -1)
{
if (futureInterface)
futureInterfaceTyped()->reportResults(_result, index, count);
@@ -233,13 +196,6 @@ class ThreadEngineStarter : public ThreadEngineStarterBase<T>
public:
ThreadEngineStarter(TypedThreadEngine *eng)
: Base(eng) { }
-
- T startBlocking()
- {
- T t = *this->threadEngine->startBlocking();
- delete this->threadEngine;
- return t;
- }
};
// Full template specialization where T is void.
@@ -247,14 +203,8 @@ template <>
class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
{
public:
- ThreadEngineStarter<void>(ThreadEngine<void> *_threadEngine)
- :ThreadEngineStarterBase<void>(_threadEngine) {}
-
- void startBlocking()
- {
- this->threadEngine->startBlocking();
- delete this->threadEngine;
- }
+ ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
+ : ThreadEngineStarterBase<void>(_threadEngine) {}
};
//! [qtconcurrentthreadengine-1]