diff options
-rw-r--r-- | src/corelib/thread/qfuture.h | 1 | ||||
-rw-r--r-- | src/corelib/thread/qfutureinterface.cpp | 5 | ||||
-rw-r--r-- | src/corelib/thread/qfutureinterface.h | 31 | ||||
-rw-r--r-- | src/corelib/thread/qfutureinterface_p.h | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qgridlayout.cpp | 6 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp | 51 |
6 files changed, 79 insertions, 17 deletions
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h index a56e9ee3ff..9aa77ccf2f 100644 --- a/src/corelib/thread/qfuture.h +++ b/src/corelib/thread/qfuture.h @@ -48,7 +48,6 @@ #include <QtCore/qfuture_impl.h> #include <type_traits> -#include <vector> QT_REQUIRE_CONFIG(future); diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 50a1fcd597..76af95e3a3 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -600,6 +600,11 @@ void QFutureInterfaceBase::reset() d->isValid = false; } +void QFutureInterfaceBase::rethrowPossibleException() +{ + exceptionStore().throwPossibleException(); +} + QFutureInterfaceBasePrivate::QFutureInterfaceBasePrivate(QFutureInterfaceBase::State initialState) : state(initialState) { diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h index 2432503cf7..62875c5ef9 100644 --- a/src/corelib/thread/qfutureinterface.h +++ b/src/corelib/thread/qfutureinterface.h @@ -40,17 +40,19 @@ #ifndef QFUTUREINTERFACE_H #define QFUTUREINTERFACE_H -#include <QtCore/qrunnable.h> #include <QtCore/qmutex.h> -#include <QtCore/qexception.h> +#include <QtCore/QMutexLocker> #include <QtCore/qresultstore.h> +#ifndef QT_NO_EXCEPTIONS +#include <exception> +#endif #include <utility> -#include <vector> -#include <mutex> QT_REQUIRE_CONFIG(future); +QT_FORWARD_DECLARE_CLASS(QRunnable) +QT_FORWARD_DECLARE_CLASS(QException) QT_BEGIN_NAMESPACE @@ -64,6 +66,8 @@ namespace QtPrivate { template<typename Function, typename ResultType, typename ParentResultType> class Continuation; +class ExceptionStore; + template<class Function, class ResultType> class CanceledHandler; @@ -169,6 +173,7 @@ protected: bool refT() const; bool derefT() const; void reset(); + void rethrowPossibleException(); public: #ifndef QFUTURE_TEST @@ -262,7 +267,7 @@ public: template <typename T> inline bool QFutureInterface<T>::reportResult(const T *result, int index) { - std::lock_guard<QMutex> locker{mutex()}; + QMutexLocker<QMutex> locker{&mutex()}; if (this->queryState(Canceled) || this->queryState(Finished)) return false; @@ -283,7 +288,7 @@ inline bool QFutureInterface<T>::reportResult(const T *result, int index) template<typename T> bool QFutureInterface<T>::reportAndMoveResult(T &&result, int index) { - std::lock_guard<QMutex> locker{mutex()}; + QMutexLocker<QMutex> locker{&mutex()}; if (queryState(Canceled) || queryState(Finished)) return false; @@ -312,7 +317,7 @@ inline bool QFutureInterface<T>::reportResult(const T &result, int index) template<typename T> inline bool QFutureInterface<T>::reportResults(const QList<T> &_results, int beginIndex, int count) { - std::lock_guard<QMutex> locker{mutex()}; + QMutexLocker<QMutex> locker{&mutex()}; if (this->queryState(Canceled) || this->queryState(Finished)) return false; @@ -343,14 +348,14 @@ inline bool QFutureInterface<T>::reportFinished(const T *result) template <typename T> inline const T &QFutureInterface<T>::resultReference(int index) const { - std::lock_guard<QMutex> locker{mutex()}; + QMutexLocker<QMutex> locker{&mutex()}; return resultStoreBase().resultAt(index).template value<T>(); } template <typename T> inline const T *QFutureInterface<T>::resultPointer(int index) const { - std::lock_guard<QMutex> locker{mutex()}; + QMutexLocker<QMutex> locker{&mutex()}; return resultStoreBase().resultAt(index).template pointer<T>(); } @@ -358,14 +363,14 @@ template <typename T> inline QList<T> QFutureInterface<T>::results() { if (this->isCanceled()) { - exceptionStore().throwPossibleException(); + rethrowPossibleException(); return QList<T>(); } QFutureInterfaceBase::waitForResult(-1); QList<T> res; - std::lock_guard<QMutex> locker{mutex()}; + QMutexLocker<QMutex> locker{&mutex()}; QtPrivate::ResultIteratorBase it = resultStoreBase().begin(); while (it != resultStoreBase().end()) { @@ -385,7 +390,7 @@ T QFutureInterface<T>::takeResult() // not to mess with other unready results. waitForResult(-1); - const std::lock_guard<QMutex> locker{mutex()}; + const QMutexLocker<QMutex> locker{&mutex()}; QtPrivate::ResultIteratorBase position = resultStoreBase().resultAt(0); T ret(std::move_if_noexcept(position.value<T>())); reset(); @@ -404,7 +409,7 @@ std::vector<T> QFutureInterface<T>::takeResults() std::vector<T> res; res.reserve(resultCount()); - const std::lock_guard<QMutex> locker{mutex()}; + const QMutexLocker<QMutex> locker{&mutex()}; QtPrivate::ResultIteratorBase it = resultStoreBase().begin(); for (auto endIt = resultStoreBase().end(); it != endIt; ++it) diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h index 25421b064c..44c3a48d2a 100644 --- a/src/corelib/thread/qfutureinterface_p.h +++ b/src/corelib/thread/qfutureinterface_p.h @@ -58,6 +58,8 @@ #include <QtCore/qwaitcondition.h> #include <QtCore/qrunnable.h> #include <QtCore/qthreadpool.h> +#include <QtCore/qfutureinterface.h> +#include <QtCore/qexception.h> QT_REQUIRE_CONFIG(future); diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp index 121bae0352..336a68cd80 100644 --- a/src/widgets/kernel/qgridlayout.cpp +++ b/src/widgets/kernel/qgridlayout.cpp @@ -149,14 +149,14 @@ public: QRect cellRect(int row, int col) const; inline QLayoutItem *itemAt(int index) const { - if (index < things.count()) + if (index >= 0 && index < things.count()) return things.at(index)->item(); else return nullptr; } inline QLayoutItem *takeAt(int index) { Q_Q(QGridLayout); - if (index < things.count()) { + if (index >= 0 && index < things.count()) { if (QGridBox *b = things.takeAt(index)) { QLayoutItem *item = b->takeItem(); if (QLayout *l = item->layout()) { @@ -184,7 +184,7 @@ public: } void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan) const { - if (index < things.count()) { + if (index >= 0 && index < things.count()) { const QGridBox *b = things.at(index); int toRow = b->toRow(rr); int toCol = b->toCol(cc); diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp index e3bd1d1553..2cf2462fd5 100644 --- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp +++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp @@ -75,6 +75,7 @@ private slots: void taskQTBUG_40609_addingWidgetToItsOwnLayout(); void taskQTBUG_40609_addingLayoutToItself(); void taskQTBUG_52357_spacingWhenItemIsHidden(); + void taskQTBUG_91261_itemIndexRange(); void replaceWidget(); void dontCrashWhenExtendsToEnd(); }; @@ -1666,6 +1667,56 @@ void tst_QGridLayout::taskQTBUG_52357_spacingWhenItemIsHidden() QTRY_COMPARE_WITH_TIMEOUT(tempWidth, button1.width() + button3.width() + layout.spacing(), 1000); } +void tst_QGridLayout::taskQTBUG_91261_itemIndexRange() +{ + QWidget widget; + QGridLayout lay(&widget); + QPushButton *btn = new QPushButton(&widget); + lay.addWidget(btn, 0, 0); + + { + auto ptr = lay.itemAt(-1); + QCOMPARE(ptr, nullptr); + + ptr = lay.itemAt(0); + QCOMPARE(ptr->widget(), btn); + + ptr = lay.itemAt(1); + QCOMPARE(ptr, nullptr); + } + + { + int row = -1; + int column = -1; + int rowSpan; + int columnSpan; + + lay.getItemPosition(-1, &row, &column, &rowSpan, &columnSpan); + QCOMPARE(row, -1); + QCOMPARE(column, -1); + + lay.getItemPosition(1, &row, &column, &rowSpan, &columnSpan); + QCOMPARE(row, -1); + QCOMPARE(column, -1); + + lay.getItemPosition(0, &row, &column, &rowSpan, &columnSpan); + QCOMPARE(row, 0); + QCOMPARE(column, 0); + } + + { + auto ptr = lay.takeAt(-1); + QCOMPARE(ptr, nullptr); + + ptr = lay.takeAt(1); + QCOMPARE(ptr, nullptr); + + ptr = lay.takeAt(0); + QCOMPARE(ptr->widget(), btn); + delete ptr; + } +} + void tst_QGridLayout::replaceWidget() { QWidget wdg; |