diff options
Diffstat (limited to 'src/concurrent')
35 files changed, 588 insertions, 1548 deletions
diff --git a/src/concurrent/CMakeLists.txt b/src/concurrent/CMakeLists.txt index 876ddaf1ba..504f854534 100644 --- a/src/concurrent/CMakeLists.txt +++ b/src/concurrent/CMakeLists.txt @@ -1,4 +1,5 @@ -# Generated from concurrent.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## Concurrent Module: @@ -24,8 +25,10 @@ qt_internal_add_module(Concurrent 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 @@ -34,6 +37,7 @@ qt_internal_add_module(Concurrent Qt::CorePrivate PRECOMPILED_HEADER "../corelib/global/qt_pch.h" + GENERATE_CPP_EXPORTS ) ## Scopes: @@ -46,4 +50,3 @@ qt_internal_extend_target(Concurrent CONDITION MSVC AND (TEST_architecture_arch 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 21c33e4c99..0000000000 --- a/src/concurrent/concurrent.pro +++ /dev/null @@ -1,41 +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 \ - qtconcurrentfilter.h \ - qtconcurrentfilterkernel.h \ - qtconcurrentfunctionwrappers.h \ - qtconcurrentiteratekernel.h \ - qtconcurrentmap.h \ - qtconcurrentmapkernel.h \ - qtconcurrentmedian.h \ - qtconcurrentreducekernel.h \ - qtconcurrentrun.h \ - qtconcurrentrunbase.h \ - qtconcurrentstoredfunctioncall.h \ - qtconcurrentthreadengine.h \ - qtaskbuilder.h \ - qtconcurrenttask.h - -# private headers -HEADERS += \ - -load(qt_module) diff --git a/src/concurrent/doc/qtconcurrent.qdocconf b/src/concurrent/doc/qtconcurrent.qdocconf index 8d740d032d..c4efe64d0a 100644 --- a/src/concurrent/doc/qtconcurrent.qdocconf +++ b/src/concurrent/doc/qtconcurrent.qdocconf @@ -15,19 +15,18 @@ 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 qmake qtcmake +depends += qtcore qtnetwork qtdoc qmake qtcmake headerdirs += .. @@ -35,14 +34,14 @@ sourcedirs += .. exampledirs += ../../../examples/qtconcurrent \ snippets \ - .. \ . -manifestmeta.highlighted.names = "QtConcurrent/Image Scaling Example" - -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 index 35be339f31..03ebb75a2e 100644 --- a/src/concurrent/doc/snippets/CMakeLists.txt +++ b/src/concurrent/doc/snippets/CMakeLists.txt @@ -1,4 +1,7 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #! [cmake_use] -find_package(Qt6 COMPONENTS Concurrent REQUIRED) -target_link_libraries(mytarget Qt6::Concurrent) +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 0e0f414b13..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); @@ -177,9 +132,7 @@ struct StringTransform }; QFuture<QString> fooString = - QtConcurrent::filteredReduced<QString>(strings, - StartsWith(QLatin1String("Foo")), - StringTransform()); + QtConcurrent::filteredReduced(strings, StartsWith(QLatin1String("Foo")), StringTransform()); //! [14] //! [15] @@ -196,7 +149,7 @@ QList<int> results = future.results(); // add up all even integers QList<int> list3 { 1, 2, 3, 4 }; -int sum = QtConcurrent::filteredReduced<int>(list3, +QFuture<int> sum = QtConcurrent::filteredReduced(list3, [](int x) { return (x & 1) == 0; }, @@ -213,7 +166,7 @@ void intSumReduce(int &sum, int x) } QList<int> list { 1, 2, 3, 4 }; -int sum = QtConcurrent::filteredReduced(list, +QFuture<int> sum = QtConcurrent::filteredReduced(list, [] (int x) { return (x & 1) == 0; }, @@ -228,7 +181,7 @@ bool keepEvenIntegers(int x) } QList<int> list { 1, 2, 3, 4 }; -int sum = QtConcurrent::filteredReduced<int>(list, +QFuture<int> sum = QtConcurrent::filteredReduced(list, keepEvenIntegers, [](int &sum, int x) { sum += x; diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp index 659925a1c6..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); @@ -135,7 +88,8 @@ QFuture<QImage> bgrImages = QtConcurrent::mapped(images, // 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] @@ -150,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] @@ -165,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] @@ -223,7 +176,7 @@ QList<QImage> collage = QtConcurrent::mappedReduced(images, //! [16] //! [17] -QList<QImage> collage = QtConcurrent::mappedReduced<QImage>(images, +QList<QImage> collage = QtConcurrent::mappedReduced(images, [&size](const QImage &image) { return image.scaled(size, size); }, diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentrun.cpp index bf39119c51..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(); @@ -230,3 +183,21 @@ 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 index 267d6ebc1e..cb1889afb6 100644 --- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrenttask.cpp +++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrenttask.cpp @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause //! [0] QtConcurrent::task([]{ qDebug("Hello, world!"); }).spawn(); @@ -77,7 +30,7 @@ std::is_invocable_v<std::decay_t<Task>, std::decay_t<Args>...> //! [5] QVariant value(42); -auto result = QtConcurrent::task(&qvariant_cast<int>) +auto result = QtConcurrent::task([](const QVariant &var){return qvariant_cast<int>(var);}) .withArguments(value) .spawn() .result(); // result == 42 diff --git a/src/concurrent/doc/src/qt6-changes.qdoc b/src/concurrent/doc/src/qt6-changes.qdoc index 9614790bac..fa23ee21a7 100644 --- a/src/concurrent/doc/src/qt6-changes.qdoc +++ b/src/concurrent/doc/src/qt6-changes.qdoc @@ -1,35 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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 concurrent-changes-qt6.html \title Changes to Qt Concurrent \ingroup changes-qt-5-to-6 - \brief Migrate Qt Concurrent to Qt 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. @@ -71,6 +47,11 @@ 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 49d7dd478c..5acf19e134 100644 --- a/src/concurrent/doc/src/qtconcurrent-index.qdoc +++ b/src/concurrent/doc/src/qtconcurrent-index.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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 @@ -137,7 +113,7 @@ 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 + 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 @@ -154,6 +130,12 @@ \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. diff --git a/src/concurrent/doc/src/qtconcurrent-module.qdoc b/src/concurrent/doc/src/qtconcurrent-module.qdoc index 31476ba522..ce132c13b7 100644 --- a/src/concurrent/doc/src/qtconcurrent-module.qdoc +++ b/src/concurrent/doc/src/qtconcurrent-module.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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 diff --git a/src/concurrent/qtaskbuilder.h b/src/concurrent/qtaskbuilder.h index 16b21f103b..95ab8021e7 100644 --- a/src/concurrent/qtaskbuilder.h +++ b/src/concurrent/qtaskbuilder.h @@ -1,52 +1,16 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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) 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_CLANG_QDOC) +#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC) #include <QtConcurrent/qtconcurrentstoredfunctioncall.h> QT_BEGIN_NAMESPACE -#ifdef Q_CLANG_QDOC +#ifdef Q_QDOC namespace QtConcurrent { @@ -162,7 +126,7 @@ private: // Data } // namespace QtConcurrent -#endif // Q_CLANG_QDOC +#endif // Q_QDOC QT_END_NAMESPACE diff --git a/src/concurrent/qtaskbuilder.qdoc b/src/concurrent/qtaskbuilder.qdoc index 1340307806..811a48f62b 100644 --- a/src/concurrent/qtaskbuilder.qdoc +++ b/src/concurrent/qtaskbuilder.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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 /*! \class QtConcurrent::QTaskBuilder @@ -75,7 +51,7 @@ */ /*! - \typedef InvokeResultType + \typedef QtConcurrent::InvokeResultType \relates QtConcurrent::QTaskBuilder The simplified definition of this type looks like this: 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 a5456f8d27..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 diff --git a/src/concurrent/qtconcurrentfilter.cpp b/src/concurrent/qtconcurrentfilter.cpp index 2bec2a6eb9..35141d2d7e 100644 --- a/src/concurrent/qtconcurrentfilter.cpp +++ b/src/concurrent/qtconcurrentfilter.cpp @@ -1,45 +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 /*! \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 @@ -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 @@ -148,9 +116,7 @@ \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 @@ -168,9 +134,7 @@ \snippet code/src_concurrent_qtconcurrentfilter.cpp 16 - For the reduce function, lambda expressions are not directly supported. - Lambda expressions can, however, be used when the type of the reduction - result is explicitly specified: + You can also pass a lambda as a reduce object: \snippet code/src_concurrent_qtconcurrentfilter.cpp 17 diff --git a/src/concurrent/qtconcurrentfilter.h b/src/concurrent/qtconcurrentfilter.h index 891eb4b9ca..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> @@ -103,13 +71,14 @@ QFuture<ResultType> filteredReduced(Sequence &&sequence, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce), options); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> filteredReduced(QThreadPool *pool, Sequence &&sequence, @@ -125,13 +94,14 @@ QFuture<ResultType> filteredReduced(QThreadPool *pool, ResultType(std::forward<InitialValueType>(initialValue)), options); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> filteredReduced(Sequence &&sequence, KeepFunctor &&keep, @@ -146,10 +116,10 @@ QFuture<ResultType> filteredReduced(Sequence &&sequence, ResultType(std::forward<InitialValueType>(initialValue)), options); } -#ifndef Q_CLANG_QDOC +#ifndef Q_QDOC template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + 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, @@ -163,8 +133,8 @@ QFuture<ResultType> filteredReduced(QThreadPool *pool, } template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + 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, @@ -177,10 +147,11 @@ QFuture<ResultType> filteredReduced(Sequence &&sequence, } template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + 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, @@ -196,10 +167,11 @@ QFuture<ResultType> filteredReduced(QThreadPool *pool, } template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + 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, @@ -241,13 +213,14 @@ QFuture<ResultType> filteredReduced(Iterator begin, std::forward<ReduceFunctor>(reduce), options); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> filteredReduced(QThreadPool *pool, Iterator begin, @@ -263,13 +236,14 @@ QFuture<ResultType> filteredReduced(QThreadPool *pool, ResultType(std::forward<InitialValueType>(initialValue)), options); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, @@ -285,10 +259,9 @@ QFuture<ResultType> filteredReduced(Iterator begin, ResultType(std::forward<InitialValueType>(initialValue)), options); } -#ifndef Q_CLANG_QDOC +#ifndef Q_QDOC template <typename Iterator, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type> QFuture<ResultType> filteredReduced(QThreadPool *pool, Iterator begin, Iterator end, @@ -302,8 +275,7 @@ QFuture<ResultType> filteredReduced(QThreadPool *pool, } template <typename Iterator, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type> QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor &&keep, @@ -317,10 +289,10 @@ QFuture<ResultType> filteredReduced(Iterator begin, } template <typename Iterator, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> QFuture<ResultType> filteredReduced(QThreadPool *pool, Iterator begin, Iterator end, @@ -336,10 +308,11 @@ QFuture<ResultType> filteredReduced(QThreadPool *pool, } template <typename Iterator, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, + std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0, + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor &&keep, @@ -433,13 +406,14 @@ ResultType blockingFilteredReduced(Sequence &&sequence, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingFilteredReduced(QThreadPool *pool, Sequence &&sequence, @@ -456,13 +430,14 @@ ResultType blockingFilteredReduced(QThreadPool *pool, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingFilteredReduced(Sequence &&sequence, KeepFunctor &&keep, @@ -478,10 +453,10 @@ ResultType blockingFilteredReduced(Sequence &&sequence, return future.takeResult(); } -#ifndef Q_CLANG_QDOC +#ifndef Q_QDOC template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + 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, @@ -496,8 +471,8 @@ ResultType blockingFilteredReduced(QThreadPool *pool, } template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + 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, @@ -511,10 +486,11 @@ ResultType blockingFilteredReduced(Sequence &&sequence, } template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + 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, @@ -531,10 +507,11 @@ ResultType blockingFilteredReduced(QThreadPool *pool, } template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + 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, @@ -580,13 +557,14 @@ ResultType blockingFilteredReduced(Iterator begin, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingFilteredReduced(QThreadPool *pool, Iterator begin, @@ -603,13 +581,14 @@ ResultType blockingFilteredReduced(QThreadPool *pool, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingFilteredReduced(Iterator begin, Iterator end, @@ -625,10 +604,9 @@ ResultType blockingFilteredReduced(Iterator begin, return future.takeResult(); } -#ifndef Q_CLANG_QDOC +#ifndef Q_QDOC template <typename Iterator, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type> ResultType blockingFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, @@ -644,8 +622,7 @@ ResultType blockingFilteredReduced(QThreadPool *pool, } template <typename Iterator, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type> ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor &&keep, @@ -660,10 +637,10 @@ ResultType blockingFilteredReduced(Iterator begin, } template <typename Iterator, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> ResultType blockingFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&keep, @@ -679,10 +656,11 @@ ResultType blockingFilteredReduced(QThreadPool *pool, } template <typename Iterator, typename KeepFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, + std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0, + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor &&keep, diff --git a/src/concurrent/qtconcurrentfilterkernel.h b/src/concurrent/qtconcurrentfilterkernel.h index ede775e9bd..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> @@ -160,21 +124,19 @@ 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: - 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(), keep(std::forward<Keep>(_keep)), + 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) { } @@ -183,8 +145,8 @@ public: FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep, Reduce &&_reduce, ReducedResultType &&initialValue, ReduceOptions reduceOption) - : IterateKernelType(pool, begin, end), - reducedResult(std::forward<ReducedResultType>(initialValue)), + : 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) diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h index 194d020fb2..78900c239b 100644 --- a/src/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/concurrent/qtconcurrentfunctionwrappers.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_FUNCTIONWRAPPERS_H #define QTCONCURRENT_FUNCTIONWRAPPERS_H #include <QtConcurrent/qtconcurrentcompilertest.h> -#include <QtCore/QStringList> +#include <QtConcurrent/qtconcurrentreducekernel.h> +#include <QtCore/qfuture.h> #include <tuple> -#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC) +#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC) QT_BEGIN_NAMESPACE @@ -129,7 +94,6 @@ struct ReduceResultType<R(*)(A...)> using ResultType = typename std::tuple_element<0, std::tuple<A...>>::type; }; -#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 template <class U, class V> struct ReduceResultType<void(*)(U&,V) noexcept> { @@ -141,17 +105,58 @@ struct ReduceResultType<T(C::*)(U) noexcept> { using ResultType = C; }; -#endif + +template<class T, class Enable = void> +inline constexpr bool hasCallOperator_v = false; + +template<class T> +inline constexpr bool hasCallOperator_v<T, std::void_t<decltype(&T::operator())>> = true; + +template<class T, class Enable = void> +inline constexpr bool isIterator_v = false; + +template<class T> +inline constexpr bool isIterator_v<T, std::void_t<typename std::iterator_traits<T>::value_type>> = + true; + +template <class Callable, class Sequence> +using isInvocable = std::is_invocable<Callable, typename std::decay_t<Sequence>::value_type>; + +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<class Callable, class Enable = void> +struct ReduceResultTypeHelper +{ +}; + +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>>>> +{ + using type = typename QtPrivate::ReduceResultType<std::decay_t<Callable>>::ResultType; +}; + +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>>>> +{ + using type = std::decay_t<typename QtPrivate::ArgResolver<Callable>::First>; +}; // -- MapSequenceResultType template <class InputSequence, class MapFunctor> -struct MapSequenceResultType; - -template <class MapFunctor> -struct MapSequenceResultType<QStringList, MapFunctor> +struct MapSequenceResultType { - typedef QList<QtPrivate::MapResultType<QStringList, MapFunctor>> 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; }; #ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS @@ -164,14 +169,6 @@ struct MapSequenceResultType<InputSequence<T...>, MapFunctor> #endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER -template<typename Sequence> -struct SequenceHolder -{ - SequenceHolder(const Sequence &s) : sequence(s) { } - SequenceHolder(Sequence &&s) : sequence(std::move(s)) { } - Sequence sequence; -}; - } // namespace QtPrivate. diff --git a/src/concurrent/qtconcurrentiteratekernel.cpp b/src/concurrent/qtconcurrentiteratekernel.cpp index 430ae89c85..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,7 +7,7 @@ #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 @@ -103,7 +67,7 @@ namespace QtConcurrent { */ BlockSizeManager::BlockSizeManager(QThreadPool *pool, int iterationCount) - : maxBlockSize(iterationCount / (pool->maxThreadCount() * 2)), + : maxBlockSize(iterationCount / (std::max(pool->maxThreadCount(), 1) * 2)), beforeUser(0), afterUser(0), m_blockSize(1) { } @@ -131,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); diff --git a/src/concurrent/qtconcurrentiteratekernel.h b/src/concurrent/qtconcurrentiteratekernel.h index 6caae61816..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> @@ -93,23 +57,22 @@ 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) @@ -122,9 +85,20 @@ public: return vector.data(); } - int currentResultCount; + int currentResultCount = 0; ThreadEngine<T> *threadEngine; 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 <> @@ -137,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 @@ -160,11 +150,41 @@ class IterateKernel : public ThreadEngine<T> public: typedef T ResultType; + 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<T>(pool), begin(_begin), end(_end), current(_begin) - , iterationCount(selectIteration(IteratorCategory()) ? std::distance(_begin, _end) : 0) - , forIteration(selectIteration(IteratorCategory())) - , progressReportingEnabled(true) + : 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)) { } @@ -199,7 +219,7 @@ public: ThreadFunctionResult forThreadFunction() { BlockSizeManager blockSizeManager(ThreadEngineBase::threadPool, iterationCount); - ResultReporter<T> resultReporter(this); + ResultReporter<T> resultReporter = createResultsReporter(); for(;;) { if (this->isCanceled()) @@ -252,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) { @@ -283,6 +303,14 @@ 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; @@ -294,6 +322,7 @@ public: 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 d68dd63bb8..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 @@ -144,6 +108,7 @@ /*! \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 @@ -260,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 @@ -274,9 +242,7 @@ \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 @@ -294,9 +260,7 @@ \snippet code/src_concurrent_qtconcurrentmap.cpp 16 - For the reduce function, lambda expressions are not directly supported. - Lambda expressions can, however, be used when the type of the reduction - result is explicitly specified: + You can also pass a lambda as a reduce object: \snippet code/src_concurrent_qtconcurrentmap.cpp 17 diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h index 4043ecd8a2..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 @@ -108,13 +75,14 @@ QFuture<ResultType> mappedReduced(Sequence &&sequence, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce), options); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> mappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -129,13 +97,14 @@ QFuture<ResultType> mappedReduced(QThreadPool *pool, std::forward<ReduceFunctor>(reduce), ResultType(std::forward<InitialValueType>(initialValue)), options); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> mappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -151,8 +120,8 @@ QFuture<ResultType> mappedReduced(Sequence &&sequence, } template <typename Sequence, typename MapFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + 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, @@ -166,8 +135,8 @@ QFuture<ResultType> mappedReduced(QThreadPool *pool, } template <typename Sequence, typename MapFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + 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, @@ -179,15 +148,15 @@ QFuture<ResultType> mappedReduced(Sequence &&sequence, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce), options); } -#ifdef Q_CLANG_QDOC +#ifdef Q_QDOC template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename ResultType, typename InitialValueType> #else -template <typename Sequence, typename MapFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, - typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> +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, @@ -203,15 +172,15 @@ QFuture<ResultType> mappedReduced(QThreadPool *pool, ResultType(std::forward<InitialValueType>(initialValue)), options); } -#ifdef Q_CLANG_QDOC +#ifdef Q_QDOC template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename ResultType, typename InitialValueType> #else -template <typename Sequence, typename MapFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, - typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> +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, @@ -254,13 +223,14 @@ QFuture<ResultType> mappedReduced(Iterator begin, std::forward<ReduceFunctor>(reduce), options); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> mappedReduced(QThreadPool *pool, Iterator begin, @@ -276,13 +246,14 @@ QFuture<ResultType> mappedReduced(QThreadPool *pool, ResultType(std::forward<InitialValueType>(initialValue)), options); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> mappedReduced(Iterator begin, Iterator end, @@ -299,8 +270,7 @@ QFuture<ResultType> mappedReduced(Iterator begin, } template <typename Iterator, typename MapFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type> QFuture<ResultType> mappedReduced(QThreadPool *pool, Iterator begin, Iterator end, @@ -315,7 +285,7 @@ QFuture<ResultType> mappedReduced(QThreadPool *pool, } template <typename Iterator, typename MapFunctor, typename ReduceFunctor, - typename ResultType = typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type> QFuture<ResultType> mappedReduced(Iterator begin, Iterator end, MapFunctor &&map, @@ -328,15 +298,15 @@ QFuture<ResultType> mappedReduced(Iterator begin, std::forward<ReduceFunctor>(reduce), options); } -#ifdef Q_CLANG_QDOC +#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::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> mappedReduced(QThreadPool *pool, Iterator begin, @@ -352,15 +322,16 @@ QFuture<ResultType> mappedReduced(QThreadPool *pool, ResultType(std::forward<InitialValueType>(initialValue)), options); } -#ifdef Q_CLANG_QDOC +#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::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, + std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0, + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif QFuture<ResultType> mappedReduced(Iterator begin, Iterator end, @@ -482,13 +453,14 @@ ResultType blockingMappedReduced(Sequence &&sequence, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -505,13 +477,14 @@ ResultType blockingMappedReduced(QThreadPool *pool, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingMappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -528,8 +501,8 @@ ResultType blockingMappedReduced(Sequence &&sequence, } template <typename MapFunctor, typename ReduceFunctor, typename Sequence, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + 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, @@ -545,8 +518,8 @@ ResultType blockingMappedReduced(QThreadPool *pool, } template <typename MapFunctor, typename ReduceFunctor, typename Sequence, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + 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, @@ -560,15 +533,15 @@ ResultType blockingMappedReduced(Sequence &&sequence, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#ifdef Q_QDOC template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename ResultType, typename InitialValueType> #else -template <typename MapFunctor, typename ReduceFunctor, typename Sequence, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, - typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> +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, @@ -585,15 +558,15 @@ ResultType blockingMappedReduced(QThreadPool *pool, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#ifdef Q_QDOC template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename ResultType, typename InitialValueType> #else -template<typename MapFunctor, typename ReduceFunctor, typename Sequence, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, - typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> +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, @@ -639,13 +612,14 @@ ResultType blockingMappedReduced(Iterator begin, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Iterator begin, @@ -663,13 +637,14 @@ ResultType blockingMappedReduced(QThreadPool *pool, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingMappedReduced(Iterator begin, Iterator end, @@ -687,8 +662,7 @@ ResultType blockingMappedReduced(Iterator begin, } template <typename Iterator, typename MapFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type> ResultType blockingMappedReduced(QThreadPool *pool, Iterator begin, Iterator end, @@ -704,8 +678,7 @@ ResultType blockingMappedReduced(QThreadPool *pool, } template <typename Iterator, typename MapFunctor, typename ReduceFunctor, - typename ResultType = - typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType> + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type> ResultType blockingMappedReduced(Iterator begin, Iterator end, MapFunctor &&map, @@ -719,15 +692,15 @@ ResultType blockingMappedReduced(Iterator begin, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Iterator begin, @@ -744,15 +717,16 @@ ResultType blockingMappedReduced(QThreadPool *pool, return future.takeResult(); } -#ifdef Q_CLANG_QDOC +#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::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType, + std::enable_if_t<QtPrivate::isIterator_v<Iterator>, int> = 0, + typename ResultType = typename QtPrivate::ReduceResultTypeHelper<ReduceFunctor>::type, typename InitialValueType, - std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0> + std::enable_if_t<QtPrivate::isInitialValueCompatible_v<InitialValueType, ResultType>, + int> = 0> #endif ResultType blockingMappedReduced(Iterator begin, Iterator end, diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h index 2753bc7d0a..61b18e5438 100644 --- a/src/concurrent/qtconcurrentmapkernel.h +++ b/src/concurrent/qtconcurrentmapkernel.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_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> @@ -93,7 +57,7 @@ template <typename ReducedResultType, QtPrivate::MapResultType<Iterator, MapFunctor>>> class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType> { - ReducedResultType reducedResult; + ReducedResultType &reducedResult; MapFunctor map; ReduceFunctor reduce; Reducer reducer; @@ -102,20 +66,22 @@ class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType> public: typedef ReducedResultType ReturnType; - 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(), - map(std::forward<F1>(_map)), reduce(std::forward<F2>(_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), - reducedResult(std::forward<ReducedResultType>(initialValue)), + 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) diff --git a/src/concurrent/qtconcurrentmedian.h b/src/concurrent/qtconcurrentmedian.h index aab80794d9..01cb8b93e0 100644 --- a/src/concurrent/qtconcurrentmedian.h +++ b/src/concurrent/qtconcurrentmedian.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_MEDIAN_H #define QTCONCURRENT_MEDIAN_H #include <QtConcurrent/qtconcurrent_global.h> -#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC) +#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC) #include <algorithm> #include <cstring> diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h index 5ad8bded6c..c337a9192f 100644 --- a/src/concurrent/qtconcurrentreducekernel.h +++ b/src/concurrent/qtconcurrentreducekernel.h @@ -1,49 +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> -#include <QtConcurrent/qtconcurrentfunctionwrappers.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> @@ -56,6 +19,17 @@ 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 @@ -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 @@ -143,7 +117,7 @@ class ReduceKernel public: ReduceKernel(QThreadPool *pool, ReduceOptions _reduceOptions) : reduceOptions(_reduceOptions), progress(0), resultsMapSize(0), - threadCount(pool->maxThreadCount()) + threadCount(std::max(pool->maxThreadCount(), 1)) { } void runReduce(ReduceFunctor &reduce, @@ -213,11 +187,13 @@ 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)); } }; diff --git a/src/concurrent/qtconcurrentrun.cpp b/src/concurrent/qtconcurrentrun.cpp index 978bc8cd8d..017f2df480 100644 --- a/src/concurrent/qtconcurrentrun.cpp +++ b/src/concurrent/qtconcurrentrun.cpp @@ -1,45 +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 /*! \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. @@ -89,12 +54,36 @@ the function. Changes made to the arguments after calling QtConcurrent::run() are \e not visible to the thread. + 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 @@ -147,18 +136,17 @@ \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 - T is the type of the computation result (it should match the type T - of QFuture<T> returned by the QtConcurrent::runWithPromise()), like e.g.: + 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 by himself, nor pass it explicitly - when calling QtConcurrent::runWithPromise(). + 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: @@ -174,6 +162,11 @@ \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: @@ -195,6 +188,10 @@ 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 @@ -227,7 +224,7 @@ */ /*! - \fn QFuture<T> QtConcurrent::run(Function function, ...); + \fn template <typename T> QFuture<T> QtConcurrent::run(Function function, ...); Equivalent to \code @@ -258,17 +255,16 @@ 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} + \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. + 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. \include qtconcurrentrun.cpp run-description */ diff --git a/src/concurrent/qtconcurrentrun.h b/src/concurrent/qtconcurrentrun.h index 4ce8d6ae05..cbc750de84 100644 --- a/src/concurrent/qtconcurrentrun.h +++ b/src/concurrent/qtconcurrentrun.h @@ -1,55 +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 #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; @@ -61,20 +29,17 @@ namespace QtConcurrent { template <typename T> QFuture<T> run(QThreadPool *pool, Function function, ...); - template <typename T> - QFuture<T> runWithPromise(Function function, ...); - - template <typename T> - QFuture<T> runWithPromise(QThreadPool *pool, Function function, ...); - } // namespace QtConcurrent #else namespace QtConcurrent { +#define QTCONCURRENT_RUN_NODISCARD \ + Q_NODISCARD_X("Use QThreadPool::start(Callable&&) if you don't need the returned QFuture") + template <class Function, class ...Args> -[[nodiscard]] +QTCONCURRENT_RUN_NODISCARD auto run(QThreadPool *pool, Function &&f, Args &&...args) { DecayedTuple<Function, Args...> tuple { std::forward<Function>(f), @@ -84,7 +49,7 @@ auto run(QThreadPool *pool, Function &&f, Args &&...args) } template <class Function, class ...Args> -[[nodiscard]] +QTCONCURRENT_RUN_NODISCARD auto run(QThreadPool *pool, std::reference_wrapper<const Function> &&functionWrapper, Args &&...args) { @@ -93,7 +58,7 @@ auto run(QThreadPool *pool, std::reference_wrapper<const Function> &&functionWra } template <class Function, class ...Args> -[[nodiscard]] +QTCONCURRENT_RUN_NODISCARD auto run(Function &&f, Args &&...args) { return run(QThreadPool::globalInstance(), std::forward<Function>(f), @@ -102,7 +67,7 @@ auto run(Function &&f, Args &&...args) // overload with a Promise Type hint, takes thread pool template <class PromiseType, class Function, class ...Args> -[[nodiscard]] +QTCONCURRENT_RUN_NODISCARD auto run(QThreadPool *pool, Function &&f, Args &&...args) { return (new StoredFunctionCallWithPromise<Function, PromiseType, Args...>( @@ -111,16 +76,18 @@ auto run(QThreadPool *pool, Function &&f, Args &&...args) // overload with a Promise Type hint, uses global thread pool template <class PromiseType, class Function, class ...Args> -[[nodiscard]] +QTCONCURRENT_RUN_NODISCARD auto run(Function &&f, Args &&...args) { return run<PromiseType>(QThreadPool::globalInstance(), std::forward<Function>(f), std::forward<Args>(args)...); } +#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 20267a2d5b..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 @@ -93,7 +57,14 @@ public: promise.setRunnable(this); promise.reportStarted(); QFuture<T> theFuture = promise.future(); - parameters.threadPool->start(this, parameters.priority); + + if (parameters.threadPool) { + parameters.threadPool->start(this, parameters.priority); + } else { + promise.reportCanceled(); + promise.reportFinished(); + delete this; + } return theFuture; } @@ -117,37 +88,15 @@ public: promise.reportException(QUnhandledException(std::current_exception())); } #endif - - reportResult(); - promise.reportFinished(); } protected: virtual void runFunctor() = 0; - virtual void reportResult() {} QFutureInterface<T> promise; }; -template <typename T> -class RunFunctionTask : public RunFunctionTaskBase<T> -{ -protected: - void reportResult() override - { - 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); - } - - T result; -}; - -template <> -class RunFunctionTask<void> : public RunFunctionTaskBase<void> {}; - } //namespace QtConcurrent #endif //Q_QDOC diff --git a/src/concurrent/qtconcurrentstoredfunctioncall.h b/src/concurrent/qtconcurrentstoredfunctioncall.h index 98ce28f6dc..e9c66a63ff 100644 --- a/src/concurrent/qtconcurrentstoredfunctioncall.h +++ b/src/concurrent/qtconcurrentstoredfunctioncall.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_STOREDFUNCTIONCALL_H #define QTCONCURRENT_STOREDFUNCTIONCALL_H @@ -138,7 +102,7 @@ template <class ...Types> using DecayedTuple = std::tuple<std::decay_t<Types>...>; template <class Function, class ...Args> -struct StoredFunctionCall : public RunFunctionTask<InvokeResultType<Function, Args...>> +struct StoredFunctionCall : public RunFunctionTaskBase<InvokeResultType<Function, Args...>> { StoredFunctionCall(DecayedTuple<Function, Args...> &&_data) : data(std::move(_data)) @@ -152,10 +116,17 @@ protected: return std::invoke(function, args...); }; - if constexpr (std::is_void_v<InvokeResultType<Function, Args...>>) + if constexpr (std::is_void_v<InvokeResultType<Function, Args...>>) { std::apply(invoke, std::move(data)); - else - this->result = std::apply(invoke, std::move(data)); + } else { + auto result = std::apply(invoke, std::move(data)); + + 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: diff --git a/src/concurrent/qtconcurrenttask.h b/src/concurrent/qtconcurrenttask.h index ff55df7748..40a47918d7 100644 --- a/src/concurrent/qtconcurrenttask.h +++ b/src/concurrent/qtconcurrenttask.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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) 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 @@ -46,7 +10,7 @@ QT_BEGIN_NAMESPACE -#ifdef Q_CLANG_QDOC +#ifdef Q_QDOC namespace QtConcurrent { @@ -66,7 +30,7 @@ constexpr auto task(Task &&t) { return QTaskBuilder(std::forward<Task>(t)); } } // namespace QtConcurrent -#endif // Q_CLANG_QDOC +#endif // Q_QDOC QT_END_NAMESPACE diff --git a/src/concurrent/qtconcurrenttask.qdoc b/src/concurrent/qtconcurrenttask.qdoc index 72951f8f11..d3828b59c2 100644 --- a/src/concurrent/qtconcurrenttask.qdoc +++ b/src/concurrent/qtconcurrenttask.qdoc @@ -1,33 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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 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 diff --git a/src/concurrent/qtconcurrentthreadengine.cpp b/src/concurrent/qtconcurrentthreadengine.cpp index fcc504a96c..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,6 +124,7 @@ bool ThreadEngineBarrier::releaseUnlessLast() if (count.testAndSetOrdered(localCount, localCount - 1)) return true; } + qYieldCpu(); } } @@ -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(std::current_exception())); - } -#endif - - if (throttled == false) { - barrier.release(); - } - - barrier.wait(); - finish(); - exceptionStore.throwPossibleException(); -} - void ThreadEngineBase::startThread() { startThreadInternal(); @@ -346,7 +281,7 @@ void ThreadEngineBase::handleException(const QException &exception) #endif -} // namepsace QtConcurrent +} // namespace QtConcurrent QT_END_NAMESPACE diff --git a/src/concurrent/qtconcurrentthreadengine.h b/src/concurrent/qtconcurrentthreadengine.h index cbd8ad04d7..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> @@ -91,7 +55,6 @@ public: ThreadEngineBase(QThreadPool *pool); virtual ~ThreadEngineBase(); void startSingleThreaded(); - void startBlocking(); void startThread(); bool isCanceled(); void waitForResume(); @@ -154,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() { @@ -242,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. @@ -256,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] |