summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp16
-rw-r--r--src/corelib/animation/qabstractanimation_p.h2
-rw-r--r--src/corelib/animation/qanimationgroup_p.h2
-rw-r--r--src/corelib/animation/qpropertyanimation_p.h2
-rw-r--r--src/corelib/animation/qsequentialanimationgroup_p.h2
-rw-r--r--src/corelib/codecs/qtextcodec_p.h2
-rw-r--r--src/corelib/configure.json19
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/eval.pri4
-rw-r--r--src/corelib/global/global.pri1
-rw-r--r--src/corelib/global/qfloat16.cpp17
-rw-r--r--src/corelib/global/qfloat16.h14
-rw-r--r--src/corelib/global/qfloat16_p.h95
-rw-r--r--src/corelib/global/qglobalstatic.h4
-rw-r--r--src/corelib/global/qhooks.cpp2
-rw-r--r--src/corelib/global/qlibraryinfo.cpp5
-rw-r--r--src/corelib/global/qnumeric.cpp25
-rw-r--r--src/corelib/global/qnumeric.h4
-rw-r--r--src/corelib/global/qnumeric_p.h19
-rw-r--r--src/corelib/global/qrandom.cpp5
-rw-r--r--src/corelib/global/qtrace_p.h2
-rw-r--r--src/corelib/io/qabstractfileengine_p.h2
-rw-r--r--src/corelib/io/qfileinfo_p.h2
-rw-r--r--src/corelib/io/qfilesystemengine_p.h2
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h4
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp8
-rw-r--r--src/corelib/io/qfsfileengine_p.h2
-rw-r--r--src/corelib/io/qprocess.cpp4
-rw-r--r--src/corelib/io/qprocess_p.h2
-rw-r--r--src/corelib/io/qresource_p.h2
-rw-r--r--src/corelib/io/qurl_p.h2
-rw-r--r--src/corelib/io/qwindowspipereader.cpp4
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp4
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel_p.h2
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel_p.h2
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel_p.h2
-rw-r--r--src/corelib/kernel/kernel.pri2
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp4
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.h4
-rw-r--r--src/corelib/kernel/qabstractnativeeventfilter.cpp1
-rw-r--r--src/corelib/kernel/qabstractnativeeventfilter.h4
-rw-r--r--src/corelib/kernel/qcore_unix_p.h2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp14
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib_p.h6
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h10
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp4
-rw-r--r--src/corelib/kernel/qmetaobject_moc_p.h4
-rw-r--r--src/corelib/kernel/qmetaobject_p.h10
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder_p.h8
-rw-r--r--src/corelib/kernel/qobject.cpp1006
-rw-r--r--src/corelib/kernel/qobject_p.h270
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h2
-rw-r--r--src/corelib/kernel/qtcore_eval.cpp560
-rw-r--r--src/corelib/kernel/qvariant.cpp8
-rw-r--r--src/corelib/kernel/qvariant_p.h10
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp1
-rw-r--r--src/corelib/mimetypes/qmimetypeparser.cpp3
-rw-r--r--src/corelib/plugin/qlibrary_p.h2
-rw-r--r--src/corelib/serialization/qdatastream.cpp1
-rw-r--r--src/corelib/serialization/qdatastream.h5
-rw-r--r--src/corelib/serialization/qjson_p.h4
-rw-r--r--src/corelib/serialization/qtextstream.cpp100
-rw-r--r--src/corelib/serialization/qtextstream.h19
-rw-r--r--src/corelib/serialization/qxmlstream_p.h10
-rw-r--r--src/corelib/statemachine/qstate_p.h8
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h4
-rw-r--r--src/corelib/thread/qatomic_bootstrap.h2
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h62
-rw-r--r--src/corelib/thread/qresultstore.h4
-rw-r--r--src/corelib/thread/qthread_p.h12
-rw-r--r--src/corelib/thread/qthreadpool_p.h2
-rw-r--r--src/corelib/thread/qthreadstorage.h4
-rw-r--r--src/corelib/tools/qbytearray.cpp3
-rw-r--r--src/corelib/tools/qcache.h14
-rw-r--r--src/corelib/tools/qcollator.cpp116
-rw-r--r--src/corelib/tools/qcollator.h6
-rw-r--r--src/corelib/tools/qcollator_icu.cpp41
-rw-r--r--src/corelib/tools/qcollator_macx.cpp46
-rw-r--r--src/corelib/tools/qcollator_posix.cpp14
-rw-r--r--src/corelib/tools/qcollator_win.cpp34
-rw-r--r--src/corelib/tools/qdatetime_p.h2
-rw-r--r--src/corelib/tools/qdatetimeparser_p.h8
-rw-r--r--src/corelib/tools/qfreelist_p.h4
-rw-r--r--src/corelib/tools/qline.cpp2
-rw-r--r--src/corelib/tools/qline.h3
-rw-r--r--src/corelib/tools/qlist.h2
-rw-r--r--src/corelib/tools/qlocale_p.h2
-rw-r--r--src/corelib/tools/qpair.h5
-rw-r--r--src/corelib/tools/qregexp.cpp6
-rw-r--r--src/corelib/tools/qscopedvaluerollback.h14
-rw-r--r--src/corelib/tools/qstring.cpp371
-rw-r--r--src/corelib/tools/qstring.h23
-rw-r--r--src/corelib/tools/qstringalgorithms.h5
-rw-r--r--src/corelib/tools/qstringmatcher.cpp82
-rw-r--r--src/corelib/tools/qstringmatcher.h5
-rw-r--r--src/corelib/tools/qstringview.cpp31
-rw-r--r--src/corelib/tools/qstringview.h2
-rw-r--r--src/corelib/tools/qvector.h12
-rw-r--r--src/corelib/tools/qvector.qdoc11
100 files changed, 1537 insertions, 1789 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 9d7a256191..e37f9a0271 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -152,6 +152,7 @@
#include <QtCore/qthreadstorage.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qscopedvaluerollback.h>
#define DEFAULT_TIMER_INTERVAL 16
#define PAUSE_TIMER_COARSE_THRESHOLD 2000
@@ -315,14 +316,13 @@ void QUnifiedTimer::updateAnimationTimers(qint64 currentTick)
//* it might happen in some cases that the delta is negative because the animation driver
// advances faster than time.elapsed()
if (delta > 0) {
- insideTick = true;
+ QScopedValueRollback<bool> guard(insideTick, true);
if (profilerCallback)
profilerCallback(delta);
for (currentAnimationIdx = 0; currentAnimationIdx < animationTimers.count(); ++currentAnimationIdx) {
QAbstractAnimationTimer *animation = animationTimers.at(currentAnimationIdx);
animation->updateAnimationsTime(delta);
}
- insideTick = false;
currentAnimationIdx = 0;
}
}
@@ -361,10 +361,11 @@ void QUnifiedTimer::localRestart()
void QUnifiedTimer::restart()
{
- insideRestart = true;
- for (int i = 0; i < animationTimers.count(); ++i)
- animationTimers.at(i)->restartAnimationTimer();
- insideRestart = false;
+ {
+ QScopedValueRollback<bool> guard(insideRestart, true);
+ for (int i = 0; i < animationTimers.count(); ++i)
+ animationTimers.at(i)->restartAnimationTimer();
+ }
localRestart();
}
@@ -599,14 +600,13 @@ void QAnimationTimer::updateAnimationsTime(qint64 delta)
//it might happen in some cases that the time doesn't change because events are delayed
//when the CPU load is high
if (delta) {
- insideTick = true;
+ QScopedValueRollback<bool> guard(insideTick, true);
for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
QAbstractAnimation *animation = animations.at(currentAnimationIdx);
int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime
+ (animation->direction() == QAbstractAnimation::Forward ? delta : -delta);
animation->setCurrentTime(elapsed);
}
- insideTick = false;
currentAnimationIdx = 0;
}
}
diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h
index 3b6e8d6cc4..037d3be74f 100644
--- a/src/corelib/animation/qabstractanimation_p.h
+++ b/src/corelib/animation/qabstractanimation_p.h
@@ -78,7 +78,7 @@ public:
hasRegisteredTimer(false),
isPause(false),
isGroup(false),
- group(0)
+ group(nullptr)
{
}
diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h
index ff759d11fd..215734b656 100644
--- a/src/corelib/animation/qanimationgroup_p.h
+++ b/src/corelib/animation/qanimationgroup_p.h
@@ -76,7 +76,7 @@ public:
void disconnectUncontrolledAnimation(QAbstractAnimation *anim)
{
//0 for the signal here because we might be called from the animation destructor
- QObject::disconnect(anim, 0, q_func(), SLOT(_q_uncontrolledAnimationFinished()));
+ QObject::disconnect(anim, nullptr, q_func(), SLOT(_q_uncontrolledAnimationFinished()));
}
void connectUncontrolledAnimation(QAbstractAnimation *anim)
diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h
index 479762f573..cbd3ce287d 100644
--- a/src/corelib/animation/qpropertyanimation_p.h
+++ b/src/corelib/animation/qpropertyanimation_p.h
@@ -64,7 +64,7 @@ class QPropertyAnimationPrivate : public QVariantAnimationPrivate
Q_DECLARE_PUBLIC(QPropertyAnimation)
public:
QPropertyAnimationPrivate()
- : targetValue(0), propertyType(0), propertyIndex(-1)
+ : targetValue(nullptr), propertyType(0), propertyIndex(-1)
{
}
diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h
index 88dac4f566..c082d6b524 100644
--- a/src/corelib/animation/qsequentialanimationgroup_p.h
+++ b/src/corelib/animation/qsequentialanimationgroup_p.h
@@ -63,7 +63,7 @@ class QSequentialAnimationGroupPrivate : public QAnimationGroupPrivate
Q_DECLARE_PUBLIC(QSequentialAnimationGroup)
public:
QSequentialAnimationGroupPrivate()
- : currentAnimation(0), currentAnimationIndex(-1), lastLoop(0)
+ : currentAnimation(nullptr), currentAnimationIndex(-1), lastLoop(0)
{ }
diff --git a/src/corelib/codecs/qtextcodec_p.h b/src/corelib/codecs/qtextcodec_p.h
index 0e449d994c..7fcf6df984 100644
--- a/src/corelib/codecs/qtextcodec_p.h
+++ b/src/corelib/codecs/qtextcodec_p.h
@@ -98,7 +98,7 @@ public:
struct ConverterState {
ConverterState(ConversionFlags f = DefaultConversion)
- : flags(f), remainingChars(0), invalidChars(0), d(0) { state_data[0] = state_data[1] = state_data[2] = 0; }
+ : flags(f), remainingChars(0), invalidChars(0), d(nullptr) { state_data[0] = state_data[1] = state_data[2] = 0; }
~ConverterState() { }
ConversionFlags flags;
int remainingChars;
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index b7eefb58c8..a6091d4825 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -12,7 +12,7 @@
"inotify": "boolean",
"journald": "boolean",
"mimetype-database": "boolean",
- "pcre": { "type": "enum", "values": [ "qt", "system" ] },
+ "pcre": { "type": "enum", "values": [ "no", "qt", "system" ] },
"posix-ipc": { "type": "boolean", "name": "ipc_posix" },
"pps": { "type": "boolean", "name": "qqnx_pps" },
"slog2": "boolean",
@@ -684,15 +684,18 @@
"condition": "features.mimetype",
"output": [ "privateFeature" ]
},
+ "pcre2": {
+ "label": "PCRE2",
+ "disable": "input.pcre == 'no' || input.pcre == 'system'",
+ "enable": "input.pcre == 'qt'",
+ "output": [ "privateConfig" ]
+ },
"system-pcre2": {
- "label": "Using system PCRE2",
- "disable": "input.pcre == 'qt'",
+ "label": " Using system PCRE2",
+ "disable": "input.pcre == 'no' || input.pcre == 'qt'",
"enable": "input.pcre == 'system'",
"condition": "libs.pcre2",
- "output": [
- "privateFeature",
- { "type": "privateConfig", "negative": true, "name": "pcre2" }
- ]
+ "output": [ "privateFeature" ]
},
"poll_ppoll": {
"label": "Native ppoll()",
@@ -771,6 +774,7 @@
"label": "QRegularExpression",
"purpose": "Provides an API to Perl-compatible regular expressions.",
"section": "Kernel",
+ "condition": "features.system-pcre2 || features.pcre2",
"output": [ "publicFeature", "feature" ]
},
"sharedmemory": {
@@ -1071,6 +1075,7 @@ Please apply the patch corresponding to your Standard Library vendor, found in
"args": "qqnx_pps",
"condition": "config.qnx"
},
+ "pcre2",
"system-pcre2"
]
}
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 4b758532e6..dc43e56836 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -68,8 +68,6 @@ integrity {
QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtCore.dynlist
-contains(DEFINES,QT_EVAL):include(eval.pri)
-
HOST_BINS = $$[QT_HOST_BINS]
host_bins.name = host_bins
host_bins.variable = HOST_BINS
diff --git a/src/corelib/eval.pri b/src/corelib/eval.pri
deleted file mode 100644
index efda56b16a..0000000000
--- a/src/corelib/eval.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES += \
- $$QT_SOURCE_TREE/src/corelib/kernel/qtcore_eval.cpp
-INCLUDEPATH += \
- $$QT_BUILD_TREE/src/corelib/global
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index 029357ff43..428c674307 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -12,7 +12,6 @@ HEADERS += \
global/qendian_p.h \
global/qnumeric_p.h \
global/qnumeric.h \
- global/qfloat16_p.h \
global/qfloat16.h \
global/qglobalstatic.h \
global/qlibraryinfo.h \
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp
index fd608efe55..110d7c4d7c 100644
--- a/src/corelib/global/qfloat16.cpp
+++ b/src/corelib/global/qfloat16.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "qfloat16_p.h"
+#include "qfloat16.h"
#include "private/qsimd_p.h"
QT_BEGIN_NAMESPACE
@@ -65,28 +65,31 @@ QT_BEGIN_NAMESPACE
*/
/*!
- Returns true if the \c qfloat16 \a {f} is equivalent to infinity.
+ \fn bool qIsInf(qfloat16 f)
\relates <QFloat16>
+ Returns true if the \c qfloat16 \a {f} is equivalent to infinity.
+
\sa qIsInf
*/
-Q_REQUIRED_RESULT bool qIsInf(qfloat16 f) Q_DECL_NOTHROW { return qt_is_inf(f); }
/*!
- Returns true if the \c qfloat16 \a {f} is not a number (NaN).
+ \fn bool qIsNaN(qfloat16 f)
\relates <QFloat16>
+ Returns true if the \c qfloat16 \a {f} is not a number (NaN).
+
\sa qIsNaN
*/
-Q_REQUIRED_RESULT bool qIsNaN(qfloat16 f) Q_DECL_NOTHROW { return qt_is_nan(f); }
/*!
- Returns true if the \c qfloat16 \a {f} is a finite number.
+ \fn bool qIsFinite(qfloat16 f)
\relates <QFloat16>
+ Returns true if the \c qfloat16 \a {f} is a finite number.
+
\sa qIsFinite
*/
-Q_REQUIRED_RESULT bool qIsFinite(qfloat16 f) Q_DECL_NOTHROW { return qt_is_finite(f); }
/*! \fn int qRound(qfloat16 value)
\relates <QFloat16>
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h
index 42cb1357f1..e823d0298b 100644
--- a/src/corelib/global/qfloat16.h
+++ b/src/corelib/global/qfloat16.h
@@ -67,10 +67,14 @@ QT_BEGIN_NAMESPACE
class qfloat16
{
public:
- Q_DECL_CONSTEXPR inline qfloat16() Q_DECL_NOTHROW : b16(0) { }
+ constexpr inline qfloat16() Q_DECL_NOTHROW : b16(0) {}
inline qfloat16(float f) Q_DECL_NOTHROW;
inline operator float() const Q_DECL_NOTHROW;
+ // Support for qIs{Inf,NaN,Finite}:
+ bool isInf() const Q_DECL_NOTHROW { return ((b16 >> 8) & 0x7e) == 0x7c; }
+ bool isNaN() const Q_DECL_NOTHROW { return ((b16 >> 8) & 0x7e) == 0x7e; }
+ bool isFinite() const Q_DECL_NOTHROW { return ((b16 >> 8) & 0x7c) != 0x7c; }
private:
quint16 b16;
@@ -89,9 +93,11 @@ Q_DECLARE_TYPEINFO(qfloat16, Q_PRIMITIVE_TYPE);
Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *, const float *, qsizetype length) Q_DECL_NOTHROW;
Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length) Q_DECL_NOTHROW;
-Q_REQUIRED_RESULT Q_CORE_EXPORT bool qIsInf(qfloat16 f) Q_DECL_NOTHROW; // complements qnumeric.h
-Q_REQUIRED_RESULT Q_CORE_EXPORT bool qIsNaN(qfloat16 f) Q_DECL_NOTHROW; // complements qnumeric.h
-Q_REQUIRED_RESULT Q_CORE_EXPORT bool qIsFinite(qfloat16 f) Q_DECL_NOTHROW; // complements qnumeric.h
+// Complement qnumeric.h:
+Q_REQUIRED_RESULT inline bool qIsInf(qfloat16 f) Q_DECL_NOTHROW { return f.isInf(); }
+Q_REQUIRED_RESULT inline bool qIsNaN(qfloat16 f) Q_DECL_NOTHROW { return f.isNaN(); }
+Q_REQUIRED_RESULT inline bool qIsFinite(qfloat16 f) Q_DECL_NOTHROW { return f.isFinite(); }
+// Q_REQUIRED_RESULT quint32 qFloatDistance(qfloat16 a, qfloat16 b);
// The remainder of these utility functions complement qglobal.h
Q_REQUIRED_RESULT inline int qRound(qfloat16 d) Q_DECL_NOTHROW
diff --git a/src/corelib/global/qfloat16_p.h b/src/corelib/global/qfloat16_p.h
deleted file mode 100644
index f3fc96e119..0000000000
--- a/src/corelib/global/qfloat16_p.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 by Southwest Research Institute (R)
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFLOAT16_P_H
-#define QFLOAT16_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qfloat16.h>
-#include <QtCore/qsysinfo.h>
-
-QT_BEGIN_NAMESPACE
-
-static inline bool qt_is_inf(qfloat16 d) Q_DECL_NOTHROW
-{
- bool is_inf;
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- is_inf = (ch[0] & 0x7c) == 0x7c && (ch[0] & 0x02) == 0;
- else
- is_inf = (ch[1] & 0x7c) == 0x7c && (ch[1] & 0x02) == 0;
- return is_inf;
-}
-
-static inline bool qt_is_nan(qfloat16 d) Q_DECL_NOTHROW
-{
- bool is_nan;
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- is_nan = (ch[0] & 0x7c) == 0x7c && (ch[0] & 0x02) != 0;
- else
- is_nan = (ch[1] & 0x7c) == 0x7c && (ch[1] & 0x02) != 0;
- return is_nan;
-}
-
-static inline bool qt_is_finite(qfloat16 d) Q_DECL_NOTHROW
-{
- bool is_finite;
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- is_finite = (ch[0] & 0x7c) != 0x7c;
- else
- is_finite = (ch[1] & 0x7c) != 0x7c;
- return is_finite;
-}
-
-
-QT_END_NAMESPACE
-
-#endif // QFLOAT16_P_H
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index 555bdf04c1..93d71cee57 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -131,8 +131,8 @@ struct QGlobalStatic
bool isDestroyed() const { return guard.load() <= QtGlobalStatic::Destroyed; }
bool exists() const { return guard.load() == QtGlobalStatic::Initialized; }
- operator Type *() { if (isDestroyed()) return 0; return innerFunction(); }
- Type *operator()() { if (isDestroyed()) return 0; return innerFunction(); }
+ operator Type *() { if (isDestroyed()) return nullptr; return innerFunction(); }
+ Type *operator()() { if (isDestroyed()) return nullptr; return innerFunction(); }
Type *operator->()
{
Q_ASSERT_X(!isDestroyed(), "Q_GLOBAL_STATIC", "The global static was used after being destroyed");
diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp
index bbddb1cbf1..020dee3710 100644
--- a/src/corelib/global/qhooks.cpp
+++ b/src/corelib/global/qhooks.cpp
@@ -67,7 +67,7 @@ quintptr Q_CORE_EXPORT qtHookData[] = {
// The required sizes and offsets are tested in tests/auto/other/toolsupport.
// When this fails and the change was intentional, adjust the test and
// adjust this value here.
- 16
+ 17
};
Q_STATIC_ASSERT(QHooks::LastHookIndex == sizeof(qtHookData) / sizeof(qtHookData[0]));
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 4119012d85..88cc5b0b01 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -717,11 +717,6 @@ void qt_core_boilerplate()
QT_PREPEND_NAMESPACE(qDumpCPUFeatures)();
-#ifdef QT_EVAL
- extern void qt_core_eval_init(QCoreApplicationPrivate::Type);
- qt_core_eval_init(QCoreApplicationPrivate::Tty);
-#endif
-
exit(0);
}
diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp
index fc2b052edf..e6ba62f530 100644
--- a/src/corelib/global/qnumeric.cpp
+++ b/src/corelib/global/qnumeric.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE
/*!
Returns \c true if the double \a {d} is equivalent to infinity.
\relates <QtGlobal>
+ \sa qInf()
*/
Q_CORE_EXPORT bool qIsInf(double d) { return qt_is_inf(d); }
@@ -64,6 +65,7 @@ Q_CORE_EXPORT bool qIsFinite(double d) { return qt_is_finite(d); }
/*!
Returns \c true if the float \a {f} is equivalent to infinity.
\relates <QtGlobal>
+ \sa qInf()
*/
Q_CORE_EXPORT bool qIsInf(float f) { return qt_is_inf(f); }
@@ -88,15 +90,36 @@ Q_CORE_EXPORT double qSNaN() { return qt_snan(); }
/*!
Returns the bit pattern of a quiet NaN as a double.
\relates <QtGlobal>
+ \sa qIsNaN()
*/
Q_CORE_EXPORT double qQNaN() { return qt_qnan(); }
/*!
Returns the bit pattern for an infinite number as a double.
\relates <QtGlobal>
+ \sa qIsInf()
*/
Q_CORE_EXPORT double qInf() { return qt_inf(); }
+/*!
+ \relates <QtGlobal>
+ Classifies a floating-point value.
+
+ The return values are defined in \c{<cmath>}: returns one of the following,
+ determined by the floating-point class of \a val:
+ \list
+ \li FP_NAN not a number
+ \li FP_INFINITE infinities (positive or negative)
+ \li FP_NORMAL finite with a full mantissa
+ \li FP_SUBNORMAL finite with a reduced mantissa
+ \endlist
+*/
+Q_CORE_EXPORT int qFpClassify(double val) { return qt_fpclassify(val); }
+
+/*!
+ \overload
+*/
+Q_CORE_EXPORT int qFpClassify(float val) { return qt_fpclassify(val); }
/*!
diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h
index 535a96aaec..6a0c64712f 100644
--- a/src/corelib/global/qnumeric.h
+++ b/src/corelib/global/qnumeric.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -48,9 +48,11 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(double d);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(double d);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(double d);
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION int qFpClassify(double val);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(float f);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(float f);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(float f);
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION int qFpClassify(float val);
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qSNaN();
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN();
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf();
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index 4a225b2599..56e670c477 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -85,9 +85,11 @@ namespace qnumeric_std_wrapper {
Q_DECL_CONST_FUNCTION static inline bool math_h_isnan(double d) { using namespace std; return isnan(d); }
Q_DECL_CONST_FUNCTION static inline bool math_h_isinf(double d) { using namespace std; return isinf(d); }
Q_DECL_CONST_FUNCTION static inline bool math_h_isfinite(double d) { using namespace std; return isfinite(d); }
+Q_DECL_CONST_FUNCTION static inline int math_h_fpclassify(double d) { using namespace std; return fpclassify(d); }
Q_DECL_CONST_FUNCTION static inline bool math_h_isnan(float f) { using namespace std; return isnan(f); }
Q_DECL_CONST_FUNCTION static inline bool math_h_isinf(float f) { using namespace std; return isinf(f); }
Q_DECL_CONST_FUNCTION static inline bool math_h_isfinite(float f) { using namespace std; return isfinite(f); }
+Q_DECL_CONST_FUNCTION static inline int math_h_fpclassify(float f) { using namespace std; return fpclassify(f); }
}
QT_END_NAMESPACE
// These macros from math.h conflict with the real functions in the std namespace.
@@ -95,6 +97,7 @@ QT_END_NAMESPACE
# undef isnan
# undef isinf
# undef isfinite
+# undef fpclassify
# endif // defined(isnan)
#endif
@@ -106,16 +109,20 @@ namespace qnumeric_std_wrapper {
Q_DECL_CONST_FUNCTION static inline bool isnan(double d) { return math_h_isnan(d); }
Q_DECL_CONST_FUNCTION static inline bool isinf(double d) { return math_h_isinf(d); }
Q_DECL_CONST_FUNCTION static inline bool isfinite(double d) { return math_h_isfinite(d); }
+Q_DECL_CONST_FUNCTION static inline int fpclassify(double d) { return math_h_fpclassify(d); }
Q_DECL_CONST_FUNCTION static inline bool isnan(float f) { return math_h_isnan(f); }
Q_DECL_CONST_FUNCTION static inline bool isinf(float f) { return math_h_isinf(f); }
Q_DECL_CONST_FUNCTION static inline bool isfinite(float f) { return math_h_isfinite(f); }
+Q_DECL_CONST_FUNCTION static inline int fpclassify(float f) { return math_h_fpclassify(f); }
#else
Q_DECL_CONST_FUNCTION static inline bool isnan(double d) { return std::isnan(d); }
Q_DECL_CONST_FUNCTION static inline bool isinf(double d) { return std::isinf(d); }
Q_DECL_CONST_FUNCTION static inline bool isfinite(double d) { return std::isfinite(d); }
+Q_DECL_CONST_FUNCTION static inline int fpclassify(double d) { return std::fpclassify(d); }
Q_DECL_CONST_FUNCTION static inline bool isnan(float f) { return std::isnan(f); }
Q_DECL_CONST_FUNCTION static inline bool isinf(float f) { return std::isinf(f); }
Q_DECL_CONST_FUNCTION static inline bool isfinite(float f) { return std::isfinite(f); }
+Q_DECL_CONST_FUNCTION static inline int fpclassify(float f) { return std::fpclassify(f); }
#endif
}
@@ -157,6 +164,11 @@ Q_DECL_CONST_FUNCTION static inline bool qt_is_finite(double d)
return qnumeric_std_wrapper::isfinite(d);
}
+Q_DECL_CONST_FUNCTION static inline int qt_fpclassify(double d)
+{
+ return qnumeric_std_wrapper::fpclassify(d);
+}
+
Q_DECL_CONST_FUNCTION static inline bool qt_is_inf(float f)
{
return qnumeric_std_wrapper::isinf(f);
@@ -172,6 +184,11 @@ Q_DECL_CONST_FUNCTION static inline bool qt_is_finite(float f)
return qnumeric_std_wrapper::isfinite(f);
}
+Q_DECL_CONST_FUNCTION static inline int qt_fpclassify(float f)
+{
+ return qnumeric_std_wrapper::fpclassify(f);
+}
+
#ifndef Q_CLANG_QDOC
namespace {
/*!
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 6195c324e7..90df8653a7 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -930,7 +930,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
- \fn quint32 QRandomGenerator::bounded(int highest)
+ \fn int QRandomGenerator::bounded(int highest)
\overload
Generates one random 32-bit quantity in the range between 0 (inclusive) and
@@ -957,7 +957,6 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\snippet code/src_corelib_global_qrandom.cpp 14
-
Note that this function cannot be used to obtain values in the full 32-bit
range of quint32. Instead, use generate().
@@ -965,7 +964,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
- \fn quint32 QRandomGenerator::bounded(int lowest, int highest)
+ \fn int QRandomGenerator::bounded(int lowest, int highest)
\overload
Generates one random 32-bit quantity in the range between \a lowest
diff --git a/src/corelib/global/qtrace_p.h b/src/corelib/global/qtrace_p.h
index 3d04a7311d..56d1f9a318 100644
--- a/src/corelib/global/qtrace_p.h
+++ b/src/corelib/global/qtrace_p.h
@@ -114,10 +114,12 @@
QT_BEGIN_NAMESPACE
#if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
+# define Q_HAS_TRACEPOINTS 1
# define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__)
# define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__)
# define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled()
#else
+# define Q_HAS_TRACEPOINTS 0
# define Q_TRACE(x, ...)
# define Q_UNCONDITIONAL_TRACE(x, ...)
# define Q_TRACE_ENABLED(x) false
diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h
index 4a7fe7bff5..c88b66c7ce 100644
--- a/src/corelib/io/qabstractfileengine_p.h
+++ b/src/corelib/io/qabstractfileengine_p.h
@@ -193,7 +193,7 @@ public:
uchar *address;
};
- virtual bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0);
+ virtual bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr);
virtual bool supportsExtension(Extension extension) const;
// Factory
diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h
index e4b28f4519..36f440812f 100644
--- a/src/corelib/io/qfileinfo_p.h
+++ b/src/corelib/io/qfileinfo_p.h
@@ -80,7 +80,7 @@ public:
};
inline QFileInfoPrivate()
- : QSharedData(), fileEngine(0),
+ : QSharedData(), fileEngine(nullptr),
cachedFlags(0),
isDefaultConstructed(true),
cache_enabled(true), fileFlags(0), fileSize(0)
diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h
index 09ec2d6a10..e44837747c 100644
--- a/src/corelib/io/qfilesystemengine_p.h
+++ b/src/corelib/io/qfilesystemengine_p.h
@@ -130,7 +130,7 @@ public:
static bool removeFile(const QFileSystemEntry &entry, QSystemError &error);
static bool setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error,
- QFileSystemMetaData *data = 0);
+ QFileSystemMetaData *data = nullptr);
// unused, therefore not implemented
static bool setFileTime(const QFileSystemEntry &entry, const QDateTime &newDate,
diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h
index 4d2a5acb9b..81f4b3ba13 100644
--- a/src/corelib/io/qfilesystemmetadata_p.h
+++ b/src/corelib/io/qfilesystemmetadata_p.h
@@ -76,7 +76,7 @@ class Q_AUTOTEST_EXPORT QFileSystemMetaData
{
public:
QFileSystemMetaData()
- : knownFlagsMask(0),
+ : knownFlagsMask(nullptr),
size_(-1)
{
}
@@ -184,7 +184,7 @@ public:
void clear()
{
- knownFlagsMask = 0;
+ knownFlagsMask = nullptr;
}
void clearFlags(MetaDataFlags flags = AllMetaDataFlags)
diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp
index 66985f8982..7f4f9d345b 100644
--- a/src/corelib/io/qfilesystemwatcher_win.cpp
+++ b/src/corelib/io/qfilesystemwatcher_win.cpp
@@ -108,7 +108,11 @@ public:
// Call from QFileSystemWatcher::addPaths() to set up notifications on drives
void addPath(const QString &path);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool nativeEventFilter(const QByteArray &, void *messageIn, qintptr *) override;
+#else
bool nativeEventFilter(const QByteArray &, void *messageIn, long *) override;
+#endif
signals:
void driveAdded();
@@ -255,7 +259,11 @@ inline void QWindowsRemovableDriveListener::handleDbtDriveArrivalRemoval(const M
}
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+bool QWindowsRemovableDriveListener::nativeEventFilter(const QByteArray &, void *messageIn, qintptr *)
+#else
bool QWindowsRemovableDriveListener::nativeEventFilter(const QByteArray &, void *messageIn, long *)
+#endif
{
const MSG *msg = reinterpret_cast<const MSG *>(messageIn);
if (msg->message == WM_DEVICECHANGE) {
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 6b091a8eef..0f416f4886 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -115,7 +115,7 @@ public:
virtual bool isUnnamedFile() const
{ return false; }
- bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) override;
+ bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr) override;
bool supportsExtension(Extension extension) const override;
//FS only!!
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index d5d67d86f3..c7635cc7b4 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -42,6 +42,7 @@
#include <qdebug.h>
#include <qdir.h>
+#include <qscopedvaluerollback.h>
#if defined(Q_OS_WIN)
#include <qtimer.h>
#endif
@@ -1062,9 +1063,8 @@ bool QProcessPrivate::tryReadFromChannel(Channel *channel)
if (currentReadChannel == channelIdx) {
didRead = true;
if (!emittedReadyRead) {
- emittedReadyRead = true;
+ QScopedValueRollback<bool> guard(emittedReadyRead, true);
emit q->readyRead();
- emittedReadyRead = false;
}
}
emit q->channelReadyRead(int(channelIdx));
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index aa7ecbe91d..1bc63240fe 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -247,7 +247,7 @@ public:
// if you add "= 4" here, increase the number of bits below
};
- Channel() : process(0), notifier(0), type(Normal), closed(false), append(false)
+ Channel() : process(nullptr), notifier(nullptr), type(Normal), closed(false), append(false)
{
pipe[0] = INVALID_Q_PIPE;
pipe[1] = INVALID_Q_PIPE;
diff --git a/src/corelib/io/qresource_p.h b/src/corelib/io/qresource_p.h
index 7451de8809..fedf95bb33 100644
--- a/src/corelib/io/qresource_p.h
+++ b/src/corelib/io/qresource_p.h
@@ -108,7 +108,7 @@ public:
Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override;
Iterator *endEntryList() override;
- bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) override;
+ bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr) override;
bool supportsExtension(Extension extension) const override;
};
diff --git a/src/corelib/io/qurl_p.h b/src/corelib/io/qurl_p.h
index 1b9237e58a..e75de32e03 100644
--- a/src/corelib/io/qurl_p.h
+++ b/src/corelib/io/qurl_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
// in qurlrecode.cpp
extern Q_AUTOTEST_EXPORT int qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
- QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications = 0);
+ QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications = nullptr);
// in qurlidna.cpp
enum AceLeadingDot { AllowLeadingDot, ForbidLeadingDot };
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index 15c9f52cf3..1f03ac5d5a 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -40,6 +40,7 @@
#include "qwindowspipereader_p.h"
#include "qiodevice_p.h"
#include <qelapsedtimer.h>
+#include <qscopedvaluerollback.h>
QT_BEGIN_NAMESPACE
@@ -301,9 +302,8 @@ void QWindowsPipeReader::emitPendingReadyRead()
{
if (readyReadPending) {
readyReadPending = false;
- inReadyRead = true;
+ QScopedValueRollback<bool> guard(inReadyRead, true);
emit readyRead();
- inReadyRead = false;
}
}
diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp
index 92e8b6db52..32536f495b 100644
--- a/src/corelib/io/qwindowspipewriter.cpp
+++ b/src/corelib/io/qwindowspipewriter.cpp
@@ -39,6 +39,7 @@
#include "qwindowspipewriter_p.h"
#include "qiodevice_p.h"
+#include <qscopedvaluerollback.h>
QT_BEGIN_NAMESPACE
@@ -111,9 +112,8 @@ void QWindowsPipeWriter::emitPendingBytesWrittenValue()
emit canWrite();
if (!inBytesWritten) {
- inBytesWritten = true;
+ QScopedValueRollback<bool> guard(inBytesWritten, true);
emit bytesWritten(bytes);
- inBytesWritten = false;
}
}
}
diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h
index e6085eca94..92a440a125 100644
--- a/src/corelib/itemmodels/qabstractitemmodel_p.h
+++ b/src/corelib/itemmodels/qabstractitemmodel_p.h
@@ -98,7 +98,7 @@ public:
void itemsMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation);
bool allowMove(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation);
- inline QModelIndex createIndex(int row, int column, void *data = 0) const {
+ inline QModelIndex createIndex(int row, int column, void *data = nullptr) const {
return q_func()->createIndex(row, column, data);
}
diff --git a/src/corelib/itemmodels/qabstractproxymodel_p.h b/src/corelib/itemmodels/qabstractproxymodel_p.h
index f7bd5cc691..a95687c970 100644
--- a/src/corelib/itemmodels/qabstractproxymodel_p.h
+++ b/src/corelib/itemmodels/qabstractproxymodel_p.h
@@ -62,7 +62,7 @@ class Q_CORE_EXPORT QAbstractProxyModelPrivate : public QAbstractItemModelPrivat
{
Q_DECLARE_PUBLIC(QAbstractProxyModel)
public:
- QAbstractProxyModelPrivate() : QAbstractItemModelPrivate(), model(0) {}
+ QAbstractProxyModelPrivate() : QAbstractItemModelPrivate(), model(nullptr) {}
QAbstractItemModel *model;
virtual void _q_sourceModelDestroyed();
void mapDropCoordinatesToSource(int row, int column, const QModelIndex &parent,
diff --git a/src/corelib/itemmodels/qitemselectionmodel_p.h b/src/corelib/itemmodels/qitemselectionmodel_p.h
index e12a0c2928..ba85f22be3 100644
--- a/src/corelib/itemmodels/qitemselectionmodel_p.h
+++ b/src/corelib/itemmodels/qitemselectionmodel_p.h
@@ -62,7 +62,7 @@ class QItemSelectionModelPrivate: public QObjectPrivate
Q_DECLARE_PUBLIC(QItemSelectionModel)
public:
QItemSelectionModelPrivate()
- : model(0),
+ : model(nullptr),
currentCommand(QItemSelectionModel::NoUpdate),
tableSelected(false), tableColCount(0), tableRowCount(0) {}
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 3f7bf3cd47..789bcb7927 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -7,7 +7,7 @@ HEADERS += \
kernel/qdeadlinetimer.h \
kernel/qdeadlinetimer_p.h \
kernel/qelapsedtimer.h \
- kernel/qeventloop.h\
+ kernel/qeventloop.h \
kernel/qpointer.h \
kernel/qcorecmdlineargs_p.h \
kernel/qcoreapplication.h \
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index 8e1b560874..0ecfc7a8c7 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -470,7 +470,11 @@ void QAbstractEventDispatcher::removeNativeEventFilter(QAbstractNativeEventFilte
\sa installNativeEventFilter(), QAbstractNativeEventFilter::nativeEventFilter()
\since 5.0
*/
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
+#else
bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, long *result)
+#endif
{
Q_D(QAbstractEventDispatcher);
if (!d->eventFilters.isEmpty()) {
diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h
index bd8da5c35d..4ef9c068df 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.h
+++ b/src/corelib/kernel/qabstracteventdispatcher.h
@@ -110,7 +110,11 @@ public:
void installNativeEventFilter(QAbstractNativeEventFilter *filterObj);
void removeNativeEventFilter(QAbstractNativeEventFilter *filterObj);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result);
+#else
bool filterNativeEvent(const QByteArray &eventType, void *message, long *result);
+#endif
#if QT_DEPRECATED_SINCE(5, 0)
QT_DEPRECATED bool filterEvent(void *message)
{ return filterNativeEvent("", message, nullptr); }
diff --git a/src/corelib/kernel/qabstractnativeeventfilter.cpp b/src/corelib/kernel/qabstractnativeeventfilter.cpp
index dcbb92f044..eaadea4c12 100644
--- a/src/corelib/kernel/qabstractnativeeventfilter.cpp
+++ b/src/corelib/kernel/qabstractnativeeventfilter.cpp
@@ -74,6 +74,7 @@ QAbstractNativeEventFilter::~QAbstractNativeEventFilter()
eventDispatcher->removeNativeEventFilter(this);
}
+// ### fixme Qt 6: result will be qintptr *
/*!
\fn bool QAbstractNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
diff --git a/src/corelib/kernel/qabstractnativeeventfilter.h b/src/corelib/kernel/qabstractnativeeventfilter.h
index d7baa42513..a468bffd61 100644
--- a/src/corelib/kernel/qabstractnativeeventfilter.h
+++ b/src/corelib/kernel/qabstractnativeeventfilter.h
@@ -52,7 +52,11 @@ public:
QAbstractNativeEventFilter();
virtual ~QAbstractNativeEventFilter();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) = 0;
+#else
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) = 0;
+#endif
private:
Q_DISABLE_COPY(QAbstractNativeEventFilter)
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 5a2a29a327..32ef6408c2 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -171,7 +171,7 @@ inline void qt_ignore_sigpipe()
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
noaction.sa_handler = SIG_IGN;
- ::sigaction(SIGPIPE, &noaction, 0);
+ ::sigaction(SIGPIPE, &noaction, nullptr);
atom.store(1);
}
}
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index c06af79cc7..5da33a5aae 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -256,15 +256,6 @@ void QCoreApplicationPrivate::processCommandLineArguments()
// Support for introspection
-#ifndef QT_NO_QOBJECT
-QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };
-
-void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set)
-{
- qt_signal_spy_callback_set = callback_set;
-}
-#endif
-
extern "C" void Q_CORE_EXPORT qt_startup_hook()
{
}
@@ -866,11 +857,6 @@ void QCoreApplicationPrivate::init()
eventDispatcherReady();
#endif
-#ifdef QT_EVAL
- extern void qt_core_eval_init(QCoreApplicationPrivate::Type);
- qt_core_eval_init(application_type);
-#endif
-
processCommandLineArguments();
qt_call_pre_routines();
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index b3479414ab..14ca3efd7f 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -149,7 +149,7 @@ public:
QString cachedApplicationDirPath;
static QString *cachedApplicationFilePath;
static void setApplicationFilePath(const QString &path);
- static inline void clearApplicationFilePath() { delete cachedApplicationFilePath; cachedApplicationFilePath = 0; }
+ static inline void clearApplicationFilePath() { delete cachedApplicationFilePath; cachedApplicationFilePath = nullptr; }
#ifndef QT_NO_QOBJECT
void execCleanup();
diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h
index 88ff316ee5..313825d0a7 100644
--- a/src/corelib/kernel/qeventdispatcher_glib_p.h
+++ b/src/corelib/kernel/qeventdispatcher_glib_p.h
@@ -66,8 +66,8 @@ class Q_CORE_EXPORT QEventDispatcherGlib : public QAbstractEventDispatcher
Q_DECLARE_PRIVATE(QEventDispatcherGlib)
public:
- explicit QEventDispatcherGlib(QObject *parent = 0);
- explicit QEventDispatcherGlib(GMainContext *context, QObject *parent = 0);
+ explicit QEventDispatcherGlib(QObject *parent = nullptr);
+ explicit QEventDispatcherGlib(GMainContext *context, QObject *parent = nullptr);
~QEventDispatcherGlib();
bool processEvents(QEventLoop::ProcessEventsFlags flags) override;
@@ -102,7 +102,7 @@ class Q_CORE_EXPORT QEventDispatcherGlibPrivate : public QAbstractEventDispatche
{
public:
- QEventDispatcherGlibPrivate(GMainContext *context = 0);
+ QEventDispatcherGlibPrivate(GMainContext *context = nullptr);
GMainContext *mainContext;
GPostEventSource *postEventSource;
GSocketNotifierSource *socketNotifierSource;
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index 0fd068b074..8cfa4bbdf7 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -102,7 +102,7 @@ class Q_CORE_EXPORT QEventDispatcherUNIX : public QAbstractEventDispatcher
Q_DECLARE_PRIVATE(QEventDispatcherUNIX)
public:
- explicit QEventDispatcherUNIX(QObject *parent = 0);
+ explicit QEventDispatcherUNIX(QObject *parent = nullptr);
~QEventDispatcherUNIX();
bool processEvents(QEventLoop::ProcessEventsFlags flags) override;
@@ -123,7 +123,7 @@ public:
void flush() override;
protected:
- QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObject *parent = 0);
+ QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObject *parent = nullptr);
};
class Q_CORE_EXPORT QEventDispatcherUNIXPrivate : public QAbstractEventDispatcherPrivate
@@ -152,9 +152,9 @@ public:
inline QSocketNotifierSetUNIX::QSocketNotifierSetUNIX() Q_DECL_NOTHROW
{
- notifiers[0] = 0;
- notifiers[1] = 0;
- notifiers[2] = 0;
+ notifiers[0] = nullptr;
+ notifiers[1] = nullptr;
+ notifiers[2] = nullptr;
}
inline bool QSocketNotifierSetUNIX::isEmpty() const Q_DECL_NOTHROW
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 685d765adb..84378454ca 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -136,7 +136,11 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
msg.wParam = wp;
msg.lParam = lp;
QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ qintptr result;
+#else
long result;
+#endif
if (!dispatcher) {
if (message == WM_TIMER)
KillTimer(hwnd, wp);
diff --git a/src/corelib/kernel/qmetaobject_moc_p.h b/src/corelib/kernel/qmetaobject_moc_p.h
index ad258acfcd..8c7900767b 100644
--- a/src/corelib/kernel/qmetaobject_moc_p.h
+++ b/src/corelib/kernel/qmetaobject_moc_p.h
@@ -138,7 +138,7 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc
{ "struct ", 7 },
{ "class ", 6 },
{ "enum ", 5 },
- { 0, 0 }
+ { nullptr, 0 }
};
int i = 0;
do {
@@ -146,7 +146,7 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc
t += optional[i].len;
break;
}
- } while (optional[++i].keyword != 0);
+ } while (optional[++i].keyword != nullptr);
}
bool star = false;
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 522bd78e42..0cd9da2eac 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -54,6 +54,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qobjectdefs.h>
+#include <QtCore/qmutex.h>
#ifndef QT_NO_QOBJECT
#include <private/qobject_p.h> // For QObjectPrivate::Connection
#endif
@@ -168,7 +169,6 @@ Q_DECLARE_TYPEINFO(QArgumentType, Q_MOVABLE_TYPE);
typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
class QMetaMethodPrivate;
-class QMutex;
struct QMetaObjectPrivate
{
@@ -226,15 +226,15 @@ struct QMetaObjectPrivate
static QObjectPrivate::Connection *connect(const QObject *sender, int signal_index,
const QMetaObject *smeta,
const QObject *receiver, int method_index_relative,
- const QMetaObject *rmeta = 0,
- int type = 0, int *types = 0);
+ const QMetaObject *rmeta = nullptr,
+ int type = 0, int *types = nullptr);
static bool disconnect(const QObject *sender, int signal_index,
const QMetaObject *smeta,
const QObject *receiver, int method_index, void **slot,
DisconnectType = DisconnectAll);
- static inline bool disconnectHelper(QObjectPrivate::Connection *c,
+ static inline bool disconnectHelper(QObjectPrivate::ConnectionData *connections, int signalIndex,
const QObject *receiver, int method_index, void **slot,
- QMutex *senderMutex, DisconnectType = DisconnectAll);
+ QBasicMutex *senderMutex, DisconnectType = DisconnectAll);
#endif
};
diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h
index 6100835bad..6d43be7811 100644
--- a/src/corelib/kernel/qmetaobjectbuilder_p.h
+++ b/src/corelib/kernel/qmetaobjectbuilder_p.h
@@ -173,7 +173,7 @@ public:
void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value);
QMetaObject *toMetaObject() const;
- QByteArray toRelocatableData(bool * = 0) const;
+ QByteArray toRelocatableData(bool * = nullptr) const;
static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &);
#ifndef QT_NO_DATASTREAM
@@ -196,7 +196,7 @@ private:
class Q_CORE_EXPORT QMetaMethodBuilder
{
public:
- QMetaMethodBuilder() : _mobj(0), _index(0) {}
+ QMetaMethodBuilder() : _mobj(nullptr), _index(0) {}
int index() const;
@@ -238,7 +238,7 @@ private:
class Q_CORE_EXPORT QMetaPropertyBuilder
{
public:
- QMetaPropertyBuilder() : _mobj(0), _index(0) {}
+ QMetaPropertyBuilder() : _mobj(nullptr), _index(0) {}
int index() const { return _index; }
@@ -294,7 +294,7 @@ private:
class Q_CORE_EXPORT QMetaEnumBuilder
{
public:
- QMetaEnumBuilder() : _mobj(0), _index(0) {}
+ QMetaEnumBuilder() : _mobj(nullptr), _index(0) {}
int index() const { return _index; }
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 15955e1665..45e88a2082 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
@@ -77,6 +77,12 @@ QT_BEGIN_NAMESPACE
static int DIRECT_CONNECTION_ONLY = 0;
+Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
+
+void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set)
+{
+ qt_signal_spy_callback_set.store(callback_set);
+}
QDynamicMetaObjectData::~QDynamicMetaObjectData()
{
@@ -146,10 +152,9 @@ static QBasicMutex _q_ObjectMutexPool[131];
* \internal
* mutex to be locked when accessing the connectionlists or the senders list
*/
-static inline QMutex *signalSlotLock(const QObject *o)
+static inline QBasicMutex *signalSlotLock(const QObject *o)
{
- return static_cast<QMutex *>(&_q_ObjectMutexPool[
- uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)]);
+ return &_q_ObjectMutexPool[uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)];
}
#if QT_VERSION < 0x60000
@@ -160,39 +165,6 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
{}
#endif
-struct QConnectionSenderSwitcher {
- QObject *receiver;
- QObjectPrivate::Sender *previousSender;
- QObjectPrivate::Sender currentSender;
- bool switched;
-
- inline QConnectionSenderSwitcher() : switched(false) {}
-
- inline QConnectionSenderSwitcher(QObject *receiver, QObject *sender, int signal_absolute_id)
- {
- switchSender(receiver, sender, signal_absolute_id);
- }
-
- inline void switchSender(QObject *receiver, QObject *sender, int signal_absolute_id)
- {
- this->receiver = receiver;
- currentSender.sender = sender;
- currentSender.signal = signal_absolute_id;
- currentSender.ref = 1;
- previousSender = QObjectPrivate::setCurrentSender(receiver, &currentSender);
- switched = true;
- }
-
- inline ~QConnectionSenderSwitcher()
- {
- if (switched)
- QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
- }
-private:
- Q_DISABLE_COPY(QConnectionSenderSwitcher)
-};
-
-
void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::destroyed_qml1)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
@@ -209,7 +181,7 @@ QMetaObject *QObjectData::dynamicMetaObject() const
}
QObjectPrivate::QObjectPrivate(int version)
- : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0)
+ : threadData(0), currentChildBeingDeleted(0)
{
#ifdef QT_BUILD_INTERNAL
// Don't check the version parameter in internal builds.
@@ -232,7 +204,6 @@ QObjectPrivate::QObjectPrivate(int version)
receiveChildEvents = true;
postedEvents = 0;
extraData = 0;
- connectedSignals[0] = connectedSignals[1] = 0;
metaObject = 0;
isWindow = false;
deleteLaterCalled = false;
@@ -285,59 +256,22 @@ static void computeOffsets(const QMetaObject *metaobject, int *signalOffset, int
}
}
-/*
- This vector contains the all connections from an object.
-
- Each object may have one vector containing the lists of
- connections for a given signal. The index in the vector correspond
- to the signal index. The signal index is the one returned by
- QObjectPrivate::signalIndex (not QMetaObject::indexOfSignal).
- Negative index means connections to all signals.
-
- This vector is protected by the object mutex (signalSlotMutexes())
-
- Each Connection is also part of a 'senders' linked list. The mutex
- of the receiver must be locked when touching the pointers of this
- linked list.
-*/
-class QObjectConnectionListVector : public QVector<QObjectPrivate::ConnectionList>
-{
-public:
- bool orphaned; //the QObject owner of this vector has been destroyed while the vector was inUse
- bool dirty; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet
- int inUse; //number of functions that are currently accessing this object or its connections
- QObjectPrivate::ConnectionList allsignals;
-
- QObjectConnectionListVector()
- : QVector<QObjectPrivate::ConnectionList>(), orphaned(false), dirty(false), inUse(0)
- { }
-
- QObjectPrivate::ConnectionList &operator[](int at)
- {
- if (at < 0)
- return allsignals;
- return QVector<QObjectPrivate::ConnectionList>::operator[](at);
- }
-};
-
// Used by QAccessibleWidget
bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
{
Q_Q(const QObject);
int signal_index = signalIndex(signal);
- if (signal_index < 0)
+ ConnectionData *cd = connections.load();
+ if (signal_index < 0 || !cd)
return false;
- QMutexLocker locker(signalSlotLock(q));
- if (connectionLists) {
- if (signal_index < connectionLists->count()) {
- const QObjectPrivate::Connection *c =
- connectionLists->at(signal_index).first;
-
- while (c) {
- if (c->receiver == receiver)
- return true;
- c = c->nextConnectionList;
- }
+ QBasicMutexLocker locker(signalSlotLock(q));
+ if (signal_index < cd->signalVectorCount()) {
+ const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
+
+ while (c) {
+ if (c->receiver.load() == receiver)
+ return true;
+ c = c->nextConnectionList.load();
}
}
return false;
@@ -346,21 +280,19 @@ bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
// Used by QAccessibleWidget
QObjectList QObjectPrivate::receiverList(const char *signal) const
{
- Q_Q(const QObject);
QObjectList returnValue;
int signal_index = signalIndex(signal);
- if (signal_index < 0)
+ ConnectionData *cd = connections.load();
+ if (signal_index < 0 || !cd)
return returnValue;
- QMutexLocker locker(signalSlotLock(q));
- if (connectionLists) {
- if (signal_index < connectionLists->count()) {
- const QObjectPrivate::Connection *c = connectionLists->at(signal_index).first;
-
- while (c) {
- if (c->receiver)
- returnValue << c->receiver;
- c = c->nextConnectionList;
- }
+ if (signal_index < cd->signalVectorCount()) {
+ const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
+
+ while (c) {
+ QObject *r = c->receiver.load();
+ if (r)
+ returnValue << r;
+ c = c->nextConnectionList.load();
}
}
return returnValue;
@@ -370,9 +302,12 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const
QObjectList QObjectPrivate::senderList() const
{
QObjectList returnValue;
- QMutexLocker locker(signalSlotLock(q_func()));
- for (Connection *c = senders; c; c = c->next)
- returnValue << c->sender;
+ ConnectionData *cd = connections.load();
+ if (cd) {
+ QBasicMutexLocker locker(signalSlotLock(q_func()));
+ for (Connection *c = cd->senders; c; c = c->next)
+ returnValue << c->sender;
+ }
return returnValue;
}
@@ -389,79 +324,187 @@ QObjectList QObjectPrivate::senderList() const
void QObjectPrivate::addConnection(int signal, Connection *c)
{
Q_ASSERT(c->sender == q_ptr);
- if (!connectionLists)
- connectionLists = new QObjectConnectionListVector();
- if (signal >= connectionLists->count())
- connectionLists->resize(signal + 1);
-
- ConnectionList &connectionList = (*connectionLists)[signal];
- if (connectionList.last) {
- connectionList.last->nextConnectionList = c;
+ ensureConnectionData();
+ ConnectionData *cd = connections.load();
+ cd->resizeSignalVector(signal + 1);
+
+ ConnectionList &connectionList = cd->connectionsForSignal(signal);
+ if (connectionList.last.load()) {
+ Q_ASSERT(connectionList.last.load()->receiver.load());
+ connectionList.last.load()->nextConnectionList.store(c);
} else {
- connectionList.first = c;
+ connectionList.first.store(c);
}
- connectionList.last = c;
+ c->id = ++cd->currentConnectionId;
+ c->prevConnectionList = connectionList.last.load();
+ connectionList.last.store(c);
- cleanConnectionLists();
+ QObjectPrivate *rd = QObjectPrivate::get(c->receiver.load());
+ rd->ensureConnectionData();
- c->prev = &(QObjectPrivate::get(c->receiver)->senders);
+ c->prev = &(rd->connections.load()->senders);
c->next = *c->prev;
*c->prev = c;
if (c->next)
c->next->prev = &c->next;
+}
+
+void QObjectPrivate::ConnectionData::removeConnection(QObjectPrivate::Connection *c)
+{
+ Q_ASSERT(c->receiver.load());
+ ConnectionList &connections = signalVector.load()->at(c->signal_index);
+ c->receiver.store(nullptr);
+ QThreadData *td = c->receiverThreadData.load();
+ if (td)
+ td->deref();
+ c->receiverThreadData.store(nullptr);
- if (signal < 0) {
- connectedSignals[0] = connectedSignals[1] = ~0;
- } else if (signal < (int)sizeof(connectedSignals) * 8) {
- connectedSignals[signal >> 5] |= (1 << (signal & 0x1f));
+#ifndef QT_NO_DEBUG
+ bool found = false;
+ for (Connection *cc = connections.first.load(); cc; cc = cc->nextConnectionList.load()) {
+ if (cc == c) {
+ found = true;
+ break;
+ }
}
+ Q_ASSERT(found);
+#endif
+
+ // remove from the senders linked list
+ *c->prev = c->next;
+ if (c->next)
+ c->next->prev = c->prev;
+ c->prev = nullptr;
+
+ if (connections.first.load() == c)
+ connections.first.store(c->nextConnectionList.load());
+ if (connections.last.load() == c)
+ connections.last.store(c->prevConnectionList);
+ Q_ASSERT(signalVector.load()->at(c->signal_index).first.load() != c);
+ Q_ASSERT(signalVector.load()->at(c->signal_index).last.load() != c);
+
+ // keep c->nextConnectionList intact, as it might still get accessed by activate
+ Connection *n = c->nextConnectionList.load();
+ if (n)
+ n->prevConnectionList = c->prevConnectionList;
+ if (c->prevConnectionList)
+ c->prevConnectionList->nextConnectionList.store(n);
+ c->prevConnectionList = nullptr;
+
+ Q_ASSERT(c != orphaned.load());
+ // add c to orphanedConnections
+ c->nextInOrphanList = orphaned.load();
+ orphaned.store(c);
+
+#ifndef QT_NO_DEBUG
+ found = false;
+ for (Connection *cc = connections.first.load(); cc; cc = cc->nextConnectionList.load()) {
+ if (cc == c) {
+ found = true;
+ break;
+ }
+ }
+ Q_ASSERT(!found);
+#endif
+
}
-void QObjectPrivate::cleanConnectionLists()
+void QObjectPrivate::ConnectionData::cleanOrphanedConnectionsImpl(QObject *sender)
{
- if (connectionLists->dirty && !connectionLists->inUse) {
- // remove broken connections
- bool allConnected = false;
- for (int signal = -1; signal < connectionLists->count(); ++signal) {
- QObjectPrivate::ConnectionList &connectionList =
- (*connectionLists)[signal];
-
- // Set to the last entry in the connection list that was *not*
- // deleted. This is needed to update the list's last pointer
- // at the end of the cleanup.
- QObjectPrivate::Connection *last = 0;
-
- QObjectPrivate::Connection **prev = &connectionList.first;
- QObjectPrivate::Connection *c = *prev;
- bool connected = false; // whether the signal is still connected somewhere
- while (c) {
- if (c->receiver) {
- last = c;
- prev = &c->nextConnectionList;
- c = *prev;
- connected = true;
- } else {
- QObjectPrivate::Connection *next = c->nextConnectionList;
- *prev = next;
- c->deref();
- c = next;
- }
- }
+ ConnectionOrSignalVector *c = nullptr;
+ {
+ QBasicMutexLocker l(signalSlotLock(sender));
+ if (ref > 1)
+ return;
- // Correct the connection list's last pointer.
- // As conectionList.last could equal last, this could be a noop
- connectionList.last = last;
+ // Since ref == 1, no activate() is in process since we locked the mutex. That implies,
+ // that nothing can reference the orphaned connection objects anymore and they can
+ // be safely deleted
+ c = orphaned.load();
+ orphaned.store(nullptr);
+ }
+ deleteOrphaned(c);
+}
- if (!allConnected && !connected && signal >= 0
- && size_t(signal) < sizeof(connectedSignals) * 8) {
- // This signal is no longer connected
- connectedSignals[signal >> 5] &= ~(1 << (signal & 0x1f));
- } else if (signal == -1) {
- allConnected = connected;
- }
+void QObjectPrivate::ConnectionData::deleteOrphaned(QObjectPrivate::ConnectionOrSignalVector *o)
+{
+ while (o) {
+ QObjectPrivate::ConnectionOrSignalVector *next = nullptr;
+ if (SignalVector *v = ConnectionOrSignalVector::asSignalVector(o)) {
+ next = v->nextInOrphanList;
+ free(v);
+ } else {
+ QObjectPrivate::Connection *c = static_cast<Connection *>(o);
+ next = c->nextInOrphanList;
+ Q_ASSERT(!c->receiver.load());
+ Q_ASSERT(!c->prev);
+ c->freeSlotObject();
+ c->deref();
}
- connectionLists->dirty = false;
+ o = next;
+ }
+}
+
+/*! \internal
+
+ Returns \c true if the signal with index \a signal_index from object \a sender is connected.
+
+ \a signal_index must be the index returned by QObjectPrivate::signalIndex;
+*/
+bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative) const
+{
+ if (checkDeclarative && isDeclarativeSignalConnected(signalIndex))
+ return true;
+
+ ConnectionData *cd = connections.load();
+ if (!cd)
+ return false;
+ SignalVector *signalVector = cd->signalVector.load();
+ if (!signalVector)
+ return false;
+
+ if (signalVector->at(-1).first.load())
+ return true;
+
+ if (signalIndex < uint(cd->signalVectorCount())) {
+ const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first.load();
+ while (c) {
+ if (c->receiver.load())
+ return true;
+ c = c->nextConnectionList.load();
+ }
+ }
+ return false;
+}
+
+bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const
+{
+ ConnectionData *cd = connections.load();
+ if (!cd)
+ return false;
+ SignalVector *signalVector = cd->signalVector.load();
+ if (!signalVector)
+ return false;
+
+ if (signalVector->at(-1).first)
+ return true;
+
+ if (signalIndex < uint(cd->signalVectorCount())) {
+ const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first;
+ return c != nullptr;
}
+ return false;
+}
+
+/*!
+ \internal
+ */
+QAbstractMetaCallEvent::~QAbstractMetaCallEvent()
+{
+#if QT_CONFIG(thread)
+ if (semaphore_)
+ semaphore_->release();
+#endif
}
/*!
@@ -470,8 +513,8 @@ void QObjectPrivate::cleanConnectionLists()
QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction,
const QObject *sender, int signalId,
int nargs, int *types, void **args, QSemaphore *semaphore)
- : QEvent(MetaCall), slotObj_(0), sender_(sender), signalId_(signalId),
- nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
+ : QAbstractMetaCallEvent(sender, signalId, semaphore),
+ slotObj_(nullptr), nargs_(nargs), types_(types), args_(args),
callFunction_(callFunction), method_offset_(method_offset), method_relative_(method_relative)
{ }
@@ -480,9 +523,9 @@ QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QOb
*/
QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, const QObject *sender, int signalId,
int nargs, int *types, void **args, QSemaphore *semaphore)
- : QEvent(MetaCall), slotObj_(slotO), sender_(sender), signalId_(signalId),
- nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
- callFunction_(0), method_offset_(0), method_relative_(ushort(-1))
+ : QAbstractMetaCallEvent(sender, signalId, semaphore),
+ slotObj_(slotO), nargs_(nargs), types_(types), args_(args),
+ callFunction_(nullptr), method_offset_(0), method_relative_(ushort(-1))
{
if (slotObj_)
slotObj_->ref();
@@ -501,10 +544,6 @@ QMetaCallEvent::~QMetaCallEvent()
free(types_);
free(args_);
}
-#if QT_CONFIG(thread)
- if (semaphore_)
- semaphore_->release();
-#endif
if (slotObj_)
slotObj_->destroyIfLastRef();
}
@@ -921,92 +960,56 @@ QObject::~QObject()
}
}
- // set ref to zero to indicate that this object has been deleted
- if (d->currentSender != 0)
- d->currentSender->ref = 0;
- d->currentSender = 0;
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ if (cd) {
+ if (cd->currentSender) {
+ cd->currentSender->receiverDeleted();
+ cd->currentSender = nullptr;
+ }
- if (d->connectionLists || d->senders) {
- QMutex *signalSlotMutex = signalSlotLock(this);
- QMutexLocker locker(signalSlotMutex);
+ QBasicMutex *signalSlotMutex = signalSlotLock(this);
+ QBasicMutexLocker locker(signalSlotMutex);
// disconnect all receivers
- if (d->connectionLists) {
- ++d->connectionLists->inUse;
- int connectionListsCount = d->connectionLists->count();
- for (int signal = -1; signal < connectionListsCount; ++signal) {
- QObjectPrivate::ConnectionList &connectionList =
- (*d->connectionLists)[signal];
-
- while (QObjectPrivate::Connection *c = connectionList.first) {
- if (!c->receiver) {
- connectionList.first = c->nextConnectionList;
- c->deref();
- continue;
- }
+ int receiverCount = cd->signalVectorCount();
+ for (int signal = -1; signal < receiverCount; ++signal) {
+ QObjectPrivate::ConnectionList &connectionList = cd->connectionsForSignal(signal);
- QMutex *m = signalSlotLock(c->receiver);
- bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
+ while (QObjectPrivate::Connection *c = connectionList.first.load()) {
+ Q_ASSERT(c->receiver);
- if (c->receiver) {
- *c->prev = c->next;
- if (c->next) c->next->prev = c->prev;
- }
- c->receiver = 0;
- if (needToUnlock)
- m->unlock();
-
- connectionList.first = c->nextConnectionList;
-
- // The destroy operation must happen outside the lock
- if (c->isSlotObject) {
- c->isSlotObject = false;
- locker.unlock();
- c->slotObj->destroyIfLastRef();
- locker.relock();
- }
- c->deref();
+ QBasicMutex *m = signalSlotLock(c->receiver.load());
+ bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
+ if (c->receiver) {
+ cd->removeConnection(c);
+ Q_ASSERT(connectionList.first.load() != c);
}
+ if (needToUnlock)
+ m->unlock();
}
-
- if (!--d->connectionLists->inUse) {
- delete d->connectionLists;
- } else {
- d->connectionLists->orphaned = true;
- }
- d->connectionLists = 0;
}
/* Disconnect all senders:
- * This loop basically just does
- * for (node = d->senders; node; node = node->next) { ... }
- *
- * We need to temporarily unlock the receiver mutex to destroy the functors or to lock the
- * sender's mutex. And when the mutex is released, node->next might be destroyed by another
- * thread. That's why we set node->prev to &node, that way, if node is destroyed, node will
- * be updated.
*/
- QObjectPrivate::Connection *node = d->senders;
- while (node) {
+ while (QObjectPrivate::Connection *node = cd->senders) {
+ Q_ASSERT(node->receiver);
QObject *sender = node->sender;
// Send disconnectNotify before removing the connection from sender's connection list.
// This ensures any eventual destructor of sender will block on getting receiver's lock
// and not finish until we release it.
sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), node->signal_index));
- QMutex *m = signalSlotLock(sender);
- node->prev = &node;
+ QBasicMutex *m = signalSlotLock(sender);
bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
//the node has maybe been removed while the mutex was unlocked in relock?
- if (!node || node->sender != sender) {
+ if (node != cd->senders) {
// We hold the wrong mutex
Q_ASSERT(needToUnlock);
m->unlock();
continue;
}
- node->receiver = 0;
- QObjectConnectionListVector *senderLists = sender->d_func()->connectionLists;
- if (senderLists)
- senderLists->dirty = true;
+
+ QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections.load();
+ Q_ASSERT(senderData);
QtPrivate::QSlotObjectBase *slotObj = nullptr;
if (node->isSlotObject) {
@@ -1014,19 +1017,24 @@ QObject::~QObject()
node->isSlotObject = false;
}
- node = node->next;
+ senderData->removeConnection(node);
if (needToUnlock)
m->unlock();
if (slotObj) {
- if (node)
- node->prev = &node;
locker.unlock();
slotObj->destroyIfLastRef();
locker.relock();
}
}
+
+ // invalidate all connections on the object and make sure
+ // activate() will skip them
+ cd->currentConnectionId.store(0);
}
+ if (cd && !cd->ref.deref())
+ delete cd;
+ d->connections.store(nullptr);
if (!d->children.isEmpty())
d->deleteChildren();
@@ -1253,9 +1261,13 @@ bool QObject::event(QEvent *e)
case QEvent::MetaCall:
{
- QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e);
+ QAbstractMetaCallEvent *mce = static_cast<QAbstractMetaCallEvent*>(e);
- QConnectionSenderSwitcher sw(this, const_cast<QObject*>(mce->sender()), mce->signalId());
+ if (!d_func()->connections.load()) {
+ QBasicMutexLocker locker(signalSlotLock(this));
+ d_func()->ensureConnectionData();
+ }
+ QObjectPrivate::Sender sender(this, const_cast<QObject*>(mce->sender()), mce->signalId());
mce->placeMetaCall(this);
break;
@@ -1510,6 +1522,9 @@ void QObject::moveToThread(QThread *targetThread)
if (!targetData)
targetData = new QThreadData(0);
+ // make sure nobody adds/removes connections to this object while we're moving it
+ QMutexLocker l(signalSlotLock(this));
+
QOrderedMutexLocker locker(&currentData->postEventList.mutex,
&targetData->postEventList.mutex);
@@ -1559,9 +1574,31 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
}
// the current emitting thread shouldn't restore currentSender after calling moveToThread()
- if (currentSender)
- currentSender->ref = 0;
- currentSender = 0;
+ ConnectionData *cd = connections.load();
+ if (cd) {
+ if (cd->currentSender) {
+ cd->currentSender->receiverDeleted();
+ cd->currentSender = nullptr;
+ }
+
+ // adjust the receiverThreadId values in the Connections
+ if (cd) {
+ auto *c = cd->senders;
+ while (c) {
+ QObject *r = c->receiver.load();
+ if (r) {
+ Q_ASSERT(r == q);
+ targetData->ref();
+ QThreadData *old = c->receiverThreadData.load();
+ if (old)
+ old->deref();
+ c->receiverThreadData.store(targetData);
+ }
+ c = c->next;
+ }
+ }
+
+ }
// set new thread data
targetData->ref();
@@ -2370,13 +2407,14 @@ QObject *QObject::sender() const
{
Q_D(const QObject);
- QMutexLocker locker(signalSlotLock(this));
- if (!d->currentSender)
- return 0;
+ QBasicMutexLocker locker(signalSlotLock(this));
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ if (!cd || !cd->currentSender)
+ return nullptr;
- for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
- if (c->sender == d->currentSender->sender)
- return d->currentSender->sender;
+ for (QObjectPrivate::Connection *c = cd->senders; c; c = c->next) {
+ if (c->sender == cd->currentSender->sender)
+ return cd->currentSender->sender;
}
return 0;
@@ -2411,14 +2449,15 @@ int QObject::senderSignalIndex() const
{
Q_D(const QObject);
- QMutexLocker locker(signalSlotLock(this));
- if (!d->currentSender)
+ QBasicMutexLocker locker(signalSlotLock(this));
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ if (!cd || !cd->currentSender)
return -1;
- for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
- if (c->sender == d->currentSender->sender) {
+ for (QObjectPrivate::Connection *c = cd->senders; c; c = c->next) {
+ if (c->sender == cd->currentSender->sender) {
// Convert from signal range to method range
- return QMetaObjectPrivate::signal(c->sender->metaObject(), d->currentSender->signal).methodIndex();
+ return QMetaObjectPrivate::signal(c->sender->metaObject(), cd->currentSender->signal).methodIndex();
}
}
@@ -2474,15 +2513,13 @@ int QObject::receivers(const char *signal) const
signal_index);
}
- QMutexLocker locker(signalSlotLock(this));
- if (d->connectionLists) {
- if (signal_index < d->connectionLists->count()) {
- const QObjectPrivate::Connection *c =
- d->connectionLists->at(signal_index).first;
- while (c) {
- receivers += c->receiver ? 1 : 0;
- c = c->nextConnectionList;
- }
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ QBasicMutexLocker locker(signalSlotLock(this));
+ if (cd && signal_index < cd->signalVectorCount()) {
+ const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
+ while (c) {
+ receivers += c->receiver.load() ? 1 : 0;
+ c = c->nextConnectionList.load();
}
}
}
@@ -2522,22 +2559,8 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const
signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj);
- QMutexLocker locker(signalSlotLock(this));
- if (d->connectionLists) {
- if (signalIndex < sizeof(d->connectedSignals) * 8 && !d->connectionLists->dirty)
- return d->isSignalConnected(signalIndex);
-
- if (signalIndex < uint(d->connectionLists->count())) {
- const QObjectPrivate::Connection *c =
- d->connectionLists->at(signalIndex).first;
- while (c) {
- if (c->receiver)
- return true;
- c = c->nextConnectionList;
- }
- }
- }
- return d->isDeclarativeSignalConnected(signalIndex);
+ QBasicMutexLocker locker(signalSlotLock(this));
+ return d->isSignalConnected(signalIndex, true);
}
/*!
@@ -3300,24 +3323,22 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
int method_offset = rmeta ? rmeta->methodOffset() : 0;
Q_ASSERT(!rmeta || QMetaObjectPrivate::get(rmeta)->revision >= 6);
- QObjectPrivate::StaticMetaCallFunction callFunction =
- rmeta ? rmeta->d.static_metacall : 0;
+ QObjectPrivate::StaticMetaCallFunction callFunction = rmeta ? rmeta->d.static_metacall : nullptr;
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
- if (type & Qt::UniqueConnection) {
- QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
- if (connectionLists && connectionLists->count() > signal_index) {
- const QObjectPrivate::Connection *c2 =
- (*connectionLists)[signal_index].first;
+ QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load();
+ if (type & Qt::UniqueConnection && scd) {
+ if (scd->signalVectorCount() > signal_index) {
+ const QObjectPrivate::Connection *c2 = scd->signalVector.load()->at(signal_index).first.load();
int method_index_absolute = method_index + method_offset;
while (c2) {
- if (!c2->isSlotObject && c2->receiver == receiver && c2->method() == method_index_absolute)
- return 0;
- c2 = c2->nextConnectionList;
+ if (!c2->isSlotObject && c2->receiver.load() == receiver && c2->method() == method_index_absolute)
+ return nullptr;
+ c2 = c2->nextConnectionList.load();
}
}
type &= Qt::UniqueConnection - 1;
@@ -3326,13 +3347,15 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
c->sender = s;
c->signal_index = signal_index;
- c->receiver = r;
+ c->receiver.store(r);
+ QThreadData *td = r->d_func()->threadData;
+ td->ref();
+ c->receiverThreadData.store(td);
c->method_relative = method_index;
c->method_offset = method_offset;
c->connectionType = type;
c->isSlotObject = false;
c->argumentTypes.store(types);
- c->nextConnectionList = 0;
c->callFunction = callFunction;
QObjectPrivate::get(s)->addConnection(signal_index, c.data());
@@ -3378,47 +3401,38 @@ bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
\internal
Helper function to remove the connection from the senders list and setting the receivers to 0
*/
-bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
+bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connections, int signalIndex,
const QObject *receiver, int method_index, void **slot,
- QMutex *senderMutex, DisconnectType disconnectType)
+ QBasicMutex *senderMutex, DisconnectType disconnectType)
{
bool success = false;
+
+ auto &connectionList = connections->connectionsForSignal(signalIndex);
+ auto *c = connectionList.first.load();
while (c) {
- if (c->receiver
- && (receiver == 0 || (c->receiver == receiver
+ QObject *r = c->receiver.load();
+ if (r && (receiver == nullptr || (r == receiver
&& (method_index < 0 || (!c->isSlotObject && c->method() == method_index))
- && (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) {
+ && (slot == nullptr || (c->isSlotObject && c->slotObj->compare(slot)))))) {
bool needToUnlock = false;
- QMutex *receiverMutex = 0;
- if (c->receiver) {
- receiverMutex = signalSlotLock(c->receiver);
+ QBasicMutex *receiverMutex = nullptr;
+ if (r) {
+ receiverMutex = signalSlotLock(r);
// need to relock this receiver and sender in the correct order
needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
}
- if (c->receiver) {
- *c->prev = c->next;
- if (c->next)
- c->next->prev = c->prev;
- }
+ if (c->receiver.load())
+ connections->removeConnection(c);
if (needToUnlock)
receiverMutex->unlock();
- c->receiver = 0;
-
- if (c->isSlotObject) {
- c->isSlotObject = false;
- senderMutex->unlock();
- c->slotObj->destroyIfLastRef();
- senderMutex->lock();
- }
-
success = true;
if (disconnectType == DisconnectOne)
return success;
}
- c = c->nextConnectionList;
+ c = c->nextConnectionList.load();
}
return success;
}
@@ -3437,43 +3451,34 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender,
QObject *s = const_cast<QObject *>(sender);
- QMutex *senderMutex = signalSlotLock(sender);
- QMutexLocker locker(senderMutex);
+ QBasicMutex *senderMutex = signalSlotLock(sender);
+ QBasicMutexLocker locker(senderMutex);
- QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
- if (!connectionLists)
+ QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load();
+ if (!scd)
return false;
- // prevent incoming connections changing the connectionLists while unlocked
- ++connectionLists->inUse;
-
bool success = false;
- if (signal_index < 0) {
- // remove from all connection lists
- for (int sig_index = -1; sig_index < connectionLists->count(); ++sig_index) {
- QObjectPrivate::Connection *c =
- (*connectionLists)[sig_index].first;
- if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
- success = true;
- connectionLists->dirty = true;
+ {
+ // prevent incoming connections changing the connections->receivers while unlocked
+ QObjectPrivate::ConnectionDataPointer connections(scd);
+
+ if (signal_index < 0) {
+ // remove from all connection lists
+ for (int sig_index = -1; sig_index < scd->signalVectorCount(); ++sig_index) {
+ if (disconnectHelper(connections.data(), sig_index, receiver, method_index, slot, senderMutex, disconnectType))
+ success = true;
}
- }
- } else if (signal_index < connectionLists->count()) {
- QObjectPrivate::Connection *c =
- (*connectionLists)[signal_index].first;
- if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
- success = true;
- connectionLists->dirty = true;
+ } else if (signal_index < scd->signalVectorCount()) {
+ if (disconnectHelper(connections.data(), signal_index, receiver, method_index, slot, senderMutex, disconnectType))
+ success = true;
}
}
- --connectionLists->inUse;
- Q_ASSERT(connectionLists->inUse >= 0);
- if (connectionLists->orphaned && !connectionLists->inUse)
- delete connectionLists;
-
locker.unlock();
if (success) {
+ scd->cleanOrphanedConnections(s);
+
QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
if (smethod.isValid())
s->disconnectNotify(smethod);
@@ -3589,8 +3594,7 @@ void QMetaObject::connectSlotsByName(QObject *o)
\a signal must be in the signal index range (see QObjectPrivate::signalIndex()).
*/
-static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv,
- QMutexLocker &locker)
+static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
{
const int *argumentTypes = c->argumentTypes.load();
if (!argumentTypes) {
@@ -3620,134 +3624,111 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
for (int n = 1; n < nargs; ++n)
types[n] = argumentTypes[n-1];
- locker.unlock();
for (int n = 1; n < nargs; ++n)
args[n] = QMetaType::create(types[n], argv[n]);
- locker.relock();
-
- if (!c->receiver) {
- locker.unlock();
- // we have been disconnected while the mutex was unlocked
- for (int n = 1; n < nargs; ++n)
- QMetaType::destroy(types[n], args[n]);
- free(types);
- free(args);
- locker.relock();
- return;
- }
+ }
+
+ QBasicMutexLocker locker(signalSlotLock(c->receiver.load()));
+ if (!c->receiver.load()) {
+ // the connection has been disconnected before we got the lock
+ locker.unlock();
+ for (int n = 1; n < nargs; ++n)
+ QMetaType::destroy(types[n], args[n]);
+ free(types);
+ free(args);
+ return;
}
QMetaCallEvent *ev = c->isSlotObject ?
new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
- QCoreApplication::postEvent(c->receiver, ev);
+ QCoreApplication::postEvent(c->receiver.load(), ev);
}
-/*!
- \internal
- */
-void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
- void **argv)
-{
- activate(sender, QMetaObjectPrivate::signalOffset(m), local_signal_index, argv);
-}
-
-/*!
- \internal
- */
-void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_index, void **argv)
+template <bool callbacks_enabled>
+void doActivate(QObject *sender, int signal_index, void **argv)
{
- int signal_index = signalOffset + local_signal_index;
+ QObjectPrivate *sp = QObjectPrivate::get(sender);
- if (sender->d_func()->blockSig)
+ if (sp->blockSig)
return;
- if (sender->d_func()->isDeclarativeSignalConnected(signal_index)
+ if (sp->isDeclarativeSignalConnected(signal_index)
&& QAbstractDeclarativeData::signalEmitted) {
Q_TRACE(QMetaObject_activate_begin_declarative_signal, sender, signal_index);
- QAbstractDeclarativeData::signalEmitted(sender->d_func()->declarativeData, sender,
+ QAbstractDeclarativeData::signalEmitted(sp->declarativeData, sender,
signal_index, argv);
Q_TRACE(QMetaObject_activate_end_declarative_signal, sender, signal_index);
}
- if (!sender->d_func()->isSignalConnected(signal_index, /*checkDeclarative =*/ false)
- && !qt_signal_spy_callback_set.signal_begin_callback
- && !qt_signal_spy_callback_set.signal_end_callback
- && !Q_TRACE_ENABLED(QMetaObject_activate_begin_signal)
- && !Q_TRACE_ENABLED(QMetaObject_activate_end_signal)) {
- // The possible declarative connection is done, and nothing else is connected, so:
- return;
- }
+ const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.load() : nullptr;
void *empty_argv[] = { nullptr };
if (!argv)
argv = empty_argv;
- if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
- qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, argv);
+ if (!sp->maybeSignalConnected(signal_index)) {
+ // The possible declarative connection is done, and nothing else is connected
+ if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr)
+ signal_spy_set->signal_begin_callback(sender, signal_index, argv);
+ Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index);
+ Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
+ if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
+ signal_spy_set->signal_end_callback(sender, signal_index);
+ return;
}
+
+ if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr)
+ signal_spy_set->signal_begin_callback(sender, signal_index, argv);
Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index);
+ bool senderDeleted = false;
{
- QMutexLocker locker(signalSlotLock(sender));
- struct ConnectionListsRef {
- QObjectConnectionListVector *connectionLists;
- ConnectionListsRef(QObjectConnectionListVector *connectionLists) : connectionLists(connectionLists)
- {
- if (connectionLists)
- ++connectionLists->inUse;
- }
- ~ConnectionListsRef()
- {
- if (!connectionLists)
- return;
-
- --connectionLists->inUse;
- Q_ASSERT(connectionLists->inUse >= 0);
- if (connectionLists->orphaned) {
- if (!connectionLists->inUse)
- delete connectionLists;
- }
- }
-
- QObjectConnectionListVector *operator->() const { return connectionLists; }
- };
- ConnectionListsRef connectionLists = sender->d_func()->connectionLists;
- if (!connectionLists.connectionLists) {
- locker.unlock();
- if (qt_signal_spy_callback_set.signal_end_callback != 0)
- qt_signal_spy_callback_set.signal_end_callback(sender, signal_index);
- Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
- return;
- }
+ Q_ASSERT(sp->connections);
+ QObjectPrivate::ConnectionDataPointer connections(sp->connections.load());
+ QObjectPrivate::SignalVector *signalVector = connections->signalVector.load();
const QObjectPrivate::ConnectionList *list;
- if (signal_index < connectionLists->count())
- list = &connectionLists->at(signal_index);
+ if (signal_index < signalVector->count())
+ list = &signalVector->at(signal_index);
else
- list = &connectionLists->allsignals;
+ list = &signalVector->at(-1);
Qt::HANDLE currentThreadId = QThread::currentThreadId();
+ bool inSenderThread = currentThreadId == QObjectPrivate::get(sender)->threadData->threadId.load();
+ // We need to check against the highest connection id to ensure that signals added
+ // during the signal emission are not emitted in this emission.
+ uint highestConnectionId = connections->currentConnectionId.load();
do {
- QObjectPrivate::Connection *c = list->first;
- if (!c) continue;
- // We need to check against last here to ensure that signals added
- // during the signal emission are not emitted in this emission.
- QObjectPrivate::Connection *last = list->last;
+ QObjectPrivate::Connection *c = list->first.load();
+ if (!c)
+ continue;
do {
- if (!c->receiver)
+ QObject * const receiver = c->receiver.load();
+ if (!receiver)
continue;
- QObject * const receiver = c->receiver;
- const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId.load();
+ QThreadData *td = c->receiverThreadData.load();
+ if (!td)
+ continue;
+
+ bool receiverInSameThread;
+ if (inSenderThread) {
+ receiverInSameThread = currentThreadId == td->threadId.load();
+ } else {
+ // need to lock before reading the threadId, because moveToThread() could interfere
+ QMutexLocker lock(signalSlotLock(receiver));
+ receiverInSameThread = currentThreadId == td->threadId.load();
+ }
+
// determine if this connection should be sent immediately or
// put into the event queue
if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
|| (c->connectionType == Qt::QueuedConnection)) {
- queued_activate(sender, signal_index, c, argv, locker);
+ queued_activate(sender, signal_index, c, argv);
continue;
#if QT_CONFIG(thread)
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
@@ -3758,89 +3739,103 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
receiver->metaObject()->className(), receiver);
}
QSemaphore semaphore;
- QMetaCallEvent *ev = c->isSlotObject ?
- new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv, &semaphore) :
- new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv, &semaphore);
- QCoreApplication::postEvent(receiver, ev);
- locker.unlock();
+ {
+ QBasicMutexLocker locker(signalSlotLock(sender));
+ if (!c->receiver)
+ continue;
+ QMetaCallEvent *ev = c->isSlotObject ?
+ new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv, &semaphore) :
+ new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv, &semaphore);
+ QCoreApplication::postEvent(receiver, ev);
+ }
semaphore.acquire();
- locker.relock();
continue;
#endif
}
- QConnectionSenderSwitcher sw;
+ QObjectPrivate::Sender senderData(receiverInSameThread ? receiver : nullptr, sender, signal_index);
- if (receiverInSameThread) {
- sw.switchSender(receiver, sender, signal_index);
- }
if (c->isSlotObject) {
c->slotObj->ref();
QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj);
- locker.unlock();
Q_TRACE(QMetaObject_activate_begin_slot_functor, obj.data());
obj->call(receiver, argv);
Q_TRACE(QMetaObject_activate_end_slot_functor, obj.data());
-
- // Make sure the slot object gets destroyed before the mutex is locked again, as the
- // destructor of the slot object might also lock a mutex from the signalSlotLock() mutex pool,
- // and that would deadlock if the pool happens to return the same mutex.
- obj.reset();
-
- locker.relock();
} else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
//we compare the vtable to make sure we are not in the destructor of the object.
- const int methodIndex = c->method();
const int method_relative = c->method_relative;
const auto callFunction = c->callFunction;
- locker.unlock();
- if (qt_signal_spy_callback_set.slot_begin_callback != 0)
- qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv);
+ const int methodIndex = (Q_HAS_TRACEPOINTS || callbacks_enabled) ? c->method() : 0;
+ if (callbacks_enabled && signal_spy_set->slot_begin_callback != nullptr)
+ signal_spy_set->slot_begin_callback(receiver, methodIndex, argv);
Q_TRACE(QMetaObject_activate_begin_slot, receiver, methodIndex);
callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv);
Q_TRACE(QMetaObject_activate_end_slot, receiver, methodIndex);
- if (qt_signal_spy_callback_set.slot_end_callback != 0)
- qt_signal_spy_callback_set.slot_end_callback(receiver, methodIndex);
- locker.relock();
+ if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr)
+ signal_spy_set->slot_end_callback(receiver, methodIndex);
} else {
const int method = c->method_relative + c->method_offset;
- locker.unlock();
- if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
- qt_signal_spy_callback_set.slot_begin_callback(receiver, method, argv);
+ if (callbacks_enabled && signal_spy_set->slot_begin_callback != nullptr) {
+ signal_spy_set->slot_begin_callback(receiver, method, argv);
}
Q_TRACE(QMetaObject_activate_begin_slot, receiver, method);
- metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv);
+ QMetaObject::metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv);
Q_TRACE(QMetaObject_activate_end_slot, receiver, method);
- if (qt_signal_spy_callback_set.slot_end_callback != 0)
- qt_signal_spy_callback_set.slot_end_callback(receiver, method);
-
- locker.relock();
+ if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr)
+ signal_spy_set->slot_end_callback(receiver, method);
}
+ } while ((c = c->nextConnectionList.load()) != nullptr && c->id <= highestConnectionId);
- if (connectionLists->orphaned)
- break;
- } while (c != last && (c = c->nextConnectionList) != 0);
-
- if (connectionLists->orphaned)
- break;
- } while (list != &connectionLists->allsignals &&
+ } while (list != &signalVector->at(-1) &&
//start over for all signals;
- ((list = &connectionLists->allsignals), true));
+ ((list = &signalVector->at(-1)), true));
+ if (connections->currentConnectionId.load() == 0)
+ senderDeleted = true;
}
+ if (!senderDeleted)
+ sp->connections.load()->cleanOrphanedConnections(sender);
- if (qt_signal_spy_callback_set.signal_end_callback != 0)
- qt_signal_spy_callback_set.signal_end_callback(sender, signal_index);
+ if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
+ signal_spy_set->signal_end_callback(sender, signal_index);
Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
+
+}
+
+/*!
+ \internal
+ */
+void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
+ void **argv)
+{
+ int signal_index = local_signal_index + QMetaObjectPrivate::signalOffset(m);
+
+ if (Q_UNLIKELY(qt_signal_spy_callback_set.load()))
+ doActivate<true>(sender, signal_index, argv);
+ else
+ doActivate<false>(sender, signal_index, argv);
}
/*!
\internal
+ */
+void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_index, void **argv)
+{
+ int signal_index = signalOffset + local_signal_index;
+
+ if (Q_UNLIKELY(qt_signal_spy_callback_set.load()))
+ doActivate<true>(sender, signal_index, argv);
+ else
+ doActivate<false>(sender, signal_index, argv);
+ }
+
+/*!
+ \internal
signal_index comes from indexOfMethod()
*/
void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
@@ -3853,7 +3848,7 @@ void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
/*!
\internal
- Returns the signal index used in the internal connectionLists vector.
+ Returns the signal index used in the internal connections->receivers vector.
It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod
while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots.
@@ -4093,37 +4088,40 @@ void QObject::dumpObjectInfo() const
objectName().isEmpty() ? "unnamed" : objectName().toLocal8Bit().data());
Q_D(const QObject);
- QMutexLocker locker(signalSlotLock(this));
+ QBasicMutexLocker locker(signalSlotLock(this));
// first, look for connections where this object is the sender
qDebug(" SIGNALS OUT");
- if (d->connectionLists) {
- for (int signal_index = 0; signal_index < d->connectionLists->count(); ++signal_index) {
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ if (cd && cd->signalVectorCount()) {
+ QObjectPrivate::SignalVector *signalVector = cd->signalVector.load();
+ for (int signal_index = 0; signal_index < signalVector->count(); ++signal_index) {
+ const QObjectPrivate::Connection *c = signalVector->at(signal_index).first.load();
+ if (!c)
+ continue;
const QMetaMethod signal = QMetaObjectPrivate::signal(metaObject(), signal_index);
qDebug(" signal: %s", signal.methodSignature().constData());
// receivers
- const QObjectPrivate::Connection *c =
- d->connectionLists->at(signal_index).first;
while (c) {
- if (!c->receiver) {
+ if (!c->receiver.load()) {
qDebug(" <Disconnected receiver>");
- c = c->nextConnectionList;
+ c = c->nextConnectionList.load();
continue;
}
if (c->isSlotObject) {
qDebug(" <functor or function pointer>");
- c = c->nextConnectionList;
+ c = c->nextConnectionList.load();
continue;
}
- const QMetaObject *receiverMetaObject = c->receiver->metaObject();
+ const QMetaObject *receiverMetaObject = c->receiver.load()->metaObject();
const QMetaMethod method = receiverMetaObject->method(c->method());
qDebug(" --> %s::%s %s",
receiverMetaObject->className(),
- c->receiver->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver->objectName()),
+ c->receiver.load()->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver.load()->objectName()),
method.methodSignature().constData());
- c = c->nextConnectionList;
+ c = c->nextConnectionList.load();
}
}
} else {
@@ -4133,8 +4131,8 @@ void QObject::dumpObjectInfo() const
// now look for connections where this object is the receiver
qDebug(" SIGNALS IN");
- if (d->senders) {
- for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) {
+ if (cd && cd->senders) {
+ for (QObjectPrivate::Connection *s = cd->senders; s; s = s->next) {
QByteArray slotName = QByteArrayLiteral("<unknown>");
if (!s->isSlotObject) {
const QMetaMethod slot = metaObject()->method(s->method());
@@ -4869,18 +4867,17 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
- if (type & Qt::UniqueConnection && slot) {
- QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
- if (connectionLists && connectionLists->count() > signal_index) {
- const QObjectPrivate::Connection *c2 =
- (*connectionLists)[signal_index].first;
+ if (type & Qt::UniqueConnection && slot && QObjectPrivate::get(s)->connections.load()) {
+ QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(s)->connections.load();
+ if (connections->signalVectorCount() > signal_index) {
+ const QObjectPrivate::Connection *c2 = connections->signalVector.load()->at(signal_index).first.load();
while (c2) {
- if (c2->receiver == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
+ if (c2->receiver.load() == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
}
- c2 = c2->nextConnectionList;
+ c2 = c2->nextConnectionList.load();
}
}
type = static_cast<Qt::ConnectionType>(type ^ Qt::UniqueConnection);
@@ -4889,7 +4886,10 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
c->sender = s;
c->signal_index = signal_index;
- c->receiver = r;
+ QThreadData *td = r->d_func()->threadData;
+ td->ref();
+ c->receiverThreadData.store(td);
+ c->receiver.store(r);
c->slotObj = slotObj;
c->connectionType = type;
c->isSlotObject = true;
@@ -4921,35 +4921,35 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
{
QObjectPrivate::Connection *c = static_cast<QObjectPrivate::Connection *>(connection.d_ptr);
- if (!c || !c->receiver)
+ if (!c)
+ return false;
+ QObject *receiver = c->receiver.load();
+ if (!receiver)
return false;
- QMutex *senderMutex = signalSlotLock(c->sender);
- QMutex *receiverMutex = signalSlotLock(c->receiver);
+ QBasicMutex *senderMutex = signalSlotLock(c->sender);
+ QBasicMutex *receiverMutex = signalSlotLock(receiver);
+ QObjectPrivate::ConnectionData *connections;
{
QOrderedMutexLocker locker(senderMutex, receiverMutex);
- QObjectConnectionListVector *connectionLists = QObjectPrivate::get(c->sender)->connectionLists;
- Q_ASSERT(connectionLists);
- connectionLists->dirty = true;
+ // load receiver once again and recheck to ensure nobody else has removed the connection in the meantime
+ receiver = c->receiver.load();
+ if (!receiver)
+ return false;
- *c->prev = c->next;
- if (c->next)
- c->next->prev = c->prev;
- c->receiver = 0;
+ connections = QObjectPrivate::get(c->sender)->connections.load();
+ Q_ASSERT(connections);
+ connections->removeConnection(c);
}
- // destroy the QSlotObject, if possible
- if (c->isSlotObject) {
- c->slotObj->destroyIfLastRef();
- c->isSlotObject = false;
- }
+ connections->cleanOrphanedConnections(c->sender);
c->sender->disconnectNotify(QMetaObjectPrivate::signal(c->sender->metaObject(),
c->signal_index));
- const_cast<QMetaObject::Connection &>(connection).d_ptr = 0;
+ const_cast<QMetaObject::Connection &>(connection).d_ptr = nullptr;
c->deref(); // has been removed from the QMetaObject::Connection object
return true;
@@ -5131,7 +5131,7 @@ bool QMetaObject::Connection::isConnected_helper() const
Q_ASSERT(d_ptr); // we're only called from operator RestrictedBool() const
QObjectPrivate::Connection *c = static_cast<QObjectPrivate::Connection *>(d_ptr);
- return c->receiver;
+ return c->receiver.load();
}
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index a762e6f529..2fb11ecc64 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
@@ -79,9 +79,9 @@ struct QSignalSpyCallbackSet
EndCallback signal_end_callback,
slot_end_callback;
};
-void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set);
+void Q_CORE_EXPORT qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set);
-extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set;
+extern Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set;
enum { QObjectPrivateVersion = QT_VERSION };
@@ -124,54 +124,199 @@ public:
};
typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
- struct Connection
+ struct Connection;
+ struct SignalVector;
+
+ struct ConnectionOrSignalVector {
+ union {
+ // linked list of orphaned connections that need cleaning up
+ ConnectionOrSignalVector *nextInOrphanList;
+ // linked list of connections connected to slots in this object
+ Connection *next;
+ };
+
+ static SignalVector *asSignalVector(ConnectionOrSignalVector *c) {
+ if (reinterpret_cast<quintptr>(c) & 1)
+ return reinterpret_cast<SignalVector *>(reinterpret_cast<quintptr>(c) & ~quintptr(1u));
+ return nullptr;
+ }
+ static Connection *fromSignalVector(SignalVector *v) {
+ return reinterpret_cast<Connection *>(reinterpret_cast<quintptr>(v) | quintptr(1u));
+ }
+ };
+
+ struct Connection : public ConnectionOrSignalVector
{
+ // linked list of connections connected to slots in this object, next is in base class
+ Connection **prev;
+ // linked list of connections connected to signals in this object
+ QAtomicPointer<Connection> nextConnectionList;
+ Connection *prevConnectionList;
+
QObject *sender;
- QObject *receiver;
+ QAtomicPointer<QObject> receiver;
+ QAtomicPointer<QThreadData> receiverThreadData;
union {
StaticMetaCallFunction callFunction;
QtPrivate::QSlotObjectBase *slotObj;
};
- // The next pointer for the singly-linked ConnectionList
- Connection *nextConnectionList;
- //senders linked list
- Connection *next;
- Connection **prev;
QAtomicPointer<const int> argumentTypes;
QAtomicInt ref_;
+ uint id = 0;
ushort method_offset;
ushort method_relative;
- uint signal_index : 27; // In signal range (see QObjectPrivate::signalIndex())
+ int signal_index : 27; // In signal range (see QObjectPrivate::signalIndex())
ushort connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
ushort isSlotObject : 1;
ushort ownArgumentTypes : 1;
- Connection() : nextConnectionList(nullptr), ref_(2), ownArgumentTypes(true) {
+ Connection() : ref_(2), ownArgumentTypes(true) {
//ref_ is 2 for the use in the internal lists, and for the use in QMetaObject::Connection
}
~Connection();
int method() const { Q_ASSERT(!isSlotObject); return method_offset + method_relative; }
void ref() { ref_.ref(); }
+ void freeSlotObject()
+ {
+ if (isSlotObject) {
+ slotObj->destroyIfLastRef();
+ isSlotObject = false;
+ }
+ }
void deref() {
if (!ref_.deref()) {
- Q_ASSERT(!receiver);
+ Q_ASSERT(!receiver.load());
+ Q_ASSERT(!isSlotObject);
delete this;
}
}
};
// ConnectionList is a singly-linked list
struct ConnectionList {
- ConnectionList() : first(nullptr), last(nullptr) {}
- Connection *first;
- Connection *last;
+ QAtomicPointer<Connection> first;
+ QAtomicPointer<Connection> last;
};
struct Sender
{
+ Sender(QObject *receiver, QObject *sender, int signal)
+ : receiver(receiver), sender(sender), signal(signal)
+ {
+ if (receiver) {
+ ConnectionData *cd = receiver->d_func()->connections.load();
+ previous = cd->currentSender;
+ cd->currentSender = this;
+ }
+ }
+ ~Sender()
+ {
+ if (receiver)
+ receiver->d_func()->connections.load()->currentSender = previous;
+ }
+ void receiverDeleted()
+ {
+ Sender *s = this;
+ while (s) {
+ s->receiver = nullptr;
+ s = s->previous;
+ }
+ }
+ Sender *previous;
+ QObject *receiver;
QObject *sender;
int signal;
- int ref;
};
+ struct SignalVector : public ConnectionOrSignalVector {
+ quintptr allocated;
+ // ConnectionList signals[]
+ ConnectionList &at(int i)
+ {
+ return reinterpret_cast<ConnectionList *>(this + 1)[i + 1];
+ }
+ const ConnectionList &at(int i) const
+ {
+ return reinterpret_cast<const ConnectionList *>(this + 1)[i + 1];
+ }
+ int count() { return static_cast<int>(allocated); }
+ };
+
+
+
+ /*
+ This contains the all connections from and to an object.
+
+ The signalVector contains the lists of connections for a given signal. The index in the vector correspond
+ to the signal index. The signal index is the one returned by QObjectPrivate::signalIndex (not
+ QMetaObject::indexOfSignal). allsignals contains a list of special connections that will get invoked on
+ any signal emission. This is done by connecting to signal index -1.
+
+ This vector is protected by the object mutex (signalSlotLock())
+
+ Each Connection is also part of a 'senders' linked list. This one contains all connections connected
+ to a slot in this object. The mutex of the receiver must be locked when touching the pointers of this
+ linked list.
+ */
+ struct ConnectionData {
+ // the id below is used to avoid activating new connections. When the object gets
+ // deleted it's set to 0, so that signal emission stops
+ QAtomicInteger<uint> currentConnectionId;
+ QAtomicInt ref;
+ QAtomicPointer<SignalVector> signalVector;
+ Connection *senders = nullptr;
+ Sender *currentSender = nullptr; // object currently activating the object
+ QAtomicPointer<Connection> orphaned;
+
+ ~ConnectionData()
+ {
+ deleteOrphaned(orphaned.load());
+ SignalVector *v = signalVector.load();
+ if (v)
+ free(v);
+ }
+
+ // must be called on the senders connection data
+ // assumes the senders and receivers lock are held
+ void removeConnection(Connection *c);
+ void cleanOrphanedConnections(QObject *sender)
+ {
+ if (orphaned.load() && ref == 1)
+ cleanOrphanedConnectionsImpl(sender);
+ }
+ void cleanOrphanedConnectionsImpl(QObject *sender);
+
+ ConnectionList &connectionsForSignal(int signal)
+ {
+ return signalVector.load()->at(signal);
+ }
+
+ void resizeSignalVector(uint size) {
+ SignalVector *vector = this->signalVector.load();
+ if (vector && vector->allocated > size)
+ return;
+ size = (size + 7) & ~7;
+ SignalVector *newVector = reinterpret_cast<SignalVector *>(malloc(sizeof(SignalVector) + (size + 1) * sizeof(ConnectionList)));
+ int start = -1;
+ if (vector) {
+ memcpy(newVector, vector, sizeof(SignalVector) + (vector->allocated + 1) * sizeof(ConnectionList));
+ start = vector->count();
+ }
+ for (int i = start; i < int(size); ++i)
+ newVector->at(i) = ConnectionList();
+ newVector->next = nullptr;
+ newVector->allocated = size;
+
+ signalVector.store(newVector);
+ if (vector) {
+ vector->nextInOrphanList = orphaned.load();
+ orphaned.store(ConnectionOrSignalVector::fromSignalVector(vector));
+ }
+ }
+ int signalVectorCount() const {
+ return signalVector ? signalVector.load()->count() : -1;
+ }
+
+ static void deleteOrphaned(ConnectionOrSignalVector *c);
+ };
QObjectPrivate(int version = QObjectPrivateVersion);
virtual ~QObjectPrivate();
@@ -187,13 +332,6 @@ public:
QObjectList senderList() const;
void addConnection(int signal, Connection *c);
- void cleanConnectionLists();
-
- static inline Sender *setCurrentSender(QObject *receiver,
- Sender *sender);
- static inline void resetCurrentSender(QObject *receiver,
- Sender *currentSender,
- Sender *previousSender);
static QObjectPrivate *get(QObject *o) {
return o->d_func();
@@ -201,7 +339,8 @@ public:
static const QObjectPrivate *get(const QObject *o) { return o->d_func(); }
int signalIndex(const char *signalName, const QMetaObject **meta = nullptr) const;
- inline bool isSignalConnected(uint signalIdx, bool checkDeclarative = true) const;
+ bool isSignalConnected(uint signalIdx, bool checkDeclarative = true) const;
+ bool maybeSignalConnected(uint signalIndex) const;
inline bool isDeclarativeSignalConnected(uint signalIdx) const;
// To allow abitrary objects to call connectNotify()/disconnectNotify() without making
@@ -224,15 +363,21 @@ public:
const int *types, const QMetaObject *senderMetaObject);
static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type);
static bool disconnect(const QObject *sender, int signal_index, void **slot);
+
+ void ensureConnectionData()
+ {
+ if (connections.load())
+ return;
+ ConnectionData *cd = new ConnectionData;
+ cd->ref.ref();
+ connections.store(cd);
+ }
public:
ExtraData *extraData; // extra data set by the user
QThreadData *threadData; // id of the thread that owns the object
- QObjectConnectionListVector *connectionLists;
-
- Connection *senders; // linked list of connections connected to this object
- Sender *currentSender; // object currently activating the object
- mutable quint32 connectedSignals[2];
+ using ConnectionDataPointer = QExplicitlySharedDataPointer<ConnectionData>;
+ QAtomicPointer<ConnectionData> connections;
union {
QObject *currentChildBeingDeleted; // should only be used when QObjectData::isDeletingChildren is set
@@ -246,47 +391,12 @@ public:
Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_MOVABLE_TYPE);
-/*! \internal
-
- Returns \c true if the signal with index \a signal_index from object \a sender is connected.
- Signals with indices above a certain range are always considered connected (see connectedSignals
- in QObjectPrivate).
-
- \a signal_index must be the index returned by QObjectPrivate::signalIndex;
-*/
-inline bool QObjectPrivate::isSignalConnected(uint signal_index, bool checkDeclarative) const
-{
- return signal_index >= sizeof(connectedSignals) * 8
- || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f))
- || (checkDeclarative && isDeclarativeSignalConnected(signal_index)));
-}
-
inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
{
return declarativeData && QAbstractDeclarativeData::isSignalConnected
&& QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
}
-inline QObjectPrivate::Sender *QObjectPrivate::setCurrentSender(QObject *receiver,
- Sender *sender)
-{
- Sender *previousSender = receiver->d_func()->currentSender;
- receiver->d_func()->currentSender = sender;
- return previousSender;
-}
-
-inline void QObjectPrivate::resetCurrentSender(QObject *receiver,
- Sender *currentSender,
- Sender *previousSender)
-{
- // ref is set to zero when this object is deleted during the metacall
- if (currentSender->ref == 1)
- receiver->d_func()->currentSender = previousSender;
- // if we've recursed, we need to tell the caller about the objects deletion
- if (previousSender)
- previousSender->ref = currentSender->ref;
-}
-
inline void QObjectPrivate::connectNotify(const QMetaMethod &signal)
{
q_ptr->connectNotify(signal);
@@ -372,7 +482,26 @@ Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE);
class QSemaphore;
-class Q_CORE_EXPORT QMetaCallEvent : public QEvent
+class Q_CORE_EXPORT QAbstractMetaCallEvent : public QEvent
+{
+public:
+ QAbstractMetaCallEvent(const QObject *sender, int signalId, QSemaphore *semaphore = nullptr)
+ : QEvent(MetaCall), signalId_(signalId), sender_(sender), semaphore_(semaphore)
+ {}
+ ~QAbstractMetaCallEvent();
+
+ virtual void placeMetaCall(QObject *object) = 0;
+
+ inline const QObject *sender() const { return sender_; }
+ inline int signalId() const { return signalId_; }
+
+private:
+ int signalId_;
+ const QObject *sender_;
+ QSemaphore *semaphore_;
+};
+
+class Q_CORE_EXPORT QMetaCallEvent : public QAbstractMetaCallEvent
{
public:
QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction , const QObject *sender, int signalId,
@@ -383,23 +512,18 @@ public:
QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
int nargs = 0, int *types = nullptr, void **args = nullptr, QSemaphore *semaphore = nullptr);
- ~QMetaCallEvent();
+ ~QMetaCallEvent() override;
inline int id() const { return method_offset_ + method_relative_; }
- inline const QObject *sender() const { return sender_; }
- inline int signalId() const { return signalId_; }
inline void **args() const { return args_; }
- virtual void placeMetaCall(QObject *object);
+ virtual void placeMetaCall(QObject *object) override;
private:
QtPrivate::QSlotObjectBase *slotObj_;
- const QObject *sender_;
- int signalId_;
int nargs_;
int *types_;
void **args_;
- QSemaphore *semaphore_;
QObjectPrivate::StaticMetaCallFunction callFunction_;
ushort method_offset_;
ushort method_relative_;
diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h
index 95fe0d1083..59802eb6ce 100644
--- a/src/corelib/kernel/qsharedmemory_p.h
+++ b/src/corelib/kernel/qsharedmemory_p.h
@@ -98,7 +98,7 @@ public:
{
if (q_sm && q_sm->lock())
return true;
- q_sm = 0;
+ q_sm = nullptr;
return false;
}
diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp
deleted file mode 100644
index 5437210699..0000000000
--- a/src/corelib/kernel/qtcore_eval.cpp
+++ /dev/null
@@ -1,560 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore 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$
-**
-****************************************************************************/
-
-#include <qcoreevent.h>
-#include <qdatetime.h>
-#include <qlibraryinfo.h>
-#include <qobject.h>
-#include <qcoreapplication.h>
-#include <private/qcoreapplication_p.h>
-
-#include "stdio.h"
-#include "stdlib.h"
-
-QT_BEGIN_NAMESPACE
-
-#include "qconfig_eval.cpp"
-
-static const char boilerplate_supported_but_time_limited[] =
- "\nQt %1 Evaluation License\n"
- "Copyright (C) 2016 The Qt Company Ltd.\n"
- "This trial version may only be used for evaluation purposes\n"
- "and will shut down after 120 minutes.\n"
- "Registered to:\n"
- " Licensee: %2\n\n"
- "The evaluation expires in %4 days\n\n"
- "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n";
-
-static const char boilerplate_supported[] =
- "\nQt %1 Evaluation License\n"
- "Copyright (C) 2016 The Qt Company Ltd.\n"
- "This trial version may only be used for evaluation purposes\n"
- "Registered to:\n"
- " Licensee: %2\n\n"
- "The evaluation expires in %4 days\n\n"
- "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n";
-
-static const char boilerplate_expired[] =
- "This software is using the trial version of the Qt GUI toolkit.\n"
- "The trial period has expired. If you need more time to\n"
- "evaluate Qt, or if you have any questions about Qt, contact us\n"
- "at: http://www.qt.io/contact-us.\n\n";
-
-static const char will_shutdown_1min[] =
- "\nThe evaluation of Qt will SHUT DOWN in 1 minute.\n"
- "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n";
-
-static const char will_shutdown_now[] =
- "\nThe evaluation of Qt has now reached its automatic\n"
- "timeout and will shut down.\n"
- "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n";
-
-enum EvaluationStatus {
- EvaluationNotSupported = 0,
- EvaluationSupportedButTimeLimited,
- EvaluationSupported
-};
-
-static EvaluationStatus qt_eval_is_supported()
-{
- const volatile char *const license_key = qt_eval_key_data + 12;
-
- // fast fail
- if (!qt_eval_key_data[0] || !*license_key)
- return EvaluationNotSupported;
-
- // is this an unsupported evaluation?
- const volatile char *typecode = license_key;
- int field = 2;
- for ( ; field && *typecode; ++typecode)
- if (*typecode == '-')
- --field;
-
- if (!field && typecode[1] == '4' && typecode[2] == 'M') {
- if (typecode[0] == 'Q')
- return EvaluationSupportedButTimeLimited;
- else if (typecode[0] == 'R' || typecode[0] == 'Z')
- return EvaluationSupported;
- }
- return EvaluationNotSupported;
-}
-
-static int qt_eval_days_left()
-{
- const volatile char *const expiry_date = qt_eval_expiry_date + 12;
-
- QDate today = QDate::currentDate();
- QDate lastday = QDate::fromString(
- QString::fromLatin1(const_cast<const char*>(expiry_date)), Qt::ISODate);
- return today.daysTo(lastday);
-}
-
-static bool qt_eval_is_expired()
-{
- return qt_eval_days_left() < 0;
-}
-
-static QString qt_eval_string()
-{
- const char *msg;
- switch (qt_eval_is_supported()) {
- case EvaluationSupportedButTimeLimited:
- msg = boilerplate_supported_but_time_limited;
- break;
- case EvaluationSupported:
- msg = boilerplate_supported;
- break;
- default:
- return QString();
- }
-
- return QString::fromLatin1(msg)
- .arg(QLatin1String(QT_VERSION_STR))
- .arg(QLibraryInfo::licensee())
- .arg(qt_eval_days_left());
-}
-
-#define WARN_TIMEOUT 60 * 1000 * 119
-#define KILL_DELAY 60 * 1000 * 1
-
-class QCoreFuriCuri : public QObject
-{
-public:
-
- int warn;
- int kill;
-
- QCoreFuriCuri() : QObject(), warn(-1), kill(-1)
- {
- if (qt_eval_is_supported() == EvaluationSupportedButTimeLimited) {
- warn = startTimer(WARN_TIMEOUT);
- kill = 0;
- }
- }
-
- void timerEvent(QTimerEvent *e) override {
- if (e->timerId() == warn) {
- killTimer(warn);
- fprintf(stderr, "%s\n", will_shutdown_1min);
- kill = startTimer(KILL_DELAY);
- } else if (e->timerId() == kill) {
- fprintf(stderr, "%s\n", will_shutdown_now);
- QCoreApplication::instance()->quit();
- }
- }
-};
-
-#if defined(QT_BUILD_CORE_LIB) || defined (QT_BOOTSTRAPPED)
-
-void qt_core_eval_init(QCoreApplicationPrivate::Type type)
-{
- if (type != QCoreApplicationPrivate::Tty)
- return;
-
- if (!qt_eval_is_supported())
- return;
-
- if (qt_eval_is_expired()) {
- fprintf(stderr, "%s\n", boilerplate_expired);
- exit(0);
- } else {
- fprintf(stderr, "%s\n", qPrintable(qt_eval_string()));
- Q_UNUSED(new QCoreFuriCuri());
- }
-}
-#endif
-
-#ifdef QT_BUILD_WIDGETS_LIB
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <qdialog.h>
-#include <qlabel.h>
-#include <qlayout.h>
-#include <qmessagebox.h>
-#if QT_CONFIG(pushbutton)
-#include <qpushbutton.h>
-#endif
-#include <qtimer.h>
-#include <qapplication.h>
-QT_END_INCLUDE_NAMESPACE
-
-
-static const char * const qtlogo_eval_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"46 55 174 2",
-" c #002E02",
-". c #00370D",
-"X c #003A0E",
-"o c #003710",
-"O c #013C13",
-"+ c #043E1A",
-"@ c #084F0A",
-"# c #0B520C",
-"$ c #054413",
-"% c #0C4C17",
-"& c #07421D",
-"* c #09451D",
-"= c #0D491E",
-"- c #125515",
-"; c #13541A",
-": c #17591B",
-"> c #1B5C1D",
-", c #1F611F",
-"< c #20621E",
-"1 c #337B1E",
-"2 c #0B4521",
-"3 c #0F4923",
-"4 c #114B24",
-"5 c #154D2A",
-"6 c #175323",
-"7 c #1C5924",
-"8 c #1C532F",
-"9 c #1E5432",
-"0 c #245936",
-"q c #265938",
-"w c #295C3B",
-"e c #246324",
-"r c #266823",
-"t c #2A6C24",
-"y c #276628",
-"u c #2D7026",
-"i c #327427",
-"p c #367927",
-"a c #37782A",
-"s c #397C2A",
-"d c #2E613E",
-"f c #336C37",
-"g c #2F6040",
-"h c #356545",
-"j c #3C6B4E",
-"k c #3F6C51",
-"l c #406E4F",
-"z c #406D52",
-"x c #477457",
-"c c #497557",
-"v c #4B7857",
-"b c #517B5E",
-"n c #3C8423",
-"m c #3E812C",
-"M c #53A61D",
-"N c #41862C",
-"B c #458A2D",
-"V c #498F2D",
-"C c #479324",
-"Z c #489226",
-"A c #4D952C",
-"S c #478B30",
-"D c #488C30",
-"F c #4D9232",
-"G c #509632",
-"H c #549A33",
-"J c #589F35",
-"K c #56A526",
-"L c #57A821",
-"P c #5BAA27",
-"I c #57A32A",
-"U c #5CA72E",
-"Y c #5DAB2A",
-"T c #5CA336",
-"R c #60AD2E",
-"E c #63B12D",
-"W c #65AF35",
-"Q c #62A53F",
-"! c #65AE39",
-"~ c #66B036",
-"^ c #6AB437",
-"/ c #67B138",
-"( c #6AB339",
-") c #6DB838",
-"_ c #70BA3C",
-"` c #4D8545",
-"' c #4E8942",
-"] c #548851",
-"[ c #6FAF4A",
-"{ c #6DB243",
-"} c #71B546",
-"| c #70B840",
-" . c #73B648",
-".. c #79BA4E",
-"X. c #7CBB53",
-"o. c #598266",
-"O. c #62886D",
-"+. c #6A8F75",
-"@. c #6B9173",
-"#. c #70937A",
-"$. c #799F79",
-"%. c #7BAF66",
-"&. c #81BD5B",
-"*. c #85BF60",
-"=. c #85AC7F",
-"-. c #8DBA7B",
-";. c #87C061",
-":. c #8AC364",
-">. c #8DC46A",
-",. c #90C56E",
-"<. c #93C771",
-"1. c #96CA73",
-"2. c #9ACB7C",
-"3. c #9FD07D",
-"4. c #779981",
-"5. c #7F9F89",
-"6. c #809F88",
-"7. c #82A18B",
-"8. c #86A192",
-"9. c #8DA994",
-"0. c #8FA998",
-"q. c #94AF9B",
-"w. c #97B991",
-"e. c #97B19E",
-"r. c #9DB6A3",
-"t. c #A3BCA7",
-"y. c #A6BCAB",
-"u. c #A9BEB1",
-"i. c #9ECD81",
-"p. c #A2CF85",
-"a. c #A5D284",
-"s. c #A6D189",
-"d. c #A9D28E",
-"f. c #ABD491",
-"g. c #B1D797",
-"h. c #B1D699",
-"j. c #B5D89E",
-"k. c #ADC5AC",
-"l. c #B1CAAE",
-"z. c #B9DAA3",
-"x. c #BDDDA8",
-"c. c #ADC1B4",
-"v. c #B2C6B6",
-"b. c #B5C6BC",
-"n. c #B6C9BA",
-"m. c #BCD1BA",
-"M. c #C6E1B4",
-"N. c #CDE5BD",
-"B. c #C2D2C6",
-"V. c #CADEC2",
-"C. c #C6D3CC",
-"Z. c #C8D7CB",
-"A. c #CEDAD2",
-"S. c #D2DDD4",
-"D. c #D3E9C6",
-"F. c #D7EBC9",
-"G. c #D9EBCD",
-"H. c #DEEED4",
-"J. c #D6E0D9",
-"K. c #DAE4DC",
-"L. c #E0EFD7",
-"P. c #E5F2DD",
-"I. c #DFE8E0",
-"U. c #E4EBE5",
-"Y. c #E9EFEA",
-"T. c #EDF4EB",
-"R. c #F0FAE6",
-"E. c #F1F8EC",
-"W. c #EDF0F0",
-"Q. c #F4F7F3",
-"!. c #F6F9F4",
-"~. c #F8FAF7",
-"^. c #FEFEFE",
-"/. c None",
-/* pixels */
-"/././././.c h ' Q / W _ &.p././././././././././././././././././././././././././././././././.",
-"/././.4 O % Z ~ ~ W ~ W R U R R ( X.>.p././././././././././././././././././././././././././.",
-"/./.. * = J _ ~ ~ ~ ~ ~ / / / / W W U P P U W .;.2././././././././././././././././././././.",
-"/.= = & a ) W ~ ~ ~ ~ ~ / W / ~ ~ ~ ^ ( ( ^ ~ R R U P Y ~ .;.2././././././././././././././.",
-"O.O = = T ^ W ~ ~ ~ ~ ~ ~ W W / W ~ ~ ~ ~ ~ ~ ~ ( ( ( ( ~ W Y Y Y Y W { &.1././././././././.",
-"0 = * 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ / / W ~ ~ ~ ~ ~ ~ ~ ~ W W W ~ ~ ~ ~ ( ( ( W W R U P U W { X.1.f./.",
-"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ / / ~ ~ ~ ~ ~ ~ ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ^ ( ( / ~ W R U U Y ",
-"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W ~ ~ ~ ^ ^ ( ",
-"= = * e ^ W ~ ~ ~ ~ ~ ~ / W / W ! ( / ~ W ^ ( ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ~ W W ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ ! ~ ~ ~ ~ ~ ~ W W ^ _ ~ K Y W W R P Y W ( ~ ~ ~ ~ ~ ~ ~ W / ~ ~ ~ ^ W ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ~ ~ ~ ~ W ) W 1 ` w.V.L.H.D.z.,.~ Y ^ ~ ~ ~ ~ ~ W ~ ~ ~ ( ~ W W ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ~ ~ ~ W ) V = 8.~.^.^.^.^.^.^.^.U.<.Y ~ ~ ~ ~ ~ W W ! ~ Y W ^ W ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ~ ~ W ^ B O u.^.~.^.^.^.^.~.~.^.^.^.h.Y ^ ~ ~ ^ F $ k.R.G.1.Y / ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ ~ ~ ~ / W ( J X 7.^.~.^.^.^.^.^.^.^.^.^.^.^.s.Y / W ) a 2 U.^.^.d.U ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W / ~ ~ ~ ^ > w ~.^.^.^.^.^.F.%.v c.^.^.^.^.~.X.W ~ ^ > h ^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ W ^ H o e.^.^.^.^.^.G.Y E n . y.^.^.^.^.M.Y ( ! $ @.^.~.^.f.U ( / ~ ~ W ~ ~ ",
-"= = & e ^ W ~ W ! ) t 4 U.^.^.^.^.^.>.U ( _ , 9 ~.^.^.^.~...^ A y.^.~.^.s.M W Y ~ ~ ~ ~ ~ ",
-"= 3 & e ^ W ~ ( ^ ( $ c ^.^.^.^.^.E.) ~ ~ ^ S o n.^.^.^.^.=.- l.v.Y.^.^.^.M.:.:.X.~ ~ ~ ~ ~ ",
-"= = & e ^ ! W W ( J X 7.^.^.^.^.^.F.Y ( W ^ T X 6.^.^.~.^.c.. J.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ",
-"= = & r ^ W / W ) B o v.^.~.^.^.^.M.U / ~ ~ ! $ o.^.^.^.^.K.* S.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ",
-"= = & e ^ ! ~ W ) a + S.^.^.^.^.^.z.P ( W ~ ( % z ^.^.^.^.~.f t.U.^.^.^.^.~.^.^.P.~ ~ ~ ~ ~ ",
-"* = & e ^ W ~ W ) t 3 Y.^.^.^.^.^.f.P ( ~ ~ ^ ; h ^.^.^.^.^.:.@ j ^.^.^.^.h.{ X.&.~ ~ ~ ~ ~ ",
-"3 = & e ^ W ~ ~ ^ e 8 Q.^.^.^.^.^.s.P ~ ~ W ^ > 0 ~.^.^.^.^.1.# z ^.^.^.^.d.L W R ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ^ > q ~.^.^.^.^.^.p.U ^ ~ W ) e 9 ~.^.^.^.^.3.# k ^.^.^.^.f.Y ( / ~ ~ ~ ~ ~ ",
-"= = & e ^ W / W ^ > w ~.^.^.^.^.^.i.Y / ~ W ^ e 8 Q.^.^.^.^.a.# z ^.^.^.^.f.Y / ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W / W ^ > w ^.^.^.^.^.^.2.Y / ~ ~ ) e 8 Q.^.^.^.^.s.# z ^.^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W W W ^ > q ^.^.^.^.^.^.p.Y / ~ ~ ^ e 9 Q.^.^.^.^.a.@ z ^.^.^.^.f.U / ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W / W ) 7 9 Q.^.^.^.^.^.a.P / ~ W ) , 9 Q.^.^.^.^.3.# z ^.^.~.^.f.P ^ ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W / W ) r 5 T.^.^.^.^.^.d.Y / ~ W ) > q ~.^.^.^.^.1.# k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ / / W ) i 2 I.^.^.^.^.^.h.P ( ~ W ( > g ^.^.^.^.^.:.# z ^.^.^.^.f.P / ~ ~ ~ ~ ~ ~ ",
-"= = & e ( W / W ) m O Z.^.^.^.^.^.x.P / ~ ~ ( ; j ^.^.^.^.~.&.- k ^.^.~.^.f.P / ~ ~ ~ ~ ~ ~ ",
-"= = & e ( W / W ) F o y.^.~.^.^.^.N.U ( ~ ~ W $ b ^.^.^.^.R._ - k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ^ J X 4.^.^.^.^.^.L.~ ~ W ^ T X #.^.^.^.^.F.~ ; j ^.^.^.^.f.U ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ ~ ~ ~ / ^ % l ^.^.^.^.^.!. .R ^ ^ G . r.^.~.^.^.j.E : j ^.^.^.^.f.P ) ( ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ W ) u = U.^.^.^.^.^.1.Y ! ) a & K.^.^.^.^.;.~ : j ^.^.~.^.z.M I I / ~ ~ W ~ ",
-"= = & e ( W ~ ~ W ( G . q.^.^.^.^.^.D.U ^ ! X o.^.^.^.^.P.~ ^ > g ^.^.^.^.E.-.$.m.X.W ~ ~ ~ ",
-"= = & e ^ / ~ ~ ^ ! ( > w ~.^.^.^.^.^.h.T > j T.^.^.~.^.a.Y _ i 3 U.^.^.^.^.^.^.^.X.R ~ ~ ~ ",
-"= = & e ^ / ~ ~ W W ^ H . 9.^.~.^.^.^.^.K.C.~.^.^.^.^.H.W W ^ T . q.^.~.^.^.^.^.^.X.R ~ ~ ~ ",
-"= = + e ^ W / ~ W W W ) m + B.^.~.^.^.^.^.^.^.^.^.^.E.X.Y ( W ^ B 6 y.^.^.^.E.D.2.( ~ ~ ~ ~ ",
-"= = * e ^ ! / ! W ^ W W ) a 4 b.^.^.^.^.^.^.^.^.^.P...Y ( ! W ! ^ W Z [ *.X.{ Y U ~ ~ ~ ~ ~ ",
-"= = & e ( W ~ ~ W / W / W ) A < +.A.~.^.^.^.^.!.p.W R ~ ~ ~ ~ ~ W / ) E U W W / ^ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ / W / / / W ( _ Z X 6.^.^.^.^.E.W ~ ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ / ~ ~ ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ ~ ~ ~ W W / W ~ ~ ~ ~ ) ; h ^.^.^.^.^.d.M U ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ",
-"= = & e ^ W ~ ~ ^ W W / ~ ~ ~ W ) p + S.^.^.^.^.~.M.f. .W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ .",
-"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( T O +.^.~.^.^.^.^.^.&.Y ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( Y 2.",
-"= = & e ( W ~ ~ ~ ~ ~ ~ ~ ~ ~ / W ) N + b.^.^.^.^.^.^.&.R ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W /.",
-"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ^ N 7 r.W.^.^.^.!.X.W ~ ~ W ~ W ~ ~ ~ ~ ~ ~ / ( ( K p./.",
-"= = & e ( W ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W C Q &.:.X.| ~ ~ ~ ~ W ~ / ~ ( / ( ~ W E U P 1././.",
-"= = + e ^ / / / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W / ) ^ R Y W W ~ ~ ( / ( / W R Y Y U R ( X.,././././.",
-"= = * e ( / ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W ! ( ( ( W W E U P Y W ( X.,.d./././././././././.",
-"= = * e ( W ~ ~ ~ ~ W ! ~ W ~ W ~ ( ( / ^ W W U Y P W ( X.,.d./././././././././././././././.",
-"8 $ * e ( W ~ ~ ~ ! ( ( ( / ( W R Y Y Y R ( X.>.d./././././././././././././././././././././.",
-"/.d . y ^ / / / ( W Y Y P P W ( X.>.d./././././././././././././././././././././././././././.",
-"/./.h : ^ R R R W ( X.<.f./././././././././././././././././././././././././././././././././.",
-"/././.] _ *.3./././././././././././././././././././././././././././././././././././././././."
-};
-
-class EvalMessageBox : public QDialog
-{
-public:
- EvalMessageBox(bool expired)
- {
- setWindowTitle(QLatin1String(" "));
-
- QString str = expired ? QLatin1String(boilerplate_expired) : qt_eval_string();
- str = str.trimmed();
-
- QFrame *border = new QFrame(this);
-
- QLabel *pixmap_label = new QLabel(border);
- pixmap_label->setPixmap(QPixmap(qtlogo_eval_xpm));
- pixmap_label->setAlignment(Qt::AlignTop);
-
- QLabel *text_label = new QLabel(str, border);
-
- QHBoxLayout *pm_and_text_layout = new QHBoxLayout();
- pm_and_text_layout->addWidget(pixmap_label);
- pm_and_text_layout->addWidget(text_label);
-
- QVBoxLayout *master_layout = new QVBoxLayout(border);
- master_layout->addLayout(pm_and_text_layout);
-
- QVBoxLayout *border_layout = new QVBoxLayout(this);
- border_layout->setMargin(0);
- border_layout->addWidget(border);
-
- if (expired) {
- QPushButton *cmd = new QPushButton(QLatin1String("OK"), border);
- cmd->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- cmd->setDefault(true);
-
- QHBoxLayout *button_layout = new QHBoxLayout();
- master_layout->addLayout(button_layout);
- button_layout->addWidget(cmd);
-
- connect(cmd, SIGNAL(clicked()), this, SLOT(close()));
- } else {
- border->setFrameShape(QFrame::WinPanel);
- border->setFrameShadow(QFrame::Raised);
- setParent(parentWidget(), Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
- QTimer::singleShot(7000, this, SLOT(close()));
- setAttribute(Qt::WA_DeleteOnClose);
- setAttribute(Qt::WA_QuitOnClose, false);
- }
-
- setFixedSize(sizeHint());
- }
-};
-
-class QGuiFuriCuri : public QCoreFuriCuri
-{
-public:
- void timerEvent(QTimerEvent *e) {
- if (e->timerId() == warn) {
- killTimer(warn);
- QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_1min));
- kill = startTimer(KILL_DELAY);
- } else if (e->timerId() == kill) {
- killTimer(kill);
- QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_now));
- qApp->quit();
- }
- }
-};
-
-
-void qt_gui_eval_init(QCoreApplicationPrivate::Type type)
-{
- Q_UNUSED(type);
-
- if (!qt_eval_is_supported())
- return;
-
- if (qt_eval_is_expired()) {
- EvalMessageBox box(true);
- box.exec();
- ::exit(0);
- } else {
- Q_UNUSED(new QGuiFuriCuri());
- }
-}
-
-static QString qt_eval_title_prefix()
-{
- return QLatin1String("[Qt Evaluation] ");
-}
-
-QString qt_eval_adapt_window_title(const QString &title)
-{
- if (!qt_eval_is_supported())
- return title;
- return qt_eval_title_prefix() + title;
-}
-
-void qt_eval_init_widget(QWidget *w)
-{
- if (!qt_eval_is_supported())
- return;
- if (w->isTopLevel() && w->windowTitle().isEmpty() && w->windowType() != Qt::Desktop ) {
- w->setWindowTitle(QLatin1String(" "));
- }
-}
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 18c7f7648d..77d2c8cbe1 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2018 Intel Corporation.
** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
@@ -1462,6 +1462,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
if (size <= sizeof(QVariant::Private::Data)
&& (type.flags() & (QMetaType::MovableType | QMetaType::IsEnumeration))) {
type.construct(&d->data.ptr, copy);
+ d->is_null = d->data.ptr == nullptr;
d->is_shared = false;
} else {
// Private::Data contains long long, and long double is the biggest standard type.
@@ -1472,6 +1473,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
void *data = operator new(offset + size);
void *ptr = static_cast<char *>(data) + offset;
type.construct(ptr, copy);
+ d->is_null = ptr == nullptr;
d->is_shared = true;
d->data.shared = new (data) QVariant::PrivateShared(ptr);
}
@@ -4002,8 +4004,8 @@ static int numericCompare(const QVariant::Private *d1, const QVariant::Private *
return 0;
// only do fuzzy comparisons for finite, non-zero numbers
- int c1 = std::fpclassify(r1);
- int c2 = std::fpclassify(r2);
+ int c1 = qFpClassify(r1);
+ int c2 = qFpClassify(r2);
if ((c1 == FP_NORMAL || c1 == FP_SUBNORMAL) && (c2 == FP_NORMAL || c2 == FP_SUBNORMAL)) {
if (qFuzzyCompare(r1, r2))
return 0;
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index b22b7c231e..3d87beac83 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -88,7 +88,7 @@ inline T *v_cast(const QVariant::Private *nd, T * = 0)
#else // every other compiler in this world
template <typename T>
-inline const T *v_cast(const QVariant::Private *d, T * = 0)
+inline const T *v_cast(const QVariant::Private *d, T * = nullptr)
{
return !QVariantIntegrator<T>::CanUseInternalSpace
? static_cast<const T *>(d->data.shared->ptr)
@@ -96,7 +96,7 @@ inline const T *v_cast(const QVariant::Private *d, T * = 0)
}
template <typename T>
-inline T *v_cast(QVariant::Private *d, T * = 0)
+inline T *v_cast(QVariant::Private *d, T * = nullptr)
{
return !QVariantIntegrator<T>::CanUseInternalSpace
? static_cast<T *>(d->data.shared->ptr)
@@ -154,7 +154,7 @@ inline void v_construct(QVariant::Private *x, const T &t)
// constructs a new variant if copy is 0, otherwise copy-constructs
template <class T>
-inline void v_construct(QVariant::Private *x, const void *copy, T * = 0)
+inline void v_construct(QVariant::Private *x, const void *copy, T * = nullptr)
{
if (copy)
v_construct<T>(x, *static_cast<const T *>(copy));
@@ -164,7 +164,7 @@ inline void v_construct(QVariant::Private *x, const void *copy, T * = 0)
// deletes the internal structures
template <class T>
-inline void v_clear(QVariant::Private *d, T* = 0)
+inline void v_clear(QVariant::Private *d, T* = nullptr)
{
if (!QVariantIntegrator<T>::CanUseInternalSpace) {
@@ -264,7 +264,7 @@ class QVariantIsNull
struct No { char unused[2]; };
Q_STATIC_ASSERT(sizeof(Yes) != sizeof(No));
- template<class C> static decltype(static_cast<const C*>(0)->isNull(), Yes()) test(int);
+ template<class C> static decltype(static_cast<const C*>(nullptr)->isNull(), Yes()) test(int);
template<class C> static No test(...);
public:
static const bool Value = (sizeof(test<T>(0)) == sizeof(Yes));
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 37c8e3b157..7e2696b719 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -460,6 +460,7 @@ void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
{
#ifdef QT_NO_XMLSTREAMREADER
+ Q_UNUSED(data);
qWarning("Cannot load mime type since QXmlStreamReader is not available.");
return;
#else
diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp
index d10575cfe9..815e0aa03b 100644
--- a/src/corelib/mimetypes/qmimetypeparser.cpp
+++ b/src/corelib/mimetypes/qmimetypeparser.cpp
@@ -194,8 +194,9 @@ static CreateMagicMatchRuleResult createMagicMatchRule(const QXmlStreamAttribute
bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString *errorMessage)
{
#ifdef QT_NO_XMLSTREAMREADER
+ Q_UNUSED(dev);
if (errorMessage)
- *errorMessage = QString::fromLatin1("QXmlStreamReader is not available, cannot parse.");
+ *errorMessage = QString::fromLatin1("QXmlStreamReader is not available, cannot parse '%1'.").arg(fileName);
return false;
#else
QMimeTypePrivate data;
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index 3f650501c8..1a216c98b5 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -96,7 +96,7 @@ public:
void setLoadHints(QLibrary::LoadHints lh);
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString(),
- QLibrary::LoadHints loadHints = 0);
+ QLibrary::LoadHints loadHints = nullptr);
static QStringList suffixes_sys(const QString &fullVersion);
static QStringList prefixes_sys();
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index ead6ed5083..3ea518907b 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -561,6 +561,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_11 Same as Qt_5_6
\value Qt_5_12 Version 18 (Qt 5.12)
\value Qt_5_13 Version 19 (Qt 5.13)
+ \value Qt_5_14 Same as Qt_5_13
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h
index 81134f74b0..6e358df02e 100644
--- a/src/corelib/serialization/qdatastream.h
+++ b/src/corelib/serialization/qdatastream.h
@@ -100,10 +100,11 @@ public:
Qt_5_11 = Qt_5_10,
Qt_5_12 = 18,
Qt_5_13 = 19,
-#if QT_VERSION >= 0x050e00
+ Qt_5_14 = Qt_5_13,
+#if QT_VERSION >= 0x050f00
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_13
+ Qt_DefaultCompiledVersion = Qt_5_14
};
enum ByteOrder {
diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h
index 40b2414e4a..a9e7059cbe 100644
--- a/src/corelib/serialization/qjson_p.h
+++ b/src/corelib/serialization/qjson_p.h
@@ -686,7 +686,7 @@ public:
{
}
inline Data(int reserved, QJsonValue::Type valueType)
- : rawData(0), compactionCounter(0), ownsData(true)
+ : rawData(nullptr), compactionCounter(0), ownsData(true)
{
Q_ASSERT(valueType == QJsonValue::Array || valueType == QJsonValue::Object);
@@ -728,7 +728,7 @@ public:
size = qMax(size + reserve, qMin(size *2, (int)Value::MaxSize));
if (size > Value::MaxSize) {
qWarning("QJson: Document too large to store in data structure");
- return 0;
+ return nullptr;
}
}
char *raw = (char *)malloc(size);
diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp
index c9ba183a50..0d83bb6cd4 100644
--- a/src/corelib/serialization/qtextstream.cpp
+++ b/src/corelib/serialization/qtextstream.cpp
@@ -135,30 +135,30 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
\table
\header \li Manipulator \li Description
- \row \li \c bin \li Same as setIntegerBase(2).
- \row \li \c oct \li Same as setIntegerBase(8).
- \row \li \c dec \li Same as setIntegerBase(10).
- \row \li \c hex \li Same as setIntegerBase(16).
- \row \li \c showbase \li Same as setNumberFlags(numberFlags() | ShowBase).
- \row \li \c forcesign \li Same as setNumberFlags(numberFlags() | ForceSign).
- \row \li \c forcepoint \li Same as setNumberFlags(numberFlags() | ForcePoint).
- \row \li \c noshowbase \li Same as setNumberFlags(numberFlags() & ~ShowBase).
- \row \li \c noforcesign \li Same as setNumberFlags(numberFlags() & ~ForceSign).
- \row \li \c noforcepoint \li Same as setNumberFlags(numberFlags() & ~ForcePoint).
- \row \li \c uppercasebase \li Same as setNumberFlags(numberFlags() | UppercaseBase).
- \row \li \c uppercasedigits \li Same as setNumberFlags(numberFlags() | UppercaseDigits).
- \row \li \c lowercasebase \li Same as setNumberFlags(numberFlags() & ~UppercaseBase).
- \row \li \c lowercasedigits \li Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
- \row \li \c fixed \li Same as setRealNumberNotation(FixedNotation).
- \row \li \c scientific \li Same as setRealNumberNotation(ScientificNotation).
- \row \li \c left \li Same as setFieldAlignment(AlignLeft).
- \row \li \c right \li Same as setFieldAlignment(AlignRight).
- \row \li \c center \li Same as setFieldAlignment(AlignCenter).
- \row \li \c endl \li Same as operator<<('\\n') and flush().
- \row \li \c flush \li Same as flush().
- \row \li \c reset \li Same as reset().
- \row \li \c ws \li Same as skipWhiteSpace().
- \row \li \c bom \li Same as setGenerateByteOrderMark(true).
+ \row \li \c Qt::bin \li Same as setIntegerBase(2).
+ \row \li \c Qt::oct \li Same as setIntegerBase(8).
+ \row \li \c Qt::dec \li Same as setIntegerBase(10).
+ \row \li \c Qt::hex \li Same as setIntegerBase(16).
+ \row \li \c Qt::showbase \li Same as setNumberFlags(numberFlags() | ShowBase).
+ \row \li \c Qt::forcesign \li Same as setNumberFlags(numberFlags() | ForceSign).
+ \row \li \c Qt::forcepoint \li Same as setNumberFlags(numberFlags() | ForcePoint).
+ \row \li \c Qt::noshowbase \li Same as setNumberFlags(numberFlags() & ~ShowBase).
+ \row \li \c Qt::noforcesign \li Same as setNumberFlags(numberFlags() & ~ForceSign).
+ \row \li \c Qt::noforcepoint \li Same as setNumberFlags(numberFlags() & ~ForcePoint).
+ \row \li \c Qt::uppercasebase \li Same as setNumberFlags(numberFlags() | UppercaseBase).
+ \row \li \c Qt::uppercasedigits \li Same as setNumberFlags(numberFlags() | UppercaseDigits).
+ \row \li \c Qt::lowercasebase \li Same as setNumberFlags(numberFlags() & ~UppercaseBase).
+ \row \li \c Qt::lowercasedigits \li Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
+ \row \li \c Qt::fixed \li Same as setRealNumberNotation(FixedNotation).
+ \row \li \c Qt::scientific \li Same as setRealNumberNotation(ScientificNotation).
+ \row \li \c Qt::left \li Same as setFieldAlignment(AlignLeft).
+ \row \li \c Qt::right \li Same as setFieldAlignment(AlignRight).
+ \row \li \c Qt::center \li Same as setFieldAlignment(AlignCenter).
+ \row \li \c Qt::endl \li Same as operator<<('\\n') and flush().
+ \row \li \c Qt::flush \li Same as flush().
+ \row \li \c Qt::reset \li Same as reset().
+ \row \li \c Qt::ws \li Same as skipWhiteSpace().
+ \row \li \c Qt::bom \li Same as setGenerateByteOrderMark(true).
\endtable
In addition, Qt provides three global manipulators that take a
@@ -2689,6 +2689,11 @@ QTextStream &QTextStream::operator<<(const void *ptr)
d->params.numberFlags = oldFlags;
return *this;
}
+#if defined(Q_QDOC) || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+namespace Qt {
+#else
+namespace QTextStreamFunctions {
+#endif
/*!
\relates QTextStream
@@ -3015,6 +3020,8 @@ QTextStream &ws(QTextStream &stream)
return stream;
}
+} // namespace QTextStreamFunctions
+
/*!
\fn QTextStreamManipulator qSetFieldWidth(int width)
\relates QTextStream
@@ -3037,6 +3044,12 @@ QTextStream &ws(QTextStream &stream)
*/
#if QT_CONFIG(textcodec)
+
+#if defined(Q_QDOC) || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+namespace Qt {
+#else
+namespace QTextStreamFunctions {
+#endif
/*!
\relates QTextStream
@@ -3051,6 +3064,8 @@ QTextStream &bom(QTextStream &stream)
return stream;
}
+} // namespace QTextStreamFunctions
+
/*!
Sets the codec for this stream to \a codec. The codec is used for
decoding any data that is read from the assigned device, and for
@@ -3200,6 +3215,43 @@ QLocale QTextStream::locale() const
return d->locale;
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && !defined(Q_QDOC)
+// Binary compatible definitions for Qt<5.14
+Q_CORE_EXPORT QTextStream &bin(QTextStream &s) { return Qt::bin(s); }
+Q_CORE_EXPORT QTextStream &oct(QTextStream &s) { return Qt::oct(s); }
+Q_CORE_EXPORT QTextStream &dec(QTextStream &s) { return Qt::dec(s); }
+Q_CORE_EXPORT QTextStream &hex(QTextStream &s) { return Qt::hex(s); }
+
+Q_CORE_EXPORT QTextStream &showbase(QTextStream &s) { return Qt::showbase(s); }
+Q_CORE_EXPORT QTextStream &forcesign(QTextStream &s) { return Qt::forcesign(s); }
+Q_CORE_EXPORT QTextStream &forcepoint(QTextStream &s) { return Qt::forcepoint(s); }
+Q_CORE_EXPORT QTextStream &noshowbase(QTextStream &s) { return Qt::noshowbase(s); }
+Q_CORE_EXPORT QTextStream &noforcesign(QTextStream &s) { return Qt::noforcesign(s); }
+Q_CORE_EXPORT QTextStream &noforcepoint(QTextStream &s) { return Qt::noforcepoint(s); }
+
+Q_CORE_EXPORT QTextStream &uppercasebase(QTextStream &s) { return Qt::uppercasebase(s); }
+Q_CORE_EXPORT QTextStream &uppercasedigits(QTextStream &s) { return Qt::uppercasedigits(s); }
+Q_CORE_EXPORT QTextStream &lowercasebase(QTextStream &s) { return Qt::lowercasebase(s); }
+Q_CORE_EXPORT QTextStream &lowercasedigits(QTextStream &s) { return Qt::lowercasedigits(s); }
+
+Q_CORE_EXPORT QTextStream &fixed(QTextStream &s) { return Qt::fixed(s); }
+Q_CORE_EXPORT QTextStream &scientific(QTextStream &s) { return Qt::scientific(s); }
+
+Q_CORE_EXPORT QTextStream &left(QTextStream &s) { return Qt::left(s); }
+Q_CORE_EXPORT QTextStream &right(QTextStream &s) { return Qt::right(s); }
+Q_CORE_EXPORT QTextStream &center(QTextStream &s) { return Qt::center(s); }
+
+Q_CORE_EXPORT QTextStream &endl(QTextStream &s) { return Qt::endl(s); }
+Q_CORE_EXPORT QTextStream &flush(QTextStream &s) { return Qt::flush(s); }
+Q_CORE_EXPORT QTextStream &reset(QTextStream &s) { return Qt::reset(s); }
+
+Q_CORE_EXPORT QTextStream &ws(QTextStream &s) { return Qt::ws(s); }
+
+#if QT_CONFIG(textcodec)
+Q_CORE_EXPORT QTextStream &bom(QTextStream &s) { return Qt::bom(s); }
+#endif
+#endif
+
QT_END_NAMESPACE
#ifndef QT_NO_QOBJECT
diff --git a/src/corelib/serialization/qtextstream.h b/src/corelib/serialization/qtextstream.h
index 1d86a18b9c..7673e5d87e 100644
--- a/src/corelib/serialization/qtextstream.h
+++ b/src/corelib/serialization/qtextstream.h
@@ -233,6 +233,13 @@ inline QTextStream &operator<<(QTextStream &s, QTextStreamFunction f)
inline QTextStream &operator<<(QTextStream &s, QTextStreamManipulator m)
{ m.exec(s); return s; }
+#if defined(Q_QDOC) || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+namespace Qt {
+#else
+// This namespace only exists for 'using namespace' declarations.
+namespace QTextStreamFunctions {
+#endif
+
Q_CORE_EXPORT QTextStream &bin(QTextStream &s);
Q_CORE_EXPORT QTextStream &oct(QTextStream &s);
Q_CORE_EXPORT QTextStream &dec(QTextStream &s);
@@ -265,6 +272,18 @@ Q_CORE_EXPORT QTextStream &bom(QTextStream &s);
Q_CORE_EXPORT QTextStream &ws(QTextStream &s);
+} // namespace QTextStreamFunctions
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && !defined(Q_QDOC)
+namespace Qt {
+using namespace QTextStreamFunctions;
+}
+
+// We use 'using namespace' as that doesn't cause
+// conflicting definitions compiler errors.
+using namespace QTextStreamFunctions;
+#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && !defined(Q_QDOC)
+
inline QTextStreamManipulator qSetFieldWidth(int width)
{
QTSMFI func = &QTextStream::setFieldWidth;
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
index 61f501f81b..cde66a48a3 100644
--- a/src/corelib/serialization/qxmlstream_p.h
+++ b/src/corelib/serialization/qxmlstream_p.h
@@ -162,12 +162,12 @@ public:
const char *const QXmlStreamReader_Table::spell [] = {
- "end of file", 0, " ", "<", ">", "&", "#", "\'", "\"", "[",
+ "end of file", nullptr, " ", "<", ">", "&", "#", "\'", "\"", "[",
"]", "(", ")", "|", "=", "%", "/", ":", ";", ",",
"-", "+", "*", ".", "?", "!", "[a-zA-Z]", "[0-9]", "[CDATA[", "DOCTYPE",
"ELEMENT", "ATTLIST", "ENTITY", "NOTATION", "SYSTEM", "PUBLIC", "NDATA", "REQUIRED", "IMPLIED", "FIXED",
- "EMPTY", "ANY", "PCDATA", 0, 0, 0, 0, "CDATA", "ID", "IDREF",
- "IDREFS", "ENTITIES", "NMTOKEN", "NMTOKENS", "<?xml", "version", 0};
+ "EMPTY", "ANY", "PCDATA", nullptr, nullptr, nullptr, nullptr, "CDATA", "ID", "IDREF",
+ "IDREFS", "ENTITIES", "NMTOKEN", "NMTOKENS", "<?xml", "version", nullptr};
const short QXmlStreamReader_Table::lhs [] = {
57, 57, 59, 59, 59, 59, 59, 59, 59, 59,
@@ -645,7 +645,7 @@ template <typename T> class QXmlStreamSimpleStack {
T *data;
int tos, cap;
public:
- inline QXmlStreamSimpleStack():data(0), tos(-1), cap(0){}
+ inline QXmlStreamSimpleStack():data(nullptr), tos(-1), cap(0){}
inline ~QXmlStreamSimpleStack(){ if (data) free(data); }
inline void reserve(int extraCapacity) {
@@ -995,7 +995,7 @@ public:
int fastScanLiteralContent();
int fastScanSpace();
int fastScanContentCharList();
- int fastScanName(int *prefix = 0);
+ int fastScanName(int *prefix = nullptr);
inline int fastScanNMTOKEN();
diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h
index 7fb40392e7..ec746caae1 100644
--- a/src/corelib/statemachine/qstate_p.h
+++ b/src/corelib/statemachine/qstate_p.h
@@ -68,14 +68,14 @@ QT_BEGIN_NAMESPACE
struct QPropertyAssignment
{
QPropertyAssignment()
- : object(0), explicitlySet(true) {}
+ : object(nullptr), explicitlySet(true) {}
QPropertyAssignment(QObject *o, const QByteArray &n,
const QVariant &v, bool es = true)
: object(o), propertyName(n), value(v), explicitlySet(es)
{}
bool objectDeleted() const { return !object; }
- void write() const { Q_ASSERT(object != 0); object->setProperty(propertyName, value); }
+ void write() const { Q_ASSERT(object != nullptr); object->setProperty(propertyName, value); }
bool hasTarget(QObject *o, const QByteArray &pn) const
{ return object == o && propertyName == pn; }
@@ -99,8 +99,8 @@ public:
QStatePrivate();
~QStatePrivate();
- static QStatePrivate *get(QState *q) { return q ? q->d_func() : 0; }
- static const QStatePrivate *get(const QState *q) { return q? q->d_func() : 0; }
+ static QStatePrivate *get(QState *q) { return q ? q->d_func() : nullptr; }
+ static const QStatePrivate *get(const QState *q) { return q? q->d_func() : nullptr; }
QList<QAbstractState*> childStates() const;
QList<QHistoryState*> historyStates() const;
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index f3366ca5f7..c66130b8ce 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -108,7 +108,7 @@ public:
~QStateMachinePrivate();
static QStateMachinePrivate *get(QStateMachine *q)
- { return q ? q->d_func() : 0; }
+ { return q ? q->d_func() : nullptr; }
QState *findLCA(const QList<QAbstractState*> &states, bool onlyCompound = false) const;
QState *findLCCA(const QList<QAbstractState*> &states) const;
@@ -313,7 +313,7 @@ public:
DelayedEvent(QEvent *e, int tid)
: event(e), timerId(tid) {}
DelayedEvent()
- : event(0), timerId(0) {}
+ : event(nullptr), timerId(0) {}
};
QHash<int, DelayedEvent> delayedEvents;
QHash<int, int> timerIdToDelayedEventId;
diff --git a/src/corelib/thread/qatomic_bootstrap.h b/src/corelib/thread/qatomic_bootstrap.h
index b463f817bd..27a67fb2ee 100644
--- a/src/corelib/thread/qatomic_bootstrap.h
+++ b/src/corelib/thread/qatomic_bootstrap.h
@@ -65,7 +65,7 @@ template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
return --_q_value != 0;
}
- static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW
+ static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) Q_DECL_NOTHROW
{
if (currentValue)
*currentValue = _q_value;
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index ded102d32d..5b2c7ab112 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -58,6 +58,8 @@
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(thread)
+
/*
Locks 2 mutexes in a defined order, avoiding a recursive lock if
we're trying to lock the same mutex twice.
@@ -65,9 +67,9 @@ QT_BEGIN_NAMESPACE
class QOrderedMutexLocker
{
public:
- QOrderedMutexLocker(QMutex *m1, QMutex *m2)
- : mtx1((m1 == m2) ? m1 : (std::less<QMutex *>()(m1, m2) ? m1 : m2)),
- mtx2((m1 == m2) ? 0 : (std::less<QMutex *>()(m1, m2) ? m2 : m1)),
+ QOrderedMutexLocker(QBasicMutex *m1, QBasicMutex *m2)
+ : mtx1((m1 == m2) ? m1 : (std::less<QBasicMutex *>()(m1, m2) ? m1 : m2)),
+ mtx2((m1 == m2) ? 0 : (std::less<QBasicMutex *>()(m1, m2) ? m2 : m1)),
locked(false)
{
relock();
@@ -95,12 +97,12 @@ public:
}
}
- static bool relock(QMutex *mtx1, QMutex *mtx2)
+ static bool relock(QBasicMutex *mtx1, QBasicMutex *mtx2)
{
// mtx1 is already locked, mtx2 not... do we need to unlock and relock?
if (mtx1 == mtx2)
return false;
- if (std::less<QMutex *>()(mtx1, mtx2)) {
+ if (std::less<QBasicMutex *>()(mtx1, mtx2)) {
mtx2->lock();
return true;
}
@@ -113,10 +115,58 @@ public:
}
private:
- QMutex *mtx1, *mtx2;
+ QBasicMutex *mtx1, *mtx2;
bool locked;
};
+class QBasicMutexLocker
+{
+public:
+ inline explicit QBasicMutexLocker(QBasicMutex *m) QT_MUTEX_LOCK_NOEXCEPT
+ : m(m), isLocked(true)
+ {
+ m->lock();
+ }
+ inline ~QBasicMutexLocker() { if (isLocked) unlock(); }
+
+ inline void unlock() Q_DECL_NOTHROW
+ {
+ isLocked = false;
+ m->unlock();
+ }
+
+ inline void relock() QT_MUTEX_LOCK_NOEXCEPT
+ {
+ isLocked = true;
+ m->lock();
+ }
+
+private:
+ Q_DISABLE_COPY(QBasicMutexLocker)
+
+ QBasicMutex *m;
+ bool isLocked;
+};
+
+#else
+
+class QOrderedMutexLocker
+{
+public:
+ QOrderedMutexLocker(QBasicMutex *, QBasicMutex *) {}
+ ~QOrderedMutexLocker() {}
+
+ void relock() {}
+ void unlock() {}
+
+ static bool relock(QBasicMutex *, QBasicMutex *) {}
+};
+
+using QBasicMutexLocker = QMutexLocker;
+
+#endif
+
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/thread/qresultstore.h b/src/corelib/thread/qresultstore.h
index 1f29e8d187..7a65089396 100644
--- a/src/corelib/thread/qresultstore.h
+++ b/src/corelib/thread/qresultstore.h
@@ -142,7 +142,7 @@ public:
template <typename T>
int addResult(int index, const T *result)
{
- if (result == 0)
+ if (result == nullptr)
return addResult(index, static_cast<void *>(nullptr));
else
return addResult(index, static_cast<void *>(new T(*result)));
@@ -158,7 +158,7 @@ public:
int addResults(int index, const QVector<T> *results, int totalCount)
{
if (m_filterMode == true && results->count() != totalCount && 0 == results->count())
- return addResults(index, 0, 0, totalCount);
+ return addResults(index, nullptr, 0, totalCount);
else
return addResults(index, new QVector<T>(*results), results->count(), totalCount);
}
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 7d9442ab79..e614ddd004 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -89,7 +89,7 @@ public:
QEvent *event;
int priority;
inline QPostEvent()
- : receiver(0), event(0), priority(0)
+ : receiver(nullptr), event(nullptr), priority(0)
{ }
inline QPostEvent(QObject *r, QEvent *e, int p)
: receiver(r), event(e), priority(p)
@@ -148,7 +148,7 @@ private:
class Q_CORE_EXPORT QDaemonThread : public QThread
{
public:
- QDaemonThread(QObject *parent = 0);
+ QDaemonThread(QObject *parent = nullptr);
~QDaemonThread();
};
@@ -157,7 +157,7 @@ class QThreadPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QThread)
public:
- QThreadPrivate(QThreadData *d = 0);
+ QThreadPrivate(QThreadData *d = nullptr);
~QThreadPrivate();
void setPriority(QThread::Priority prio);
@@ -248,7 +248,7 @@ public:
#endif
static void clearCurrentThreadData();
static QThreadData *get2(QThread *thread)
- { Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; }
+ { Q_ASSERT_X(thread != nullptr, "QThread", "internal error"); return thread->d_func()->data; }
void ref();
@@ -281,7 +281,7 @@ public:
public:
FlaggedDebugSignatures() : idx(0)
- { std::fill_n(locations, Count, static_cast<char*>(0)); }
+ { std::fill_n(locations, Count, static_cast<char*>(nullptr)); }
void store(const char* method)
{ locations[idx++ % Count] = method; }
@@ -328,7 +328,7 @@ class QAdoptedThread : public QThread
Q_DECLARE_PRIVATE(QThread)
public:
- QAdoptedThread(QThreadData *data = 0);
+ QAdoptedThread(QThreadData *data = nullptr);
~QAdoptedThread();
void init();
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index 952e02ef20..01852d8366 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -162,7 +162,7 @@ public:
void tryToStartMoreThreads();
bool tooManyThreadsActive() const;
- void startThread(QRunnable *runnable = 0);
+ void startThread(QRunnable *runnable = nullptr);
void reset();
bool waitForDone(int msecs);
bool waitForDone(const QDeadlineTimer &timer);
diff --git a/src/corelib/thread/qthreadstorage.h b/src/corelib/thread/qthreadstorage.h
index 55fc482da3..9eb8672e92 100644
--- a/src/corelib/thread/qthreadstorage.h
+++ b/src/corelib/thread/qthreadstorage.h
@@ -69,7 +69,7 @@ inline
T *&qThreadStorage_localData(QThreadStorageData &d, T **)
{
void **v = d.get();
- if (!v) v = d.set(0);
+ if (!v) v = d.set(nullptr);
return *(reinterpret_cast<T**>(v));
}
@@ -139,7 +139,7 @@ public:
inline ~QThreadStorage() { }
inline bool hasLocalData() const
- { return d.get() != 0; }
+ { return d.get() != nullptr; }
inline T& localData()
{ return qThreadStorage_localData(d, reinterpret_cast<T*>(0)); }
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 0f27071176..8bf20350d6 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -4136,10 +4136,9 @@ ushort QByteArray::toUShort(bool *ok, int base) const
double QByteArray::toDouble(bool *ok) const
{
- QByteArray nulled = nulTerminated();
bool nonNullOk = false;
int processed = 0;
- double d = qt_asciiToDouble(nulled.constData(), nulled.length(),
+ double d = qt_asciiToDouble(constData(), size(),
nonNullOk, processed, WhitespacesAllowed);
if (ok)
*ok = nonNullOk;
diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h
index 8c0e7860f7..b558a8358d 100644
--- a/src/corelib/tools/qcache.h
+++ b/src/corelib/tools/qcache.h
@@ -51,7 +51,7 @@ class QCache
struct Node {
inline Node() : keyPtr(0) {}
inline Node(T *data, int cost)
- : keyPtr(0), t(data), c(cost), p(0), n(0) {}
+ : keyPtr(nullptr), t(data), c(cost), p(nullptr), n(nullptr) {}
const Key *keyPtr; T *t; int c; Node *p,*n;
};
Node *f, *l;
@@ -71,14 +71,14 @@ class QCache
inline T *relink(const Key &key) {
typename QHash<Key, Node>::iterator i = hash.find(key);
if (typename QHash<Key, Node>::const_iterator(i) == hash.constEnd())
- return 0;
+ return nullptr;
Node &n = *i;
if (f != &n) {
if (n.p) n.p->n = n.n;
if (n.n) n.n->p = n.p;
if (l == &n) l = n.p;
- n.p = 0;
+ n.p = nullptr;
n.n = f;
f->p = &n;
f = &n;
@@ -117,12 +117,12 @@ private:
template <class Key, class T>
inline QCache<Key, T>::QCache(int amaxCost) Q_DECL_NOTHROW
- : f(0), l(0), mx(amaxCost), total(0) {}
+ : f(nullptr), l(nullptr), mx(amaxCost), total(0) {}
template <class Key, class T>
inline void QCache<Key,T>::clear()
{ while (f) { delete f->t; f = f->n; }
- hash.clear(); l = 0; total = 0; }
+ hash.clear(); l = nullptr; total = 0; }
template <class Key, class T>
inline void QCache<Key,T>::setMaxCost(int m)
@@ -153,11 +153,11 @@ inline T *QCache<Key,T>::take(const Key &key)
{
typename QHash<Key, Node>::iterator i = hash.find(key);
if (i == hash.end())
- return 0;
+ return nullptr;
Node &n = *i;
T *t = n.t;
- n.t = 0;
+ n.t = nullptr;
unlink(n);
return t;
}
diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp
index 76dcf35833..d73eb0d07c 100644
--- a/src/corelib/tools/qcollator.cpp
+++ b/src/corelib/tools/qcollator.cpp
@@ -59,20 +59,21 @@ QT_BEGIN_NAMESPACE
\ingroup string-processing
\ingroup shared
- QCollator is initialized with a QLocale and an optional collation strategy. It tries to
- initialize the collator with the specified values. The collator can then be used to compare
- and sort strings in a locale dependent fashion.
+ QCollator is initialized with a QLocale and an optional collation strategy.
+ It tries to initialize the collator with the specified values. The collator
+ can then be used to compare and sort strings in a locale dependent fashion.
- A QCollator object can be used together with template based sorting algorithms such as std::sort
- to sort a list of QStrings.
+ A QCollator object can be used together with template based sorting
+ algorithms such as std::sort to sort a list of QStrings.
- In addition to the locale and collation strategy, several optional flags can be set that influence
- the result of the collation.
+ In addition to the locale and collation strategy, several optional flags can
+ be set that influence the result of the collation.
*/
/*!
- Constructs a QCollator from \a locale. If \a locale is not specified
- the system's default locale is used.
+ Constructs a QCollator for \a locale.
+
+ If \a locale is not specified, the system's default locale is used.
\sa setLocale()
*/
@@ -128,9 +129,9 @@ QCollator &QCollator::operator=(const QCollator &other)
Move constructor. Moves from \a other into this collator.
- Note that a moved-from QCollator can only be destroyed or assigned
- to. The effect of calling other functions than the destructor or
- one of the assignment operators is undefined.
+ Note that a moved-from QCollator can only be destroyed or assigned to.
+ The effect of calling other functions than the destructor or one of the
+ assignment operators is undefined.
*/
/*!
@@ -138,9 +139,9 @@ QCollator &QCollator::operator=(const QCollator &other)
Move-assigns from \a other to this collator.
- Note that a moved-from QCollator can only be destroyed or assigned
- to. The effect of calling other functions than the destructor or
- one of the assignment operators is undefined.
+ Note that a moved-from QCollator can only be destroyed or assigned to.
+ The effect of calling other functions than the destructor or one of the
+ assignment operators is undefined.
*/
/*!
@@ -218,7 +219,8 @@ Qt::CaseSensitivity QCollator::caseSensitivity() const
Enables numeric sorting mode when \a on is set to true.
- This will enable proper sorting of numeric digits, so that e.g. 100 sorts after 99.
+ This will enable proper sorting of numeric digits, so that e.g. 100 sorts
+ after 99.
By default this mode is off.
@@ -248,11 +250,13 @@ bool QCollator::numericMode() const
/*!
\fn void QCollator::setIgnorePunctuation(bool on)
- If \a on is set to true, punctuation characters and symbols are ignored when determining sort order.
+ If \a on is set to true, punctuation characters and symbols are ignored when
+ determining sort order.
The default is locale dependent.
- \note This method is not currently supported if Qt is configured to not use ICU on Linux.
+ \note This method is not currently supported if Qt is configured to not use
+ ICU on Linux.
\sa ignorePunctuation()
*/
@@ -268,7 +272,8 @@ void QCollator::setIgnorePunctuation(bool on)
/*!
\fn bool QCollator::ignorePunctuation() const
- Returns \c true if punctuation characters and symbols are ignored when determining sort order.
+ Returns \c true if punctuation characters and symbols are ignored when
+ determining sort order.
\sa setIgnorePunctuation()
*/
@@ -278,35 +283,66 @@ bool QCollator::ignorePunctuation() const
}
/*!
- \fn int QCollator::compare(const QString &s1, const QString &s2) const
+ \since 5.13
+ \fn bool QCollator::operator()(QStringView s1, QStringView s2) const
+ \internal
+*/
+
+/*!
+ \since 5.13
+ \fn int QCollator::compare(QStringView s1, QStringView s2) const
- Compares \a s1 with \a s2. Returns an integer less than, equal to, or greater than zero
- depending on whether \a s1 is smaller, equal or larger than \a s2.
- */
+ Compares \a s1 with \a s2.
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
+*/
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn bool QCollator::operator()(const QString &s1, const QString &s2) const
\internal
*/
/*!
- \fn int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
\overload
- Compares \a s1 with \a s2. Returns an integer less than, equal to, or greater than zero
- depending on whether \a s1 is smaller, equal or larger than \a s2.
+ Compares \a s1 with \a s2.
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
+*/
+int QCollator::compare(const QString &s1, const QString &s2) const
+{
+ return compare(QStringView(s1), QStringView(s2));
+}
+
+/*!
+ \overload
+
+ Compares \a s1 with \a s2.
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
*/
+int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
+{
+ return compare(QStringView(s1), QStringView(s2));
+}
/*!
- \fn int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
\overload
- Compares \a s1 with \a s2. \a len1 and \a len2 specify the length of the
- QChar arrays pointer to by \a s1 and \a s2.
+ Compares \a s1 with \a s2. \a len1 and \a len2 specify the lengths of the
+ QChar arrays pointed to by \a s1 and \a s2.
- Returns an integer less than, equal to, or greater than zero
- depending on whether \a s1 is smaller, equal or larger than \a s2.
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
*/
+int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+{
+ return compare(QStringView(s1, len1), QStringView(s2, len2));
+}
+#endif // QT_STRINGVIEW_LEVEL < 2
/*!
\fn QCollatorSortKey QCollator::sortKey(const QString &string) const
@@ -314,9 +350,9 @@ bool QCollator::ignorePunctuation() const
Returns a sortKey for \a string.
Creating the sort key is usually somewhat slower, than using the compare()
- methods directly. But if the string is compared repeatedly (e.g. when sorting
- a whole list of strings), it's usually faster to create the sort keys for each
- string and then sort using the keys.
+ methods directly. But if the string is compared repeatedly (e.g. when
+ sorting a whole list of strings), it's usually faster to create the sort
+ keys for each string and then sort using the keys.
\note Not supported with the C (a.k.a. POSIX) locale on Darwin.
*/
@@ -328,8 +364,8 @@ bool QCollator::ignorePunctuation() const
\since 5.2
- The QCollatorSortKey class is always created by QCollator::sortKey()
- and is used for fast strings collation, for example when collating many strings.
+ The QCollatorSortKey class is always created by QCollator::sortKey() and is
+ used for fast strings collation, for example when collating many strings.
\reentrant
\ingroup i18n
@@ -398,9 +434,11 @@ QCollatorSortKey& QCollatorSortKey::operator=(const QCollatorSortKey &other)
/*!
\fn int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
- Compares the key to \a otherKey. Returns a negative value if the key
- is less than \a otherKey, 0 if the key is equal to \a otherKey or a
- positive value if the key is greater than \a otherKey.
+ Compares this key to \a otherKey.
+
+ Returns a negative value if the key is less than \a otherKey, 0 if the key
+ is equal to \a otherKey or a positive value if the key is greater than \a
+ otherKey.
\sa operator<()
*/
diff --git a/src/corelib/tools/qcollator.h b/src/corelib/tools/qcollator.h
index 6fa199cb0f..700de739bb 100644
--- a/src/corelib/tools/qcollator.h
+++ b/src/corelib/tools/qcollator.h
@@ -109,12 +109,18 @@ public:
void setIgnorePunctuation(bool on);
bool ignorePunctuation() const;
+#if QT_STRINGVIEW_LEVEL < 2
int compare(const QString &s1, const QString &s2) const;
int compare(const QStringRef &s1, const QStringRef &s2) const;
int compare(const QChar *s1, int len1, const QChar *s2, int len2) const;
bool operator()(const QString &s1, const QString &s2) const
{ return compare(s1, s2) < 0; }
+#endif
+ int compare(QStringView s1, QStringView s2) const;
+
+ bool operator()(QStringView s1, QStringView s2) const
+ { return compare(s1, s2) < 0; }
QCollatorSortKey sortKey(const QString &string) const;
diff --git a/src/corelib/tools/qcollator_icu.cpp b/src/corelib/tools/qcollator_icu.cpp
index ab45b9a1a1..8acda45070 100644
--- a/src/corelib/tools/qcollator_icu.cpp
+++ b/src/corelib/tools/qcollator_icu.cpp
@@ -78,7 +78,8 @@ void QCollatorPrivate::init()
// and does case sensitive comparison.
// UCOL_QUATERNARY is used as default in a few languages such as Japanese to take care of some
// additional differences in those languages.
- UColAttributeValue val = (caseSensitivity == Qt::CaseSensitive) ? UCOL_DEFAULT_STRENGTH : UCOL_SECONDARY;
+ UColAttributeValue val = (caseSensitivity == Qt::CaseSensitive)
+ ? UCOL_DEFAULT_STRENGTH : UCOL_SECONDARY;
status = U_ZERO_ERROR;
ucol_setAttribute(collator, UCOL_STRENGTH, val, &status);
@@ -91,7 +92,8 @@ void QCollatorPrivate::init()
qWarning("ucol_setAttribute: numeric collation failed: %d", status);
status = U_ZERO_ERROR;
- ucol_setAttribute(collator, UCOL_ALTERNATE_HANDLING, ignorePunctuation ? UCOL_SHIFTED : UCOL_NON_IGNORABLE, &status);
+ ucol_setAttribute(collator, UCOL_ALTERNATE_HANDLING,
+ ignorePunctuation ? UCOL_SHIFTED : UCOL_NON_IGNORABLE, &status);
if (U_FAILURE(status))
qWarning("ucol_setAttribute: Alternate handling failed: %d", status);
@@ -105,37 +107,20 @@ void QCollatorPrivate::cleanup()
collator = nullptr;
}
-int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+int QCollator::compare(QStringView s1, QStringView s2) const
{
if (d->dirty)
d->init();
- if (d->collator)
- return ucol_strcoll(d->collator, (const UChar *)s1, len1, (const UChar *)s2, len2);
-
- return QString::compare_helper(s1, len1, s2, len2, d->caseSensitivity);
-}
-
-int QCollator::compare(const QString &s1, const QString &s2) const
-{
- if (d->dirty)
- d->init();
-
- if (d->collator)
- return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
-
- return QString::compare(s1, s2, d->caseSensitivity);
-}
-
-int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
-{
- if (d->dirty)
- d->init();
-
- if (d->collator)
- return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
+ if (d->collator) {
+ return ucol_strcoll(d->collator,
+ reinterpret_cast<const UChar *>(s1.data()), s1.size(),
+ reinterpret_cast<const UChar *>(s2.data()), s2.size());
+ }
- return QStringRef::compare(s1, s2, d->caseSensitivity);
+ return QString::compare_helper(s1.data(), s1.size(),
+ s2.data(), s2.size(),
+ d->caseSensitivity);
}
QCollatorSortKey QCollator::sortKey(const QString &string) const
diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp
index 42e67e0c12..071d7c048f 100644
--- a/src/corelib/tools/qcollator_macx.cpp
+++ b/src/corelib/tools/qcollator_macx.cpp
@@ -65,12 +65,12 @@ void QCollatorPrivate::init()
return;
LocaleRef localeRef;
- int rc = LocaleRefFromLocaleString(QLocalePrivate::get(locale)->bcp47Name().constData(), &localeRef);
- if (rc != 0)
- qWarning("couldn't initialize the locale");
+ OSStatus status =
+ LocaleRefFromLocaleString(QLocalePrivate::get(locale)->bcp47Name().constData(), &localeRef);
+ if (status != 0)
+ qWarning("Couldn't initialize the locale (%d)", int(status));
UInt32 options = 0;
-
if (caseSensitivity == Qt::CaseInsensitive)
options |= kUCCollateCaseInsensitiveMask;
if (numericMode)
@@ -78,14 +78,9 @@ void QCollatorPrivate::init()
if (!ignorePunctuation)
options |= kUCCollatePunctuationSignificantMask;
- OSStatus status = UCCreateCollator(
- localeRef,
- 0,
- options,
- &collator
- );
+ status = UCCreateCollator(localeRef, 0, options, &collator);
if (status != 0)
- qWarning("Couldn't initialize the collator");
+ qWarning("Couldn't initialize the collator (%d)", int(status));
dirty = false;
}
@@ -97,18 +92,18 @@ void QCollatorPrivate::cleanup()
collator = 0;
}
-int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+int QCollator::compare(QStringView s1, QStringView s2) const
{
if (d->dirty)
d->init();
if (!d->collator)
- return QStringView(s1, len1).compare(QStringView(s2, len2), caseSensitivity());
+ return s1.compare(s2, caseSensitivity());
SInt32 result;
Boolean equivalent;
UCCompareText(d->collator,
- reinterpret_cast<const UniChar *>(s1), len1,
- reinterpret_cast<const UniChar *>(s2), len2,
+ reinterpret_cast<const UniChar *>(s1.data()), s1.size(),
+ reinterpret_cast<const UniChar *>(s2.data()), s2.size(),
&equivalent,
&result);
if (equivalent)
@@ -116,16 +111,6 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con
return result < 0 ? -1 : 1;
}
-int QCollator::compare(const QString &str1, const QString &str2) const
-{
- return compare(str1.constData(), str1.size(), str2.constData(), str2.size());
-}
-
-int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
-{
- return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
-}
-
QCollatorSortKey QCollator::sortKey(const QString &string) const
{
if (d->dirty)
@@ -139,13 +124,14 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
//Documentation recommends having it 5 times as big as the input
QVector<UCCollationValue> ret(string.size() * 5);
ItemCount actualSize;
- int status = UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()), string.count(),
- ret.size(), &actualSize, ret.data());
+ int status = UCGetCollationKey(d->collator,
+ reinterpret_cast<const UniChar *>(string.constData()),
+ string.count(), ret.size(), &actualSize, ret.data());
- ret.resize(actualSize+1);
+ ret.resize(actualSize + 1);
if (status == kUCOutputBufferTooSmall) {
- UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()), string.count(),
- ret.size(), &actualSize, ret.data());
+ UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()),
+ string.count(), ret.size(), &actualSize, ret.data());
}
ret[actualSize] = 0;
return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(ret)));
diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/tools/qcollator_posix.cpp
index 81f97a02e1..9cbc539ebe 100644
--- a/src/corelib/tools/qcollator_posix.cpp
+++ b/src/corelib/tools/qcollator_posix.cpp
@@ -65,7 +65,7 @@ void QCollatorPrivate::cleanup()
{
}
-static void stringToWCharArray(QVarLengthArray<wchar_t> &ret, const QString &string)
+static void stringToWCharArray(QVarLengthArray<wchar_t> &ret, QStringView string)
{
ret.resize(string.length());
int len = string.toWCharArray(ret.data());
@@ -73,12 +73,7 @@ static void stringToWCharArray(QVarLengthArray<wchar_t> &ret, const QString &str
ret[len] = 0;
}
-int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
-{
- return compare(QString::fromRawData(s1, len1), QString::fromRawData(s2, len2));
-}
-
-int QCollator::compare(const QString &s1, const QString &s2) const
+int QCollator::compare(QStringView s1, QStringView s2) const
{
if (d->isC())
return s1.compare(s2, caseSensitivity());
@@ -91,11 +86,6 @@ int QCollator::compare(const QString &s1, const QString &s2) const
return std::wcscoll(array1.constData(), array2.constData());
}
-int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
-{
- return compare(s1.toString(), s2.toString());
-}
-
QCollatorSortKey QCollator::sortKey(const QString &string) const
{
if (d->dirty)
diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp
index 10cfdaa264..9d81de882f 100644
--- a/src/corelib/tools/qcollator_win.cpp
+++ b/src/corelib/tools/qcollator_win.cpp
@@ -87,30 +87,30 @@ void QCollatorPrivate::cleanup()
{
}
-
-int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+int QCollator::compare(QStringView s1, QStringView s2) const
{
if (d->isC())
- return QString::compare_helper(s1, len1, s2, len2, d->caseSensitivity);
+ return s1.compare(s2, d->caseSensitivity);
if (d->dirty)
d->init();
//* from Windows documentation *
- // Returns one of the following values if successful. To maintain the C runtime convention of
- // comparing strings, the value 2 can be subtracted from a nonzero return value. Then, the
- // meaning of <0, ==0, and >0 is consistent with the C runtime.
+ // Returns one of the following values if successful. To maintain the C
+ // runtime convention of comparing strings, the value 2 can be subtracted
+ // from a nonzero return value. Then, the meaning of <0, ==0, and >0 is
+ // consistent with the C runtime.
// [...] The function returns 0 if it does not succeed.
// https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-comparestringex#return-value
#ifndef USE_COMPARESTRINGEX
const int ret = CompareString(d->localeID, d->collator,
- reinterpret_cast<const wchar_t*>(s1), len1,
- reinterpret_cast<const wchar_t*>(s2), len2);
+ reinterpret_cast<const wchar_t *>(s1.data()), s1.size(),
+ reinterpret_cast<const wchar_t *>(s2.data()), s2.size());
#else
const int ret = CompareStringEx(LPCWSTR(d->localeName.utf16()), d->collator,
- reinterpret_cast<LPCWSTR>(s1), len1,
- reinterpret_cast<LPCWSTR>(s2), len2,
+ reinterpret_cast<LPCWSTR>(s1.data()), s1.size(),
+ reinterpret_cast<LPCWSTR>(s2.data()), s2.size(),
nullptr, nullptr, 0);
#endif
if (Q_LIKELY(ret))
@@ -132,16 +132,6 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con
return 0;
}
-int QCollator::compare(const QString &str1, const QString &str2) const
-{
- return compare(str1.constData(), str1.size(), str2.constData(), str2.size());
-}
-
-int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
-{
- return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
-}
-
QCollatorSortKey QCollator::sortKey(const QString &string) const
{
if (d->dirty)
@@ -170,7 +160,9 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
NULL, NULL, 0);
#endif
if (finalSize == 0) {
- qWarning() << "there were problems when generating the ::sortKey by LCMapStringW with error:" << GetLastError();
+ qWarning()
+ << "there were problems when generating the ::sortKey by LCMapStringW with error:"
+ << GetLastError();
}
return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(ret)));
}
diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h
index 4d30d4192b..6e4120d762 100644
--- a/src/corelib/tools/qdatetime_p.h
+++ b/src/corelib/tools/qdatetime_p.h
@@ -135,7 +135,7 @@ public:
#if QT_CONFIG(timezone)
static qint64 zoneMSecsToEpochMSecs(qint64 msecs, const QTimeZone &zone,
DaylightStatus hint = UnknownDaylightTime,
- QDate *localDate = 0, QTime *localTime = 0);
+ QDate *localDate = nullptr, QTime *localTime = nullptr);
// Inlined for its one caller in qdatetime.cpp
inline void setUtcOffsetByTZ(qint64 atMSecsSinceEpoch);
diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h
index f7e6e351fe..e244fed09a 100644
--- a/src/corelib/tools/qdatetimeparser_p.h
+++ b/src/corelib/tools/qdatetimeparser_p.h
@@ -86,7 +86,7 @@ public:
DateTimeEdit
};
QDateTimeParser(QVariant::Type t, Context ctx)
- : currentSectionIndex(-1), display(0), cachedDay(-1), parserType(t),
+ : currentSectionIndex(-1), display(nullptr), cachedDay(-1), parserType(t),
fixday(false), spec(Qt::LocalTime), context(ctx)
{
defaultLocale = QLocale::system();
@@ -218,9 +218,9 @@ private:
ParsedSection parseSection(const QDateTime &currentValue, int sectionIndex,
int offset, QString *text) const;
int findMonth(const QString &str1, int monthstart, int sectionIndex,
- QString *monthName = 0, int *used = 0) const;
+ QString *monthName = nullptr, int *used = nullptr) const;
int findDay(const QString &str1, int intDaystart, int sectionIndex,
- QString *dayName = 0, int *used = 0) const;
+ QString *dayName = nullptr, int *used = nullptr) const;
ParsedSection findTimeZone(QStringRef str, const QDateTime &when,
int maxVal, int minVal) const;
#if QT_CONFIG(timezone)
@@ -236,7 +236,7 @@ private:
PossiblePM = 3,
PossibleBoth = 4
};
- AmPmFinder findAmPm(QString &str, int index, int *used = 0) const;
+ AmPmFinder findAmPm(QString &str, int index, int *used = nullptr) const;
#endif // datestring
bool potentialValue(const QStringRef &str, int min, int max, int index,
diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h
index 63be0952ff..d72d6e1b4b 100644
--- a/src/corelib/tools/qfreelist_p.h
+++ b/src/corelib/tools/qfreelist_p.h
@@ -249,11 +249,11 @@ inline int QFreeList<T, ConstantsType>::next()
if (!v) {
v = allocate((id & ConstantsType::IndexMask) - at, ConstantsType::Sizes[block]);
- if (!_v[block].testAndSetRelease(0, v)) {
+ if (!_v[block].testAndSetRelease(nullptr, v)) {
// race with another thread lost
delete [] v;
v = _v[block].loadAcquire();
- Q_ASSERT(v != 0);
+ Q_ASSERT(v != nullptr);
}
}
diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp
index 949f63ea15..6f3c22a6ec 100644
--- a/src/corelib/tools/qline.cpp
+++ b/src/corelib/tools/qline.cpp
@@ -805,6 +805,7 @@ qreal QLineF::angleTo(const QLineF &l) const
return delta_normalized;
}
+#if QT_DEPRECATED_SINCE(5, 14)
/*!
\fn qreal QLineF::angle(const QLineF &line) const
@@ -837,6 +838,7 @@ qreal QLineF::angle(const QLineF &l) const
if (cos_line >= -1.0 && cos_line <= 1.0) rad = qAcos( cos_line );
return rad * 360 / M_2PI;
}
+#endif
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h
index 6361c1af9f..14980b60a0 100644
--- a/src/corelib/tools/qline.h
+++ b/src/corelib/tools/qline.h
@@ -251,7 +251,10 @@ public:
// ### Qt 6: rename intersects() or intersection() and rename IntersectType IntersectionType
IntersectType intersect(const QLineF &l, QPointF *intersectionPoint) const;
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_X("Use angleTo() instead, take care that the return value is between 0 and 360 degree.")
qreal angle(const QLineF &l) const;
+#endif
Q_DECL_CONSTEXPR inline QPointF pointAt(qreal t) const;
inline void translate(const QPointF &p);
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 6643288bd5..34577acaa5 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -526,7 +526,7 @@ inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
Q_ASSERT_X(isValidIterator(before), "QList::insert", "The specified iterator argument 'before' is invalid");
int iBefore = int(before.i - reinterpret_cast<Node *>(p.begin()));
- Node *n = 0;
+ Node *n = nullptr;
if (d->ref.isShared())
n = detach_helper_grow(iBefore, 1);
else
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 98b6a31a46..1e8dc28fbf 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -249,7 +249,7 @@ public:
if (qIsInf(d))
return float(d);
if (std::fabs(d) > std::numeric_limits<float>::max()) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
const float huge = std::numeric_limits<float>::infinity();
return d < 0 ? -huge : huge;
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
index 94977fc826..1af43d0a68 100644
--- a/src/corelib/tools/qpair.h
+++ b/src/corelib/tools/qpair.h
@@ -97,6 +97,11 @@ struct QPair
T2 second;
};
+#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
+template<class T1, class T2>
+QPair(T1, T2) -> QPair<T1, T2>;
+#endif
+
template <typename T1, typename T2>
void swap(QPair<T1, T2> &lhs, QPair<T1, T2> &rhs) Q_DECL_NOEXCEPT_EXPR(noexcept(lhs.swap(rhs)))
{ lhs.swap(rhs); }
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 87b30c952e..589eb74520 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -58,9 +58,6 @@
QT_BEGIN_NAMESPACE
-int qFindString(const QChar *haystack, int haystackLen, int from,
- const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
-
// error strings for the regexp parser
#define RXERR_OK QT_TRANSLATE_NOOP("QRegExp", "no error occurred")
#define RXERR_DISABLED QT_TRANSLATE_NOOP("QRegExp", "disabled feature used")
@@ -1423,7 +1420,8 @@ void QRegExpMatchState::match(const QChar *str0, int len0, int pos0,
#ifndef QT_NO_REGEXP_OPTIM
if (eng->trivial && !oneTest) {
- pos = qFindString(str0, len0, pos0, eng->goodStr.unicode(), eng->goodStr.length(), eng->cs);
+ // ### Qt6: qsize
+ pos = int(QtPrivate::findString(QStringView(str0, len0), pos0, QStringView(eng->goodStr.unicode(), eng->goodStr.length()), eng->cs));
matchLen = eng->goodStr.length();
matched = (pos != -1);
} else
diff --git a/src/corelib/tools/qscopedvaluerollback.h b/src/corelib/tools/qscopedvaluerollback.h
index 5f76269388..f904b8dfcb 100644
--- a/src/corelib/tools/qscopedvaluerollback.h
+++ b/src/corelib/tools/qscopedvaluerollback.h
@@ -48,20 +48,20 @@ template <typename T>
class QScopedValueRollback
{
public:
- explicit QScopedValueRollback(T &var) :
- varRef(var), oldValue(var)
+ explicit QScopedValueRollback(T &var)
+ : varRef(var), oldValue(var)
{
}
- explicit QScopedValueRollback(T &var, T value) :
- varRef(var), oldValue(var)
+ explicit QScopedValueRollback(T &var, T value)
+ : varRef(var), oldValue(std::move(var))
{
- varRef = qMove(value);
+ varRef = std::move(value);
}
~QScopedValueRollback()
{
- varRef = qMove(oldValue);
+ varRef = std::move(oldValue);
}
void commit()
@@ -70,7 +70,7 @@ public:
}
private:
- T& varRef;
+ T &varRef;
T oldValue;
Q_DISABLE_COPY(QScopedValueRollback)
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 9d6e0cbdd8..65519d1f98 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -2,6 +2,7 @@
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 Intel Corporation.
+** Copyright (C) 2019 Mail.ru Group.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -142,19 +143,11 @@ extern "C" void qt_toLatin1_mips_dsp_asm(uchar *dst, const ushort *src, int leng
#endif
// internal
-int qFindString(const QChar *haystack, int haystackLen, int from,
- const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
-int qFindStringBoyerMoore(const QChar *haystack, int haystackLen, int from,
- const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
-static inline int qt_last_index_of(const QChar *haystack, int haystackLen, QChar needle,
- int from, Qt::CaseSensitivity cs);
-static inline int qt_string_count(const QChar *haystack, int haystackLen,
- const QChar *needle, int needleLen,
- Qt::CaseSensitivity cs);
-static inline int qt_string_count(const QChar *haystack, int haystackLen,
- QChar needle, Qt::CaseSensitivity cs);
-static inline int qt_find_latin1_string(const QChar *hay, int size, QLatin1String needle,
- int from, Qt::CaseSensitivity cs);
+qsizetype qFindStringBoyerMoore(QStringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs);
+static inline qsizetype qt_last_index_of(QStringView haystack, QChar needle, qsizetype from, Qt::CaseSensitivity cs);
+static inline qsizetype qt_string_count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs);
+static inline qsizetype qt_string_count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs);
+
static inline bool qt_starts_with(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs);
static inline bool qt_starts_with(QStringView haystack, QLatin1String needle, Qt::CaseSensitivity cs);
static inline bool qt_starts_with(QStringView haystack, QChar needle, Qt::CaseSensitivity cs);
@@ -1283,42 +1276,9 @@ int QtPrivate::compareStrings(QLatin1String lhs, QLatin1String rhs, Qt::CaseSens
return qt_compare_strings(lhs, rhs, cs);
}
-/*!
- \internal
-
- Returns the index position of the first occurrence of the
- character \a ch in the string given by \a str and \a len,
- searching forward from index
- position \a from. Returns -1 if \a ch could not be found.
-*/
-static int findChar(const QChar *str, int len, QChar ch, int from,
- Qt::CaseSensitivity cs)
-{
- const ushort *s = (const ushort *)str;
- ushort c = ch.unicode();
- if (from < 0)
- from = qMax(from + len, 0);
- if (from < len) {
- const ushort *n = s + from;
- const ushort *e = s + len;
- if (cs == Qt::CaseSensitive) {
- n = QtPrivate::qustrchr(QStringView(n, e), c);
- if (n != e)
- return n - s;
- } else {
- c = foldCase(c);
- --n;
- while (++n != e)
- if (foldCase(*n) == c)
- return n - s;
- }
- }
- return -1;
-}
-
#define REHASH(a) \
- if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \
- hashHaystack -= uint(a) << sl_minus_1; \
+ if (sl_minus_1 < sizeof(std::size_t) * CHAR_BIT) \
+ hashHaystack -= std::size_t(a) << sl_minus_1; \
hashHaystack <<= 1
inline bool qIsUpper(char ch)
@@ -2086,7 +2046,7 @@ int QString::toUcs4_helper(const ushort *uc, int length, uint *out)
\note This function does not append a null character to the array.
- \sa utf16(), toUcs4(), toLatin1(), toUtf8(), toLocal8Bit(), toStdWString()
+ \sa utf16(), toUcs4(), toLatin1(), toUtf8(), toLocal8Bit(), toStdWString(), QStringView::toWCharArray()
*/
/*! \fn QString::QString(const QString &other)
@@ -3735,7 +3695,8 @@ bool QString::operator>(QLatin1String other) const Q_DECL_NOTHROW
*/
int QString::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
{
- return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
+ // ### Qt6: qsize
+ return int(QtPrivate::findString(QStringView(unicode(), length()), from, QStringView(str.unicode(), str.length()), cs));
}
/*!
@@ -3759,85 +3720,8 @@ int QString::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
int QString::indexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
{
- return qt_find_latin1_string(unicode(), size(), str, from, cs);
-}
-
-int qFindString(
- const QChar *haystack0, int haystackLen, int from,
- const QChar *needle0, int needleLen, Qt::CaseSensitivity cs)
-{
- const int l = haystackLen;
- const int sl = needleLen;
- if (from < 0)
- from += l;
- if (uint(sl + from) > (uint)l)
- return -1;
- if (!sl)
- return from;
- if (!l)
- return -1;
-
- if (sl == 1)
- return findChar(haystack0, haystackLen, needle0[0], from, cs);
-
- /*
- We use the Boyer-Moore algorithm in cases where the overhead
- for the skip table should pay off, otherwise we use a simple
- hash function.
- */
- if (l > 500 && sl > 5)
- return qFindStringBoyerMoore(haystack0, haystackLen, from,
- needle0, needleLen, cs);
-
- auto sv = [sl](const ushort *v) { return QStringView(v, sl); };
- /*
- We use some hashing for efficiency's sake. Instead of
- comparing strings, we compare the hash value of str with that
- of a part of this QString. Only if that matches, we call
- qt_string_compare().
- */
- const ushort *needle = (const ushort *)needle0;
- const ushort *haystack = (const ushort *)haystack0 + from;
- const ushort *end = (const ushort *)haystack0 + (l-sl);
- const uint sl_minus_1 = sl - 1;
- uint hashNeedle = 0, hashHaystack = 0;
- int idx;
-
- if (cs == Qt::CaseSensitive) {
- for (idx = 0; idx < sl; ++idx) {
- hashNeedle = ((hashNeedle<<1) + needle[idx]);
- hashHaystack = ((hashHaystack<<1) + haystack[idx]);
- }
- hashHaystack -= haystack[sl_minus_1];
-
- while (haystack <= end) {
- hashHaystack += haystack[sl_minus_1];
- if (hashHaystack == hashNeedle
- && qt_compare_strings(sv(needle), sv(haystack), Qt::CaseSensitive) == 0)
- return haystack - (const ushort *)haystack0;
-
- REHASH(*haystack);
- ++haystack;
- }
- } else {
- const ushort *haystack_start = (const ushort *)haystack0;
- for (idx = 0; idx < sl; ++idx) {
- hashNeedle = (hashNeedle<<1) + foldCase(needle + idx, needle);
- hashHaystack = (hashHaystack<<1) + foldCase(haystack + idx, haystack_start);
- }
- hashHaystack -= foldCase(haystack + sl_minus_1, haystack_start);
-
- while (haystack <= end) {
- hashHaystack += foldCase(haystack + sl_minus_1, haystack_start);
- if (hashHaystack == hashNeedle
- && qt_compare_strings(sv(needle), sv(haystack), Qt::CaseInsensitive) == 0)
- return haystack - (const ushort *)haystack0;
-
- REHASH(foldCase(haystack, haystack_start));
- ++haystack;
- }
- }
- return -1;
+ // ### Qt6: qsize
+ return int(QtPrivate::findString(QStringView(unicode(), size()), from, str, cs));
}
/*!
@@ -3849,7 +3733,8 @@ int qFindString(
*/
int QString::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- return findChar(unicode(), length(), ch, from, cs);
+ // ### Qt6: qsize
+ return int(QtPrivate::findChar(QStringView(unicode(), length()), ch, from, cs));
}
/*!
@@ -3866,7 +3751,8 @@ int QString::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
*/
int QString::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
{
- return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
+ // ### Qt6: qsize
+ return int(QtPrivate::findString(QStringView(unicode(), length()), from, QStringView(str.unicode(), str.length()), cs));
}
static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *needle, int sl, Qt::CaseSensitivity cs)
@@ -3989,7 +3875,8 @@ int QString::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) co
*/
int QString::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- return qt_last_index_of(unicode(), size(), ch, from, cs);
+ // ### Qt6: qsize
+ return int(qt_last_index_of(QStringView(unicode(), size()), ch, from, cs));
}
/*!
@@ -4322,7 +4209,8 @@ QString &QString::replace(const QRegularExpression &re, const QString &after)
int QString::count(const QString &str, Qt::CaseSensitivity cs) const
{
- return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
+ // ### Qt6: qsize
+ return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
/*!
@@ -4338,8 +4226,9 @@ int QString::count(const QString &str, Qt::CaseSensitivity cs) const
int QString::count(QChar ch, Qt::CaseSensitivity cs) const
{
- return qt_string_count(unicode(), size(), ch, cs);
- }
+ // ### Qt6: qsize
+ return int(qt_string_count(QStringView(unicode(), size()), ch, cs));
+}
/*!
\since 4.8
@@ -4354,7 +4243,8 @@ int QString::count(QChar ch, Qt::CaseSensitivity cs) const
*/
int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
{
- return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
+ // ### Qt6: qsize
+ return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
@@ -6831,6 +6721,7 @@ QString QString::toUpper_helper(QString &str)
return QUnicodeTables::convertCase<QUnicodeTables::UppercaseTraits>(str);
}
+#if QT_DEPRECATED_SINCE(5, 14)
/*!
\obsolete
@@ -6844,6 +6735,7 @@ QString &QString::sprintf(const char *cformat, ...)
va_end(ap);
return *this;
}
+#endif
// ### Qt 6: Consider whether this function shouldn't be removed See task 202871.
/*!
@@ -6889,6 +6781,7 @@ QString QString::asprintf(const char *cformat, ...)
return s;
}
+#if QT_DEPRECATED_SINCE(5, 14)
/*!
\obsolete
@@ -6898,6 +6791,7 @@ QString &QString::vsprintf(const char *cformat, va_list ap)
{
return *this = vasprintf(cformat, ap);
}
+#endif
static void append_utf8(QString &qs, const char *cs, int len)
{
@@ -7778,10 +7672,10 @@ static ResultList splitString(const StringSource &source, const QChar *sep,
QString::SplitBehavior behavior, Qt::CaseSensitivity cs, const int separatorSize)
{
ResultList list;
- int start = 0;
- int end;
- int extra = 0;
- while ((end = qFindString(source.constData(), source.size(), start + extra, sep, separatorSize, cs)) != -1) {
+ typename StringSource::size_type start = 0;
+ typename StringSource::size_type end;
+ typename StringSource::size_type extra = 0;
+ while ((end = QtPrivate::findString(QStringView(source.constData(), source.size()), start + extra, QStringView(sep, separatorSize), cs)) != -1) {
if (start != end || behavior == QString::KeepEmptyParts)
list.append(source.mid(start, end - start));
start = end + separatorSize;
@@ -11154,7 +11048,8 @@ QStringRef QString::midRef(int position, int n) const
*/
int QStringRef::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
{
- return qFindString(unicode(), length(), from, str.unicode(), str.length(), cs);
+ // ### Qt6: qsize
+ return int(QtPrivate::findString(QStringView(unicode(), length()), from, QStringView(str.unicode(), str.length()), cs));
}
/*!
@@ -11169,7 +11064,8 @@ int QStringRef::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) co
*/
int QStringRef::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- return findChar(unicode(), length(), ch, from, cs);
+ // ### Qt6: qsize
+ return int(QtPrivate::findChar(QStringView(unicode(), length()), ch, from, cs));
}
/*!
@@ -11189,7 +11085,8 @@ int QStringRef::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
*/
int QStringRef::indexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
{
- return qt_find_latin1_string(unicode(), size(), str, from, cs);
+ // ### Qt6: qsize
+ return int(QtPrivate::findString(QStringView(unicode(), size()), from, str, cs));
}
/*!
@@ -11208,7 +11105,8 @@ int QStringRef::indexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) con
*/
int QStringRef::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
{
- return qFindString(unicode(), size(), from, str.unicode(), str.size(), cs);
+ // ### Qt6: qsize
+ return int(QtPrivate::findString(QStringView(unicode(), size()), from, QStringView(str.unicode(), str.size()), cs));
}
/*!
@@ -11241,7 +11139,8 @@ int QStringRef::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs
*/
int QStringRef::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- return qt_last_index_of(unicode(), size(), ch, from, cs);
+ // ### Qt6: qsize
+ return int(qt_last_index_of(QStringView(unicode(), size()), ch, from, cs));
}
template<typename T>
@@ -11317,7 +11216,8 @@ int QStringRef::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity
*/
int QStringRef::count(const QString &str, Qt::CaseSensitivity cs) const
{
- return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
+ // ### Qt6: qsize
+ return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
/*!
@@ -11334,7 +11234,8 @@ int QStringRef::count(const QString &str, Qt::CaseSensitivity cs) const
*/
int QStringRef::count(QChar ch, Qt::CaseSensitivity cs) const
{
- return qt_string_count(unicode(), size(), ch, cs);
+ // ### Qt6: qsize
+ return int(qt_string_count(QStringView(unicode(), size()), ch, cs));
}
/*!
@@ -11351,7 +11252,8 @@ int QStringRef::count(QChar ch, Qt::CaseSensitivity cs) const
*/
int QStringRef::count(const QStringRef &str, Qt::CaseSensitivity cs) const
{
- return qt_string_count(unicode(), size(), str.unicode(), str.size(), cs);
+ // ### Qt6: qsize
+ return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
/*!
@@ -11588,16 +11490,16 @@ bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
-static inline int qt_last_index_of(const QChar *haystack, int haystackLen, QChar needle,
- int from, Qt::CaseSensitivity cs)
+static inline qsizetype qt_last_index_of(QStringView haystack, QChar needle,
+ qsizetype from, Qt::CaseSensitivity cs)
{
- ushort c = needle.unicode();
if (from < 0)
- from += haystackLen;
- if (uint(from) >= uint(haystackLen))
+ from += haystack.size();
+ if (std::size_t(from) >= std::size_t(haystack.size()))
return -1;
if (from >= 0) {
- const ushort *b = reinterpret_cast<const ushort*>(haystack);
+ ushort c = needle.unicode();
+ const ushort *b = reinterpret_cast<const ushort*>(haystack.data());
const ushort *n = b + from;
if (cs == Qt::CaseSensitive) {
for (; n >= b; --n)
@@ -11615,30 +11517,28 @@ static inline int qt_last_index_of(const QChar *haystack, int haystackLen, QChar
}
-static inline int qt_string_count(const QChar *haystack, int haystackLen,
- const QChar *needle, int needleLen,
- Qt::CaseSensitivity cs)
+static inline qsizetype qt_string_count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs)
{
- int num = 0;
- int i = -1;
- if (haystackLen > 500 && needleLen > 5) {
- QStringMatcher matcher(needle, needleLen, cs);
- while ((i = matcher.indexIn(haystack, haystackLen, i + 1)) != -1)
+ qsizetype num = 0;
+ qsizetype i = -1;
+ if (haystack.size() > 500 && needle.size() > 5) {
+ QStringMatcher matcher(needle, cs);
+ while ((i = matcher.indexIn(haystack, i + 1)) != -1)
++num;
} else {
- while ((i = qFindString(haystack, haystackLen, i + 1, needle, needleLen, cs)) != -1)
+ while ((i = QtPrivate::findString(haystack, i + 1, needle, cs)) != -1)
++num;
}
return num;
}
-static inline int qt_string_count(const QChar *unicode, int size, QChar ch,
+static inline qsizetype qt_string_count(QStringView haystack, QChar ch,
Qt::CaseSensitivity cs)
{
ushort c = ch.unicode();
- int num = 0;
- const ushort *b = reinterpret_cast<const ushort*>(unicode);
- const ushort *i = b + size;
+ qsizetype num = 0;
+ const ushort *b = reinterpret_cast<const ushort*>(haystack.data());
+ const ushort *i = b + haystack.size();
if (cs == Qt::CaseSensitive) {
while (i != b)
if (*--i == c)
@@ -11652,22 +11552,6 @@ static inline int qt_string_count(const QChar *unicode, int size, QChar ch,
return num;
}
-static inline int qt_find_latin1_string(const QChar *haystack, int size,
- QLatin1String needle,
- int from, Qt::CaseSensitivity cs)
-{
- if (size < needle.size())
- return -1;
-
- const char *latin1 = needle.latin1();
- int len = needle.size();
- QVarLengthArray<ushort> s(len);
- qt_from_latin1(s.data(), latin1, len);
-
- return qFindString(haystack, size, from,
- reinterpret_cast<const QChar*>(s.constData()), len, cs);
-}
-
template <typename Haystack, typename Needle>
bool qt_starts_with_impl(Haystack haystack, Needle needle, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{
@@ -11815,6 +11699,127 @@ bool QtPrivate::endsWith(QLatin1String haystack, QLatin1String needle, Qt::CaseS
}
/*!
+ \internal
+
+ Returns the index position of the first occurrence of the
+ character \a ch in the string given by \a str and \a len,
+ searching forward from index
+ position \a from. Returns -1 if \a ch could not be found.
+*/
+
+qsizetype QtPrivate::findChar(QStringView str, QChar ch, qsizetype from, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
+{
+ if (from < 0)
+ from = qMax(from + str.size(), qsizetype(0));
+ if (from < str.size()) {
+ const ushort *s = (const ushort *)str.data();
+ ushort c = ch.unicode();
+ const ushort *n = s + from;
+ const ushort *e = s + str.size();
+ if (cs == Qt::CaseSensitive) {
+ n = QtPrivate::qustrchr(QStringView(n, e), c);
+ if (n != e)
+ return n - s;
+ } else {
+ c = foldCase(c);
+ --n;
+ while (++n != e)
+ if (foldCase(*n) == c)
+ return n - s;
+ }
+ }
+ return -1;
+}
+
+qsizetype QtPrivate::findString(QStringView haystack0, qsizetype from, QStringView needle0, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
+{
+ const qsizetype l = haystack0.size();
+ const qsizetype sl = needle0.size();
+ if (from < 0)
+ from += l;
+ if (std::size_t(sl + from) > std::size_t(l))
+ return -1;
+ if (!sl)
+ return from;
+ if (!l)
+ return -1;
+
+ if (sl == 1)
+ return QtPrivate::findChar(haystack0, needle0[0], from, cs);
+
+ /*
+ We use the Boyer-Moore algorithm in cases where the overhead
+ for the skip table should pay off, otherwise we use a simple
+ hash function.
+ */
+ if (l > 500 && sl > 5)
+ return qFindStringBoyerMoore(haystack0, from, needle0, cs);
+
+ auto sv = [sl](const ushort *v) { return QStringView(v, sl); };
+ /*
+ We use some hashing for efficiency's sake. Instead of
+ comparing strings, we compare the hash value of str with that
+ of a part of this QString. Only if that matches, we call
+ qt_string_compare().
+ */
+ const ushort *needle = (const ushort *)needle0.data();
+ const ushort *haystack = (const ushort *)(haystack0.data()) + from;
+ const ushort *end = (const ushort *)(haystack0.data()) + (l - sl);
+ const std::size_t sl_minus_1 = sl - 1;
+ std::size_t hashNeedle = 0, hashHaystack = 0;
+ qsizetype idx;
+
+ if (cs == Qt::CaseSensitive) {
+ for (idx = 0; idx < sl; ++idx) {
+ hashNeedle = ((hashNeedle<<1) + needle[idx]);
+ hashHaystack = ((hashHaystack<<1) + haystack[idx]);
+ }
+ hashHaystack -= haystack[sl_minus_1];
+
+ while (haystack <= end) {
+ hashHaystack += haystack[sl_minus_1];
+ if (hashHaystack == hashNeedle
+ && qt_compare_strings(needle0, sv(haystack), Qt::CaseSensitive) == 0)
+ return haystack - (const ushort *)haystack0.data();
+
+ REHASH(*haystack);
+ ++haystack;
+ }
+ } else {
+ const ushort *haystack_start = (const ushort *)haystack0.data();
+ for (idx = 0; idx < sl; ++idx) {
+ hashNeedle = (hashNeedle<<1) + foldCase(needle + idx, needle);
+ hashHaystack = (hashHaystack<<1) + foldCase(haystack + idx, haystack_start);
+ }
+ hashHaystack -= foldCase(haystack + sl_minus_1, haystack_start);
+
+ while (haystack <= end) {
+ hashHaystack += foldCase(haystack + sl_minus_1, haystack_start);
+ if (hashHaystack == hashNeedle
+ && qt_compare_strings(needle0, sv(haystack), Qt::CaseInsensitive) == 0)
+ return haystack - (const ushort *)haystack0.data();
+
+ REHASH(foldCase(haystack, haystack_start));
+ ++haystack;
+ }
+ }
+ return -1;
+}
+
+qsizetype QtPrivate::findString(QStringView haystack, qsizetype from, QLatin1String needle, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
+{
+ if (haystack.size() < needle.size())
+ return -1;
+
+ const char *latin1 = needle.latin1();
+ const qsizetype len = needle.size();
+ QVarLengthArray<ushort> s(len);
+ qt_from_latin1(s.data(), latin1, len);
+
+ return QtPrivate::findString(haystack, from, QStringView(reinterpret_cast<const QChar*>(s.constData()), len), cs);
+}
+
+/*!
\since 4.8
Returns a Latin-1 representation of the string as a QByteArray.
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index da76601e88..e9a205dfdf 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -320,8 +320,12 @@ public:
const QString &a4, const QString &a5, const QString &a6,
const QString &a7, const QString &a8, const QString &a9) const;
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_X("Use vasprintf(), arg() or QTextStream instead")
QString &vsprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(2, 0);
+ QT_DEPRECATED_X("Use asprintf(), arg() or QTextStream instead")
QString &sprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+#endif
static QString vasprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(1, 0);
static QString asprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
@@ -1017,12 +1021,7 @@ QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable"
inline int QString::toWCharArray(wchar_t *array) const
{
- if (sizeof(wchar_t) == sizeof(QChar)) {
- memcpy(array, d->data(), sizeof(QChar) * size());
- return size();
- } else {
- return toUcs4_helper(d->data(), size(), reinterpret_cast<uint *>(array));
- }
+ return QStringView(*this).toWCharArray(array);
}
QT_WARNING_POP
@@ -1376,14 +1375,12 @@ inline std::wstring QString::toStdWString() const
{
std::wstring str;
str.resize(length());
-
-#ifdef Q_CC_MSVC
- // VS2005 crashes if the string is empty
- if (!length())
- return str;
+#if __cplusplus >= 201703L
+ str.resize(toWCharArray(str.data()));
+#else
+ if (length())
+ str.resize(toWCharArray(&str.front()));
#endif
-
- str.resize(toWCharArray(&(*str.begin())));
return str;
}
diff --git a/src/corelib/tools/qstringalgorithms.h b/src/corelib/tools/qstringalgorithms.h
index cc0eda71f3..e94f725598 100644
--- a/src/corelib/tools/qstringalgorithms.h
+++ b/src/corelib/tools/qstringalgorithms.h
@@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE
class QByteArray;
class QLatin1String;
class QStringView;
+class QChar;
template <typename T> class QVector;
namespace QtPrivate {
@@ -74,6 +75,10 @@ Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QStringView
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QLatin1String haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QLatin1String haystack, QLatin1String needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findChar(QStringView str, QChar ch, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QStringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QStringView haystack, qsizetype from, QLatin1String needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
+
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QStringView trimmed(QStringView s) Q_DECL_NOTHROW;
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QLatin1String trimmed(QLatin1String s) Q_DECL_NOTHROW;
diff --git a/src/corelib/tools/qstringmatcher.cpp b/src/corelib/tools/qstringmatcher.cpp
index 67d3f0ebc8..417910b6ec 100644
--- a/src/corelib/tools/qstringmatcher.cpp
+++ b/src/corelib/tools/qstringmatcher.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 Mail.ru Group.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -41,43 +42,43 @@
QT_BEGIN_NAMESPACE
-static void bm_init_skiptable(const ushort *uc, int len, uchar *skiptable, Qt::CaseSensitivity cs)
+static void bm_init_skiptable(const ushort *uc, qsizetype len, uchar *skiptable, Qt::CaseSensitivity cs)
{
- int l = qMin(len, 255);
- memset(skiptable, l, 256*sizeof(uchar));
+ int l = int(qMin(len, qsizetype(255)));
+ memset(skiptable, l, 256 * sizeof(uchar));
uc += len - l;
if (cs == Qt::CaseSensitive) {
while (l--) {
skiptable[*uc & 0xff] = l;
- uc++;
+ ++uc;
}
} else {
const ushort *start = uc;
while (l--) {
skiptable[foldCase(uc, start) & 0xff] = l;
- uc++;
+ ++uc;
}
}
}
-static inline int bm_find(const ushort *uc, uint l, int index, const ushort *puc, uint pl,
+static inline qsizetype bm_find(const ushort *uc, qsizetype l, qsizetype index, const ushort *puc, qsizetype pl,
const uchar *skiptable, Qt::CaseSensitivity cs)
{
if (pl == 0)
- return index > (int)l ? -1 : index;
- const uint pl_minus_one = pl - 1;
+ return index > l ? -1 : index;
+ const qsizetype pl_minus_one = pl - 1;
const ushort *current = uc + index + pl_minus_one;
const ushort *end = uc + l;
if (cs == Qt::CaseSensitive) {
while (current < end) {
- uint skip = skiptable[*current & 0xff];
+ qsizetype skip = skiptable[*current & 0xff];
if (!skip) {
// possible match
while (skip < pl) {
if (*(current - skip) != puc[pl_minus_one-skip])
break;
- skip++;
+ ++skip;
}
if (skip > pl_minus_one) // we have a match
return (current - uc) - pl_minus_one;
@@ -95,13 +96,13 @@ static inline int bm_find(const ushort *uc, uint l, int index, const ushort *puc
}
} else {
while (current < end) {
- uint skip = skiptable[foldCase(current, uc) & 0xff];
+ qsizetype skip = skiptable[foldCase(current, uc) & 0xff];
if (!skip) {
// possible match
while (skip < pl) {
if (foldCase(current - skip, uc) != foldCase(puc + pl_minus_one - skip, puc))
break;
- skip++;
+ ++skip;
}
if (skip > pl_minus_one) // we have a match
return (current - uc) - pl_minus_one;
@@ -175,14 +176,27 @@ QStringMatcher::QStringMatcher(const QString &pattern, Qt::CaseSensitivity cs)
by \a uc with the given \a length and case sensitivity specified by \a cs.
*/
QStringMatcher::QStringMatcher(const QChar *uc, int len, Qt::CaseSensitivity cs)
- : d_ptr(0), q_cs(cs)
+ : QStringMatcher(QStringView(uc, len), cs)
{
- p.uc = uc;
- p.len = len;
- bm_init_skiptable((const ushort *)p.uc, len, p.q_skiptable, cs);
}
/*!
+ \fn QStringMatcher::QStringMatcher(QStringView str, Qt::CaseSensitivity cs)
+ \since 5.14
+
+ Constructs a string matcher that will search for \a pattern, with
+ case sensitivity \a cs.
+
+ Call indexIn() to perform a search.
+*/
+QStringMatcher::QStringMatcher(QStringView str, Qt::CaseSensitivity cs)
+ : d_ptr(nullptr), q_cs(cs)
+{
+ p.uc = str.data();
+ p.len = int(str.size());
+ bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs);
+}
+/*!
Copies the \a other string matcher to this string matcher.
*/
QStringMatcher::QStringMatcher(const QStringMatcher &other)
@@ -267,11 +281,7 @@ void QStringMatcher::setCaseSensitivity(Qt::CaseSensitivity cs)
*/
int QStringMatcher::indexIn(const QString &str, int from) const
{
- if (from < 0)
- from = 0;
- return bm_find((const ushort *)str.unicode(), str.size(), from,
- (const ushort *)p.uc, p.len,
- p.q_skiptable, q_cs);
+ return int(indexIn(QStringView(str), from));
}
/*!
@@ -288,9 +298,25 @@ int QStringMatcher::indexIn(const QString &str, int from) const
*/
int QStringMatcher::indexIn(const QChar *str, int length, int from) const
{
+ return int(indexIn(QStringView(str, length), from));
+}
+
+/*!
+ \since 5.14
+
+ Searches the string \a str from character position \a from
+ (default 0, i.e. from the first character), for the string
+ pattern() that was set in the constructor or in the most recent
+ call to setPattern(). Returns the position where the pattern()
+ matched in \a str, or -1 if no match was found.
+
+ \sa setPattern(), setCaseSensitivity()
+*/
+qsizetype QStringMatcher::indexIn(QStringView str, qsizetype from) const
+{
if (from < 0)
from = 0;
- return bm_find((const ushort *)str, length, from,
+ return bm_find((const ushort *)str.data(), str.size(), from,
(const ushort *)p.uc, p.len,
p.q_skiptable, q_cs);
}
@@ -307,16 +333,16 @@ int QStringMatcher::indexIn(const QChar *str, int length, int from) const
\internal
*/
-int qFindStringBoyerMoore(
- const QChar *haystack, int haystackLen, int haystackOffset,
- const QChar *needle, int needleLen, Qt::CaseSensitivity cs)
+qsizetype qFindStringBoyerMoore(
+ QStringView haystack, qsizetype haystackOffset,
+ QStringView needle, Qt::CaseSensitivity cs)
{
uchar skiptable[256];
- bm_init_skiptable((const ushort *)needle, needleLen, skiptable, cs);
+ bm_init_skiptable((const ushort *)needle.data(), needle.size(), skiptable, cs);
if (haystackOffset < 0)
haystackOffset = 0;
- return bm_find((const ushort *)haystack, haystackLen, haystackOffset,
- (const ushort *)needle, needleLen, skiptable, cs);
+ return bm_find((const ushort *)haystack.data(), haystack.size(), haystackOffset,
+ (const ushort *)needle.data(), needle.size(), skiptable, cs);
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstringmatcher.h b/src/corelib/tools/qstringmatcher.h
index 549bff9f29..6de4353930 100644
--- a/src/corelib/tools/qstringmatcher.h
+++ b/src/corelib/tools/qstringmatcher.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 Mail.ru Group.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -41,6 +42,7 @@
#define QSTRINGMATCHER_H
#include <QtCore/qstring.h>
+#include <QtCore/qstringview.h>
QT_BEGIN_NAMESPACE
@@ -55,6 +57,8 @@ public:
Qt::CaseSensitivity cs = Qt::CaseSensitive);
QStringMatcher(const QChar *uc, int len,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ QStringMatcher(QStringView pattern,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive);
QStringMatcher(const QStringMatcher &other);
~QStringMatcher();
@@ -65,6 +69,7 @@ public:
int indexIn(const QString &str, int from = 0) const;
int indexIn(const QChar *str, int length, int from = 0) const;
+ qsizetype indexIn(QStringView str, qsizetype from = 0) const;
QString pattern() const;
inline Qt::CaseSensitivity caseSensitivity() const { return q_cs; }
diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp
index b97e989110..c863ca7ce2 100644
--- a/src/corelib/tools/qstringview.cpp
+++ b/src/corelib/tools/qstringview.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qstringview.h"
+#include "qstring.h"
QT_BEGIN_NAMESPACE
@@ -794,4 +795,34 @@ QT_BEGIN_NAMESPACE
\sa QString::isRightToLeft()
*/
+/*!
+ \since 5.14
+
+ Transcribes this string into the given \a array.
+
+ Caller is responsible for ensuring \a array is large enough to hold the \t
+ wchar_t encoding of this string (allocating the array with the same length
+ as the string is always sufficient). The array is encoded in UTF-16 on
+ platforms where \t wchar_t is 2 bytes wide (e.g. Windows); otherwise (Unix
+ systems), \t wchar_t is assumed to be 4 bytes wide and the data is written
+ in UCS-4.
+
+ \note This function writes no null terminator to the end of \a array.
+
+ Returns the number of \t wchar_t entries written to \a array.
+
+ \sa QString::toWCharArray()
+*/
+
+int QStringView::toWCharArray(wchar_t *array) const
+{
+ if (sizeof(wchar_t) == sizeof(QChar)) {
+ memcpy(array, data(), sizeof(QChar) * size());
+ return size();
+ } else {
+ return QString::toUcs4_helper(reinterpret_cast<const ushort *>(data()), int(size()),
+ reinterpret_cast<uint *>(array));
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h
index 2e95c2b218..4a900b5e89 100644
--- a/src/corelib/tools/qstringview.h
+++ b/src/corelib/tools/qstringview.h
@@ -272,6 +272,8 @@ public:
Q_REQUIRED_RESULT bool isRightToLeft() const Q_DECL_NOTHROW
{ return QtPrivate::isRightToLeft(*this); }
+ Q_REQUIRED_RESULT Q_CORE_EXPORT int toWCharArray(wchar_t *array) const;
+
//
// STL compatibility API:
//
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 988d5a9e1b..9762ec1b5b 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -79,6 +79,7 @@ public:
void swap(QVector<T> &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QVector(std::initializer_list<T> args);
+ QVector<T> &operator=(std::initializer_list<T> args);
#endif
bool operator==(const QVector<T> &v) const;
inline bool operator!=(const QVector<T> &v) const { return !(*this == v); }
@@ -542,10 +543,19 @@ QVector<T>::QVector(std::initializer_list<T> args)
d = Data::sharedNull();
}
}
+
+template <typename T>
+QVector<T> &QVector<T>::operator=(std::initializer_list<T> args)
+{
+ QVector<T> tmp(args);
+ tmp.swap(*this);
+ return *this;
+}
+
# if defined(Q_CC_MSVC)
QT_WARNING_POP
# endif // Q_CC_MSVC
-#endif // Q_COMPILER_INITALIZER_LISTS
+#endif // Q_COMPILER_INITIALIZER_LISTS
template <typename T>
void QVector<T>::freeData(Data *x)
diff --git a/src/corelib/tools/qvector.qdoc b/src/corelib/tools/qvector.qdoc
index 75b17a4207..69bbb5f9a2 100644
--- a/src/corelib/tools/qvector.qdoc
+++ b/src/corelib/tools/qvector.qdoc
@@ -263,6 +263,17 @@
\since 5.2
*/
+/*!
+ \fn template <typename T> QVector<T> &QVector<T>::operator=(std::initializer_list<T> args)
+
+ Assigns the collection of values in \a args to this QVector instance.
+
+ This operator is only enabled if the compiler supports C++11 initializer
+ lists.
+
+ \since 5.14
+*/
+
/*! \fn template <typename T> void QVector<T>::swap(QVector<T> &other)
\since 4.8