summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/animation/qabstractanimation.h8
-rw-r--r--src/corelib/animation/qanimationgroup.h2
-rw-r--r--src/corelib/animation/qparallelanimationgroup.h2
-rw-r--r--src/corelib/animation/qpauseanimation.h4
-rw-r--r--src/corelib/animation/qpropertyanimation.h4
-rw-r--r--src/corelib/animation/qsequentialanimationgroup.h2
-rw-r--r--src/corelib/animation/qsequentialanimationgroup_p.h2
-rw-r--r--src/corelib/animation/qvariantanimation.h4
-rw-r--r--src/corelib/codecs/qtextcodec.cpp1
-rw-r--r--src/corelib/codecs/qtextcodec.h6
-rw-r--r--src/corelib/corelib.pro6
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp10
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp6
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp19
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp19
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp17
-rw-r--r--src/corelib/doc/src/external-resources.qdoc9
-rw-r--r--src/corelib/doc/src/objectmodel/properties.qdoc9
-rw-r--r--src/corelib/global/global.pri4
-rw-r--r--src/corelib/global/qflags.h2
-rw-r--r--src/corelib/global/qglobal.cpp148
-rw-r--r--src/corelib/global/qglobal.h75
-rw-r--r--src/corelib/global/qlogging.cpp32
-rw-r--r--src/corelib/global/qlogging.h3
-rw-r--r--src/corelib/global/qnamespace.h29
-rw-r--r--src/corelib/global/qnamespace.qdoc71
-rw-r--r--src/corelib/global/qsysinfo.h28
-rw-r--r--src/corelib/global/qtypeinfo.h72
-rw-r--r--src/corelib/io/forkfd_qt.cpp7
-rw-r--r--src/corelib/io/qabstractfileengine.cpp1
-rw-r--r--src/corelib/io/qbuffer.h4
-rw-r--r--src/corelib/io/qdatastream.cpp1
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qdebug.cpp27
-rw-r--r--src/corelib/io/qdebug.h25
-rw-r--r--src/corelib/io/qdir.cpp12
-rw-r--r--src/corelib/io/qdir.h16
-rw-r--r--src/corelib/io/qfile.h2
-rw-r--r--src/corelib/io/qfiledevice.cpp2
-rw-r--r--src/corelib/io/qfiledevice.h2
-rw-r--r--src/corelib/io/qfileinfo.h5
-rw-r--r--src/corelib/io/qfileselector.h2
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp5
-rw-r--r--src/corelib/io/qfilesystemwatcher.h4
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm31
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp4
-rw-r--r--src/corelib/io/qiodevice.cpp64
-rw-r--r--src/corelib/io/qiodevice.h2
-rw-r--r--src/corelib/io/qiodevice_p.h1
-rw-r--r--src/corelib/io/qlockfile_unix.cpp1
-rw-r--r--src/corelib/io/qloggingcategory.cpp9
-rw-r--r--src/corelib/io/qloggingregistry.cpp68
-rw-r--r--src/corelib/io/qloggingregistry_p.h1
-rw-r--r--src/corelib/io/qprocess.cpp146
-rw-r--r--src/corelib/io/qprocess.h27
-rw-r--r--src/corelib/io/qprocess_p.h2
-rw-r--r--src/corelib/io/qprocess_unix.cpp49
-rw-r--r--src/corelib/io/qprocess_win.cpp44
-rw-r--r--src/corelib/io/qprocess_wince.cpp9
-rw-r--r--src/corelib/io/qresource.cpp2
-rw-r--r--src/corelib/io/qsavefile.h2
-rw-r--r--src/corelib/io/qsettings.cpp28
-rw-r--r--src/corelib/io/qsettings.h10
-rw-r--r--src/corelib/io/qsettings_mac.cpp9
-rw-r--r--src/corelib/io/qsettings_p.h3
-rw-r--r--src/corelib/io/qsettings_win.cpp8
-rw-r--r--src/corelib/io/qstandardpaths.cpp10
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp6
-rw-r--r--src/corelib/io/qstorageinfo.cpp12
-rw-r--r--src/corelib/io/qstorageinfo.h6
-rw-r--r--src/corelib/io/qstorageinfo_mac.cpp1
-rw-r--r--src/corelib/io/qstorageinfo_p.h3
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp10
-rw-r--r--src/corelib/io/qtemporarydir.cpp47
-rw-r--r--src/corelib/io/qtemporarydir.h1
-rw-r--r--src/corelib/io/qtemporaryfile.cpp4
-rw-r--r--src/corelib/io/qtemporaryfile_p.h2
-rw-r--r--src/corelib/io/qtextstream.h4
-rw-r--r--src/corelib/io/qtldurl.cpp1
-rw-r--r--src/corelib/io/qurlquery.cpp22
-rw-r--r--src/corelib/io/qurlquery.h8
-rw-r--r--src/corelib/io/qwindowspipereader.cpp6
-rw-r--r--src/corelib/io/qwindowspipereader_p.h2
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp6
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.h16
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel_p.h3
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp1
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.h2
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.cpp3
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.h2
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp10
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.h36
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp33
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.h2
-rw-r--r--src/corelib/itemmodels/qstringlistmodel.cpp4
-rw-r--r--src/corelib/itemmodels/qstringlistmodel.h4
-rw-r--r--src/corelib/json/qjsonarray.cpp1
-rw-r--r--src/corelib/json/qjsonarray.h8
-rw-r--r--src/corelib/json/qjsondocument.h2
-rw-r--r--src/corelib/json/qjsonobject.cpp2
-rw-r--r--src/corelib/json/qjsonobject.h4
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.h4
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm17
-rw-r--r--src/corelib/kernel/qcore_unix_p.h64
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp242
-rw-r--r--src/corelib/kernel/qcoreapplication.h17
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h8
-rw-r--r--src/corelib/kernel/qcoreevent.cpp2
-rw-r--r--src/corelib/kernel/qcoreevent.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp1
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp4
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp108
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h4
-rw-r--r--src/corelib/kernel/qeventloop.cpp2
-rw-r--r--src/corelib/kernel/qeventloop.h2
-rw-r--r--src/corelib/kernel/qfunctions_wince.cpp8
-rw-r--r--src/corelib/kernel/qfunctions_wince.h15
-rw-r--r--src/corelib/kernel/qjni.cpp10
-rw-r--r--src/corelib/kernel/qjni_p.h8
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp39
-rw-r--r--src/corelib/kernel/qjnihelpers_p.h13
-rw-r--r--src/corelib/kernel/qmath.h10
-rw-r--r--src/corelib/kernel/qmetaobject.cpp1
-rw-r--r--src/corelib/kernel/qmetaobject.h36
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp20
-rw-r--r--src/corelib/kernel/qmetatype.cpp28
-rw-r--r--src/corelib/kernel/qmetatype.h113
-rw-r--r--src/corelib/kernel/qmimedata.cpp4
-rw-r--r--src/corelib/kernel/qobject.cpp12
-rw-r--r--src/corelib/kernel/qobject.h46
-rw-r--r--src/corelib/kernel/qobject_impl.h10
-rw-r--r--src/corelib/kernel/qobject_p.h6
-rw-r--r--src/corelib/kernel/qobjectdefs.h24
-rw-r--r--src/corelib/kernel/qpointer.cpp8
-rw-r--r--src/corelib/kernel/qpointer.h12
-rw-r--r--src/corelib/kernel/qsharedmemory.h4
-rw-r--r--src/corelib/kernel/qsignalmapper.h2
-rw-r--r--src/corelib/kernel/qsocketnotifier.h2
-rw-r--r--src/corelib/kernel/qsystemerror.cpp2
-rw-r--r--src/corelib/kernel/qsystemerror_p.h10
-rw-r--r--src/corelib/kernel/qsystemsemaphore_win.cpp2
-rw-r--r--src/corelib/kernel/qtimer.h10
-rw-r--r--src/corelib/kernel/qtranslator.cpp1
-rw-r--r--src/corelib/kernel/qtranslator.h4
-rw-r--r--src/corelib/kernel/qvariant.cpp8
-rw-r--r--src/corelib/kernel/qvariant.h30
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp1
-rw-r--r--src/corelib/mimetypes/qmimedatabase_p.h1
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp1
-rw-r--r--src/corelib/mimetypes/qmimetype.cpp13
-rw-r--r--src/corelib/mimetypes/qmimetype.h12
-rw-r--r--src/corelib/plugin/plugin.pri1
-rw-r--r--src/corelib/plugin/qfactoryinterface.cpp43
-rw-r--r--src/corelib/plugin/qfactoryinterface.h2
-rw-r--r--src/corelib/plugin/qlibrary.h8
-rw-r--r--src/corelib/plugin/qpluginloader.cpp30
-rw-r--r--src/corelib/plugin/qpluginloader.h4
-rw-r--r--src/corelib/statemachine/qabstractstate.cpp12
-rw-r--r--src/corelib/statemachine/qabstractstate.h2
-rw-r--r--src/corelib/statemachine/qabstractstate_p.h9
-rw-r--r--src/corelib/statemachine/qabstracttransition.cpp18
-rw-r--r--src/corelib/statemachine/qabstracttransition.h2
-rw-r--r--src/corelib/statemachine/qabstracttransition_p.h6
-rw-r--r--src/corelib/statemachine/qeventtransition.cpp3
-rw-r--r--src/corelib/statemachine/qeventtransition.h4
-rw-r--r--src/corelib/statemachine/qeventtransition_p.h4
-rw-r--r--src/corelib/statemachine/qfinalstate.h2
-rw-r--r--src/corelib/statemachine/qhistorystate.cpp64
-rw-r--r--src/corelib/statemachine/qhistorystate.h10
-rw-r--r--src/corelib/statemachine/qhistorystate_p.h25
-rw-r--r--src/corelib/statemachine/qsignaltransition.cpp5
-rw-r--r--src/corelib/statemachine/qsignaltransition.h4
-rw-r--r--src/corelib/statemachine/qsignaltransition_p.h3
-rw-r--r--src/corelib/statemachine/qstate.cpp10
-rw-r--r--src/corelib/statemachine/qstate.h4
-rw-r--r--src/corelib/statemachine/qstate_p.h3
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp188
-rw-r--r--src/corelib/statemachine/qstatemachine.h4
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h18
-rw-r--r--src/corelib/thread/qexception.cpp20
-rw-r--r--src/corelib/thread/qexception.h16
-rw-r--r--src/corelib/thread/qfuture.qdoc1
-rw-r--r--src/corelib/thread/qfutureinterface.h2
-rw-r--r--src/corelib/thread/qfuturewatcher.h4
-rw-r--r--src/corelib/thread/qgenericatomic.h81
-rw-r--r--src/corelib/thread/qmutex.h8
-rw-r--r--src/corelib/thread/qmutex_win.cpp6
-rw-r--r--src/corelib/thread/qresultstore.h4
-rw-r--r--src/corelib/thread/qrunnable.cpp11
-rw-r--r--src/corelib/thread/qrunnable.h9
-rw-r--r--src/corelib/thread/qthread.cpp28
-rw-r--r--src/corelib/thread/qthread.h4
-rw-r--r--src/corelib/thread/qthread_p.h10
-rw-r--r--src/corelib/thread/qthread_unix.cpp15
-rw-r--r--src/corelib/thread/qthread_win.cpp6
-rw-r--r--src/corelib/thread/qthreadpool.h2
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp2
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp6
-rw-r--r--src/corelib/tools/qalgorithms.h125
-rwxr-xr-x[-rw-r--r--]src/corelib/tools/qalgorithms.qdoc70
-rw-r--r--src/corelib/tools/qarraydata.cpp4
-rw-r--r--src/corelib/tools/qarraydata.h6
-rw-r--r--src/corelib/tools/qarraydatapointer.h11
-rw-r--r--src/corelib/tools/qbytearray.cpp90
-rw-r--r--src/corelib/tools/qbytearray.h48
-rw-r--r--src/corelib/tools/qbytearray_p.h61
-rw-r--r--src/corelib/tools/qbytearraylist.h2
-rw-r--r--src/corelib/tools/qchar.cpp61
-rw-r--r--src/corelib/tools/qchar.h269
-rw-r--r--src/corelib/tools/qcollator.h2
-rw-r--r--src/corelib/tools/qcommandlineoption.cpp114
-rw-r--r--src/corelib/tools/qcommandlineoption.h8
-rw-r--r--src/corelib/tools/qcommandlineparser.cpp50
-rw-r--r--src/corelib/tools/qcommandlineparser.h6
-rw-r--r--src/corelib/tools/qdatetime.h7
-rw-r--r--src/corelib/tools/qdatetimeparser_p.h1
-rw-r--r--src/corelib/tools/qeasingcurve.cpp2
-rw-r--r--src/corelib/tools/qeasingcurve.h2
-rw-r--r--src/corelib/tools/qharfbuzz.cpp3
-rw-r--r--src/corelib/tools/qhash.cpp148
-rw-r--r--src/corelib/tools/qhash.h164
-rw-r--r--src/corelib/tools/qhashfunctions.h156
-rw-r--r--src/corelib/tools/qlinkedlist.h2
-rw-r--r--src/corelib/tools/qlist.cpp303
-rw-r--r--src/corelib/tools/qlist.h141
-rw-r--r--src/corelib/tools/qlocale.cpp18
-rw-r--r--src/corelib/tools/qlocale.h39
-rw-r--r--src/corelib/tools/qlocale_mac.mm14
-rw-r--r--src/corelib/tools/qlocale_p.h3
-rw-r--r--src/corelib/tools/qmap.cpp160
-rw-r--r--src/corelib/tools/qmap.h140
-rw-r--r--src/corelib/tools/qqueue.cpp13
-rw-r--r--src/corelib/tools/qqueue.h3
-rw-r--r--src/corelib/tools/qrect.cpp4
-rw-r--r--src/corelib/tools/qregexp.cpp44
-rw-r--r--src/corelib/tools/qregexp.h5
-rw-r--r--src/corelib/tools/qregularexpression.cpp19
-rw-r--r--src/corelib/tools/qregularexpression.h4
-rw-r--r--src/corelib/tools/qringbuffer.cpp314
-rw-r--r--src/corelib/tools/qringbuffer_p.h246
-rw-r--r--src/corelib/tools/qscopedpointer.h14
-rw-r--r--src/corelib/tools/qset.h42
-rw-r--r--src/corelib/tools/qset.qdoc46
-rw-r--r--src/corelib/tools/qshareddata.h11
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h81
-rw-r--r--src/corelib/tools/qsimd.cpp4
-rw-r--r--src/corelib/tools/qsimd_p.h5
-rw-r--r--src/corelib/tools/qstack.cpp13
-rw-r--r--src/corelib/tools/qstack.h3
-rw-r--r--src/corelib/tools/qstring.cpp386
-rw-r--r--src/corelib/tools/qstring.h139
-rw-r--r--src/corelib/tools/qtextboundaryfinder.h2
-rw-r--r--src/corelib/tools/qtimeline.h2
-rw-r--r--src/corelib/tools/qtimezone.cpp4
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp1
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h1
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp1
-rw-r--r--src/corelib/tools/qvarlengtharray.h39
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc108
-rw-r--r--src/corelib/tools/qvector.cpp244
-rw-r--r--src/corelib/tools/qvector.h122
-rw-r--r--src/corelib/tools/qversionnumber.cpp136
-rw-r--r--src/corelib/tools/qversionnumber.h313
-rw-r--r--src/corelib/tools/qversionnumber_p.h193
-rw-r--r--src/corelib/tools/tools.pri5
-rw-r--r--src/corelib/xml/qxmlstream.h22
267 files changed, 5580 insertions, 2485 deletions
diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h
index da78341d90..7085a9fc5e 100644
--- a/src/corelib/animation/qabstractanimation.h
+++ b/src/corelib/animation/qabstractanimation.h
@@ -76,7 +76,7 @@ public:
DeleteWhenStopped
};
- QAbstractAnimation(QObject *parent = 0);
+ QAbstractAnimation(QObject *parent = Q_NULLPTR);
virtual ~QAbstractAnimation();
State state() const;
@@ -111,7 +111,7 @@ public Q_SLOTS:
void setCurrentTime(int msecs);
protected:
- QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = 0);
+ QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = Q_NULLPTR);
bool event(QEvent *event) Q_DECL_OVERRIDE;
virtual void updateCurrentTime(int currentTime) = 0;
@@ -130,7 +130,7 @@ class Q_CORE_EXPORT QAnimationDriver : public QObject
Q_DECLARE_PRIVATE(QAnimationDriver)
public:
- QAnimationDriver(QObject *parent = 0);
+ QAnimationDriver(QObject *parent = Q_NULLPTR);
~QAnimationDriver();
virtual void advance();
@@ -156,7 +156,7 @@ protected:
virtual void start();
virtual void stop();
- QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = 0);
+ QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = Q_NULLPTR);
private:
friend class QUnifiedTimer;
diff --git a/src/corelib/animation/qanimationgroup.h b/src/corelib/animation/qanimationgroup.h
index 9b180b1704..b668b503b4 100644
--- a/src/corelib/animation/qanimationgroup.h
+++ b/src/corelib/animation/qanimationgroup.h
@@ -47,7 +47,7 @@ class Q_CORE_EXPORT QAnimationGroup : public QAbstractAnimation
Q_OBJECT
public:
- QAnimationGroup(QObject *parent = 0);
+ QAnimationGroup(QObject *parent = Q_NULLPTR);
~QAnimationGroup();
QAbstractAnimation *animationAt(int index) const;
diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h
index 52a61dafcd..7ce05d6344 100644
--- a/src/corelib/animation/qparallelanimationgroup.h
+++ b/src/corelib/animation/qparallelanimationgroup.h
@@ -47,7 +47,7 @@ class Q_CORE_EXPORT QParallelAnimationGroup : public QAnimationGroup
Q_OBJECT
public:
- QParallelAnimationGroup(QObject *parent = 0);
+ QParallelAnimationGroup(QObject *parent = Q_NULLPTR);
~QParallelAnimationGroup();
int duration() const Q_DECL_OVERRIDE;
diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h
index 159d82f969..5207472623 100644
--- a/src/corelib/animation/qpauseanimation.h
+++ b/src/corelib/animation/qpauseanimation.h
@@ -48,8 +48,8 @@ class Q_CORE_EXPORT QPauseAnimation : public QAbstractAnimation
Q_OBJECT
Q_PROPERTY(int duration READ duration WRITE setDuration)
public:
- QPauseAnimation(QObject *parent = 0);
- QPauseAnimation(int msecs, QObject *parent = 0);
+ QPauseAnimation(QObject *parent = Q_NULLPTR);
+ QPauseAnimation(int msecs, QObject *parent = Q_NULLPTR);
~QPauseAnimation();
int duration() const Q_DECL_OVERRIDE;
diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h
index 8d06a9f354..c0d30ba0fd 100644
--- a/src/corelib/animation/qpropertyanimation.h
+++ b/src/corelib/animation/qpropertyanimation.h
@@ -49,8 +49,8 @@ class Q_CORE_EXPORT QPropertyAnimation : public QVariantAnimation
Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject)
public:
- QPropertyAnimation(QObject *parent = 0);
- QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0);
+ QPropertyAnimation(QObject *parent = Q_NULLPTR);
+ QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = Q_NULLPTR);
~QPropertyAnimation();
QObject *targetObject() const;
diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h
index 1a4ead90d4..c8a84a1220 100644
--- a/src/corelib/animation/qsequentialanimationgroup.h
+++ b/src/corelib/animation/qsequentialanimationgroup.h
@@ -50,7 +50,7 @@ class Q_CORE_EXPORT QSequentialAnimationGroup : public QAnimationGroup
Q_PROPERTY(QAbstractAnimation* currentAnimation READ currentAnimation NOTIFY currentAnimationChanged)
public:
- QSequentialAnimationGroup(QObject *parent = 0);
+ QSequentialAnimationGroup(QObject *parent = Q_NULLPTR);
~QSequentialAnimationGroup();
QPauseAnimation *addPause(int msecs);
diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h
index 035a553799..fdb97ca83c 100644
--- a/src/corelib/animation/qsequentialanimationgroup_p.h
+++ b/src/corelib/animation/qsequentialanimationgroup_p.h
@@ -86,7 +86,7 @@ public:
// this is the actual duration of uncontrolled animations
// it helps seeking and even going forward
- QList<int> actualDuration;
+ QVector<int> actualDuration;
void restart();
int lastLoop;
diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h
index 8a6524a594..4340a187a2 100644
--- a/src/corelib/animation/qvariantanimation.h
+++ b/src/corelib/animation/qvariantanimation.h
@@ -59,7 +59,7 @@ public:
typedef QPair<qreal, QVariant> KeyValue;
typedef QVector<KeyValue> KeyValues;
- QVariantAnimation(QObject *parent = 0);
+ QVariantAnimation(QObject *parent = Q_NULLPTR);
~QVariantAnimation();
QVariant startValue() const;
@@ -88,7 +88,7 @@ Q_SIGNALS:
void valueChanged(const QVariant &value);
protected:
- QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent = 0);
+ QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent = Q_NULLPTR);
bool event(QEvent *event) Q_DECL_OVERRIDE;
void updateCurrentTime(int) Q_DECL_OVERRIDE;
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index c6d5c7388d..88987865c4 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -1155,7 +1155,6 @@ QTextCodec *QTextCodec::codecForUtfText(const QByteArray &ba)
function returns 0 (the default), tr() assumes Latin-1.
*/
-
/*!
\internal
\since 4.3
diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h
index 1d5e25efcc..3e73872d64 100644
--- a/src/corelib/codecs/qtextcodec.h
+++ b/src/corelib/codecs/qtextcodec.h
@@ -88,7 +88,7 @@ public:
struct Q_CORE_EXPORT 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(Q_NULLPTR) { state_data[0] = state_data[1] = state_data[2] = 0; }
~ConverterState();
ConversionFlags flags;
int remainingChars;
@@ -99,9 +99,9 @@ public:
Q_DISABLE_COPY(ConverterState)
};
- QString toUnicode(const char *in, int length, ConverterState *state = 0) const
+ QString toUnicode(const char *in, int length, ConverterState *state = Q_NULLPTR) const
{ return convertToUnicode(in, length, state); }
- QByteArray fromUnicode(const QChar *in, int length, ConverterState *state = 0) const
+ QByteArray fromUnicode(const QChar *in, int length, ConverterState *state = Q_NULLPTR) const
{ return convertFromUnicode(in, length, state); }
QTextDecoder* makeDecoder(ConversionFlags flags = DefaultConversion) const;
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 2d78041752..5cd0bde87b 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -13,9 +13,6 @@ irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused
CONFIG += optimize_full
-# otherwise mingw headers do not declare common functions like putenv
-mingw:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x
-
QMAKE_DOCS = $$PWD/doc/qtcore.qdocconf
ANDROID_JAR_DEPENDENCIES = \
@@ -48,6 +45,9 @@ include(statemachine/statemachine.pri)
include(mimetypes/mimetypes.pri)
include(xml/xml.pri)
+# otherwise mingw headers do not declare common functions like putenv
+mingw: CONFIG -= strict_c++
+
mac|darwin {
!ios {
LIBS_PRIVATE += -framework ApplicationServices
diff --git a/src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp b/src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp
index e2cf761ff8..eacc94b19f 100644
--- a/src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_codecs_qtextcodec.cpp
@@ -63,13 +63,3 @@ while (new_data_available()) {
}
delete decoder;
//! [2]
-
-
-//! [3]
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
- QTextCodec::setCodecForTr(QTextCodec::codecForName("eucKR"));
- ...
-}
-//! [3]
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp
index b0048014a4..8ff44c9dca 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp
@@ -418,17 +418,17 @@ QString example = tr("Example");
//! [40]
//! [41]
-QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildOnly);
+QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildrenOnly);
//! [41]
//! [42]
-QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildOnly);
+QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildrenOnly);
//! [42]
//! [43]
-QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(QString(), Qt::FindDirectChildOnly);
+QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(QString(), Qt::FindDirectChildrenOnly);
//! [43]
//! [44]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp
index 43d64fc08e..0ac7cb5769 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp
@@ -298,6 +298,25 @@ while (i != hash.end() && i.key() == "plenty") {
}
//! [26]
+//! [27]
+for (QHash<int, QString>::const_iterator it = hash.cbegin(), end = hash.cend(); it != end; ++it) {
+ cout << "The key: " << it.key() << endl
+ cout << "The value: " << it.value() << endl;
+ cout << "Also the value: " << (*it) << endl;
+}
+//! [27]
+
+//! [28]
+// Inefficient, keys() is expensive
+QList<int> keys = hash.keys();
+int numPrimes = std::count_if(keys.cbegin(), keys.cend(), isPrimeNumber);
+qDeleteAll(hash2.keys());
+
+// Efficient, no memory allocation needed
+int numPrimes = std::count_if(hash.keyBegin(), hash.keyEnd(), isPrimeNumber);
+qDeleteAll(hash2.keyBegin(), hash2.keyEnd());
+//! [28]
+
//! [qhashbits]
inline uint qHash(const std::vector<int> &key, uint seed = 0)
{
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp
index 7580b6bbaf..29e53fc700 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp
@@ -311,3 +311,22 @@ while (i != map.end() && i.key() == "plenty") {
++i;
}
//! [27]
+
+//! [keyiterator1]
+for (QMap<int, QString>::const_iterator it = map.cbegin(), end = map.cend(); it != end; ++it) {
+ cout << "The key: " << it.key() << endl
+ cout << "The value: " << it.value() << endl;
+ cout << "Also the value: " << (*it) << endl;
+}
+//! [keyiterator1]
+
+//! [keyiterator2]
+// Inefficient, keys() is expensive
+QList<int> keys = map.keys();
+int numPrimes = std::count_if(map.cbegin(), map.cend(), isPrimeNumber);
+qDeleteAll(map2.keys());
+
+// Efficient, no memory allocation needed
+int numPrimes = std::count_if(map.keyBegin(), map.keyEnd(), isPrimeNumber);
+qDeleteAll(map2.keyBegin(), map2.keyEnd());
+//! [keyiterator2]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp
index 77b34c95fc..5def361b83 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qvector.cpp
@@ -84,14 +84,27 @@ for (int i = 0; i < 10; ++i)
//! [7]
-QVector<QString> vector(0);
+QVector<QString> vector;
vector.append("one");
vector.append("two");
-vector.append("three");
+QString three = "three";
+vector.append(three);
// vector: ["one", "two", "three"]
+// three: "three"
//! [7]
+//! [move-append]
+QVector<QString> vector;
+vector.append("one");
+vector.append("two");
+QString three = "three";
+vector.append(std::move(three));
+// vector: ["one", "two", "three"]
+// three: ""
+//! [move-append]
+
+
//! [8]
QVector<QString> vector;
vector.prepend("one");
diff --git a/src/corelib/doc/src/external-resources.qdoc b/src/corelib/doc/src/external-resources.qdoc
index ec4715c933..d612ce8280 100644
--- a/src/corelib/doc/src/external-resources.qdoc
+++ b/src/corelib/doc/src/external-resources.qdoc
@@ -65,4 +65,13 @@
\externalpage http://doc-snapshot.qt-project.org/qt5-5.4/designer-widget-mode.html#the-property-editor
\title Qt Designer's Widget Editing Mode#The Property Editor
*/
+
+/*!
+ \externalpage http://marcmutz.wordpress.com/effective-qt/containers/#containers-qlist
+ \title Pros and Cons of Using QList
+*/
+
+/*!
+ \externalpage http://marcmutz.wordpress.com/effective-qt/containers/
+ \title Understand the Qt Containers
*/
diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc
index abb0720fe9..55622dd56b 100644
--- a/src/corelib/doc/src/objectmodel/properties.qdoc
+++ b/src/corelib/doc/src/objectmodel/properties.qdoc
@@ -160,13 +160,8 @@
Because QDate is user-defined, you must include the \c{<QDate>}
header file with the property declaration.
- For QMap, QList, and QValueList properties, the property value is
- a QVariant whose value is the entire list or map. Note that the
- Q_PROPERTY string cannot contain commas, because commas separate
- macro arguments. Therefore, you must use \c QMap as the property
- type instead of \c QMap<QString,QVariant>. For consistency, also
- use \c QList and \c QValueList instead of \c QList<QVariant> and
- \c QValueList<QVariant>.
+ For historical reasons, \a QMap and \a QList as property types
+ are synonym of \a QVariantMap and \a QVariantList.
\section1 Reading and Writing Properties with the Meta-Object System
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index 6a8104bee2..43f3a86544 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -54,3 +54,7 @@ journald {
PKGCONFIG_PRIVATE += libsystemd-journal
DEFINES += QT_USE_JOURNALD
}
+
+syslog {
+ DEFINES += QT_USE_SYSLOG
+}
diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h
index d3b9c3f5a7..f434e87c85 100644
--- a/src/corelib/global/qflags.h
+++ b/src/corelib/global/qflags.h
@@ -109,7 +109,7 @@ public:
inline QFlags &operator=(const QFlags &other);
#endif
Q_DECL_CONSTEXPR inline QFlags(Enum f) Q_DECL_NOTHROW : i(Int(f)) {}
- Q_DECL_CONSTEXPR inline QFlags(Zero = 0) Q_DECL_NOTHROW : i(0) {}
+ Q_DECL_CONSTEXPR inline QFlags(Zero = Q_NULLPTR) Q_DECL_NOTHROW : i(0) {}
Q_DECL_CONSTEXPR inline QFlags(QFlag f) Q_DECL_NOTHROW : i(f) {}
#ifdef Q_COMPILER_INITIALIZER_LISTS
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index b5bdcedaa1..77ac53f7e9 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -42,6 +42,7 @@
#include <private/qlocale_tools_p.h>
#include <private/qsystemlibrary_p.h>
+#include <qmutex.h>
#ifndef QT_NO_QOBJECT
#include <private/qthread_p.h>
@@ -64,6 +65,20 @@
# endif
#endif
+#ifdef Q_OS_WINRT
+#include <wrl.h>
+#include <windows.networking.h>
+#include <windows.networking.sockets.h>
+#include <windows.networking.connectivity.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Connectivity;
+using namespace ABI::Windows::Networking::Sockets;
+#endif
+
#if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL)
# include <envLib.h>
#endif
@@ -89,6 +104,10 @@
#include <private/qcore_unix_p.h>
#endif
+#ifdef Q_OS_BSD4
+#include <sys/sysctl.h>
+#endif
+
#include "archdetect.cpp"
QT_BEGIN_NAMESPACE
@@ -1886,6 +1905,36 @@ QT_END_INCLUDE_NAMESPACE
#ifndef Q_OS_WINRT
+# ifndef QT_BOOTSTRAPPED
+class QWindowsSockInit
+{
+public:
+ QWindowsSockInit();
+ ~QWindowsSockInit();
+ int version;
+};
+
+QWindowsSockInit::QWindowsSockInit()
+: version(0)
+{
+ //### should we try for 2.2 on all platforms ??
+ WSAData wsadata;
+
+ // IPv6 requires Winsock v2.0 or better.
+ if (WSAStartup(MAKEWORD(2,0), &wsadata) != 0) {
+ qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed.");
+ } else {
+ version = 0x20;
+ }
+}
+
+QWindowsSockInit::~QWindowsSockInit()
+{
+ WSACleanup();
+}
+Q_GLOBAL_STATIC(QWindowsSockInit, winsockInit)
+# endif // QT_BOOTSTRAPPED
+
# ifndef Q_OS_WINCE
// Determine Windows versions >= 8 by querying the version of kernel32.dll.
@@ -2774,6 +2823,82 @@ QString QSysInfo::prettyProductName()
return unknownText();
}
+#ifndef QT_BOOTSTRAPPED
+/*!
+ \since 5.6
+
+ Returns this machine's host name, if one is configured. Note that hostnames
+ are not guaranteed to be globally unique, especially if they were
+ configured automatically.
+
+ This function does not guarantee the returned host name is a Fully
+ Qualified Domain Name (FQDN). For that, use QHostInfo to resolve the
+ returned name to an FQDN.
+
+ This function returns the same as QHostInfo::localHostName().
+
+ \sa QHostInfo::localDomainName
+ */
+QString QSysInfo::machineHostName()
+{
+#if defined(Q_OS_LINUX)
+ // gethostname(3) on Linux just calls uname(2), so do it ourselves
+ // and avoid a memcpy
+ struct utsname u;
+ if (uname(&u) == 0)
+ return QString::fromLocal8Bit(u.nodename);
+#elif defined(Q_OS_WINRT)
+ ComPtr<INetworkInformationStatics> statics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics);
+
+ ComPtr<IVectorView<HostName *>> hostNames;
+ statics->GetHostNames(&hostNames);
+ if (!hostNames)
+ return QString();
+
+ unsigned int size;
+ hostNames->get_Size(&size);
+ if (size == 0)
+ return QString();
+
+ for (unsigned int i = 0; i < size; ++i) {
+ ComPtr<IHostName> hostName;
+ hostNames->GetAt(i, &hostName);
+ HostNameType type;
+ hostName->get_Type(&type);
+ if (type != HostNameType_DomainName)
+ continue;
+
+ HString name;
+ hostName->get_CanonicalName(name.GetAddressOf());
+ UINT32 length;
+ PCWSTR rawString = name.GetRawBuffer(&length);
+ return QString::fromWCharArray(rawString, length);
+ }
+ ComPtr<IHostName> firstHost;
+ hostNames->GetAt(0, &firstHost);
+
+ HString name;
+ firstHost->get_CanonicalName(name.GetAddressOf());
+ UINT32 length;
+ PCWSTR rawString = name.GetRawBuffer(&length);
+ return QString::fromWCharArray(rawString, length);
+#else
+# ifdef Q_OS_WIN
+ // Important: QtNetwork depends on machineHostName() initializing ws2_32.dll
+ winsockInit();
+# endif
+
+ char hostName[512];
+ if (gethostname(hostName, sizeof(hostName)) == -1)
+ return QString();
+ hostName[sizeof(hostName) - 1] = '\0';
+ return QString::fromLocal8Bit(hostName);
+#endif
+ return QString();
+}
+#endif // QT_BOOTSTRAPPED
+
/*!
\macro void Q_ASSERT(bool test)
\relates <QtGlobal>
@@ -2885,12 +3010,15 @@ QString QSysInfo::prettyProductName()
\macro void Q_CHECK_PTR(void *pointer)
\relates <QtGlobal>
- If \a pointer is 0, prints a warning message containing the source
+ If \a pointer is 0, prints a message containing the source
code's file name and line number, saying that the program ran out
- of memory.
+ of memory and aborts program execution. It throws \c std::bad_alloc instead
+ if exceptions are enabled.
- Q_CHECK_PTR does nothing if \c QT_NO_DEBUG was defined during
- compilation.
+ Q_CHECK_PTR does nothing if \c QT_NO_DEBUG and \c QT_NO_EXCEPTIONS were
+ defined during compilation. Therefore you must not use Q_CHECK_PTR to check
+ for successful memory allocations because the check will be disabled in
+ some cases.
Example:
@@ -3020,7 +3148,7 @@ namespace {
// depending on the return type
static inline Q_DECL_UNUSED QString fromstrerror_helper(int, const QByteArray &buf)
{
- return QString::fromLocal8Bit(buf);
+ return QString::fromLocal8Bit(buf.constData());
}
static inline Q_DECL_UNUSED QString fromstrerror_helper(const char *str, const QByteArray &)
{
@@ -3098,6 +3226,10 @@ QString qt_error_string(int errorCode)
return ret.trimmed();
}
+// In the C runtime on all platforms access to the environment is not thread-safe. We
+// add thread-safety for the Qt wrappers.
+static QBasicMutex environmentMutex;
+
// getenv is declared as deprecated in VS2005. This function
// makes use of the new secure getenv function.
/*!
@@ -3115,6 +3247,7 @@ QString qt_error_string(int errorCode)
*/
QByteArray qgetenv(const char *varName)
{
+ QMutexLocker locker(&environmentMutex);
#if defined(_MSC_VER) && _MSC_VER >= 1400
size_t requiredSize = 0;
QByteArray buffer;
@@ -3148,6 +3281,7 @@ QByteArray qgetenv(const char *varName)
*/
bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT
{
+ QMutexLocker locker(&environmentMutex);
#if defined(_MSC_VER) && _MSC_VER >= 1400
// we provide a buffer that can only hold the empty string, so
// when the env.var isn't empty, we'll get an ERANGE error (buffer
@@ -3179,6 +3313,7 @@ bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT
*/
int qEnvironmentVariableIntValue(const char *varName, bool *ok) Q_DECL_NOEXCEPT
{
+ QMutexLocker locker(&environmentMutex);
#if defined(_MSC_VER) && _MSC_VER >= 1400
// we provide a buffer that can hold any int value:
static const int NumBinaryDigitsPerOctalDigit = 3;
@@ -3227,6 +3362,7 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) Q_DECL_NOEXCEPT
*/
bool qEnvironmentVariableIsSet(const char *varName) Q_DECL_NOEXCEPT
{
+ QMutexLocker locker(&environmentMutex);
#if defined(_MSC_VER) && _MSC_VER >= 1400
size_t requiredSize = 0;
(void)getenv_s(&requiredSize, 0, 0, varName);
@@ -3256,6 +3392,7 @@ bool qEnvironmentVariableIsSet(const char *varName) Q_DECL_NOEXCEPT
*/
bool qputenv(const char *varName, const QByteArray& value)
{
+ QMutexLocker locker(&environmentMutex);
#if defined(_MSC_VER) && _MSC_VER >= 1400
return _putenv_s(varName, value.constData()) == 0;
#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_HAIKU)
@@ -3286,6 +3423,7 @@ bool qputenv(const char *varName, const QByteArray& value)
*/
bool qunsetenv(const char *varName)
{
+ QMutexLocker locker(&environmentMutex);
#if defined(_MSC_VER) && _MSC_VER >= 1400
return _putenv_s(varName, "") == 0;
#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_BSD4) || defined(Q_OS_HAIKU)
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 97c5f37cab..f8f306f614 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -41,11 +41,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "5.5.1"
+#define QT_VERSION_STR "5.6.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x050501
+#define QT_VERSION 0x050600
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -322,6 +322,15 @@ typedef double qreal;
#endif
/*
+ Some classes do not permit copies to be made of an object. These
+ classes contains a private copy constructor and assignment
+ operator to disable copying (the compiler gives an error message).
+*/
+#define Q_DISABLE_COPY(Class) \
+ Class(const Class &) Q_DECL_EQ_DELETE;\
+ Class &operator=(const Class &) Q_DECL_EQ_DELETE;
+
+/*
No, this is not an evil backdoor. QT_BUILD_INTERNAL just exports more symbols
for Qt's internal unit tests. If you want slower loading times and more
symbols that can vanish from version to version, feel free to define QT_BUILD_INTERNAL.
@@ -487,10 +496,13 @@ typedef qptrdiff qintptr;
#ifdef Q_CC_MSVC
# define Q_NEVER_INLINE __declspec(noinline)
+# define Q_ALWAYS_INLINE __forceinline
#elif defined(Q_CC_GNU)
# define Q_NEVER_INLINE __attribute__((noinline))
+# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
#else
# define Q_NEVER_INLINE
+# define Q_ALWAYS_INLINE inline
#endif
//defines the type for the WNDPROC on windows
@@ -543,7 +555,21 @@ template <typename T>
Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max)
{ return qMax(min, qMin(max, val)); }
-#ifdef Q_OS_DARWIN
+#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
+# ifdef __OBJC__
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
+# else
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
+# endif
+#endif
+#ifndef Q_FORWARD_DECLARE_CF_TYPE
+# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
+#endif
+#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE
+# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
+#endif
+
+#ifdef Q_OS_MAC
# define QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) \
((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MAX_ALLOWED >= osx) || \
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios))
@@ -561,7 +587,23 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max
QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_NA, ios)
# define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) \
QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, __IPHONE_NA)
-#endif
+
+QT_END_NAMESPACE
+Q_FORWARD_DECLARE_OBJC_CLASS(NSAutoreleasePool);
+QT_BEGIN_NAMESPACE
+
+// Implemented in qcore_mac_objc.mm
+class Q_CORE_EXPORT QMacAutoReleasePool
+{
+public:
+ QMacAutoReleasePool();
+ ~QMacAutoReleasePool();
+private:
+ Q_DISABLE_COPY(QMacAutoReleasePool);
+ NSAutoreleasePool *pool;
+};
+
+#endif // Q_OS_MAC
/*
Data stream functions are provided by many classes (defined in qdatastream.h)
@@ -1033,15 +1075,6 @@ Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1);
{ return T::dynamic_cast_will_always_fail_because_rtti_is_disabled; }
#endif
-/*
- Some classes do not permit copies to be made of an object. These
- classes contains a private copy constructor and assignment
- operator to disable copying (the compiler gives an error message).
-*/
-#define Q_DISABLE_COPY(Class) \
- Class(const Class &) Q_DECL_EQ_DELETE;\
- Class &operator=(const Class &) Q_DECL_EQ_DELETE;
-
class QByteArray;
Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value);
@@ -1049,7 +1082,7 @@ Q_CORE_EXPORT bool qunsetenv(const char *varName);
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT;
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) Q_DECL_NOEXCEPT;
-Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=0) Q_DECL_NOEXCEPT;
+Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=Q_NULLPTR) Q_DECL_NOEXCEPT;
inline int qIntCast(double f) { return int(f); }
inline int qIntCast(float f) { return int(f); }
@@ -1077,20 +1110,6 @@ template <bool B, typename T, typename F> struct QConditional { typedef T Type;
template <typename T, typename F> struct QConditional<false, T, F> { typedef F Type; };
}
-#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
-# ifdef __OBJC__
-# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
-# else
-# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
-# endif
-#endif
-#ifndef Q_FORWARD_DECLARE_CF_TYPE
-# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
-#endif
-#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE
-# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
-#endif
-
QT_END_NAMESPACE
// We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4.
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index fca8656f9b..20c31f7ef8 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -65,6 +65,9 @@
# include <systemd/sd-journal.h>
# include <syslog.h>
#endif
+#if defined(QT_USE_SYSLOG) && !defined(QT_BOOTSTRAPPED)
+# include <syslog.h>
+#endif
#ifdef Q_OS_UNIX
# include <sys/types.h>
# include <sys/stat.h>
@@ -1436,6 +1439,32 @@ static void systemd_default_message_handler(QtMsgType type,
}
#endif
+#ifdef QT_USE_SYSLOG
+static void syslog_default_message_handler(QtMsgType type, const char *message)
+{
+ int priority = LOG_INFO; // Informational
+ switch (type) {
+ case QtDebugMsg:
+ priority = LOG_DEBUG; // Debug-level messages
+ break;
+ case QtInfoMsg:
+ priority = LOG_INFO; // Informational conditions
+ break;
+ case QtWarningMsg:
+ priority = LOG_WARNING; // Warning conditions
+ break;
+ case QtCriticalMsg:
+ priority = LOG_CRIT; // Critical conditions
+ break;
+ case QtFatalMsg:
+ priority = LOG_ALERT; // Action must be taken immediately
+ break;
+ }
+
+ syslog(priority, "%s", message);
+}
+#endif
+
#ifdef Q_OS_ANDROID
static void android_default_message_handler(QtMsgType type,
const QMessageLogContext &context,
@@ -1481,6 +1510,9 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
#elif defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
systemd_default_message_handler(type, context, logMessage);
return;
+#elif defined(QT_USE_SYSLOG) && !defined(QT_BOOTSTRAPPED)
+ syslog_default_message_handler(type, logMessage.toUtf8().constData());
+ return;
#elif defined(Q_OS_ANDROID)
android_default_message_handler(type, context, logMessage);
return;
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 679afddb20..c63346086a 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -57,7 +57,8 @@ class QMessageLogContext
{
Q_DISABLE_COPY(QMessageLogContext)
public:
- Q_DECL_CONSTEXPR QMessageLogContext() : version(2), line(0), file(0), function(0), category(0) {}
+ Q_DECL_CONSTEXPR QMessageLogContext()
+ : version(2), line(0), file(Q_NULLPTR), function(Q_NULLPTR), category(Q_NULLPTR) {}
Q_DECL_CONSTEXPR QMessageLogContext(const char *fileName, int lineNumber, const char *functionName, const char *categoryName)
: version(2), line(lineNumber), file(fileName), function(functionName), category(categoryName) {}
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 82b383e69c..de8a17fa51 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -496,6 +496,7 @@ public:
AA_UseSoftwareOpenGL = 17,
AA_ShareOpenGLContexts = 18,
AA_SetPalette = 19,
+ AA_NoHighDpiScaling = 20,
// Add new attributes before this line
AA_AttributeCount
@@ -1326,6 +1327,7 @@ public:
ImAbsolutePosition = 0x400,
ImTextBeforeCursor = 0x800,
ImTextAfterCursor = 0x1000,
+ ImEnterKeyType = 0x2000,
ImPlatformData = 0x80000000,
ImQueryInput = ImCursorRectangle | ImCursorPosition | ImSurroundingText |
@@ -1365,6 +1367,17 @@ public:
};
Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint)
+ enum EnterKeyType {
+ EnterKeyDefault,
+ EnterKeyReturn,
+ EnterKeyDone,
+ EnterKeyGo,
+ EnterKeySend,
+ EnterKeySearch,
+ EnterKeyNext,
+ EnterKeyPrevious
+ };
+
enum ToolButtonStyle {
ToolButtonIconOnly,
ToolButtonTextOnly,
@@ -1449,7 +1462,10 @@ public:
ItemIsDropEnabled = 8,
ItemIsUserCheckable = 16,
ItemIsEnabled = 32,
- ItemIsTristate = 64,
+ ItemIsAutoTristate = 64,
+#if QT_DEPRECATED_SINCE(5, 6)
+ ItemIsTristate = ItemIsAutoTristate,
+#endif
ItemNeverHasChildren = 128,
ItemIsUserTristate = 256
};
@@ -1520,9 +1536,16 @@ public:
TitleBarArea // For move
};
+#if defined(Q_COMPILER_CLASS_ENUM) && defined(Q_COMPILER_CONSTEXPR)
+ enum class Initialization {
+ Uninitialized
+ };
+ static constexpr Q_DECL_UNUSED Initialization Uninitialized = Initialization::Uninitialized;
+#else
enum Initialization {
Uninitialized
};
+#endif
enum CoordinateSystem {
DeviceCoordinates,
@@ -1610,7 +1633,8 @@ public:
enum MouseEventSource {
MouseEventNotSynthesized,
MouseEventSynthesizedBySystem,
- MouseEventSynthesizedByQt
+ MouseEventSynthesizedByQt,
+ MouseEventSynthesizedByApplication
};
enum MouseEventFlag {
@@ -1685,6 +1709,7 @@ public:
QT_Q_ENUM(InputMethodHint)
QT_Q_ENUM(InputMethodQuery)
QT_Q_FLAG(InputMethodHints)
+ QT_Q_ENUM(EnterKeyType)
QT_Q_FLAG(InputMethodQueries)
QT_Q_FLAG(TouchPointStates)
QT_Q_ENUM(ScreenOrientation)
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index c6098007d1..a7da751da4 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -170,12 +170,13 @@
\value AA_UseDesktopOpenGL Forces the usage of desktop OpenGL (for example,
\e opengl32.dll or \e libGL.so) on platforms that use dynamic loading
- of the OpenGL implementation.
- This value has been added in Qt 5.3.
+ of the OpenGL implementation. This value has been added in Qt 5.3.
+ This attribute must be set before Q(Gui)Application is constructed.
\value AA_UseOpenGLES Forces the usage of OpenGL ES 2.0 or higher on
platforms that use dynamic loading of the OpenGL implementation.
- This value has been added in Qt 5.3.
+ This value has been added in Qt 5.3. This attribute must be set
+ before Q(Gui)Application is constructed.
\value AA_UseSoftwareOpenGL Forces the usage of a software based OpenGL
implementation on platforms that use dynamic loading of the OpenGL
@@ -186,17 +187,24 @@
\c opengl32sw.dll and can be overridden by setting the environment
variable \e QT_OPENGL_DLL. See the platform-specific pages, for
instance \l{Qt for Windows}, for more information. This value has
- been added in Qt 5.4.
+ been added in Qt 5.4. This attribute must be set before
+ Q(Gui)Application is constructed.
\value AA_ShareOpenGLContexts Enables resource sharing between the OpenGL
contexts used by classes like QOpenGLWidget and QQuickWidget. This
allows sharing OpenGL resources, like textures, between QOpenGLWidget
instances that belong to different top-level windows. This value has
- been added in Qt 5.4.
+ been added in Qt 5.4. This attribute must be set before
+ Q(Gui)Application is constructed.
\value AA_SetPalette Indicates whether a palette was explicitly set on the
QApplication/QGuiApplication. This value has been added in Qt 5.5.
+ \value AA_NoHighDpiScaling Disables all high-DPI scaling in Qt, exposing window
+ system coordinates. Note that the window system may do its own scaling,
+ so this does not guarantee that QPaintDevice::devicePixelRatio() will
+ be equal to 1. This value has been added in Qt 5.6.
+
The following values are obsolete:
\value AA_ImmediateWidgetCreation This attribute is no longer fully
@@ -1670,6 +1678,16 @@
\value Key_Blue
\value Key_ChannelUp
\value Key_ChannelDown
+ \value Key_Guide
+ \value Key_Info
+ \value Key_Settings
+ \value Key_MicVolumeUp
+ \value Key_MicVolumeDown
+ \value Key_New
+ \value Key_Open
+ \value Key_Find
+ \value Key_Undo
+ \value Key_Redo
\value Key_MediaLast
\value Key_unknown
@@ -1694,6 +1712,7 @@
\value Key_Play
\value Key_Sleep
\value Key_Zoom
+ \value Key_Exit
\value Key_Cancel
\sa QKeyEvent::key()
@@ -2516,6 +2535,7 @@
but \b{must} not return an empty string unless the cursor is at the start of the document.
\value ImTextAfterCursor The plain text after the cursor. The widget can decide how much text to return,
but \b{must} not return an empty string unless the cursor is at the end of the document.
+ \value ImEnterKeyType The Enter key type.
Masks:
@@ -2526,6 +2546,37 @@
*/
/*!
+ \enum Qt::EnterKeyType
+
+ This can be used to alter the appearance of the Return key on an on-screen keyboard.
+
+ \note Not all of these values are supported on all platforms.
+ For unsupported values the default key will be used instead.
+
+ \value EnterKeyDefault The default Enter key.
+ This can either be a button closing the keyboard, or a Return button
+ causing a new line in case of a multi-line input field.
+ \value EnterKeyReturn Show a Return button that inserts a new line.
+ The keyboard will not close when this button is pressed.
+ \value EnterKeyDone Show a "Done" button.
+ The keyboard will close when this button is pressed.
+ \value EnterKeyGo Show a "Go" button.
+ Typically used in an address bar when entering a URL; the keyboard
+ will close when this button is pressed.
+ \value EnterKeySend Show a "Send" button.
+ The keyboard will close when this button is pressed.
+ \value EnterKeySearch Show a "Search" button.
+ The keyboard will close when this button is pressed.
+ \value EnterKeyNext Show a "Next" button.
+ Typically used in a form to allow navigating to the next input field;
+ the keyboard will not close when this button is pressed.
+ \value EnterKeyPrevious Show a "Previous" button.
+ The keyboard will not close when this button is pressed.
+
+ \since 5.6
+*/
+
+/*!
\enum Qt::ItemDataRole
Each item in the model has a set of data elements associated with
@@ -2600,10 +2651,12 @@
\value ItemIsDropEnabled It can be used as a drop target.
\value ItemIsUserCheckable It can be checked or unchecked by the user.
\value ItemIsEnabled The user can interact with the item.
- \value ItemIsTristate The item can show three separate states.
+ \value ItemIsAutoTristate The item's state depends on the state of its children.
This enables automatic management of the state of parent items in QTreeWidget
(checked if all children are checked, unchecked if all children are unchecked,
or partially checked if only some children are checked).
+ \value ItemIsTristate \e{This enum value is deprecated.} Use Qt::ItemIsAutoTristate
+ instead.
\value ItemNeverHasChildren The item never has child items.
This is used for optimization purposes only.
\value ItemIsUserTristate The user can cycle through three separate states.
@@ -3024,6 +3077,12 @@
\value MouseEventSynthesizedByQt Indicates that the mouse event was
synthesized from an unhandled touch event by Qt.
+ \value MouseEventSynthesizedByApplication Indicates that the mouse
+ event was synthesized by the application. This allows
+ distinguishing application-generated mouse events from the ones
+ that are coming from the system or are synthesized by Qt. This
+ value was introduced in Qt 5.6
+
\sa Qt::AA_SynthesizeMouseForUnhandledTouchEvents
*/
diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h
index 625b366cc6..27a285fd36 100644
--- a/src/corelib/global/qsysinfo.h
+++ b/src/corelib/global/qsysinfo.h
@@ -125,19 +125,19 @@ public:
MV_Unknown = 0x0000,
/* version */
- MV_9 = 0x0001,
- MV_10_0 = 0x0002,
- MV_10_1 = 0x0003,
- MV_10_2 = 0x0004,
- MV_10_3 = 0x0005,
- MV_10_4 = 0x0006,
- MV_10_5 = 0x0007,
- MV_10_6 = 0x0008,
- MV_10_7 = 0x0009,
- MV_10_8 = 0x000A,
- MV_10_9 = 0x000B,
- MV_10_10 = 0x000C,
- MV_10_11 = 0x000D,
+ MV_9 = Q_MV_OSX(9, 0),
+ MV_10_0 = Q_MV_OSX(10, 0),
+ MV_10_1 = Q_MV_OSX(10, 1),
+ MV_10_2 = Q_MV_OSX(10, 2),
+ MV_10_3 = Q_MV_OSX(10, 3),
+ MV_10_4 = Q_MV_OSX(10, 4),
+ MV_10_5 = Q_MV_OSX(10, 5),
+ MV_10_6 = Q_MV_OSX(10, 6),
+ MV_10_7 = Q_MV_OSX(10, 7),
+ MV_10_8 = Q_MV_OSX(10, 8),
+ MV_10_9 = Q_MV_OSX(10, 9),
+ MV_10_10 = Q_MV_OSX(10, 10),
+ MV_10_11 = Q_MV_OSX(10, 11),
/* codenames */
MV_CHEETAH = MV_10_0,
@@ -186,6 +186,8 @@ public:
static QString productType();
static QString productVersion();
static QString prettyProductName();
+
+ static QString machineHostName();
};
QT_END_NAMESPACE
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 90ac8c6a0c..b42e5998fc 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -32,6 +32,7 @@
****************************************************************************/
#include <QtCore/qtypetraits.h>
+#include <QtCore/qisenum.h>
#ifndef QTYPEINFO_H
#define QTYPEINFO_H
@@ -55,6 +56,7 @@ public:
isIntegral = QtPrivate::is_integral<T>::value,
isComplex = true,
isStatic = true,
+ isRelocatable = Q_IS_ENUM(T),
isLarge = (sizeof(T)>sizeof(void*)),
isDummy = false, //### Qt6: remove
sizeOf = sizeof(T)
@@ -70,6 +72,7 @@ public:
isIntegral = false,
isComplex = false,
isStatic = false,
+ isRelocatable = false,
isLarge = false,
isDummy = false,
sizeOf = 0
@@ -85,6 +88,7 @@ public:
isIntegral = false,
isComplex = false,
isStatic = false,
+ isRelocatable = true,
isLarge = false,
isDummy = false,
sizeOf = sizeof(T*)
@@ -92,6 +96,32 @@ public:
};
/*!
+ \class QTypeInfoQuery
+ \inmodule QtCore
+ \internal
+ \brief QTypeInfoQuery is used to query the values of a given QTypeInfo<T>
+
+ We use it because there may be some QTypeInfo<T> specializations in user
+ code that don't provide certain flags that we added after Qt 5.0. They are:
+ \list
+ \li isRelocatable: defaults to !isStatic
+ \endlist
+
+ DO NOT specialize this class elsewhere.
+*/
+// apply defaults for a generic QTypeInfo<T> that didn't provide the new values
+template <typename T, typename = void>
+struct QTypeInfoQuery : QTypeInfo<T>
+{
+ enum { isRelocatable = !QTypeInfo<T>::isStatic };
+};
+
+// if QTypeInfo<T>::isRelocatable exists, use it
+template <typename T>
+struct QTypeInfoQuery<T, typename QtPrivate::QEnableIf<QTypeInfo<T>::isRelocatable || true>::Type> : QTypeInfo<T>
+{};
+
+/*!
\class QTypeInfoMerger
\inmodule QtCore
\internal
@@ -116,8 +146,12 @@ class QTypeInfoMerger
{
public:
enum {
- isComplex = QTypeInfo<T1>::isComplex || QTypeInfo<T2>::isComplex || QTypeInfo<T3>::isComplex || QTypeInfo<T4>::isComplex,
- isStatic = QTypeInfo<T1>::isStatic || QTypeInfo<T2>::isStatic || QTypeInfo<T3>::isStatic || QTypeInfo<T4>::isStatic,
+ isComplex = QTypeInfoQuery<T1>::isComplex || QTypeInfoQuery<T2>::isComplex
+ || QTypeInfoQuery<T3>::isComplex || QTypeInfoQuery<T4>::isComplex,
+ isStatic = QTypeInfoQuery<T1>::isStatic || QTypeInfoQuery<T2>::isStatic
+ || QTypeInfoQuery<T3>::isStatic || QTypeInfoQuery<T4>::isStatic,
+ isRelocatable = QTypeInfoQuery<T1>::isRelocatable && QTypeInfoQuery<T2>::isRelocatable
+ && QTypeInfoQuery<T3>::isRelocatable && QTypeInfoQuery<T4>::isRelocatable,
isLarge = sizeof(T) > sizeof(void*),
isPointer = false,
isIntegral = false,
@@ -136,19 +170,20 @@ public: \
isPointer = false, \
isIntegral = false, \
isComplex = true, \
+ isRelocatable = true, \
isStatic = false, \
isLarge = (sizeof(CONTAINER<T>) > sizeof(void*)), \
isDummy = false, \
sizeOf = sizeof(CONTAINER<T>) \
}; \
-};
+}
-Q_DECLARE_MOVABLE_CONTAINER(QList)
-Q_DECLARE_MOVABLE_CONTAINER(QVector)
-Q_DECLARE_MOVABLE_CONTAINER(QQueue)
-Q_DECLARE_MOVABLE_CONTAINER(QStack)
-Q_DECLARE_MOVABLE_CONTAINER(QLinkedList)
-Q_DECLARE_MOVABLE_CONTAINER(QSet)
+Q_DECLARE_MOVABLE_CONTAINER(QList);
+Q_DECLARE_MOVABLE_CONTAINER(QVector);
+Q_DECLARE_MOVABLE_CONTAINER(QQueue);
+Q_DECLARE_MOVABLE_CONTAINER(QStack);
+Q_DECLARE_MOVABLE_CONTAINER(QLinkedList);
+Q_DECLARE_MOVABLE_CONTAINER(QSet);
#undef Q_DECLARE_MOVABLE_CONTAINER
@@ -164,8 +199,9 @@ enum { /* TYPEINFO flags */
Q_COMPLEX_TYPE = 0,
Q_PRIMITIVE_TYPE = 0x1,
Q_STATIC_TYPE = 0,
- Q_MOVABLE_TYPE = 0x2,
- Q_DUMMY_TYPE = 0x4
+ Q_MOVABLE_TYPE = 0x2, // ### Qt6: merge movable and relocatable once QList no longer depends on it
+ Q_DUMMY_TYPE = 0x4,
+ Q_RELOCATABLE_TYPE = 0x8
};
#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
@@ -175,6 +211,7 @@ public: \
enum { \
isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \
isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \
+ isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE), \
isLarge = (sizeof(TYPE)>sizeof(void*)), \
isPointer = false, \
isIntegral = QtPrivate::is_integral< TYPE >::value, \
@@ -201,13 +238,22 @@ Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);
where 'type' is the name of the type to specialize. NOTE: shared
types must define a member-swap, and be defined in the same
namespace as Qt for this to work.
+
+ If the type was already released without Q_DECLARE_SHARED applied,
+ _and_ without an explicit Q_DECLARE_TYPEINFO(type, Q_MOVABLE_TYPE),
+ then use Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(type) to mark the
+ type shared (incl. swap()), without marking it movable (which
+ would change the memory layout of QList, a BiC change.
*/
-#define Q_DECLARE_SHARED(TYPE) \
-Q_DECLARE_TYPEINFO(TYPE, Q_MOVABLE_TYPE); \
+#define Q_DECLARE_SHARED_IMPL(TYPE, FLAGS) \
+Q_DECLARE_TYPEINFO(TYPE, FLAGS); \
inline void swap(TYPE &value1, TYPE &value2) \
Q_DECL_NOEXCEPT_EXPR(noexcept(value1.swap(value2))) \
{ value1.swap(value2); }
+#define Q_DECLARE_SHARED(TYPE) Q_DECLARE_SHARED_IMPL(TYPE, Q_MOVABLE_TYPE)
+#define Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(TYPE) \
+ Q_DECLARE_SHARED_IMPL(TYPE, QT_VERSION >= QT_VERSION_CHECK(6,0,0) ? Q_MOVABLE_TYPE : Q_RELOCATABLE_TYPE)
/*
QTypeInfo primitive specializations
diff --git a/src/corelib/io/forkfd_qt.cpp b/src/corelib/io/forkfd_qt.cpp
index 6704ec6f2a..b226332cc1 100644
--- a/src/corelib/io/forkfd_qt.cpp
+++ b/src/corelib/io/forkfd_qt.cpp
@@ -32,13 +32,6 @@
****************************************************************************/
// these might be defined via precompiled headers
-#ifndef _POSIX_C_SOURCE
-# define _POSIX_C_SOURCE 200809L
-#endif
-#if !defined(_XOPEN_SOURCE) && !defined(__QNXNTO__) && !defined(ANDROID)
-# define _XOPEN_SOURCE 700
-#endif
-
#include <QtCore/qatomic.h>
#include "qprocess_p.h"
diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp
index 07270eb790..2ab789e0af 100644
--- a/src/corelib/io/qabstractfileengine.cpp
+++ b/src/corelib/io/qabstractfileengine.cpp
@@ -891,7 +891,6 @@ bool QAbstractFileEngine::unmap(uchar *address)
/*!
\typedef QAbstractFileEngine::Iterator
\since 4.3
- \relates QAbstractFileEngine
Synonym for QAbstractFileEngineIterator.
*/
diff --git a/src/corelib/io/qbuffer.h b/src/corelib/io/qbuffer.h
index 1b2758d040..233c702213 100644
--- a/src/corelib/io/qbuffer.h
+++ b/src/corelib/io/qbuffer.h
@@ -51,8 +51,8 @@ class Q_CORE_EXPORT QBuffer : public QIODevice
public:
#ifndef QT_NO_QOBJECT
- explicit QBuffer(QObject *parent = 0);
- QBuffer(QByteArray *buf, QObject *parent = 0);
+ explicit QBuffer(QObject *parent = Q_NULLPTR);
+ QBuffer(QByteArray *buf, QObject *parent = Q_NULLPTR);
#else
QBuffer();
explicit QBuffer(QByteArray *buf);
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 48672db2e9..713b5a2f55 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -526,6 +526,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_3 Same as Qt_5_2
\value Qt_5_4 Version 16 (Qt 5.4)
\value Qt_5_5 Same as Qt_5_4
+ \value Qt_5_6 Same as Qt_5_4
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index 436bf8dd57..b87dbe4784 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -83,10 +83,11 @@ public:
Qt_5_3 = Qt_5_2,
Qt_5_4 = 16,
Qt_5_5 = Qt_5_4,
-#if QT_VERSION >= 0x050600
+ Qt_5_6 = Qt_5_5,
+#if QT_VERSION >= 0x050700
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_5
+ Qt_DefaultCompiledVersion = Qt_5_6
};
enum ByteOrder {
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 30086b2dac..54a705b72b 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -351,6 +351,7 @@ QDebug &QDebug::resetFormat()
stream->space = true;
if (stream->context.version > 1)
stream->flags = 0;
+ stream->setVerbosity(Stream::defaultVerbosity);
return *this;
}
@@ -444,6 +445,32 @@ QDebug &QDebug::resetFormat()
*/
/*!
+ \fn int QDebug::verbosity() const
+ \since 5.6
+
+ Returns the verbosity of the debug stream.
+
+ Streaming operators can check the value to decide whether
+ verbose output is desired and print more information depending on the
+ level. Higher values indicate that more information is desired.
+
+ The allowed range is from 0 to 7. The default value is 2.
+
+ \sa setVerbosity()
+*/
+
+/*!
+ \fn void QDebug::setVerbosity(int verbosityLevel)
+ \since 5.6
+
+ Sets the verbosity of the stream to \a verbosityLevel.
+
+ The allowed range is from 0 to 7. The default value is 2.
+
+ \sa verbosity()
+*/
+
+/*!
\fn QDebug &QDebug::operator<<(QChar t)
Writes the character, \a t, to the stream and returns a reference to the
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 3c3ceba249..2f626dfc1f 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -53,9 +53,14 @@ class Q_CORE_EXPORT QDebug
friend class QMessageLogger;
friend class QDebugStateSaverPrivate;
struct Stream {
- Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false), flags(0) {}
- Stream(QString *string) : ts(string, QIODevice::WriteOnly), ref(1), type(QtDebugMsg), space(true), message_output(false), flags(0) {}
- Stream(QtMsgType t) : ts(&buffer, QIODevice::WriteOnly), ref(1), type(t), space(true), message_output(true), flags(0) {}
+ enum { defaultVerbosity = 2, verbosityShift = 29, verbosityMask = 0x7 };
+
+ Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg),
+ space(true), message_output(false), flags(defaultVerbosity << verbosityShift) {}
+ Stream(QString *string) : ts(string, QIODevice::WriteOnly), ref(1), type(QtDebugMsg),
+ space(true), message_output(false), flags(defaultVerbosity << verbosityShift) {}
+ Stream(QtMsgType t) : ts(&buffer, QIODevice::WriteOnly), ref(1), type(t),
+ space(true), message_output(true), flags(defaultVerbosity << verbosityShift) {}
QTextStream ts;
QString buffer;
int ref;
@@ -64,7 +69,7 @@ class Q_CORE_EXPORT QDebug
bool message_output;
QMessageLogContext context;
- enum FormatFlag {
+ enum FormatFlag { // Note: Bits 29..31 are reserved for the verbose level introduced in 5.6.
NoQuotes = 0x1
};
@@ -72,7 +77,15 @@ class Q_CORE_EXPORT QDebug
bool testFlag(FormatFlag flag) const { return (context.version > 1) ? (flags & flag) : false; }
void setFlag(FormatFlag flag) { if (context.version > 1) { flags |= flag; } }
void unsetFlag(FormatFlag flag) { if (context.version > 1) { flags &= ~flag; } }
-
+ int verbosity() const
+ { return context.version > 1 ? (flags >> verbosityShift) & verbosityMask : int(Stream::defaultVerbosity); }
+ void setVerbosity(int v)
+ {
+ if (context.version > 1) {
+ flags &= ~(verbosityMask << verbosityShift);
+ flags |= (v & verbosityMask) << verbosityShift;
+ }
+ }
// added in 5.4
int flags;
} *stream;
@@ -96,6 +109,8 @@ public:
inline QDebug &space() { stream->space = true; stream->ts << ' '; return *this; }
inline QDebug &nospace() { stream->space = false; return *this; }
inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; }
+ int verbosity() const { return stream->verbosity(); }
+ void setVerbosity(int verbosityLevel) { stream->setVerbosity(verbosityLevel); }
bool autoInsertSpaces() const { return stream->space; }
void setAutoInsertSpaces(bool b) { stream->space = b; }
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index f6e132708e..e1d9858a66 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -1836,6 +1836,8 @@ QFileInfoList QDir::drives()
underlying operating system. If you want to display paths to the
user using their operating system's separator use
toNativeSeparators().
+
+ \sa listSeparator()
*/
QChar QDir::separator()
{
@@ -1847,6 +1849,16 @@ QChar QDir::separator()
}
/*!
+ \fn QDir::listSeparator()
+ \since 5.6
+
+ Returns the native path list separator: ':' under Unix
+ and ';' under Windows.
+
+ \sa separator()
+*/
+
+/*!
Sets the application's current working directory to \a path.
Returns \c true if the directory was successfully changed; otherwise
returns \c false.
diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h
index e622011f98..ab3a331229 100644
--- a/src/corelib/io/qdir.h
+++ b/src/corelib/io/qdir.h
@@ -101,11 +101,10 @@ public:
QDir &operator=(const QDir &);
QDir &operator=(const QString &path);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QDir &operator=(QDir &&other)
- { qSwap(d_ptr, other.d_ptr); return *this; }
+ QDir &operator=(QDir &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- inline void swap(QDir &other)
+ void swap(QDir &other) Q_DECL_NOTHROW
{ qSwap(d_ptr, other.d_ptr); }
void setPath(const QString &path);
@@ -177,7 +176,16 @@ public:
static QFileInfoList drives();
- static QChar separator();
+ Q_DECL_CONSTEXPR static inline QChar listSeparator() Q_DECL_NOTHROW
+ {
+#if defined(Q_OS_WIN)
+ return QLatin1Char(';');
+#else
+ return QLatin1Char(':');
+#endif
+ }
+
+ static QChar separator(); // ### Qt6: Make it inline
static bool setCurrent(const QString &path);
static inline QDir current() { return QDir(currentPath()); }
diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h
index 35a73680af..4eac710d4c 100644
--- a/src/corelib/io/qfile.h
+++ b/src/corelib/io/qfile.h
@@ -134,7 +134,7 @@ protected:
#ifdef QT_NO_QOBJECT
QFile(QFilePrivate &dd);
#else
- QFile(QFilePrivate &dd, QObject *parent = 0);
+ QFile(QFilePrivate &dd, QObject *parent = Q_NULLPTR);
#endif
private:
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index 3ee0e33573..4c5ed0aef6 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -481,7 +481,7 @@ bool QFileDevicePrivate::putCharHelper(char c)
#else
// Cutoff for code that doesn't only touch the buffer.
- int writeBufferSize = writeBuffer.size();
+ qint64 writeBufferSize = writeBuffer.size();
if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
#ifdef Q_OS_WIN
|| ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h
index e9320d8d31..afa42bd86b 100644
--- a/src/corelib/io/qfiledevice.h
+++ b/src/corelib/io/qfiledevice.h
@@ -119,7 +119,7 @@ protected:
QFileDevice(QFileDevicePrivate &dd);
#else
explicit QFileDevice(QObject *parent);
- QFileDevice(QFileDevicePrivate &dd, QObject *parent = 0);
+ QFileDevice(QFileDevicePrivate &dd, QObject *parent = Q_NULLPTR);
#endif
qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index 58cf9a5c0f..59d12c3883 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -62,11 +62,10 @@ public:
QFileInfo &operator=(const QFileInfo &fileinfo);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QFileInfo&operator=(QFileInfo &&other)
- { qSwap(d_ptr, other.d_ptr); return *this; }
+ QFileInfo &operator=(QFileInfo &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- inline void swap(QFileInfo &other)
+ void swap(QFileInfo &other) Q_DECL_NOTHROW
{ qSwap(d_ptr, other.d_ptr); }
bool operator==(const QFileInfo &fileinfo) const;
diff --git a/src/corelib/io/qfileselector.h b/src/corelib/io/qfileselector.h
index 967d5eee75..9ee3588780 100644
--- a/src/corelib/io/qfileselector.h
+++ b/src/corelib/io/qfileselector.h
@@ -44,7 +44,7 @@ class Q_CORE_EXPORT QFileSelector : public QObject
{
Q_OBJECT
public:
- explicit QFileSelector(QObject *parent = 0);
+ explicit QFileSelector(QObject *parent = Q_NULLPTR);
~QFileSelector();
QString select(const QString &filePath) const;
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index d62c120d7e..379095a83d 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -407,7 +407,7 @@ static QString readLink(const QFileSystemEntry &link)
Q_UNUSED(link);
return QString();
#endif // QT_NO_LIBRARY
-#else
+#elif !defined(QT_NO_WINCE_SHELLSDK)
wchar_t target[MAX_PATH];
QString result;
if (SHGetShortcutTarget((wchar_t*)QFileInfo(link.filePath()).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) {
@@ -418,6 +418,9 @@ static QString readLink(const QFileSystemEntry &link)
result.remove(result.size()-1,1);
}
return result;
+#else // QT_NO_WINCE_SHELLSDK
+ Q_UNUSED(link);
+ return QString();
#endif // Q_OS_WINCE
}
diff --git a/src/corelib/io/qfilesystemwatcher.h b/src/corelib/io/qfilesystemwatcher.h
index 13d1782913..095b50d1e5 100644
--- a/src/corelib/io/qfilesystemwatcher.h
+++ b/src/corelib/io/qfilesystemwatcher.h
@@ -49,8 +49,8 @@ class Q_CORE_EXPORT QFileSystemWatcher : public QObject
Q_DECLARE_PRIVATE(QFileSystemWatcher)
public:
- QFileSystemWatcher(QObject *parent = 0);
- QFileSystemWatcher(const QStringList &paths, QObject *parent = 0);
+ QFileSystemWatcher(QObject *parent = Q_NULLPTR);
+ QFileSystemWatcher(const QStringList &paths, QObject *parent = Q_NULLPTR);
~QFileSystemWatcher();
bool addPath(const QString &file);
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index 8a028c91e1..7656530a46 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -56,25 +56,6 @@
QT_BEGIN_NAMESPACE
-namespace {
-class RaiiAutoreleasePool
-{
- Q_DISABLE_COPY(RaiiAutoreleasePool)
-
-public:
- RaiiAutoreleasePool()
- : pool([[NSAutoreleasePool alloc] init])
- {}
-
- ~RaiiAutoreleasePool()
- { [pool release]; }
-
-private:
- NSAutoreleasePool *pool;
-};
-#define Q_AUTORELEASE_POOL(pool) RaiiAutoreleasePool pool; Q_UNUSED(pool);
-}
-
static void callBackFunction(ConstFSEventStreamRef streamRef,
void *clientCallBackInfo,
size_t numEvents,
@@ -82,7 +63,7 @@ static void callBackFunction(ConstFSEventStreamRef streamRef,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
- Q_AUTORELEASE_POOL(pool)
+ QMacAutoReleasePool pool;
char **paths = static_cast<char **>(eventPaths);
QFseventsFileSystemWatcherEngine *engine = static_cast<QFseventsFileSystemWatcherEngine *>(clientCallBackInfo);
@@ -297,7 +278,7 @@ void QFseventsFileSystemWatcherEngine::doEmitDirectoryChanged(const QString &pat
void QFseventsFileSystemWatcherEngine::restartStream()
{
- Q_AUTORELEASE_POOL(pool)
+ QMacAutoReleasePool pool;
QMutexLocker locker(&lock);
stopStream();
startStream();
@@ -328,7 +309,7 @@ QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *pare
QFseventsFileSystemWatcherEngine::~QFseventsFileSystemWatcherEngine()
{
- Q_AUTORELEASE_POOL(pool)
+ QMacAutoReleasePool pool;
if (stream)
FSEventStreamStop(stream);
@@ -344,7 +325,7 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
- Q_AUTORELEASE_POOL(pool)
+ QMacAutoReleasePool pool;
if (stream) {
DEBUG("Flushing, last id is %llu", FSEventStreamGetLatestEventId(stream));
@@ -432,7 +413,7 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
QStringList *files,
QStringList *directories)
{
- Q_AUTORELEASE_POOL(pool)
+ QMacAutoReleasePool pool;
QMutexLocker locker(&lock);
@@ -489,7 +470,7 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
bool QFseventsFileSystemWatcherEngine::startStream()
{
Q_ASSERT(stream == 0);
- Q_AUTORELEASE_POOL(pool)
+ QMacAutoReleasePool pool;
if (stream) // This shouldn't happen, but let's be nice and handle it.
stopStream();
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 19343f22ff..cfd50955a6 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -711,7 +711,7 @@ bool QFSFileEngine::link(const QString &newName)
Q_UNUSED(newName);
return false;
#endif // QT_NO_LIBRARY
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_OS_WINCE) && !defined(QT_NO_WINCE_SHELLSDK)
QString linkName = newName;
linkName.replace(QLatin1Char('/'), QLatin1Char('\\'));
if (!linkName.endsWith(QLatin1String(".lnk")))
@@ -724,7 +724,7 @@ bool QFSFileEngine::link(const QString &newName)
if (!ret)
setError(QFile::RenameError, qt_error_string());
return ret;
-#else // Q_OS_WINCE
+#else // Q_OS_WINCE && !QT_NO_WINCE_SHELLSDK
Q_UNUSED(newName);
Q_UNIMPLEMENTED();
return false;
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index b908ae3145..84a6a1d9cb 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -39,6 +39,7 @@
#include "qfile.h"
#include "qstringlist.h"
#include "qdir.h"
+#include "private/qbytearray_p.h"
#include <algorithm>
@@ -138,7 +139,6 @@ QIODevicePrivate::QIODevicePrivate()
: openMode(QIODevice::NotOpen), buffer(QIODEVICE_BUFFERSIZE),
pos(0), devicePos(0)
, baseReadLineDataCalled(false)
- , firstRead(true)
, accessMode(Unset)
#ifdef QT_NO_QOBJECT
, q_ptr(0)
@@ -463,7 +463,6 @@ void QIODevice::setOpenMode(OpenMode openMode)
#endif
d->openMode = openMode;
d->accessMode = QIODevicePrivate::Unset;
- d->firstRead = true;
if (!isReadable())
d->buffer.clear();
}
@@ -555,7 +554,6 @@ bool QIODevice::open(OpenMode mode)
d->pos = (mode & Append) ? size() : qint64(0);
d->buffer.clear();
d->accessMode = QIODevicePrivate::Unset;
- d->firstRead = true;
#if defined QIODEVICE_DEBUG
printf("%p QIODevice::open(0x%x)\n", this, quint32(mode));
#endif
@@ -585,7 +583,6 @@ void QIODevice::close()
d->errorString.clear();
d->pos = 0;
d->buffer.clear();
- d->firstRead = true;
}
/*!
@@ -692,12 +689,13 @@ bool QIODevice::seek(qint64 pos)
bool QIODevice::atEnd() const
{
Q_D(const QIODevice);
+ const bool result = (d->openMode == NotOpen || (d->buffer.isEmpty()
+ && bytesAvailable() == 0));
#if defined QIODEVICE_DEBUG
printf("%p QIODevice::atEnd() returns %s, d->openMode == %d, d->pos == %lld\n", this,
- (d->openMode == NotOpen || d->pos == size()) ? "true" : "false", int(d->openMode),
- d->pos);
+ result ? "true" : "false", int(d->openMode), d->pos);
#endif
- return d->openMode == NotOpen || (d->buffer.isEmpty() && bytesAvailable() == 0);
+ return result;
}
/*!
@@ -814,12 +812,7 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
bufferReadChunkSize, readSoFar - bufferReadChunkSize);
#endif
} else {
- if (d->firstRead) {
- // this is the first time the file has been read, check it's valid and set up pos pointers
- // for fast pos updates.
- CHECK_READABLE(read, qint64(-1));
- d->firstRead = false;
- }
+ CHECK_READABLE(read, qint64(-1));
}
if (maxSize > 0 && !deviceAtEof) {
@@ -941,9 +934,9 @@ QByteArray QIODevice::read(qint64 maxSize)
Q_UNUSED(d);
#endif
- if (quint64(maxSize) >= QByteArray::MaxSize) {
+ if (maxSize >= MaxByteArraySize) {
checkWarnMessage(this, "read", "maxSize argument exceeds QByteArray size limit");
- maxSize = QByteArray::MaxSize - 1;
+ maxSize = MaxByteArraySize - 1;
}
qint64 readBytes = 0;
@@ -990,40 +983,31 @@ QByteArray QIODevice::readAll()
#endif
QByteArray result;
- qint64 readBytes = 0;
- const bool sequential = d->isSequential();
-
- // flush internal read buffer
- if (!(d->openMode & Text) && !d->buffer.isEmpty()) {
- if (quint64(d->buffer.size()) >= QByteArray::MaxSize)
- return QByteArray();
- result = d->buffer.readAll();
- readBytes = result.size();
- if (!sequential)
- d->pos += readBytes;
- }
-
- qint64 theSize;
- if (sequential || (theSize = size()) == 0) {
+ qint64 readBytes = (d->isSequential() ? Q_INT64_C(0) : size());
+ if (readBytes == 0) {
// Size is unknown, read incrementally.
+ qint64 readChunkSize = qMax(d->buffer.size(), QIODEVICE_BUFFERSIZE);
qint64 readResult;
do {
- if (quint64(readBytes) + QIODEVICE_BUFFERSIZE > QByteArray::MaxSize) {
+ if (readBytes + readChunkSize >= MaxByteArraySize) {
// If resize would fail, don't read more, return what we have.
break;
}
- result.resize(readBytes + QIODEVICE_BUFFERSIZE);
- readResult = read(result.data() + readBytes, QIODEVICE_BUFFERSIZE);
- if (readResult > 0 || readBytes == 0)
+ result.resize(readBytes + readChunkSize);
+ readResult = read(result.data() + readBytes, readChunkSize);
+ if (readResult > 0 || readBytes == 0) {
readBytes += readResult;
+ readChunkSize = QIODEVICE_BUFFERSIZE;
+ }
} while (readResult > 0);
} else {
// Read it all in one go.
// If resize fails, don't read anything.
- if (quint64(readBytes + theSize - d->pos) > QByteArray::MaxSize)
+ readBytes -= d->pos;
+ if (readBytes >= MaxByteArraySize)
return QByteArray();
- result.resize(int(readBytes + theSize - d->pos));
- readBytes += read(result.data() + readBytes, result.size() - readBytes);
+ result.resize(readBytes);
+ readBytes = read(result.data(), readBytes);
}
if (readBytes <= 0)
@@ -1178,9 +1162,9 @@ QByteArray QIODevice::readLine(qint64 maxSize)
Q_UNUSED(d);
#endif
- if (quint64(maxSize) >= QByteArray::MaxSize) {
+ if (maxSize >= MaxByteArraySize) {
qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit");
- maxSize = QByteArray::MaxSize - 1;
+ maxSize = MaxByteArraySize - 1;
}
result.resize(int(maxSize));
@@ -1188,7 +1172,7 @@ QByteArray QIODevice::readLine(qint64 maxSize)
if (!result.size()) {
// If resize fails or maxSize == 0, read incrementally
if (maxSize == 0)
- maxSize = QByteArray::MaxSize - 1;
+ maxSize = MaxByteArraySize - 1;
// The first iteration needs to leave an extra byte for the terminating null
result.resize(1);
diff --git a/src/corelib/io/qiodevice.h b/src/corelib/io/qiodevice.h
index 4f45805fca..b62c8d266c 100644
--- a/src/corelib/io/qiodevice.h
+++ b/src/corelib/io/qiodevice.h
@@ -140,7 +140,7 @@ protected:
#ifdef QT_NO_QOBJECT
QIODevice(QIODevicePrivate &dd);
#else
- QIODevice(QIODevicePrivate &dd, QObject *parent = 0);
+ QIODevice(QIODevicePrivate &dd, QObject *parent = Q_NULLPTR);
#endif
virtual qint64 readData(char *data, qint64 maxlen) = 0;
virtual qint64 readLineData(char *data, qint64 maxlen);
diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h
index f4cf387eb5..56a89ab680 100644
--- a/src/corelib/io/qiodevice_p.h
+++ b/src/corelib/io/qiodevice_p.h
@@ -212,7 +212,6 @@ public:
qint64 pos;
qint64 devicePos;
bool baseReadLineDataCalled;
- bool firstRead;
virtual bool putCharHelper(char c);
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 815c0f025b..27f8a97fd4 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -241,6 +241,7 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
free(proc);
return name;
#else
+ Q_UNUSED(pid);
return QString();
#endif
}
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index e6bc7caaeb..b51085ef42 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -147,8 +147,17 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
\c QT_LOGGING_CONF, and rules set by \c QT_LOGGING_RULES.
+ Since Qt 5.6, \c QT_LOGGING_RULES may contain multiple rules separated
+ by semicolons:
+
+ \code
+ QT_LOGGING_RULES="*.debug=false;driver.usb.debug=true"
+ \endcode
+
+
Order of evaluation:
\list
+ \li [QLibraryInfo::DataPath]/qtlogging.ini
\li QtProject/qtlogging.ini
\li \l setFilterRules()
\li \c QT_LOGGING_CONF
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 880e567562..b53e251102 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -34,6 +34,7 @@
#include "qloggingregistry_p.h"
#include <QtCore/qfile.h>
+#include <QtCore/qlibraryinfo.h>
#include <QtCore/qstandardpaths.h>
#include <QtCore/qtextstream.h>
#include <QtCore/qdir.h>
@@ -208,7 +209,7 @@ void QLoggingSettingsParser::setContent(QTextStream &stream)
continue;
}
- if (_section == QLatin1String("Rules")) {
+ if (_section.toLower() == QLatin1String("rules")) {
int equalPos = line.indexOf(QLatin1Char('='));
if (equalPos != -1) {
if (line.lastIndexOf(QLatin1Char('=')) == equalPos) {
@@ -247,6 +248,21 @@ static bool qtLoggingDebug()
return debugEnv;
}
+static QVector<QLoggingRule> loadRulesFromFile(const QString &filePath)
+{
+ QFile file(filePath);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ if (qtLoggingDebug())
+ debugMsg("Loading \"%s\" ...",
+ QDir::toNativeSeparators(file.fileName()).toUtf8().constData());
+ QTextStream stream(&file);
+ QLoggingSettingsParser parser;
+ parser.setContent(stream);
+ return parser.rules();
+ }
+ return QVector<QLoggingRule>();
+}
+
/*!
\internal
Initializes the rules database by loading
@@ -256,19 +272,10 @@ void QLoggingRegistry::init()
{
// get rules from environment
const QByteArray rulesFilePath = qgetenv("QT_LOGGING_CONF");
- if (!rulesFilePath.isEmpty()) {
- QFile file(QFile::decodeName(rulesFilePath));
- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- if (qtLoggingDebug())
- debugMsg("Loading \"%s\" ...",
- QDir::toNativeSeparators(file.fileName()).toUtf8().constData());
- QTextStream stream(&file);
- QLoggingSettingsParser parser;
- parser.setContent(stream);
- envRules = parser.rules();
- }
- }
- const QByteArray rulesSrc = qgetenv("QT_LOGGING_RULES");
+ if (!rulesFilePath.isEmpty())
+ envRules = loadRulesFromFile(QFile::decodeName(rulesFilePath));
+
+ const QByteArray rulesSrc = qgetenv("QT_LOGGING_RULES").replace(';', '\n');
if (!rulesSrc.isEmpty()) {
QTextStream stream(rulesSrc);
QLoggingSettingsParser parser;
@@ -277,23 +284,22 @@ void QLoggingRegistry::init()
envRules += parser.rules();
}
- // get rules from qt configuration
- QString envPath = QStandardPaths::locate(QStandardPaths::GenericConfigLocation,
- QStringLiteral("QtProject/qtlogging.ini"));
- if (!envPath.isEmpty()) {
- QFile file(envPath);
- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- if (qtLoggingDebug())
- debugMsg("Loading \"%s\" ...",
- QDir::toNativeSeparators(envPath).toUtf8().constData());
- QTextStream stream(&file);
- QLoggingSettingsParser parser;
- parser.setContent(stream);
- configRules = parser.rules();
- }
- }
+ const QString configFileName = QStringLiteral("qtlogging.ini");
+
+#if !defined(QT_BOOTSTRAPPED)
+ // get rules from Qt data configuration path
+ const QString qtConfigPath
+ = QDir(QLibraryInfo::location(QLibraryInfo::DataPath)).absoluteFilePath(configFileName);
+ qtConfigRules = loadRulesFromFile(qtConfigPath);
+#endif
+
+ // get rules from user's/system configuration
+ const QString envPath = QStandardPaths::locate(QStandardPaths::GenericConfigLocation,
+ QString::fromLatin1("QtProject/") + configFileName);
+ if (!envPath.isEmpty())
+ configRules = loadRulesFromFile(envPath);
- if (!envRules.isEmpty() || !configRules.isEmpty()) {
+ if (!envRules.isEmpty() || !qtConfigRules.isEmpty() || !configRules.isEmpty()) {
QMutexLocker locker(&registryMutex);
updateRules();
}
@@ -356,7 +362,7 @@ void QLoggingRegistry::updateRules()
if (categoryFilter != defaultCategoryFilter)
return;
- rules = configRules + apiRules + envRules;
+ rules = qtConfigRules + configRules + apiRules + envRules;
foreach (QLoggingCategory *cat, categories.keys())
(*categoryFilter)(cat);
diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h
index 718e09d9bb..bb32a4996d 100644
--- a/src/corelib/io/qloggingregistry_p.h
+++ b/src/corelib/io/qloggingregistry_p.h
@@ -122,6 +122,7 @@ private:
QMutex registryMutex;
+ QVector<QLoggingRule> qtConfigRules;
QVector<QLoggingRule> configRules;
QVector<QLoggingRule> envRules;
QVector<QLoggingRule> apiRules;
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index c29b97b535..8ee8d0b703 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -101,6 +101,19 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
/*!
+ \since 5.6
+
+ \macro QT_NO_PROCESS_COMBINED_ARGUMENT_START
+ \relates QProcess
+
+ Disables the QProcess::start() overload taking a single string.
+ In most cases where it is used, the user intends for the first argument
+ to be treated atomically as per the other overload.
+
+ \sa QProcess::start()
+*/
+
+/*!
\class QProcessEnvironment
\inmodule QtCore
@@ -110,7 +123,6 @@ QT_BEGIN_NAMESPACE
\ingroup io
\ingroup misc
\ingroup shared
- \mainclass
\reentrant
\since 4.6
@@ -265,11 +277,16 @@ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const
{
if (d == other.d)
return true;
- if (d && other.d) {
- QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d);
- return d->hash == other.d->hash;
+ if (d) {
+ if (other.d) {
+ QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d);
+ return d->hash == other.d->hash;
+ } else {
+ return isEmpty();
+ }
+ } else {
+ return other.isEmpty();
}
- return false;
}
/*!
@@ -498,8 +515,8 @@ void QProcessPrivate::Channel::clear()
the process as arguments, and you can also call exitCode() to
obtain the exit code of the last process that finished, and
exitStatus() to obtain its exit status. If an error occurs at
- any point in time, QProcess will emit the error() signal. You
- can also call error() to find the type of error that occurred
+ any point in time, QProcess will emit the errorOccurred() signal.
+ You can also call error() to find the type of error that occurred
last, and state() to find the current process state.
\section1 Communicating via Channels
@@ -736,6 +753,14 @@ void QProcessPrivate::Channel::clear()
/*!
\fn void QProcess::error(QProcess::ProcessError error)
+ \obsolete
+
+ Use errorOccurred() instead.
+*/
+
+/*!
+ \fn void QProcess::errorOccurred(QProcess::ProcessError error)
+ \since 5.6
This signal is emitted when an error occurs with the process. The
specified \a error describes the type of error that occurred.
@@ -898,6 +923,50 @@ void QProcessPrivate::cleanup()
/*!
\internal
+*/
+void QProcessPrivate::setError(QProcess::ProcessError error, const QString &description)
+{
+ processError = error;
+ if (description.isEmpty()) {
+ switch (error) {
+ case QProcess::FailedToStart:
+ errorString = QProcess::tr("Process failed to start");
+ break;
+ case QProcess::Crashed:
+ errorString = QProcess::tr("Process crashed");
+ break;
+ case QProcess::Timedout:
+ errorString = QProcess::tr("Process operation timed out");
+ break;
+ case QProcess::ReadError:
+ errorString = QProcess::tr("Error reading from process");
+ break;
+ case QProcess::WriteError:
+ errorString = QProcess::tr("Error writing to process");
+ break;
+ case QProcess::UnknownError:
+ errorString.clear();
+ break;
+ }
+ } else {
+ errorString = description;
+ }
+}
+
+/*!
+ \internal
+*/
+void QProcessPrivate::setErrorAndEmit(QProcess::ProcessError error, const QString &description)
+{
+ Q_Q(QProcess);
+ Q_ASSERT(error != QProcess::UnknownError);
+ setError(error, description);
+ emit q->errorOccurred(processError);
+ emit q->error(processError);
+}
+
+/*!
+ \internal
Returns true if we emitted readyRead().
*/
bool QProcessPrivate::tryReadFromChannel(Channel *channel)
@@ -919,9 +988,7 @@ bool QProcessPrivate::tryReadFromChannel(Channel *channel)
return false;
}
if (readBytes == -1) {
- processError = QProcess::ReadError;
- q->setErrorString(QProcess::tr("Error reading from process"));
- emit q->error(processError);
+ setErrorAndEmit(QProcess::ReadError);
#if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process", channel - &stdinChannel);
#endif
@@ -1005,9 +1072,7 @@ bool QProcessPrivate::_q_canWrite()
stdinChannel.buffer.nextDataBlockSize());
if (written < 0) {
closeChannel(&stdinChannel);
- processError = QProcess::WriteError;
- q->setErrorString(QProcess::tr("Error writing to process"));
- emit q->error(processError);
+ setErrorAndEmit(QProcess::WriteError);
return false;
}
@@ -1051,7 +1116,7 @@ bool QProcessPrivate::_q_processDied()
// the process may have died before it got a chance to report that it was
// either running or stopped, so we will call _q_startupNotification() and
- // give it a chance to emit started() or error(FailedToStart).
+ // give it a chance to emit started() or errorOccurred(FailedToStart).
if (processState == QProcess::Starting) {
if (!_q_startupNotification())
return true;
@@ -1076,9 +1141,7 @@ bool QProcessPrivate::_q_processDied()
if (crashed) {
exitStatus = QProcess::CrashExit;
- processError = QProcess::Crashed;
- q->setErrorString(QProcess::tr("Process crashed"));
- emit q->error(processError);
+ setErrorAndEmit(QProcess::Crashed);
} else {
#ifdef QPROCESS_USE_SPAWN
// if we're using posix_spawn, waitForStarted always succeeds.
@@ -1086,8 +1149,8 @@ bool QProcessPrivate::_q_processDied()
// 127 if anything prevents the target program from starting.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_spawn.html
if (exitStatus == QProcess::NormalExit && exitCode == 127) {
- processError = QProcess::FailedToStart;
- q->setErrorString(QProcess::tr("Process failed to start (spawned process exited with code 127)"));
+ setError(QProcess::FailedToStart,
+ QProcess::tr("Process failed to start (spawned process exited with code 127)"));
}
#endif
}
@@ -1131,8 +1194,7 @@ bool QProcessPrivate::_q_startupNotification()
}
q->setProcessState(QProcess::NotRunning);
- processError = QProcess::FailedToStart;
- emit q->error(processError);
+ setErrorAndEmit(QProcess::FailedToStart);
#ifdef Q_OS_UNIX
// make sure the process manager removes this entry
waitForDeadChild();
@@ -1911,12 +1973,12 @@ qint64 QProcess::readData(char *data, qint64 maxlen)
return 1;
}
- qint64 bytesToRead = qint64(qMin(readBuffer->size(), (int)maxlen));
+ qint64 bytesToRead = qMin(readBuffer->size(), maxlen);
qint64 readSoFar = 0;
while (readSoFar < bytesToRead) {
const char *ptr = readBuffer->readPointer();
- int bytesToReadFromThisBlock = qMin<qint64>(bytesToRead - readSoFar,
- readBuffer->nextDataBlockSize());
+ qint64 bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar,
+ readBuffer->nextDataBlockSize());
memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock);
readSoFar += bytesToReadFromThisBlock;
readBuffer->free(bytesToReadFromThisBlock);
@@ -1940,9 +2002,7 @@ qint64 QProcess::writeData(const char *data, qint64 len)
#if defined(Q_OS_WINCE)
Q_UNUSED(data);
Q_UNUSED(len);
- d->processError = QProcess::WriteError;
- setErrorString(tr("Error writing to process"));
- emit error(d->processError);
+ d->setErrorAndEmit(QProcess::WriteError);
return -1;
#endif
@@ -2033,10 +2093,10 @@ QByteArray QProcess::readAllStandardError()
The QProcess object will immediately enter the Starting state. If the
process starts successfully, QProcess will emit started(); otherwise,
- error() will be emitted.
+ errorOccurred() will be emitted.
\note Processes are started asynchronously, which means the started()
- and error() signals may be delayed. Call waitForStarted() to make
+ and errorOccurred() signals may be delayed. Call waitForStarted() to make
sure the process has started (or has failed to start) and those signals
have been emitted.
@@ -2147,6 +2207,16 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
mode &= ~QIODevice::ReadOnly; // not open for reading
if (mode == 0)
mode = QIODevice::Unbuffered;
+#ifndef Q_OS_WINCE
+ if ((mode & QIODevice::ReadOnly) == 0) {
+ if (stdoutChannel.type == QProcessPrivate::Channel::Normal)
+ q->setStandardOutputFile(q->nullDevice());
+ if (stderrChannel.type == QProcessPrivate::Channel::Normal
+ && processChannelMode != QProcess::MergedChannels)
+ q->setStandardErrorFile(q->nullDevice());
+ }
+#endif
+
q->QIODevice::open(mode);
stdinChannel.closed = false;
@@ -2226,15 +2296,26 @@ static QStringList parseCombinedArgString(const QString &program)
After the \a command string has been split and unquoted, this function
behaves like the overload which takes the arguments as a string list.
+ You can disable this overload by defining \c
+ QT_NO_PROCESS_COMBINED_ARGUMENT_START when you compile your applications.
+ This can be useful if you want to ensure that you are not splitting arguments
+ unintentionally, for example. In virtually all cases, using the other overload
+ is the preferred method.
+
+ On operating systems where the system API for passing command line
+ arguments to a subprocess natively uses a single string (Windows), one can
+ conceive command lines which cannot be passed via QProcess's portable
+ list-based API. In these rare cases you need to use setProgram() and
+ setNativeArguments() instead of this function.
+
*/
+#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
void QProcess::start(const QString &command, OpenMode mode)
{
QStringList args = parseCombinedArgString(command);
if (args.isEmpty()) {
Q_D(QProcess);
- d->processError = QProcess::FailedToStart;
- setErrorString(tr("No program defined"));
- emit error(d->processError);
+ d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
return;
}
@@ -2243,6 +2324,7 @@ void QProcess::start(const QString &command, OpenMode mode)
start(prog, args, mode);
}
+#endif
/*!
\since 5.0
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index 078217ea0b..f95358250e 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -60,9 +60,12 @@ public:
QProcessEnvironment();
QProcessEnvironment(const QProcessEnvironment &other);
~QProcessEnvironment();
+#ifdef Q_COMPILER_RVALUE_REFS
+ QProcessEnvironment &operator=(QProcessEnvironment && other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
QProcessEnvironment &operator=(const QProcessEnvironment &other);
- inline void swap(QProcessEnvironment &other) { qSwap(d, other.d); }
+ void swap(QProcessEnvironment &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
bool operator==(const QProcessEnvironment &other) const;
inline bool operator!=(const QProcessEnvironment &other) const
@@ -104,15 +107,21 @@ public:
WriteError,
UnknownError
};
+ Q_ENUM(ProcessError)
+
enum ProcessState {
NotRunning,
Starting,
Running
};
+ Q_ENUM(ProcessState)
+
enum ProcessChannel {
StandardOutput,
StandardError
};
+ Q_ENUM(ProcessChannel)
+
enum ProcessChannelMode {
SeparateChannels,
MergedChannels,
@@ -120,20 +129,27 @@ public:
ForwardedOutputChannel,
ForwardedErrorChannel
};
+ Q_ENUM(ProcessChannelMode)
+
enum InputChannelMode {
ManagedInputChannel,
ForwardedInputChannel
};
+ Q_ENUM(InputChannelMode)
+
enum ExitStatus {
NormalExit,
CrashExit
};
+ Q_ENUM(ExitStatus)
- explicit QProcess(QObject *parent = 0);
+ explicit QProcess(QObject *parent = Q_NULLPTR);
virtual ~QProcess();
void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite);
+#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
void start(const QString &command, OpenMode mode = ReadWrite);
+#endif
void start(OpenMode mode = ReadWrite);
bool open(OpenMode mode = ReadWrite) Q_DECL_OVERRIDE;
@@ -208,7 +224,7 @@ public:
#if defined(Q_QDOC)
= QString()
#endif
- , qint64 *pid = 0);
+ , qint64 *pid = Q_NULLPTR);
#if !defined(Q_QDOC)
static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads
#endif
@@ -226,7 +242,10 @@ Q_SIGNALS:
void started(QPrivateSignal);
void finished(int exitCode); // ### Qt 6: merge the two signals with a default value
void finished(int exitCode, QProcess::ExitStatus exitStatus);
- void error(QProcess::ProcessError error);
+#if QT_DEPRECATED_SINCE(5,6)
+ QT_MOC_COMPAT void error(QProcess::ProcessError error);
+#endif
+ void errorOccurred(QProcess::ProcessError error);
void stateChanged(QProcess::ProcessState state, QPrivateSignal);
void readyReadStandardOutput(QPrivateSignal);
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index f6bd64fb87..fc6b5345d1 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -383,6 +383,8 @@ public:
qint64 writeToStdin(const char *data, qint64 maxlen);
void cleanup();
+ void setError(QProcess::ProcessError error, const QString &description = QString());
+ void setErrorAndEmit(QProcess::ProcessError error, const QString &description = QString());
#ifdef Q_OS_BLACKBERRY
QList<QSocketNotifier *> defaultNotifiers() const;
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 7b6da90b04..63480dfc6b 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -93,7 +93,6 @@ QT_END_NAMESPACE
#include <qfile.h>
#include <qfileinfo.h>
#include <qlist.h>
-#include <qhash.h>
#include <qmutex.h>
#include <qsemaphore.h>
#include <qsocketnotifier.h>
@@ -204,8 +203,8 @@ bool QProcessPrivate::openChannel(Channel &channel)
channel.pipe[1] = -1;
if ( (channel.pipe[0] = qt_safe_open(fname, O_RDONLY)) != -1)
return true; // success
-
- q->setErrorString(QProcess::tr("Could not open input redirection for reading"));
+ setErrorAndEmit(QProcess::FailedToStart,
+ QProcess::tr("Could not open input redirection for reading"));
} else {
int mode = O_WRONLY | O_CREAT;
if (channel.append)
@@ -217,12 +216,9 @@ bool QProcessPrivate::openChannel(Channel &channel)
if ( (channel.pipe[1] = qt_safe_open(fname, mode, 0666)) != -1)
return true; // success
- q->setErrorString(QProcess::tr("Could not open output redirection for writing"));
+ setErrorAndEmit(QProcess::FailedToStart,
+ QProcess::tr("Could not open input redirection for reading"));
}
-
- // could not open file
- processError = QProcess::FailedToStart;
- emit q->error(processError);
cleanup();
return false;
} else {
@@ -331,9 +327,7 @@ void QProcessPrivate::startProcess()
!openChannel(stdoutChannel) ||
!openChannel(stderrChannel) ||
qt_create_pipe(childStartedPipe) != 0) {
- processError = QProcess::FailedToStart;
- q->setErrorString(qt_error_string(errno));
- emit q->error(processError);
+ setErrorAndEmit(QProcess::FailedToStart, qt_error_string(errno));
cleanup();
return;
}
@@ -406,7 +400,7 @@ void QProcessPrivate::startProcess()
char **path = 0;
int pathc = 0;
if (!program.contains(QLatin1Char('/'))) {
- const QString pathEnv = QString::fromLocal8Bit(::getenv("PATH"));
+ const QString pathEnv = QString::fromLocal8Bit(qgetenv("PATH"));
if (!pathEnv.isEmpty()) {
QStringList pathEntries = pathEnv.split(QLatin1Char(':'), QString::SkipEmptyParts);
if (!pathEntries.isEmpty()) {
@@ -459,9 +453,8 @@ void QProcessPrivate::startProcess()
qDebug("fork failed: %s", qPrintable(qt_error_string(lastForkErrno)));
#endif
q->setProcessState(QProcess::NotRunning);
- processError = QProcess::FailedToStart;
- q->setErrorString(QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno)));
- emit q->error(processError);
+ setErrorAndEmit(QProcess::FailedToStart,
+ QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno)));
cleanup();
return;
}
@@ -679,9 +672,9 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
qt_safe_close(childStartedPipe[0]);
// enter the working directory
- if (workingDir) {
- if (QT_CHDIR(workingDir) == -1)
- qWarning("QProcessPrivate::execChild() failed to chdir to %s", workingDir);
+ if (workingDir && QT_CHDIR(workingDir) == -1) {
+ // failed, stop the process
+ goto report_errno;
}
// this is a virtual call, and it base behavior is to do nothing.
@@ -710,6 +703,7 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
}
// notify failure
+report_errno:
QString error = qt_error_string(errno);
#if defined (QPROCESS_DEBUG)
fprintf(stderr, "QProcessPrivate::execChild() failed (%s), notifying parent process\n", qPrintable(error));
@@ -809,8 +803,6 @@ void QProcessPrivate::killProcess()
bool QProcessPrivate::waitForStarted(int msecs)
{
- Q_Q(QProcess);
-
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForStarted(%d) waiting for child to start (fd = %d)", msecs,
childStartedPipe[0]);
@@ -820,8 +812,7 @@ bool QProcessPrivate::waitForStarted(int msecs)
FD_ZERO(&fds);
FD_SET(childStartedPipe[0], &fds);
if (qt_select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) {
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForStarted(%d) == false (timed out)", msecs);
#endif
@@ -848,7 +839,6 @@ QList<QSocketNotifier *> QProcessPrivate::defaultNotifiers() const
bool QProcessPrivate::waitForReadyRead(int msecs)
{
- Q_Q(QProcess);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForReadyRead(%d)", msecs);
#endif
@@ -891,8 +881,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
break;
}
if (ret == 0) {
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
@@ -928,7 +917,6 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
bool QProcessPrivate::waitForBytesWritten(int msecs)
{
- Q_Q(QProcess);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForBytesWritten(%d)", msecs);
#endif
@@ -973,8 +961,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
}
if (ret == 0) {
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
@@ -1003,7 +990,6 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
bool QProcessPrivate::waitForFinished(int msecs)
{
- Q_Q(QProcess);
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForFinished(%d)", msecs);
#endif
@@ -1047,8 +1033,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
break;
}
if (ret == 0) {
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
@@ -1188,7 +1173,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
argv[arguments.size() + 1] = 0;
if (!program.contains(QLatin1Char('/'))) {
- const QString path = QString::fromLocal8Bit(::getenv("PATH"));
+ const QString path = QString::fromLocal8Bit(qgetenv("PATH"));
if (!path.isEmpty()) {
QStringList pathEntries = path.split(QLatin1Char(':'));
for (int k = 0; k < pathEntries.size(); ++k) {
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index eb88ded2c9..e77249975c 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -217,7 +217,8 @@ bool QProcessPrivate::openChannel(Channel &channel)
if (channel.pipe[0] != INVALID_Q_PIPE)
return true;
- q->setErrorString(QProcess::tr("Could not open input redirection for reading"));
+ setErrorAndEmit(QProcess::FailedToStart,
+ QProcess::tr("Could not open input redirection for reading"));
} else {
// open in write mode
channel.pipe[0] = INVALID_Q_PIPE;
@@ -237,12 +238,9 @@ bool QProcessPrivate::openChannel(Channel &channel)
return true;
}
- q->setErrorString(QProcess::tr("Could not open output redirection for writing"));
+ setErrorAndEmit(QProcess::FailedToStart,
+ QProcess::tr("Could not open output redirection for writing"));
}
-
- // could not open file
- processError = QProcess::FailedToStart;
- emit q->error(processError);
cleanup();
return false;
} else {
@@ -504,9 +502,10 @@ void QProcessPrivate::startProcess()
environment.isEmpty() ? 0 : envlist.data(),
workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(),
&startupInfo, pid);
+ QString errorString;
if (!success) {
// Capture the error string before we do CloseHandle below
- q->setErrorString(QProcess::tr("Process failed to start: %1").arg(qt_error_string()));
+ errorString = QProcess::tr("Process failed to start: %1").arg(qt_error_string());
}
if (stdinChannel.pipe[0] != INVALID_Q_PIPE) {
@@ -524,8 +523,7 @@ void QProcessPrivate::startProcess()
if (!success) {
cleanup();
- processError = QProcess::FailedToStart;
- emit q->error(processError);
+ setErrorAndEmit(QProcess::FailedToStart, errorString);
q->setProcessState(QProcess::NotRunning);
return;
}
@@ -595,16 +593,13 @@ void QProcessPrivate::killProcess()
bool QProcessPrivate::waitForStarted(int)
{
- Q_Q(QProcess);
-
if (processStarted())
return true;
if (processError == QProcess::FailedToStart)
return false;
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
@@ -636,8 +631,6 @@ bool QProcessPrivate::drainOutputPipes()
bool QProcessPrivate::waitForReadyRead(int msecs)
{
- Q_Q(QProcess);
-
QIncrementalSleepTimer timer(msecs);
forever {
@@ -652,7 +645,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
if (!pid)
return false;
- if (WaitForSingleObject(pid->hProcess, 0) == WAIT_OBJECT_0) {
+ if (WaitForSingleObjectEx(pid->hProcess, 0, false) == WAIT_OBJECT_0) {
bool readyReadEmitted = drainOutputPipes();
_q_processDied();
return readyReadEmitted;
@@ -663,15 +656,12 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
break;
}
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
bool QProcessPrivate::waitForBytesWritten(int msecs)
{
- Q_Q(QProcess);
-
QIncrementalSleepTimer timer(msecs);
forever {
@@ -723,7 +713,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
// Wait for the process to signal any change in its state,
// such as incoming data, or if the process died.
- if (WaitForSingleObject(pid->hProcess, 0) == WAIT_OBJECT_0) {
+ if (WaitForSingleObjectEx(pid->hProcess, 0, false) == WAIT_OBJECT_0) {
_q_processDied();
return false;
}
@@ -733,14 +723,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
break;
}
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
bool QProcessPrivate::waitForFinished(int msecs)
{
- Q_Q(QProcess);
#if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::waitForFinished(%d)", msecs);
#endif
@@ -772,8 +760,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
break;
}
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
@@ -816,13 +803,10 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
bool QProcessPrivate::waitForWrite(int msecs)
{
- Q_Q(QProcess);
-
if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(msecs))
return true;
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp
index 53767758c2..807472b7b2 100644
--- a/src/corelib/io/qprocess_wince.cpp
+++ b/src/corelib/io/qprocess_wince.cpp
@@ -138,8 +138,7 @@ void QProcessPrivate::startProcess()
if (!success) {
cleanup();
- processError = QProcess::FailedToStart;
- emit q->error(processError);
+ setErrorAndEmit(QProcess::FailedToStart);
q->setProcessState(QProcess::NotRunning);
return;
}
@@ -210,8 +209,7 @@ bool QProcessPrivate::waitForStarted(int)
if (processError == QProcess::FailedToStart)
return false;
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
@@ -251,8 +249,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (timer.hasTimedOut())
break;
}
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
+ setError(QProcess::Timedout);
return false;
}
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 6671333ffb..4e6079306b 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -35,7 +35,6 @@
#include "qresource_p.h"
#include "qresource_iterator_p.h"
#include "qset.h"
-#include "qhash.h"
#include "qmutex.h"
#include "qdebug.h"
#include "qlocale.h"
@@ -791,6 +790,7 @@ QStringList QResourceRoot::children(int node) const
offset += 4;
const int child_off = (tree[offset+0] << 24) + (tree[offset+1] << 16) +
(tree[offset+2] << 8) + (tree[offset+3] << 0);
+ ret.reserve(child_count);
for(int i = child_off; i < child_off+child_count; ++i)
ret << name(i);
}
diff --git a/src/corelib/io/qsavefile.h b/src/corelib/io/qsavefile.h
index 3f5f09bf5c..085378ed4e 100644
--- a/src/corelib/io/qsavefile.h
+++ b/src/corelib/io/qsavefile.h
@@ -58,7 +58,7 @@ class Q_CORE_EXPORT QSaveFile : public QFileDevice
public:
explicit QSaveFile(const QString &name);
- explicit QSaveFile(QObject *parent = 0);
+ explicit QSaveFile(QObject *parent = Q_NULLPTR);
explicit QSaveFile(const QString &name, QObject *parent);
~QSaveFile();
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 413f5693f0..da4a02e4e4 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -127,6 +127,7 @@ struct QConfFileCustomFormat
QSettings::WriteFunc writeFunc;
Qt::CaseSensitivity caseSensitivity;
};
+Q_DECLARE_TYPEINFO(QConfFileCustomFormat, Q_MOVABLE_TYPE);
typedef QHash<QString, QConfFile *> ConfFileHash;
typedef QCache<QString, QConfFile> ConfFileCache;
@@ -299,7 +300,7 @@ QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::F
}
#endif
-void QSettingsPrivate::processChild(QString key, ChildSpec spec, QMap<QString, QString> &result)
+void QSettingsPrivate::processChild(QStringRef key, ChildSpec spec, QStringList &result)
{
if (spec != AllKeys) {
int slashPos = key.indexOf(QLatin1Char('/'));
@@ -312,7 +313,7 @@ void QSettingsPrivate::processChild(QString key, ChildSpec spec, QMap<QString, Q
key.truncate(slashPos);
}
}
- result.insert(key, QString());
+ result.append(key.toString());
}
void QSettingsPrivate::beginGroupOrArray(const QSettingsGroup &group)
@@ -357,6 +358,7 @@ void QSettingsPrivate::requestUpdate()
QStringList QSettingsPrivate::variantListToStringList(const QVariantList &l)
{
QStringList result;
+ result.reserve(l.count());
QVariantList::const_iterator it = l.constBegin();
for (; it != l.constEnd(); ++it)
result.append(variantToString(*it));
@@ -374,7 +376,9 @@ QVariant QSettingsPrivate::stringListToVariantList(const QStringList &l)
outStringList[i].remove(0, 1);
} else {
QVariantList variantList;
- for (int j = 0; j < l.count(); ++j)
+ const int stringCount = l.count();
+ variantList.reserve(stringCount);
+ for (int j = 0; j < stringCount; ++j)
variantList.append(stringToVariant(l.at(j)));
return variantList;
}
@@ -1052,12 +1056,12 @@ static void initDefaultPaths(QMutexLocker *locker)
// Non XDG platforms (OS X, iOS, Blackberry, Android...) have used this code path erroneously
// for some time now. Moving away from that would require migrating existing settings.
QString userPath;
- char *env = getenv("XDG_CONFIG_HOME");
- if (env == 0) {
+ QByteArray env = qgetenv("XDG_CONFIG_HOME");
+ if (env.isEmpty()) {
userPath = QDir::homePath();
userPath += QLatin1Char('/');
userPath += QLatin1String(".config");
- } else if (*env == '/') {
+ } else if (env.startsWith('/')) {
userPath = QFile::decodeName(env);
} else {
userPath = QDir::homePath();
@@ -1269,7 +1273,7 @@ bool QConfFileSettingsPrivate::get(const QString &key, QVariant *value) const
QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec spec) const
{
- QMap<QString, QString> result;
+ QStringList result;
ParsedSettingsMap::const_iterator j;
QSettingsKey thePrefix(prefix, caseSensitivity);
@@ -1289,14 +1293,14 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec
&confFile->originalKeys)->lowerBound( thePrefix);
while (j != confFile->originalKeys.constEnd() && j.key().startsWith(thePrefix)) {
if (!confFile->removedKeys.contains(j.key()))
- processChild(j.key().originalCaseKey().mid(startPos), spec, result);
+ processChild(j.key().originalCaseKey().midRef(startPos), spec, result);
++j;
}
j = const_cast<const ParsedSettingsMap *>(
&confFile->addedKeys)->lowerBound(thePrefix);
while (j != confFile->addedKeys.constEnd() && j.key().startsWith(thePrefix)) {
- processChild(j.key().originalCaseKey().mid(startPos), spec, result);
+ processChild(j.key().originalCaseKey().midRef(startPos), spec, result);
++j;
}
@@ -1304,7 +1308,10 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec
break;
}
}
- return result.keys();
+ std::sort(result.begin(), result.end());
+ result.erase(std::unique(result.begin(), result.end()),
+ result.end());
+ return result;
}
void QConfFileSettingsPrivate::clear()
@@ -1755,6 +1762,7 @@ public:
int position;
};
+Q_DECLARE_TYPEINFO(QSettingsIniKey, Q_MOVABLE_TYPE);
static bool operator<(const QSettingsIniKey &k1, const QSettingsIniKey &k2)
{
diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h
index f7a7bdbb19..8f41273ffa 100644
--- a/src/corelib/io/qsettings.h
+++ b/src/corelib/io/qsettings.h
@@ -105,13 +105,13 @@ public:
#ifndef QT_NO_QOBJECT
explicit QSettings(const QString &organization,
- const QString &application = QString(), QObject *parent = 0);
+ const QString &application = QString(), QObject *parent = Q_NULLPTR);
QSettings(Scope scope, const QString &organization,
- const QString &application = QString(), QObject *parent = 0);
+ const QString &application = QString(), QObject *parent = Q_NULLPTR);
QSettings(Format format, Scope scope, const QString &organization,
- const QString &application = QString(), QObject *parent = 0);
- QSettings(const QString &fileName, Format format, QObject *parent = 0);
- explicit QSettings(QObject *parent = 0);
+ const QString &application = QString(), QObject *parent = Q_NULLPTR);
+ QSettings(const QString &fileName, Format format, QObject *parent = Q_NULLPTR);
+ explicit QSettings(QObject *parent = Q_NULLPTR);
#else
explicit QSettings(const QString &organization,
const QString &application = QString());
diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp
index 51321c49e7..1ad198b990 100644
--- a/src/corelib/io/qsettings_mac.cpp
+++ b/src/corelib/io/qsettings_mac.cpp
@@ -491,7 +491,7 @@ bool QMacSettingsPrivate::get(const QString &key, QVariant *value) const
QStringList QMacSettingsPrivate::children(const QString &prefix, ChildSpec spec) const
{
- QMap<QString, QString> result;
+ QStringList result;
int startPos = prefix.size();
for (int i = 0; i < numDomains; ++i) {
@@ -505,7 +505,7 @@ QStringList QMacSettingsPrivate::children(const QString &prefix, ChildSpec spec)
QString currentKey =
qtKey(static_cast<CFStringRef>(CFArrayGetValueAtIndex(cfarray, k)));
if (currentKey.startsWith(prefix))
- processChild(currentKey.mid(startPos), spec, result);
+ processChild(currentKey.midRef(startPos), spec, result);
}
}
}
@@ -513,7 +513,10 @@ QStringList QMacSettingsPrivate::children(const QString &prefix, ChildSpec spec)
if (!fallbacks)
break;
}
- return result.keys();
+ std::sort(result.begin(), result.end());
+ result.erase(std::unique(result.begin(), result.end()),
+ result.end());
+ return result;
}
void QMacSettingsPrivate::clear()
diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h
index 93d63fd411..5a3eb58a58 100644
--- a/src/corelib/io/qsettings_p.h
+++ b/src/corelib/io/qsettings_p.h
@@ -127,6 +127,7 @@ public:
int num;
int maxNum;
};
+Q_DECLARE_TYPEINFO(QSettingsGroup, Q_MOVABLE_TYPE);
inline QString QSettingsGroup::toString() const
{
@@ -211,7 +212,7 @@ public:
const QString &organization, const QString &application);
static QSettingsPrivate *create(const QString &fileName, QSettings::Format format);
- static void processChild(QString key, ChildSpec spec, QMap<QString, QString> &result);
+ static void processChild(QStringRef key, ChildSpec spec, QStringList &result);
// Variant streaming functions
static QStringList variantListToStringList(const QVariantList &l);
diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp
index 60b15f41a0..1546219c3b 100644
--- a/src/corelib/io/qsettings_win.cpp
+++ b/src/corelib/io/qsettings_win.cpp
@@ -319,11 +319,11 @@ private:
};
RegistryKey::RegistryKey(HKEY parent_handle, const QString &key, bool read_only)
+ : m_parent_handle(parent_handle),
+ m_handle(0),
+ m_key(key),
+ m_read_only(read_only)
{
- m_parent_handle = parent_handle;
- m_handle = 0;
- m_read_only = read_only;
- m_key = key;
}
QString RegistryKey::key() const
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 74252d1f0a..8828e09e8f 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -35,7 +35,6 @@
#include <qdir.h>
#include <qfileinfo.h>
-#include <qhash.h>
#ifndef QT_BOOTSTRAPPED
#include <qobject.h>
@@ -183,7 +182,7 @@ QT_BEGIN_NAMESPACE
\li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
\row \li GenericDataLocation
\li "~/Library/Application Support", "/Library/Application Support"
- \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
+ \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData", "<APPDIR>", "<APPDIR>/data"
\row \li RuntimeLocation
\li "~/Library/Application Support"
\li "C:/Users/<USER>"
@@ -523,13 +522,8 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr
QStringList searchPaths = paths;
if (paths.isEmpty()) {
QByteArray pEnv = qgetenv("PATH");
-#if defined(Q_OS_WIN)
- const QLatin1Char pathSep(';');
-#else
- const QLatin1Char pathSep(':');
-#endif
// Remove trailing slashes, which occur on Windows.
- const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, QString::SkipEmptyParts);
+ const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(QDir::listSeparator(), QString::SkipEmptyParts);
searchPaths.reserve(rawPaths.size());
foreach (const QString &rawPath, rawPaths) {
QString cleanPath = QDir::cleanPath(rawPath);
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index b1d5821a97..0a13f94f05 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -212,10 +212,8 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
}
dirs.append(result);
#ifndef QT_BOOTSTRAPPED
- if (type != GenericDataLocation) {
- dirs.append(QCoreApplication::applicationDirPath());
- dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data"));
- }
+ dirs.append(QCoreApplication::applicationDirPath());
+ dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data"));
#endif
}
break;
diff --git a/src/corelib/io/qstorageinfo.cpp b/src/corelib/io/qstorageinfo.cpp
index 337a9c7cef..99a2a1a42a 100644
--- a/src/corelib/io/qstorageinfo.cpp
+++ b/src/corelib/io/qstorageinfo.cpp
@@ -222,6 +222,18 @@ qint64 QStorageInfo::bytesTotal() const
}
/*!
+ \since 5.6
+ Returns the optimal transfer block size for this filesystem.
+
+ Returns -1 if QStorageInfo could not determine the size or if the QStorageInfo
+ object is not valid.
+ */
+int QStorageInfo::blockSize() const
+{
+ return d->blockSize;
+}
+
+/*!
Returns the type name of the filesystem.
This is a platform-dependent function, and filesystem names can vary
diff --git a/src/corelib/io/qstorageinfo.h b/src/corelib/io/qstorageinfo.h
index 848278e69f..c7a558bb4e 100644
--- a/src/corelib/io/qstorageinfo.h
+++ b/src/corelib/io/qstorageinfo.h
@@ -55,11 +55,10 @@ public:
QStorageInfo &operator=(const QStorageInfo &other);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QStorageInfo &operator=(QStorageInfo &&other)
- { qSwap(d, other.d); return *this; }
+ QStorageInfo &operator=(QStorageInfo &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- inline void swap(QStorageInfo &other)
+ inline void swap(QStorageInfo &other) Q_DECL_NOTHROW
{ qSwap(d, other.d); }
void setPath(const QString &path);
@@ -73,6 +72,7 @@ public:
qint64 bytesTotal() const;
qint64 bytesFree() const;
qint64 bytesAvailable() const;
+ int blockSize() const;
inline bool isRoot() const;
bool isReadOnly() const;
diff --git a/src/corelib/io/qstorageinfo_mac.cpp b/src/corelib/io/qstorageinfo_mac.cpp
index 539af33c5d..1ef9983918 100644
--- a/src/corelib/io/qstorageinfo_mac.cpp
+++ b/src/corelib/io/qstorageinfo_mac.cpp
@@ -76,6 +76,7 @@ void QStorageInfoPrivate::retrievePosixInfo()
device = QByteArray(statfs_buf.f_mntfromname);
readOnly = (statfs_buf.f_flags & MNT_RDONLY) != 0;
fileSystemType = QByteArray(statfs_buf.f_fstypename);
+ blockSize = statfs_buf.f_bsize;
}
}
diff --git a/src/corelib/io/qstorageinfo_p.h b/src/corelib/io/qstorageinfo_p.h
index 564321bedd..fb3bd8bd5b 100644
--- a/src/corelib/io/qstorageinfo_p.h
+++ b/src/corelib/io/qstorageinfo_p.h
@@ -53,7 +53,7 @@ class QStorageInfoPrivate : public QSharedData
{
public:
inline QStorageInfoPrivate() : QSharedData(),
- bytesTotal(-1), bytesFree(-1), bytesAvailable(-1),
+ bytesTotal(-1), bytesFree(-1), bytesAvailable(-1), blockSize(-1),
readOnly(false), ready(false), valid(false)
{}
@@ -84,6 +84,7 @@ public:
qint64 bytesTotal;
qint64 bytesFree;
qint64 bytesAvailable;
+ int blockSize;
bool readOnly;
bool ready;
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index bf1e6ce245..54a2855239 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -49,7 +49,7 @@
# include <sys/mount.h>
# include <sys/vfs.h>
# include <mntent.h>
-#elif defined(Q_OS_LINUX)
+#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
# include <mntent.h>
# include <sys/statvfs.h>
#elif defined(Q_OS_SOLARIS)
@@ -145,7 +145,7 @@ private:
QByteArray m_rootPath;
QByteArray m_fileSystemType;
QByteArray m_device;
-#elif defined(Q_OS_LINUX)
+#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
FILE *fp;
mntent mnt;
QByteArray buffer;
@@ -287,10 +287,11 @@ inline QByteArray QStorageIterator::device() const
return m_device;
}
-#elif defined(Q_OS_LINUX)
+#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
static const char pathMounted[] = "/etc/mtab";
-static const int bufferSize = 3*PATH_MAX; // 2 paths (mount point+device) and metainfo
+static const int bufferSize = 1024; // 2 paths (mount point+device) and metainfo;
+ // should be enough
inline QStorageIterator::QStorageIterator() :
buffer(QByteArray(bufferSize, 0))
@@ -509,6 +510,7 @@ void QStorageInfoPrivate::retrieveVolumeInfo()
bytesTotal = statfs_buf.f_blocks * statfs_buf.f_frsize;
bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize;
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize;
+ blockSize = statfs_buf.f_bsize;
#if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4)
#if defined(_STATFS_F_FLAGS)
readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0;
diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp
index 0beda22f24..c7150d7b33 100644
--- a/src/corelib/io/qtemporarydir.cpp
+++ b/src/corelib/io/qtemporarydir.cpp
@@ -38,6 +38,7 @@
#include "qdiriterator.h"
#include "qplatformdefs.h"
#include <QDebug>
+#include <QPair>
#if defined(QT_BUILD_CORE_LIB)
#include "qcoreapplication.h"
@@ -59,7 +60,7 @@ public:
void create(const QString &templateName);
- QString path;
+ QString pathOrError;
bool autoRemove;
bool success;
};
@@ -97,7 +98,7 @@ static int nextRand(int &v)
return r;
}
-static char *q_mkdtemp(char *templateName)
+QPair<QString, bool> q_mkdtemp(char *templateName)
{
static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
@@ -105,8 +106,7 @@ static char *q_mkdtemp(char *templateName)
char *XXXXXX = templateName + length - 6;
- if ((length < 6u) || strncmp(XXXXXX, "XXXXXX", 6))
- return 0;
+ Q_ASSERT((length >= 6u) && strncmp(XXXXXX, "XXXXXX", 6) == 0);
for (int i = 0; i < 256; ++i) {
int v = qrand();
@@ -133,17 +133,27 @@ static char *q_mkdtemp(char *templateName)
qWarning() << "Unable to remove unused directory" << templateNameStr;
continue;
}
- return templateName;
+ return qMakePair(QFile::decodeName(templateName), true);
}
+# ifdef Q_OS_WIN
+ const int exists = ERROR_ALREADY_EXISTS;
+ int code = GetLastError();
+# else
+ const int exists = EEXIST;
+ int code = errno;
+# endif
+ if (code != exists)
+ return qMakePair(qt_error_string(code), false);
}
- return 0;
+ return qMakePair(qt_error_string(), false);
}
#else // defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
-static char *q_mkdtemp(char *templateName)
+QPair<QString, bool> q_mkdtemp(char *templateName)
{
- return mkdtemp(templateName);
+ bool ok = (mkdtemp(templateName) != 0);
+ return qMakePair(ok ? QFile::decodeName(templateName) : qt_error_string(), ok);
}
#endif
@@ -153,10 +163,9 @@ void QTemporaryDirPrivate::create(const QString &templateName)
QByteArray buffer = QFile::encodeName(templateName);
if (!buffer.endsWith("XXXXXX"))
buffer += "XXXXXX";
- if (q_mkdtemp(buffer.data())) { // modifies buffer
- success = true;
- path = QFile::decodeName(buffer.constData());
- }
+ QPair<QString, bool> result = q_mkdtemp(buffer.data()); // modifies buffer
+ pathOrError = result.first;
+ success = result.second;
}
//************* QTemporaryDir
@@ -256,12 +265,24 @@ bool QTemporaryDir::isValid() const
}
/*!
+ \since 5.6
+
+ If isValid() returns \c false, this function returns the error string that
+ explains why the creation of the temporary directory failed. Otherwise, this
+ function return an empty string.
+*/
+QString QTemporaryDir::errorString() const
+{
+ return d_ptr->success ? QString() : d_ptr->pathOrError;
+}
+
+/*!
Returns the path to the temporary directory.
Empty if the QTemporaryDir could not be created.
*/
QString QTemporaryDir::path() const
{
- return d_ptr->path;
+ return d_ptr->success ? d_ptr->pathOrError : QString();
}
/*!
diff --git a/src/corelib/io/qtemporarydir.h b/src/corelib/io/qtemporarydir.h
index 8b98226529..ab6d841cdf 100644
--- a/src/corelib/io/qtemporarydir.h
+++ b/src/corelib/io/qtemporarydir.h
@@ -52,6 +52,7 @@ public:
~QTemporaryDir();
bool isValid() const;
+ QString errorString() const;
bool autoRemove() const;
void setAutoRemove(bool b);
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 68ac85fffd..e8e8d8c878 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -236,9 +236,9 @@ QTemporaryFileEngine::~QTemporaryFileEngine()
QFSFileEngine::close();
}
-bool QTemporaryFileEngine::isReallyOpen()
+bool QTemporaryFileEngine::isReallyOpen() const
{
- Q_D(QFSFileEngine);
+ Q_D(const QFSFileEngine);
if (!((0 == d->fh) && (-1 == d->fd)
#if defined Q_OS_WIN
diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h
index 2d4468fcf8..8002990270 100644
--- a/src/corelib/io/qtemporaryfile_p.h
+++ b/src/corelib/io/qtemporaryfile_p.h
@@ -91,7 +91,7 @@ public:
}
~QTemporaryFileEngine();
- bool isReallyOpen();
+ bool isReallyOpen() const;
void setFileName(const QString &file);
void setFileTemplate(const QString &fileTemplate);
diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h
index e5f429ae4d..eb33db63d7 100644
--- a/src/corelib/io/qtextstream.h
+++ b/src/corelib/io/qtextstream.h
@@ -205,8 +205,8 @@ typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument
class Q_CORE_EXPORT QTextStreamManipulator
{
public:
- QTextStreamManipulator(QTSMFI m, int a) { mf = m; mc = 0; arg = a; }
- QTextStreamManipulator(QTSMFC m, QChar c) { mf = 0; mc = m; ch = c; arg = -1; }
+ Q_DECL_CONSTEXPR QTextStreamManipulator(QTSMFI m, int a) Q_DECL_NOTHROW : mf(m), mc(Q_NULLPTR), arg(a), ch() {}
+ Q_DECL_CONSTEXPR QTextStreamManipulator(QTSMFC m, QChar c) Q_DECL_NOTHROW : mf(Q_NULLPTR), mc(m), arg(-1), ch(c) {}
void exec(QTextStream &s) { if (mf) { (s.*mf)(arg); } else { (s.*mc)(ch); } }
private:
diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp
index 2e787a1bc5..d68d0ddf46 100644
--- a/src/corelib/io/qtldurl.cpp
+++ b/src/corelib/io/qtldurl.cpp
@@ -37,7 +37,6 @@
#include "private/qtldurl_p.h"
#include "QtCore/qstring.h"
#include "QtCore/qvector.h"
-#include "QtCore/qhash.h"
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp
index 77d1ab3e24..2b695a4f7b 100644
--- a/src/corelib/io/qurlquery.cpp
+++ b/src/corelib/io/qurlquery.cpp
@@ -34,6 +34,7 @@
#include "qurlquery.h"
#include "qurl_p.h"
+#include <QtCore/qhashfunctions.h>
#include <QtCore/qstringlist.h>
QT_BEGIN_NAMESPACE
@@ -407,6 +408,7 @@ bool QUrlQuery::operator ==(const QUrlQuery &other) const
if (d == other.d)
return true;
if (d && other.d)
+ // keep in sync with qHash(QUrlQuery):
return d->valueDelimiter == other.d->valueDelimiter &&
d->pairDelimiter == other.d->pairDelimiter &&
d->itemList == other.d->itemList;
@@ -414,6 +416,25 @@ bool QUrlQuery::operator ==(const QUrlQuery &other) const
}
/*!
+ \since 5.6
+ \relates QUrlQuery
+
+ Returns the hash value for \a key,
+ using \a seed to seed the calculation.
+*/
+uint qHash(const QUrlQuery &key, uint seed) Q_DECL_NOTHROW
+{
+ if (const QUrlQueryPrivate *d = key.d) {
+ QtPrivate::QHashCombine hash;
+ // keep in sync with operator==:
+ seed = hash(seed, d->valueDelimiter);
+ seed = hash(seed, d->pairDelimiter);
+ seed = hash(seed, d->itemList);
+ }
+ return seed;
+}
+
+/*!
Returns \c true if this QUrlQuery object contains no key-value pairs, such as
after being default-constructed or after parsing an empty query string.
@@ -621,6 +642,7 @@ QList<QPair<QString, QString> > QUrlQuery::queryItems(QUrl::ComponentFormattingO
QList<QPair<QString, QString> > result;
Map::const_iterator it = d->itemList.constBegin();
Map::const_iterator end = d->itemList.constEnd();
+ result.reserve(d->itemList.count());
for ( ; it != end; ++it)
result << qMakePair(d->recodeToUser(it->first, encoding),
d->recodeToUser(it->second, encoding));
diff --git a/src/corelib/io/qurlquery.h b/src/corelib/io/qurlquery.h
index 77a0b4a82d..ae3a79c119 100644
--- a/src/corelib/io/qurlquery.h
+++ b/src/corelib/io/qurlquery.h
@@ -44,6 +44,8 @@
QT_BEGIN_NAMESPACE
+Q_CORE_EXPORT uint qHash(const QUrlQuery &key, uint seed = 0) Q_DECL_NOTHROW;
+
class QUrlQueryPrivate;
class Q_CORE_EXPORT QUrlQuery
{
@@ -54,8 +56,7 @@ public:
QUrlQuery(const QUrlQuery &other);
QUrlQuery &operator=(const QUrlQuery &other);
#ifdef Q_COMPILER_RVALUE_REFS
- QUrlQuery &operator=(QUrlQuery &&other)
- { qSwap(d, other.d); return *this; }
+ QUrlQuery &operator=(QUrlQuery &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
~QUrlQuery();
@@ -63,7 +64,7 @@ public:
bool operator!=(const QUrlQuery &other) const
{ return !(*this == other); }
- void swap(QUrlQuery &other) { qSwap(d, other.d); }
+ void swap(QUrlQuery &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
bool isEmpty() const;
bool isDetached() const;
@@ -95,6 +96,7 @@ public:
private:
friend class QUrl;
+ friend Q_CORE_EXPORT uint qHash(const QUrlQuery &key, uint seed) Q_DECL_NOTHROW;
QSharedDataPointer<QUrlQueryPrivate> d;
public:
typedef QSharedDataPointer<QUrlQueryPrivate> DataPtr;
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index 14aad0e193..2cc5741250 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -136,12 +136,12 @@ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
actualReadBufferSize--;
readSoFar = 1;
} else {
- qint64 bytesToRead = qMin(qint64(actualReadBufferSize), maxlen);
+ qint64 bytesToRead = qMin(actualReadBufferSize, maxlen);
readSoFar = 0;
while (readSoFar < bytesToRead) {
const char *ptr = readBuffer.readPointer();
- int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar,
- qint64(readBuffer.nextDataBlockSize()));
+ qint64 bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar,
+ readBuffer.nextDataBlockSize());
memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock);
readSoFar += bytesToReadFromThisBlock;
readBuffer.free(bytesToReadFromThisBlock);
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index 2c32eeb9ce..c8a66d9511 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -96,7 +96,7 @@ private:
QWinOverlappedIoNotifier *dataReadNotifier;
qint64 readBufferMaxSize;
QRingBuffer readBuffer;
- int actualReadBufferSize;
+ qint64 actualReadBufferSize;
bool stopped;
bool readSequenceStarted;
bool pipeBroken;
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 60ac75133c..90297b9115 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -479,6 +479,11 @@ public:
Q_GLOBAL_STATIC(QEmptyItemModel, qEmptyModel)
+
+QAbstractItemModelPrivate::~QAbstractItemModelPrivate()
+{
+}
+
QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel()
{
return qEmptyModel();
@@ -3217,6 +3222,7 @@ QModelIndexList QAbstractItemModel::persistentIndexList() const
{
Q_D(const QAbstractItemModel);
QModelIndexList result;
+ result.reserve(d->persistent.indexes.count());
for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = d->persistent.indexes.constBegin();
it != d->persistent.indexes.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h
index 5ca7bd0123..096e67c513 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.h
+++ b/src/corelib/itemmodels/qabstractitemmodel.h
@@ -49,7 +49,7 @@ class Q_CORE_EXPORT QModelIndex
{
friend class QAbstractItemModel;
public:
- Q_DECL_CONSTEXPR inline QModelIndex() Q_DECL_NOTHROW : r(-1), c(-1), i(0), m(0) {}
+ Q_DECL_CONSTEXPR inline QModelIndex() Q_DECL_NOTHROW : r(-1), c(-1), i(0), m(Q_NULLPTR) {}
// compiler-generated copy/move ctors/assignment operators are fine!
Q_DECL_CONSTEXPR inline int row() const Q_DECL_NOTHROW { return r; }
Q_DECL_CONSTEXPR inline int column() const Q_DECL_NOTHROW { return c; }
@@ -61,7 +61,7 @@ public:
inline QVariant data(int role = Qt::DisplayRole) const;
inline Qt::ItemFlags flags() const;
Q_DECL_CONSTEXPR inline const QAbstractItemModel *model() const Q_DECL_NOTHROW { return m; }
- Q_DECL_CONSTEXPR inline bool isValid() const Q_DECL_NOTHROW { return (r >= 0) && (c >= 0) && (m != 0); }
+ Q_DECL_CONSTEXPR inline bool isValid() const Q_DECL_NOTHROW { return (r >= 0) && (c >= 0) && (m != Q_NULLPTR); }
Q_DECL_CONSTEXPR inline bool operator==(const QModelIndex &other) const Q_DECL_NOTHROW
{ return (other.r == r) && (other.i == i) && (other.c == c) && (other.m == m); }
Q_DECL_CONSTEXPR inline bool operator!=(const QModelIndex &other) const Q_DECL_NOTHROW
@@ -161,7 +161,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject
friend class QIdentityProxyModel;
public:
- explicit QAbstractItemModel(QObject *parent = 0);
+ explicit QAbstractItemModel(QObject *parent = Q_NULLPTR);
virtual ~QAbstractItemModel();
Q_INVOKABLE bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const;
@@ -276,9 +276,9 @@ protected Q_SLOTS:
void resetInternalData();
protected:
- QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent = 0);
+ QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent = Q_NULLPTR);
- inline QModelIndex createIndex(int row, int column, void *data = 0) const;
+ inline QModelIndex createIndex(int row, int column, void *data = Q_NULLPTR) const;
inline QModelIndex createIndex(int row, int column, quintptr id) const;
void encodeData(const QModelIndexList &indexes, QDataStream &stream) const;
@@ -357,7 +357,7 @@ class Q_CORE_EXPORT QAbstractTableModel : public QAbstractItemModel
Q_OBJECT
public:
- explicit QAbstractTableModel(QObject *parent = 0);
+ explicit QAbstractTableModel(QObject *parent = Q_NULLPTR);
~QAbstractTableModel();
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
@@ -383,7 +383,7 @@ class Q_CORE_EXPORT QAbstractListModel : public QAbstractItemModel
Q_OBJECT
public:
- explicit QAbstractListModel(QObject *parent = 0);
+ explicit QAbstractListModel(QObject *parent = Q_NULLPTR);
~QAbstractListModel();
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
@@ -420,7 +420,7 @@ inline QVariant QModelIndex::data(int arole) const
{ return m ? m->data(*this, arole) : QVariant(); }
inline Qt::ItemFlags QModelIndex::flags() const
-{ return m ? m->flags(*this) : Qt::ItemFlags(0); }
+{ return m ? m->flags(*this) : Qt::ItemFlags(); }
inline uint qHash(const QModelIndex &index) Q_DECL_NOTHROW
{ return uint((index.row() << 4) + index.column() + index.internalId()); }
diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h
index 075e6a9018..c2cbaf5298 100644
--- a/src/corelib/itemmodels/qabstractitemmodel_p.h
+++ b/src/corelib/itemmodels/qabstractitemmodel_p.h
@@ -71,6 +71,8 @@ class Q_CORE_EXPORT QAbstractItemModelPrivate : public QObjectPrivate
public:
QAbstractItemModelPrivate() : QObjectPrivate(), supportedDragActions(-1), roleNames(defaultRoleNames()) {}
+ ~QAbstractItemModelPrivate();
+
void removePersistentIndexData(QPersistentModelIndexData *data);
void movePersistentIndexes(const QVector<QPersistentModelIndexData *> &indexes, int change, const QModelIndex &parent, Qt::Orientation orientation);
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
@@ -162,6 +164,7 @@ public:
QHash<int,QByteArray> roleNames;
static const QHash<int,QByteArray> &defaultRoleNames();
};
+Q_DECLARE_TYPEINFO(QAbstractItemModelPrivate::Change, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp
index 4d08306d28..dbbbbb8ff4 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.cpp
+++ b/src/corelib/itemmodels/qabstractproxymodel.cpp
@@ -379,6 +379,7 @@ QMimeData* QAbstractProxyModel::mimeData(const QModelIndexList &indexes) const
{
Q_D(const QAbstractProxyModel);
QModelIndexList list;
+ list.reserve(indexes.count());
foreach(const QModelIndex &index, indexes)
list << mapToSource(index);
return d->model->mimeData(list);
diff --git a/src/corelib/itemmodels/qabstractproxymodel.h b/src/corelib/itemmodels/qabstractproxymodel.h
index dc8d2d4dc8..a4cb74830b 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.h
+++ b/src/corelib/itemmodels/qabstractproxymodel.h
@@ -50,7 +50,7 @@ class Q_CORE_EXPORT QAbstractProxyModel : public QAbstractItemModel
Q_PROPERTY(QAbstractItemModel* sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged)
public:
- explicit QAbstractProxyModel(QObject *parent = 0);
+ explicit QAbstractProxyModel(QObject *parent = Q_NULLPTR);
~QAbstractProxyModel();
virtual void setSourceModel(QAbstractItemModel *sourceModel);
diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp
index f773219aeb..f46fd135ca 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.cpp
+++ b/src/corelib/itemmodels/qidentityproxymodel.cpp
@@ -212,6 +212,7 @@ QItemSelection QIdentityProxyModel::mapSelectionFromSource(const QItemSelection&
QItemSelection::const_iterator it = selection.constBegin();
const QItemSelection::const_iterator end = selection.constEnd();
+ proxySelection.reserve(selection.count());
for ( ; it != end; ++it) {
Q_ASSERT(it->model() == d->model);
const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight()));
@@ -234,6 +235,7 @@ QItemSelection QIdentityProxyModel::mapSelectionToSource(const QItemSelection& s
QItemSelection::const_iterator it = selection.constBegin();
const QItemSelection::const_iterator end = selection.constEnd();
+ sourceSelection.reserve(selection.count());
for ( ; it != end; ++it) {
Q_ASSERT(it->model() == this);
const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight()));
@@ -269,6 +271,7 @@ QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, c
QModelIndexList::const_iterator it = sourceList.constBegin();
const QModelIndexList::const_iterator end = sourceList.constEnd();
QModelIndexList proxyList;
+ proxyList.reserve(sourceList.count());
for ( ; it != end; ++it)
proxyList.append(mapFromSource(*it));
return proxyList;
diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h
index e4587cb386..7578f8d380 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.h
+++ b/src/corelib/itemmodels/qidentityproxymodel.h
@@ -48,7 +48,7 @@ class Q_CORE_EXPORT QIdentityProxyModel : public QAbstractProxyModel
{
Q_OBJECT
public:
- explicit QIdentityProxyModel(QObject* parent = 0);
+ explicit QIdentityProxyModel(QObject* parent = Q_NULLPTR);
~QIdentityProxyModel();
int columnCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index de28953fb5..ba97543c44 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -104,6 +104,14 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn QItemSelectionRange::swap(QItemSelectionRange &other)
+ \since 5.6
+
+ Swaps this selection range's contents with \a other.
+ This function is very fast and never fails.
+*/
+
+/*!
\fn int QItemSelectionRange::top() const
Returns the row index corresponding to the uppermost selected row in the
@@ -1770,7 +1778,7 @@ const QAbstractItemModel *QItemSelectionModel::model() const
/*!
\since 5.5
- Sets the model. The modelChanged() signal will be emitted.
+ Sets the model to \a model. The modelChanged() signal will be emitted.
\sa model(), modelChanged()
*/
diff --git a/src/corelib/itemmodels/qitemselectionmodel.h b/src/corelib/itemmodels/qitemselectionmodel.h
index 4fe836c098..09b710175e 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.h
+++ b/src/corelib/itemmodels/qitemselectionmodel.h
@@ -48,12 +48,28 @@ class Q_CORE_EXPORT QItemSelectionRange
{
public:
- inline QItemSelectionRange() {}
+ inline QItemSelectionRange() : tl(), br() {}
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ // ### Qt 6: remove them all, the compiler-generated ones are fine
inline QItemSelectionRange(const QItemSelectionRange &other)
: tl(other.tl), br(other.br) {}
- inline QItemSelectionRange(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- explicit inline QItemSelectionRange(const QModelIndex &index)
- { tl = index; br = tl; }
+# ifdef Q_COMPILER_RVALUE_REFS
+ QItemSelectionRange(QItemSelectionRange &&other) Q_DECL_NOTHROW
+ : tl(std::move(other.tl)), br(std::move(other.br)) {}
+ QItemSelectionRange &operator=(QItemSelectionRange &&other) Q_DECL_NOTHROW
+ { tl = std::move(other.tl); br = std::move(other.br); return *this; }
+# endif
+ QItemSelectionRange &operator=(const QItemSelectionRange &other)
+ { tl = other.tl; br = other.br; return *this; }
+#endif // Qt < 6
+ QItemSelectionRange(const QModelIndex &topL, const QModelIndex &bottomR) : tl(topL), br(bottomR) {}
+ explicit QItemSelectionRange(const QModelIndex &index) : tl(index), br(tl) {}
+
+ void swap(QItemSelectionRange &other) Q_DECL_NOTHROW
+ {
+ qSwap(tl, other.tl);
+ qSwap(br, other.br);
+ }
inline int top() const { return tl.row(); }
inline int left() const { return tl.column(); }
@@ -133,10 +149,6 @@ private:
};
Q_DECLARE_TYPEINFO(QItemSelectionRange, Q_MOVABLE_TYPE);
-inline QItemSelectionRange::QItemSelectionRange(const QModelIndex &atopLeft,
- const QModelIndex &abottomRight)
-{ tl = atopLeft; br = abottomRight; }
-
class QItemSelection;
class QItemSelectionModelPrivate;
@@ -170,7 +182,7 @@ public:
Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag)
Q_FLAG(SelectionFlags)
- explicit QItemSelectionModel(QAbstractItemModel *model = 0);
+ explicit QItemSelectionModel(QAbstractItemModel *model = Q_NULLPTR);
explicit QItemSelectionModel(QAbstractItemModel *model, QObject *parent);
virtual ~QItemSelectionModel();
@@ -235,8 +247,11 @@ inline uint qHash(const QItemSelectionRange &) { return 0; }
class Q_CORE_EXPORT QItemSelection : public QList<QItemSelectionRange>
{
public:
- QItemSelection() {}
+ QItemSelection() Q_DECL_NOTHROW : QList<QItemSelectionRange>() {}
QItemSelection(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+
+ // reusing QList::swap() here is OK!
+
void select(const QModelIndex &topLeft, const QModelIndex &bottomRight);
bool contains(const QModelIndex &index) const;
QModelIndexList indexes() const;
@@ -245,6 +260,7 @@ public:
const QItemSelectionRange &other,
QItemSelection *result);
};
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QItemSelection)
#ifndef QT_NO_DEBUG_STREAM
Q_CORE_EXPORT QDebug operator<<(QDebug, const QItemSelectionRange &);
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 6853cbd38f..0771fd0e30 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -272,6 +272,7 @@ public:
QModelIndexPairList store_persistent_indexes();
void update_persistent_indexes(const QModelIndexPairList &source_indexes);
+ void filter_about_to_be_changed(const QModelIndex &source_parent = QModelIndex());
void filter_changed(const QModelIndex &source_parent = QModelIndex());
QSet<int> handle_filter_changed(
QVector<int> &source_to_proxy, QVector<int> &proxy_to_source,
@@ -1011,6 +1012,7 @@ QModelIndexPairList QSortFilterProxyModelPrivate::store_persistent_indexes()
{
Q_Q(QSortFilterProxyModel);
QModelIndexPairList source_indexes;
+ source_indexes.reserve(persistent.indexes.count());
foreach (QPersistentModelIndexData *data, persistent.indexes) {
QModelIndex proxy_index = data->index;
QModelIndex source_index = q->mapToSource(proxy_index);
@@ -1030,7 +1032,10 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes(
{
Q_Q(QSortFilterProxyModel);
QModelIndexList from, to;
- for (int i = 0; i < source_indexes.count(); ++i) {
+ const int numSourceIndexes = source_indexes.count();
+ from.reserve(numSourceIndexes);
+ to.reserve(numSourceIndexes);
+ for (int i = 0; i < numSourceIndexes; ++i) {
QModelIndex source_index = source_indexes.at(i).second;
QModelIndex old_proxy_index = source_indexes.at(i).first;
create_mapping(source_index.parent());
@@ -1041,6 +1046,19 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes(
q->changePersistentIndexList(from, to);
}
+/*!
+ \internal
+
+ Updates the source_index mapping in case it's invalid and we
+ need it because we have a valid filter
+*/
+void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent)
+{
+ if (!filter_regexp.pattern().isEmpty() &&
+ source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd())
+ create_mapping(source_parent);
+}
+
/*!
\internal
@@ -2013,7 +2031,9 @@ QMimeData *QSortFilterProxyModel::mimeData(const QModelIndexList &indexes) const
{
Q_D(const QSortFilterProxyModel);
QModelIndexList source_indexes;
- for (int i = 0; i < indexes.count(); ++i)
+ const int numIndexes = indexes.count();
+ source_indexes.reserve(numIndexes);
+ for (int i = 0; i < numIndexes; ++i)
source_indexes << mapToSource(indexes.at(i));
return d->model->mimeData(source_indexes);
}
@@ -2108,6 +2128,7 @@ bool QSortFilterProxyModel::removeRows(int row, int count, const QModelIndex &pa
// remove corresponding source intervals
// ### if this proves to be slow, we can switch to single-row removal
QVector<int> rows;
+ rows.reserve(count);
for (int i = row; i < row + count; ++i)
rows.append(m->source_rows.at(i));
std::sort(rows.begin(), rows.end());
@@ -2147,6 +2168,7 @@ bool QSortFilterProxyModel::removeColumns(int column, int count, const QModelInd
}
// remove corresponding source intervals
QVector<int> columns;
+ columns.reserve(count);
for (int i = column; i < column + count; ++i)
columns.append(m->source_columns.at(i));
@@ -2298,6 +2320,7 @@ QRegExp QSortFilterProxyModel::filterRegExp() const
void QSortFilterProxyModel::setFilterRegExp(const QRegExp &regExp)
{
Q_D(QSortFilterProxyModel);
+ d->filter_about_to_be_changed();
d->filter_regexp = regExp;
d->filter_changed();
}
@@ -2319,6 +2342,7 @@ int QSortFilterProxyModel::filterKeyColumn() const
void QSortFilterProxyModel::setFilterKeyColumn(int column)
{
Q_D(QSortFilterProxyModel);
+ d->filter_about_to_be_changed();
d->filter_column = column;
d->filter_changed();
}
@@ -2344,6 +2368,7 @@ void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs)
Q_D(QSortFilterProxyModel);
if (cs == d->filter_regexp.caseSensitivity())
return;
+ d->filter_about_to_be_changed();
d->filter_regexp.setCaseSensitivity(cs);
d->filter_changed();
}
@@ -2409,6 +2434,7 @@ void QSortFilterProxyModel::setSortLocaleAware(bool on)
void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
{
Q_D(QSortFilterProxyModel);
+ d->filter_about_to_be_changed();
d->filter_regexp.setPatternSyntax(QRegExp::RegExp);
d->filter_regexp.setPattern(pattern);
d->filter_changed();
@@ -2423,6 +2449,7 @@ void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
void QSortFilterProxyModel::setFilterWildcard(const QString &pattern)
{
Q_D(QSortFilterProxyModel);
+ d->filter_about_to_be_changed();
d->filter_regexp.setPatternSyntax(QRegExp::Wildcard);
d->filter_regexp.setPattern(pattern);
d->filter_changed();
@@ -2437,6 +2464,7 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern)
void QSortFilterProxyModel::setFilterFixedString(const QString &pattern)
{
Q_D(QSortFilterProxyModel);
+ d->filter_about_to_be_changed();
d->filter_regexp.setPatternSyntax(QRegExp::FixedString);
d->filter_regexp.setPattern(pattern);
d->filter_changed();
@@ -2516,6 +2544,7 @@ void QSortFilterProxyModel::setFilterRole(int role)
Q_D(QSortFilterProxyModel);
if (d->filter_role == role)
return;
+ d->filter_about_to_be_changed();
d->filter_role = role;
d->filter_changed();
}
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h
index a08d7c6416..4be5aedd48 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.h
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.h
@@ -63,7 +63,7 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole)
public:
- explicit QSortFilterProxyModel(QObject *parent = 0);
+ explicit QSortFilterProxyModel(QObject *parent = Q_NULLPTR);
~QSortFilterProxyModel();
void setSourceModel(QAbstractItemModel *sourceModel) Q_DECL_OVERRIDE;
diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp
index 2853be3fda..dad736b445 100644
--- a/src/corelib/itemmodels/qstringlistmodel.cpp
+++ b/src/corelib/itemmodels/qstringlistmodel.cpp
@@ -257,7 +257,9 @@ void QStringListModel::sort(int, Qt::SortOrder order)
emit layoutAboutToBeChanged(QList<QPersistentModelIndex>(), VerticalSortHint);
QList<QPair<QString, int> > list;
- for (int i = 0; i < lst.count(); ++i)
+ const int lstCount = lst.count();
+ list.reserve(lstCount);
+ for (int i = 0; i < lstCount; ++i)
list.append(QPair<QString, int>(lst.at(i), i));
if (order == Qt::AscendingOrder)
diff --git a/src/corelib/itemmodels/qstringlistmodel.h b/src/corelib/itemmodels/qstringlistmodel.h
index 973007995b..a1cb923dbb 100644
--- a/src/corelib/itemmodels/qstringlistmodel.h
+++ b/src/corelib/itemmodels/qstringlistmodel.h
@@ -46,8 +46,8 @@ class Q_CORE_EXPORT QStringListModel : public QAbstractListModel
{
Q_OBJECT
public:
- explicit QStringListModel(QObject *parent = 0);
- explicit QStringListModel(const QStringList &strings, QObject *parent = 0);
+ explicit QStringListModel(QObject *parent = Q_NULLPTR);
+ explicit QStringListModel(const QStringList &strings, QObject *parent = Q_NULLPTR);
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex sibling(int row, int column, const QModelIndex &idx) const Q_DECL_OVERRIDE;
diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp
index 77a3d0a2b8..dd27603d6d 100644
--- a/src/corelib/json/qjsonarray.cpp
+++ b/src/corelib/json/qjsonarray.cpp
@@ -271,6 +271,7 @@ QVariantList QJsonArray::toVariantList() const
QVariantList list;
if (a) {
+ list.reserve(a->length);
for (int i = 0; i < (int)a->length; ++i)
list.append(QJsonValue(d, a, a->at(i)).toVariant());
}
diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h
index 6148642106..611e1f4193 100644
--- a/src/corelib/json/qjsonarray.h
+++ b/src/corelib/json/qjsonarray.h
@@ -107,7 +107,7 @@ public:
typedef QJsonValueRef reference;
typedef QJsonValueRefPtr pointer;
- inline iterator() : a(0), i(0) { }
+ inline iterator() : a(Q_NULLPTR), i(0) { }
explicit inline iterator(QJsonArray *array, int index) : a(array), i(index) { }
inline QJsonValueRef operator*() const { return QJsonValueRef(a, i); }
@@ -152,9 +152,11 @@ public:
typedef QJsonValue reference;
typedef QJsonValuePtr pointer;
- inline const_iterator() : a(0), i(0) { }
+ inline const_iterator() : a(Q_NULLPTR), i(0) { }
explicit inline const_iterator(const QJsonArray *array, int index) : a(array), i(index) { }
- inline const_iterator(const const_iterator &o) : a(o.a), i(o.i) {}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ inline const_iterator(const const_iterator &o) : a(o.a), i(o.i) {} // ### Qt 6: Removed so class can be trivially-copyable
+#endif
inline const_iterator(const iterator &o) : a(o.a), i(o.i) {}
inline QJsonValue operator*() const { return a->at(i); }
diff --git a/src/corelib/json/qjsondocument.h b/src/corelib/json/qjsondocument.h
index 285b42c6c8..d7a88b2f15 100644
--- a/src/corelib/json/qjsondocument.h
+++ b/src/corelib/json/qjsondocument.h
@@ -106,7 +106,7 @@ public:
Compact
};
- static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = 0);
+ static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR);
#ifdef Q_QDOC
QByteArray toJson(JsonFormat format = Indented) const;
diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp
index ae44cd9ff9..b7dfe88434 100644
--- a/src/corelib/json/qjsonobject.cpp
+++ b/src/corelib/json/qjsonobject.cpp
@@ -274,7 +274,7 @@ QStringList QJsonObject::keys() const
return QStringList();
QStringList keys;
-
+ keys.reserve(o->length);
for (uint i = 0; i < o->length; ++i) {
QJsonPrivate::Entry *e = o->entryAt(i);
keys.append(e->key());
diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h
index 5f24ac3ac8..19c938fd83 100644
--- a/src/corelib/json/qjsonobject.h
+++ b/src/corelib/json/qjsonobject.h
@@ -105,7 +105,7 @@ public:
typedef QJsonValue value_type;
typedef QJsonValueRef reference;
- Q_DECL_CONSTEXPR inline iterator() : o(0), i(0) {}
+ Q_DECL_CONSTEXPR inline iterator() : o(Q_NULLPTR), i(0) {}
Q_DECL_CONSTEXPR inline iterator(QJsonObject *obj, int index) : o(obj), i(index) {}
inline QString key() const { return o->keyAt(i); }
@@ -147,7 +147,7 @@ public:
typedef QJsonValue value_type;
typedef QJsonValue reference;
- Q_DECL_CONSTEXPR inline const_iterator() : o(0), i(0) {}
+ Q_DECL_CONSTEXPR inline const_iterator() : o(Q_NULLPTR), i(0) {}
Q_DECL_CONSTEXPR inline const_iterator(const QJsonObject *obj, int index)
: o(obj), i(index) {}
inline const_iterator(const iterator &other)
diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h
index c80f7d3d08..eb357cefe5 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.h
+++ b/src/corelib/kernel/qabstracteventdispatcher.h
@@ -64,10 +64,10 @@ public:
{ }
};
- explicit QAbstractEventDispatcher(QObject *parent = 0);
+ explicit QAbstractEventDispatcher(QObject *parent = Q_NULLPTR);
~QAbstractEventDispatcher();
- static QAbstractEventDispatcher *instance(QThread *thread = 0);
+ static QAbstractEventDispatcher *instance(QThread *thread = Q_NULLPTR);
virtual bool processEvents(QEventLoop::ProcessEventsFlags flags) = 0;
virtual bool hasPendingEvents() = 0; // ### Qt6: remove, mark final or make protected
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index a215557aed..14c0f803b9 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -131,5 +131,22 @@ QAppleOperatingSystemVersion qt_apple_os_version()
return v;
}
+// -------------------------------------------------------------------------
+
+QMacAutoReleasePool::QMacAutoReleasePool()
+ : pool([[NSAutoreleasePool alloc] init])
+{
+}
+
+QMacAutoReleasePool::~QMacAutoReleasePool()
+{
+ // Drain behaves the same as release, with the advantage that
+ // if we're ever used in a garbage-collected environment, the
+ // drain acts as a hint to the garbage collector to collect.
+ [pool drain];
+}
+
+// -------------------------------------------------------------------------
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index fa083a3f44..c744873fce 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -67,24 +67,6 @@
struct sockaddr;
-#if defined(Q_OS_LINUX) && defined(O_CLOEXEC)
-# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1
-QT_BEGIN_NAMESPACE
-namespace QtLibcSupplement {
- inline int accept4(int, sockaddr *, QT_SOCKLEN_T *, int)
- { errno = ENOSYS; return -1; }
- inline int dup3(int, int, int)
- { errno = ENOSYS; return -1; }
- inline int pipe2(int [], int )
- { errno = ENOSYS; return -1; }
-}
-QT_END_NAMESPACE
-using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement);
-
-#else
-# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0
-#endif
-
#define EINTR_LOOP(var, cmd) \
do { \
var = cmd; \
@@ -179,22 +161,14 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07
// call qt_safe_pipe
static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
{
-#ifdef O_CLOEXEC
- Q_ASSERT((flags & ~(O_CLOEXEC | O_NONBLOCK)) == 0);
-#else
Q_ASSERT((flags & ~O_NONBLOCK) == 0);
-#endif
- int ret;
-#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC)
+#ifdef QT_THREADSAFE_CLOEXEC
// use pipe2
flags |= O_CLOEXEC;
- ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR
- if (ret == 0 || errno != ENOSYS)
- return ret;
-#endif
-
- ret = ::pipe(pipefd);
+ return ::pipe2(pipefd, flags); // pipe2 is documented not to return EINTR
+#else
+ int ret = ::pipe(pipefd);
if (ret == -1)
return -1;
@@ -208,6 +182,7 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
}
return 0;
+#endif
}
#endif // Q_OS_VXWORKS
@@ -217,22 +192,19 @@ static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC
{
Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
- int ret;
#ifdef F_DUPFD_CLOEXEC
- // use this fcntl
- if (flags & FD_CLOEXEC) {
- ret = ::fcntl(oldfd, F_DUPFD_CLOEXEC, atleast);
- if (ret != -1 || errno != EINVAL)
- return ret;
- }
-#endif
-
+ int cmd = F_DUPFD;
+ if (flags & FD_CLOEXEC)
+ cmd = F_DUPFD_CLOEXEC;
+ return ::fcntl(oldfd, cmd, atleast);
+#else
// use F_DUPFD
- ret = ::fcntl(oldfd, F_DUPFD, atleast);
+ int ret = ::fcntl(oldfd, F_DUPFD, atleast);
if (flags && ret != -1)
::fcntl(ret, F_SETFD, flags);
return ret;
+#endif
}
// don't call dup2
@@ -242,14 +214,11 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC)
Q_ASSERT(flags == FD_CLOEXEC || flags == 0);
int ret;
-#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC)
+#ifdef QT_THREADSAFE_CLOEXEC
// use dup3
- if (flags & FD_CLOEXEC) {
- EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC));
- if (ret == 0 || errno != ENOSYS)
- return ret;
- }
-#endif
+ EINTR_LOOP(ret, ::dup3(oldfd, newfd, flags ? O_CLOEXEC : 0));
+ return ret;
+#else
EINTR_LOOP(ret, ::dup2(oldfd, newfd));
if (ret == -1)
return -1;
@@ -257,6 +226,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC)
if (flags)
::fcntl(newfd, F_SETFD, flags);
return 0;
+#endif
}
static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 37a26cf556..8f4774a1e0 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Intel Corporation.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -45,7 +46,6 @@
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
-#include <qhash.h>
#include <qmutex.h>
#include <private/qloggingregistry_p.h>
#include <qstandardpaths.h>
@@ -323,15 +323,9 @@ uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandled
struct QCoreApplicationData {
QCoreApplicationData() Q_DECL_NOTHROW {
-#ifndef QT_NO_LIBRARY
- app_libpaths = 0;
-#endif
applicationNameSet = false;
}
~QCoreApplicationData() {
-#ifndef QT_NO_LIBRARY
- delete app_libpaths;
-#endif
#ifndef QT_NO_QOBJECT
// cleanup the QAdoptedThread created for the main() thread
if (QCoreApplicationPrivate::theMainThread) {
@@ -375,7 +369,8 @@ struct QCoreApplicationData {
bool applicationNameSet; // true if setApplicationName was called
#ifndef QT_NO_LIBRARY
- QStringList *app_libpaths;
+ QScopedPointer<QStringList> app_libpaths;
+ QScopedPointer<QStringList> manual_libpaths;
#endif
};
@@ -538,6 +533,14 @@ QThread *QCoreApplicationPrivate::mainThread()
return theMainThread;
}
+bool QCoreApplicationPrivate::threadRequiresCoreApplication()
+{
+ QThreadData *data = QThreadData::current(false);
+ if (!data)
+ return true; // default setting
+ return data->requiresCoreApplication;
+}
+
void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
{
QThread *currentThread = QThread::currentThread();
@@ -560,9 +563,9 @@ void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
{
#ifndef QT_NO_LIBRARY
- QStringList *app_libpaths = coreappdata()->app_libpaths;
+ QStringList *app_libpaths = coreappdata()->app_libpaths.data();
if (!app_libpaths)
- coreappdata()->app_libpaths = app_libpaths = new QStringList;
+ coreappdata()->app_libpaths.reset(app_libpaths = new QStringList);
QString app_location = QCoreApplication::applicationFilePath();
app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
#ifdef Q_OS_WINRT
@@ -759,6 +762,36 @@ void QCoreApplication::init()
QLoggingRegistry::instance()->init();
+#ifndef QT_NO_LIBRARY
+ // Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
+ // into account. If necessary, recompute right away and replay the manual changes on top of the
+ // new lib paths.
+ QStringList *appPaths = coreappdata()->app_libpaths.take();
+ QStringList *manualPaths = coreappdata()->manual_libpaths.take();
+ if (appPaths) {
+ if (manualPaths) {
+ // Replay the delta. As paths can only be prepended to the front or removed from
+ // anywhere in the list, we can just linearly scan the lists and find the items that
+ // have been removed. Once the original list is exhausted we know all the remaining
+ // items have been added.
+ QStringList newPaths(libraryPaths());
+ for (int i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) {
+ if (--j < 0) {
+ newPaths.prepend((*manualPaths)[--i]);
+ } else if (--i < 0) {
+ newPaths.removeAll((*appPaths)[j]);
+ } else if ((*manualPaths)[i] != (*appPaths)[j]) {
+ newPaths.removeAll((*appPaths)[j]);
+ ++i; // try again with next item.
+ }
+ }
+ delete manualPaths;
+ coreappdata()->manual_libpaths.reset(new QStringList(newPaths));
+ }
+ delete appPaths;
+ }
+#endif
+
#ifndef QT_NO_QOBJECT
// use the event dispatcher created by the app programmer (if any)
if (!QCoreApplicationPrivate::eventDispatcher)
@@ -777,11 +810,6 @@ void QCoreApplication::init()
d->eventDispatcherReady();
#endif
-#ifndef QT_NO_LIBRARY
- if (coreappdata()->app_libpaths)
- d->appendApplicationPathToLibraryPaths();
-#endif
-
#ifdef QT_EVAL
extern void qt_core_eval_init(QCoreApplicationPrivate::Type);
qt_core_eval_init(d->application_type);
@@ -834,8 +862,8 @@ QCoreApplication::~QCoreApplication()
#endif
#ifndef QT_NO_LIBRARY
- delete coreappdata()->app_libpaths;
- coreappdata()->app_libpaths = 0;
+ coreappdata()->app_libpaths.reset();
+ coreappdata()->manual_libpaths.reset();
#endif
}
@@ -909,31 +937,21 @@ bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
/*!
\property QCoreApplication::quitLockEnabled
- Returns \c true if the use of the QEventLoopLocker feature can cause the
- application to quit, otherwise returns \c false.
+ \brief Whether the use of the QEventLoopLocker feature can cause the
+ application to quit.
+
+ The default is \c true.
\sa QEventLoopLocker
*/
-/*!
- Returns \c true if the use of the QEventLoopLocker feature can cause the
- application to quit, otherwise returns \c false.
-
- \sa QEventLoopLocker
- */
bool QCoreApplication::isQuitLockEnabled()
{
return quitLockRefEnabled;
}
-/*!
- Enables the ability of the QEventLoopLocker feature to quit
- the application.
-
- If disabled, the use of QEventLoopLocker will not quit the application.
+static bool doNotify(QObject *, QEvent *);
- \sa QEventLoopLocker
- */
void QCoreApplication::setQuitLockEnabled(bool enabled)
{
quitLockRefEnabled = enabled;
@@ -941,12 +959,29 @@ void QCoreApplication::setQuitLockEnabled(bool enabled)
/*!
\internal
+ \deprecated
This function is here to make it possible for Qt extensions to
hook into event notification without subclassing QApplication
*/
bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
{
+ return notifyInternal2(receiver, event);
+}
+
+/*!
+ \internal
+ \since 5.6
+
+ This function is here to make it possible for Qt extensions to
+ hook into event notification without subclassing QApplication.
+*/
+bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
+{
+ bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication();
+ if (!self && selfRequired)
+ return false;
+
// Make it possible for Qt Script to hook into events even
// though QApplication is subclassed...
bool result = false;
@@ -962,10 +997,11 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
QObjectPrivate *d = receiver->d_func();
QThreadData *threadData = d->threadData;
QScopedLoopLevelCounter loopLevelCounter(threadData);
- return notify(receiver, event);
+ if (!selfRequired)
+ return doNotify(receiver, event);
+ return self->notify(receiver, event);
}
-
/*!
Sends \a event to \a receiver: \a {receiver}->event(\a event).
Returns the value that is returned from the receiver's event
@@ -1021,26 +1057,32 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
bool QCoreApplication::notify(QObject *receiver, QEvent *event)
{
- Q_D(QCoreApplication);
// no events are delivered after ~QCoreApplication() has started
if (QCoreApplicationPrivate::is_app_closing)
return true;
+ return doNotify(receiver, event);
+}
+static bool doNotify(QObject *receiver, QEvent *event)
+{
if (receiver == 0) { // serious error
qWarning("QCoreApplication::notify: Unexpected null receiver");
return true;
}
#ifndef QT_NO_DEBUG
- d->checkReceiverThread(receiver);
+ QCoreApplicationPrivate::checkReceiverThread(receiver);
#endif
- return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
+ return receiver->isWidgetType() ? false : QCoreApplicationPrivate::notify_helper(receiver, event);
}
bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
{
- if (receiver->d_func()->threadData == this->threadData && extraData) {
+ // We can't access the application event filters outside of the main thread (race conditions)
+ Q_ASSERT(receiver->d_func()->threadData->thread == mainThread());
+
+ if (extraData) {
// application event filters are only called for objects in the GUI thread
for (int i = 0; i < extraData->eventFilters.size(); ++i) {
QObject *obj = extraData->eventFilters.at(i);
@@ -1059,8 +1101,7 @@ bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiv
bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
{
- Q_Q(QCoreApplication);
- if (receiver != q && receiver->d_func()->extraData) {
+ if (receiver != QCoreApplication::instance() && receiver->d_func()->extraData) {
for (int i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
if (!obj)
@@ -1079,12 +1120,14 @@ bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, Q
/*!
\internal
- Helper function called by notify()
+ Helper function called by QCoreApplicationPrivate::notify() and qapplication.cpp
*/
bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
{
- // send to all application event filters
- if (sendThroughApplicationEventFilters(receiver, event))
+ // send to all application event filters (only does anything in the main thread)
+ if (QCoreApplication::self
+ && receiver->d_func()->threadData->thread == mainThread()
+ && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event))
return true;
// send to all receiver event filters
if (sendThroughObjectEventFilters(receiver, event))
@@ -1764,7 +1807,7 @@ void QCoreApplicationPrivate::maybeQuit()
Tells the application to exit with return code 0 (success).
Equivalent to calling QCoreApplication::exit(0).
- It's common to connect the QApplication::lastWindowClosed() signal
+ It's common to connect the QGuiApplication::lastWindowClosed() signal
to quit(), and you also often connect e.g. QAbstractButton::clicked() or
signals in QAction, QMenu, or QMenuBar to it.
@@ -1772,7 +1815,7 @@ void QCoreApplicationPrivate::maybeQuit()
\snippet code/src_corelib_kernel_qcoreapplication.cpp 1
- \sa exit(), aboutToQuit(), QApplication::lastWindowClosed()
+ \sa exit(), aboutToQuit(), QGuiApplication::lastWindowClosed()
*/
void QCoreApplication::quit()
@@ -2468,28 +2511,17 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
QStringList QCoreApplication::libraryPaths()
{
QMutexLocker locker(libraryPathMutex());
- if (!coreappdata()->app_libpaths) {
- QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList;
- QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
- if (QFile::exists(installPathPlugins)) {
- // Make sure we convert from backslashes to slashes.
- installPathPlugins = QDir(installPathPlugins).canonicalPath();
- if (!app_libpaths->contains(installPathPlugins))
- app_libpaths->append(installPathPlugins);
- }
- // If QCoreApplication is not yet instantiated,
- // make sure we add the application path when we construct the QCoreApplication
- if (self) self->d_func()->appendApplicationPathToLibraryPaths();
+ if (coreappdata()->manual_libpaths)
+ return *(coreappdata()->manual_libpaths);
+
+ if (!coreappdata()->app_libpaths) {
+ QStringList *app_libpaths = new QStringList;
+ coreappdata()->app_libpaths.reset(app_libpaths);
const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
if (!libPathEnv.isEmpty()) {
-#if defined(Q_OS_WIN)
- QLatin1Char pathSep(';');
-#else
- QLatin1Char pathSep(':');
-#endif
- QStringList paths = QFile::decodeName(libPathEnv).split(pathSep, QString::SkipEmptyParts);
+ QStringList paths = QFile::decodeName(libPathEnv).split(QDir::listSeparator(), QString::SkipEmptyParts);
for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
QString canonicalPath = QDir(*it).canonicalPath();
if (!canonicalPath.isEmpty()
@@ -2498,6 +2530,18 @@ QStringList QCoreApplication::libraryPaths()
}
}
}
+
+ QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
+ if (QFile::exists(installPathPlugins)) {
+ // Make sure we convert from backslashes to slashes.
+ installPathPlugins = QDir(installPathPlugins).canonicalPath();
+ if (!app_libpaths->contains(installPathPlugins))
+ app_libpaths->append(installPathPlugins);
+ }
+
+ // If QCoreApplication is not yet instantiated,
+ // make sure we add the application path when we construct the QCoreApplication
+ if (self) self->d_func()->appendApplicationPathToLibraryPaths();
}
return *(coreappdata()->app_libpaths);
}
@@ -2510,14 +2554,26 @@ QStringList QCoreApplication::libraryPaths()
\a paths. All existing paths will be deleted and the path list
will consist of the paths given in \a paths.
+ The library paths are reset to the default when an instance of
+ QCoreApplication is destructed.
+
\sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
*/
void QCoreApplication::setLibraryPaths(const QStringList &paths)
{
QMutexLocker locker(libraryPathMutex());
+
+ // setLibraryPaths() is considered a "remove everything and then add some new ones" operation.
+ // When the application is constructed it should still amend the paths. So we keep the originals
+ // around, and even create them if they don't exist, yet.
if (!coreappdata()->app_libpaths)
- coreappdata()->app_libpaths = new QStringList;
- *(coreappdata()->app_libpaths) = paths;
+ libraryPaths();
+
+ if (coreappdata()->manual_libpaths)
+ *(coreappdata()->manual_libpaths) = paths;
+ else
+ coreappdata()->manual_libpaths.reset(new QStringList(paths));
+
locker.unlock();
QFactoryLoader::refreshAll();
}
@@ -2532,6 +2588,9 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths)
is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
installed.
+ The library paths are reset to the default when an instance of
+ QCoreApplication is destructed.
+
\sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
*/
void QCoreApplication::addLibraryPath(const QString &path)
@@ -2539,24 +2598,38 @@ void QCoreApplication::addLibraryPath(const QString &path)
if (path.isEmpty())
return;
+ QString canonicalPath = QDir(path).canonicalPath();
+ if (canonicalPath.isEmpty())
+ return;
+
QMutexLocker locker(libraryPathMutex());
- // make sure that library paths is initialized
- libraryPaths();
+ QStringList *libpaths = coreappdata()->manual_libpaths.data();
+ if (libpaths) {
+ if (libpaths->contains(canonicalPath))
+ return;
+ } else {
+ // make sure that library paths are initialized
+ libraryPaths();
+ QStringList *app_libpaths = coreappdata()->app_libpaths.data();
+ if (app_libpaths->contains(canonicalPath))
+ return;
- QString canonicalPath = QDir(path).canonicalPath();
- if (!canonicalPath.isEmpty()
- && !coreappdata()->app_libpaths->contains(canonicalPath)) {
- coreappdata()->app_libpaths->prepend(canonicalPath);
- locker.unlock();
- QFactoryLoader::refreshAll();
+ coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
}
+
+ libpaths->prepend(canonicalPath);
+ locker.unlock();
+ QFactoryLoader::refreshAll();
}
/*!
Removes \a path from the library path list. If \a path is empty or not
in the path list, the list is not changed.
+ The library paths are reset to the default when an instance of
+ QCoreApplication is destructed.
+
\sa addLibraryPath(), libraryPaths(), setLibraryPaths()
*/
void QCoreApplication::removeLibraryPath(const QString &path)
@@ -2564,13 +2637,28 @@ void QCoreApplication::removeLibraryPath(const QString &path)
if (path.isEmpty())
return;
+ QString canonicalPath = QDir(path).canonicalPath();
+ if (canonicalPath.isEmpty())
+ return;
+
QMutexLocker locker(libraryPathMutex());
- // make sure that library paths is initialized
- libraryPaths();
+ QStringList *libpaths = coreappdata()->manual_libpaths.data();
+ if (libpaths) {
+ if (libpaths->removeAll(canonicalPath) == 0)
+ return;
+ } else {
+ // make sure that library paths is initialized
+ libraryPaths();
+ QStringList *app_libpaths = coreappdata()->app_libpaths.data();
+ if (!app_libpaths->contains(canonicalPath))
+ return;
+
+ coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
+ libpaths->removeAll(canonicalPath);
+ }
- QString canonicalPath = QDir(path).canonicalPath();
- coreappdata()->app_libpaths->removeAll(canonicalPath);
+ locker.unlock();
QFactoryLoader::refreshAll();
}
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 1cd835daae..d865c4e7a8 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -117,7 +117,7 @@ public:
static bool sendEvent(QObject *receiver, QEvent *event);
static void postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority);
- static void sendPostedEvents(QObject *receiver = 0, int event_type = 0);
+ static void sendPostedEvents(QObject *receiver = Q_NULLPTR, int event_type = 0);
static void removePostedEvents(QObject *receiver, int eventType = 0);
#if QT_DEPRECATED_SINCE(5, 3)
QT_DEPRECATED static bool hasPendingEvents();
@@ -149,7 +149,7 @@ public:
static QString translate(const char * context,
const char * key,
- const char * disambiguation = 0,
+ const char * disambiguation = Q_NULLPTR,
int n = -1);
#if QT_DEPRECATED_SINCE(5, 0)
enum Encoding { UnicodeUTF8, Latin1, DefaultCodec = UnicodeUTF8, CodecForTr = UnicodeUTF8 };
@@ -194,7 +194,10 @@ protected:
private:
#ifndef QT_NO_QOBJECT
static bool sendSpontaneousEvent(QObject *receiver, QEvent *event);
- bool notifyInternal(QObject *receiver, QEvent *event);
+# if QT_DEPRECATED_SINCE(5,6)
+ QT_DEPRECATED bool notifyInternal(QObject *receiver, QEvent *event); // ### Qt6 BIC: remove me
+# endif
+ static bool notifyInternal2(QObject *receiver, QEvent *);
#endif
void init();
@@ -221,23 +224,23 @@ private:
#ifndef QT_NO_QOBJECT
inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
-{ if (event) event->spont = false; return self ? self->notifyInternal(receiver, event) : false; }
+{ if (event) event->spont = false; return notifyInternal2(receiver, event); }
inline bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
-{ if (event) event->spont = true; return self ? self->notifyInternal(receiver, event) : false; }
+{ if (event) event->spont = true; return notifyInternal2(receiver, event); }
#endif
#ifdef QT_NO_DEPRECATED
# define QT_DECLARE_DEPRECATED_TR_FUNCTIONS(context)
#else
# define QT_DECLARE_DEPRECATED_TR_FUNCTIONS(context) \
- QT_DEPRECATED static inline QString trUtf8(const char *sourceText, const char *disambiguation = 0, int n = -1) \
+ QT_DEPRECATED static inline QString trUtf8(const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1) \
{ return QCoreApplication::translate(#context, sourceText, disambiguation, n); }
#endif
#define Q_DECLARE_TR_FUNCTIONS(context) \
public: \
- static inline QString tr(const char *sourceText, const char *disambiguation = 0, int n = -1) \
+ static inline QString tr(const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1) \
{ return QCoreApplication::translate(#context, sourceText, disambiguation, n); } \
QT_DECLARE_DEPRECATED_TR_FUNCTIONS(context) \
private:
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 2646a28d71..21f59d8197 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -86,8 +86,8 @@ public:
#ifndef QT_NO_QOBJECT
bool sendThroughApplicationEventFilters(QObject *, QEvent *);
- bool sendThroughObjectEventFilters(QObject *, QEvent *);
- bool notify_helper(QObject *, QEvent *);
+ static bool sendThroughObjectEventFilters(QObject *, QEvent *);
+ static bool notify_helper(QObject *, QEvent *);
static inline void setEventSpontaneous(QEvent *e, bool spontaneous) { e->spont = spontaneous; }
virtual void createEventDispatcher();
@@ -107,9 +107,11 @@ public:
static QThread *theMainThread;
static QThread *mainThread();
+ static bool threadRequiresCoreApplication();
+
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data);
- void checkReceiverThread(QObject *receiver);
+ static void checkReceiverThread(QObject *receiver);
void cleanupThreadData();
#endif // QT_NO_QOBJECT
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index e9ae355d70..98514c56af 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -150,7 +150,7 @@ QT_BEGIN_NAMESPACE
\value HoverLeave The mouse cursor leaves a hover widget (QHoverEvent).
\value HoverMove The mouse cursor moves inside a hover widget (QHoverEvent).
\value IconDrag The main icon of a window has been dragged away (QIconDragEvent).
- \value IconTextChange Widget's icon text has been changed.
+ \value IconTextChange Widget's icon text has been changed. (Deprecated)
\value InputMethod An input method is being used (QInputMethodEvent).
\value InputMethodQuery A input method query event (QInputMethodQueryEvent)
\value KeyboardLayoutChange The keyboard layout has changed.
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index c208eb1180..53da4a849b 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -133,7 +133,7 @@ public:
EnabledChange = 98, // enabled state has changed
ActivationChange = 99, // window activation has changed
StyleChange = 100, // style has changed
- IconTextChange = 101, // icon text has changed
+ IconTextChange = 101, // icon text has changed. Deprecated.
ModifiedChange = 102, // modified state has changed
MouseTrackingChange = 109, // mouse tracking state has changed
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 876825b5f0..d9bbd4d5f2 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -39,7 +39,6 @@
#include "qcoreapplication.h"
#include "qsocketnotifier.h"
-#include <QtCore/qhash.h>
#include <QtCore/qlist.h>
#include <QtCore/qpair.h>
diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h
index afdb6b9317..2cb919df07 100644
--- a/src/corelib/kernel/qeventdispatcher_glib_p.h
+++ b/src/corelib/kernel/qeventdispatcher_glib_p.h
@@ -48,8 +48,6 @@
#include "qabstracteventdispatcher.h"
#include "qabstracteventdispatcher_p.h"
-#include <QtCore/qhash.h>
-
typedef struct _GMainContext GMainContext;
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 6da70cf0bd..e8ff8a7936 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -34,7 +34,6 @@
#include "qeventdispatcher_win_p.h"
#include "qcoreapplication.h"
-#include "qhash.h"
#include <private/qsystemlibrary_p.h>
#include "qpair.h"
#include "qset.h"
@@ -1087,11 +1086,10 @@ void QEventDispatcherWin32::activateEventNotifiers()
for (int i=0; i<d->winEventNotifierList.count(); i++) {
#if !defined(Q_OS_WINCE)
if (WaitForSingleObjectEx(d->winEventNotifierList.at(i)->handle(), 0, TRUE) == WAIT_OBJECT_0)
- d->activateEventNotifier(d->winEventNotifierList.at(i));
#else
if (WaitForSingleObject(d->winEventNotifierList.at(i)->handle(), 0) == WAIT_OBJECT_0)
- d->activateEventNotifier(d->winEventNotifierList.at(i));
#endif
+ d->activateEventNotifier(d->winEventNotifierList.at(i));
}
}
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index eceba8d002..f771974a24 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -40,6 +40,7 @@
#include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
+#include <functional>
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.system.threading.h>
@@ -70,6 +71,23 @@ struct WinRTTimerInfo : public QAbstractEventDispatcher::TimerInfo {
quint64 targetTime;
};
+class AgileDispatchedHandler : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IDispatchedHandler, IAgileObject>
+{
+public:
+ AgileDispatchedHandler(const std::function<HRESULT()> &delegate)
+ : delegate(delegate)
+ {
+ }
+
+ HRESULT __stdcall Invoke()
+ {
+ return delegate();
+ }
+
+private:
+ std::function<HRESULT()> delegate;
+};
+
class QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate
{
Q_DECLARE_PUBLIC(QEventDispatcherWinRT)
@@ -80,8 +98,6 @@ public:
private:
ComPtr<IThreadPoolTimerStatics> timerFactory;
- ComPtr<ICoreDispatcher> coreDispatcher;
- QPointer<QThread> thread;
QHash<int, QObject *> timerIdToObject;
QVector<WinRTTimerInfo> timerInfos;
@@ -136,40 +152,11 @@ private:
}
return true;
}
-
- void fetchCoreDispatcher()
- {
- ComPtr<ICoreImmersiveApplication> application;
- HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
- IID_PPV_ARGS(&application));
- RETURN_VOID_IF_FAILED("Failed to get the application factory");
-
- static ComPtr<ICoreApplicationView> view;
- if (view)
- return;
-
- hr = application->get_MainView(&view);
- RETURN_VOID_IF_FAILED("Failed to get the main view");
-
- ComPtr<ICoreApplicationView2> view2;
- hr = view.As(&view2);
- RETURN_VOID_IF_FAILED("Failed to cast the main view");
-
- hr = view2->get_Dispatcher(&coreDispatcher);
- if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) // expected in thread pool cases
- return;
- RETURN_VOID_IF_FAILED("Failed to get core dispatcher");
-
- thread = QThread::currentThread();
- }
};
QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
: QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
{
- Q_D(QEventDispatcherWinRT);
-
- d->fetchCoreDispatcher();
}
QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
@@ -180,25 +167,43 @@ QEventDispatcherWinRT::~QEventDispatcherWinRT()
{
}
+HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT ()> &delegate)
+{
+ static __declspec(thread) ICoreDispatcher *dispatcher = nullptr;
+ if (!dispatcher) {
+ HRESULT hr;
+ ComPtr<ICoreImmersiveApplication> application;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&application));
+ ComPtr<ICoreApplicationView> view;
+ hr = application->get_MainView(&view);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<ICoreWindow> window;
+ hr = view->get_CoreWindow(&window);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = window->get_Dispatcher(&dispatcher);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ HRESULT hr;
+ boolean onXamlThread;
+ hr = dispatcher->get_HasThreadAccess(&onXamlThread);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (onXamlThread) // Already there
+ return delegate();
+
+ ComPtr<IAsyncAction> op;
+ hr = dispatcher->RunAsync(CoreDispatcherPriority_Normal, Make<AgileDispatchedHandler>(delegate).Get(), &op);
+ if (FAILED(hr))
+ return hr;
+ return QWinRTFunctions::await(op);
+}
+
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherWinRT);
- if (d->thread && d->thread != QThread::currentThread())
- d->fetchCoreDispatcher();
-
do {
- // Process native events
- if (d->coreDispatcher) {
- boolean hasThreadAccess;
- HRESULT hr = d->coreDispatcher->get_HasThreadAccess(&hasThreadAccess);
- if (SUCCEEDED(hr) && hasThreadAccess) {
- hr = d->coreDispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
- if (FAILED(hr))
- qErrnoWarning(hr, "Failed to process events");
- }
- }
-
// Additional user events have to be handled before timer events, but the function may not
// return yet.
const bool userEventsSent = sendPostedEvents(flags);
@@ -284,10 +289,11 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy
TimeSpan period;
period.Duration = interval ? (interval * 10000) : 1; // TimeSpan is based on 100-nanosecond units
- IThreadPoolTimer *timer;
const HANDLE handle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE | EVENT_MODIFY_STATE);
const HANDLE cancelHandle = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, SYNCHRONIZE|EVENT_MODIFY_STATE);
- HRESULT hr = d->timerFactory->CreatePeriodicTimerWithCompletion(
+ HRESULT hr = runOnXamlThread([&]() {
+ IThreadPoolTimer *timer;
+ HRESULT hr = d->timerFactory->CreatePeriodicTimerWithCompletion(
Callback<ITimerElapsedHandler>([handle, cancelHandle](IThreadPoolTimer *timer) {
DWORD cancelResult = WaitForSingleObjectEx(cancelHandle, 0, TRUE);
if (cancelResult == WAIT_OBJECT_0) {
@@ -306,13 +312,15 @@ void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerTy
CloseHandle(cancelHandle);
return S_OK;
}).Get(), &timer);
+ RETURN_HR_IF_FAILED("Failed to create periodic timer");
+
+ d->addTimer(timerId, interval, timerType, object, handle, cancelHandle);
+ return hr;
+ });
if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to create periodic timer");
CloseHandle(handle);
CloseHandle(cancelHandle);
- return;
}
- d->addTimer(timerId, interval, timerType, object, handle, cancelHandle);
}
bool QEventDispatcherWinRT::unregisterTimer(int timerId)
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
index fd3d259c96..073aa1c121 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt_p.h
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -50,6 +50,8 @@
#include <qt_windows.h>
+namespace std { template <typename T> class function; }
+
QT_BEGIN_NAMESPACE
quint64 qt_msectime();
@@ -65,6 +67,8 @@ public:
explicit QEventDispatcherWinRT(QObject *parent = 0);
~QEventDispatcherWinRT();
+ static HRESULT runOnXamlThread(const std::function<HRESULT()> &delegate);
+
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index 1723db0ab9..dca25ce968 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -93,7 +93,7 @@ QEventLoop::QEventLoop(QObject *parent)
: QObject(*new QEventLoopPrivate, parent)
{
Q_D(QEventLoop);
- if (!QCoreApplication::instance()) {
+ if (!QCoreApplication::instance() && QCoreApplicationPrivate::threadRequiresCoreApplication()) {
qWarning("QEventLoop: Cannot be used without QApplication");
} else if (!d->threadData->eventDispatcher.load()) {
QThreadPrivate::createEventDispatcher(d->threadData);
diff --git a/src/corelib/kernel/qeventloop.h b/src/corelib/kernel/qeventloop.h
index 99c0cd50ff..375a63abdd 100644
--- a/src/corelib/kernel/qeventloop.h
+++ b/src/corelib/kernel/qeventloop.h
@@ -47,7 +47,7 @@ class Q_CORE_EXPORT QEventLoop : public QObject
Q_DECLARE_PRIVATE(QEventLoop)
public:
- explicit QEventLoop(QObject *parent = 0);
+ explicit QEventLoop(QObject *parent = Q_NULLPTR);
~QEventLoop();
enum ProcessEventsFlag {
diff --git a/src/corelib/kernel/qfunctions_wince.cpp b/src/corelib/kernel/qfunctions_wince.cpp
index 8f8fc21313..2503a262cd 100644
--- a/src/corelib/kernel/qfunctions_wince.cpp
+++ b/src/corelib/kernel/qfunctions_wince.cpp
@@ -36,7 +36,11 @@
#include <winbase.h>
#include <kfuncs.h>
#include <stdio.h>
-#include <altcecrt.h>
+#if _WIN32_WCE < 0x800
+# include <altcecrt.h>
+#else
+# include <fcntl.h>
+#endif
#include "qplatformdefs.h"
#include "qfunctions_wince.h"
@@ -93,7 +97,9 @@ FILETIME qt_wince_time_tToFt( time_t tt )
}
// File I/O ---------------------------------------------------------
+#if _WIN32_WCE < 0x800
int errno = 0;
+#endif
int qt_wince__getdrive( void )
{
diff --git a/src/corelib/kernel/qfunctions_wince.h b/src/corelib/kernel/qfunctions_wince.h
index 987342d29a..d172acceec 100644
--- a/src/corelib/kernel/qfunctions_wince.h
+++ b/src/corelib/kernel/qfunctions_wince.h
@@ -37,6 +37,9 @@
#include <QtCore/qglobal.h>
#ifdef Q_OS_WINCE
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
@@ -47,7 +50,12 @@
#include <ctype.h>
#include <time.h>
#include <crtdefs.h>
-#include <altcecrt.h>
+#if _WIN32_WCE < 0x800
+# include <altcecrt.h>
+#else
+# include <fcntl.h>
+# include <stat.h>
+#endif
#include <winsock.h>
#include <ceconfig.h>
@@ -102,6 +110,8 @@ struct tm {
FILETIME qt_wince_time_tToFt( time_t tt );
time_t qt_wince_ftToTime_t( const FILETIME ft );
+#if _WIN32_WCE < 0x800
+
// File I/O ---------------------------------------------------------
#define _O_RDONLY 0x0001
#define _O_RDWR 0x0002
@@ -161,6 +171,7 @@ struct stat
typedef int mode_t;
extern int errno;
+#endif // _WIN32_WCE < 0x800
int qt_wince__getdrive( void );
int qt_wince__waccess( const wchar_t *path, int pmode );
@@ -437,8 +448,10 @@ generate_inline_return_func0(tmpfile, FILE *)
generate_inline_return_func2(_rename, int, const char *, const char *)
generate_inline_return_func1(_remove, int, const char *)
generate_inline_return_func1(SetErrorMode, int, int)
+#if _WIN32_WCE < 0x800
generate_inline_return_func2(_chmod, bool, const char *, int)
generate_inline_return_func2(_wchmod, bool, const wchar_t *, int)
+#endif
generate_inline_return_func7(CreateFileA, HANDLE, LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE)
generate_inline_return_func4(SetWindowOrgEx, BOOL, HDC, int, int, LPPOINT)
generate_inline_return_func2(calloc, void *, size_t, size_t)
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 2640ecaaaf..108a01aab7 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -225,6 +225,15 @@ static jfieldID getCachedFieldID(JNIEnv *env,
}
}
+void QJNILocalRefDeleter::cleanup(jobject obj)
+{
+ if (obj == 0)
+ return;
+
+ QJNIEnvironmentPrivate env;
+ env->DeleteLocalRef(obj);
+}
+
class QJNIEnvironmentPrivateTLS
{
public:
@@ -2371,4 +2380,3 @@ bool QJNIObjectPrivate::isSameObject(const QJNIObjectPrivate &other) const
}
QT_END_NAMESPACE
-
diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h
index a32d656ebf..1c23f2ab76 100644
--- a/src/corelib/kernel/qjni_p.h
+++ b/src/corelib/kernel/qjni_p.h
@@ -51,6 +51,14 @@
QT_BEGIN_NAMESPACE
+struct Q_CORE_EXPORT QJNILocalRefDeleter
+{
+ static void cleanup(jobject obj);
+};
+
+// To simplify this we only define it for jobjects.
+typedef QScopedPointer<_jobject, QJNILocalRefDeleter> QJNIScopedLocalRef;
+
class Q_CORE_EXPORT QJNIEnvironmentPrivate
{
public:
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index dad2d5dc1e..f77fc4220c 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -122,6 +122,45 @@ void QtAndroidPrivate::handleNewIntent(JNIEnv *env, jobject intent)
}
}
+namespace {
+ class ResumePauseListeners
+ {
+ public:
+ QMutex mutex;
+ QList<QtAndroidPrivate::ResumePauseListener *> listeners;
+ };
+}
+
+Q_GLOBAL_STATIC(ResumePauseListeners, g_resumePauseListeners)
+
+void QtAndroidPrivate::registerResumePauseListener(ResumePauseListener *listener)
+{
+ QMutexLocker locker(&g_resumePauseListeners()->mutex);
+ g_resumePauseListeners()->listeners.append(listener);
+}
+
+void QtAndroidPrivate::unregisterResumePauseListener(ResumePauseListener *listener)
+{
+ QMutexLocker locker(&g_resumePauseListeners()->mutex);
+ g_resumePauseListeners()->listeners.removeAll(listener);
+}
+
+void QtAndroidPrivate::handlePause()
+{
+ QMutexLocker locker(&g_resumePauseListeners()->mutex);
+ const QList<QtAndroidPrivate::ResumePauseListener *> &listeners = g_resumePauseListeners()->listeners;
+ for (int i=0; i<listeners.size(); ++i)
+ listeners.at(i)->handlePause();
+}
+
+void QtAndroidPrivate::handleResume()
+{
+ QMutexLocker locker(&g_resumePauseListeners()->mutex);
+ const QList<QtAndroidPrivate::ResumePauseListener *> &listeners = g_resumePauseListeners()->listeners;
+ for (int i=0; i<listeners.size(); ++i)
+ listeners.at(i)->handleResume();
+}
+
static inline bool exceptionCheck(JNIEnv *env)
{
if (env->ExceptionCheck()) {
diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h
index 3ed8338b18..883b08ef60 100644
--- a/src/corelib/kernel/qjnihelpers_p.h
+++ b/src/corelib/kernel/qjnihelpers_p.h
@@ -68,6 +68,14 @@ namespace QtAndroidPrivate
virtual bool handleNewIntent(JNIEnv *env, jobject intent) = 0;
};
+ class Q_CORE_EXPORT ResumePauseListener
+ {
+ public:
+ virtual ~ResumePauseListener() {}
+ virtual void handlePause() {};
+ virtual void handleResume() {};
+ };
+
Q_CORE_EXPORT jobject activity();
Q_CORE_EXPORT JavaVM *javaVM();
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
@@ -82,6 +90,11 @@ namespace QtAndroidPrivate
Q_CORE_EXPORT void handleNewIntent(JNIEnv *env, jobject intent);
Q_CORE_EXPORT void registerNewIntentListener(NewIntentListener *listener);
Q_CORE_EXPORT void unregisterNewIntentListener(NewIntentListener *listener);
+
+ Q_CORE_EXPORT void handlePause();
+ Q_CORE_EXPORT void handleResume();
+ Q_CORE_EXPORT void registerResumePauseListener(ResumePauseListener *listener);
+ Q_CORE_EXPORT void unregisterResumePauseListener(ResumePauseListener *listener);
}
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h
index 5cc3ec586e..e60561c05f 100644
--- a/src/corelib/kernel/qmath.h
+++ b/src/corelib/kernel/qmath.h
@@ -40,8 +40,18 @@
#include <QtCore/qglobal.h>
+#ifndef _USE_MATH_DEFINES
+# define _USE_MATH_DEFINES
+# define undef_USE_MATH_DEFINES
+#endif
+
#include <cmath>
+#ifdef undef_USE_MATH_DEFINES
+# undef _USE_MATH_DEFINES
+# undef undef_USE_MATH_DEFINES
+#endif
+
QT_BEGIN_NAMESPACE
#define QT_SINE_TABLE_SIZE 256
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 6858209b12..7ae9fef622 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -43,7 +43,6 @@
#include <qstringlist.h>
#include <qthread.h>
#include <qvariant.h>
-#include <qhash.h>
#include <qdebug.h>
#include <qsemaphore.h>
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index b522a211bb..1a282d3261 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -48,7 +48,7 @@ template <typename T> class QList;
class Q_CORE_EXPORT QMetaMethod
{
public:
- Q_DECL_CONSTEXPR inline QMetaMethod() : mobj(0),handle(0) {}
+ Q_DECL_CONSTEXPR inline QMetaMethod() : mobj(Q_NULLPTR), handle(0) {}
QByteArray methodSignature() const;
QByteArray name() const;
@@ -74,7 +74,7 @@ public:
bool invoke(QObject *object,
Qt::ConnectionType connectionType,
QGenericReturnArgument returnValue,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -86,7 +86,7 @@ public:
QGenericArgument val9 = QGenericArgument()) const;
inline bool invoke(QObject *object,
QGenericReturnArgument returnValue,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -102,7 +102,7 @@ public:
}
inline bool invoke(QObject *object,
Qt::ConnectionType connectionType,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -117,7 +117,7 @@ public:
val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
inline bool invoke(QObject *object,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -134,7 +134,7 @@ public:
bool invokeOnGadget(void *gadget,
QGenericReturnArgument returnValue,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -145,7 +145,7 @@ public:
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument()) const;
inline bool invokeOnGadget(void *gadget,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -160,7 +160,7 @@ public:
val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
- inline bool isValid() const { return mobj != 0; }
+ inline bool isValid() const { return mobj != Q_NULLPTR; }
#ifdef Q_QDOC
static QMetaMethod fromSignal(PointerToMemberFunction signal);
@@ -204,7 +204,7 @@ inline bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2)
class Q_CORE_EXPORT QMetaEnum
{
public:
- Q_DECL_CONSTEXPR inline QMetaEnum() : mobj(0),handle(0) {}
+ Q_DECL_CONSTEXPR inline QMetaEnum() : mobj(Q_NULLPTR), handle(0) {}
const char *name() const;
bool isFlag() const;
@@ -215,14 +215,14 @@ public:
const char *scope() const;
- int keyToValue(const char *key, bool *ok = 0) const;
+ int keyToValue(const char *key, bool *ok = Q_NULLPTR) const;
const char* valueToKey(int value) const;
- int keysToValue(const char * keys, bool *ok = 0) const;
+ int keysToValue(const char * keys, bool *ok = Q_NULLPTR) const;
QByteArray valueToKeys(int value) const;
inline const QMetaObject *enclosingMetaObject() const { return mobj; }
- inline bool isValid() const { return name() != 0; }
+ inline bool isValid() const { return name() != Q_NULLPTR; }
template<typename T> static QMetaEnum fromType() {
Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value,
@@ -253,11 +253,11 @@ public:
bool isReadable() const;
bool isWritable() const;
bool isResettable() const;
- bool isDesignable(const QObject *obj = 0) const;
- bool isScriptable(const QObject *obj = 0) const;
- bool isStored(const QObject *obj = 0) const;
- bool isEditable(const QObject *obj = 0) const;
- bool isUser(const QObject *obj = 0) const;
+ bool isDesignable(const QObject *obj = Q_NULLPTR) const;
+ bool isScriptable(const QObject *obj = Q_NULLPTR) const;
+ bool isStored(const QObject *obj = Q_NULLPTR) const;
+ bool isEditable(const QObject *obj = Q_NULLPTR) const;
+ bool isUser(const QObject *obj = Q_NULLPTR) const;
bool isConstant() const;
bool isFinal() const;
@@ -297,7 +297,7 @@ private:
class Q_CORE_EXPORT QMetaClassInfo
{
public:
- Q_DECL_CONSTEXPR inline QMetaClassInfo() : mobj(0),handle(0) {}
+ Q_DECL_CONSTEXPR inline QMetaClassInfo() : mobj(Q_NULLPTR), handle(0) {}
const char *name() const;
const char *value() const;
inline const QMetaObject *enclosingMetaObject() const { return mobj; }
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index a1b8125121..021e137273 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -88,6 +88,7 @@ static inline Q_DECL_UNUSED const QMetaObjectPrivate *priv(const uint* data)
class QMetaMethodBuilderPrivate
{
public:
+ QMetaMethodBuilderPrivate() {} // for QVector, don't use
QMetaMethodBuilderPrivate
(QMetaMethod::MethodType _methodType,
const QByteArray& _signature,
@@ -139,10 +140,12 @@ public:
return signature.left(qMax(signature.indexOf('('), 0));
}
};
+Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_MOVABLE_TYPE);
class QMetaPropertyBuilderPrivate
{
public:
+ QMetaPropertyBuilderPrivate() {} // for QVector, don't use
QMetaPropertyBuilderPrivate
(const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1,
int _revision = 0)
@@ -176,10 +179,12 @@ public:
flags &= ~f;
}
};
+Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_MOVABLE_TYPE);
class QMetaEnumBuilderPrivate
{
public:
+ QMetaEnumBuilderPrivate() {} // for QVector, don't use
QMetaEnumBuilderPrivate(const QByteArray& _name)
: name(_name), isFlag(false)
{
@@ -188,8 +193,9 @@ public:
QByteArray name;
bool isFlag;
QList<QByteArray> keys;
- QList<int> values;
+ QVector<int> values;
};
+Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_MOVABLE_TYPE);
class QMetaObjectBuilderPrivate
{
@@ -207,12 +213,12 @@ public:
QByteArray className;
const QMetaObject *superClass;
QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction;
- QList<QMetaMethodBuilderPrivate> methods;
- QList<QMetaMethodBuilderPrivate> constructors;
- QList<QMetaPropertyBuilderPrivate> properties;
+ QVector<QMetaMethodBuilderPrivate> methods;
+ QVector<QMetaMethodBuilderPrivate> constructors;
+ QVector<QMetaPropertyBuilderPrivate> properties;
QList<QByteArray> classInfoNames;
QList<QByteArray> classInfoValues;
- QList<QMetaEnumBuilderPrivate> enumerators;
+ QVector<QMetaEnumBuilderPrivate> enumerators;
QList<const QMetaObject *> relatedMetaObjects;
int flags;
};
@@ -1149,7 +1155,7 @@ void QMetaStringTable::writeBlob(char *out) const
// Returns the sum of all parameters (including return type) for the given
// \a methods. This is needed for calculating the size of the methods'
// parameter type/name meta-data.
-static int aggregateParameterCount(const QList<QMetaMethodBuilderPrivate> &methods)
+static int aggregateParameterCount(const QVector<QMetaMethodBuilderPrivate> &methods)
{
int sum = 0;
for (int i = 0; i < methods.size(); ++i)
@@ -1330,7 +1336,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
Q_ASSERT(!buf || dataIndex == pmeta->methodData + d->methods.size() * 5
+ (hasRevisionedMethods ? d->methods.size() : 0));
for (int x = 0; x < 2; ++x) {
- QList<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
+ QVector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
for (index = 0; index < methods.size(); ++index) {
QMetaMethodBuilderPrivate *method = &(methods[index]);
QList<QByteArray> paramTypeNames = method->parameterTypes();
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 7fadb66319..01e2542dfa 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -1081,25 +1081,16 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
normalizedTypeName.constData(), idx, previousSize, size);
}
- // Do not compare types higher than 0x100:
- // Ignore WasDeclaredAsMetaType inconsitency, to many users were hitting the problem
- // Ignore IsGadget as it was added in Qt 5.5
- // Ignore all the future flags as well
- if ((previousFlags ^ flags) & 0xff) {
- const int maskForTypeInfo = NeedsConstruction | NeedsDestruction | MovableType;
+ // these flags cannot change in a binary compatible way:
+ const int binaryCompatibilityFlag = PointerToQObject | IsEnumeration | SharedPointerToQObject
+ | WeakPointerToQObject | TrackingPointerToQObject;
+ if ((previousFlags ^ flags) & binaryCompatibilityFlag) {
+
const char *msg = "QMetaType::registerType: Binary compatibility break. "
"\nType flags for type '%s' [%i] don't match. Previously "
- "registered TypeFlags(0x%x), now registering TypeFlags(0x%x). "
- "This is an ODR break, which means that your application depends on a C++ undefined behavior."
- "\nHint: %s";
- QT_PREPEND_NAMESPACE(QByteArray) hint;
- if ((previousFlags & maskForTypeInfo) != (flags & maskForTypeInfo)) {
- hint += "\nIt seems that the type was registered at least twice in a different translation units, "
- "but Q_DECLARE_TYPEINFO is not visible from all the translations unit or different flags were used."
- "Remember that Q_DECLARE_TYPEINFO should be declared before QMetaType registration, "
- "preferably it should be placed just after the type declaration and before Q_DECLARE_METATYPE";
- }
- qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags), hint.constData());
+ "registered TypeFlags(0x%x), now registering TypeFlags(0x%x). ";
+
+ qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags));
}
return idx;
@@ -1188,9 +1179,6 @@ bool QMetaType::isRegistered(int type)
return ((type >= User) && (ct && ct->count() > type - User) && !ct->at(type - User).typeName.isEmpty());
}
-/*!
- \internal
-*/
template <bool tryNormalizedType>
static inline int qMetaTypeTypeImpl(const char *typeName, int length)
{
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 1b214e9f74..b7f01ca5ca 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -229,7 +229,7 @@ struct AbstractDebugStreamFunction
{
typedef void (*Stream)(const AbstractDebugStreamFunction *, QDebug&, const void *);
typedef void (*Destroy)(AbstractDebugStreamFunction *);
- explicit AbstractDebugStreamFunction(Stream s = 0, Destroy d = 0)
+ explicit AbstractDebugStreamFunction(Stream s = Q_NULLPTR, Destroy d = Q_NULLPTR)
: stream(s), destroy(d) {}
Q_DISABLE_COPY(AbstractDebugStreamFunction)
Stream stream;
@@ -259,7 +259,7 @@ struct AbstractComparatorFunction
typedef bool (*LessThan)(const AbstractComparatorFunction *, const void *, const void *);
typedef bool (*Equals)(const AbstractComparatorFunction *, const void *, const void *);
typedef void (*Destroy)(AbstractComparatorFunction *);
- explicit AbstractComparatorFunction(LessThan lt = 0, Equals e = 0, Destroy d = 0)
+ explicit AbstractComparatorFunction(LessThan lt = Q_NULLPTR, Equals e = Q_NULLPTR, Destroy d = Q_NULLPTR)
: lessThan(lt), equals(e), destroy(d) {}
Q_DISABLE_COPY(AbstractComparatorFunction)
LessThan lessThan;
@@ -296,7 +296,7 @@ template<typename T>
struct BuiltInEqualsComparatorFunction : public AbstractComparatorFunction
{
BuiltInEqualsComparatorFunction()
- : AbstractComparatorFunction(0, equals, destroy) {}
+ : AbstractComparatorFunction(Q_NULLPTR, equals, destroy) {}
static bool equals(const AbstractComparatorFunction *, const void *l, const void *r)
{
const T *lhs = static_cast<const T *>(l);
@@ -313,7 +313,7 @@ struct BuiltInEqualsComparatorFunction : public AbstractComparatorFunction
struct AbstractConverterFunction
{
typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*);
- explicit AbstractConverterFunction(Converter c = 0)
+ explicit AbstractConverterFunction(Converter c = Q_NULLPTR)
: convert(c) {}
Q_DISABLE_COPY(AbstractConverterFunction)
Converter convert;
@@ -510,9 +510,9 @@ public:
static TypeFlags typeFlags(int type);
static const QMetaObject *metaObjectForType(int type);
static bool isRegistered(int type);
- static void *create(int type, const void *copy = 0);
+ static void *create(int type, const void *copy = Q_NULLPTR);
#if QT_DEPRECATED_SINCE(5, 0)
- QT_DEPRECATED static void *construct(int type, const void *copy = 0)
+ QT_DEPRECATED static void *construct(int type, const void *copy = Q_NULLPTR)
{ return create(type, copy); }
#endif
static void destroy(int type, void *data);
@@ -533,9 +533,9 @@ public:
inline TypeFlags flags() const;
inline const QMetaObject *metaObject() const;
- inline void *create(const void *copy = 0) const;
+ inline void *create(const void *copy = Q_NULLPTR) const;
inline void destroy(void *data) const;
- inline void *construct(void *where, const void *copy = 0) const;
+ inline void *construct(void *where, const void *copy = Q_NULLPTR) const;
inline void destruct(void *data) const;
public:
@@ -611,7 +611,7 @@ public:
return registerConverterFunction(&f, fromTypeId, toTypeId);
}
- // member function as in "double QString::toDouble(bool *ok = 0) const"
+ // member function as in "double QString::toDouble(bool *ok = Q_NULLPTR) const"
template<typename From, typename To>
static bool registerConverter(To(From::*function)(bool*) const)
{
@@ -674,9 +674,9 @@ private:
uint sizeExtended() const;
QMetaType::TypeFlags flagsExtended() const;
const QMetaObject *metaObjectExtended() const;
- void *createExtended(const void *copy = 0) const;
+ void *createExtended(const void *copy = Q_NULLPTR) const;
void destroyExtended(void *data) const;
- void *constructExtended(void *where, const void *copy = 0) const;
+ void *constructExtended(void *where, const void *copy = Q_NULLPTR) const;
void destructExtended(void *data) const;
static bool registerComparatorFunction(const QtPrivate::AbstractComparatorFunction *f, int type);
@@ -740,6 +740,11 @@ ConverterFunctor<From, To, UnaryFunction>::~ConverterFunctor()
}
+#define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F) \
+ } \
+ Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \
+ namespace QtMetaTypePrivate {
+
namespace QtMetaTypePrivate {
template <typename T, bool Accepted = true>
struct QMetaTypeFunctionHelper {
@@ -771,7 +776,7 @@ struct QMetaTypeFunctionHelper {
template <typename T>
struct QMetaTypeFunctionHelper<T, /* Accepted */ false> {
static void Destruct(void *) {}
- static void *Construct(void *, const void *) { return 0; }
+ static void *Construct(void *, const void *) { return Q_NULLPTR; }
#ifndef QT_NO_DATASTREAM
static void Save(QDataStream &, const void *) {}
static void Load(QDataStream &, void *) {}
@@ -1009,7 +1014,7 @@ public:
public:
template<class T> QSequentialIterableImpl(const T*p)
: _iterable(p)
- , _iterator(0)
+ , _iterator(Q_NULLPTR)
, _metaType_id(qMetaTypeId<typename T::value_type>())
, _metaType_flags(QTypeInfo<typename T::value_type>::isPointer)
, _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities)
@@ -1026,20 +1031,20 @@ public:
}
QSequentialIterableImpl()
- : _iterable(0)
- , _iterator(0)
+ : _iterable(Q_NULLPTR)
+ , _iterator(Q_NULLPTR)
, _metaType_id(QMetaType::UnknownType)
, _metaType_flags(0)
, _iteratorCapabilities(0)
- , _size(0)
- , _at(0)
- , _moveToBegin(0)
- , _moveToEnd(0)
- , _advance(0)
- , _get(0)
- , _destroyIter(0)
- , _equalIter(0)
- , _copyIter(0)
+ , _size(Q_NULLPTR)
+ , _at(Q_NULLPTR)
+ , _moveToBegin(Q_NULLPTR)
+ , _moveToEnd(Q_NULLPTR)
+ , _advance(Q_NULLPTR)
+ , _get(Q_NULLPTR)
+ , _destroyIter(Q_NULLPTR)
+ , _equalIter(Q_NULLPTR)
+ , _copyIter(Q_NULLPTR)
{
}
@@ -1067,6 +1072,7 @@ public:
_copyIter(&_iterator, &other._iterator);
}
};
+QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QSequentialIterableImpl, Q_MOVABLE_TYPE)
template<typename From>
struct QSequentialIterableConvertFunctor
@@ -1195,21 +1201,21 @@ public:
}
QAssociativeIterableImpl()
- : _iterable(0)
+ : _iterable(Q_NULLPTR)
, _metaType_id_key(QMetaType::UnknownType)
, _metaType_flags_key(0)
, _metaType_id_value(QMetaType::UnknownType)
, _metaType_flags_value(0)
- , _size(0)
- , _find(0)
- , _begin(0)
- , _end(0)
- , _advance(0)
- , _getKey(0)
- , _getValue(0)
- , _destroyIter(0)
- , _equalIter(0)
- , _copyIter(0)
+ , _size(Q_NULLPTR)
+ , _find(Q_NULLPTR)
+ , _begin(Q_NULLPTR)
+ , _end(Q_NULLPTR)
+ , _advance(Q_NULLPTR)
+ , _getKey(Q_NULLPTR)
+ , _getValue(Q_NULLPTR)
+ , _destroyIter(Q_NULLPTR)
+ , _equalIter(Q_NULLPTR)
+ , _copyIter(Q_NULLPTR)
{
}
@@ -1234,6 +1240,7 @@ public:
_copyIter(&_iterator, &other._iterator);
}
};
+QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QAssociativeIterableImpl, Q_MOVABLE_TYPE)
template<typename From>
struct QAssociativeIterableConvertFunctor
@@ -1277,15 +1284,20 @@ public:
}
QPairVariantInterfaceImpl()
- : _pair(0)
- , _getFirst(0)
- , _getSecond(0)
+ : _pair(Q_NULLPTR)
+ , _metaType_id_first(QMetaType::UnknownType)
+ , _metaType_flags_first(0)
+ , _metaType_id_second(QMetaType::UnknownType)
+ , _metaType_flags_second(0)
+ , _getFirst(Q_NULLPTR)
+ , _getSecond(Q_NULLPTR)
{
}
inline VariantData first() const { return _getFirst(&_pair, _metaType_id_first, _metaType_flags_first); }
inline VariantData second() const { return _getSecond(&_pair, _metaType_id_second, _metaType_flags_second); }
};
+QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(QPairVariantInterfaceImpl, Q_MOVABLE_TYPE)
template<typename From>
struct QPairVariantInterfaceConvertFunctor;
@@ -1354,7 +1366,7 @@ namespace QtPrivate
#endif
static no_type checkType(...);
Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined");
- enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) };
+ enum { Value = sizeof(checkType(static_cast<T*>(Q_NULLPTR))) == sizeof(yes_type) };
};
template<typename T, typename Enable = void>
@@ -1391,7 +1403,7 @@ QT_WARNING_POP
template<typename T, typename Enable = void>
struct MetaObjectForType
{
- static inline const QMetaObject *value() { return 0; }
+ static inline const QMetaObject *value() { return Q_NULLPTR; }
};
template<>
struct MetaObjectForType<void>
@@ -1692,7 +1704,7 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
template <typename T>
int qRegisterMetaType(const char *typeName
#ifndef Q_QDOC
- , T * dummy = 0
+ , T * dummy = Q_NULLPTR
, typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
#endif
)
@@ -1709,7 +1721,7 @@ int qRegisterMetaType(const char *typeName
template <typename T>
void qRegisterMetaTypeStreamOperators(const char *typeName
#ifndef Q_QDOC
- , T * /* dummy */ = 0
+ , T * /* dummy */ = Q_NULLPTR
#endif
)
{
@@ -2095,7 +2107,7 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI
, m_loadOp(loadOp)
, m_constructor(constructor)
, m_destructor(destructor)
- , m_extension(0)
+ , m_extension(Q_NULLPTR)
, m_size(size)
, m_typeFlags(theTypeFlags)
, m_extensionFlags(extensionFlags)
@@ -2232,21 +2244,6 @@ namespace QtPrivate {
};
}
-namespace QtMetaTypePrivate {
-inline Q_DECL_CONSTEXPR bool isBuiltinSequentialType(int typeId)
-{
- return typeId == qMetaTypeId<QStringList>()
- || typeId == qMetaTypeId<QByteArrayList>()
- || typeId == qMetaTypeId<QVariantList>();
-}
-
-inline Q_DECL_CONSTEXPR bool isBuiltinAssociativeType(int typeId)
-{
- return typeId == qMetaTypeId<QVariantHash>()
- || typeId == qMetaTypeId<QVariantMap>();
-}
-} // QtMetaTypePrivate
-
QT_END_NAMESPACE
#endif // QMETATYPE_H
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index 3e9cdac966..93788afeae 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -354,7 +354,9 @@ void QMimeData::setUrls(const QList<QUrl> &urls)
{
Q_D(QMimeData);
QList<QVariant> list;
- for (int i = 0; i < urls.size(); ++i)
+ const int numUrls = urls.size();
+ list.reserve(numUrls);
+ for (int i = 0; i < numUrls; ++i)
list.append(urls.at(i));
d->setData(QLatin1String("text/uri-list"), list);
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index bcc4e7f8e6..b624c3880e 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -47,7 +47,6 @@
#include <qthread.h>
#include <private/qthread_p.h>
#include <qdebug.h>
-#include <qhash.h>
#include <qpair.h>
#include <qvarlengtharray.h>
#include <qset.h>
@@ -66,6 +65,16 @@ QT_BEGIN_NAMESPACE
static int DIRECT_CONNECTION_ONLY = 0;
+
+QDynamicMetaObjectData::~QDynamicMetaObjectData()
+{
+}
+
+QAbstractDynamicMetaObject::~QAbstractDynamicMetaObject()
+{
+}
+
+
struct QSlotObjectBaseDeleter { // for use with QScopedPointer<QSlotObjectBase,...>
static void cleanup(QtPrivate::QSlotObjectBase *slot) {
if (slot) slot->destroyIfLastRef();
@@ -494,6 +503,7 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
\brief Exception-safe wrapper around QObject::blockSignals()
\since 5.3
\ingroup objectmodel
+ \inmodule QtCore
\reentrant
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 5f61dd984f..64c5b58fd4 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -110,23 +110,23 @@ class Q_CORE_EXPORT QObject
Q_DECLARE_PRIVATE(QObject)
public:
- Q_INVOKABLE explicit QObject(QObject *parent=0);
+ Q_INVOKABLE explicit QObject(QObject *parent=Q_NULLPTR);
virtual ~QObject();
virtual bool event(QEvent *);
virtual bool eventFilter(QObject *, QEvent *);
#ifdef Q_QDOC
- static QString tr(const char *sourceText, const char *comment = 0, int n = -1);
- static QString trUtf8(const char *sourceText, const char *comment = 0, int n = -1);
+ static QString tr(const char *sourceText, const char *comment = Q_NULLPTR, int n = -1);
+ static QString trUtf8(const char *sourceText, const char *comment = Q_NULLPTR, int n = -1);
virtual const QMetaObject *metaObject() const;
static const QMetaObject staticMetaObject;
#endif
#ifdef QT_NO_TRANSLATION
- static QString tr(const char *sourceText, const char * = 0, int = -1)
+ static QString tr(const char *sourceText, const char * = Q_NULLPTR, int = -1)
{ return QString::fromUtf8(sourceText); }
#if QT_DEPRECATED_SINCE(5, 0)
- QT_DEPRECATED static QString trUtf8(const char *sourceText, const char * = 0, int = -1)
+ QT_DEPRECATED static QString trUtf8(const char *sourceText, const char * = Q_NULLPTR, int = -1)
{ return QString::fromUtf8(sourceText); }
#endif
#endif //QT_NO_TRANSLATION
@@ -228,7 +228,7 @@ public:
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
- const int *types = 0;
+ const int *types = Q_NULLPTR;
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
@@ -268,11 +268,11 @@ public:
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
- const int *types = 0;
+ const int *types = Q_NULLPTR;
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
- return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0,
+ return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR,
new QtPrivate::QStaticSlotObject<Func2,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
@@ -338,11 +338,11 @@ public:
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
"No Q_OBJECT in the class with the signal");
- const int *types = 0;
+ const int *types = Q_NULLPTR;
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
- return connectImpl(sender, reinterpret_cast<void **>(&signal), context, 0,
+ return connectImpl(sender, reinterpret_cast<void **>(&signal), context, Q_NULLPTR,
new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
@@ -354,11 +354,11 @@ public:
const QObject *receiver, const char *member);
static bool disconnect(const QObject *sender, const QMetaMethod &signal,
const QObject *receiver, const QMetaMethod &member);
- inline bool disconnect(const char *signal = 0,
- const QObject *receiver = 0, const char *member = 0) const
+ inline bool disconnect(const char *signal = Q_NULLPTR,
+ const QObject *receiver = Q_NULLPTR, const char *member = Q_NULLPTR) const
{ return disconnect(this, signal, receiver, member); }
- inline bool disconnect(const QObject *receiver, const char *member = 0) const
- { return disconnect(this, 0, receiver, member); }
+ inline bool disconnect(const QObject *receiver, const char *member = Q_NULLPTR) const
+ { return disconnect(this, Q_NULLPTR, receiver, member); }
static bool disconnect(const QMetaObject::Connection &);
#ifdef Q_QDOC
@@ -385,7 +385,7 @@ public:
static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const QObject *receiver, void **zero)
{
- // This is the overload for when one wish to disconnect a signal from any slot. (slot=0)
+ // This is the overload for when one wish to disconnect a signal from any slot. (slot=Q_NULLPTR)
// Since the function template parameter cannot be deduced from '0', we use a
// dummy void ** parameter that must be equal to 0
Q_ASSERT(!zero);
@@ -412,14 +412,14 @@ public:
#endif // QT_NO_USERDATA
Q_SIGNALS:
- void destroyed(QObject * = 0);
+ void destroyed(QObject * = Q_NULLPTR);
void objectNameChanged(const QString &objectName, QPrivateSignal);
public:
inline QObject *parent() const { return d_ptr->parent; }
inline bool inherits(const char *classname) const
- { return const_cast<QObject *>(this)->qt_metacast(classname) != 0; }
+ { return const_cast<QObject *>(this)->qt_metacast(classname) != Q_NULLPTR; }
public Q_SLOTS:
void deleteLater();
@@ -438,7 +438,7 @@ protected:
virtual void disconnectNotify(const QMetaMethod &signal);
protected:
- QObject(QObjectPrivate &dd, QObject *parent = 0);
+ QObject(QObjectPrivate &dd, QObject *parent = Q_NULLPTR);
protected:
QScopedPointer<QObjectData> d_ptr;
@@ -529,16 +529,16 @@ inline T qobject_cast(const QObject *object)
template <class T> inline const char * qobject_interface_iid()
-{ return 0; }
+{ return Q_NULLPTR; }
#ifndef Q_MOC_RUN
# define Q_DECLARE_INTERFACE(IFace, IId) \
template <> inline const char *qobject_interface_iid<IFace *>() \
{ return IId; } \
template <> inline IFace *qobject_cast<IFace *>(QObject *object) \
- { return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : 0)); } \
+ { return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : Q_NULLPTR)); } \
template <> inline IFace *qobject_cast<IFace *>(const QObject *object) \
- { return reinterpret_cast<IFace *>((object ? const_cast<QObject *>(object)->qt_metacast(IId) : 0)); }
+ { return reinterpret_cast<IFace *>((object ? const_cast<QObject *>(object)->qt_metacast(IId) : Q_NULLPTR)); }
#endif // Q_MOC_RUN
#ifndef QT_NO_DEBUG_STREAM
@@ -584,7 +584,7 @@ QSignalBlocker::QSignalBlocker(QSignalBlocker &&other) Q_DECL_NOTHROW
m_blocked(other.m_blocked),
m_inhibited(other.m_inhibited)
{
- other.m_o = 0;
+ other.m_o = Q_NULLPTR;
}
QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other) Q_DECL_NOTHROW
@@ -598,7 +598,7 @@ QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other) Q_DECL_NOTHROW
m_blocked = other.m_blocked;
m_inhibited = other.m_inhibited;
// disable other:
- other.m_o = 0;
+ other.m_o = Q_NULLPTR;
}
return *this;
}
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index 4d9e42ba76..09d52584c4 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -90,9 +90,9 @@ namespace QtPrivate {
{ enum { Value = QMetaTypeId2<Arg>::Defined && TypesAreDeclaredMetaType<List<Tail...>>::Value }; };
template <typename ArgList, bool Declared = TypesAreDeclaredMetaType<ArgList>::Value > struct ConnectionTypes
- { static const int *types() { return 0; } };
+ { static const int *types() { return Q_NULLPTR; } };
template <> struct ConnectionTypes<List<>, true>
- { static const int *types() { return 0; } };
+ { static const int *types() { return Q_NULLPTR; } };
template <typename... Args> struct ConnectionTypes<List<Args...>, true>
{ static const int *types() { static const int t[sizeof...(Args) + 1] = { (QtPrivate::QMetaTypeIdHelper<Args>::qt_metatype_id())..., 0 }; return t; } };
#endif
@@ -118,10 +118,10 @@ namespace QtPrivate {
inline int ref() Q_DECL_NOTHROW { return m_ref.ref(); }
inline void destroyIfLastRef() Q_DECL_NOTHROW
- { if (!m_ref.deref()) m_impl(Destroy, this, 0, 0, 0); }
+ { if (!m_ref.deref()) m_impl(Destroy, this, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR); }
- inline bool compare(void **a) { bool ret; m_impl(Compare, this, 0, a, &ret); return ret; }
- inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, 0); }
+ inline bool compare(void **a) { bool ret; m_impl(Compare, this, Q_NULLPTR, a, &ret); return ret; }
+ inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, Q_NULLPTR); }
protected:
~QSlotObjectBase() {}
private:
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 1b64103e40..b0690563d7 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -110,7 +110,7 @@ public:
QVector<QObjectUserData *> userData;
#endif
QList<QByteArray> propertyNames;
- QList<QVariant> propertyValues;
+ QVector<QVariant> propertyValues;
QVector<int> runningTimers;
QList<QPointer<QObject> > eventFilters;
QString objectName;
@@ -406,7 +406,7 @@ void Q_CORE_EXPORT qDeleteInEventHandler(QObject *o);
struct QAbstractDynamicMetaObject;
struct Q_CORE_EXPORT QDynamicMetaObjectData
{
- virtual ~QDynamicMetaObjectData() {}
+ virtual ~QDynamicMetaObjectData();
virtual void objectDestroyed(QObject *) { delete this; }
virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) = 0;
@@ -415,6 +415,8 @@ struct Q_CORE_EXPORT QDynamicMetaObjectData
struct Q_CORE_EXPORT QAbstractDynamicMetaObject : public QDynamicMetaObjectData, public QMetaObject
{
+ ~QAbstractDynamicMetaObject();
+
virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) Q_DECL_OVERRIDE { return this; }
virtual int createProperty(const char *, const char *) { return -1; }
virtual int metaCall(QObject *, QMetaObject::Call c, int _id, void **a) Q_DECL_OVERRIDE
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 6484507a12..b1ed971eba 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -78,7 +78,11 @@ class QString;
#define Q_CLASSINFO(name, value)
#define Q_PLUGIN_METADATA(x)
#define Q_INTERFACES(x)
+#ifdef Q_COMPILER_VARIADIC_MACROS
+#define Q_PROPERTY(...)
+#else
#define Q_PROPERTY(text)
+#endif
#define Q_PRIVATE_PROPERTY(d, text)
#define Q_REVISION(v)
#define Q_OVERRIDE(text)
@@ -254,7 +258,7 @@ class QMetaClassInfo;
class Q_CORE_EXPORT QGenericArgument
{
public:
- inline QGenericArgument(const char *aName = 0, const void *aData = 0)
+ inline QGenericArgument(const char *aName = Q_NULLPTR, const void *aData = Q_NULLPTR)
: _data(aData), _name(aName) {}
inline void *data() const { return const_cast<void *>(_data); }
inline const char *name() const { return _name; }
@@ -267,7 +271,7 @@ private:
class Q_CORE_EXPORT QGenericReturnArgument: public QGenericArgument
{
public:
- inline QGenericReturnArgument(const char *aName = 0, void *aData = 0)
+ inline QGenericReturnArgument(const char *aName = Q_NULLPTR, void *aData = Q_NULLPTR)
: QGenericArgument(aName, aData)
{}
};
@@ -347,7 +351,7 @@ struct Q_CORE_EXPORT QMetaObject
// internal index-based connect
static Connection connect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index,
- int type = 0, int *types = 0);
+ int type = 0, int *types = Q_NULLPTR);
// internal index-based disconnect
static bool disconnect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index);
@@ -364,7 +368,7 @@ struct Q_CORE_EXPORT QMetaObject
static bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType,
QGenericReturnArgument ret,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -377,7 +381,7 @@ struct Q_CORE_EXPORT QMetaObject
static inline bool invokeMethod(QObject *obj, const char *member,
QGenericReturnArgument ret,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -394,7 +398,7 @@ struct Q_CORE_EXPORT QMetaObject
static inline bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType type,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -410,7 +414,7 @@ struct Q_CORE_EXPORT QMetaObject
}
static inline bool invokeMethod(QObject *obj, const char *member,
- QGenericArgument val0 = QGenericArgument(0),
+ QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -425,7 +429,7 @@ struct Q_CORE_EXPORT QMetaObject
val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
- QObject *newInstance(QGenericArgument val0 = QGenericArgument(0),
+ QObject *newInstance(QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
@@ -482,11 +486,11 @@ public:
operator bool() const;
#else
typedef void *Connection::*RestrictedBool;
- operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : 0; }
+ operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : Q_NULLPTR; }
#endif
#ifdef Q_COMPILER_RVALUE_REFS
- inline Connection(Connection &&o) : d_ptr(o.d_ptr) { o.d_ptr = 0; }
+ inline Connection(Connection &&o) : d_ptr(o.d_ptr) { o.d_ptr = Q_NULLPTR; }
inline Connection &operator=(Connection &&other)
{ qSwap(d_ptr, other.d_ptr); return *this; }
#endif
diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp
index 2c872716d1..f237498f4e 100644
--- a/src/corelib/kernel/qpointer.cpp
+++ b/src/corelib/kernel/qpointer.cpp
@@ -128,6 +128,14 @@
*/
/*!
+ \fn void QPointer::swap(QPointer &other)
+ \since 5.6
+
+ Swaps the contents of this QPointer with the contents of \a other.
+ This operation is very fast and never fails.
+*/
+
+/*!
\fn QPointer<T> & QPointer::operator=(T* p)
Assignment operator. This guarded pointer will now point to the
diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h
index af7c11e4d7..52bd368301 100644
--- a/src/corelib/kernel/qpointer.h
+++ b/src/corelib/kernel/qpointer.h
@@ -35,6 +35,7 @@
#define QPOINTER_H
#include <QtCore/qsharedpointer.h>
+#include <QtCore/qtypeinfo.h>
#ifndef QT_NO_QOBJECT
@@ -45,6 +46,8 @@ class QVariant;
template <class T>
class QPointer
{
+ Q_STATIC_ASSERT_X(!QtPrivate::is_pointer<T>::value, "QPointer's template type must not be a pointer type");
+
template<typename U>
struct TypeSelector
{
@@ -61,7 +64,14 @@ public:
inline QPointer() { }
inline QPointer(T *p) : wp(p, true) { }
// compiler-generated copy/move ctor/assignment operators are fine!
- inline ~QPointer() { }
+ // compiler-generated dtor is fine!
+
+#ifdef Q_QDOC
+ // Stop qdoc from complaining about missing function
+ ~QPointer();
+#endif
+
+ inline void swap(QPointer &other) { wp.swap(other.wp); }
inline QPointer<T> &operator=(T* p)
{ wp.assign(static_cast<QObjectType*>(p)); return *this; }
diff --git a/src/corelib/kernel/qsharedmemory.h b/src/corelib/kernel/qsharedmemory.h
index c192910dc7..67558e3348 100644
--- a/src/corelib/kernel/qsharedmemory.h
+++ b/src/corelib/kernel/qsharedmemory.h
@@ -68,8 +68,8 @@ public:
UnknownError
};
- QSharedMemory(QObject *parent = 0);
- QSharedMemory(const QString &key, QObject *parent = 0);
+ QSharedMemory(QObject *parent = Q_NULLPTR);
+ QSharedMemory(const QString &key, QObject *parent = Q_NULLPTR);
~QSharedMemory();
void setKey(const QString &key);
diff --git a/src/corelib/kernel/qsignalmapper.h b/src/corelib/kernel/qsignalmapper.h
index df2a0a52ea..7aaef6affc 100644
--- a/src/corelib/kernel/qsignalmapper.h
+++ b/src/corelib/kernel/qsignalmapper.h
@@ -45,7 +45,7 @@ class Q_CORE_EXPORT QSignalMapper : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QSignalMapper)
public:
- explicit QSignalMapper(QObject *parent = 0);
+ explicit QSignalMapper(QObject *parent = Q_NULLPTR);
~QSignalMapper();
void setMapping(QObject *sender, int id);
diff --git a/src/corelib/kernel/qsocketnotifier.h b/src/corelib/kernel/qsocketnotifier.h
index 4bafbfa69f..8a7af6ebbc 100644
--- a/src/corelib/kernel/qsocketnotifier.h
+++ b/src/corelib/kernel/qsocketnotifier.h
@@ -47,7 +47,7 @@ class Q_CORE_EXPORT QSocketNotifier : public QObject
public:
enum Type { Read, Write, Exception };
- QSocketNotifier(qintptr socket, Type, QObject *parent = 0);
+ QSocketNotifier(qintptr socket, Type, QObject *parent = Q_NULLPTR);
~QSocketNotifier();
qintptr socket() const;
diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp
index 19d84c2b3e..e333104add 100644
--- a/src/corelib/kernel/qsystemerror.cpp
+++ b/src/corelib/kernel/qsystemerror.cpp
@@ -145,7 +145,7 @@ static QString standardLibraryErrorString(int errorCode)
return ret.trimmed();
}
-QString QSystemError::toString()
+QString QSystemError::toString() const
{
switch(errorScope) {
case NativeError:
diff --git a/src/corelib/kernel/qsystemerror_p.h b/src/corelib/kernel/qsystemerror_p.h
index e7efb9bbf3..29e9e440e4 100644
--- a/src/corelib/kernel/qsystemerror_p.h
+++ b/src/corelib/kernel/qsystemerror_p.h
@@ -62,9 +62,9 @@ public:
inline QSystemError(int error, ErrorScope scope);
inline QSystemError();
- QString toString();
- inline ErrorScope scope();
- inline int error();
+ QString toString() const;
+ inline ErrorScope scope() const;
+ inline int error() const;
//data members
int errorCode;
@@ -83,12 +83,12 @@ QSystemError::QSystemError()
}
-QSystemError::ErrorScope QSystemError::scope()
+QSystemError::ErrorScope QSystemError::scope() const
{
return errorScope;
}
-int QSystemError::error()
+int QSystemError::error() const
{
return errorCode;
}
diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp
index ca55025c2a..89b8a87f2a 100644
--- a/src/corelib/kernel/qsystemsemaphore_win.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_win.cpp
@@ -115,7 +115,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
return false;
}
} else {
-#if defined(Q_OS_WINRT)
+#if !defined(Q_OS_WINCE)
if (WAIT_OBJECT_0 != WaitForSingleObjectEx(semaphore, INFINITE, FALSE)) {
#else
if (WAIT_OBJECT_0 != WaitForSingleObject(semaphore, INFINITE)) {
diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h
index 163ef75291..889f5d7f70 100644
--- a/src/corelib/kernel/qtimer.h
+++ b/src/corelib/kernel/qtimer.h
@@ -53,7 +53,7 @@ class Q_CORE_EXPORT QTimer : public QObject
Q_PROPERTY(Qt::TimerType timerType READ timerType WRITE setTimerType)
Q_PROPERTY(bool active READ isActive)
public:
- explicit QTimer(QObject *parent = 0);
+ explicit QTimer(QObject *parent = Q_NULLPTR);
~QTimer();
inline bool isActive() const { return id >= 0; }
@@ -102,12 +102,16 @@ public:
}
// singleShot to a functor or function pointer (without context)
template <typename Func1>
- static inline void singleShot(int msec, Func1 slot)
+ static inline typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
+ !QtPrivate::is_same<const char*, Func1>::value, void>::Type
+ singleShot(int msec, Func1 slot)
{
singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, Q_NULLPTR, slot);
}
template <typename Func1>
- static inline void singleShot(int msec, Qt::TimerType timerType, Func1 slot)
+ static inline typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
+ !QtPrivate::is_same<const char*, Func1>::value, void>::Type
+ singleShot(int msec, Qt::TimerType timerType, Func1 slot)
{
singleShot(msec, timerType, Q_NULLPTR, slot);
}
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 360c5873d4..794a4aaa0c 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -46,7 +46,6 @@
#include "qfile.h"
#include "qmap.h"
#include "qalgorithms.h"
-#include "qhash.h"
#include "qtranslator_p.h"
#include "qlocale.h"
#include "qendian.h"
diff --git a/src/corelib/kernel/qtranslator.h b/src/corelib/kernel/qtranslator.h
index 1552bbde35..78f714c5c6 100644
--- a/src/corelib/kernel/qtranslator.h
+++ b/src/corelib/kernel/qtranslator.h
@@ -49,11 +49,11 @@ class Q_CORE_EXPORT QTranslator : public QObject
{
Q_OBJECT
public:
- explicit QTranslator(QObject *parent = 0);
+ explicit QTranslator(QObject *parent = Q_NULLPTR);
~QTranslator();
virtual QString translate(const char *context, const char *sourceText,
- const char *disambiguation = 0, int n = -1) const;
+ const char *disambiguation = Q_NULLPTR, int n = -1) const;
virtual bool isEmpty() const;
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index f7a4abbf68..35f178e6a9 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -3832,7 +3832,11 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
/*!
\internal
*/
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QSequentialIterable::QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl)
+#else
+QSequentialIterable::QSequentialIterable(const QtMetaTypePrivate::QSequentialIterableImpl &impl)
+#endif
: m_impl(impl)
{
}
@@ -4140,7 +4144,11 @@ QSequentialIterable::const_iterator QSequentialIterable::const_iterator::operato
/*!
\internal
*/
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QAssociativeIterable::QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl)
+#else
+QAssociativeIterable::QAssociativeIterable(const QtMetaTypePrivate::QAssociativeIterableImpl &impl)
+#endif
: m_impl(impl)
{
}
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 58dfc3aab0..4c7e498280 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -278,14 +278,14 @@ class Q_CORE_EXPORT QVariant
void detach();
inline bool isDetached() const;
- int toInt(bool *ok = 0) const;
- uint toUInt(bool *ok = 0) const;
- qlonglong toLongLong(bool *ok = 0) const;
- qulonglong toULongLong(bool *ok = 0) const;
+ int toInt(bool *ok = Q_NULLPTR) const;
+ uint toUInt(bool *ok = Q_NULLPTR) const;
+ qlonglong toLongLong(bool *ok = Q_NULLPTR) const;
+ qulonglong toULongLong(bool *ok = Q_NULLPTR) const;
bool toBool() const;
- double toDouble(bool *ok = 0) const;
- float toFloat(bool *ok = 0) const;
- qreal toReal(bool *ok = 0) const;
+ double toDouble(bool *ok = Q_NULLPTR) const;
+ float toFloat(bool *ok = Q_NULLPTR) const;
+ qreal toReal(bool *ok = Q_NULLPTR) const;
QByteArray toByteArray() const;
QBitArray toBitArray() const;
QString toString() const;
@@ -364,7 +364,7 @@ class Q_CORE_EXPORT QVariant
struct Private
{
inline Private() Q_DECL_NOTHROW : type(Invalid), is_shared(false), is_null(true)
- { data.ptr = 0; }
+ { data.ptr = Q_NULLPTR; }
// Internal constructor for initialized variants.
explicit inline Private(uint variantType) Q_DECL_NOTHROW
@@ -607,7 +607,11 @@ public:
friend struct const_iterator;
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
explicit QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl impl);
+#else
+ explicit QSequentialIterable(const QtMetaTypePrivate::QSequentialIterableImpl &impl);
+#endif
const_iterator begin() const;
const_iterator end() const;
@@ -660,7 +664,11 @@ public:
friend struct const_iterator;
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
explicit QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl impl);
+#else
+ explicit QAssociativeIterable(const QtMetaTypePrivate::QAssociativeIterableImpl &impl);
+#endif
const_iterator begin() const;
const_iterator end() const;
@@ -742,7 +750,7 @@ namespace QtPrivate {
static QVariantList invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (QtMetaTypePrivate::isBuiltinSequentialType(typeId) || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
+ if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
QVariantList l;
l.reserve(iter.size());
@@ -759,7 +767,7 @@ namespace QtPrivate {
static QVariantHash invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (QtMetaTypePrivate::isBuiltinAssociativeType(typeId) || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ if (typeId == qMetaTypeId<QVariantMap>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantHash l;
l.reserve(iter.size());
@@ -776,7 +784,7 @@ namespace QtPrivate {
static QVariantMap invoke(const QVariant &v)
{
const int typeId = v.userType();
- if (QtMetaTypePrivate::isBuiltinAssociativeType(typeId) || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ if (typeId == qMetaTypeId<QVariantHash>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantMap l;
for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index bec7a79e8f..133933f9af 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -434,6 +434,7 @@ QList<QMimeType> QMimeDatabase::mimeTypesForFileName(const QString &fileName) co
QStringList matches = d->mimeTypeForFileName(fileName);
QList<QMimeType> mimes;
matches.sort(); // Make it deterministic
+ mimes.reserve(matches.count());
foreach (const QString &mime, matches)
mimes.append(d->mimeTypeForName(mime));
return mimes;
diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h
index e3cfe3443f..1308907b9b 100644
--- a/src/corelib/mimetypes/qmimedatabase_p.h
+++ b/src/corelib/mimetypes/qmimedatabase_p.h
@@ -52,7 +52,6 @@
#include "qmimetype_p.h"
#include "qmimeglobpattern_p.h"
-#include <QtCore/qhash.h>
#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 887db51e5c..fa40b743d3 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -540,6 +540,7 @@ QList<QMimeType> QMimeBinaryProvider::allMimeTypes()
{
QList<QMimeType> result;
loadMimeTypeList();
+ result.reserve(m_mimetypeNames.count());
for (QSet<QString>::const_iterator it = m_mimetypeNames.constBegin();
it != m_mimetypeNames.constEnd(); ++it)
diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
index a5f9cb70d5..3206ff66e3 100644
--- a/src/corelib/mimetypes/qmimetype.cpp
+++ b/src/corelib/mimetypes/qmimetype.cpp
@@ -43,6 +43,7 @@
#include <QtCore/QDebug>
#include <QtCore/QLocale>
+#include <QtCore/QHashFunctions>
#include <memory>
@@ -181,6 +182,18 @@ bool QMimeType::operator==(const QMimeType &other) const
}
/*!
+ \since 5.6
+ \relates QMimeType
+
+ Returns the hash value for \a key, using
+ \a seed to seed the calculation.
+ */
+uint qHash(const QMimeType &key, uint seed) Q_DECL_NOTHROW
+{
+ return qHash(key.d->name, seed);
+}
+
+/*!
\fn bool QMimeType::operator!=(const QMimeType &other) const;
Returns \c true if \a other does not equal this QMimeType object, otherwise returns \c false.
*/
diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h
index 4ba3c53470..3c153da21d 100644
--- a/src/corelib/mimetypes/qmimetype.h
+++ b/src/corelib/mimetypes/qmimetype.h
@@ -46,6 +46,9 @@ QT_BEGIN_NAMESPACE
class QMimeTypePrivate;
class QFileinfo;
class QStringList;
+class QMimeType;
+
+Q_CORE_EXPORT uint qHash(const QMimeType &key, uint seed = 0) Q_DECL_NOTHROW;
class Q_CORE_EXPORT QMimeType
{
@@ -54,13 +57,9 @@ public:
QMimeType(const QMimeType &other);
QMimeType &operator=(const QMimeType &other);
#ifdef Q_COMPILER_RVALUE_REFS
- QMimeType &operator=(QMimeType &&other)
- {
- qSwap(d, other.d);
- return *this;
- }
+ QMimeType &operator=(QMimeType &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- void swap(QMimeType &other)
+ void swap(QMimeType &other) Q_DECL_NOTHROW
{
qSwap(d, other.d);
}
@@ -100,6 +99,7 @@ protected:
friend class QMimeXMLProvider;
friend class QMimeBinaryProvider;
friend class QMimeTypePrivate;
+ friend Q_CORE_EXPORT uint qHash(const QMimeType &key, uint seed) Q_DECL_NOTHROW;
QExplicitlySharedDataPointer<QMimeTypePrivate> d;
};
diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri
index 338b3d0972..8b64f93467 100644
--- a/src/corelib/plugin/plugin.pri
+++ b/src/corelib/plugin/plugin.pri
@@ -13,6 +13,7 @@ HEADERS += \
plugin/qmachparser_p.h
SOURCES += \
+ plugin/qfactoryinterface.cpp \
plugin/qpluginloader.cpp \
plugin/qfactoryloader.cpp \
plugin/quuid.cpp \
diff --git a/src/corelib/plugin/qfactoryinterface.cpp b/src/corelib/plugin/qfactoryinterface.cpp
new file mode 100644
index 0000000000..0307d58315
--- /dev/null
+++ b/src/corelib/plugin/qfactoryinterface.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfactoryinterface.h"
+
+QT_BEGIN_NAMESPACE
+
+QFactoryInterface::~QFactoryInterface()
+{
+ // must be empty until ### Qt 6
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/plugin/qfactoryinterface.h b/src/corelib/plugin/qfactoryinterface.h
index e20864cd31..86a46fabfa 100644
--- a/src/corelib/plugin/qfactoryinterface.h
+++ b/src/corelib/plugin/qfactoryinterface.h
@@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE
struct Q_CORE_EXPORT QFactoryInterface
{
- virtual ~QFactoryInterface() {}
+ virtual ~QFactoryInterface();
virtual QStringList keys() const = 0;
};
diff --git a/src/corelib/plugin/qlibrary.h b/src/corelib/plugin/qlibrary.h
index 16bdf79206..77ad107c6f 100644
--- a/src/corelib/plugin/qlibrary.h
+++ b/src/corelib/plugin/qlibrary.h
@@ -59,10 +59,10 @@ public:
Q_FLAG(LoadHint)
Q_FLAG(LoadHints)
- explicit QLibrary(QObject *parent = 0);
- explicit QLibrary(const QString& fileName, QObject *parent = 0);
- explicit QLibrary(const QString& fileName, int verNum, QObject *parent = 0);
- explicit QLibrary(const QString& fileName, const QString &version, QObject *parent = 0);
+ explicit QLibrary(QObject *parent = Q_NULLPTR);
+ explicit QLibrary(const QString& fileName, QObject *parent = Q_NULLPTR);
+ explicit QLibrary(const QString& fileName, int verNum, QObject *parent = Q_NULLPTR);
+ explicit QLibrary(const QString& fileName, const QString &version, QObject *parent = Q_NULLPTR);
~QLibrary();
QFunctionPointer resolve(const char *symbol);
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 988dad1d94..292ad30525 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -273,6 +273,13 @@ bool QPluginLoader::isLoaded() const
#if defined(QT_SHARED)
static QString locatePlugin(const QString& fileName)
{
+ const bool isAbsolute = QDir::isAbsolutePath(fileName);
+ if (isAbsolute) {
+ QFileInfo fi(fileName);
+ if (fi.isFile()) {
+ return fi.canonicalFilePath();
+ }
+ }
QStringList prefixes = QLibraryPrivate::prefixes_sys();
prefixes.prepend(QString());
QStringList suffixes = QLibraryPrivate::suffixes_sys(QString());
@@ -281,12 +288,18 @@ static QString locatePlugin(const QString& fileName)
// Split up "subdir/filename"
const int slash = fileName.lastIndexOf('/');
const QString baseName = fileName.mid(slash + 1);
- const QString basePath = fileName.left(slash + 1); // keep the '/'
+ const QString basePath = isAbsolute ? QString() : fileName.left(slash + 1); // keep the '/'
const bool debug = qt_debug_component();
- QStringList paths = QCoreApplication::libraryPaths();
- paths.prepend(QStringLiteral("./")); // search in current dir first
+ QStringList paths;
+ if (isAbsolute) {
+ paths.append(fileName.left(slash)); // don't include the '/'
+ } else {
+ paths = QCoreApplication::libraryPaths();
+ paths.prepend(QStringLiteral(".")); // search in current dir first
+ }
+
foreach (const QString &path, paths) {
foreach (const QString &prefix, prefixes) {
foreach (const QString &suffix, suffixes) {
@@ -337,12 +350,7 @@ void QPluginLoader::setFileName(const QString &fileName)
did_load = false;
}
- QFileInfo fi(fileName);
- QString fn;
- if (fi.isAbsolute())
- fn = fi.canonicalFilePath();
- else
- fn = locatePlugin(fileName);
+ const QString fn = locatePlugin(fileName);
d = QLibraryPrivate::findOrCreate(fn, QString(), lh);
if (!fn.isEmpty())
@@ -427,7 +435,9 @@ QObjectList QPluginLoader::staticInstances()
QObjectList instances;
const StaticPluginList *plugins = staticPluginList();
if (plugins) {
- for (int i = 0; i < plugins->size(); ++i)
+ const int numPlugins = plugins->size();
+ instances.reserve(numPlugins);
+ for (int i = 0; i < numPlugins; ++i)
instances += plugins->at(i).instance();
}
return instances;
diff --git a/src/corelib/plugin/qpluginloader.h b/src/corelib/plugin/qpluginloader.h
index b947e6ed9e..0ab25bbb07 100644
--- a/src/corelib/plugin/qpluginloader.h
+++ b/src/corelib/plugin/qpluginloader.h
@@ -50,8 +50,8 @@ class Q_CORE_EXPORT QPluginLoader : public QObject
Q_PROPERTY(QString fileName READ fileName WRITE setFileName)
Q_PROPERTY(QLibrary::LoadHints loadHints READ loadHints WRITE setLoadHints)
public:
- explicit QPluginLoader(QObject *parent = 0);
- explicit QPluginLoader(const QString &fileName, QObject *parent = 0);
+ explicit QPluginLoader(QObject *parent = Q_NULLPTR);
+ explicit QPluginLoader(const QString &fileName, QObject *parent = Q_NULLPTR);
~QPluginLoader();
QObject *instance();
diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp
index 543edb2f98..2c412849e8 100644
--- a/src/corelib/statemachine/qabstractstate.cpp
+++ b/src/corelib/statemachine/qabstractstate.cpp
@@ -85,16 +85,6 @@ QAbstractStatePrivate::QAbstractStatePrivate(StateType type)
{
}
-QAbstractStatePrivate *QAbstractStatePrivate::get(QAbstractState *q)
-{
- return q->d_func();
-}
-
-const QAbstractStatePrivate *QAbstractStatePrivate::get(const QAbstractState *q)
-{
- return q->d_func();
-}
-
QStateMachine *QAbstractStatePrivate::machine() const
{
QObject *par = parent;
@@ -227,7 +217,7 @@ bool QAbstractState::active() const
\fn QAbstractState::activeChanged(bool active)
\since 5.4
- This signal is emitted when the active property is changed.
+ This signal is emitted when the active property is changed with \a active as argument.
\sa QAbstractState::active, entered(), exited()
*/
diff --git a/src/corelib/statemachine/qabstractstate.h b/src/corelib/statemachine/qabstractstate.h
index 592c841c18..3aa4b2fabb 100644
--- a/src/corelib/statemachine/qabstractstate.h
+++ b/src/corelib/statemachine/qabstractstate.h
@@ -63,7 +63,7 @@ Q_SIGNALS:
void activeChanged(bool active);
protected:
- QAbstractState(QState *parent = 0);
+ QAbstractState(QState *parent = Q_NULLPTR);
virtual void onEntry(QEvent *event) = 0;
virtual void onExit(QEvent *event) = 0;
diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h
index 087e355b71..1eb3cbd420 100644
--- a/src/corelib/statemachine/qabstractstate_p.h
+++ b/src/corelib/statemachine/qabstractstate_p.h
@@ -46,12 +46,13 @@
//
#include <private/qobject_p.h>
+#include <QtCore/qabstractstate.h>
QT_BEGIN_NAMESPACE
class QStateMachine;
-class QAbstractState;
+class QState;
class QAbstractStatePrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QAbstractState)
@@ -66,8 +67,10 @@ public:
QAbstractStatePrivate(StateType type);
- static QAbstractStatePrivate *get(QAbstractState *q);
- static const QAbstractStatePrivate *get(const QAbstractState *q);
+ static QAbstractStatePrivate *get(QAbstractState *q)
+ { return q->d_func(); }
+ static const QAbstractStatePrivate *get(const QAbstractState *q)
+ { return q->d_func(); }
QStateMachine *machine() const;
diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp
index 81b38ea4c4..5a7a95883b 100644
--- a/src/corelib/statemachine/qabstracttransition.cpp
+++ b/src/corelib/statemachine/qabstracttransition.cpp
@@ -37,6 +37,7 @@
#include "qabstracttransition_p.h"
#include "qabstractstate.h"
+#include "qhistorystate.h"
#include "qstate.h"
#include "qstatemachine.h"
@@ -133,17 +134,14 @@ QAbstractTransitionPrivate::QAbstractTransitionPrivate()
{
}
-QAbstractTransitionPrivate *QAbstractTransitionPrivate::get(QAbstractTransition *q)
-{
- return q->d_func();
-}
-
QStateMachine *QAbstractTransitionPrivate::machine() const
{
- QState *source = sourceState();
- if (!source)
- return 0;
- return source->machine();
+ if (QState *source = sourceState())
+ return source->machine();
+ Q_Q(const QAbstractTransition);
+ if (QHistoryState *parent = qobject_cast<QHistoryState *>(q->parent()))
+ return parent->machine();
+ return 0;
}
bool QAbstractTransitionPrivate::callEventTest(QEvent *e)
@@ -254,7 +252,7 @@ QList<QAbstractState*> QAbstractTransition::targetStates() const
void QAbstractTransition::setTargetStates(const QList<QAbstractState*> &targets)
{
Q_D(QAbstractTransition);
- QList<QPointer<QAbstractState> > copy(d->targetStates);
+ QVector<QPointer<QAbstractState> > copy(d->targetStates);
bool sameList = true;
for (int i = 0; i < targets.size(); ++i) {
QAbstractState *target = targets.at(i);
diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h
index 475a4dedfc..4398c41ca2 100644
--- a/src/corelib/statemachine/qabstracttransition.h
+++ b/src/corelib/statemachine/qabstracttransition.h
@@ -67,7 +67,7 @@ public:
};
Q_ENUM(TransitionType)
- QAbstractTransition(QState *sourceState = 0);
+ QAbstractTransition(QState *sourceState = Q_NULLPTR);
virtual ~QAbstractTransition();
QState *sourceState() const;
diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h
index 4b0644acd9..ed726fa6ef 100644
--- a/src/corelib/statemachine/qabstracttransition_p.h
+++ b/src/corelib/statemachine/qabstracttransition_p.h
@@ -48,6 +48,7 @@
#include <private/qobject_p.h>
#include <QtCore/qlist.h>
+#include <QtCore/qvector.h>
#include <QtCore/qsharedpointer.h>
QT_BEGIN_NAMESPACE
@@ -64,7 +65,8 @@ class Q_CORE_EXPORT QAbstractTransitionPrivate
public:
QAbstractTransitionPrivate();
- static QAbstractTransitionPrivate *get(QAbstractTransition *q);
+ static QAbstractTransitionPrivate *get(QAbstractTransition *q)
+ { return q->d_func(); }
bool callEventTest(QEvent *e);
virtual void callOnTransition(QEvent *e);
@@ -72,7 +74,7 @@ public:
QStateMachine *machine() const;
void emitTriggered();
- QList<QPointer<QAbstractState> > targetStates;
+ QVector<QPointer<QAbstractState> > targetStates;
QAbstractTransition::TransitionType transitionType;
#ifndef QT_NO_ANIMATION
diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp
index 096d667bc3..de6858ae42 100644
--- a/src/corelib/statemachine/qeventtransition.cpp
+++ b/src/corelib/statemachine/qeventtransition.cpp
@@ -102,9 +102,8 @@ QEventTransitionPrivate::QEventTransitionPrivate()
registered = false;
}
-QEventTransitionPrivate *QEventTransitionPrivate::get(QEventTransition *q)
+QEventTransitionPrivate::~QEventTransitionPrivate()
{
- return q->d_func();
}
void QEventTransitionPrivate::unregister()
diff --git a/src/corelib/statemachine/qeventtransition.h b/src/corelib/statemachine/qeventtransition.h
index 6909e855b1..5ec3b7bb26 100644
--- a/src/corelib/statemachine/qeventtransition.h
+++ b/src/corelib/statemachine/qeventtransition.h
@@ -49,8 +49,8 @@ class Q_CORE_EXPORT QEventTransition : public QAbstractTransition
Q_PROPERTY(QObject* eventSource READ eventSource WRITE setEventSource)
Q_PROPERTY(QEvent::Type eventType READ eventType WRITE setEventType)
public:
- QEventTransition(QState *sourceState = 0);
- QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = 0);
+ QEventTransition(QState *sourceState = Q_NULLPTR);
+ QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = Q_NULLPTR);
~QEventTransition();
QObject *eventSource() const;
diff --git a/src/corelib/statemachine/qeventtransition_p.h b/src/corelib/statemachine/qeventtransition_p.h
index 59b0fcb30f..3f6c9475ea 100644
--- a/src/corelib/statemachine/qeventtransition_p.h
+++ b/src/corelib/statemachine/qeventtransition_p.h
@@ -55,8 +55,10 @@ class Q_CORE_EXPORT QEventTransitionPrivate : public QAbstractTransitionPrivate
Q_DECLARE_PUBLIC(QEventTransition)
public:
QEventTransitionPrivate();
+ ~QEventTransitionPrivate();
- static QEventTransitionPrivate *get(QEventTransition *q);
+ static QEventTransitionPrivate *get(QEventTransition *q)
+ { return q->d_func(); }
void unregister();
void maybeRegister();
diff --git a/src/corelib/statemachine/qfinalstate.h b/src/corelib/statemachine/qfinalstate.h
index 51c97b1545..2c76e7b6e6 100644
--- a/src/corelib/statemachine/qfinalstate.h
+++ b/src/corelib/statemachine/qfinalstate.h
@@ -46,7 +46,7 @@ class Q_CORE_EXPORT QFinalState : public QAbstractState
{
Q_OBJECT
public:
- QFinalState(QState *parent = 0);
+ QFinalState(QState *parent = Q_NULLPTR);
~QFinalState();
protected:
diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp
index e58b0c16fc..a0ebb9d239 100644
--- a/src/corelib/statemachine/qhistorystate.cpp
+++ b/src/corelib/statemachine/qhistorystate.cpp
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
A history state is a pseudo-state that represents the child state that the
parent state was in the last time the parent state was exited. A transition
- with a history state as its target is in fact a transition to one of the
+ with a history state as its target is in fact a transition to one or more
other child states of the parent state. QHistoryState is part of \l{The
State Machine Framework}.
@@ -79,11 +79,22 @@ QT_BEGIN_NAMESPACE
s1->addTransition(button, SIGNAL(clicked()), s1h);
\endcode
+ If more than one default state has to be entered, or if the transition to the default state(s)
+ has to be acted upon, the defaultTransition should be set instead. Note that the eventTest()
+ method of that transition will never be called: the selection and execution of the transition is
+ done automatically when entering the history state.
+
By default a history state is shallow, meaning that it won't remember nested
states. This can be configured through the historyType property.
*/
/*!
+ \property QHistoryState::defaultTransition
+
+ \brief the default transition of this history state
+*/
+
+/*!
\property QHistoryState::defaultState
\brief the default state of this history state
@@ -113,14 +124,17 @@ QT_BEGIN_NAMESPACE
*/
QHistoryStatePrivate::QHistoryStatePrivate()
- : QAbstractStatePrivate(HistoryState),
- defaultState(0), historyType(QHistoryState::ShallowHistory)
+ : QAbstractStatePrivate(HistoryState)
+ , defaultTransition(0)
+ , historyType(QHistoryState::ShallowHistory)
{
}
-QHistoryStatePrivate *QHistoryStatePrivate::get(QHistoryState *q)
+DefaultStateTransition::DefaultStateTransition(QHistoryState *source, QAbstractState *target)
+ : QAbstractTransition()
{
- return q->d_func();
+ setParent(source);
+ setTargetState(target);
}
/*!
@@ -149,13 +163,40 @@ QHistoryState::~QHistoryState()
}
/*!
+ Returns this history state's default transition. The default transition is
+ taken when the history state has never been entered before. The target states
+ of the default transition therefore make up the default state.
+*/
+QAbstractTransition *QHistoryState::defaultTransition() const
+{
+ Q_D(const QHistoryState);
+ return d->defaultTransition;
+}
+
+/*!
+ Sets this history state's default transition to be the given \a transition.
+ This will set the source state of the \a transition to the history state.
+
+ Note that the eventTest method of the \a transition will never be called.
+*/
+void QHistoryState::setDefaultTransition(QAbstractTransition *transition)
+{
+ Q_D(QHistoryState);
+ if (d->defaultTransition != transition) {
+ d->defaultTransition = transition;
+ transition->setParent(this);
+ emit defaultTransitionChanged(QHistoryState::QPrivateSignal());
+ }
+}
+
+/*!
Returns this history state's default state. The default state indicates the
state to transition to if the parent state has never been entered before.
*/
QAbstractState *QHistoryState::defaultState() const
{
Q_D(const QHistoryState);
- return d->defaultState;
+ return d->defaultTransition ? d->defaultTransition->targetState() : Q_NULLPTR;
}
/*!
@@ -173,8 +214,15 @@ void QHistoryState::setDefaultState(QAbstractState *state)
"to this history state's group (%p)", state, parentState());
return;
}
- if (d->defaultState != state) {
- d->defaultState = state;
+ if (!d->defaultTransition
+ || d->defaultTransition->targetStates().size() != 1
+ || d->defaultTransition->targetStates().first() != state) {
+ if (!d->defaultTransition || !qobject_cast<DefaultStateTransition*>(d->defaultTransition)) {
+ d->defaultTransition = new DefaultStateTransition(this, state);
+ emit defaultTransitionChanged(QHistoryState::QPrivateSignal());
+ } else {
+ d->defaultTransition->setTargetState(state);
+ }
emit defaultStateChanged(QHistoryState::QPrivateSignal());
}
}
diff --git a/src/corelib/statemachine/qhistorystate.h b/src/corelib/statemachine/qhistorystate.h
index 549be15ab0..2f2081bf9c 100644
--- a/src/corelib/statemachine/qhistorystate.h
+++ b/src/corelib/statemachine/qhistorystate.h
@@ -41,11 +41,13 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_STATEMACHINE
+class QAbstractTransition;
class QHistoryStatePrivate;
class Q_CORE_EXPORT QHistoryState : public QAbstractState
{
Q_OBJECT
Q_PROPERTY(QAbstractState* defaultState READ defaultState WRITE setDefaultState NOTIFY defaultStateChanged)
+ Q_PROPERTY(QAbstractTransition* defaultTransition READ defaultTransition WRITE setDefaultTransition NOTIFY defaultTransitionChanged)
Q_PROPERTY(HistoryType historyType READ historyType WRITE setHistoryType NOTIFY historyTypeChanged)
public:
enum HistoryType {
@@ -54,10 +56,13 @@ public:
};
Q_ENUM(HistoryType)
- QHistoryState(QState *parent = 0);
- QHistoryState(HistoryType type, QState *parent = 0);
+ QHistoryState(QState *parent = Q_NULLPTR);
+ QHistoryState(HistoryType type, QState *parent = Q_NULLPTR);
~QHistoryState();
+ QAbstractTransition *defaultTransition() const;
+ void setDefaultTransition(QAbstractTransition *transition);
+
QAbstractState *defaultState() const;
void setDefaultState(QAbstractState *state);
@@ -65,6 +70,7 @@ public:
void setHistoryType(HistoryType type);
Q_SIGNALS:
+ void defaultTransitionChanged(QPrivateSignal);
void defaultStateChanged(QPrivateSignal);
void historyTypeChanged(QPrivateSignal);
diff --git a/src/corelib/statemachine/qhistorystate_p.h b/src/corelib/statemachine/qhistorystate_p.h
index b5c353fdff..b0865f7f46 100644
--- a/src/corelib/statemachine/qhistorystate_p.h
+++ b/src/corelib/statemachine/qhistorystate_p.h
@@ -47,11 +47,12 @@
#include "private/qabstractstate_p.h"
+#include <QtCore/qabstracttransition.h>
+#include <QtCore/qhistorystate.h>
#include <QtCore/qlist.h>
QT_BEGIN_NAMESPACE
-class QHistoryState;
class QHistoryStatePrivate : public QAbstractStatePrivate
{
Q_DECLARE_PUBLIC(QHistoryState)
@@ -59,13 +60,31 @@ class QHistoryStatePrivate : public QAbstractStatePrivate
public:
QHistoryStatePrivate();
- static QHistoryStatePrivate *get(QHistoryState *q);
+ static QHistoryStatePrivate *get(QHistoryState *q)
+ { return q->d_func(); }
- QAbstractState *defaultState;
+ QAbstractTransition *defaultTransition;
QHistoryState::HistoryType historyType;
QList<QAbstractState*> configuration;
};
+class DefaultStateTransition: public QAbstractTransition
+{
+ Q_OBJECT
+
+public:
+ DefaultStateTransition(QHistoryState *source, QAbstractState *target);
+
+protected:
+ // It doesn't matter whether this transition matches any event or not. It is always associated
+ // with a QHistoryState, and as soon as the state-machine detects that it enters a history
+ // state, it will handle this transition as a special case. The history state itself is never
+ // entered either: either the stored configuration will be used, or the target(s) of this
+ // transition are used.
+ virtual bool eventTest(QEvent *event) { Q_UNUSED(event); return false; }
+ virtual void onTransition(QEvent *event) { Q_UNUSED(event); }
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp
index 41005fca41..7ec72df77c 100644
--- a/src/corelib/statemachine/qsignaltransition.cpp
+++ b/src/corelib/statemachine/qsignaltransition.cpp
@@ -108,11 +108,6 @@ QSignalTransitionPrivate::QSignalTransitionPrivate()
signalIndex = -1;
}
-QSignalTransitionPrivate *QSignalTransitionPrivate::get(QSignalTransition *q)
-{
- return q->d_func();
-}
-
void QSignalTransitionPrivate::unregister()
{
Q_Q(QSignalTransition);
diff --git a/src/corelib/statemachine/qsignaltransition.h b/src/corelib/statemachine/qsignaltransition.h
index bc56f4e9b7..c388323ec4 100644
--- a/src/corelib/statemachine/qsignaltransition.h
+++ b/src/corelib/statemachine/qsignaltransition.h
@@ -49,9 +49,9 @@ class Q_CORE_EXPORT QSignalTransition : public QAbstractTransition
Q_PROPERTY(QByteArray signal READ signal WRITE setSignal NOTIFY signalChanged)
public:
- QSignalTransition(QState *sourceState = 0);
+ QSignalTransition(QState *sourceState = Q_NULLPTR);
QSignalTransition(const QObject *sender, const char *signal,
- QState *sourceState = 0);
+ QState *sourceState = Q_NULLPTR);
~QSignalTransition();
QObject *senderObject() const;
diff --git a/src/corelib/statemachine/qsignaltransition_p.h b/src/corelib/statemachine/qsignaltransition_p.h
index bed0abd9ff..0bf4b1540b 100644
--- a/src/corelib/statemachine/qsignaltransition_p.h
+++ b/src/corelib/statemachine/qsignaltransition_p.h
@@ -56,7 +56,8 @@ class QSignalTransitionPrivate : public QAbstractTransitionPrivate
public:
QSignalTransitionPrivate();
- static QSignalTransitionPrivate *get(QSignalTransition *q);
+ static QSignalTransitionPrivate *get(QSignalTransition *q)
+ { return q->d_func(); }
void unregister();
void maybeRegister();
diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp
index 6e9fb63554..3b84230cb2 100644
--- a/src/corelib/statemachine/qstate.cpp
+++ b/src/corelib/statemachine/qstate.cpp
@@ -320,7 +320,7 @@ void QState::addTransition(QAbstractTransition *transition)
}
transition->setParent(this);
- const QList<QPointer<QAbstractState> > &targets = QAbstractTransitionPrivate::get(transition)->targetStates;
+ const QVector<QPointer<QAbstractState> > &targets = QAbstractTransitionPrivate::get(transition)->targetStates;
for (int i = 0; i < targets.size(); ++i) {
QAbstractState *t = targets.at(i).data();
if (!t) {
@@ -518,6 +518,14 @@ QState::ChildMode QState::childMode() const
void QState::setChildMode(ChildMode mode)
{
Q_D(QState);
+
+ if (mode == QState::ParallelStates && d->initialState) {
+ qWarning("QState::setChildMode: setting the child-mode of state %p to "
+ "parallel removes the initial state", this);
+ d->initialState = Q_NULLPTR;
+ emit initialStateChanged(QState::QPrivateSignal());
+ }
+
if (d->childMode != mode) {
d->childMode = mode;
emit childModeChanged(QState::QPrivateSignal());
diff --git a/src/corelib/statemachine/qstate.h b/src/corelib/statemachine/qstate.h
index a74c782027..0300a9ef2d 100644
--- a/src/corelib/statemachine/qstate.h
+++ b/src/corelib/statemachine/qstate.h
@@ -66,8 +66,8 @@ public:
};
Q_ENUM(RestorePolicy)
- QState(QState *parent = 0);
- QState(ChildMode childMode, QState *parent = 0);
+ QState(QState *parent = Q_NULLPTR);
+ QState(ChildMode childMode, QState *parent = Q_NULLPTR);
~QState();
QAbstractState *errorState() const;
diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h
index 2ce0c13522..3b8dae9499 100644
--- a/src/corelib/statemachine/qstate_p.h
+++ b/src/corelib/statemachine/qstate_p.h
@@ -75,6 +75,7 @@ struct QPropertyAssignment
QVariant value;
bool explicitlySet; // false means the property is being restored to its old value
};
+Q_DECLARE_TYPEINFO(QPropertyAssignment, Q_MOVABLE_TYPE);
#endif // QT_NO_PROPERTIES
@@ -108,7 +109,7 @@ public:
mutable QList<QAbstractTransition*> transitionsList;
#ifndef QT_NO_PROPERTIES
- QList<QPropertyAssignment> propertyAssignments;
+ QVector<QPropertyAssignment> propertyAssignments;
#endif
};
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index e5d019dc8b..687f676819 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -160,6 +160,8 @@ QT_BEGIN_NAMESPACE
\since 5.4
\brief the running state of this state machine
+
+ \sa start(), stop(), started(), stopped(), runningChanged()
*/
#ifndef QT_NO_ANIMATION
@@ -365,9 +367,9 @@ static QList<QAbstractState *> getEffectiveTargetStates(QAbstractTransition *tra
if (!historyConfiguration.isEmpty()) {
// There is a saved history, so apply that.
targets.unite(historyConfiguration.toSet());
- } else if (QAbstractState *defaultState = historyState->defaultState()) {
- // Qt does not support initial transitions, but uses the default state of the history state for this.
- targets.insert(defaultState);
+ } else if (QAbstractTransition *defaultTransition = historyState->defaultTransition()) {
+ // No saved history, take all default transition targets.
+ targets.unite(defaultTransition->targetStates().toSet());
} else {
// Woops, we found a history state without a default state. That's not valid!
QStateMachinePrivate *m = QStateMachinePrivate::get(historyState->machine());
@@ -383,10 +385,6 @@ static QList<QAbstractState *> getEffectiveTargetStates(QAbstractTransition *tra
return targetsList;
}
-template <class T>
-static uint qHash(const QPointer<T> &p)
-{ return qHash(p.data()); }
-
QStateMachinePrivate::QStateMachinePrivate()
{
isMachine = true;
@@ -410,13 +408,6 @@ QStateMachinePrivate::~QStateMachinePrivate()
qDeleteAll(externalEventQueue);
}
-QStateMachinePrivate *QStateMachinePrivate::get(QStateMachine *q)
-{
- if (q)
- return q->d_func();
- return 0;
-}
-
QState *QStateMachinePrivate::rootState() const
{
return const_cast<QStateMachine*>(q_func());
@@ -684,7 +675,7 @@ void QStateMachinePrivate::microstep(QEvent *event, const QList<QAbstractTransit
qDebug() << q_func() << ": computed entry set:" << enteredStates;
#endif
- QHash<QAbstractState*, QList<QPropertyAssignment> > assignmentsForEnteredStates =
+ QHash<QAbstractState*, QVector<QPropertyAssignment> > assignmentsForEnteredStates =
computePropertyAssignments(enteredStates, pendingRestorables);
if (!pendingRestorables.isEmpty()) {
// Add "implicit" assignments for restored properties to the first
@@ -795,7 +786,7 @@ QSet<QAbstractState*> QStateMachinePrivate::computeExitSet_Unordered(QAbstractTr
}
void QStateMachinePrivate::exitStates(QEvent *event, const QList<QAbstractState*> &statesToExit_sorted,
- const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates)
+ const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates)
{
for (int i = 0; i < statesToExit_sorted.size(); ++i) {
QAbstractState *s = statesToExit_sorted.at(i);
@@ -943,7 +934,7 @@ QAbstractState *QStateMachinePrivate::getTransitionDomain(QAbstractTransition *t
void QStateMachinePrivate::enterStates(QEvent *event, const QList<QAbstractState*> &exitedStates_sorted,
const QList<QAbstractState*> &statesToEnter_sorted,
const QSet<QAbstractState*> &statesForDefaultEntry,
- QHash<QAbstractState*, QList<QPropertyAssignment> > &propertyAssignmentsForState
+ QHash<QAbstractState*, QVector<QPropertyAssignment> > &propertyAssignmentsForState
#ifndef QT_NO_ANIMATION
, const QList<QAbstractAnimation *> &selectedAnimations
#endif
@@ -966,7 +957,7 @@ void QStateMachinePrivate::enterStates(QEvent *event, const QList<QAbstractState
// Immediately set the properties that are not animated.
{
- QList<QPropertyAssignment> assignments = propertyAssignmentsForState.value(s);
+ QVector<QPropertyAssignment> assignments = propertyAssignmentsForState.value(s);
for (int i = 0; i < assignments.size(); ++i) {
const QPropertyAssignment &assn = assignments.at(i);
if (globalRestorePolicy == QState::RestoreProperties) {
@@ -989,9 +980,16 @@ void QStateMachinePrivate::enterStates(QEvent *event, const QList<QAbstractState
QAbstractStatePrivate::get(s)->callOnEntry(event);
QAbstractStatePrivate::get(s)->emitEntered();
- if (statesForDefaultEntry.contains(s)) {
- // ### executeContent(s.initial.transition.children())
- }
+
+ // FIXME:
+ // See the "initial transitions" comment in addDescendantStatesToEnter first, then implement:
+// if (statesForDefaultEntry.contains(s)) {
+// // ### executeContent(s.initial.transition.children())
+// }
+ Q_UNUSED(statesForDefaultEntry);
+
+ if (QHistoryState *h = toHistoryState(s))
+ QAbstractTransitionPrivate::get(h->defaultTransition())->callOnTransition(event);
// Emit propertiesAssigned signal if the state has no animated properties.
{
@@ -1052,69 +1050,6 @@ void QStateMachinePrivate::enterStates(QEvent *event, const QList<QAbstractState
// qDebug() << "configuration:" << configuration.toList();
}
-void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root,
- QSet<QAbstractState*> &statesToEnter,
- QSet<QAbstractState*> &statesForDefaultEntry)
-{
- if (QHistoryState *h = toHistoryState(s)) {
- QList<QAbstractState*> hconf = QHistoryStatePrivate::get(h)->configuration;
- if (!hconf.isEmpty()) {
- for (int k = 0; k < hconf.size(); ++k) {
- QAbstractState *s0 = hconf.at(k);
- addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry);
- }
-#ifdef QSTATEMACHINE_DEBUG
- qDebug() << q_func() << ": restoring"
- << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow")
- << "history from" << s << ':' << hconf;
-#endif
- } else {
- QList<QAbstractState*> hlst;
- if (QHistoryStatePrivate::get(h)->defaultState)
- hlst.append(QHistoryStatePrivate::get(h)->defaultState);
-
- if (hlst.isEmpty()) {
- setError(QStateMachine::NoDefaultStateInHistoryStateError, h);
- } else {
- for (int k = 0; k < hlst.size(); ++k) {
- QAbstractState *s0 = hlst.at(k);
- addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry);
- }
-#ifdef QSTATEMACHINE_DEBUG
- qDebug() << q_func() << ": initial history targets for" << s << ':' << hlst;
-#endif
- }
- }
- } else {
- if (s == rootState()) {
- // Error has already been set by exitStates().
- Q_ASSERT(error != QStateMachine::NoError);
- return;
- }
- statesToEnter.insert(s);
- if (isParallel(s)) {
- QState *grp = toStandardState(s);
- QList<QAbstractState*> lst = QStatePrivate::get(grp)->childStates();
- for (int i = 0; i < lst.size(); ++i) {
- QAbstractState *child = lst.at(i);
- addStatesToEnter(child, grp, statesToEnter, statesForDefaultEntry);
- }
- } else if (isCompound(s)) {
- statesForDefaultEntry.insert(s);
- QState *grp = toStandardState(s);
- QAbstractState *initial = grp->initialState();
- if (initial != 0) {
- Q_ASSERT(initial->machine() == q_func());
- addStatesToEnter(initial, grp, statesToEnter, statesForDefaultEntry);
- } else {
- setError(QStateMachine::NoInitialStateError, grp);
- return;
- }
- }
- addAncestorStatesToEnter(s, root, statesToEnter, statesForDefaultEntry);
- }
-}
-
/* The algorithm as described in http://www.w3.org/TR/2014/WD-scxml-20140529/ has a bug. See
* QTBUG-44963 for details. The algorithm here is as described in
* http://www.w3.org/Voice/2013/scxml-irp/SCXML.htm as of Friday March 13, 2015.
@@ -1165,8 +1100,8 @@ void QStateMachinePrivate::addDescendantStatesToEnter(QAbstractState *state,
#endif
} else {
QList<QAbstractState*> defaultHistoryContent;
- if (QHistoryStatePrivate::get(h)->defaultState)
- defaultHistoryContent.append(QHistoryStatePrivate::get(h)->defaultState);
+ if (QAbstractTransition *t = QHistoryStatePrivate::get(h)->defaultTransition)
+ defaultHistoryContent = t->targetStates();
if (defaultHistoryContent.isEmpty()) {
setError(QStateMachine::NoDefaultStateInHistoryStateError, h);
@@ -1192,8 +1127,10 @@ void QStateMachinePrivate::addDescendantStatesToEnter(QAbstractState *state,
if (QAbstractState *initial = toStandardState(state)->initialState()) {
Q_ASSERT(initial->machine() == q_func());
+ // FIXME:
// Qt does not support initial transitions (which is a problem for parallel states).
// The way it simulates this for other states, is by having a single initial state.
+ // See also the FIXME in enterStates.
statesForDefaultEntry.insert(initial);
addDescendantStatesToEnter(initial, statesToEnter, statesForDefaultEntry);
@@ -1413,9 +1350,9 @@ void QStateMachinePrivate::unregisterRestorables(const QList<QAbstractState *> &
}
}
-QList<QPropertyAssignment> QStateMachinePrivate::restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const
+QVector<QPropertyAssignment> QStateMachinePrivate::restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const
{
- QList<QPropertyAssignment> result;
+ QVector<QPropertyAssignment> result;
QHash<RestorableId, QVariant>::const_iterator it;
for (it = restorables.constBegin(); it != restorables.constEnd(); ++it) {
const RestorableId &id = it.key();
@@ -1470,16 +1407,16 @@ QHash<QStateMachinePrivate::RestorableId, QVariant> QStateMachinePrivate::comput
properties that should not be restored because they are assigned by an
entered state).
*/
-QHash<QAbstractState*, QList<QPropertyAssignment> > QStateMachinePrivate::computePropertyAssignments(
+QHash<QAbstractState*, QVector<QPropertyAssignment> > QStateMachinePrivate::computePropertyAssignments(
const QList<QAbstractState*> &statesToEnter_sorted, QHash<RestorableId, QVariant> &pendingRestorables) const
{
- QHash<QAbstractState*, QList<QPropertyAssignment> > assignmentsForState;
+ QHash<QAbstractState*, QVector<QPropertyAssignment> > assignmentsForState;
for (int i = 0; i < statesToEnter_sorted.size(); ++i) {
QState *s = toStandardState(statesToEnter_sorted.at(i));
if (!s)
continue;
- QList<QPropertyAssignment> &assignments = QStatePrivate::get(s)->propertyAssignments;
+ QVector<QPropertyAssignment> &assignments = QStatePrivate::get(s)->propertyAssignments;
for (int j = 0; j < assignments.size(); ++j) {
const QPropertyAssignment &assn = assignments.at(j);
if (assn.objectDeleted()) {
@@ -1556,8 +1493,11 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta
#ifdef QSTATEMACHINE_DEBUG
qDebug() << q << ": entering error state" << currentErrorState << "from" << currentContext;
#endif
- QState *lca = findLCA(QList<QAbstractState*>() << currentErrorState << currentContext);
- addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry);
+ pendingErrorStates.insert(currentErrorState);
+ addDescendantStatesToEnter(currentErrorState, pendingErrorStates, pendingErrorStatesForDefaultEntry);
+ addAncestorStatesToEnter(currentErrorState, rootState(), pendingErrorStates, pendingErrorStatesForDefaultEntry);
+ foreach (QAbstractState *s, configuration)
+ pendingErrorStates.remove(s);
} else {
qWarning("Unrecoverable error detected in running state machine: %s",
qPrintable(errorString));
@@ -1652,7 +1592,7 @@ QList<QAbstractAnimation *> QStateMachinePrivate::selectAnimations(const QList<Q
}
void QStateMachinePrivate::terminateActiveAnimations(QAbstractState *state,
- const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates)
+ const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates)
{
Q_Q(QStateMachine);
QList<QAbstractAnimation*> animations = animationsForState.take(state);
@@ -1677,9 +1617,9 @@ void QStateMachinePrivate::terminateActiveAnimations(QAbstractState *state,
// If there is no property assignment that sets this property,
// set the property to its target value.
bool found = false;
- QHash<QAbstractState*, QList<QPropertyAssignment> >::const_iterator it;
+ QHash<QAbstractState*, QVector<QPropertyAssignment> >::const_iterator it;
for (it = assignmentsForEnteredStates.constBegin(); it != assignmentsForEnteredStates.constEnd(); ++it) {
- const QList<QPropertyAssignment> &assignments = it.value();
+ const QVector<QPropertyAssignment> &assignments = it.value();
for (int j = 0; j < assignments.size(); ++j) {
if (assignments.at(j).hasTarget(assn.object, assn.propertyName)) {
found = true;
@@ -1697,15 +1637,15 @@ void QStateMachinePrivate::terminateActiveAnimations(QAbstractState *state,
void QStateMachinePrivate::initializeAnimations(QAbstractState *state, const QList<QAbstractAnimation *> &selectedAnimations,
const QList<QAbstractState*> &exitedStates_sorted,
- QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates)
+ QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates)
{
Q_Q(QStateMachine);
if (!assignmentsForEnteredStates.contains(state))
return;
- QList<QPropertyAssignment> &assignments = assignmentsForEnteredStates[state];
+ QVector<QPropertyAssignment> &assignments = assignmentsForEnteredStates[state];
for (int i = 0; i < selectedAnimations.size(); ++i) {
QAbstractAnimation *anim = selectedAnimations.at(i);
- QList<QPropertyAssignment>::iterator it;
+ QVector<QPropertyAssignment>::iterator it;
for (it = assignments.begin(); it != assignments.end(); ) {
QPair<QList<QAbstractAnimation*>, QList<QAbstractAnimation*> > ret;
const QPropertyAssignment &assn = *it;
@@ -1864,7 +1804,7 @@ void QStateMachinePrivate::_q_start()
QSet<QAbstractState*> statesForDefaultEntry;
QList<QAbstractState*> enteredStates = computeEntrySet(transitions, statesForDefaultEntry, &calculationCache);
QHash<RestorableId, QVariant> pendingRestorables;
- QHash<QAbstractState*, QList<QPropertyAssignment> > assignmentsForEnteredStates =
+ QHash<QAbstractState*, QVector<QPropertyAssignment> > assignmentsForEnteredStates =
computePropertyAssignments(enteredStates, pendingRestorables);
#ifndef QT_NO_ANIMATION
QList<QAbstractAnimation*> selectedAnimations = selectAnimations(transitions);
@@ -2097,23 +2037,6 @@ void QStateMachinePrivate::cancelAllDelayedEvents()
delayedEvents.clear();
}
-void QStateMachinePrivate::emitStateFinished(QState *forState, QFinalState *guiltyState)
-{
- Q_UNUSED(guiltyState);
- Q_ASSERT(guiltyState);
-
-#ifdef QSTATEMACHINE_DEBUG
- Q_Q(QStateMachine);
- qDebug() << q << ": emitting finished signal for" << forState;
-#endif
-
- QStatePrivate::get(forState)->emitFinished();
-}
-
-void QStateMachinePrivate::startupHook()
-{
-}
-
/*
This function is called when the state machine is performing no
microstep because no transition is enabled (i.e. an event is ignored).
@@ -2154,6 +2077,24 @@ void QStateMachinePrivate::endMacrostep(bool didChange)
Q_UNUSED(didChange);
}
+
+void QStateMachinePrivate::emitStateFinished(QState *forState, QFinalState *guiltyState)
+{
+ Q_UNUSED(guiltyState);
+ Q_ASSERT(guiltyState);
+
+#ifdef QSTATEMACHINE_DEBUG
+ Q_Q(QStateMachine);
+ qDebug() << q << ": emitting finished signal for" << forState;
+#endif
+
+ QStatePrivate::get(forState)->emitFinished();
+}
+
+void QStateMachinePrivate::startupHook()
+{
+}
+
namespace _QStateMachine_Internal{
class GoToStateTransition : public QAbstractTransition
@@ -2453,6 +2394,7 @@ void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalInd
QMetaMethod method = meta->method(signalIndex);
int argc = method.parameterCount();
QList<QVariant> vargs;
+ vargs.reserve(argc);
for (int i = 0; i < argc; ++i) {
int type = method.parameterType(i);
vargs.append(QVariant(type, argv[i+1]));
@@ -2636,11 +2578,6 @@ void QStateMachine::removeState(QAbstractState *state)
state->setParent(0);
}
-/*!
- Returns whether this state machine is running.
-
- \sa start(), stop()
-*/
bool QStateMachine::isRunning() const
{
Q_D(const QStateMachine);
@@ -2703,11 +2640,6 @@ void QStateMachine::stop()
}
}
-/*!
- Convenience functions to start/stop this state machine.
-
- \sa start(), stop(), started(), finished(), stopped()
-*/
void QStateMachine::setRunning(bool running)
{
if (running)
@@ -3272,7 +3204,7 @@ QStateMachine::WrappedEvent::~WrappedEvent()
\fn QStateMachine::runningChanged(bool running)
\since 5.4
- This signal is emitted when the running property is changed.
+ This signal is emitted when the running property is changed with \a running as argument.
\sa QStateMachine::running
*/
diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h
index d6c3b7bfa7..5fca034386 100644
--- a/src/corelib/statemachine/qstatemachine.h
+++ b/src/corelib/statemachine/qstatemachine.h
@@ -104,8 +104,8 @@ public:
NoCommonAncestorForTransitionError
};
- explicit QStateMachine(QObject *parent = 0);
- explicit QStateMachine(QState::ChildMode childMode, QObject *parent = 0);
+ explicit QStateMachine(QObject *parent = Q_NULLPTR);
+ explicit QStateMachine(QState::ChildMode childMode, QObject *parent = Q_NULLPTR);
~QStateMachine();
void addState(QAbstractState *state);
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index 426f2732df..4419ebc7f3 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -99,7 +99,8 @@ public:
QStateMachinePrivate();
~QStateMachinePrivate();
- static QStateMachinePrivate *get(QStateMachine *q);
+ static QStateMachinePrivate *get(QStateMachine *q)
+ { return q ? q->d_func() : 0; }
QState *findLCA(const QList<QAbstractState*> &states, bool onlyCompound = false) const;
QState *findLCCA(const QList<QAbstractState*> &states) const;
@@ -133,7 +134,7 @@ public:
virtual void beginMacrostep();
virtual void endMacrostep(bool didChange);
void exitStates(QEvent *event, const QList<QAbstractState *> &statesToExit_sorted,
- const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates);
+ const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates);
QList<QAbstractState*> computeExitSet(const QList<QAbstractTransition*> &enabledTransitions, CalculationCache *cache);
QSet<QAbstractState*> computeExitSet_Unordered(const QList<QAbstractTransition*> &enabledTransitions, CalculationCache *cache);
QSet<QAbstractState*> computeExitSet_Unordered(QAbstractTransition *t, CalculationCache *cache);
@@ -141,7 +142,7 @@ public:
void enterStates(QEvent *event, const QList<QAbstractState*> &exitedStates_sorted,
const QList<QAbstractState*> &statesToEnter_sorted,
const QSet<QAbstractState*> &statesForDefaultEntry,
- QHash<QAbstractState *, QList<QPropertyAssignment> > &propertyAssignmentsForState
+ QHash<QAbstractState *, QVector<QPropertyAssignment> > &propertyAssignmentsForState
#ifndef QT_NO_ANIMATION
, const QList<QAbstractAnimation*> &selectedAnimations
#endif
@@ -154,9 +155,6 @@ public:
void addDescendantStatesToEnter(QAbstractState *state,
QSet<QAbstractState*> &statesToEnter,
QSet<QAbstractState*> &statesForDefaultEntry);
- void addStatesToEnter(QAbstractState *s, QState *root,
- QSet<QAbstractState*> &statesToEnter,
- QSet<QAbstractState*> &statesForDefaultEntry);
void addAncestorStatesToEnter(QAbstractState *s, QAbstractState *ancestor,
QSet<QAbstractState*> &statesToEnter,
QSet<QAbstractState*> &statesForDefaultEntry);
@@ -232,9 +230,9 @@ public:
const QVariant &value);
void unregisterRestorables(const QList<QAbstractState*> &states, QObject *object,
const QByteArray &propertyName);
- QList<QPropertyAssignment> restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const;
+ QVector<QPropertyAssignment> restorablesToPropertyList(const QHash<RestorableId, QVariant> &restorables) const;
QHash<RestorableId, QVariant> computePendingRestorables(const QList<QAbstractState*> &statesToExit_sorted) const;
- QHash<QAbstractState*, QList<QPropertyAssignment> > computePropertyAssignments(
+ QHash<QAbstractState*, QVector<QPropertyAssignment> > computePropertyAssignments(
const QList<QAbstractState*> &statesToEnter_sorted,
QHash<RestorableId, QVariant> &pendingRestorables) const;
#endif
@@ -275,10 +273,10 @@ public:
QList<QAbstractAnimation *> selectAnimations(const QList<QAbstractTransition *> &transitionList) const;
void terminateActiveAnimations(QAbstractState *state,
- const QHash<QAbstractState*, QList<QPropertyAssignment> > &assignmentsForEnteredStates);
+ const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates);
void initializeAnimations(QAbstractState *state, const QList<QAbstractAnimation*> &selectedAnimations,
const QList<QAbstractState *> &exitedStates_sorted,
- QHash<QAbstractState *, QList<QPropertyAssignment> > &assignmentsForEnteredStates);
+ QHash<QAbstractState *, QVector<QPropertyAssignment> > &assignmentsForEnteredStates);
#endif // QT_NO_ANIMATION
QSignalEventGenerator *signalEventGenerator;
diff --git a/src/corelib/thread/qexception.cpp b/src/corelib/thread/qexception.cpp
index acc3663936..04a03b8623 100644
--- a/src/corelib/thread/qexception.cpp
+++ b/src/corelib/thread/qexception.cpp
@@ -107,6 +107,16 @@ QT_BEGIN_NAMESPACE
\internal
*/
+QException::~QException()
+#ifdef Q_COMPILER_NOEXCEPT
+ noexcept
+#else
+ throw()
+#endif
+{
+ // must stay empty until ### Qt 6
+}
+
void QException::raise() const
{
QException e = *this;
@@ -118,6 +128,16 @@ QException *QException::clone() const
return new QException(*this);
}
+QUnhandledException::~QUnhandledException()
+#ifdef Q_COMPILER_NOEXCEPT
+ noexcept
+#else
+ throw()
+#endif
+{
+ // must stay empty until ### Qt 6
+}
+
void QUnhandledException::raise() const
{
QUnhandledException e = *this;
diff --git a/src/corelib/thread/qexception.h b/src/corelib/thread/qexception.h
index 55fc441020..b15ae5095a 100644
--- a/src/corelib/thread/qexception.h
+++ b/src/corelib/thread/qexception.h
@@ -53,6 +53,13 @@ QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT QException : public std::exception
{
public:
+ ~QException()
+#ifdef Q_COMPILER_NOEXCEPT
+ noexcept
+#else
+ throw()
+#endif
+ ;
virtual void raise() const;
virtual QException *clone() const;
};
@@ -60,6 +67,13 @@ public:
class Q_CORE_EXPORT QUnhandledException : public QException
{
public:
+ ~QUnhandledException()
+#ifdef Q_COMPILER_NOEXCEPT
+ noexcept
+#else
+ throw()
+#endif
+ ;
void raise() const Q_DECL_OVERRIDE;
QUnhandledException *clone() const Q_DECL_OVERRIDE;
};
@@ -70,7 +84,7 @@ class Base;
class Q_CORE_EXPORT ExceptionHolder
{
public:
- ExceptionHolder(QException *exception = 0);
+ ExceptionHolder(QException *exception = Q_NULLPTR);
ExceptionHolder(const ExceptionHolder &other);
void operator=(const ExceptionHolder &other);
~ExceptionHolder();
diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc
index be4cee2bd6..ed0b26e121 100644
--- a/src/corelib/thread/qfuture.qdoc
+++ b/src/corelib/thread/qfuture.qdoc
@@ -352,6 +352,7 @@
/*! \class QFuture::const_iterator
\reentrant
\since 4.4
+ \inmodule QtCore
\brief The QFuture::const_iterator class provides an STL-style const
iterator for QFuture.
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index 01eb043a5e..8c1f7e7d82 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -299,7 +299,7 @@ public:
void reportResult(const void *, int) { }
void reportResults(const QVector<void> &, int) { }
- void reportFinished(const void * = 0) { QFutureInterfaceBase::reportFinished(); }
+ void reportFinished(const void * = Q_NULLPTR) { QFutureInterfaceBase::reportFinished(); }
};
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qfuturewatcher.h b/src/corelib/thread/qfuturewatcher.h
index 63558d4a0f..42a22d9063 100644
--- a/src/corelib/thread/qfuturewatcher.h
+++ b/src/corelib/thread/qfuturewatcher.h
@@ -52,7 +52,7 @@ class Q_CORE_EXPORT QFutureWatcherBase : public QObject
Q_DECLARE_PRIVATE(QFutureWatcherBase)
public:
- explicit QFutureWatcherBase(QObject *parent = 0);
+ explicit QFutureWatcherBase(QObject *parent = Q_NULLPTR);
// de-inline dtor
int progressValue() const;
@@ -179,7 +179,7 @@ template <>
class QFutureWatcher<void> : public QFutureWatcherBase
{
public:
- explicit QFutureWatcher(QObject *_parent = 0)
+ explicit QFutureWatcher(QObject *_parent = Q_NULLPTR)
: QFutureWatcherBase(_parent)
{ }
~QFutureWatcher()
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index a9a790c14c..d3e7d51efd 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -46,13 +46,6 @@ QT_END_NAMESPACE
#pragma qt_sync_stop_processing
#endif
-#ifdef Q_CC_GNU
-// lowercase is fine, we'll undef it below
-#define always_inline __attribute__((always_inline, gnu_inline))
-#else
-#define always_inline
-#endif
-
template<int> struct QAtomicOpsSupport { enum { IsSupported = 0 }; };
template<> struct QAtomicOpsSupport<4> { enum { IsSupported = 1 }; };
@@ -84,19 +77,19 @@ template <typename BaseClass> struct QGenericAtomicOps
{
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T load(const T &_q_value) Q_DECL_NOTHROW
{
return _q_value;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
void store(T &_q_value, X newValue) Q_DECL_NOTHROW
{
_q_value = newValue;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T loadAcquire(const T &_q_value) Q_DECL_NOTHROW
{
T tmp = *static_cast<const volatile T *>(&_q_value);
@@ -104,7 +97,7 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
void storeRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
@@ -115,13 +108,13 @@ template <typename BaseClass> struct QGenericAtomicOps
{ return BaseClass::isFetchAndAddNative(); }
static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW
{ return BaseClass::isFetchAndAddWaitFree(); }
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
bool ref(T &_q_value) Q_DECL_NOTHROW
{
return BaseClass::fetchAndAddRelaxed(_q_value, 1) != T(-1);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
bool deref(T &_q_value) Q_DECL_NOTHROW
{
return BaseClass::fetchAndAddRelaxed(_q_value, -1) != 1;
@@ -138,7 +131,7 @@ template <typename BaseClass> struct QGenericAtomicOps
bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW;
#endif
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
{
bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
@@ -146,21 +139,21 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetRelease(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
{
bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
@@ -168,14 +161,14 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetRelease(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
@@ -185,7 +178,7 @@ template <typename BaseClass> struct QGenericAtomicOps
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; }
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
T fetchAndStoreRelaxed(T &_q_value, X newValue) Q_DECL_NOTHROW
{
// implement fetchAndStore on top of testAndSet
@@ -196,7 +189,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
T fetchAndStoreAcquire(T &_q_value, X newValue) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
@@ -204,14 +197,14 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
T fetchAndStoreRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
}
- template <typename T, typename X> static inline always_inline
+ template <typename T, typename X> static Q_ALWAYS_INLINE
T fetchAndStoreOrdered(T &_q_value, X newValue) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
@@ -220,7 +213,7 @@ template <typename BaseClass> struct QGenericAtomicOps
static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return false; }
static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; }
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
{
// implement fetchAndAdd on top of testAndSet
@@ -231,7 +224,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
@@ -239,28 +232,28 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
// implement fetchAndSub on top of fetchAndAdd
return fetchAndAddRelaxed(_q_value, -operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndSubRelaxed(_q_value, operand);
@@ -268,21 +261,21 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndSubRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndSubOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndSubRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAndRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
// implement fetchAndAnd on top of testAndSet
@@ -293,7 +286,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAndAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndAndRelaxed(_q_value, operand);
@@ -301,21 +294,21 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAndRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndAndRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndAndOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndAndRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndOrRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
// implement fetchAndOr on top of testAndSet
@@ -326,7 +319,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndOrAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndOrRelaxed(_q_value, operand);
@@ -334,21 +327,21 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndOrRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndOrRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndOrOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndOrRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndXorRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
// implement fetchAndXor on top of testAndSet
@@ -359,7 +352,7 @@ template <typename BaseClass> struct QGenericAtomicOps
}
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndXorAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
T tmp = BaseClass::fetchAndXorRelaxed(_q_value, operand);
@@ -367,14 +360,14 @@ template <typename BaseClass> struct QGenericAtomicOps
return tmp;
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndXorRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndXorRelaxed(_q_value, operand);
}
- template <typename T> static inline always_inline
+ template <typename T> static Q_ALWAYS_INLINE
T fetchAndXorOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
{
BaseClass::orderedMemoryFence(_q_value);
@@ -382,7 +375,5 @@ template <typename BaseClass> struct QGenericAtomicOps
}
};
-#undef always_inline
-
QT_END_NAMESPACE
#endif // QGENERICATOMIC_H
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 63c488747f..0c5a73b4df 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -73,16 +73,16 @@ public:
private:
inline bool fastTryLock() Q_DECL_NOTHROW {
- return d_ptr.testAndSetAcquire(0, dummyLocked());
+ return d_ptr.testAndSetAcquire(Q_NULLPTR, dummyLocked());
}
inline bool fastTryUnlock() Q_DECL_NOTHROW {
- return d_ptr.testAndSetRelease(dummyLocked(), 0);
+ return d_ptr.testAndSetRelease(dummyLocked(), Q_NULLPTR);
}
inline bool fastTryLock(QMutexData *&current) Q_DECL_NOTHROW {
- return d_ptr.testAndSetAcquire(0, dummyLocked(), current);
+ return d_ptr.testAndSetAcquire(Q_NULLPTR, dummyLocked(), current);
}
inline bool fastTryUnlock(QMutexData *&current) Q_DECL_NOTHROW {
- return d_ptr.testAndSetRelease(dummyLocked(), 0, current);
+ return d_ptr.testAndSetRelease(dummyLocked(), Q_NULLPTR, current);
}
void lockInternal() QT_MUTEX_LOCK_NOEXCEPT;
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index c4130fdba5..c24ea58868 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -55,10 +55,10 @@ QMutexPrivate::~QMutexPrivate()
bool QMutexPrivate::wait(int timeout)
{
-#ifndef Q_OS_WINRT
- return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0);
-#else
+#ifndef Q_OS_WINCE
return (WaitForSingleObjectEx(event, timeout < 0 ? INFINITE : timeout, FALSE) == WAIT_OBJECT_0);
+#else
+ return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0);
#endif
}
diff --git a/src/corelib/thread/qresultstore.h b/src/corelib/thread/qresultstore.h
index fbcb8ad3cd..7ecaa231b2 100644
--- a/src/corelib/thread/qresultstore.h
+++ b/src/corelib/thread/qresultstore.h
@@ -61,8 +61,8 @@ class ResultItem
public:
ResultItem(const void *_result, int _count) : m_count(_count), result(_result) { } // contruct with vector of results
ResultItem(const void *_result) : m_count(0), result(_result) { } // construct with result
- ResultItem() : m_count(0), result(0) { }
- bool isValid() const { return result != 0; }
+ ResultItem() : m_count(0), result(Q_NULLPTR) { }
+ bool isValid() const { return result != Q_NULLPTR; }
bool isVector() const { return m_count != 0; }
int count() const { return (m_count == 0) ? 1 : m_count; }
int m_count; // result is either a pointer to a result or to a vector of results,
diff --git a/src/corelib/thread/qrunnable.cpp b/src/corelib/thread/qrunnable.cpp
index 64a2613d27..04aa39a81e 100644
--- a/src/corelib/thread/qrunnable.cpp
+++ b/src/corelib/thread/qrunnable.cpp
@@ -31,6 +31,15 @@
**
****************************************************************************/
+#include "qrunnable.h"
+
+QT_BEGIN_NAMESPACE
+
+QRunnable::~QRunnable()
+{
+ // Must be empty until ### Qt 6
+}
+
/*!
\class QRunnable
\inmodule QtCore
@@ -98,3 +107,5 @@
\sa autoDelete(), QThreadPool
*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/thread/qrunnable.h b/src/corelib/thread/qrunnable.h
index f00c58d51d..28d14a46c0 100644
--- a/src/corelib/thread/qrunnable.h
+++ b/src/corelib/thread/qrunnable.h
@@ -38,20 +38,21 @@
QT_BEGIN_NAMESPACE
-
-class QRunnable
+class Q_CORE_EXPORT QRunnable
{
int ref;
friend class QThreadPool;
friend class QThreadPoolPrivate;
friend class QThreadPoolThread;
-
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ Q_DISABLE_COPY(QRunnable)
+#endif
public:
virtual void run() = 0;
QRunnable() : ref(0) { }
- virtual ~QRunnable() { }
+ virtual ~QRunnable();
bool autoDelete() const { return ref != -1; }
void setAutoDelete(bool _autoDelete) { ref = _autoDelete ? 0 : -1; }
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index dc231a00f8..590479d68c 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -38,7 +38,6 @@
#include "qabstracteventdispatcher.h"
#include <qeventloop.h>
-#include <qhash.h>
#include "qthread_p.h"
#include "private/qcoreapplication_p.h"
@@ -51,7 +50,8 @@ QT_BEGIN_NAMESPACE
QThreadData::QThreadData(int initialRefCount)
: _ref(initialRefCount), loopLevel(0), thread(0), threadId(0),
- eventDispatcher(0), quitNow(false), canWait(true), isAdopted(false)
+ eventDispatcher(0),
+ quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true)
{
// fprintf(stderr, "QThreadData %p created\n", this);
}
@@ -868,4 +868,28 @@ bool QThread::isInterruptionRequested() const
return d->interruptionRequested;
}
+/*!
+ \class QDaemonThread
+ \since 5.5
+ \brief The QDaemonThread provides a class to manage threads that outlive QCoreApplication
+ \internal
+
+ Note: don't try to deliver events from the started() signal.
+*/
+static void setThreadDoesNotRequireCoreApplication()
+{
+ QThreadData::current()->requiresCoreApplication = false;
+}
+
+QDaemonThread::QDaemonThread(QObject *parent)
+ : QThread(parent)
+{
+ // QThread::started() is emitted from the thread we start
+ connect(this, &QThread::started, setThreadDoesNotRequireCoreApplication);
+}
+
+QDaemonThread::~QDaemonThread()
+{
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index bfc469583d..d333980bf4 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -55,7 +55,7 @@ public:
static int idealThreadCount() Q_DECL_NOTHROW;
static void yieldCurrentThread();
- explicit QThread(QObject *parent = 0);
+ explicit QThread(QObject *parent = Q_NULLPTR);
~QThread();
enum Priority {
@@ -116,7 +116,7 @@ protected:
static void setTerminationEnabled(bool enabled = true);
protected:
- QThread(QThreadPrivate &dd, QObject *parent = 0);
+ QThread(QThreadPrivate &dd, QObject *parent = Q_NULLPTR);
private:
Q_DECLARE_PRIVATE(QThread)
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 1ecd682ad1..ffefe0b1d1 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -135,6 +135,13 @@ private:
#ifndef QT_NO_THREAD
+class Q_CORE_EXPORT QDaemonThread : public QThread
+{
+public:
+ QDaemonThread(QObject *parent = 0);
+ ~QDaemonThread();
+};
+
class QThreadPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QThread)
@@ -224,7 +231,7 @@ public:
QThreadData(int initialRefCount = 1);
~QThreadData();
- static QThreadData *current(bool createIfNecessary = true);
+ static Q_AUTOTEST_EXPORT QThreadData *current(bool createIfNecessary = true);
static void clearCurrentThreadData();
static QThreadData *get2(QThread *thread)
{ Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; }
@@ -278,6 +285,7 @@ public:
bool quitNow;
bool canWait;
bool isAdopted;
+ bool requiresCoreApplication;
};
class QScopedLoopLevelCounter
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 77093c9cf1..f054a727cf 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -313,14 +313,15 @@ void *QThreadPrivate::start(void *arg)
createEventDispatcher(data);
#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
- // sets the name of the current thread.
- QString objectName = thr->objectName();
-
- if (Q_LIKELY(objectName.isEmpty()))
- setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className());
- else
- setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit());
+ {
+ // sets the name of the current thread.
+ QString objectName = thr->objectName();
+ if (Q_LIKELY(objectName.isEmpty()))
+ setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className());
+ else
+ setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit());
+ }
#endif
emit thr->started(QThread::QPrivateSignal());
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index c16a2e958c..57eeb10b7d 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -118,7 +118,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
}
threadData->deref();
threadData->isAdopted = true;
- threadData->threadId = reinterpret_cast<Qt::HANDLE>(GetCurrentThreadId());
+ threadData->threadId = reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()));
if (!QCoreApplicationPrivate::theMainThread) {
QCoreApplicationPrivate::theMainThread = threadData->thread;
@@ -340,7 +340,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
qt_create_tls();
TlsSetValue(qt_current_thread_data_tls_index, data);
- data->threadId = reinterpret_cast<Qt::HANDLE>(GetCurrentThreadId());
+ data->threadId = reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()));
QThread::setTerminationEnabled(false);
@@ -413,7 +413,7 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway)
Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
{
- return reinterpret_cast<Qt::HANDLE>(GetCurrentThreadId());
+ return reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()));
}
int QThread::idealThreadCount() Q_DECL_NOTHROW
diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h
index b1ca808a99..95b41a0417 100644
--- a/src/corelib/thread/qthreadpool.h
+++ b/src/corelib/thread/qthreadpool.h
@@ -55,7 +55,7 @@ class Q_CORE_EXPORT QThreadPool : public QObject
friend class QFutureInterfaceBase;
public:
- QThreadPool(QObject *parent = 0);
+ QThreadPool(QObject *parent = Q_NULLPTR);
~QThreadPool();
static QThreadPool *globalInstance();
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index fd6af7db39..89bf523263 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -77,7 +77,7 @@ void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where)
#if defined(Q_OS_ANDROID)
if (local_condattr_setclock && QElapsedTimer::clockType() == QElapsedTimer::MonotonicClock)
local_condattr_setclock(&condattr, CLOCK_MONOTONIC);
-#elif !defined(Q_OS_MAC) && !defined(Q_OS_HAIKU)
+#elif !defined(Q_OS_MAC)
if (QElapsedTimer::clockType() == QElapsedTimer::MonotonicClock)
pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
#endif
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index ef8330570e..3ea34461d3 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -109,10 +109,10 @@ bool QWaitConditionPrivate::wait(QWaitConditionEvent *wce, unsigned long time)
{
// wait for the event
bool ret = false;
-#ifndef Q_OS_WINRT
- switch (WaitForSingleObject(wce->event, time)) {
-#else
+#ifndef Q_OS_WINCE
switch (WaitForSingleObjectEx(wce->event, time, FALSE)) {
+#else
+ switch (WaitForSingleObject(wce->event, time)) {
#endif
default: break;
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index ff4d5a3ebd..ffa3082d5e 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -584,6 +584,131 @@ Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(long unsigne
#undef QALGORITHMS_USE_BUILTIN_POPCOUNT
#endif
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint32 v) Q_DECL_NOTHROW
+{
+#if defined(Q_CC_GNU)
+ return v ? __builtin_ctz(v) : 32U;
+#else
+ // see http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightParallel
+ unsigned int c = 32; // c will be the number of zero bits on the right
+ v &= -signed(v);
+ if (v) c--;
+ if (v & 0x0000FFFF) c -= 16;
+ if (v & 0x00FF00FF) c -= 8;
+ if (v & 0x0F0F0F0F) c -= 4;
+ if (v & 0x33333333) c -= 2;
+ if (v & 0x55555555) c -= 1;
+ return c;
+#endif
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint8 v) Q_DECL_NOTHROW
+{
+#if defined(Q_CC_GNU)
+ return v ? __builtin_ctz(v) : 8U;
+#else
+ unsigned int c = 8; // c will be the number of zero bits on the right
+ v &= -signed(v);
+ if (v) c--;
+ if (v & 0x0000000F) c -= 4;
+ if (v & 0x00000033) c -= 2;
+ if (v & 0x00000055) c -= 1;
+ return c;
+#endif
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint16 v) Q_DECL_NOTHROW
+{
+#if defined(Q_CC_GNU)
+ return v ? __builtin_ctz(v) : 16U;
+#else
+ unsigned int c = 16; // c will be the number of zero bits on the right
+ v &= -signed(v);
+ if (v) c--;
+ if (v & 0x000000FF) c -= 8;
+ if (v & 0x00000F0F) c -= 4;
+ if (v & 0x00003333) c -= 2;
+ if (v & 0x00005555) c -= 1;
+ return c;
+#endif
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint64 v) Q_DECL_NOTHROW
+{
+#if defined(Q_CC_GNU)
+ return v ? __builtin_ctzll(v) : 64;
+#else
+ quint32 x = static_cast<quint32>(v);
+ return x ? qCountTrailingZeroBits(x)
+ : 32 + qCountTrailingZeroBits(static_cast<quint32>(v >> 32));
+#endif
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(unsigned long v) Q_DECL_NOTHROW
+{
+ return qCountTrailingZeroBits(QIntegerForSizeof<long>::Unsigned(v));
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint32 v) Q_DECL_NOTHROW
+{
+#if defined(Q_CC_GNU)
+ return v ? __builtin_clz(v) : 32U;
+#else
+ // Hacker's Delight, 2nd ed. Fig 5-16, p. 102
+ v = v | (v >> 1);
+ v = v | (v >> 2);
+ v = v | (v >> 4);
+ v = v | (v >> 8);
+ v = v | (v >> 16);
+ return qPopulationCount(~v);
+#endif
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint8 v) Q_DECL_NOTHROW
+{
+#if defined(Q_CC_GNU)
+ return v ? __builtin_clz(v)-24U : 8U;
+#else
+ v = v | (v >> 1);
+ v = v | (v >> 2);
+ v = v | (v >> 4);
+ return qPopulationCount(static_cast<quint8>(~v));
+#endif
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint16 v) Q_DECL_NOTHROW
+{
+#if defined(Q_CC_GNU)
+ return v ? __builtin_clz(v)-16U : 16U;
+#else
+ v = v | (v >> 1);
+ v = v | (v >> 2);
+ v = v | (v >> 4);
+ v = v | (v >> 8);
+ return qPopulationCount(static_cast<quint16>(~v));
+#endif
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint64 v) Q_DECL_NOTHROW
+{
+#if defined(Q_CC_GNU)
+ return v ? __builtin_clzll(v) : 64U;
+#else
+ v = v | (v >> 1);
+ v = v | (v >> 2);
+ v = v | (v >> 4);
+ v = v | (v >> 8);
+ v = v | (v >> 16);
+ v = v | (v >> 32);
+ return qPopulationCount(~v);
+#endif
+}
+
+Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(unsigned long v) Q_DECL_NOTHROW
+{
+ return qCountLeadingZeroBits(QIntegerForSizeof<long>::Unsigned(v));
+}
+
QT_WARNING_POP
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index 193042e017..dac353fa70 100644..100755
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -785,3 +785,73 @@
\since 5.2
\overload
*/
+
+/*!
+ \fn uint qCountTrailingZeroBits(quint8 v)
+ \relates <QtAlgorithms>
+ \since 5.6
+
+ Returns the number of consecutive zero bits in \a v, when searching from the LSB.
+ For example, qCountTrailingZeroBits(1) returns 0 and qCountTrailingZeroBits(8) returns 3.
+ */
+
+/*!
+ \fn uint qCountTrailingZeroBits(quint16 v)
+ \relates <QtAlgorithms>
+ \since 5.6
+ \overload
+ */
+
+/*!
+ \fn uint qCountTrailingZeroBits(quint32 v)
+ \relates <QtAlgorithms>
+ \since 5.6
+ \overload
+ */
+
+/*!
+ \fn uint qCountTrailingZeroBits(quint64 v)
+ \relates <QtAlgorithms>
+ \since 5.6
+ \overload
+ */
+
+/*!
+ \fn uint qCountLeadingZeroBits(quint8 v)
+ \relates <QtAlgorithms>
+ \since 5.6
+
+ Returns the number of consecutive zero bits in \a v, when searching from the MSB.
+ For example, qCountLeadingZeroBits(quint8(1)) returns 7 and
+ qCountLeadingZeroBits(quint8(8)) returns 4.
+ */
+
+/*!
+ \fn uint qCountLeadingZeroBits(quint16 v)
+ \relates <QtAlgorithms>
+ \since 5.6
+
+ Returns the number of consecutive zero bits in \a v, when searching from the MSB.
+ For example, qCountLeadingZeroBits(quint16(1)) returns 15 and
+ qCountLeadingZeroBits(quint16(8)) returns 12.
+ */
+
+/*!
+ \fn uint qCountLeadingZeroBits(quint32 v)
+ \relates <QtAlgorithms>
+ \since 5.6
+
+ Returns the number of consecutive zero bits in \a v, when searching from the MSB.
+ For example, qCountLeadingZeroBits(quint32(1)) returns 31 and
+ qCountLeadingZeroBits(quint32(8)) returns 28.
+ */
+
+/*!
+ \fn uint qCountLeadingZeroBits(quint64 v)
+ \relates <QtAlgorithms>
+ \since 5.6
+
+ Returns the number of consecutive zero bits in \a v, when searching from the MSB.
+ For example, qCountLeadingZeroBits(quint64(1)) returns 63 and
+ qCountLeadingZeroBits(quint64(8)) returns 60.
+ */
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index ef15fae83a..d9519745b0 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -103,7 +103,11 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
quintptr data = (quintptr(header) + sizeof(QArrayData) + alignment - 1)
& ~(alignment - 1);
+#if QT_SUPPORTS(UNSHARABLE_CONTAINERS)
header->ref.atomic.store(bool(!(options & Unsharable)));
+#else
+ header->ref.atomic.store(1);
+#endif
header->size = 0;
header->alloc = capacity;
header->capacityReserved = bool(options & CapacityReserved);
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index df35a1cb62..865bd4325d 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -132,7 +132,7 @@ struct QTypedArrayData
typedef T *pointer;
typedef T &reference;
- inline iterator() : i(0) {}
+ inline iterator() : i(Q_NULLPTR) {}
inline iterator(T *n) : i(n) {}
inline iterator(const iterator &o): i(o.i){} // #### Qt 6: remove, the implicit version is fine
inline T &operator*() const { return *i; }
@@ -166,7 +166,7 @@ struct QTypedArrayData
typedef const T *pointer;
typedef const T &reference;
- inline const_iterator() : i(0) {}
+ inline const_iterator() : i(Q_NULLPTR) {}
inline const_iterator(const T *n) : i(n) {}
inline const_iterator(const const_iterator &o): i(o.i) {} // #### Qt 6: remove, the default version is fine
inline explicit const_iterator(const iterator &o): i(o.i) {}
@@ -249,11 +249,13 @@ struct QTypedArrayData
return allocate(/* capacity */ 0);
}
+#if QT_SUPPORTS(UNSHARABLE_CONTAINERS)
static QTypedArrayData *unsharableEmpty()
{
Q_STATIC_ASSERT(sizeof(QTypedArrayData) == sizeof(QArrayData));
return allocate(/* capacity */ 0, Unsharable);
}
+#endif
};
template <class T, size_t N>
diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h
index 103eb073a9..9804d2c2d5 100644
--- a/src/corelib/tools/qarraydatapointer.h
+++ b/src/corelib/tools/qarraydatapointer.h
@@ -46,7 +46,7 @@ private:
typedef QArrayDataOps<T> DataOps;
public:
- QArrayDataPointer()
+ QArrayDataPointer() Q_DECL_NOTHROW
: d(Data::sharedNull())
{
}
@@ -77,15 +77,16 @@ public:
}
#ifdef Q_COMPILER_RVALUE_REFS
- QArrayDataPointer(QArrayDataPointer &&other)
+ QArrayDataPointer(QArrayDataPointer &&other) Q_DECL_NOTHROW
: d(other.d)
{
other.d = Data::sharedNull();
}
- QArrayDataPointer &operator=(QArrayDataPointer &&other)
+ QArrayDataPointer &operator=(QArrayDataPointer &&other) Q_DECL_NOTHROW
{
- this->swap(other);
+ QArrayDataPointer moved(std::move(other));
+ this->swap(moved);
return *this;
}
#endif
@@ -143,7 +144,7 @@ public:
bool isSharable() const { return d->isSharable(); }
#endif
- void swap(QArrayDataPointer &other)
+ void swap(QArrayDataPointer &other) Q_DECL_NOTHROW
{
qSwap(d, other.d);
}
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 9d6c9d4ed1..5ed72fc341 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -41,6 +41,7 @@
#include "qlocale_p.h"
#include "qstringalgorithms_p.h"
#include "qscopedpointer.h"
+#include "qbytearray_p.h"
#include <qdatastream.h>
#include <qmath.h>
@@ -123,7 +124,7 @@ int qFindByteArray(
int qAllocMore(int alloc, int extra) Q_DECL_NOTHROW
{
- Q_ASSERT(alloc >= 0 && extra >= 0);
+ Q_ASSERT(alloc >= 0 && extra >= 0 && extra <= MaxAllocSize);
Q_ASSERT_X(alloc <= MaxAllocSize - extra, "qAllocMore", "Requested size is too large!");
unsigned nalloc = qNextPowerOfTwo(alloc + extra);
@@ -488,8 +489,8 @@ quint16 qChecksum(const char *data, uint len)
\overload
- Compresses the first \a nbytes of \a data and returns the
- compressed data in a new byte array.
+ Compresses the first \a nbytes of \a data at compression level
+ \a compressionLevel and returns the compressed data in a new byte array.
*/
#ifndef QT_NO_COMPRESS
@@ -838,15 +839,6 @@ static inline char qToLower(char c)
*/
/*!
- \variable QByteArray::MaxSize
- \internal
- \since 5.4
-
- The maximum size of a QByteArray, in bytes. Also applies to a the maximum
- storage size of QString and QVector, though not the number of elements.
-*/
-
-/*!
\enum QByteArray::Base64Option
\since 5.2
@@ -927,6 +919,52 @@ static inline char qToLower(char c)
\sa constBegin(), end()
*/
+/*! \fn QByteArray::reverse_iterator QByteArray::rbegin()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ character in the byte-array, in reverse order.
+
+ \sa begin(), crbegin(), rend()
+*/
+
+/*! \fn QByteArray::const_reverse_iterator QByteArray::rbegin() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QByteArray::const_reverse_iterator QByteArray::crbegin() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ character in the byte-array, in reverse order.
+
+ \sa begin(), rbegin(), rend()
+*/
+
+/*! \fn QByteArray::reverse_iterator QByteArray::rend()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past
+ the last character in the byte-array, in reverse order.
+
+ \sa end(), crend(), rbegin()
+*/
+
+/*! \fn QByteArray::const_reverse_iterator QByteArray::rend() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QByteArray::const_reverse_iterator QByteArray::crend() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one
+ past the last character in the byte-array, in reverse order.
+
+ \sa end(), rend(), rbegin()
+*/
+
/*! \fn void QByteArray::push_back(const QByteArray &other)
This function is provided for STL compatibility. It is equivalent
@@ -1574,7 +1612,7 @@ void QByteArray::reallocData(uint alloc, Data::AllocationOptions options)
d = x;
} else {
if (options & Data::Grow) {
- if (alloc > uint(MaxAllocSize) - uint(sizeof(Data)))
+ if (alloc > MaxByteArraySize)
qBadAlloc();
alloc = qAllocMore(alloc, sizeof(Data));
}
@@ -4489,11 +4527,33 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA
*/
/*! \typedef QByteArray::const_iterator
- \internal
+
+ This typedef provides an STL-style const iterator for QByteArray.
+
+ \sa QByteArray::const_reverse_iterator, QByteArray::iterator
*/
/*! \typedef QByteArray::iterator
- \internal
+
+ This typedef provides an STL-style non-const iterator for QByteArray.
+
+ \sa QByteArray::reverse_iterator, QByteArray::const_iterator
+*/
+
+/*! \typedef QByteArray::const_reverse_iterator
+ \since 5.6
+
+ This typedef provides an STL-style const reverse iterator for QByteArray.
+
+ \sa QByteArray::reverse_iterator, QByteArray::const_iterator
+*/
+
+/*! \typedef QByteArray::reverse_iterator
+ \since 5.6
+
+ This typedef provides an STL-style non-const reverse iterator for QByteArray.
+
+ \sa QByteArray::const_reverse_iterator, QByteArray::iterator
*/
/*! \typedef QByteArray::size_type
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index 6d14cd5131..f0032227e8 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -43,6 +43,7 @@
#include <stdarg.h>
#include <string>
+#include <iterator>
#ifdef truncate
#error qbytearray.h must be included before any header file that defines truncate
@@ -162,9 +163,6 @@ private:
typedef QTypedArrayData<char> Data;
public:
- // undocumented:
- static const quint64 MaxSize = (1 << 30) - sizeof(Data);
-
enum Base64Option {
Base64Encoding = 0,
Base64UrlEncoding = 1,
@@ -338,16 +336,16 @@ public:
inline QT_ASCII_CAST_WARN bool operator>=(const QString &s2) const;
#endif
- short toShort(bool *ok = 0, int base = 10) const;
- ushort toUShort(bool *ok = 0, int base = 10) const;
- int toInt(bool *ok = 0, int base = 10) const;
- uint toUInt(bool *ok = 0, int base = 10) const;
- long toLong(bool *ok = 0, int base = 10) const;
- ulong toULong(bool *ok = 0, int base = 10) const;
- qlonglong toLongLong(bool *ok = 0, int base = 10) const;
- qulonglong toULongLong(bool *ok = 0, int base = 10) const;
- float toFloat(bool *ok = 0) const;
- double toDouble(bool *ok = 0) const;
+ short toShort(bool *ok = Q_NULLPTR, int base = 10) const;
+ ushort toUShort(bool *ok = Q_NULLPTR, int base = 10) const;
+ int toInt(bool *ok = Q_NULLPTR, int base = 10) const;
+ uint toUInt(bool *ok = Q_NULLPTR, int base = 10) const;
+ long toLong(bool *ok = Q_NULLPTR, int base = 10) const;
+ ulong toULong(bool *ok = Q_NULLPTR, int base = 10) const;
+ qlonglong toLongLong(bool *ok = Q_NULLPTR, int base = 10) const;
+ qulonglong toULongLong(bool *ok = Q_NULLPTR, int base = 10) const;
+ float toFloat(bool *ok = Q_NULLPTR) const;
+ double toDouble(bool *ok = Q_NULLPTR) const;
QByteArray toBase64(Base64Options options) const;
QByteArray toBase64() const; // ### Qt6 merge with previous
QByteArray toHex() const;
@@ -393,14 +391,22 @@ public:
typedef const char *const_iterator;
typedef iterator Iterator;
typedef const_iterator ConstIterator;
- iterator begin();
- const_iterator begin() const;
- const_iterator cbegin() const;
- const_iterator constBegin() const;
- iterator end();
- const_iterator end() const;
- const_iterator cend() const;
- const_iterator constEnd() const;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ inline iterator begin();
+ inline const_iterator begin() const;
+ inline const_iterator cbegin() const;
+ inline const_iterator constBegin() const;
+ inline iterator end();
+ inline const_iterator end() const;
+ inline const_iterator cend() const;
+ inline const_iterator constEnd() const;
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
// stl compatibility
typedef int size_type;
diff --git a/src/corelib/tools/qbytearray_p.h b/src/corelib/tools/qbytearray_p.h
new file mode 100644
index 0000000000..78c667aa90
--- /dev/null
+++ b/src/corelib/tools/qbytearray_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBYTEARRAY_P_H
+#define QBYTEARRAY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qtypetraits.h>
+#include "qtools_p.h"
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ // Define as enum to force inlining. Don't expose MaxAllocSize in a public header.
+ MaxByteArraySize = MaxAllocSize - sizeof(QtPrivate::remove_pointer<QByteArray::DataPtr>::type)
+};
+
+QT_END_NAMESPACE
+
+#endif // QBYTEARRAY_P_H
diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h
index f8539ca07a..8b832b7760 100644
--- a/src/corelib/tools/qbytearraylist.h
+++ b/src/corelib/tools/qbytearraylist.h
@@ -61,7 +61,7 @@ protected:
#endif
public:
inline QByteArray join() const
- { return QtPrivate::QByteArrayList_join(self(), 0, 0); }
+ { return QtPrivate::QByteArrayList_join(self(), Q_NULLPTR, 0); }
inline QByteArray join(const QByteArray &sep) const
{ return QtPrivate::QByteArrayList_join(self(), sep.constData(), sep.size()); }
inline QByteArray join(char sep) const
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index 014d91162a..5469eee14d 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -178,6 +178,7 @@ QT_BEGIN_NAMESPACE
\value Unicode_6_1 Version 6.1
\value Unicode_6_2 Version 6.2
\value Unicode_6_3 Version 6.3 Since Qt 5.3
+ \value Unicode_7_0 Version 7.0 Since Qt 5.5
\value Unicode_Unassigned The value is not assigned to any character
in version 6.3 of Unicode.
@@ -691,7 +692,7 @@ QT_BEGIN_NAMESPACE
Note that this gives no indication of whether the character is
available in a particular font.
*/
-bool QChar::isPrint(uint ucs4)
+bool QChar::isPrint(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -724,7 +725,7 @@ bool QChar::isPrint(uint ucs4)
/*!
\internal
*/
-bool QT_FASTCALL QChar::isSpace_helper(uint ucs4)
+bool QT_FASTCALL QChar::isSpace_helper(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -750,7 +751,7 @@ bool QT_FASTCALL QChar::isSpace_helper(uint ucs4)
Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
a mark (Mark_* categories); otherwise returns \c false.
*/
-bool QChar::isMark(uint ucs4)
+bool QChar::isMark(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -774,7 +775,7 @@ bool QChar::isMark(uint ucs4)
Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
a punctuation mark (Punctuation_* categories); otherwise returns \c false.
*/
-bool QChar::isPunct(uint ucs4)
+bool QChar::isPunct(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -802,7 +803,7 @@ bool QChar::isPunct(uint ucs4)
Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
a symbol (Symbol_* categories); otherwise returns \c false.
*/
-bool QChar::isSymbol(uint ucs4)
+bool QChar::isSymbol(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -832,7 +833,7 @@ bool QChar::isSymbol(uint ucs4)
/*!
\internal
*/
-bool QT_FASTCALL QChar::isLetter_helper(uint ucs4)
+bool QT_FASTCALL QChar::isLetter_helper(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -867,7 +868,7 @@ bool QT_FASTCALL QChar::isLetter_helper(uint ucs4)
/*!
\internal
*/
-bool QT_FASTCALL QChar::isNumber_helper(uint ucs4)
+bool QT_FASTCALL QChar::isNumber_helper(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -896,7 +897,7 @@ bool QT_FASTCALL QChar::isNumber_helper(uint ucs4)
/*!
\internal
*/
-bool QT_FASTCALL QChar::isLetterOrNumber_helper(uint ucs4)
+bool QT_FASTCALL QChar::isLetterOrNumber_helper(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -1059,7 +1060,7 @@ bool QT_FASTCALL QChar::isLetterOrNumber_helper(uint ucs4)
Returns the numeric value of the digit specified by the UCS-4-encoded
character, \a ucs4, or -1 if the character is not a digit.
*/
-int QChar::digitValue(uint ucs4)
+int QChar::digitValue(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return -1;
@@ -1076,7 +1077,7 @@ int QChar::digitValue(uint ucs4)
\overload
Returns the category of the UCS-4-encoded character specified by \a ucs4.
*/
-QChar::Category QChar::category(uint ucs4)
+QChar::Category QChar::category(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return QChar::Other_NotAssigned;
@@ -1093,7 +1094,7 @@ QChar::Category QChar::category(uint ucs4)
\overload
Returns the direction of the UCS-4-encoded character specified by \a ucs4.
*/
-QChar::Direction QChar::direction(uint ucs4)
+QChar::Direction QChar::direction(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return QChar::DirL;
@@ -1116,7 +1117,7 @@ QChar::Direction QChar::direction(uint ucs4)
character specified by \a ucs4
(needed for certain languages such as Arabic or Syriac).
*/
-QChar::JoiningType QChar::joiningType(uint ucs4)
+QChar::JoiningType QChar::joiningType(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return QChar::Joining_None;
@@ -1139,7 +1140,7 @@ QChar::JoiningType QChar::joiningType(uint ucs4)
Returns information about the joining properties of the UCS-4-encoded
character specified by \a ucs4 (needed for certain languages such as Arabic).
*/
-QChar::Joining QChar::joining(uint ucs4)
+QChar::Joining QChar::joining(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return QChar::OtherJoining;
@@ -1175,7 +1176,7 @@ QChar::Joining QChar::joining(uint ucs4)
\sa mirroredChar()
*/
-bool QChar::hasMirrored(uint ucs4)
+bool QChar::hasMirrored(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return false;
@@ -1257,7 +1258,7 @@ bool QChar::hasMirrored(uint ucs4)
\sa hasMirrored()
*/
-uint QChar::mirroredChar(uint ucs4)
+uint QChar::mirroredChar(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return ucs4;
@@ -1341,7 +1342,7 @@ QString QChar::decomposition(uint ucs4)
Returns the tag defining the composition of the UCS-4-encoded character
specified by \a ucs4. Returns QChar::NoDecomposition if no decomposition exists.
*/
-QChar::Decomposition QChar::decompositionTag(uint ucs4)
+QChar::Decomposition QChar::decompositionTag(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 >= Hangul_SBase && ucs4 < Hangul_SBase + Hangul_SCount)
return QChar::Canonical;
@@ -1367,7 +1368,7 @@ QChar::Decomposition QChar::decompositionTag(uint ucs4)
Returns the combining class for the UCS-4-encoded character specified by
\a ucs4, as defined in the Unicode standard.
*/
-unsigned char QChar::combiningClass(uint ucs4)
+unsigned char QChar::combiningClass(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return 0;
@@ -1388,7 +1389,7 @@ unsigned char QChar::combiningClass(uint ucs4)
Returns the Unicode script property value for the character specified in
its UCS-4-encoded form as \a ucs4.
*/
-QChar::Script QChar::script(uint ucs4)
+QChar::Script QChar::script(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return QChar::Script_Unknown;
@@ -1406,7 +1407,7 @@ QChar::Script QChar::script(uint ucs4)
Returns the Unicode version that introduced the character specified in
its UCS-4-encoded form as \a ucs4.
*/
-QChar::UnicodeVersion QChar::unicodeVersion(uint ucs4)
+QChar::UnicodeVersion QChar::unicodeVersion(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return QChar::Unicode_Unassigned;
@@ -1416,14 +1417,14 @@ QChar::UnicodeVersion QChar::unicodeVersion(uint ucs4)
/*!
Returns the most recent supported Unicode version.
*/
-QChar::UnicodeVersion QChar::currentUnicodeVersion()
+QChar::UnicodeVersion QChar::currentUnicodeVersion() Q_DECL_NOTHROW
{
return UNICODE_DATA_VERSION;
}
template <typename T>
-Q_DECL_CONST_FUNCTION static inline T toLowerCase_helper(T uc)
+Q_DECL_CONST_FUNCTION static inline T toLowerCase_helper(T uc) Q_DECL_NOTHROW
{
const QUnicodeTables::Properties *p = qGetProp(uc);
if (p->lowerCaseSpecial) {
@@ -1434,7 +1435,7 @@ Q_DECL_CONST_FUNCTION static inline T toLowerCase_helper(T uc)
}
template <typename T>
-Q_DECL_CONST_FUNCTION static inline T toUpperCase_helper(T uc)
+Q_DECL_CONST_FUNCTION static inline T toUpperCase_helper(T uc) Q_DECL_NOTHROW
{
const QUnicodeTables::Properties *p = qGetProp(uc);
if (p->upperCaseSpecial) {
@@ -1445,7 +1446,7 @@ Q_DECL_CONST_FUNCTION static inline T toUpperCase_helper(T uc)
}
template <typename T>
-Q_DECL_CONST_FUNCTION static inline T toTitleCase_helper(T uc)
+Q_DECL_CONST_FUNCTION static inline T toTitleCase_helper(T uc) Q_DECL_NOTHROW
{
const QUnicodeTables::Properties *p = qGetProp(uc);
if (p->titleCaseSpecial) {
@@ -1456,7 +1457,7 @@ Q_DECL_CONST_FUNCTION static inline T toTitleCase_helper(T uc)
}
template <typename T>
-Q_DECL_CONST_FUNCTION static inline T toCaseFolded_helper(T uc)
+Q_DECL_CONST_FUNCTION static inline T toCaseFolded_helper(T uc) Q_DECL_NOTHROW
{
const QUnicodeTables::Properties *p = qGetProp(uc);
if (p->caseFoldSpecial) {
@@ -1479,7 +1480,7 @@ Q_DECL_CONST_FUNCTION static inline T toCaseFolded_helper(T uc)
by \a ucs4 if the character is uppercase or titlecase; otherwise returns
the character itself.
*/
-uint QChar::toLower(uint ucs4)
+uint QChar::toLower(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return ucs4;
@@ -1499,7 +1500,7 @@ uint QChar::toLower(uint ucs4)
by \a ucs4 if the character is lowercase or titlecase; otherwise returns
the character itself.
*/
-uint QChar::toUpper(uint ucs4)
+uint QChar::toUpper(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return ucs4;
@@ -1519,7 +1520,7 @@ uint QChar::toUpper(uint ucs4)
by \a ucs4 if the character is lowercase or uppercase; otherwise returns
the character itself.
*/
-uint QChar::toTitleCase(uint ucs4)
+uint QChar::toTitleCase(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return ucs4;
@@ -1534,7 +1535,7 @@ static inline uint foldCase(const ushort *ch, const ushort *start)
return toCaseFolded_helper<uint>(c);
}
-static inline uint foldCase(uint ch, uint &last)
+static inline uint foldCase(uint ch, uint &last) Q_DECL_NOTHROW
{
uint c = ch;
if (QChar(c).isLowSurrogate() && QChar(last).isHighSurrogate())
@@ -1543,7 +1544,7 @@ static inline uint foldCase(uint ch, uint &last)
return toCaseFolded_helper<uint>(c);
}
-static inline ushort foldCase(ushort ch)
+static inline ushort foldCase(ushort ch) Q_DECL_NOTHROW
{
return toCaseFolded_helper<ushort>(ch);
}
@@ -1560,7 +1561,7 @@ static inline ushort foldCase(ushort ch)
Returns the case folded equivalent of the UCS-4-encoded character specified
by \a ucs4. For most Unicode characters this is the same as toLower().
*/
-uint QChar::toCaseFolded(uint ucs4)
+uint QChar::toCaseFolded(uint ucs4) Q_DECL_NOTHROW
{
if (ucs4 > LastValidCodePoint)
return ucs4;
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index 97e2aa7088..fc1fc7bc16 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -44,9 +44,9 @@ class QString;
struct QLatin1Char
{
public:
- Q_DECL_CONSTEXPR inline explicit QLatin1Char(char c) : ch(c) {}
- Q_DECL_CONSTEXPR inline char toLatin1() const { return ch; }
- Q_DECL_CONSTEXPR inline ushort unicode() const { return ushort(uchar(ch)); }
+ Q_DECL_CONSTEXPR inline explicit QLatin1Char(char c) Q_DECL_NOTHROW : ch(c) {}
+ Q_DECL_CONSTEXPR inline char toLatin1() const Q_DECL_NOTHROW { return ch; }
+ Q_DECL_CONSTEXPR inline ushort unicode() const Q_DECL_NOTHROW { return ushort(uchar(ch)); }
private:
char ch;
@@ -72,19 +72,19 @@ public:
LastValidCodePoint = 0x10ffff
};
- Q_DECL_CONSTEXPR QChar() : ucs(0) {}
- Q_DECL_CONSTEXPR QChar(ushort rc) : ucs(rc){} // implicit
- Q_DECL_CONSTEXPR QChar(uchar c, uchar r) : ucs(ushort((r << 8) | c)){}
- Q_DECL_CONSTEXPR QChar(short rc) : ucs(ushort(rc)){} // implicit
- Q_DECL_CONSTEXPR QChar(uint rc) : ucs(ushort(rc & 0xffff)){}
- Q_DECL_CONSTEXPR QChar(int rc) : ucs(ushort(rc & 0xffff)){}
- Q_DECL_CONSTEXPR QChar(SpecialCharacter s) : ucs(ushort(s)) {} // implicit
- Q_DECL_CONSTEXPR QChar(QLatin1Char ch) : ucs(ch.unicode()) {} // implicit
+ Q_DECL_CONSTEXPR QChar() Q_DECL_NOTHROW : ucs(0) {}
+ Q_DECL_CONSTEXPR QChar(ushort rc) Q_DECL_NOTHROW : ucs(rc) {} // implicit
+ Q_DECL_CONSTEXPR QChar(uchar c, uchar r) Q_DECL_NOTHROW : ucs(ushort((r << 8) | c)) {}
+ Q_DECL_CONSTEXPR QChar(short rc) Q_DECL_NOTHROW : ucs(ushort(rc)) {} // implicit
+ Q_DECL_CONSTEXPR QChar(uint rc) Q_DECL_NOTHROW : ucs(ushort(rc & 0xffff)) {}
+ Q_DECL_CONSTEXPR QChar(int rc) Q_DECL_NOTHROW : ucs(ushort(rc & 0xffff)) {}
+ Q_DECL_CONSTEXPR QChar(SpecialCharacter s) Q_DECL_NOTHROW : ucs(ushort(s)) {} // implicit
+ Q_DECL_CONSTEXPR QChar(QLatin1Char ch) Q_DECL_NOTHROW : ucs(ch.unicode()) {} // implicit
#ifndef QT_NO_CAST_FROM_ASCII
- QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(char c) : ucs(uchar(c)) { }
+ QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(char c) Q_DECL_NOTHROW : ucs(uchar(c)) { }
#ifndef QT_RESTRICTED_CAST_FROM_ASCII
- QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(uchar c) : ucs(c) { }
+ QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(uchar c) Q_DECL_NOTHROW : ucs(c) { }
#endif
#endif
// Unicode information
@@ -369,11 +369,11 @@ public:
};
// ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO
- inline Category category() const { return QChar::category(ucs); }
- inline Direction direction() const { return QChar::direction(ucs); }
- inline JoiningType joiningType() const { return QChar::joiningType(ucs); }
+ inline Category category() const Q_DECL_NOTHROW { return QChar::category(ucs); }
+ inline Direction direction() const Q_DECL_NOTHROW { return QChar::direction(ucs); }
+ inline JoiningType joiningType() const Q_DECL_NOTHROW { return QChar::joiningType(ucs); }
#if QT_DEPRECATED_SINCE(5, 3)
- QT_DEPRECATED inline Joining joining() const
+ QT_DEPRECATED inline Joining joining() const Q_DECL_NOTHROW
{
switch (QChar::joiningType(ucs)) {
case QChar::Joining_Causing: return QChar::Center;
@@ -386,194 +386,177 @@ public:
}
}
#endif
- inline unsigned char combiningClass() const { return QChar::combiningClass(ucs); }
+ inline unsigned char combiningClass() const Q_DECL_NOTHROW { return QChar::combiningClass(ucs); }
- inline QChar mirroredChar() const { return QChar::mirroredChar(ucs); }
- inline bool hasMirrored() const { return QChar::hasMirrored(ucs); }
+ inline QChar mirroredChar() const Q_DECL_NOTHROW { return QChar::mirroredChar(ucs); }
+ inline bool hasMirrored() const Q_DECL_NOTHROW { return QChar::hasMirrored(ucs); }
QString decomposition() const;
- inline Decomposition decompositionTag() const { return QChar::decompositionTag(ucs); }
+ inline Decomposition decompositionTag() const Q_DECL_NOTHROW { return QChar::decompositionTag(ucs); }
- inline int digitValue() const { return QChar::digitValue(ucs); }
- inline QChar toLower() const { return QChar::toLower(ucs); }
- inline QChar toUpper() const { return QChar::toUpper(ucs); }
- inline QChar toTitleCase() const { return QChar::toTitleCase(ucs); }
- inline QChar toCaseFolded() const { return QChar::toCaseFolded(ucs); }
+ inline int digitValue() const Q_DECL_NOTHROW { return QChar::digitValue(ucs); }
+ inline QChar toLower() const Q_DECL_NOTHROW { return QChar::toLower(ucs); }
+ inline QChar toUpper() const Q_DECL_NOTHROW { return QChar::toUpper(ucs); }
+ inline QChar toTitleCase() const Q_DECL_NOTHROW { return QChar::toTitleCase(ucs); }
+ inline QChar toCaseFolded() const Q_DECL_NOTHROW { return QChar::toCaseFolded(ucs); }
- inline Script script() const { return QChar::script(ucs); }
+ inline Script script() const Q_DECL_NOTHROW { return QChar::script(ucs); }
- inline UnicodeVersion unicodeVersion() const { return QChar::unicodeVersion(ucs); }
+ inline UnicodeVersion unicodeVersion() const Q_DECL_NOTHROW { return QChar::unicodeVersion(ucs); }
#if QT_DEPRECATED_SINCE(5, 0)
- QT_DEPRECATED Q_DECL_CONSTEXPR inline char toAscii() const { return toLatin1(); }
+ QT_DEPRECATED Q_DECL_CONSTEXPR inline char toAscii() const Q_DECL_NOTHROW { return toLatin1(); }
#endif
- Q_DECL_CONSTEXPR inline char toLatin1() const;
- Q_DECL_CONSTEXPR inline ushort unicode() const { return ucs; }
- inline ushort &unicode() { return ucs; }
+ Q_DECL_CONSTEXPR inline char toLatin1() const Q_DECL_NOTHROW { return ucs > 0xff ? '\0' : char(ucs); }
+ Q_DECL_CONSTEXPR inline ushort unicode() const Q_DECL_NOTHROW { return ucs; }
+ Q_DECL_RELAXED_CONSTEXPR inline ushort &unicode() Q_DECL_NOTHROW { return ucs; }
#if QT_DEPRECATED_SINCE(5, 0)
- QT_DEPRECATED static Q_DECL_CONSTEXPR inline QChar fromAscii(char c)
+ QT_DEPRECATED static Q_DECL_CONSTEXPR inline QChar fromAscii(char c) Q_DECL_NOTHROW
{ return fromLatin1(c); }
#endif
- Q_DECL_CONSTEXPR static inline QChar fromLatin1(char c);
-
- Q_DECL_CONSTEXPR inline bool isNull() const { return ucs == 0; }
-
- inline bool isPrint() const { return QChar::isPrint(ucs); }
- Q_DECL_CONSTEXPR inline bool isSpace() const { return QChar::isSpace(ucs); }
- inline bool isMark() const { return QChar::isMark(ucs); }
- inline bool isPunct() const { return QChar::isPunct(ucs); }
- inline bool isSymbol() const { return QChar::isSymbol(ucs); }
- Q_DECL_CONSTEXPR inline bool isLetter() const { return QChar::isLetter(ucs); }
- Q_DECL_CONSTEXPR inline bool isNumber() const { return QChar::isNumber(ucs); }
- Q_DECL_CONSTEXPR inline bool isLetterOrNumber() const { return QChar::isLetterOrNumber(ucs); }
- Q_DECL_CONSTEXPR inline bool isDigit() const { return QChar::isDigit(ucs); }
- Q_DECL_CONSTEXPR inline bool isLower() const { return QChar::isLower(ucs); }
- Q_DECL_CONSTEXPR inline bool isUpper() const { return QChar::isUpper(ucs); }
- Q_DECL_CONSTEXPR inline bool isTitleCase() const { return QChar::isTitleCase(ucs); }
-
- Q_DECL_CONSTEXPR inline bool isNonCharacter() const { return QChar::isNonCharacter(ucs); }
- Q_DECL_CONSTEXPR inline bool isHighSurrogate() const { return QChar::isHighSurrogate(ucs); }
- Q_DECL_CONSTEXPR inline bool isLowSurrogate() const { return QChar::isLowSurrogate(ucs); }
- Q_DECL_CONSTEXPR inline bool isSurrogate() const { return QChar::isSurrogate(ucs); }
-
- Q_DECL_CONSTEXPR inline uchar cell() const { return uchar(ucs & 0xff); }
- Q_DECL_CONSTEXPR inline uchar row() const { return uchar((ucs>>8)&0xff); }
- inline void setCell(uchar cell);
- inline void setRow(uchar row);
-
- static Q_DECL_CONSTEXPR inline bool isNonCharacter(uint ucs4)
+ static Q_DECL_CONSTEXPR inline QChar fromLatin1(char c) Q_DECL_NOTHROW { return QChar(ushort(uchar(c))); }
+
+ Q_DECL_CONSTEXPR inline bool isNull() const Q_DECL_NOTHROW { return ucs == 0; }
+
+ inline bool isPrint() const Q_DECL_NOTHROW { return QChar::isPrint(ucs); }
+ Q_DECL_CONSTEXPR inline bool isSpace() const Q_DECL_NOTHROW { return QChar::isSpace(ucs); }
+ inline bool isMark() const Q_DECL_NOTHROW { return QChar::isMark(ucs); }
+ inline bool isPunct() const Q_DECL_NOTHROW { return QChar::isPunct(ucs); }
+ inline bool isSymbol() const Q_DECL_NOTHROW { return QChar::isSymbol(ucs); }
+ Q_DECL_CONSTEXPR inline bool isLetter() const Q_DECL_NOTHROW { return QChar::isLetter(ucs); }
+ Q_DECL_CONSTEXPR inline bool isNumber() const Q_DECL_NOTHROW { return QChar::isNumber(ucs); }
+ Q_DECL_CONSTEXPR inline bool isLetterOrNumber() const Q_DECL_NOTHROW { return QChar::isLetterOrNumber(ucs); }
+ Q_DECL_CONSTEXPR inline bool isDigit() const Q_DECL_NOTHROW { return QChar::isDigit(ucs); }
+ Q_DECL_CONSTEXPR inline bool isLower() const Q_DECL_NOTHROW { return QChar::isLower(ucs); }
+ Q_DECL_CONSTEXPR inline bool isUpper() const Q_DECL_NOTHROW { return QChar::isUpper(ucs); }
+ Q_DECL_CONSTEXPR inline bool isTitleCase() const Q_DECL_NOTHROW { return QChar::isTitleCase(ucs); }
+
+ Q_DECL_CONSTEXPR inline bool isNonCharacter() const Q_DECL_NOTHROW { return QChar::isNonCharacter(ucs); }
+ Q_DECL_CONSTEXPR inline bool isHighSurrogate() const Q_DECL_NOTHROW { return QChar::isHighSurrogate(ucs); }
+ Q_DECL_CONSTEXPR inline bool isLowSurrogate() const Q_DECL_NOTHROW { return QChar::isLowSurrogate(ucs); }
+ Q_DECL_CONSTEXPR inline bool isSurrogate() const Q_DECL_NOTHROW { return QChar::isSurrogate(ucs); }
+
+ Q_DECL_CONSTEXPR inline uchar cell() const Q_DECL_NOTHROW { return uchar(ucs & 0xff); }
+ Q_DECL_CONSTEXPR inline uchar row() const Q_DECL_NOTHROW { return uchar((ucs>>8)&0xff); }
+ Q_DECL_RELAXED_CONSTEXPR inline void setCell(uchar acell) Q_DECL_NOTHROW { ucs = ushort((ucs & 0xff00) + acell); }
+ Q_DECL_RELAXED_CONSTEXPR inline void setRow(uchar arow) Q_DECL_NOTHROW { ucs = ushort((ushort(arow)<<8) + (ucs&0xff)); }
+
+ static Q_DECL_CONSTEXPR inline bool isNonCharacter(uint ucs4) Q_DECL_NOTHROW
{
return ucs4 >= 0xfdd0 && (ucs4 <= 0xfdef || (ucs4 & 0xfffe) == 0xfffe);
}
- static Q_DECL_CONSTEXPR inline bool isHighSurrogate(uint ucs4)
+ static Q_DECL_CONSTEXPR inline bool isHighSurrogate(uint ucs4) Q_DECL_NOTHROW
{
return ((ucs4 & 0xfffffc00) == 0xd800);
}
- static Q_DECL_CONSTEXPR inline bool isLowSurrogate(uint ucs4)
+ static Q_DECL_CONSTEXPR inline bool isLowSurrogate(uint ucs4) Q_DECL_NOTHROW
{
return ((ucs4 & 0xfffffc00) == 0xdc00);
}
- static Q_DECL_CONSTEXPR inline bool isSurrogate(uint ucs4)
+ static Q_DECL_CONSTEXPR inline bool isSurrogate(uint ucs4) Q_DECL_NOTHROW
{
return (ucs4 - 0xd800u < 2048u);
}
- static Q_DECL_CONSTEXPR inline bool requiresSurrogates(uint ucs4)
+ static Q_DECL_CONSTEXPR inline bool requiresSurrogates(uint ucs4) Q_DECL_NOTHROW
{
return (ucs4 >= 0x10000);
}
- static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(ushort high, ushort low)
+ static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(ushort high, ushort low) Q_DECL_NOTHROW
{
return (uint(high)<<10) + low - 0x35fdc00;
}
- static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(QChar high, QChar low)
+ static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(QChar high, QChar low) Q_DECL_NOTHROW
{
return surrogateToUcs4(high.ucs, low.ucs);
}
- static Q_DECL_CONSTEXPR inline ushort highSurrogate(uint ucs4)
+ static Q_DECL_CONSTEXPR inline ushort highSurrogate(uint ucs4) Q_DECL_NOTHROW
{
return ushort((ucs4>>10) + 0xd7c0);
}
- static Q_DECL_CONSTEXPR inline ushort lowSurrogate(uint ucs4)
+ static Q_DECL_CONSTEXPR inline ushort lowSurrogate(uint ucs4) Q_DECL_NOTHROW
{
return ushort(ucs4%0x400 + 0xdc00);
}
- static Category QT_FASTCALL category(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Direction QT_FASTCALL direction(uint ucs4) Q_DECL_CONST_FUNCTION;
- static JoiningType QT_FASTCALL joiningType(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static Category QT_FASTCALL category(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static Direction QT_FASTCALL direction(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static JoiningType QT_FASTCALL joiningType(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
#if QT_DEPRECATED_SINCE(5, 3)
- QT_DEPRECATED static Joining QT_FASTCALL joining(uint ucs4) Q_DECL_CONST_FUNCTION;
+ QT_DEPRECATED static Joining QT_FASTCALL joining(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
#endif
- static unsigned char QT_FASTCALL combiningClass(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static unsigned char QT_FASTCALL combiningClass(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
- static uint QT_FASTCALL mirroredChar(uint ucs4) Q_DECL_CONST_FUNCTION;
- static bool QT_FASTCALL hasMirrored(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL mirroredChar(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL hasMirrored(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
static QString QT_FASTCALL decomposition(uint ucs4);
- static Decomposition QT_FASTCALL decompositionTag(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static Decomposition QT_FASTCALL decompositionTag(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
- static int QT_FASTCALL digitValue(uint ucs4) Q_DECL_CONST_FUNCTION;
- static uint QT_FASTCALL toLower(uint ucs4) Q_DECL_CONST_FUNCTION;
- static uint QT_FASTCALL toUpper(uint ucs4) Q_DECL_CONST_FUNCTION;
- static uint QT_FASTCALL toTitleCase(uint ucs4) Q_DECL_CONST_FUNCTION;
- static uint QT_FASTCALL toCaseFolded(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static int QT_FASTCALL digitValue(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL toLower(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL toUpper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL toTitleCase(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL toCaseFolded(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
- static Script QT_FASTCALL script(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static Script QT_FASTCALL script(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
- static UnicodeVersion QT_FASTCALL unicodeVersion(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static UnicodeVersion QT_FASTCALL unicodeVersion(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
- static UnicodeVersion QT_FASTCALL currentUnicodeVersion() Q_DECL_CONST_FUNCTION;
+ static UnicodeVersion QT_FASTCALL currentUnicodeVersion() Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
- static bool QT_FASTCALL isPrint(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Q_DECL_CONSTEXPR inline bool isSpace(uint ucs4) Q_DECL_CONST_FUNCTION;
- static bool QT_FASTCALL isMark(uint ucs4) Q_DECL_CONST_FUNCTION;
- static bool QT_FASTCALL isPunct(uint ucs4) Q_DECL_CONST_FUNCTION;
- static bool QT_FASTCALL isSymbol(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Q_DECL_CONSTEXPR inline bool isLetter(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Q_DECL_CONSTEXPR inline bool isNumber(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Q_DECL_CONSTEXPR inline bool isLetterOrNumber(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Q_DECL_CONSTEXPR inline bool isDigit(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Q_DECL_CONSTEXPR inline bool isLower(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Q_DECL_CONSTEXPR inline bool isUpper(uint ucs4) Q_DECL_CONST_FUNCTION;
- static Q_DECL_CONSTEXPR inline bool isTitleCase(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isPrint(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static Q_DECL_CONSTEXPR inline bool isSpace(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION
+ {
+ // note that [0x09..0x0d] + 0x85 are exceptional Cc-s and must be handled explicitly
+ return ucs4 == 0x20 || (ucs4 <= 0x0d && ucs4 >= 0x09)
+ || (ucs4 > 127 && (ucs4 == 0x85 || ucs4 == 0xa0 || QChar::isSpace_helper(ucs4)));
+ }
+ static bool QT_FASTCALL isMark(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isPunct(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isSymbol(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static Q_DECL_CONSTEXPR inline bool isLetter(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION
+ {
+ return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
+ || (ucs4 > 127 && QChar::isLetter_helper(ucs4));
+ }
+ static Q_DECL_CONSTEXPR inline bool isNumber(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION
+ { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::isNumber_helper(ucs4)); }
+ static Q_DECL_CONSTEXPR inline bool isLetterOrNumber(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION
+ {
+ return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
+ || (ucs4 >= '0' && ucs4 <= '9')
+ || (ucs4 > 127 && QChar::isLetterOrNumber_helper(ucs4));
+ }
+ static Q_DECL_CONSTEXPR inline bool isDigit(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION
+ { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::category(ucs4) == Number_DecimalDigit); }
+ static Q_DECL_CONSTEXPR inline bool isLower(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION
+ { return (ucs4 <= 'z' && ucs4 >= 'a') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Lowercase); }
+ static Q_DECL_CONSTEXPR inline bool isUpper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION
+ { return (ucs4 <= 'Z' && ucs4 >= 'A') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Uppercase); }
+ static Q_DECL_CONSTEXPR inline bool isTitleCase(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION
+ { return ucs4 > 127 && QChar::category(ucs4) == Letter_Titlecase; }
private:
- static bool QT_FASTCALL isSpace_helper(uint ucs4) Q_DECL_CONST_FUNCTION;
- static bool QT_FASTCALL isLetter_helper(uint ucs4) Q_DECL_CONST_FUNCTION;
- static bool QT_FASTCALL isNumber_helper(uint ucs4) Q_DECL_CONST_FUNCTION;
- static bool QT_FASTCALL isLetterOrNumber_helper(uint ucs4) Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isSpace_helper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isLetter_helper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isNumber_helper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isLetterOrNumber_helper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION;
#ifdef QT_NO_CAST_FROM_ASCII
- QChar(char c);
- QChar(uchar c);
+ QChar(char c) Q_DECL_NOTHROW;
+ QChar(uchar c) Q_DECL_NOTHROW;
#endif
- friend Q_DECL_CONSTEXPR bool operator==(QChar, QChar);
- friend Q_DECL_CONSTEXPR bool operator< (QChar, QChar);
+ friend Q_DECL_CONSTEXPR bool operator==(QChar, QChar) Q_DECL_NOTHROW;
+ friend Q_DECL_CONSTEXPR bool operator< (QChar, QChar) Q_DECL_NOTHROW;
ushort ucs;
};
Q_DECLARE_TYPEINFO(QChar, Q_MOVABLE_TYPE);
-Q_DECL_CONSTEXPR inline char QChar::toLatin1() const { return ucs > 0xff ? '\0' : char(ucs); }
-Q_DECL_CONSTEXPR inline QChar QChar::fromLatin1(char c) { return QChar(ushort(uchar(c))); }
-
-inline void QChar::setCell(uchar acell)
-{ ucs = ushort((ucs & 0xff00) + acell); }
-inline void QChar::setRow(uchar arow)
-{ ucs = ushort((ushort(arow)<<8) + (ucs&0xff)); }
-
-Q_DECL_CONSTEXPR inline bool QChar::isSpace(uint ucs4)
-{
- // note that [0x09..0x0d] + 0x85 are exceptional Cc-s and must be handled explicitly
- return ucs4 == 0x20 || (ucs4 <= 0x0d && ucs4 >= 0x09)
- || (ucs4 > 127 && (ucs4 == 0x85 || ucs4 == 0xa0 || QChar::isSpace_helper(ucs4)));
-}
-Q_DECL_CONSTEXPR inline bool QChar::isLetter(uint ucs4)
-{
- return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
- || (ucs4 > 127 && QChar::isLetter_helper(ucs4));
-}
-Q_DECL_CONSTEXPR inline bool QChar::isNumber(uint ucs4)
-{ return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::isNumber_helper(ucs4)); }
-Q_DECL_CONSTEXPR inline bool QChar::isLetterOrNumber(uint ucs4)
-{
- return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
- || (ucs4 >= '0' && ucs4 <= '9')
- || (ucs4 > 127 && QChar::isLetterOrNumber_helper(ucs4));
-}
-Q_DECL_CONSTEXPR inline bool QChar::isDigit(uint ucs4)
-{ return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::category(ucs4) == Number_DecimalDigit); }
-Q_DECL_CONSTEXPR inline bool QChar::isLower(uint ucs4)
-{ return (ucs4 <= 'z' && ucs4 >= 'a') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Lowercase); }
-Q_DECL_CONSTEXPR inline bool QChar::isUpper(uint ucs4)
-{ return (ucs4 <= 'Z' && ucs4 >= 'A') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Uppercase); }
-Q_DECL_CONSTEXPR inline bool QChar::isTitleCase(uint ucs4)
-{ return ucs4 > 127 && QChar::category(ucs4) == Letter_Titlecase; }
-
-Q_DECL_CONSTEXPR inline bool operator==(QChar c1, QChar c2) { return c1.ucs == c2.ucs; }
-Q_DECL_CONSTEXPR inline bool operator< (QChar c1, QChar c2) { return c1.ucs < c2.ucs; }
+Q_DECL_CONSTEXPR inline bool operator==(QChar c1, QChar c2) Q_DECL_NOTHROW { return c1.ucs == c2.ucs; }
+Q_DECL_CONSTEXPR inline bool operator< (QChar c1, QChar c2) Q_DECL_NOTHROW { return c1.ucs < c2.ucs; }
Q_DECL_CONSTEXPR inline bool operator!=(QChar c1, QChar c2) { return !operator==(c1, c2); }
Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) { return !operator< (c1, c2); }
diff --git a/src/corelib/tools/qcollator.h b/src/corelib/tools/qcollator.h
index e1fa161257..57133165c4 100644
--- a/src/corelib/tools/qcollator.h
+++ b/src/corelib/tools/qcollator.h
@@ -83,7 +83,7 @@ public:
QCollator &operator=(const QCollator &);
#ifdef Q_COMPILER_RVALUE_REFS
QCollator(QCollator &&other) Q_DECL_NOTHROW
- : d(other.d) { other.d = 0; }
+ : d(other.d) { other.d = Q_NULLPTR; }
QCollator &operator=(QCollator &&other) Q_DECL_NOTHROW
{ swap(other); return *this; }
#endif
diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp
index 7f898f68a8..8c0ba8cb2b 100644
--- a/src/corelib/tools/qcommandlineoption.cpp
+++ b/src/corelib/tools/qcommandlineoption.cpp
@@ -41,10 +41,19 @@ QT_BEGIN_NAMESPACE
class QCommandLineOptionPrivate : public QSharedData
{
public:
- inline QCommandLineOptionPrivate()
+ Q_NEVER_INLINE
+ explicit QCommandLineOptionPrivate(const QString &name)
+ : names(removeInvalidNames(QStringList(name))),
+ hidden(false)
{ }
- void setNames(const QStringList &nameList);
+ Q_NEVER_INLINE
+ explicit QCommandLineOptionPrivate(const QStringList &names)
+ : names(removeInvalidNames(names)),
+ hidden(false)
+ { }
+
+ static QStringList removeInvalidNames(QStringList nameList);
//! The list of names used for this option.
QStringList names;
@@ -58,6 +67,9 @@ public:
//! The list of default values used for this option.
QStringList defaultValues;
+
+ //! Show or hide in --help
+ bool hidden;
};
/*!
@@ -98,9 +110,8 @@ public:
\sa setDescription(), setValueName(), setDefaultValues()
*/
QCommandLineOption::QCommandLineOption(const QString &name)
- : d(new QCommandLineOptionPrivate)
+ : d(new QCommandLineOptionPrivate(name))
{
- d->setNames(QStringList(name));
}
/*!
@@ -117,9 +128,8 @@ QCommandLineOption::QCommandLineOption(const QString &name)
\sa setDescription(), setValueName(), setDefaultValues()
*/
QCommandLineOption::QCommandLineOption(const QStringList &names)
- : d(new QCommandLineOptionPrivate)
+ : d(new QCommandLineOptionPrivate(names))
{
- d->setNames(names);
}
/*!
@@ -148,9 +158,8 @@ QCommandLineOption::QCommandLineOption(const QStringList &names)
QCommandLineOption::QCommandLineOption(const QString &name, const QString &description,
const QString &valueName,
const QString &defaultValue)
- : d(new QCommandLineOptionPrivate)
+ : d(new QCommandLineOptionPrivate(name))
{
- d->setNames(QStringList(name));
setValueName(valueName);
setDescription(description);
setDefaultValue(defaultValue);
@@ -185,9 +194,8 @@ QCommandLineOption::QCommandLineOption(const QString &name, const QString &descr
QCommandLineOption::QCommandLineOption(const QStringList &names, const QString &description,
const QString &valueName,
const QString &defaultValue)
- : d(new QCommandLineOptionPrivate)
+ : d(new QCommandLineOptionPrivate(names))
{
- d->setNames(names);
setValueName(valueName);
setDescription(description);
setDefaultValue(defaultValue);
@@ -236,29 +244,47 @@ QStringList QCommandLineOption::names() const
return d->names;
}
-void QCommandLineOptionPrivate::setNames(const QStringList &nameList)
-{
- QStringList newNames;
- newNames.reserve(nameList.size());
- if (nameList.isEmpty())
- qWarning("QCommandLineOption: Options must have at least one name");
- foreach (const QString &name, nameList) {
- if (name.isEmpty()) {
- qWarning("QCommandLineOption: Option names cannot be empty");
- } else {
+namespace {
+ struct IsInvalidName
+ {
+ typedef bool result_type;
+ typedef QString argument_type;
+
+ Q_NEVER_INLINE
+ result_type operator()(const QString &name) const Q_DECL_NOEXCEPT
+ {
+ if (Q_UNLIKELY(name.isEmpty()))
+ return warn("be empty");
+
const QChar c = name.at(0);
- if (c == QLatin1Char('-'))
- qWarning("QCommandLineOption: Option names cannot start with a '-'");
- else if (c == QLatin1Char('/'))
- qWarning("QCommandLineOption: Option names cannot start with a '/'");
- else if (name.contains(QLatin1Char('=')))
- qWarning("QCommandLineOption: Option names cannot contain a '='");
- else
- newNames.append(name);
+ if (Q_UNLIKELY(c == QLatin1Char('-')))
+ return warn("start with a '-'");
+ if (Q_UNLIKELY(c == QLatin1Char('/')))
+ return warn("start with a '/'");
+ if (Q_UNLIKELY(name.contains(QLatin1Char('='))))
+ return warn("contain a '='");
+
+ return false;
}
- }
- // commit
- names.swap(newNames);
+
+ Q_NEVER_INLINE
+ static bool warn(const char *what) Q_DECL_NOEXCEPT
+ {
+ qWarning("QCommandLineOption: Option names cannot %s", what);
+ return true;
+ }
+ };
+} // unnamed namespace
+
+// static
+QStringList QCommandLineOptionPrivate::removeInvalidNames(QStringList nameList)
+{
+ if (Q_UNLIKELY(nameList.isEmpty()))
+ qWarning("QCommandLineOption: Options must have at least one name");
+ else
+ nameList.erase(std::remove_if(nameList.begin(), nameList.end(), IsInvalidName()),
+ nameList.end());
+ return nameList;
}
/*!
@@ -362,4 +388,30 @@ QStringList QCommandLineOption::defaultValues() const
return d->defaultValues;
}
+/*!
+ Sets whether to hide this option in the user-visible help output.
+
+ All options are visible by default. Setting \a hide to true for
+ a particular option makes it internal, i.e. not listed in the help output.
+
+ \since 5.6
+ \sa isHidden
+ */
+void QCommandLineOption::setHidden(bool hide)
+{
+ d->hidden = hide;
+}
+
+/*!
+ Returns true if this option is omitted from the help output,
+ false if the option is listed.
+
+ \since 5.6
+ \sa setHidden()
+ */
+bool QCommandLineOption::isHidden() const
+{
+ return d->hidden;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qcommandlineoption.h b/src/corelib/tools/qcommandlineoption.h
index cf4160ecd2..828522cbc5 100644
--- a/src/corelib/tools/qcommandlineoption.h
+++ b/src/corelib/tools/qcommandlineoption.h
@@ -58,11 +58,10 @@ public:
QCommandLineOption &operator=(const QCommandLineOption &other);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QCommandLineOption &operator=(QCommandLineOption &&other)
- { qSwap(d, other.d); return *this; }
+ QCommandLineOption &operator=(QCommandLineOption &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- inline void swap(QCommandLineOption &other)
+ void swap(QCommandLineOption &other) Q_DECL_NOTHROW
{ qSwap(d, other.d); }
QStringList names() const;
@@ -77,6 +76,9 @@ public:
void setDefaultValues(const QStringList &defaultValues);
QStringList defaultValues() const;
+ void setHidden(bool hidden);
+ bool isHidden() const;
+
private:
QSharedDataPointer<QCommandLineOptionPrivate> d;
};
diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp
index 0814921a58..20e0688f45 100644
--- a/src/corelib/tools/qcommandlineparser.cpp
+++ b/src/corelib/tools/qcommandlineparser.cpp
@@ -53,6 +53,7 @@ class QCommandLineParserPrivate
public:
inline QCommandLineParserPrivate()
: singleDashWordOptionMode(QCommandLineParser::ParseAsCompactedShortOptions),
+ optionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsOptions),
builtinVersionOption(false),
builtinHelpOption(false),
needsParsing(true)
@@ -103,6 +104,9 @@ public:
//! The parsing mode for "-abc"
QCommandLineParser::SingleDashWordOptionMode singleDashWordOptionMode;
+ //! How to parse "arg -option"
+ QCommandLineParser::OptionsAfterPositionalArgumentsMode optionsAfterPositionalArgumentsMode;
+
//! Whether addVersionOption was called
bool builtinVersionOption;
@@ -112,6 +116,7 @@ public:
//! True if parse() needs to be called
bool needsParsing;
};
+Q_DECLARE_TYPEINFO(QCommandLineParserPrivate::PositionalArgumentDefinition, Q_MOVABLE_TYPE);
QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const
{
@@ -299,6 +304,41 @@ void QCommandLineParser::setSingleDashWordOptionMode(QCommandLineParser::SingleD
}
/*!
+ \enum QCommandLineParser::OptionsAfterPositionalArgumentsMode
+
+ This enum describes the way the parser interprets options that
+ occur after positional arguments.
+
+ \value ParseAsOptions \c{application argument --opt -t} is interpreted as setting
+ the options \c{opt} and \c{t}, just like \c{application --opt -t argument} would do.
+ This is the default parsing mode. In order to specify that \c{--opt} and \c{-t}
+ are positional arguments instead, the user can use \c{--}, as in
+ \c{application argument -- --opt -t}.
+
+ \value ParseAsPositionalArguments \c{application argument --opt} is interpreted as
+ having two positional arguments, \c{argument} and \c{--opt}.
+ This mode is useful for executables that aim to launch other executables
+ (e.g. wrappers, debugging tools, etc.) or that support internal commands
+ followed by options for the command. \c{argument} is the name of the command,
+ and all options occurring after it can be collected and parsed by another
+ command line parser, possibly in another executable.
+
+ \sa setOptionsAfterPositionalArgumentsMode()
+
+ \since 5.5
+*/
+
+/*!
+ Sets the parsing mode to \a parsingMode.
+ This must be called before process() or parse().
+ \since 5.5
+*/
+void QCommandLineParser::setOptionsAfterPositionalArgumentsMode(QCommandLineParser::OptionsAfterPositionalArgumentsMode parsingMode)
+{
+ d->optionsAfterPositionalArgumentsMode = parsingMode;
+}
+
+/*!
Adds the option \a option to look for while parsing.
Returns \c true if adding the option was successful; otherwise returns \c false.
@@ -640,7 +680,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
const QLatin1Char dashChar('-');
const QLatin1Char assignChar('=');
- bool doubleDashFound = false;
+ bool forcePositional = false;
errorText.clear();
positionalArgumentList.clear();
optionNames.clear();
@@ -658,7 +698,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
for (; argumentIterator != args.end() ; ++argumentIterator) {
QString argument = *argumentIterator;
- if (doubleDashFound) {
+ if (forcePositional) {
positionalArgumentList.append(argument);
} else if (argument.startsWith(doubleDashString)) {
if (argument.length() > 2) {
@@ -670,7 +710,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
error = true;
}
} else {
- doubleDashFound = true;
+ forcePositional = true;
}
} else if (argument.startsWith(dashChar)) {
if (argument.size() == 1) { // single dash ("stdin")
@@ -722,6 +762,8 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
}
} else {
positionalArgumentList.append(argument);
+ if (optionsAfterPositionalArgumentsMode == QCommandLineParser::ParseAsPositionalArguments)
+ forcePositional = true;
}
if (argumentIterator == args.end())
break;
@@ -1062,6 +1104,8 @@ QString QCommandLineParserPrivate::helpText() const
++longestOptionNameString;
for (int i = 0; i < commandLineOptionList.count(); ++i) {
const QCommandLineOption &option = commandLineOptionList.at(i);
+ if (option.isHidden())
+ continue;
text += wrapText(optionNameList.at(i), longestOptionNameString, option.description());
}
if (!positionalArgumentDefinitions.isEmpty()) {
diff --git a/src/corelib/tools/qcommandlineparser.h b/src/corelib/tools/qcommandlineparser.h
index 91a799b4d5..8c528ba69e 100644
--- a/src/corelib/tools/qcommandlineparser.h
+++ b/src/corelib/tools/qcommandlineparser.h
@@ -57,6 +57,12 @@ public:
};
void setSingleDashWordOptionMode(SingleDashWordOptionMode parsingMode);
+ enum OptionsAfterPositionalArgumentsMode {
+ ParseAsOptions,
+ ParseAsPositionalArguments
+ };
+ void setOptionsAfterPositionalArgumentsMode(OptionsAfterPositionalArgumentsMode mode);
+
bool addOption(const QCommandLineOption &commandLineOption);
bool addOptions(const QList<QCommandLineOption> &options);
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index 6651efdc13..c44f7f8fee 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -74,7 +74,7 @@ public:
int dayOfYear() const;
int daysInMonth() const;
int daysInYear() const;
- int weekNumber(int *yearNum = 0) const;
+ int weekNumber(int *yearNum = Q_NULLPTR) const;
#ifndef QT_NO_TEXTDATE
static QString shortMonthName(int month, MonthNameType type = DateFormat);
@@ -222,9 +222,12 @@ public:
QDateTime(const QDateTime &other);
~QDateTime();
+#ifdef Q_COMPILER_RVALUE_REFS
+ QDateTime &operator=(QDateTime &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+#endif
QDateTime &operator=(const QDateTime &other);
- inline void swap(QDateTime &other) { qSwap(d, other.d); }
+ void swap(QDateTime &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
bool isNull() const;
bool isValid() const;
diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h
index 9457e35ad5..a1cf8f283f 100644
--- a/src/corelib/tools/qdatetimeparser_p.h
+++ b/src/corelib/tools/qdatetimeparser_p.h
@@ -252,6 +252,7 @@ public:
Qt::TimeSpec spec; // spec if used by QDateTimeEdit
Context context;
};
+Q_DECLARE_TYPEINFO(QDateTimeParser::SectionNode, Q_PRIMITIVE_TYPE);
Q_CORE_EXPORT bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2);
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index 1bd9c5ebb9..22f5c65a40 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -340,6 +340,7 @@ struct TCBPoint {
qFuzzyCompare(_b, other._b);
}
};
+Q_DECLARE_TYPEINFO(TCBPoint, Q_PRIMITIVE_TYPE);
typedef QVector<TCBPoint> TCBPoints;
@@ -1219,6 +1220,7 @@ QVector<QPointF> static inline tcbToBezier(const TCBPoints &tcbPoints)
{
const int count = tcbPoints.count();
QVector<QPointF> bezierPoints;
+ bezierPoints.reserve(3 * (count - 1));
for (int i = 1; i < count; i++) {
const qreal t_0 = tcbPoints.at(i - 1)._t;
diff --git a/src/corelib/tools/qeasingcurve.h b/src/corelib/tools/qeasingcurve.h
index 4065de1366..d04d5ef30a 100644
--- a/src/corelib/tools/qeasingcurve.h
+++ b/src/corelib/tools/qeasingcurve.h
@@ -75,7 +75,7 @@ public:
QEasingCurve &operator=(const QEasingCurve &other)
{ if ( this != &other ) { QEasingCurve copy(other); swap(copy); } return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
- QEasingCurve(QEasingCurve &&other) : d_ptr(other.d_ptr) { other.d_ptr = 0; }
+ QEasingCurve(QEasingCurve &&other) : d_ptr(other.d_ptr) { other.d_ptr = Q_NULLPTR; }
QEasingCurve &operator=(QEasingCurve &&other)
{ qSwap(d_ptr, other.d_ptr); return *this; }
#endif
diff --git a/src/corelib/tools/qharfbuzz.cpp b/src/corelib/tools/qharfbuzz.cpp
index afc8b23473..fa279949ea 100644
--- a/src/corelib/tools/qharfbuzz.cpp
+++ b/src/corelib/tools/qharfbuzz.cpp
@@ -65,6 +65,9 @@ HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
void (*HB_Library_Resolve(const char *library, int version, const char *symbol))()
{
#ifdef QT_NO_LIBRARY
+ Q_UNUSED(library);
+ Q_UNUSED(version);
+ Q_UNUSED(symbol);
return 0;
#else
return QLibrary::resolve(QLatin1String(library), version, symbol);
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index a8a461e868..1f3ea36121 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1536,6 +1536,15 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
\sa begin(), constEnd()
*/
+/*! \fn QHash::key_iterator QHash::keyBegin() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first key
+ in the hash.
+
+ \sa keyEnd()
+*/
+
/*! \fn QHash::iterator QHash::end()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
@@ -1566,6 +1575,15 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
\sa cbegin(), end()
*/
+/*! \fn QHash::key_iterator QHash::keyEnd() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
+ item after the last key in the hash.
+
+ \sa keyBegin()
+*/
+
/*! \fn QHash::iterator QHash::erase(iterator pos)
Removes the (key, value) pair associated with the iterator \a pos
@@ -1729,6 +1747,26 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
\internal
*/
+/*! \typedef QHash::key_iterator::difference_type
+ \internal
+*/
+
+/*! \typedef QHash::key_iterator::iterator_category
+ \internal
+*/
+
+/*! \typedef QHash::key_iterator::pointer
+ \internal
+*/
+
+/*! \typedef QHash::key_iterator::reference
+ \internal
+*/
+
+/*! \typedef QHash::key_iterator::value_type
+ \internal
+*/
+
/*! \class QHash::iterator
\inmodule QtCore
\brief The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
@@ -1802,7 +1840,7 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
while iterators are active on that container. For more information,
read \l{Implicit sharing iterator problem}.
- \sa QHash::const_iterator, QMutableHashIterator
+ \sa QHash::const_iterator, QHash::key_iterator, QMutableHashIterator
*/
/*! \fn QHash::iterator::iterator()
@@ -2155,6 +2193,114 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
\sa operator+=(), operator-()
*/
+/*! \class QHash::key_iterator
+ \inmodule QtCore
+ \since 5.6
+ \brief The QHash::key_iterator class provides an STL-style const iterator for QHash and QMultiHash keys.
+
+ QHash::key_iterator is essentially the same as QHash::const_iterator
+ with the difference that operator*() and operator->() return a key
+ instead of a value.
+
+ For most uses QHash::iterator and QHash::const_iterator should be used,
+ you can easily access the key by calling QHash::iterator::key():
+
+ \snippet code/src_corelib_tools_qhash.cpp 27
+
+ However, to have interoperability between QHash's keys and STL-style
+ algorithms we need an iterator that dereferences to a key instead
+ of a value. With QHash::key_iterator we can apply an algorithm to a
+ range of keys without having to call QHash::keys(), which is inefficient
+ as it costs one QHash iteration and memory allocation to create a temporary
+ QList.
+
+ \snippet code/src_corelib_tools_qhash.cpp 28
+
+ QHash::key_iterator is const, it's not possible to modify the key.
+
+ The default QHash::key_iterator constructor creates an uninitialized
+ iterator. You must initialize it using a QHash function like
+ QHash::keyBegin() or QHash::keyEnd().
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
+ \sa QHash::const_iterator, QHash::iterator
+*/
+
+/*! \fn const T &QHash::key_iterator::operator*() const
+
+ Returns the current item's key.
+*/
+
+/*! \fn const T *QHash::key_iterator::operator->() const
+
+ Returns a pointer to the current item's key.
+*/
+
+/*! \fn bool QHash::key_iterator::operator==(key_iterator other) const
+
+ Returns \c true if \a other points to the same item as this
+ iterator; otherwise returns \c false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QHash::key_iterator::operator!=(key_iterator other) const
+
+ Returns \c true if \a other points to a different item than this
+ iterator; otherwise returns \c false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn QHash::key_iterator &QHash::key_iterator::operator++()
+
+ The prefix ++ operator (\c{++i}) advances the iterator to the
+ next item in the hash and returns an iterator to the new current
+ item.
+
+ Calling this function on QHash::keyEnd() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QHash::key_iterator QHash::key_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{i++}) advances the iterator to the
+ next item in the hash and returns an iterator to the previous
+ item.
+*/
+
+/*! \fn QHash::key_iterator &QHash::key_iterator::operator--()
+
+ The prefix -- operator (\c{--i}) makes the preceding item
+ current and returns an iterator pointing to the new current item.
+
+ Calling this function on QHash::keyBegin() leads to undefined
+ results.
+
+ \sa operator++()
+*/
+
+/*! \fn QHash::key_iterator QHash::key_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{i--}) makes the preceding item
+ current and returns an iterator pointing to the previous
+ item.
+*/
+
+/*! \fn const_iterator QHash::key_iterator::base() const
+ Returns the underlying const_iterator this key_iterator is based on.
+*/
+
/*! \fn QDataStream &operator<<(QDataStream &out, const QHash<Key, T>& hash)
\relates QHash
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index a9ece12670..e367cc0068 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -38,10 +38,9 @@
#include <QtCore/qchar.h>
#include <QtCore/qiterator.h>
#include <QtCore/qlist.h>
-#include <QtCore/qpair.h>
#include <QtCore/qrefcount.h>
+#include <QtCore/qhashfunctions.h>
-#include <numeric> // for std::accumulate
#ifdef Q_COMPILER_INITIALIZER_LISTS
#include <initializer_list>
#endif
@@ -54,101 +53,6 @@
QT_BEGIN_NAMESPACE
-class QBitArray;
-class QByteArray;
-class QString;
-class QStringRef;
-class QLatin1String;
-
-Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHashBits(const void *p, size_t size, uint seed = 0) Q_DECL_NOTHROW;
-
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uchar key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(signed char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ushort key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(short key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uint key, uint seed = 0) Q_DECL_NOTHROW { return key ^ seed; }
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(int key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ulong key, uint seed = 0) Q_DECL_NOTHROW
-{
- return (sizeof(ulong) > sizeof(uint))
- ? (uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed)
- : (uint(key & (~0U)) ^ seed);
-}
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(long key, uint seed = 0) Q_DECL_NOTHROW { return qHash(ulong(key), seed); }
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW
-{
- return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed;
-}
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); }
-Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW;
-Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW;
-#ifndef Q_OS_DARWIN
-Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW;
-#endif
-Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(const QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); }
-Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW;
-Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW;
-Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QStringRef &key, uint seed = 0) Q_DECL_NOTHROW;
-Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed = 0) Q_DECL_NOTHROW;
-Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW;
-Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QString &key) Q_DECL_NOTHROW;
-Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QStringRef &key) Q_DECL_NOTHROW;
-
-template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
-{
- return qHash(reinterpret_cast<quintptr>(key), seed);
-}
-template<typename T> inline uint qHash(const T &t, uint seed)
- Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
-{ return (qHash(t) ^ seed); }
-
-namespace QtPrivate {
-
-struct QHashCombine {
- typedef uint result_type;
- template <typename T>
- Q_DECL_CONSTEXPR result_type operator()(uint seed, const T &t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
- // combiner taken from N3876 / boost::hash_combine
- { return seed ^ (qHash(t) + 0x9e3779b9 + (seed << 6) + (seed >> 2)) ; }
-};
-
-struct QHashCombineCommutative {
- // QHashCombine is a good hash combiner, but is not commutative,
- // ie. it depends on the order of the input elements. That is
- // usually what we want: {0,1,3} should hash differently than
- // {1,3,0}. Except when it isn't (e.g. for QSet and
- // QHash). Therefore, provide a commutative combiner, too.
- typedef uint result_type;
- template <typename T>
- Q_DECL_CONSTEXPR result_type operator()(uint seed, const T &t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
- { return seed + qHash(t); } // don't use xor!
-};
-
-} // namespace QtPrivate
-
-template <typename InputIterator>
-inline uint qHashRange(InputIterator first, InputIterator last, uint seed = 0)
- Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(*first))) // assume iterator operations don't throw
-{
- return std::accumulate(first, last, seed, QtPrivate::QHashCombine());
-}
-
-template <typename InputIterator>
-inline uint qHashRangeCommutative(InputIterator first, InputIterator last, uint seed = 0)
- Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(*first))) // assume iterator operations don't throw
-{
- return std::accumulate(first, last, seed, QtPrivate::QHashCombineCommutative());
-}
-
-template <typename T1, typename T2> inline uint qHash(const QPair<T1, T2> &key, uint seed = 0)
- Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed)))
-{
- uint h1 = qHash(key.first, seed);
- uint h2 = qHash(key.second, seed);
- return ((h1 << 16) | (h1 >> 16)) ^ h2 ^ seed;
-}
-
struct Q_CORE_EXPORT QHashData
{
struct Node {
@@ -345,7 +249,7 @@ public:
#ifdef Q_COMPILER_RVALUE_REFS
QHash(QHash &&other) Q_DECL_NOTHROW : d(other.d) { other.d = const_cast<QHashData *>(&QHashData::shared_null); }
QHash &operator=(QHash &&other) Q_DECL_NOTHROW
- { qSwap(d, other.d); return *this; }
+ { QHash moved(std::move(other)); swap(moved); return *this; }
#endif
void swap(QHash &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
@@ -402,7 +306,7 @@ public:
typedef T *pointer;
typedef T &reference;
- inline iterator() : i(0) { }
+ inline iterator() : i(Q_NULLPTR) { }
explicit inline iterator(void *node) : i(reinterpret_cast<QHashData::Node *>(node)) { }
inline const Key &key() const { return concrete(i)->key; }
@@ -449,6 +353,7 @@ public:
class const_iterator
{
friend class iterator;
+ friend class QSet<Key>;
QHashData::Node *i;
public:
@@ -458,7 +363,7 @@ public:
typedef const T *pointer;
typedef const T &reference;
- inline const_iterator() : i(0) { }
+ inline const_iterator() : i(Q_NULLPTR) { }
explicit inline const_iterator(void *node)
: i(reinterpret_cast<QHashData::Node *>(node)) { }
#ifdef QT_STRICT_ITERATORS
@@ -508,6 +413,31 @@ public:
};
friend class const_iterator;
+ class key_iterator
+ {
+ const_iterator i;
+
+ public:
+ typedef typename const_iterator::iterator_category iterator_category;
+ typedef typename const_iterator::difference_type difference_type;
+ typedef Key value_type;
+ typedef const Key *pointer;
+ typedef const Key &reference;
+
+ explicit key_iterator(const_iterator o) : i(o) { }
+
+ const Key &operator*() const { return i.key(); }
+ const Key *operator->() const { return &i.key(); }
+ bool operator==(key_iterator o) const { return i == o.i; }
+ bool operator!=(key_iterator o) const { return i != o.i; }
+
+ inline key_iterator &operator++() { ++i; return *this; }
+ inline key_iterator operator++(int) { return key_iterator(i++);}
+ inline key_iterator &operator--() { --i; return *this; }
+ inline key_iterator operator--(int) { return key_iterator(i--); }
+ const_iterator base() const { return i; }
+ };
+
// STL style
inline iterator begin() { detach(); return iterator(d->firstNode()); }
inline const_iterator begin() const { return const_iterator(d->firstNode()); }
@@ -517,6 +447,9 @@ public:
inline const_iterator end() const { return const_iterator(e); }
inline const_iterator cend() const { return const_iterator(e); }
inline const_iterator constEnd() const { return const_iterator(e); }
+ inline key_iterator keyBegin() const { return key_iterator(begin()); }
+ inline key_iterator keyEnd() const { return key_iterator(end()); }
+
iterator erase(iterator it);
// more Qt
@@ -546,7 +479,8 @@ public:
private:
void detach_helper();
void freeData(QHashData *d);
- Node **findNode(const Key &key, uint *hp = 0) const;
+ Node **findNode(const Key &key, uint *hp = Q_NULLPTR) const;
+ Node **findNode(const Key &key, uint h) const;
Node *createNode(uint h, const Key &key, const T &value, Node **nextNode);
void deleteNode(Node *node);
static void deleteNode2(QHashData::Node *node);
@@ -590,7 +524,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE void QHash<Key, T>::duplicateNode(QHashData::Node *node, void *newNode)
{
Node *concreteNode = concrete(node);
- new (newNode) Node(concreteNode->key, concreteNode->value, concreteNode->h, 0);
+ new (newNode) Node(concreteNode->key, concreteNode->value, concreteNode->h, Q_NULLPTR);
}
template <class Key, class T>
@@ -942,17 +876,10 @@ Q_INLINE_TEMPLATE bool QHash<Key, T>::contains(const Key &akey) const
}
template <class Key, class T>
-Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::Node **QHash<Key, T>::findNode(const Key &akey,
- uint *ahp) const
+Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::Node **QHash<Key, T>::findNode(const Key &akey, uint h) const
{
Node **node;
- uint h = 0;
- if (d->numBuckets || ahp) {
- h = qHash(akey, d->seed);
- if (ahp)
- *ahp = h;
- }
if (d->numBuckets) {
node = reinterpret_cast<Node **>(&d->buckets[h % d->numBuckets]);
Q_ASSERT(*node == e || (*node)->next);
@@ -965,6 +892,20 @@ Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::Node **QHash<Key, T>::findNode(cons
}
template <class Key, class T>
+Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::Node **QHash<Key, T>::findNode(const Key &akey,
+ uint *ahp) const
+{
+ uint h = 0;
+
+ if (d->numBuckets || ahp) {
+ h = qHash(akey, d->seed);
+ if (ahp)
+ *ahp = h;
+ }
+ return findNode(akey, h);
+}
+
+template <class Key, class T>
Q_OUTOFLINE_TEMPLATE bool QHash<Key, T>::operator==(const QHash &other) const
{
if (size() != other.size())
@@ -1003,6 +944,9 @@ public:
insert(it->first, it->second);
}
#endif
+ // compiler-generated copy/move ctors/assignment operators are fine!
+ // compiler-generated destructor is fine!
+
QMultiHash(const QHash<Key, T> &other) : QHash<Key, T>(other) {}
void swap(QMultiHash &other) { QHash<Key, T>::swap(other); } // prevent QMultiHash<->QHash swaps
diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h
new file mode 100644
index 0000000000..e15fbb07ac
--- /dev/null
+++ b/src/corelib/tools/qhashfunctions.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHASHFUNCTIONS_H
+#define QHASHFUNCTIONS_H
+
+#include <QtCore/qchar.h>
+#include <QtCore/qpair.h>
+
+#include <numeric> // for std::accumulate
+
+#if 0
+#pragma qt_class(QHashFunctions)
+#endif
+
+#if defined(Q_CC_MSVC)
+#pragma warning( push )
+#pragma warning( disable : 4311 ) // disable pointer truncation warning
+#pragma warning( disable : 4127 ) // conditional expression is constant
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QBitArray;
+class QByteArray;
+class QString;
+class QStringRef;
+class QLatin1String;
+
+Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHashBits(const void *p, size_t size, uint seed = 0) Q_DECL_NOTHROW;
+
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uchar key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(signed char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ushort key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(short key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uint key, uint seed = 0) Q_DECL_NOTHROW { return key ^ seed; }
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(int key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; }
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ulong key, uint seed = 0) Q_DECL_NOTHROW
+{
+ return (sizeof(ulong) > sizeof(uint))
+ ? (uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed)
+ : (uint(key & (~0U)) ^ seed);
+}
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(long key, uint seed = 0) Q_DECL_NOTHROW { return qHash(ulong(key), seed); }
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW
+{
+ return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed;
+}
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); }
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW;
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW;
+#ifndef Q_OS_DARWIN
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW;
+#endif
+Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(const QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); }
+Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW;
+Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW;
+Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QStringRef &key, uint seed = 0) Q_DECL_NOTHROW;
+Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed = 0) Q_DECL_NOTHROW;
+Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW;
+Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QString &key) Q_DECL_NOTHROW;
+Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QStringRef &key) Q_DECL_NOTHROW;
+
+template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
+{
+ return qHash(reinterpret_cast<quintptr>(key), seed);
+}
+template<typename T> inline uint qHash(const T &t, uint seed)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
+{ return qHash(t) ^ seed; }
+
+namespace QtPrivate {
+
+struct QHashCombine {
+ typedef uint result_type;
+ template <typename T>
+ Q_DECL_CONSTEXPR result_type operator()(uint seed, const T &t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
+ // combiner taken from N3876 / boost::hash_combine
+ { return seed ^ (qHash(t) + 0x9e3779b9 + (seed << 6) + (seed >> 2)) ; }
+};
+
+struct QHashCombineCommutative {
+ // QHashCombine is a good hash combiner, but is not commutative,
+ // ie. it depends on the order of the input elements. That is
+ // usually what we want: {0,1,3} should hash differently than
+ // {1,3,0}. Except when it isn't (e.g. for QSet and
+ // QHash). Therefore, provide a commutative combiner, too.
+ typedef uint result_type;
+ template <typename T>
+ Q_DECL_CONSTEXPR result_type operator()(uint seed, const T &t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
+ { return seed + qHash(t); } // don't use xor!
+};
+
+} // namespace QtPrivate
+
+template <typename InputIterator>
+inline uint qHashRange(InputIterator first, InputIterator last, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(*first))) // assume iterator operations don't throw
+{
+ return std::accumulate(first, last, seed, QtPrivate::QHashCombine());
+}
+
+template <typename InputIterator>
+inline uint qHashRangeCommutative(InputIterator first, InputIterator last, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(*first))) // assume iterator operations don't throw
+{
+ return std::accumulate(first, last, seed, QtPrivate::QHashCombineCommutative());
+}
+
+template <typename T1, typename T2> inline uint qHash(const QPair<T1, T2> &key, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed)))
+{
+ uint h1 = qHash(key.first, seed);
+ uint h2 = qHash(key.second, seed);
+ return ((h1 << 16) | (h1 >> 16)) ^ h2 ^ seed;
+}
+
+QT_END_NAMESPACE
+
+#if defined(Q_CC_MSVC)
+#pragma warning( pop )
+#endif
+
+#endif // QHASHFUNCTIONS_H
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index 7908bf5137..f216aa121c 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -88,7 +88,7 @@ public:
#ifdef Q_COMPILER_RVALUE_REFS
inline QLinkedList(QLinkedList<T> &&other) : d(other.d) { other.d = const_cast<QLinkedListData *>(&QLinkedListData::shared_null); }
inline QLinkedList<T> &operator=(QLinkedList<T> &&other)
- { qSwap(d, other.d); return *this; }
+ { QLinkedList moved(std::move(other)); swap(moved); return *this; }
#endif
inline void swap(QLinkedList<T> &other) { qSwap(d, other.d); }
bool operator==(const QLinkedList<T> &l) const;
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index db00dcb458..8ed0da7ca0 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Intel Corporation.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -148,6 +149,17 @@ void QListData::realloc(int alloc)
d->begin = d->end = 0;
}
+void QListData::realloc_grow(int growth)
+{
+ Q_ASSERT(!d->ref.isShared());
+ int alloc = grow(d->alloc + growth);
+ Data *x = static_cast<Data *>(::realloc(d, DataHeaderSize + alloc * sizeof(void *)));
+ Q_CHECK_PTR(x);
+
+ d = x;
+ d->alloc = alloc;
+}
+
void QListData::dispose(Data *d)
{
Q_ASSERT(!d->ref.isShared());
@@ -167,7 +179,7 @@ void **QListData::append(int n)
::memcpy(d->array, d->array + b, e * sizeof(void *));
d->begin = 0;
} else {
- realloc(grow(d->alloc + n));
+ realloc_grow(n);
}
}
d->end = e + n;
@@ -191,7 +203,7 @@ void **QListData::prepend()
Q_ASSERT(!d->ref.isShared());
if (d->begin == 0) {
if (d->end >= d->alloc / 3)
- realloc(grow(d->alloc + 1));
+ realloc_grow(1);
if (d->end < d->alloc / 3)
d->begin = d->alloc - 2 * d->end;
@@ -218,7 +230,7 @@ void **QListData::insert(int i)
if (d->begin == 0) {
if (d->end == d->alloc) {
// If the array is full, we expand it and move some items rightward
- realloc(grow(d->alloc + 1));
+ realloc_grow(1);
} else {
// If there is free space at the end of the array, we move some items rightward
}
@@ -332,41 +344,56 @@ void **QListData::erase(void **xi)
\reentrant
QList\<T\> is one of Qt's generic \l{container classes}. It
- stores a list of values and provides fast index-based access as
- well as fast insertions and removals.
+ stores items in a list that provides fast index-based access
+ and index-based insertions and removals.
QList\<T\>, QLinkedList\<T\>, and QVector\<T\> provide similar
- functionality. Here's an overview:
+ APIs and functionality. They are often interchangeable, but there
+ are performance consequences. Here is an overview of use cases:
\list
- \li For most purposes, QList is the right class to use. Its
- index-based API is more convenient than QLinkedList's
- iterator-based API, and it is usually faster than
- QVector because of the way it stores its items in
- memory. It also expands to less code in your executable.
- \li If you need a real linked list, with guarantees of \l{constant
- time} insertions in the middle of the list and iterators to
- items rather than indexes, use QLinkedList.
- \li If you want the items to occupy adjacent memory positions,
- use QVector.
+ \li QVector should be your default first choice.
+ QVector\<T\> will usually give better performance than QList\<T\>,
+ because QVector\<T\> always stores its items sequentially in memory,
+ where QList\<T\> will allocate its items on the heap unless
+ \c {sizeof(T) <= sizeof(void*)} and T has been declared to be
+ either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using
+ \l {Q_DECLARE_TYPEINFO}. See the \l {Pros and Cons of Using QList}
+ for an explanation.
+ \li However, QList is used throughout the Qt APIs for passing
+ parameters and for returning values. Use QList to interface with
+ those APIs.
+ \li If you need a real linked list, which guarantees
+ \l {Algorithmic Complexity}{constant time} insertions mid-list and
+ uses iterators to items rather than indexes, use QLinkedList.
\endlist
+ \note QVector and QVarLengthArray both guarantee C-compatible
+ array layout. QList does not. This might be important if your
+ application must interface with a C API.
- Internally, QList\<T\> is represented as an array of pointers to
- items of type T. If T is itself a pointer type or a basic type
- that is no larger than a pointer, or if T is one of Qt's \l{shared
- classes}, then QList\<T\> stores the items directly in the pointer
- array. For lists under a thousand items, this array representation
- allows for very fast insertions in the middle, and it allows
- index-based access. Furthermore, operations like prepend() and
- append() are very fast, because QList preallocates memory at both
+ \note Iterators into a QLinkedList and references into
+ heap-allocating QLists remain valid long as the referenced items
+ remain in the container. This is not true for iterators and
+ references into a QVector and non-heap-allocating QLists.
+
+ Internally, QList\<T\> is represented as an array of T if
+ \c{sizeof(T) <= sizeof(void*)} and T has been declared to be
+ either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using
+ \l {Q_DECLARE_TYPEINFO}. Otherwise, QList\<T\> is represented
+ as an array of T* and the items are allocated on the heap.
+
+ The array representation allows very fast insertions and
+ index-based access. The prepend() and append() operations are
+ also very fast because QList preallocates memory at both
ends of its internal array. (See \l{Algorithmic Complexity} for
- details.) Note, however, that for unshared list items that are
- larger than a pointer, each append or insert of a new item
- requires allocating the new item on the heap, and this per item
- allocation might make QVector a better choice in cases that do
- lots of appending or inserting, since QVector allocates memory for
- its items in a single heap allocation.
+ details.
+
+ Note, however, that when the conditions specified above are not met,
+ each append or insert of a new item requires allocating the new item
+ on the heap, and this per item allocation will make QVector a better
+ choice for use cases that do a lot of appending or inserting, because
+ QVector can allocate memory for many items in a single heap allocation.
Note that the internal array only ever gets bigger over the life
of the list. It never shrinks. The internal array is deallocated
@@ -401,9 +428,10 @@ void **QListData::erase(void **xi)
\snippet code/src_corelib_tools_qlistdata.cpp 2
- Because QList is implemented as an array of pointers, this
- operation is very fast (\l{constant time}). For read-only access,
- an alternative syntax is to use at():
+ Because QList is implemented as an array of pointers for types
+ that are larger than a pointer or are not movable, this operation
+ requires (\l{Algorithmic Complexity}{constant time}). For read-only
+ access, an alternative syntax is to use at():
\snippet code/src_corelib_tools_qlistdata.cpp 3
@@ -417,10 +445,10 @@ void **QListData::erase(void **xi)
\snippet code/src_corelib_tools_qlistdata.cpp 4
- Inserting and removing items at either ends of the list is very
- fast (\l{constant time} in most cases), because QList
- preallocates extra space on both sides of its internal buffer to
- allow for fast growth at both ends of the list.
+ Inserting and removing items at either end of the list is very
+ fast (\l{Algorithmic Complexity}{constant time} in most cases),
+ because QList preallocates extra space on both sides of its
+ internal buffer to allow for fast growth at both ends of the list.
If you want to find all occurrences of a particular value in a
list, use indexOf() or lastIndexOf(). The former searches forward
@@ -481,6 +509,11 @@ void **QListData::erase(void **xi)
\l{QStringList::removeDuplicates()}{removeDuplicates},
\l{QStringList::sort()}{sort}.
+ \section1 More Information on Using Qt Containers
+
+ For a detailed discussion comparing Qt containers with each other and
+ with STL containers, see \l {Understand the Qt Containers}.
+
\sa QListIterator, QMutableListIterator, QLinkedList, QVector
*/
@@ -512,10 +545,11 @@ void **QListData::erase(void **xi)
Constructs a copy of \a other.
- This operation takes \l{constant time}, because QList is
- \l{implicitly shared}. This makes returning a QList from a
- function very fast. If a shared instance is modified, it will be
- copied (copy-on-write), and that takes \l{linear time}.
+ This operation takes \l{Algorithmic Complexity}{constant time},
+ because QList is \l{implicitly shared}. This makes returning a
+ QList from a function very fast. If a shared instance is modified,
+ it will be copied (copy-on-write), and that takes
+ \l{Algorithmic Complexity}{linear time}.
\sa operator=()
*/
@@ -584,6 +618,65 @@ void **QListData::erase(void **xi)
\sa operator==()
*/
+/*! \fn bool operator<(const QList<T> &lhs, const QList<T> &rhs)
+ \since 5.6
+ \relates QList
+
+ Returns \c true if list \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically less than} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator<=(const QList<T> &lhs, const QList<T> &rhs)
+ \since 5.6
+ \relates QList
+
+ Returns \c true if list \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically less than or equal to} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator>(const QList<T> &lhs, const QList<T> &rhs)
+ \since 5.6
+ \relates QList
+
+ Returns \c true if list \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically greater than} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator>=(const QList<T> &lhs, const QList<T> &rhs)
+ \since 5.6
+ \relates QList
+
+ Returns \c true if list \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically greater than or equal to} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*!
+ \fn uint qHash(const QList<T> &key, uint seed = 0)
+ \since 5.6
+ \relates QList
+
+ Returns the hash value for \a key,
+ using \a seed to seed the calculation.
+
+ This function requires qHash() to be overloaded for the value type \c T.
+*/
+
/*!
\fn int QList::size() const
@@ -641,7 +734,7 @@ void **QListData::erase(void **xi)
Returns the item at index position \a i in the list. \a i must be
a valid index position in the list (i.e., 0 <= \a i < size()).
- This function is very fast (\l{constant time}).
+ This function is very fast (\l{Algorithmic Complexity}{constant time}).
\sa value(), operator[]()
*/
@@ -654,8 +747,8 @@ void **QListData::erase(void **xi)
If this function is called on a list that is currently being shared, it
will trigger a copy of all elements. Otherwise, this function runs in
- \l{constant time}. If you do not want to modify the list you should use
- QList::at().
+ \l{Algorithmic Complexity}{constant time}. If you do not want to modify
+ the list you should use QList::at().
\sa at(), value()
*/
@@ -664,7 +757,7 @@ void **QListData::erase(void **xi)
\overload
- Same as at(). This function runs in \l{constant time}.
+ Same as at(). This function runs in \l{Algorithmic Complexity}{constant time}.
*/
/*! \fn QList::reserve(int alloc)
@@ -690,9 +783,9 @@ void **QListData::erase(void **xi)
This is the same as list.insert(size(), \a value).
If this list is not shared, this operation is typically
- very fast (amortized \l{constant time}), because QList
- preallocates extra space on both sides of its internal
- buffer to allow for fast growth at both ends of the list.
+ very fast (amortized \l{Algorithmic Complexity}{constant time}),
+ because QList preallocates extra space on both sides of its
+ internal buffer to allow for fast growth at both ends of the list.
\sa operator<<(), prepend(), insert()
*/
@@ -718,9 +811,9 @@ void **QListData::erase(void **xi)
This is the same as list.insert(0, \a value).
If this list is not shared, this operation is typically
- very fast (amortized \l{constant time}), because QList
- preallocates extra space on both sides of its internal
- buffer to allow for fast growth at both ends of the list.
+ very fast (amortized \l{Algorithmic Complexity}{constant time}),
+ because QList preallocates extra space on both sides of its
+ internal buffer to allow for fast growth at both ends of the list.
\sa append(), insert()
*/
@@ -811,7 +904,8 @@ void **QListData::erase(void **xi)
same as takeAt(0). This function assumes the list is not empty. To
avoid failure, call isEmpty() before calling this function.
- If this list is not shared, this operation takes \l{constant time}.
+ If this list is not shared, this operation takes
+ \l {Algorithmic Complexity}{constant time}.
If you don't use the return value, removeFirst() is more
efficient.
@@ -826,7 +920,8 @@ void **QListData::erase(void **xi)
not empty. To avoid failure, call isEmpty() before calling this
function.
- If this list is not shared, this operation takes \l{constant time}.
+ If this list is not shared, this operation takes
+ \l {Algorithmic Complexity}{constant time}.
If you don't use the return value, removeLast() is more
efficient.
@@ -1000,6 +1095,52 @@ void **QListData::erase(void **xi)
\sa constBegin(), end()
*/
+/*! \fn QList::reverse_iterator QList::rbegin()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ item in the list, in reverse order.
+
+ \sa begin(), crbegin(), rend()
+*/
+
+/*! \fn QList::const_reverse_iterator QList::rbegin() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QList::const_reverse_iterator QList::crbegin() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ item in the list, in reverse order.
+
+ \sa begin(), rbegin(), rend()
+*/
+
+/*! \fn QList::reverse_iterator QList::rend()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past
+ the last item in the list, in reverse order.
+
+ \sa end(), crend(), rbegin()
+*/
+
+/*! \fn QList::const_reverse_iterator QList::rend() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QList::const_reverse_iterator QList::crend() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one
+ past the last item in the list, in reverse order.
+
+ \sa end(), rend(), rbegin()
+*/
+
/*! \fn QList::iterator QList::erase(iterator pos)
Removes the item associated with the iterator \a pos from the
@@ -1070,6 +1211,38 @@ void **QListData::erase(void **xi)
Typedef for const T &. Provided for STL compatibility.
*/
+/*! \typedef QList::reverse_iterator
+ \since 5.6
+
+ The QList::reverse_iterator typedef provides an STL-style non-const
+ reverse iterator for QList.
+
+ It is simply a typedef for \c{std::reverse_iterator<iterator>}.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
+ \sa QList::rbegin(), QList::rend(), QList::const_reverse_iterator, QList::iterator
+*/
+
+/*! \typedef QList::const_reverse_iterator
+ \since 5.6
+
+ The QList::const_reverse_iterator typedef provides an STL-style const
+ reverse iterator for QList.
+
+ It is simply a typedef for \c{std::reverse_iterator<const_iterator>}.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
+ \sa QList::rbegin(), QList::rend(), QList::reverse_iterator, QList::const_iterator
+*/
+
/*! \fn int QList::count() const
Returns the number of items in the list. This is effectively the
@@ -1090,7 +1263,7 @@ void **QListData::erase(void **xi)
not be empty. If the list can be empty, call isEmpty() before
calling this function.
- \sa last(), isEmpty()
+ \sa constFirst(), last(), isEmpty()
*/
/*! \fn const T& QList::first() const
@@ -1098,13 +1271,23 @@ void **QListData::erase(void **xi)
\overload
*/
+/*! \fn const T& QList::constFirst() const
+ \since 5.6
+
+ Returns a const reference to the first item in the list. The list must
+ not be empty. If the list can be empty, call isEmpty() before
+ calling this function.
+
+ \sa constLast(), isEmpty(), first()
+*/
+
/*! \fn T& QList::last()
Returns a reference to the last item in the list. The list must
not be empty. If the list can be empty, call isEmpty() before
calling this function.
- \sa first(), isEmpty()
+ \sa constLast(), first(), isEmpty()
*/
/*! \fn const T& QList::last() const
@@ -1112,6 +1295,16 @@ void **QListData::erase(void **xi)
\overload
*/
+/*! \fn const T& QList::constLast() const
+ \since 5.6
+
+ Returns a reference to the last item in the list. The list must
+ not be empty. If the list can be empty, call isEmpty() before
+ calling this function.
+
+ \sa constFirst(), isEmpty(), last()
+*/
+
/*! \fn void QList::removeFirst()
Removes the first item in the list. Calling this function is
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index f5ff952f97..32e0141d55 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -38,6 +38,7 @@
#include <QtCore/qiterator.h>
#include <QtCore/qrefcount.h>
#include <QtCore/qarraydata.h>
+#include <QtCore/qhashfunctions.h>
#include <iterator>
#include <list>
@@ -89,6 +90,7 @@ struct Q_CORE_EXPORT QListData {
Data *detach(int alloc);
Data *detach_grow(int *i, int n);
void realloc(int alloc);
+ void realloc_grow(int growth);
inline void dispose() { dispose(d); }
static void dispose(Data *d);
static const Data shared_null;
@@ -102,11 +104,11 @@ struct Q_CORE_EXPORT QListData {
void remove(int i);
void remove(int i, int n);
void move(int from, int to);
- inline int size() const { return d->end - d->begin; }
- inline bool isEmpty() const { return d->end == d->begin; }
- inline void **at(int i) const { return d->array + d->begin + i; }
- inline void **begin() const { return d->array + d->begin; }
- inline void **end() const { return d->array + d->end; }
+ inline int size() const Q_DECL_NOTHROW { return d->end - d->begin; }
+ inline bool isEmpty() const Q_DECL_NOTHROW { return d->end == d->begin; }
+ inline void **at(int i) const Q_DECL_NOTHROW { return d->array + d->begin + i; }
+ inline void **begin() const Q_DECL_NOTHROW { return d->array + d->begin; }
+ inline void **end() const Q_DECL_NOTHROW { return d->array + d->end; }
};
template <typename T>
@@ -143,7 +145,7 @@ public:
#ifdef Q_COMPILER_RVALUE_REFS
inline QList(QList<T> &&other) : d(other.d) { other.d = const_cast<QListData::Data *>(&QListData::shared_null); }
inline QList &operator=(QList<T> &&other)
- { qSwap(d, other.d); return *this; }
+ { QList moved(std::move(other)); swap(moved); return *this; }
#endif
inline void swap(QList<T> &other) { qSwap(d, other.d); }
#ifdef Q_COMPILER_INITIALIZER_LISTS
@@ -154,7 +156,7 @@ public:
bool operator==(const QList<T> &l) const;
inline bool operator!=(const QList<T> &l) const { return !(*this == l); }
- inline int size() const { return p.size(); }
+ inline int size() const Q_DECL_NOTHROW { return p.size(); }
inline void detach() { if (d->ref.isShared()) detach_helper(); }
@@ -177,9 +179,9 @@ public:
d->ref.setSharable(sharable);
}
#endif
- inline bool isSharedWith(const QList<T> &other) const { return d == other.d; }
+ inline bool isSharedWith(const QList<T> &other) const Q_DECL_NOTHROW { return d == other.d; }
- inline bool isEmpty() const { return p.isEmpty(); }
+ inline bool isEmpty() const Q_DECL_NOTHROW { return p.isEmpty(); }
void clear();
@@ -218,30 +220,34 @@ public:
typedef T *pointer;
typedef T &reference;
- inline iterator() : i(0) {}
- inline iterator(Node *n) : i(n) {}
- inline iterator(const iterator &o): i(o.i){}
+ inline iterator() Q_DECL_NOTHROW : i(Q_NULLPTR) {}
+ inline iterator(Node *n) Q_DECL_NOTHROW : i(n) {}
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ // can't remove it in Qt 5, since doing so would make the type trivial,
+ // which changes the way it's passed to functions by value.
+ inline iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i){}
+#endif
inline T &operator*() const { return i->t(); }
inline T *operator->() const { return &i->t(); }
inline T &operator[](difference_type j) const { return i[j].t(); }
- inline bool operator==(const iterator &o) const { return i == o.i; }
- inline bool operator!=(const iterator &o) const { return i != o.i; }
- inline bool operator<(const iterator& other) const { return i < other.i; }
- inline bool operator<=(const iterator& other) const { return i <= other.i; }
- inline bool operator>(const iterator& other) const { return i > other.i; }
- inline bool operator>=(const iterator& other) const { return i >= other.i; }
+ inline bool operator==(const iterator &o) const Q_DECL_NOTHROW { return i == o.i; }
+ inline bool operator!=(const iterator &o) const Q_DECL_NOTHROW { return i != o.i; }
+ inline bool operator<(const iterator& other) const Q_DECL_NOTHROW { return i < other.i; }
+ inline bool operator<=(const iterator& other) const Q_DECL_NOTHROW { return i <= other.i; }
+ inline bool operator>(const iterator& other) const Q_DECL_NOTHROW { return i > other.i; }
+ inline bool operator>=(const iterator& other) const Q_DECL_NOTHROW { return i >= other.i; }
#ifndef QT_STRICT_ITERATORS
- inline bool operator==(const const_iterator &o) const
+ inline bool operator==(const const_iterator &o) const Q_DECL_NOTHROW
{ return i == o.i; }
- inline bool operator!=(const const_iterator &o) const
+ inline bool operator!=(const const_iterator &o) const Q_DECL_NOTHROW
{ return i != o.i; }
- inline bool operator<(const const_iterator& other) const
+ inline bool operator<(const const_iterator& other) const Q_DECL_NOTHROW
{ return i < other.i; }
- inline bool operator<=(const const_iterator& other) const
+ inline bool operator<=(const const_iterator& other) const Q_DECL_NOTHROW
{ return i <= other.i; }
- inline bool operator>(const const_iterator& other) const
+ inline bool operator>(const const_iterator& other) const Q_DECL_NOTHROW
{ return i > other.i; }
- inline bool operator>=(const const_iterator& other) const
+ inline bool operator>=(const const_iterator& other) const Q_DECL_NOTHROW
{ return i >= other.i; }
#endif
inline iterator &operator++() { ++i; return *this; }
@@ -266,23 +272,27 @@ public:
typedef const T *pointer;
typedef const T &reference;
- inline const_iterator() : i(0) {}
- inline const_iterator(Node *n) : i(n) {}
- inline const_iterator(const const_iterator &o): i(o.i) {}
+ inline const_iterator() Q_DECL_NOTHROW : i(Q_NULLPTR) {}
+ inline const_iterator(Node *n) Q_DECL_NOTHROW : i(n) {}
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ // can't remove it in Qt 5, since doing so would make the type trivial,
+ // which changes the way it's passed to functions by value.
+ inline const_iterator(const const_iterator &o) Q_DECL_NOTHROW : i(o.i) {}
+#endif
#ifdef QT_STRICT_ITERATORS
- inline explicit const_iterator(const iterator &o): i(o.i) {}
+ inline explicit const_iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i) {}
#else
- inline const_iterator(const iterator &o): i(o.i) {}
+ inline const_iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i) {}
#endif
inline const T &operator*() const { return i->t(); }
inline const T *operator->() const { return &i->t(); }
inline const T &operator[](difference_type j) const { return i[j].t(); }
- inline bool operator==(const const_iterator &o) const { return i == o.i; }
- inline bool operator!=(const const_iterator &o) const { return i != o.i; }
- inline bool operator<(const const_iterator& other) const { return i < other.i; }
- inline bool operator<=(const const_iterator& other) const { return i <= other.i; }
- inline bool operator>(const const_iterator& other) const { return i > other.i; }
- inline bool operator>=(const const_iterator& other) const { return i >= other.i; }
+ inline bool operator==(const const_iterator &o) const Q_DECL_NOTHROW { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const Q_DECL_NOTHROW { return i != o.i; }
+ inline bool operator<(const const_iterator& other) const Q_DECL_NOTHROW { return i < other.i; }
+ inline bool operator<=(const const_iterator& other) const Q_DECL_NOTHROW { return i <= other.i; }
+ inline bool operator>(const const_iterator& other) const Q_DECL_NOTHROW { return i > other.i; }
+ inline bool operator>=(const const_iterator& other) const Q_DECL_NOTHROW { return i >= other.i; }
inline const_iterator &operator++() { ++i; return *this; }
inline const_iterator operator++(int) { Node *n = i; ++i; return n; }
inline const_iterator &operator--() { i--; return *this; }
@@ -296,14 +306,22 @@ public:
friend class const_iterator;
// stl style
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
inline iterator begin() { detach(); return reinterpret_cast<Node *>(p.begin()); }
- inline const_iterator begin() const { return reinterpret_cast<Node *>(p.begin()); }
- inline const_iterator cbegin() const { return reinterpret_cast<Node *>(p.begin()); }
- inline const_iterator constBegin() const { return reinterpret_cast<Node *>(p.begin()); }
+ inline const_iterator begin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); }
+ inline const_iterator cbegin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); }
+ inline const_iterator constBegin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); }
inline iterator end() { detach(); return reinterpret_cast<Node *>(p.end()); }
- inline const_iterator end() const { return reinterpret_cast<Node *>(p.end()); }
- inline const_iterator cend() const { return reinterpret_cast<Node *>(p.end()); }
- inline const_iterator constEnd() const { return reinterpret_cast<Node *>(p.end()); }
+ inline const_iterator end() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); }
+ inline const_iterator cend() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); }
+ inline const_iterator constEnd() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
+ const_reverse_iterator crend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
iterator insert(iterator before, const T &t);
iterator erase(iterator pos);
iterator erase(iterator first, iterator last);
@@ -314,9 +332,11 @@ public:
inline int count() const { return p.size(); }
inline int length() const { return p.size(); } // Same as count()
inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
+ inline const T& constFirst() const { return first(); }
inline const T& first() const { Q_ASSERT(!isEmpty()); return at(0); }
T& last() { Q_ASSERT(!isEmpty()); return *(--end()); }
const T& last() const { Q_ASSERT(!isEmpty()); return at(count() - 1); }
+ inline const T& constLast() const { return last(); }
inline void removeFirst() { Q_ASSERT(!isEmpty()); erase(begin()); }
inline void removeLast() { Q_ASSERT(!isEmpty()); erase(--end()); }
inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
@@ -378,7 +398,7 @@ private:
void node_copy(Node *from, Node *to, Node *src);
void node_destruct(Node *from, Node *to);
- bool isValidIterator(const iterator &i) const
+ bool isValidIterator(const iterator &i) const Q_DECL_NOTHROW
{
return (constBegin().i <= i.i) && (i.i <= constEnd().i);
}
@@ -1020,6 +1040,43 @@ inline int QList<T>::count_impl(const T &t, QListData::ArrayCompatibleLayout) co
Q_DECLARE_SEQUENTIAL_ITERATOR(List)
Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List)
+template <typename T>
+uint qHash(const QList<T> &key, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHashRange(key.cbegin(), key.cend(), seed)))
+{
+ return qHashRange(key.cbegin(), key.cend(), seed);
+}
+
+template <typename T>
+bool operator<(const QList<T> &lhs, const QList<T> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(),
+ rhs.begin(), rhs.end())))
+{
+ return std::lexicographical_compare(lhs.begin(), lhs.end(),
+ rhs.begin(), rhs.end());
+}
+
+template <typename T>
+inline bool operator>(const QList<T> &lhs, const QList<T> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return rhs < lhs;
+}
+
+template <typename T>
+inline bool operator<=(const QList<T> &lhs, const QList<T> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return !(lhs > rhs);
+}
+
+template <typename T>
+inline bool operator>=(const QList<T> &lhs, const QList<T> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return !(lhs < rhs);
+}
+
QT_END_NAMESPACE
#include <QtCore/qbytearraylist.h>
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 824b70c3fd..703341cc36 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -42,6 +42,7 @@
#include "qdatastream.h"
#include "qdebug.h"
+#include "qhashfunctions.h"
#include "qstring.h"
#include "qlocale.h"
#include "qlocale_p.h"
@@ -420,7 +421,7 @@ bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QSt
state = ScriptState;
break;
case ScriptState: {
- QString scripts = QString::fromLatin1((const char *)script_code_list, sizeof(script_code_list));
+ QString scripts = QString::fromLatin1((const char *)script_code_list, sizeof(script_code_list) - 1);
if (value.length() == 4 && scripts.indexOf(value) % 4 == 0) {
// script name is always 4 characters
script = value;
@@ -866,6 +867,21 @@ bool QLocale::operator!=(const QLocale &other) const
}
/*!
+ \since 5.6
+ \relates QLocale
+
+ Returns the hash value for \a key, using
+ \a seed to seed the calculation.
+*/
+uint qHash(const QLocale &key, uint seed) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.d->m_data);
+ seed = hash(seed, key.d->m_numberOptions);
+ return seed;
+}
+
+/*!
\since 4.2
Sets the \a options related to number conversions for this
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 61574ba44f..0cbfa6710c 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE
class QDataStream;
class QDate;
class QDateTime;
+class QLocale;
class QTime;
class QVariant;
class QTextStream;
@@ -52,6 +53,8 @@ class QTextStreamPrivate;
class QLocalePrivate;
+Q_CORE_EXPORT uint qHash(const QLocale &key, uint seed = 0) Q_DECL_NOTHROW;
+
class Q_CORE_EXPORT QLocale
{
Q_GADGET
@@ -868,23 +871,23 @@ public:
QString nativeLanguageName() const;
QString nativeCountryName() const;
- short toShort(const QString &s, bool *ok = 0) const;
- ushort toUShort(const QString &s, bool *ok = 0) const;
- int toInt(const QString &s, bool *ok = 0) const;
- uint toUInt(const QString &s, bool *ok = 0) const;
- qlonglong toLongLong(const QString &s, bool *ok = 0) const;
- qulonglong toULongLong(const QString &s, bool *ok = 0) const;
- float toFloat(const QString &s, bool *ok = 0) const;
- double toDouble(const QString &s, bool *ok = 0) const;
-
- short toShort(const QStringRef &s, bool *ok = 0) const;
- ushort toUShort(const QStringRef &s, bool *ok = 0) const;
- int toInt(const QStringRef &s, bool *ok = 0) const;
- uint toUInt(const QStringRef &s, bool *ok = 0) const;
- qlonglong toLongLong(const QStringRef &s, bool *ok = 0) const;
- qulonglong toULongLong(const QStringRef &s, bool *ok = 0) const;
- float toFloat(const QStringRef &s, bool *ok = 0) const;
- double toDouble(const QStringRef &s, bool *ok = 0) const;
+ short toShort(const QString &s, bool *ok = Q_NULLPTR) const;
+ ushort toUShort(const QString &s, bool *ok = Q_NULLPTR) const;
+ int toInt(const QString &s, bool *ok = Q_NULLPTR) const;
+ uint toUInt(const QString &s, bool *ok = Q_NULLPTR) const;
+ qlonglong toLongLong(const QString &s, bool *ok = Q_NULLPTR) const;
+ qulonglong toULongLong(const QString &s, bool *ok = Q_NULLPTR) const;
+ float toFloat(const QString &s, bool *ok = Q_NULLPTR) const;
+ double toDouble(const QString &s, bool *ok = Q_NULLPTR) const;
+
+ short toShort(const QStringRef &s, bool *ok = Q_NULLPTR) const;
+ ushort toUShort(const QStringRef &s, bool *ok = Q_NULLPTR) const;
+ int toInt(const QStringRef &s, bool *ok = Q_NULLPTR) const;
+ uint toUInt(const QStringRef &s, bool *ok = Q_NULLPTR) const;
+ qlonglong toLongLong(const QStringRef &s, bool *ok = Q_NULLPTR) const;
+ qulonglong toULongLong(const QStringRef &s, bool *ok = Q_NULLPTR) const;
+ float toFloat(const QStringRef &s, bool *ok = Q_NULLPTR) const;
+ double toDouble(const QStringRef &s, bool *ok = Q_NULLPTR) const;
QString toString(qlonglong i) const;
QString toString(qulonglong i) const;
@@ -979,6 +982,8 @@ public:
private:
QLocale(QLocalePrivate &dd);
friend class QLocalePrivate;
+ friend Q_CORE_EXPORT uint qHash(const QLocale &key, uint seed) Q_DECL_NOTHROW;
+
QSharedDataPointer<QLocalePrivate> d;
};
Q_DECLARE_TYPEINFO(QLocale, Q_MOVABLE_TYPE);
diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm
index 37a63a2ca4..c0818f07d7 100644
--- a/src/corelib/tools/qlocale_mac.mm
+++ b/src/corelib/tools/qlocale_mac.mm
@@ -44,18 +44,6 @@
QT_BEGIN_NAMESPACE
-namespace {
-class AutoReleasePool
-{
-public:
- AutoReleasePool(): pool([[NSAutoreleasePool alloc] init]) {}
- ~AutoReleasePool() { [pool release]; }
-
-private:
- NSAutoreleasePool *pool;
-};
-}
-
/******************************************************************************
** Wrappers for Mac locale system functions
*/
@@ -426,7 +414,7 @@ QLocale QSystemLocale::fallbackUiLocale() const
QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
{
- AutoReleasePool pool;
+ QMacAutoReleasePool pool;
switch(type) {
// case Name:
// return getMacLocaleName();
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 430f95dcda..b3fd7a96b8 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -122,6 +122,8 @@ private:
QSystemLocale(bool);
friend class QSystemLocaleSingleton;
};
+Q_DECLARE_TYPEINFO(QSystemLocale::QueryType, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QSystemLocale::CurrencyToStringArgument, Q_MOVABLE_TYPE);
#endif
#ifdef QT_USE_ICU
@@ -153,6 +155,7 @@ struct QLocaleId
ushort language_id, script_id, country_id;
};
+Q_DECLARE_TYPEINFO(QLocaleId, Q_PRIMITIVE_TYPE);
struct QLocaleData
{
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 1b7a8007cd..e49a1a098d 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -858,6 +858,15 @@ void QMapDataBase::freeData(QMapDataBase *d)
\sa begin(), constEnd()
*/
+/*! \fn QMap::key_iterator QMap::keyBegin() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first key
+ in the map.
+
+ \sa keyEnd(), firstKey()
+*/
+
/*! \fn QMap::iterator QMap::end()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
@@ -888,6 +897,15 @@ void QMapDataBase::freeData(QMapDataBase *d)
\sa constBegin(), end()
*/
+/*! \fn QMap::key_iterator QMap::keyEnd() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
+ item after the last key in the map.
+
+ \sa keyBegin(), lastKey()
+*/
+
/*! \fn const Key &QMap::firstKey() const
\since 5.2
@@ -896,7 +914,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
This executes in \l{constant time}.
- \sa lastKey(), first(), isEmpty()
+ \sa lastKey(), first(), keyBegin(), isEmpty()
*/
/*! \fn const Key &QMap::lastKey() const
@@ -907,7 +925,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
This executes in \l{logarithmic time}.
- \sa firstKey(), last(), isEmpty()
+ \sa firstKey(), last(), keyEnd(), isEmpty()
*/
/*! \fn T &QMap::first()
@@ -1161,6 +1179,12 @@ void QMapDataBase::freeData(QMapDataBase *d)
are stored under \a key.
*/
+/*!
+ \fn QPair<const_iterator, const_iterator> QMap::equal_range(const Key &key) const
+ \overload
+ \since 5.6
+*/
+
/*! \class QMap::iterator
\inmodule QtCore
@@ -1229,7 +1253,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
while iterators are active on that container. For more information,
read \l{Implicit sharing iterator problem}.
- \sa QMap::const_iterator, QMutableMapIterator
+ \sa QMap::const_iterator, QMap::key_iterator, QMutableMapIterator
*/
/*! \typedef QMap::iterator::difference_type
@@ -1452,7 +1476,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
while iterators are active on that container. For more information,
read \l{Implicit sharing iterator problem}.
- \sa QMap::iterator, QMapIterator
+ \sa QMap::iterator, QMap::key_iterator, QMapIterator
*/
/*! \typedef QMap::const_iterator::difference_type
@@ -1628,6 +1652,134 @@ void QMapDataBase::freeData(QMapDataBase *d)
\sa operator+=(), operator-()
*/
+/*! \class QMap::key_iterator
+ \inmodule QtCore
+ \since 5.6
+ \brief The QMap::key_iterator class provides an STL-style const iterator for QMap and QMultiMap keys.
+
+ QMap::key_iterator is essentially the same as QMap::const_iterator
+ with the difference that operator*() and operator->() return a key
+ instead of a value.
+
+ For most uses QMap::iterator and QMap::const_iterator should be used,
+ you can easily access the key by calling QMap::iterator::key():
+
+ \snippet code/src_corelib_tools_qmap.cpp keyiterator1
+
+ However, to have interoperability between QMap's keys and STL-style
+ algorithms we need an iterator that dereferences to a key instead
+ of a value. With QMap::key_iterator we can apply an algorithm to a
+ range of keys without having to call QMap::keys(), which is inefficient
+ as it costs one QMap iteration and memory allocation to create a temporary
+ QList.
+
+ \snippet code/src_corelib_tools_qmap.cpp keyiterator2
+
+ QMap::key_iterator is const, it's not possible to modify the key.
+
+ The default QMap::key_iterator constructor creates an uninitialized
+ iterator. You must initialize it using a QMap function like
+ QMap::keyBegin() or QMap::keyEnd().
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
+ \sa QMap::const_iterator, QMap::iterator
+*/
+
+/*! \typedef QMap::key_iterator::difference_type
+ \internal
+*/
+
+/*! \typedef QMap::key_iterator::iterator_category
+ \internal
+*/
+
+/*! \typedef QMap::key_iterator::pointer
+ \internal
+*/
+
+/*! \typedef QMap::key_iterator::reference
+ \internal
+*/
+
+/*! \typedef QMap::key_iterator::value_type
+ \internal
+*/
+
+/*! \fn const T &QMap::key_iterator::operator*() const
+
+ Returns the current item's key.
+*/
+
+/*! \fn const T *QMap::key_iterator::operator->() const
+
+ Returns a pointer to the current item's key.
+*/
+
+/*! \fn bool QMap::key_iterator::operator==(key_iterator other) const
+
+ Returns \c true if \a other points to the same item as this
+ iterator; otherwise returns \c false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QMap::key_iterator::operator!=(key_iterator other) const
+
+ Returns \c true if \a other points to a different item than this
+ iterator; otherwise returns \c false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn QMap::key_iterator &QMap::key_iterator::operator++()
+
+ The prefix ++ operator (\c{++i}) advances the iterator to the
+ next item in the hash and returns an iterator to the new current
+ item.
+
+ Calling this function on QMap::keyEnd() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QMap::key_iterator QMap::key_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator (\c{i++}) advances the iterator to the
+ next item in the hash and returns an iterator to the previous
+ item.
+*/
+
+/*! \fn QMap::key_iterator &QMap::key_iterator::operator--()
+
+ The prefix -- operator (\c{--i}) makes the preceding item
+ current and returns an iterator pointing to the new current item.
+
+ Calling this function on QMap::keyBegin() leads to undefined
+ results.
+
+ \sa operator++()
+*/
+
+/*! \fn QMap::key_iterator QMap::key_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator (\c{i--}) makes the preceding item
+ current and returns an iterator pointing to the previous
+ item.
+*/
+
+/*! \fn const_iterator QMap::key_iterator::base() const
+ Returns the underlying const_iterator this key_iterator is based on.
+*/
+
/*! \fn QDataStream &operator<<(QDataStream &out, const QMap<Key, T> &map)
\relates QMap
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 1f80e8f0f4..b7bd268bda 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -38,6 +38,7 @@
#include <QtCore/qlist.h>
#include <QtCore/qrefcount.h>
#include <QtCore/qpair.h>
+#include <QtCore/qtypetraits.h>
#ifdef Q_MAP_DEBUG
#include <QtCore/qdebug.h>
@@ -94,6 +95,13 @@ struct Q_CORE_EXPORT QMapNodeBase
void setColor(Color c) { if (c == Black) p |= Black; else p &= ~Black; }
QMapNodeBase *parent() const { return reinterpret_cast<QMapNodeBase *>(p & ~Mask); }
void setParent(QMapNodeBase *pp) { p = (p & Mask) | quintptr(pp); }
+
+ template <typename T>
+ static typename QtPrivate::QEnableIf<QTypeInfo<T>::isComplex>::Type
+ callDestructorIfNecessary(T &t) Q_DECL_NOTHROW { Q_UNUSED(t); t.~T(); } // Q_UNUSED: silence MSVC unused 't' warning
+ template <typename T>
+ static typename QtPrivate::QEnableIf<!QTypeInfo<T>::isComplex>::Type
+ callDestructorIfNecessary(T &) Q_DECL_NOTHROW {}
};
template <class Key, class T>
@@ -112,12 +120,26 @@ struct QMapNode : public QMapNodeBase
QMapNode<Key, T> *copy(QMapData<Key, T> *d) const;
- void destroySubTree();
+ void destroySubTree()
+ {
+ callDestructorIfNecessary(key);
+ callDestructorIfNecessary(value);
+ doDestroySubTree(QtPrivate::integral_constant<bool, QTypeInfo<T>::isComplex || QTypeInfo<Key>::isComplex>());
+ }
QMapNode<Key, T> *lowerBound(const Key &key);
QMapNode<Key, T> *upperBound(const Key &key);
private:
+ void doDestroySubTree(QtPrivate::false_type) {}
+ void doDestroySubTree(QtPrivate::true_type)
+ {
+ if (left)
+ leftNode()->destroySubTree();
+ if (right)
+ rightNode()->destroySubTree();
+ }
+
QMapNode() Q_DECL_EQ_DELETE;
Q_DISABLE_COPY(QMapNode)
};
@@ -126,7 +148,7 @@ template <class Key, class T>
inline QMapNode<Key, T> *QMapNode<Key, T>::lowerBound(const Key &akey)
{
QMapNode<Key, T> *n = this;
- QMapNode<Key, T> *lastNode = 0;
+ QMapNode<Key, T> *lastNode = Q_NULLPTR;
while (n) {
if (!qMapLessThanKey(n->key, akey)) {
lastNode = n;
@@ -142,7 +164,7 @@ template <class Key, class T>
inline QMapNode<Key, T> *QMapNode<Key, T>::upperBound(const Key &akey)
{
QMapNode<Key, T> *n = this;
- QMapNode<Key, T> *lastNode = 0;
+ QMapNode<Key, T> *lastNode = Q_NULLPTR;
while (n) {
if (qMapLessThanKey(akey, n->key)) {
lastNode = n;
@@ -194,7 +216,7 @@ struct QMapData : public QMapDataBase
Node *findNode(const Key &akey) const;
void nodeRange(const Key &akey, Node **firstNode, Node **lastNode);
- Node *createNode(const Key &k, const T &v, Node *parent = 0, bool left = false)
+ Node *createNode(const Key &k, const T &v, Node *parent = Q_NULLPTR, bool left = false)
{
Node *n = static_cast<Node *>(QMapDataBase::createNode(sizeof(Node), Q_ALIGNOF(Node),
parent, left));
@@ -235,48 +257,22 @@ QMapNode<Key, T> *QMapNode<Key, T>::copy(QMapData<Key, T> *d) const
n->left = leftNode()->copy(d);
n->left->setParent(n);
} else {
- n->left = 0;
+ n->left = Q_NULLPTR;
}
if (right) {
n->right = rightNode()->copy(d);
n->right->setParent(n);
} else {
- n->right = 0;
+ n->right = Q_NULLPTR;
}
return n;
}
-#if defined(Q_CC_MSVC)
-#pragma warning( push )
-#pragma warning( disable : 4127 ) // conditional expression is constant
-#endif
-
-template <class Key, class T>
-void QMapNode<Key, T>::destroySubTree()
-{
- if (QTypeInfo<Key>::isComplex)
- key.~Key();
- if (QTypeInfo<T>::isComplex)
- value.~T();
- if (QTypeInfo<Key>::isComplex || QTypeInfo<T>::isComplex) {
- if (left)
- leftNode()->destroySubTree();
- if (right)
- rightNode()->destroySubTree();
- }
-}
-
-#if defined(Q_CC_MSVC)
-#pragma warning( pop )
-#endif
-
template <class Key, class T>
void QMapData<Key, T>::deleteNode(QMapNode<Key, T> *z)
{
- if (QTypeInfo<Key>::isComplex)
- z->key.~Key();
- if (QTypeInfo<T>::isComplex)
- z->value.~T();
+ QMapNodeBase::callDestructorIfNecessary(z->key);
+ QMapNodeBase::callDestructorIfNecessary(z->value);
freeNodeAndRebalance(z);
}
@@ -288,7 +284,7 @@ QMapNode<Key, T> *QMapData<Key, T>::findNode(const Key &akey) const
if (lb && !qMapLessThanKey(akey, lb->key))
return lb;
}
- return 0;
+ return Q_NULLPTR;
}
@@ -304,10 +300,10 @@ void QMapData<Key, T>::nodeRange(const Key &akey, QMapNode<Key, T> **firstNode,
} else if (qMapLessThanKey(n->key, akey)) {
n = n->rightNode();
} else {
- *firstNode = n->leftNode() ? n->leftNode()->lowerBound(akey) : 0;
+ *firstNode = n->leftNode() ? n->leftNode()->lowerBound(akey) : Q_NULLPTR;
if (!*firstNode)
*firstNode = n;
- *lastNode = n->rightNode() ? n->rightNode()->upperBound(akey) : 0;
+ *lastNode = n->rightNode() ? n->rightNode()->upperBound(akey) : Q_NULLPTR;
if (!*lastNode)
*lastNode = l;
return;
@@ -348,7 +344,7 @@ public:
}
inline QMap<Key, T> &operator=(QMap<Key, T> &&other)
- { qSwap(d, other.d); return *this; }
+ { QMap moved(std::move(other)); swap(moved); return *this; }
#endif
inline void swap(QMap<Key, T> &other) { qSwap(d, other.d); }
explicit QMap(const typename std::map<Key, T> &other);
@@ -416,7 +412,7 @@ public:
typedef T *pointer;
typedef T &reference;
- inline iterator() : i(0) { }
+ inline iterator() : i(Q_NULLPTR) { }
inline iterator(Node *node) : i(node) { }
inline const Key &key() const { return i->key; }
@@ -473,7 +469,7 @@ public:
typedef const T *pointer;
typedef const T &reference;
- inline const_iterator() : i(0) { }
+ inline const_iterator() : i(Q_NULLPTR) { }
inline const_iterator(const Node *node) : i(node) { }
#ifdef QT_STRICT_ITERATORS
explicit inline const_iterator(const iterator &o)
@@ -522,6 +518,32 @@ public:
};
friend class const_iterator;
+ class key_iterator
+ {
+ const_iterator i;
+
+ public:
+ typedef typename const_iterator::iterator_category iterator_category;
+ typedef typename const_iterator::difference_type difference_type;
+ typedef Key value_type;
+ typedef const Key *pointer;
+ typedef const Key &reference;
+
+ explicit key_iterator(const_iterator o) : i(o) { }
+
+ const Key &operator*() const { return i.key(); }
+ const Key *operator->() const { return &i.key(); }
+ bool operator==(key_iterator o) const { return i == o.i; }
+ bool operator!=(key_iterator o) const { return i != o.i; }
+
+ inline key_iterator &operator++() { ++i; return *this; }
+ inline key_iterator operator++(int) { return key_iterator(i++);}
+ inline key_iterator &operator--() { --i; return *this; }
+ inline key_iterator operator--(int) { return key_iterator(i--); }
+ const_iterator base() const { return i; }
+ };
+
+
// STL style
inline iterator begin() { detach(); return iterator(d->begin()); }
inline const_iterator begin() const { return const_iterator(d->begin()); }
@@ -531,6 +553,8 @@ public:
inline const_iterator end() const { return const_iterator(d->end()); }
inline const_iterator constEnd() const { return const_iterator(d->end()); }
inline const_iterator cend() const { return const_iterator(d->end()); }
+ inline key_iterator keyBegin() const { return key_iterator(begin()); }
+ inline key_iterator keyEnd() const { return key_iterator(end()); }
iterator erase(iterator it);
// more Qt
@@ -557,6 +581,7 @@ public:
typedef int size_type;
inline bool empty() const { return isEmpty(); }
QPair<iterator, iterator> equal_range(const Key &akey);
+ QPair<const_iterator, const_iterator> equal_range(const Key &akey) const;
#ifdef Q_MAP_DEBUG
void dump() const;
@@ -653,7 +678,7 @@ Q_INLINE_TEMPLATE int QMap<Key, T>::count(const Key &akey) const
template <class Key, class T>
Q_INLINE_TEMPLATE bool QMap<Key, T>::contains(const Key &akey) const
{
- return d->findNode(akey) != 0;
+ return d->findNode(akey) != Q_NULLPTR;
}
template <class Key, class T>
@@ -662,7 +687,7 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insert(const Key
detach();
Node *n = d->root();
Node *y = d->end();
- Node *lastNode = 0;
+ Node *lastNode = Q_NULLPTR;
bool left = true;
while (n) {
y = n;
@@ -737,15 +762,15 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const K
}
// we need to insert (not overwrite)
- if (prev->right == 0) {
+ if (prev->right == Q_NULLPTR) {
Node *z = d->createNode(akey, avalue, prev, false);
return iterator(z);
}
- if (next->left == 0) {
+ if (next->left == Q_NULLPTR) {
Node *z = d->createNode(akey, avalue, next, true);
return iterator(z);
}
- Q_ASSERT(false); // We should have prev->right == 0 or next->left == 0.
+ Q_ASSERT(false); // We should have prev->right == Q_NULLPTR or next->left == Q_NULLPTR.
return this->insert(akey, avalue);
}
}
@@ -759,7 +784,7 @@ Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(cons
Node* y = d->end();
Node* x = static_cast<Node *>(d->root());
bool left = true;
- while (x != 0) {
+ while (x != Q_NULLPTR) {
left = !qMapLessThanKey(x->key, akey);
y = x;
x = left ? x->leftNode() : x->rightNode();
@@ -806,15 +831,15 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, co
return this->insertMulti(akey, avalue); // ignore hint
// Hint is ok - do insert
- if (prev->right == 0) {
+ if (prev->right == Q_NULLPTR) {
Node *z = d->createNode(akey, avalue, prev, false);
return iterator(z);
}
- if (next->left == 0) {
+ if (next->left == Q_NULLPTR) {
Node *z = d->createNode(akey, avalue, next, true);
return iterator(z);
}
- Q_ASSERT(false); // We should have prev->right == 0 or next->left == 0.
+ Q_ASSERT(false); // We should have prev->right == Q_NULLPTR or next->left == Q_NULLPTR.
return this->insertMulti(akey, avalue);
}
}
@@ -864,6 +889,15 @@ QPair<typename QMap<Key, T>::iterator, typename QMap<Key, T>::iterator> QMap<Key
return QPair<iterator, iterator>(iterator(firstNode), iterator(lastNode));
}
+template <class Key, class T>
+QPair<typename QMap<Key, T>::const_iterator, typename QMap<Key, T>::const_iterator>
+QMap<Key, T>::equal_range(const Key &akey) const
+{
+ Node *firstNode, *lastNode;
+ d->nodeRange(akey, &firstNode, &lastNode);
+ return qMakePair(const_iterator(firstNode), const_iterator(lastNode));
+}
+
#ifdef Q_MAP_DEBUG
template <class Key, class T>
void QMap<Key, T>::dump() const
@@ -1051,7 +1085,7 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values(const Key &akey) const
template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator QMap<Key, T>::lowerBound(const Key &akey) const
{
- Node *lb = d->root() ? d->root()->lowerBound(akey) : 0;
+ Node *lb = d->root() ? d->root()->lowerBound(akey) : Q_NULLPTR;
if (!lb)
lb = d->end();
return const_iterator(lb);
@@ -1061,7 +1095,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::lowerBound(const Key &akey)
{
detach();
- Node *lb = d->root() ? d->root()->lowerBound(akey) : 0;
+ Node *lb = d->root() ? d->root()->lowerBound(akey) : Q_NULLPTR;
if (!lb)
lb = d->end();
return iterator(lb);
@@ -1071,7 +1105,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::const_iterator
QMap<Key, T>::upperBound(const Key &akey) const
{
- Node *ub = d->root() ? d->root()->upperBound(akey) : 0;
+ Node *ub = d->root() ? d->root()->upperBound(akey) : Q_NULLPTR;
if (!ub)
ub = d->end();
return const_iterator(ub);
@@ -1081,7 +1115,7 @@ template <class Key, class T>
Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::upperBound(const Key &akey)
{
detach();
- Node *ub = d->root() ? d->root()->upperBound(akey) : 0;
+ Node *ub = d->root() ? d->root()->upperBound(akey) : Q_NULLPTR;
if (!ub)
ub = d->end();
return iterator(ub);
diff --git a/src/corelib/tools/qqueue.cpp b/src/corelib/tools/qqueue.cpp
index 65b50c4e03..a8b5051616 100644
--- a/src/corelib/tools/qqueue.cpp
+++ b/src/corelib/tools/qqueue.cpp
@@ -71,19 +71,6 @@
*/
/*!
- \fn QQueue::QQueue()
-
- Constructs an empty queue.
-*/
-
-/*!
- \fn QQueue::~QQueue()
-
- Destroys the queue. References to the values in the queue, and all
- iterators over this queue, become invalid.
-*/
-
-/*!
\fn void QQueue::swap(QQueue<T> &other)
\since 4.8
diff --git a/src/corelib/tools/qqueue.h b/src/corelib/tools/qqueue.h
index 9d5bda1210..7a7abab070 100644
--- a/src/corelib/tools/qqueue.h
+++ b/src/corelib/tools/qqueue.h
@@ -43,8 +43,7 @@ template <class T>
class QQueue : public QList<T>
{
public:
- inline QQueue() {}
- inline ~QQueue() {}
+ // compiler-generated special member functions are fine!
inline void swap(QQueue<T> &other) { QList<T>::swap(other); } // prevent QList<->QQueue swaps
#ifndef Q_QDOC
// bring in QList::swap(int, int). We cannot say using QList<T>::swap,
diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp
index b2174745e4..847f650a70 100644
--- a/src/corelib/tools/qrect.cpp
+++ b/src/corelib/tools/qrect.cpp
@@ -2403,7 +2403,6 @@ QRect QRectF::toAlignedRect() const Q_DECL_NOTHROW
/*!
\fn QRectF QRectF::marginsAdded(const QMarginsF &margins) const
- \relates QRectF
\since 5.3
Returns a rectangle grown by the \a margins.
@@ -2413,7 +2412,6 @@ QRect QRectF::toAlignedRect() const Q_DECL_NOTHROW
/*!
\fn QRectF QRectF::marginsRemoved(const QMarginsF &margins) const
- \relates QRectF
\since 5.3
Removes the \a margins from the rectangle, shrinking it.
@@ -2423,7 +2421,6 @@ QRect QRectF::toAlignedRect() const Q_DECL_NOTHROW
/*!
\fn QRectF QRectF::operator+=(const QMarginsF &margins)
- \relates QRectF
\since 5.3
Adds the \a margins to the rectangle, growing it.
@@ -2433,7 +2430,6 @@ QRect QRectF::toAlignedRect() const Q_DECL_NOTHROW
/*!
\fn QRectF QRectF::operator-=(const QMarginsF &margins)
- \relates QRectF
\since 5.3
Returns a rectangle shrunk by the \a margins.
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index f896828e2e..c52e4b5a7c 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -38,6 +38,7 @@
#include "qcache.h"
#include "qdatastream.h"
#include "qdebug.h"
+#include "qhashfunctions.h"
#include "qlist.h"
#include "qmap.h"
#include "qmutex.h"
@@ -886,6 +887,15 @@ static bool operator==(const QRegExpEngineKey &key1, const QRegExpEngineKey &key
&& key1.cs == key2.cs;
}
+static uint qHash(const QRegExpEngineKey &key, uint seed = 0) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.pattern);
+ seed = hash(seed, key.patternSyntax);
+ seed = hash(seed, key.cs);
+ return seed;
+}
+
class QRegExpEngine;
//Q_DECLARE_TYPEINFO(QVector<int>, Q_MOVABLE_TYPE);
@@ -1019,9 +1029,6 @@ class QRegExpCharClass
{
public:
QRegExpCharClass();
- inline QRegExpCharClass(const QRegExpCharClass &cc) { operator=(cc); }
-
- QRegExpCharClass &operator=(const QRegExpCharClass &cc);
void clear();
bool negative() const { return n; }
@@ -2319,17 +2326,6 @@ QRegExpCharClass::QRegExpCharClass()
#endif
}
-QRegExpCharClass &QRegExpCharClass::operator=(const QRegExpCharClass &cc)
-{
- c = cc.c;
- r = cc.r;
- n = cc.n;
-#ifndef QT_NO_REGEXP_OPTIM
- occ1 = cc.occ1;
-#endif
- return *this;
-}
-
void QRegExpCharClass::clear()
{
c = 0;
@@ -3811,11 +3807,6 @@ struct QRegExpPrivate
};
#if !defined(QT_NO_REGEXP_OPTIM)
-uint qHash(const QRegExpEngineKey &key, uint seed = 0) Q_DECL_NOTHROW
-{
- return qHash(key.pattern, seed);
-}
-
typedef QCache<QRegExpEngineKey, QRegExpEngine> EngineCache;
Q_GLOBAL_STATIC(EngineCache, globalEngineCache)
static QBasicMutex globalEngineCacheMutex;
@@ -4037,6 +4028,21 @@ bool QRegExp::operator==(const QRegExp &rx) const
}
/*!
+ \since 5.6
+ \relates QRegExp
+
+ Returns the hash value for \a key, using
+ \a seed to seed the calculation.
+*/
+uint qHash(const QRegExp &key, uint seed) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.priv->engineKey);
+ seed = hash(seed, key.priv->minimal);
+ return seed;
+}
+
+/*!
\fn bool QRegExp::operator!=(const QRegExp &rx) const
Returns \c true if this regular expression is not equal to \a rx;
diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h
index b08a8bd282..f384e6c51f 100644
--- a/src/corelib/tools/qregexp.h
+++ b/src/corelib/tools/qregexp.h
@@ -45,6 +45,9 @@ QT_BEGIN_NAMESPACE
struct QRegExpPrivate;
class QStringList;
+class QRegExp;
+
+Q_CORE_EXPORT uint qHash(const QRegExp &key, uint seed = 0) Q_DECL_NOTHROW;
class Q_CORE_EXPORT QRegExp
{
@@ -104,6 +107,8 @@ public:
static QString escape(const QString &str);
+ friend Q_CORE_EXPORT uint qHash(const QRegExp &key, uint seed) Q_DECL_NOTHROW;
+
private:
QRegExpPrivate *priv;
};
diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp
index 070e68154f..d8b0bf6e9f 100644
--- a/src/corelib/tools/qregularexpression.cpp
+++ b/src/corelib/tools/qregularexpression.cpp
@@ -38,6 +38,7 @@
#ifndef QT_NO_REGULAREXPRESSION
#include <QtCore/qcoreapplication.h>
+#include <QtCore/qhashfunctions.h>
#include <QtCore/qmutex.h>
#include <QtCore/qvector.h>
#include <QtCore/qstringlist.h>
@@ -1842,6 +1843,21 @@ bool QRegularExpression::operator==(const QRegularExpression &re) const
*/
/*!
+ \since 5.6
+ \relates QRegularExpression
+
+ Returns the hash value for \a key, using
+ \a seed to seed the calculation.
+*/
+uint qHash(const QRegularExpression &key, uint seed) Q_DECL_NOTHROW
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.d->pattern);
+ seed = hash(seed, key.d->patternOptions);
+ return seed;
+}
+
+/*!
Escapes all characters of \a str so that they no longer have any special
meaning when used as a regular expression pattern string, and returns
the escaped string. For instance:
@@ -2109,7 +2125,8 @@ QStringRef QRegularExpressionMatch::capturedRef(const QString &name) const
QStringList QRegularExpressionMatch::capturedTexts() const
{
QStringList texts;
- for (int i = 0; i <= lastCapturedIndex(); ++i)
+ texts.reserve(d->capturedCount);
+ for (int i = 0; i < d->capturedCount; ++i)
texts << captured(i);
return texts;
}
diff --git a/src/corelib/tools/qregularexpression.h b/src/corelib/tools/qregularexpression.h
index d2abfc7701..2bca6a211b 100644
--- a/src/corelib/tools/qregularexpression.h
+++ b/src/corelib/tools/qregularexpression.h
@@ -49,6 +49,9 @@ QT_BEGIN_NAMESPACE
class QRegularExpressionMatch;
class QRegularExpressionMatchIterator;
struct QRegularExpressionPrivate;
+class QRegularExpression;
+
+Q_CORE_EXPORT uint qHash(const QRegularExpression &key, uint seed = 0) Q_DECL_NOTHROW;
class Q_CORE_EXPORT QRegularExpression
{
@@ -139,6 +142,7 @@ private:
friend class QRegularExpressionMatch;
friend struct QRegularExpressionMatchPrivate;
friend class QRegularExpressionMatchIterator;
+ friend Q_CORE_EXPORT uint qHash(const QRegularExpression &key, uint seed) Q_DECL_NOTHROW;
QRegularExpression(QRegularExpressionPrivate &dd);
QExplicitlySharedDataPointer<QRegularExpressionPrivate> d;
diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp
new file mode 100644
index 0000000000..85cfdaf129
--- /dev/null
+++ b/src/corelib/tools/qringbuffer.cpp
@@ -0,0 +1,314 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Alex Trotsenko <alex1973tr@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qringbuffer_p.h"
+#include "private/qbytearray_p.h"
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+
+ Access the bytes at a specified position the out-variable length will
+ contain the amount of bytes readable from there, e.g. the amount still
+ the same QByteArray
+*/
+const char *QRingBuffer::readPointerAtPosition(qint64 pos, qint64 &length) const
+{
+ if (pos >= 0) {
+ pos += head;
+ for (int i = 0; i < buffers.size(); ++i) {
+ length = (i == tailBuffer ? tail : buffers[i].size());
+ if (length > pos) {
+ length -= pos;
+ return buffers[i].constData() + pos;
+ }
+ pos -= length;
+ }
+ }
+
+ length = 0;
+ return 0;
+}
+
+void QRingBuffer::free(qint64 bytes)
+{
+ while (bytes > 0) {
+ const qint64 blockSize = buffers.first().size() - head;
+
+ if (tailBuffer == 0 || blockSize > bytes) {
+ // keep a single block around if it does not exceed
+ // the basic block size, to avoid repeated allocations
+ // between uses of the buffer
+ if (bufferSize <= bytes) {
+ if (buffers.first().size() <= basicBlockSize) {
+ bufferSize = 0;
+ head = tail = 0;
+ } else {
+ clear(); // try to minify/squeeze us
+ }
+ } else {
+ Q_ASSERT(bytes < MaxByteArraySize);
+ head += int(bytes);
+ bufferSize -= bytes;
+ }
+ return;
+ }
+
+ bufferSize -= blockSize;
+ bytes -= blockSize;
+ buffers.removeFirst();
+ --tailBuffer;
+ head = 0;
+ }
+}
+
+char *QRingBuffer::reserve(qint64 bytes)
+{
+ if (bytes <= 0 || bytes >= MaxByteArraySize)
+ return 0;
+
+ const qint64 newSize = bytes + tail;
+ // if need buffer reallocation
+ if (newSize > buffers.last().size()) {
+ if (newSize > buffers.last().capacity() && (tail >= basicBlockSize
+ || newSize >= MaxByteArraySize)) {
+ // shrink this buffer to its current size
+ buffers.last().resize(tail);
+
+ // create a new QByteArray
+ buffers.append(QByteArray());
+ ++tailBuffer;
+ tail = 0;
+ }
+ buffers.last().resize(qMax(basicBlockSize, tail + int(bytes)));
+ }
+
+ char *writePtr = buffers.last().data() + tail;
+ bufferSize += bytes;
+ Q_ASSERT(bytes < MaxByteArraySize);
+ tail += int(bytes);
+ return writePtr;
+}
+
+/*!
+ \internal
+
+ Allocate data at buffer head
+*/
+char *QRingBuffer::reserveFront(qint64 bytes)
+{
+ if (bytes <= 0 || bytes >= MaxByteArraySize)
+ return 0;
+
+ if (head < bytes) {
+ buffers.first().remove(0, head);
+ if (tailBuffer == 0)
+ tail -= head;
+
+ head = qMax(basicBlockSize, int(bytes));
+ if (bufferSize == 0) {
+ tail = head;
+ } else {
+ buffers.prepend(QByteArray());
+ ++tailBuffer;
+ }
+ buffers.first().resize(head);
+ }
+
+ head -= int(bytes);
+ bufferSize += bytes;
+ return buffers.first().data() + head;
+}
+
+void QRingBuffer::chop(qint64 bytes)
+{
+ while (bytes > 0) {
+ if (tailBuffer == 0 || tail > bytes) {
+ // keep a single block around if it does not exceed
+ // the basic block size, to avoid repeated allocations
+ // between uses of the buffer
+ if (bufferSize <= bytes) {
+ if (buffers.first().size() <= basicBlockSize) {
+ bufferSize = 0;
+ head = tail = 0;
+ } else {
+ clear(); // try to minify/squeeze us
+ }
+ } else {
+ Q_ASSERT(bytes < MaxByteArraySize);
+ tail -= int(bytes);
+ bufferSize -= bytes;
+ }
+ return;
+ }
+
+ bufferSize -= tail;
+ bytes -= tail;
+ buffers.removeLast();
+ --tailBuffer;
+ tail = buffers.last().size();
+ }
+}
+
+void QRingBuffer::clear()
+{
+ buffers.erase(buffers.begin() + 1, buffers.end());
+ buffers.first().clear();
+
+ head = tail = 0;
+ tailBuffer = 0;
+ bufferSize = 0;
+}
+
+qint64 QRingBuffer::indexOf(char c, qint64 maxLength) const
+{
+ qint64 index = 0;
+ qint64 j = head;
+ for (int i = 0; index < maxLength && i < buffers.size(); ++i) {
+ const char *ptr = buffers[i].constData() + j;
+ j = qMin(index + (i == tailBuffer ? tail : buffers[i].size()) - j, maxLength);
+
+ while (index < j) {
+ if (*ptr++ == c)
+ return index;
+ ++index;
+ }
+ j = 0;
+ }
+ return -1;
+}
+
+qint64 QRingBuffer::read(char *data, qint64 maxLength)
+{
+ const qint64 bytesToRead = qMin(size(), maxLength);
+ qint64 readSoFar = 0;
+ while (readSoFar < bytesToRead) {
+ const qint64 bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar,
+ nextDataBlockSize());
+ if (data)
+ memcpy(data + readSoFar, readPointer(), bytesToReadFromThisBlock);
+ readSoFar += bytesToReadFromThisBlock;
+ free(bytesToReadFromThisBlock);
+ }
+ return readSoFar;
+}
+
+/*!
+ \internal
+
+ Read an unspecified amount (will read the first buffer)
+*/
+QByteArray QRingBuffer::read()
+{
+ if (bufferSize == 0)
+ return QByteArray();
+
+ QByteArray qba(buffers.takeFirst());
+
+ qba.reserve(0); // avoid that resizing needlessly reallocates
+ if (tailBuffer == 0) {
+ qba.resize(tail);
+ tail = 0;
+ buffers.append(QByteArray());
+ } else {
+ --tailBuffer;
+ }
+ qba.remove(0, head); // does nothing if head is 0
+ head = 0;
+ bufferSize -= qba.size();
+ return qba;
+}
+
+/*!
+ \internal
+
+ Peek the bytes from a specified position
+*/
+qint64 QRingBuffer::peek(char *data, qint64 maxLength, qint64 pos) const
+{
+ qint64 readSoFar = 0;
+
+ if (pos >= 0) {
+ pos += head;
+ for (int i = 0; readSoFar < maxLength && i < buffers.size(); ++i) {
+ qint64 blockLength = (i == tailBuffer ? tail : buffers[i].size());
+
+ if (pos < blockLength) {
+ blockLength = qMin(blockLength - pos, maxLength - readSoFar);
+ memcpy(data + readSoFar, buffers[i].constData() + pos, blockLength);
+ readSoFar += blockLength;
+ pos = 0;
+ } else {
+ pos -= blockLength;
+ }
+ }
+ }
+
+ return readSoFar;
+}
+
+/*!
+ \internal
+
+ Append a new buffer to the end
+*/
+void QRingBuffer::append(const QByteArray &qba)
+{
+ if (tail == 0) {
+ buffers.last() = qba;
+ } else {
+ buffers.last().resize(tail);
+ buffers.append(qba);
+ ++tailBuffer;
+ }
+ tail = qba.size();
+ bufferSize += tail;
+}
+
+qint64 QRingBuffer::readLine(char *data, qint64 maxLength)
+{
+ if (!data || --maxLength <= 0)
+ return -1;
+
+ qint64 i = indexOf('\n', maxLength);
+ i = read(data, i >= 0 ? (i + 1) : maxLength);
+
+ // Terminate it.
+ data[i] = '\0';
+ return i;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
index ead85e9da0..68509a6a80 100644
--- a/src/corelib/tools/qringbuffer_p.h
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -58,7 +58,7 @@ public:
buffers.append(QByteArray());
}
- inline int nextDataBlockSize() const {
+ inline qint64 nextDataBlockSize() const {
return (tailBuffer == 0 ? tail : buffers.first().size()) - head;
}
@@ -66,112 +66,17 @@ public:
return bufferSize == 0 ? Q_NULLPTR : (buffers.first().constData() + head);
}
- // access the bytes at a specified position
- // the out-variable length will contain the amount of bytes readable
- // from there, e.g. the amount still the same QByteArray
- inline const char *readPointerAtPosition(qint64 pos, qint64 &length) const {
- if (pos >= 0) {
- pos += head;
- for (int i = 0; i < buffers.size(); ++i) {
- length = (i == tailBuffer ? tail : buffers[i].size());
- if (length > pos) {
- length -= pos;
- return buffers[i].constData() + pos;
- }
- pos -= length;
- }
- }
-
- length = 0;
- return 0;
- }
-
- inline void free(int bytes) {
- while (bytes > 0) {
- int blockSize = buffers.first().size() - head;
-
- if (tailBuffer == 0 || blockSize > bytes) {
- // keep a single block around if it does not exceed
- // the basic block size, to avoid repeated allocations
- // between uses of the buffer
- if (bufferSize <= bytes) {
- if (buffers.first().size() <= basicBlockSize) {
- bufferSize = 0;
- head = tail = 0;
- } else {
- clear(); // try to minify/squeeze us
- }
- } else {
- head += bytes;
- bufferSize -= bytes;
- }
- return;
- }
-
- bufferSize -= blockSize;
- bytes -= blockSize;
- buffers.removeFirst();
- --tailBuffer;
- head = 0;
- }
- }
-
- inline char *reserve(int bytes) {
- if (bytes <= 0)
- return 0;
-
- // if need buffer reallocation
- if (tail + bytes > buffers.last().size()) {
- if (tail + bytes > buffers.last().capacity() && tail >= basicBlockSize) {
- // shrink this buffer to its current size
- buffers.last().resize(tail);
-
- // create a new QByteArray
- buffers.append(QByteArray());
- ++tailBuffer;
- tail = 0;
- }
- buffers.last().resize(qMax(basicBlockSize, tail + bytes));
- }
+ Q_CORE_EXPORT const char *readPointerAtPosition(qint64 pos, qint64 &length) const;
+ Q_CORE_EXPORT void free(qint64 bytes);
+ Q_CORE_EXPORT char *reserve(qint64 bytes);
+ Q_CORE_EXPORT char *reserveFront(qint64 bytes);
- char *writePtr = buffers.last().data() + tail;
- bufferSize += bytes;
- tail += bytes;
- return writePtr;
- }
-
- inline void truncate(int pos) {
+ inline void truncate(qint64 pos) {
if (pos < size())
chop(size() - pos);
}
- inline void chop(int bytes) {
- while (bytes > 0) {
- if (tailBuffer == 0 || tail > bytes) {
- // keep a single block around if it does not exceed
- // the basic block size, to avoid repeated allocations
- // between uses of the buffer
- if (bufferSize <= bytes) {
- if (buffers.first().size() <= basicBlockSize) {
- bufferSize = 0;
- head = tail = 0;
- } else {
- clear(); // try to minify/squeeze us
- }
- } else {
- tail -= bytes;
- bufferSize -= bytes;
- }
- return;
- }
-
- bufferSize -= tail;
- bytes -= tail;
- buffers.removeLast();
- --tailBuffer;
- tail = buffers.last().size();
- }
- }
+ Q_CORE_EXPORT void chop(qint64 bytes);
inline bool isEmpty() const {
return bufferSize == 0;
@@ -190,131 +95,36 @@ public:
*ptr = c;
}
- inline void ungetChar(char c) {
- --head;
- if (head < 0) {
- if (bufferSize != 0) {
- buffers.prepend(QByteArray());
- ++tailBuffer;
- } else {
- tail = basicBlockSize;
- }
- buffers.first().resize(basicBlockSize);
- head = basicBlockSize - 1;
- }
- buffers.first()[head] = c;
- ++bufferSize;
- }
-
- inline int size() const {
- return bufferSize;
- }
-
- inline void clear() {
- buffers.erase(buffers.begin() + 1, buffers.end());
- buffers.first().clear();
-
- head = tail = 0;
- tailBuffer = 0;
- bufferSize = 0;
- }
-
- inline int indexOf(char c) const {
- int index = 0;
- int j = head;
- for (int i = 0; i < buffers.size(); ++i) {
- const char *ptr = buffers[i].constData() + j;
- j = index + (i == tailBuffer ? tail : buffers[i].size()) - j;
-
- while (index < j) {
- if (*ptr++ == c)
- return index;
- ++index;
- }
- j = 0;
- }
- return -1;
- }
-
- inline int indexOf(char c, int maxLength) const {
- int index = 0;
- int j = head;
- for (int i = 0; index < maxLength && i < buffers.size(); ++i) {
- const char *ptr = buffers[i].constData() + j;
- j = qMin(index + (i == tailBuffer ? tail : buffers[i].size()) - j, maxLength);
-
- while (index < j) {
- if (*ptr++ == c)
- return index;
- ++index;
- }
- j = 0;
- }
- return -1;
- }
-
- inline int read(char *data, int maxLength) {
- int bytesToRead = qMin(size(), maxLength);
- int readSoFar = 0;
- while (readSoFar < bytesToRead) {
- int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, nextDataBlockSize());
- if (data)
- memcpy(data + readSoFar, readPointer(), bytesToReadFromThisBlock);
- readSoFar += bytesToReadFromThisBlock;
- free(bytesToReadFromThisBlock);
+ void ungetChar(char c)
+ {
+ if (head > 0) {
+ --head;
+ buffers.first()[head] = c;
+ ++bufferSize;
+ } else {
+ char *ptr = reserveFront(1);
+ *ptr = c;
}
- return readSoFar;
}
- // read an unspecified amount (will read the first buffer)
- inline QByteArray read() {
- if (bufferSize == 0)
- return QByteArray();
- QByteArray qba(buffers.takeFirst());
-
- qba.reserve(0); // avoid that resizing needlessly reallocates
- if (tailBuffer == 0) {
- qba.resize(tail);
- tail = 0;
- buffers.append(QByteArray());
- } else {
- --tailBuffer;
- }
- qba.remove(0, head); // does nothing if head is 0
- head = 0;
- bufferSize -= qba.size();
- return qba;
+ inline qint64 size() const {
+ return bufferSize;
}
- // append a new buffer to the end
- inline void append(const QByteArray &qba) {
- if (tail == 0) {
- buffers.last() = qba;
- } else {
- buffers.last().resize(tail);
- buffers.append(qba);
- ++tailBuffer;
- }
- tail = qba.size();
- bufferSize += tail;
- }
+ Q_CORE_EXPORT void clear();
+ inline qint64 indexOf(char c) const { return indexOf(c, size()); }
+ Q_CORE_EXPORT qint64 indexOf(char c, qint64 maxLength) const;
+ Q_CORE_EXPORT qint64 read(char *data, qint64 maxLength);
+ Q_CORE_EXPORT QByteArray read();
+ Q_CORE_EXPORT qint64 peek(char *data, qint64 maxLength, qint64 pos = 0) const;
+ Q_CORE_EXPORT void append(const QByteArray &qba);
- inline int skip(int length) {
+ inline qint64 skip(qint64 length) {
return read(0, length);
}
- inline int readLine(char *data, int maxLength) {
- if (!data || --maxLength <= 0)
- return -1;
-
- int i = indexOf('\n', maxLength);
- i = read(data, i >= 0 ? (i + 1) : maxLength);
-
- // Terminate it.
- data[i] = '\0';
- return i;
- }
+ Q_CORE_EXPORT qint64 readLine(char *data, qint64 maxLength);
inline bool canReadLine() const {
return indexOf('\n') >= 0;
@@ -325,7 +135,7 @@ private:
int head, tail;
int tailBuffer; // always buffers.size() - 1
const int basicBlockSize;
- int bufferSize;
+ qint64 bufferSize;
};
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h
index 819ab00584..8d478f81f9 100644
--- a/src/corelib/tools/qscopedpointer.h
+++ b/src/corelib/tools/qscopedpointer.h
@@ -91,7 +91,7 @@ class QScopedPointer
{
typedef T *QScopedPointer:: *RestrictedBool;
public:
- explicit inline QScopedPointer(T *p = 0) : d(p)
+ explicit inline QScopedPointer(T *p = Q_NULLPTR) : d(p)
{
}
@@ -121,12 +121,12 @@ public:
#if defined(Q_QDOC)
inline operator bool() const
{
- return isNull() ? 0 : &QScopedPointer::d;
+ return isNull() ? Q_NULLPTR : &QScopedPointer::d;
}
#else
inline operator RestrictedBool() const
{
- return isNull() ? 0 : &QScopedPointer::d;
+ return isNull() ? Q_NULLPTR : &QScopedPointer::d;
}
#endif
@@ -140,7 +140,7 @@ public:
return !d;
}
- inline void reset(T *other = 0)
+ inline void reset(T *other = Q_NULLPTR)
{
if (d == other)
return;
@@ -152,7 +152,7 @@ public:
inline T *take()
{
T *oldD = d;
- d = 0;
+ d = Q_NULLPTR;
return oldD;
}
@@ -206,10 +206,10 @@ template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> >
class QScopedArrayPointer : public QScopedPointer<T, Cleanup>
{
public:
- inline QScopedArrayPointer() : QScopedPointer<T, Cleanup>(0) {}
+ inline QScopedArrayPointer() : QScopedPointer<T, Cleanup>(Q_NULLPTR) {}
template <typename D>
- explicit inline QScopedArrayPointer(D *p, typename QtPrivate::QScopedArrayEnsureSameType<T,D>::Type = 0)
+ explicit inline QScopedArrayPointer(D *p, typename QtPrivate::QScopedArrayEnsureSameType<T,D>::Type = Q_NULLPTR)
: QScopedPointer<T, Cleanup>(p)
{
}
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index e4688711d6..aeba6cf68d 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -57,15 +57,9 @@ public:
insert(*it);
}
#endif
- inline QSet(const QSet<T> &other) : q_hash(other.q_hash) {}
-
- inline QSet<T> &operator=(const QSet<T> &other)
- { q_hash = other.q_hash; return *this; }
-#ifdef Q_COMPILER_RVALUE_REFS
- inline QSet(QSet &&other) : q_hash(qMove(other.q_hash)) {}
- inline QSet<T> &operator=(QSet<T> &&other)
- { qSwap(q_hash, other.q_hash); return *this; }
-#endif
+ // compiler-generated copy/move ctor/assignment operators are fine!
+ // compiler-generated destructor is fine!
+
inline void swap(QSet<T> &other) { q_hash.swap(other.q_hash); }
inline bool operator==(const QSet<T> &other) const
@@ -137,6 +131,7 @@ public:
typedef QHash<T, QHashDummyValue> Hash;
typename Hash::const_iterator i;
friend class iterator;
+ friend class QSet<T>;
public:
typedef std::bidirectional_iterator_tag iterator_category;
@@ -191,6 +186,7 @@ public:
inline const_iterator constFind(const T &value) const { return find(value); }
QSet<T> &unite(const QSet<T> &other);
QSet<T> &intersect(const QSet<T> &other);
+ bool intersects(const QSet<T> &other) const;
QSet<T> &subtract(const QSet<T> &other);
// STL compatibility
@@ -284,6 +280,34 @@ Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
}
template <class T>
+Q_INLINE_TEMPLATE bool QSet<T>::intersects(const QSet<T> &other) const
+{
+ const bool otherIsBigger = other.size() > size();
+ const QSet &smallestSet = otherIsBigger ? *this : other;
+ const QSet &biggestSet = otherIsBigger ? other : *this;
+ const bool equalSeeds = q_hash.d->seed == other.q_hash.d->seed;
+ typename QSet::const_iterator i = smallestSet.cbegin();
+ typename QSet::const_iterator e = smallestSet.cend();
+
+ if (Q_LIKELY(equalSeeds)) {
+ // If seeds are equal we take the fast path so no hash is recalculated.
+ while (i != e) {
+ if (*biggestSet.q_hash.findNode(*i, i.i.i->h) != biggestSet.q_hash.e)
+ return true;
+ ++i;
+ }
+ } else {
+ while (i != e) {
+ if (biggestSet.contains(*i))
+ return true;
+ ++i;
+ }
+ }
+
+ return false;
+}
+
+template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::subtract(const QSet<T> &other)
{
QSet<T> copy1(*this);
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index 072e65af0e..d91a589aa1 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -114,40 +114,6 @@
*/
/*!
- \fn QSet::QSet(const QSet<T> &other)
-
- Constructs a copy of \a other.
-
- This operation occurs in \l{constant time}, because QSet is
- \l{implicitly shared}. This makes returning a QSet from a
- function very fast. If a shared instance is modified, it will be
- copied (copy-on-write), and this takes \l{linear time}.
-
- \sa operator=()
-*/
-
-/*!
- \fn QSet::QSet(QSet && other)
-
- Move-constructs a QSet instance, making it point to the same object that
- \a other was pointing to.
-*/
-
-
-/*!
- \fn QSet<T> &QSet::operator=(const QSet<T> &other)
-
- Assigns the \a other set to this set and returns a reference to
- this set.
-*/
-
-/*!
- \fn QSet<T> &QSet::operator=(QSet<T> &&other)
-
- Move-assigns the \a other set to this set.
-*/
-
-/*!
\fn void QSet::swap(QSet<T> &other)
Swaps set \a other with this set. This operation is very fast and
@@ -504,7 +470,17 @@
Removes all items from this set that are not contained in the
\a other set. A reference to this set is returned.
- \sa operator&=(), unite(), subtract()
+ \sa intersects(), operator&=(), unite(), subtract()
+*/
+
+/*!
+ \fn bool QSet::intersects(const QSet<T> &other) const
+ \since 5.6
+
+ Returns \c true if this set has at least one item in common with
+ \a other.
+
+ \sa contains(), intersect()
*/
/*!
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index 9dd8fff9cb..6a0900cf3f 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -36,7 +36,10 @@
#include <QtCore/qglobal.h>
#include <QtCore/qatomic.h>
+#if QT_DEPRECATED_SINCE(5, 5)
#include <QtCore/qhash.h>
+#endif
+#include <QtCore/qhashfunctions.h>
QT_BEGIN_NAMESPACE
@@ -76,7 +79,7 @@ public:
inline bool operator==(const QSharedDataPointer<T> &other) const { return d == other.d; }
inline bool operator!=(const QSharedDataPointer<T> &other) const { return d != other.d; }
- inline QSharedDataPointer() { d = 0; }
+ inline QSharedDataPointer() { d = Q_NULLPTR; }
inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }
explicit QSharedDataPointer(T *data) Q_DECL_NOTHROW;
@@ -142,17 +145,17 @@ public:
if(d && !d->ref.deref())
delete d;
- d = 0;
+ d = Q_NULLPTR;
}
- inline operator bool () const { return d != 0; }
+ inline operator bool () const { return d != Q_NULLPTR; }
inline bool operator==(const QExplicitlySharedDataPointer<T> &other) const { return d == other.d; }
inline bool operator!=(const QExplicitlySharedDataPointer<T> &other) const { return d != other.d; }
inline bool operator==(const T *ptr) const { return d == ptr; }
inline bool operator!=(const T *ptr) const { return d != ptr; }
- inline QExplicitlySharedDataPointer() { d = 0; }
+ inline QExplicitlySharedDataPointer() { d = Q_NULLPTR; }
inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
explicit QExplicitlySharedDataPointer(T *data) Q_DECL_NOTHROW;
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 9e6b48a97d..1323dd6b1c 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -55,7 +55,10 @@ QT_END_NAMESPACE
#include <new>
#include <QtCore/qatomic.h>
#include <QtCore/qobject.h> // for qobject_cast
-#include <QtCore/qhash.h> // for qHash
+#if QT_DEPRECATED_SINCE(5, 5)
+#include <QtCore/qhash.h>
+#endif
+#include <QtCore/qhashfunctions.h>
#if defined(Q_COMPILER_RVALUE_REFS) && defined(Q_COMPILER_VARIADIC_TEMPLATES)
# include <utility> // for std::forward
@@ -297,12 +300,12 @@ public:
inline T *data() const { return value; }
inline bool isNull() const { return !data(); }
- inline operator RestrictedBool() const { return isNull() ? 0 : &QSharedPointer::value; }
+ inline operator RestrictedBool() const { return isNull() ? Q_NULLPTR : &QSharedPointer::value; }
inline bool operator !() const { return isNull(); }
inline T &operator*() const { return *data(); }
inline T *operator->() const { return data(); }
- QSharedPointer() : value(0), d(0) { }
+ QSharedPointer() : value(Q_NULLPTR), d(Q_NULLPTR) { }
~QSharedPointer() { deref(); }
inline explicit QSharedPointer(T *ptr) : value(ptr) // noexcept
@@ -324,14 +327,32 @@ public:
inline QSharedPointer(QSharedPointer &&other)
: value(other.value), d(other.d)
{
- other.d = 0;
- other.value = 0;
+ other.d = Q_NULLPTR;
+ other.value = Q_NULLPTR;
}
inline QSharedPointer &operator=(QSharedPointer &&other)
{
- swap(other);
+ QSharedPointer moved(std::move(other));
+ swap(moved);
+ return *this;
+ }
+
+ template <class X>
+ QSharedPointer(QSharedPointer<X> &&other) Q_DECL_NOTHROW
+ : value(other.value), d(other.d)
+ {
+ other.d = Q_NULLPTR;
+ other.value = Q_NULLPTR;
+ }
+
+ template <class X>
+ QSharedPointer &operator=(QSharedPointer<X> &&other) Q_DECL_NOTHROW
+ {
+ QSharedPointer moved(std::move(other));
+ swap(moved);
return *this;
}
+
#endif
template <class X>
@@ -341,13 +362,13 @@ public:
template <class X>
inline QSharedPointer &operator=(const QSharedPointer<X> &other)
{
- QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
- internalCopy(other);
+ QSharedPointer copy(other);
+ swap(copy);
return *this;
}
template <class X>
- inline QSharedPointer(const QWeakPointer<X> &other) : value(0), d(0)
+ inline QSharedPointer(const QWeakPointer<X> &other) : value(Q_NULLPTR), d(Q_NULLPTR)
{ *this = other; }
template <class X>
@@ -463,9 +484,9 @@ public:
private:
explicit QSharedPointer(Qt::Initialization) {}
- inline void deref()
+ void deref() Q_DECL_NOTHROW
{ deref(d); }
- static inline void deref(Data *d)
+ static void deref(Data *d) Q_DECL_NOTHROW
{
if (!d) return;
if (!d->strongref.deref()) {
@@ -487,7 +508,7 @@ private:
inline void internalConstruct(T *ptr, Deleter deleter)
{
if (!ptr) {
- d = 0;
+ d = Q_NULLPTR;
return;
}
@@ -506,19 +527,7 @@ private:
enableSharedFromThis(ptr);
}
- template <class X>
- inline void internalCopy(const QSharedPointer<X> &other)
- {
- Data *o = other.d;
- T *actual = other.value;
- if (o)
- other.ref();
- qSwap(d, o);
- qSwap(this->value, actual);
- deref(o);
- }
-
- inline void internalSwap(QSharedPointer &other)
+ void internalSwap(QSharedPointer &other) Q_DECL_NOTHROW
{
qSwap(d, other.d);
qSwap(this->value, other.value);
@@ -531,7 +540,7 @@ public:
template <class X> friend class QWeakPointer;
template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
#endif
- inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
+ void ref() const Q_DECL_NOTHROW { d->weakref.ref(); d->strongref.ref(); }
inline void internalSet(Data *o, T *actual)
{
@@ -550,14 +559,14 @@ public:
o->weakref.ref();
} else {
o->checkQObjectShared(actual);
- o = 0;
+ o = Q_NULLPTR;
}
}
qSwap(d, o);
qSwap(this->value, actual);
if (!d || d->strongref.load() == 0)
- this->value = 0;
+ this->value = Q_NULLPTR;
// dereference saved data
deref(o);
@@ -582,19 +591,19 @@ public:
typedef const value_type &const_reference;
typedef qptrdiff difference_type;
- inline bool isNull() const { return d == 0 || d->strongref.load() == 0 || value == 0; }
- inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; }
+ inline bool isNull() const { return d == Q_NULLPTR || d->strongref.load() == 0 || value == Q_NULLPTR; }
+ inline operator RestrictedBool() const { return isNull() ? Q_NULLPTR : &QWeakPointer::value; }
inline bool operator !() const { return isNull(); }
- inline T *data() const { return d == 0 || d->strongref.load() == 0 ? 0 : value; }
+ inline T *data() const { return d == Q_NULLPTR || d->strongref.load() == 0 ? Q_NULLPTR : value; }
- Q_DECL_CONSTEXPR inline QWeakPointer() : d(0), value(0) { }
+ inline QWeakPointer() : d(Q_NULLPTR), value(Q_NULLPTR) { }
inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
#ifndef QT_NO_QOBJECT
// special constructor that is enabled only if X derives from QObject
#if QT_DEPRECATED_SINCE(5, 0)
template <class X>
- QT_DEPRECATED inline QWeakPointer(X *ptr) : d(ptr ? Data::getAndRef(ptr) : 0), value(ptr)
+ QT_DEPRECATED inline QWeakPointer(X *ptr) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
{ }
#endif
#endif
@@ -628,7 +637,7 @@ public:
}
template <class X>
- inline QWeakPointer(const QWeakPointer<X> &o) : d(0), value(0)
+ inline QWeakPointer(const QWeakPointer<X> &o) : d(Q_NULLPTR), value(Q_NULLPTR)
{ *this = o; }
template <class X>
@@ -649,7 +658,7 @@ public:
{ return !(*this == o); }
template <class X>
- inline QWeakPointer(const QSharedPointer<X> &o) : d(0), value(0)
+ inline QWeakPointer(const QSharedPointer<X> &o) : d(Q_NULLPTR), value(Q_NULLPTR)
{ *this = o; }
template <class X>
@@ -693,7 +702,7 @@ public:
#ifndef QT_NO_QOBJECT
template <class X>
- inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : 0), value(ptr)
+ inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : Q_NULLPTR), value(ptr)
{ }
#endif
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 4459d89e07..e7917ffdac 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -43,7 +43,9 @@
#if defined(Q_OS_WIN)
# if defined(Q_OS_WINCE)
# include <qt_windows.h>
-# include <cmnintrin.h>
+# if _WIN32_WCE < 0x800
+# include <cmnintrin.h>
+# endif
# endif
# if !defined(Q_CC_GNU)
# ifndef Q_OS_WINCE
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index dd93b4fd26..8523fb09c1 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -54,9 +54,9 @@
* for the x86 and ARM intrinsics:
* - GCC: the -mXXX or march=YYY flag is necessary before #include
* up to 4.8; GCC >= 4.9 can include unconditionally
+ * - Clang: same as GCC, with unconditional inclusion with version 3.7
* - Intel CC: #include can happen unconditionally
* - MSVC: #include can happen unconditionally
- * - RVCT: ???
*
* We will try to include all headers possible under this configuration.
*
@@ -138,7 +138,8 @@
#define QT_COMPILER_SUPPORTS(x) (QT_COMPILER_SUPPORTS_ ## x - 0)
#if (defined(Q_CC_INTEL) || defined(Q_CC_MSVC) \
- || (defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && (__GNUC__-0) * 100 + (__GNUC_MINOR__-0) >= 409)) \
+ || (defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && (__GNUC__-0) * 100 + (__GNUC_MINOR__-0) >= 409) \
+ || (defined(Q_CC_CLANG) && Q_CC_CLANG >= 307)) \
&& !defined(QT_BOOTSTRAPPED)
# define QT_COMPILER_SUPPORTS_SIMD_ALWAYS
# define QT_COMPILER_SUPPORTS_HERE(x) QT_COMPILER_SUPPORTS(x)
diff --git a/src/corelib/tools/qstack.cpp b/src/corelib/tools/qstack.cpp
index e367622c0d..224f72926b 100644
--- a/src/corelib/tools/qstack.cpp
+++ b/src/corelib/tools/qstack.cpp
@@ -71,19 +71,6 @@
*/
/*!
- \fn QStack::QStack()
-
- Constructs an empty stack.
-*/
-
-/*!
- \fn QStack::~QStack()
-
- Destroys the stack. References to the values in the stack, and all
- iterators over this stack, become invalid.
-*/
-
-/*!
\fn void QStack::swap(QStack<T> &other)
\since 4.8
diff --git a/src/corelib/tools/qstack.h b/src/corelib/tools/qstack.h
index fa05e22de1..278e89ca2f 100644
--- a/src/corelib/tools/qstack.h
+++ b/src/corelib/tools/qstack.h
@@ -43,8 +43,7 @@ template<class T>
class QStack : public QVector<T>
{
public:
- inline QStack() {}
- inline ~QStack() {}
+ // compiler-generated special member functions are fine!
inline void swap(QStack<T> &other) { QVector<T>::swap(other); } // prevent QVector<->QStack swaps
inline void push(const T &t) { QVector<T>::append(t); }
T pop();
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index b623c62043..e3a3cc79c6 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -50,7 +50,6 @@
#include "qstringmatcher.h"
#include "qvarlengtharray.h"
#include "qtools_p.h"
-#include "qhash.h"
#include "qdebug.h"
#include "qendian.h"
#include "qcollator.h"
@@ -1201,6 +1200,22 @@ const QString::Null QString::null = { };
\sa QString::const_iterator
*/
+/*! \typedef QString::const_reverse_iterator
+ \since 5.6
+
+ This typedef provides an STL-style const reverse iterator for QString.
+
+ \sa QString::reverse_iterator, QString::const_iterator
+*/
+
+/*! \typedef QString::reverse_iterator
+ \since 5.6
+
+ This typedef provides an STL-style non-const reverse iterator for QString.
+
+ \sa QString::const_reverse_iterator, QString::iterator
+*/
+
/*!
\typedef QString::size_type
@@ -1304,6 +1319,52 @@ const QString::Null QString::null = { };
\sa constBegin(), end()
*/
+/*! \fn QString::reverse_iterator QString::rbegin()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ character in the string, in reverse order.
+
+ \sa begin(), crbegin(), rend()
+*/
+
+/*! \fn QString::const_reverse_iterator QString::rbegin() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QString::const_reverse_iterator QString::crbegin() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ character in the string, in reverse order.
+
+ \sa begin(), rbegin(), rend()
+*/
+
+/*! \fn QString::reverse_iterator QString::rend()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past
+ the last character in the string, in reverse order.
+
+ \sa end(), crend(), rbegin()
+*/
+
+/*! \fn QString::const_reverse_iterator QString::rend() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QString::const_reverse_iterator QString::crend() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one
+ past the last character in the string, in reverse order.
+
+ \sa end(), rend(), rbegin()
+*/
+
/*!
\fn QString::QString()
@@ -1828,6 +1889,51 @@ QString &QString::operator=(QChar ch)
/*!
+ \fn QString& QString::insert(int position, const QStringRef &str)
+ \since 5.5
+ \overload insert()
+
+ Inserts the string reference \a str at the given index \a position and
+ returns a reference to this string.
+
+ If the given \a position is greater than size(), the array is
+ first extended using resize().
+*/
+
+
+/*!
+ \fn QString& QString::insert(int position, const char *str)
+ \since 5.5
+ \overload insert()
+
+ Inserts the C string \a str at the given index \a position and
+ returns a reference to this string.
+
+ If the given \a position is greater than size(), the array is
+ first extended using resize().
+
+ This function is not available when QT_NO_CAST_FROM_ASCII is
+ defined.
+*/
+
+
+/*!
+ \fn QString& QString::insert(int position, const QByteArray &str)
+ \since 5.5
+ \overload insert()
+
+ Inserts the byte array \a str at the given index \a position and
+ returns a reference to this string.
+
+ If the given \a position is greater than size(), the array is
+ first extended using resize().
+
+ This function is not available when QT_NO_CAST_FROM_ASCII is
+ defined.
+*/
+
+
+/*!
\fn QString &QString::insert(int position, QLatin1String str)
\overload insert()
@@ -2027,6 +2133,22 @@ QString &QString::append(QChar ch)
Prepends the Latin-1 string \a str to this string.
*/
+/*! \fn QString &QString::prepend(const QChar *str, int len)
+ \since 5.5
+ \overload prepend()
+
+ Prepends \a len characters from the QChar array \a str to this string and
+ returns a reference to this string.
+*/
+
+/*! \fn QString &QString::prepend(const QStringRef &str)
+ \since 5.5
+ \overload prepend()
+
+ Prepends the string reference \a str to the beginning of this string and
+ returns a reference to this string.
+*/
+
/*! \fn QString &QString::prepend(const QByteArray &ba)
\overload prepend()
@@ -2558,6 +2680,8 @@ bool operator==(const QString &s1, const QString &s2)
/*!
\overload operator==()
+ Returns \c true if this string is equal to \a other; otherwise
+ returns \c false.
*/
bool QString::operator==(QLatin1String other) const
{
@@ -2616,7 +2740,7 @@ bool operator<(const QString &s1, const QString &s2)
}
/*!
\overload operator<()
- \relates QString
+
Returns \c true if this string is lexically less than the parameter
string called \a other; otherwise returns \c false.
*/
@@ -2659,9 +2783,9 @@ bool QString::operator<(QLatin1String other) const
go through QObject::tr(), for example.
*/
-/*! \fn bool QString::operator<=(const QString &s1, const QString &s2)
+/*! \fn bool operator<=(const QString &s1, const QString &s2)
- \relates Qstring
+ \relates QString
Returns \c true if string \a s1 is lexically less than or equal to
string \a s2; otherwise returns \c false.
@@ -2707,7 +2831,7 @@ bool QString::operator<(QLatin1String other) const
go through QObject::tr(), for example.
*/
-/*! \fn bool QString::operator>(const QString &s1, const QString &s2)
+/*! \fn bool operator>(const QString &s1, const QString &s2)
\relates QString
Returns \c true if string \a s1 is lexically greater than string \a s2;
@@ -2721,7 +2845,7 @@ bool QString::operator<(QLatin1String other) const
/*!
\overload operator>()
- \relates QString
+
Returns \c true if this string is lexically greater than the parameter
string \a other; otherwise returns \c false.
*/
@@ -3184,6 +3308,7 @@ struct QStringCapture
int len;
int no;
};
+Q_DECLARE_TYPEINFO(QStringCapture, Q_PRIMITIVE_TYPE);
#endif
#ifndef QT_NO_REGEXP
@@ -3491,9 +3616,14 @@ int QString::count(const QString &str, Qt::CaseSensitivity cs) const
}
/*!
- \overload count()
+ \overload count()
+
+ Returns the number of occurrences of character \a ch in the string.
- Returns the number of occurrences of character \a ch in the string.
+ If \a cs is Qt::CaseSensitive (default), the search is
+ case sensitive; otherwise the search is case insensitive.
+
+ \sa contains(), indexOf()
*/
int QString::count(QChar ch, Qt::CaseSensitivity cs) const
@@ -3939,10 +4069,9 @@ int QString::count(const QRegularExpression &re) const
QString QString::section(const QString &sep, int start, int end, SectionFlags flags) const
{
- QStringList sections = split(sep, KeepEmptyParts,
- (flags & SectionCaseInsensitiveSeps) ? Qt::CaseInsensitive : Qt::CaseSensitive);
+ const QVector<QStringRef> sections = splitRef(sep, KeepEmptyParts,
+ (flags & SectionCaseInsensitiveSeps) ? Qt::CaseInsensitive : Qt::CaseSensitive);
const int sectionsSize = sections.size();
-
if (!(flags & SectionSkipEmpty)) {
if (start < 0)
start += sectionsSize;
@@ -3962,11 +4091,10 @@ QString QString::section(const QString &sep, int start, int end, SectionFlags fl
if (start >= sectionsSize || end < 0 || start > end)
return QString();
- int x = 0;
QString ret;
int first_i = start, last_i = end;
- for (int i = 0; x <= end && i < sectionsSize; ++i) {
- QString section = sections.at(i);
+ for (int x = 0, i = 0; x <= end && i < sectionsSize; ++i) {
+ const QStringRef &section = sections.at(i);
const bool empty = section.isEmpty();
if (x >= start) {
if(x == start)
@@ -3991,9 +4119,9 @@ QString QString::section(const QString &sep, int start, int end, SectionFlags fl
class qt_section_chunk {
public:
qt_section_chunk() {}
- qt_section_chunk(int l, QString s) : length(l), string(qMove(s)) {}
+ qt_section_chunk(int l, QStringRef s) : length(l), string(qMove(s)) {}
int length;
- QString string;
+ QStringRef string;
};
Q_DECLARE_TYPEINFO(qt_section_chunk, Q_MOVABLE_TYPE);
@@ -4086,12 +4214,12 @@ QString QString::section(const QRegExp &reg, int start, int end, SectionFlags fl
QVector<qt_section_chunk> sections;
int n = length(), m = 0, last_m = 0, last_len = 0;
while ((m = sep.indexIn(*this, m)) != -1) {
- sections.append(qt_section_chunk(last_len, QString(uc + last_m, m - last_m)));
+ sections.append(qt_section_chunk(last_len, QStringRef(this, last_m, m - last_m)));
last_m = m;
last_len = sep.matchedLength();
m += qMax(sep.matchedLength(), 1);
}
- sections.append(qt_section_chunk(last_len, QString(uc + last_m, n - last_m)));
+ sections.append(qt_section_chunk(last_len, QStringRef(this, last_m, n - last_m)));
return extractSections(sections, start, end, flags);
}
@@ -4134,11 +4262,11 @@ QString QString::section(const QRegularExpression &re, int start, int end, Secti
while (iterator.hasNext()) {
QRegularExpressionMatch match = iterator.next();
m = match.capturedStart();
- sections.append(qt_section_chunk(last_len, QString(uc + last_m, m - last_m)));
+ sections.append(qt_section_chunk(last_len, QStringRef(this, last_m, m - last_m)));
last_m = m;
last_len = match.capturedLength();
}
- sections.append(qt_section_chunk(last_len, QString(uc + last_m, n - last_m)));
+ sections.append(qt_section_chunk(last_len, QStringRef(this, last_m, n - last_m)));
return extractSections(sections, start, end, flags);
}
@@ -4149,8 +4277,8 @@ QString QString::section(const QRegularExpression &re, int start, int end, Secti
Returns a substring that contains the \a n leftmost characters
of the string.
- The entire string is returned if \a n is greater than size() or
- less than zero.
+ The entire string is returned if \a n is greater than or equal
+ to size(), or less than zero.
\snippet qstring/main.cpp 31
@@ -4167,8 +4295,8 @@ QString QString::left(int n) const
Returns a substring that contains the \a n rightmost characters
of the string.
- The entire string is returned if \a n is greater than size() or
- less than zero.
+ The entire string is returned if \a n is greater than or equal
+ to size(), or less than zero.
\snippet qstring/main.cpp 48
@@ -4822,7 +4950,7 @@ modifiable reference.
If \a position is negative, it is equivalent to passing zero.
- \sa chop(), resize(), left()
+ \sa chop(), resize(), left(), QStringRef::truncate()
*/
void QString::truncate(int pos)
@@ -4835,7 +4963,8 @@ void QString::truncate(int pos)
/*!
Removes \a n characters from the end of the string.
- If \a n is greater than size(), the result is an empty string.
+ If \a n is greater than or equal to size(), the result is an
+ empty string.
Example:
\snippet qstring/main.cpp 15
@@ -7622,86 +7751,155 @@ static int getEscape(const QChar *uc, int *pos, int len, int maxNumber = 999)
return -1;
}
+/*
+ Algorithm for multiArg:
+
+ 1. Parse the string as a sequence of verbatim text and placeholders (%L?\d{,3}).
+ The L is parsed and accepted for compatibility with non-multi-arg, but since
+ multiArg only accepts strings as replacements, the localization request can
+ be safely ignored.
+ 2. The result of step (1) is a list of (string-ref,int)-tuples. The string-ref
+ either points at text to be copied verbatim (in which case the int is -1),
+ or, initially, at the textual representation of the placeholder. In that case,
+ the int contains the numerical number as parsed from the placeholder.
+ 3. Next, collect all the non-negative ints found, sort them in ascending order and
+ remove duplicates.
+ 3a. If the result has more entires than multiArg() was given replacement strings,
+ we have found placeholders we can't satisfy with replacement strings. That is
+ fine (there could be another .arg() call coming after this one), so just
+ truncate the result to the number of actual multiArg() replacement strings.
+ 3b. If the result has less entries than multiArg() was given replacement strings,
+ the string is missing placeholders. This is an error that the user should be
+ warned about.
+ 4. The result of step (3) is a mapping from the index of any replacement string to
+ placeholder number. This is the wrong way around, but since placeholder
+ numbers could get as large as 999, while we typically don't have more than 9
+ replacement strings, we trade 4K of sparsely-used memory for doing a reverse lookup
+ each time we need to map a placeholder number to a replacement string index
+ (that's a linear search; but still *much* faster than using an associative container).
+ 5. Next, for each of the tuples found in step (1), do the following:
+ 5a. If the int is negative, do nothing.
+ 5b. Otherwise, if the int is found in the result of step (3) at index I, replace
+ the string-ref with a string-ref for the (complete) I'th replacement string.
+ 5c. Otherwise, do nothing.
+ 6. Concatenate all string refs into a single result string.
+*/
+
namespace {
-class ArgMapper {
- QVarLengthArray<int, 16> argPosToNumberMap; // maps from argument position to number
-public:
- void found(int n) { argPosToNumberMap.push_back(n); }
+struct Part
+{
+ Part() : stringRef(), number(0) {}
+ Part(const QString &s, int pos, int len, int num = -1) Q_DECL_NOTHROW
+ : stringRef(&s, pos, len), number(num) {}
- struct AssignmentResult {
- int numArgs;
- int lastNumber;
- };
+ QStringRef stringRef;
+ int number;
+};
+} // unnamed namespace
- AssignmentResult assignArgumentNumberToEachOfTheNs(int numArgs)
- {
- std::sort(argPosToNumberMap.begin(), argPosToNumberMap.end());
- argPosToNumberMap.erase(std::unique(argPosToNumberMap.begin(), argPosToNumberMap.end()),
- argPosToNumberMap.end());
+template <>
+class QTypeInfo<Part> : public QTypeInfoMerger<Part, QStringRef, int> {}; // Q_DECLARE_METATYPE
- if (argPosToNumberMap.size() > numArgs)
- argPosToNumberMap.resize(numArgs);
- int lastNumber = argPosToNumberMap.empty() ? -1 : argPosToNumberMap.back();
- int arg = argPosToNumberMap.size();
+namespace {
- const AssignmentResult result = {arg, lastNumber};
- return result;
- }
+enum { ExpectedParts = 32 };
- int numberToArgsIndex(int number) const
- {
- if (number != -1) {
- const int * const it = std::find(argPosToNumberMap.begin(), argPosToNumberMap.end(), number);
- return it == argPosToNumberMap.end() ? -1 : it - argPosToNumberMap.begin();
- } else {
- return -1;
- }
- }
-};
-} // unnamed namespace
+typedef QVarLengthArray<Part, ExpectedParts> ParseResult;
+typedef QVarLengthArray<int, ExpectedParts/2> ArgIndexToPlaceholderMap;
-QString QString::multiArg(int numArgs, const QString **args) const
+static ParseResult parseMultiArgFormatString(const QString &s)
{
- QString result;
- ArgMapper mapper;
- const QChar *uc = (const QChar *) d->data();
- const int len = d->size;
+ ParseResult result;
+
+ const QChar *uc = s.constData();
+ const int len = s.size();
const int end = len - 1;
int i = 0;
+ int last = 0;
- // populate the arg-mapper with the %n's that actually occur in the string
while (i < end) {
if (uc[i] == QLatin1Char('%')) {
+ int percent = i;
int number = getEscape(uc, &i, len);
if (number != -1) {
- mapper.found(number);
+ if (last != percent)
+ result.push_back(Part(s, last, percent - last)); // literal text (incl. failed placeholders)
+ result.push_back(Part(s, percent, i - percent, number)); // parsed placeholder
+ last = i;
continue;
}
}
++i;
}
- const ArgMapper::AssignmentResult r = mapper.assignArgumentNumberToEachOfTheNs(numArgs);
+ if (last < len)
+ result.push_back(Part(s, last, len - last)); // trailing literal text
- // sanity
- if (numArgs > r.numArgs) {
- qWarning("QString::arg: %d argument(s) missing in %s", numArgs - r.numArgs, toLocal8Bit().data());
- numArgs = r.numArgs;
+ return result;
+}
+
+static ArgIndexToPlaceholderMap makeArgIndexToPlaceholderMap(const ParseResult &parts)
+{
+ ArgIndexToPlaceholderMap result;
+
+ for (ParseResult::const_iterator it = parts.begin(), end = parts.end(); it != end; ++it) {
+ if (it->number >= 0)
+ result.push_back(it->number);
}
- i = 0;
- while (i < len) {
- if (uc[i] == QLatin1Char('%') && i != end) {
- int number = getEscape(uc, &i, len, r.lastNumber);
- int arg = mapper.numberToArgsIndex(number);
- if (number != -1 && arg != -1) {
- result += *args[arg];
- continue;
- }
+ std::sort(result.begin(), result.end());
+ result.erase(std::unique(result.begin(), result.end()),
+ result.end());
+
+ return result;
+}
+
+static int resolveStringRefsAndReturnTotalSize(ParseResult &parts, const ArgIndexToPlaceholderMap &argIndexToPlaceholderMap, const QString *args[])
+{
+ int totalSize = 0;
+ for (ParseResult::iterator pit = parts.begin(), end = parts.end(); pit != end; ++pit) {
+ if (pit->number != -1) {
+ const ArgIndexToPlaceholderMap::const_iterator ait
+ = std::find(argIndexToPlaceholderMap.begin(), argIndexToPlaceholderMap.end(), pit->number);
+ if (ait != argIndexToPlaceholderMap.end())
+ pit->stringRef = QStringRef(args[ait - argIndexToPlaceholderMap.begin()]);
}
- result += uc[i++];
+ totalSize += pit->stringRef.size();
}
+ return totalSize;
+}
+
+} // unnamed namespace
+
+QString QString::multiArg(int numArgs, const QString **args) const
+{
+ // Step 1-2 above
+ ParseResult parts = parseMultiArgFormatString(*this);
+
+ // 3-4
+ ArgIndexToPlaceholderMap argIndexToPlaceholderMap = makeArgIndexToPlaceholderMap(parts);
+
+ if (argIndexToPlaceholderMap.size() > numArgs) // 3a
+ argIndexToPlaceholderMap.resize(numArgs);
+ else if (argIndexToPlaceholderMap.size() < numArgs) // 3b
+ qWarning("QString::arg: %d argument(s) missing in %s",
+ numArgs - argIndexToPlaceholderMap.size(), toLocal8Bit().data());
+
+ // 5
+ const int totalSize = resolveStringRefsAndReturnTotalSize(parts, argIndexToPlaceholderMap, args);
+
+ // 6:
+ QString result(totalSize, Qt::Uninitialized);
+ QChar *out = result.data();
+
+ for (ParseResult::const_iterator it = parts.begin(), end = parts.end(); it != end; ++it) {
+ if (const int sz = it->stringRef.size()) {
+ memcpy(out, it->stringRef.constData(), sz * sizeof(QChar));
+ out += sz;
+ }
+ }
+
return result;
}
@@ -9125,8 +9323,8 @@ QString &QString::append(const QStringRef &str)
Returns a substring reference to the \a n leftmost characters
of the string.
- If \a n is greater than size() or less than zero, a reference to the entire
- string is returned.
+ If \a n is greater than or equal to size(), or less than zero,
+ a reference to the entire string is returned.
\sa right(), mid(), startsWith()
*/
@@ -9143,8 +9341,8 @@ QStringRef QStringRef::left(int n) const
Returns a substring reference to the \a n leftmost characters
of the string.
- If \a n is greater than size() or less than zero, a reference to the entire
- string is returned.
+ If \a n is greater than or equal to size(), or less than zero,
+ a reference to the entire string is returned.
\snippet qstring/main.cpp leftRef
@@ -9164,8 +9362,8 @@ QStringRef QString::leftRef(int n) const
Returns a substring reference to the \a n rightmost characters
of the string.
- If \a n is greater than size() or less than zero, a reference to the entire
- string is returned.
+ If \a n is greater than or equal to size(), or less than zero,
+ a reference to the entire string is returned.
\sa left(), mid(), endsWith()
*/
@@ -9182,8 +9380,8 @@ QStringRef QStringRef::right(int n) const
Returns a substring reference to the \a n rightmost characters
of the string.
- If \a n is greater than size() or less than zero, a reference to the entire
- string is returned.
+ If \a n is greater than or equal to size(), or less than zero,
+ a reference to the entire string is returned.
\snippet qstring/main.cpp rightRef
@@ -9268,6 +9466,20 @@ QStringRef QString::midRef(int position, int n) const
}
/*!
+ \fn void QStringRef::truncate(int position)
+ \since 5.6
+
+ Truncates the string at the given \a position index.
+
+ If the specified \a position index is beyond the end of the
+ string, nothing happens.
+
+ If \a position is negative, it is equivalent to passing zero.
+
+ \sa QString::truncate()
+*/
+
+/*!
\since 4.8
Returns the index position of the first occurrence of the string \a
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 63107ff688..643378a7bd 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -44,6 +44,7 @@
#include <QtCore/qnamespace.h>
#include <string>
+#include <iterator>
#if defined(Q_OS_ANDROID)
// std::wstring is disabled on android's glibc, as bionic lacks certain features
@@ -84,7 +85,7 @@ class QLatin1String
public:
Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) : m_size(s ? int(strlen(s)) : 0), m_data(s) {}
Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) : m_size(sz), m_data(s) {}
- inline explicit QLatin1String(const QByteArray &s) : m_size(int(qstrnlen(s.constData(), s.size()))), m_data(s.constData()) {}
+ inline explicit QLatin1String(const QByteArray &s) : m_size(s.size()), m_data(s.constData()) {}
inline const char *latin1() const { return m_data; }
inline int size() const { return m_size; }
@@ -420,6 +421,7 @@ public:
QString &insert(int i, QChar c);
QString &insert(int i, const QChar *uc, int len);
inline QString &insert(int i, const QString &s) { return insert(i, s.constData(), s.length()); }
+ inline QString &insert(int i, const QStringRef &s);
QString &insert(int i, QLatin1String s);
QString &append(QChar c);
QString &append(const QChar *uc, int len);
@@ -427,7 +429,9 @@ public:
QString &append(const QStringRef &s);
QString &append(QLatin1String s);
inline QString &prepend(QChar c) { return insert(0, c); }
+ inline QString &prepend(const QChar *uc, int len) { return insert(0, uc, len); }
inline QString &prepend(const QString &s) { return insert(0, s); }
+ inline QString &prepend(const QStringRef &s) { return insert(0, s); }
inline QString &prepend(QLatin1String s) { return insert(0, s); }
inline QString &operator+=(QChar c) {
@@ -534,11 +538,11 @@ public:
return fromLocal8Bit_helper(str, (str && size == -1) ? int(strlen(str)) : size);
}
static inline QString fromLatin1(const QByteArray &str)
- { return fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); }
+ { return str.isNull() ? QString() : fromLatin1(str.data(), str.size()); }
static inline QString fromUtf8(const QByteArray &str)
- { return fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); }
+ { return str.isNull() ? QString() : fromUtf8(str.data(), str.size()); }
static inline QString fromLocal8Bit(const QByteArray &str)
- { return fromLocal8Bit(str.data(), qstrnlen(str.constData(), str.size())); }
+ { return str.isNull() ? QString() : fromLocal8Bit(str.data(), str.size()); }
static QString fromUtf16(const ushort *, int size = -1);
static QString fromUcs4(const uint *, int size = -1);
static QString fromRawData(const QChar *, int size);
@@ -591,16 +595,16 @@ public:
static int localeAwareCompare(const QString& s1, const QStringRef& s2);
// ### Qt6: make inline except for the long long versions
- short toShort(bool *ok=0, int base=10) const;
- ushort toUShort(bool *ok=0, int base=10) const;
- int toInt(bool *ok=0, int base=10) const;
- uint toUInt(bool *ok=0, int base=10) const;
- long toLong(bool *ok=0, int base=10) const;
- ulong toULong(bool *ok=0, int base=10) const;
- qlonglong toLongLong(bool *ok=0, int base=10) const;
- qulonglong toULongLong(bool *ok=0, int base=10) const;
- float toFloat(bool *ok=0) const;
- double toDouble(bool *ok=0) const;
+ short toShort(bool *ok=Q_NULLPTR, int base=10) const;
+ ushort toUShort(bool *ok=Q_NULLPTR, int base=10) const;
+ int toInt(bool *ok=Q_NULLPTR, int base=10) const;
+ uint toUInt(bool *ok=Q_NULLPTR, int base=10) const;
+ long toLong(bool *ok=Q_NULLPTR, int base=10) const;
+ ulong toULong(bool *ok=Q_NULLPTR, int base=10) const;
+ qlonglong toLongLong(bool *ok=Q_NULLPTR, int base=10) const;
+ qulonglong toULongLong(bool *ok=Q_NULLPTR, int base=10) const;
+ float toFloat(bool *ok=Q_NULLPTR) const;
+ double toDouble(bool *ok=Q_NULLPTR) const;
QString &setNum(short, int base=10);
QString &setNum(ushort, int base=10);
@@ -650,7 +654,7 @@ public:
: d(fromAscii_helper(ch, ch ? int(strlen(ch)) : -1))
{}
inline QT_ASCII_CAST_WARN QString(const QByteArray &a)
- : d(fromAscii_helper(a.constData(), qstrnlen(a.constData(), a.size())))
+ : d(fromAscii_helper(a.constData(), a.size()))
{}
inline QT_ASCII_CAST_WARN QString &operator=(const char *ch)
{ return (*this = fromUtf8(ch)); }
@@ -668,6 +672,10 @@ public:
{ return append(QString::fromUtf8(s)); }
inline QT_ASCII_CAST_WARN QString &append(const QByteArray &s)
{ return append(QString::fromUtf8(s)); }
+ inline QT_ASCII_CAST_WARN QString &insert(int i, const char *s)
+ { return insert(i, QString::fromUtf8(s)); }
+ inline QT_ASCII_CAST_WARN QString &insert(int i, const QByteArray &s)
+ { return insert(i, QString::fromUtf8(s)); }
inline QT_ASCII_CAST_WARN QString &operator+=(const char *s)
{ return append(QString::fromUtf8(s)); }
inline QT_ASCII_CAST_WARN QString &operator+=(const QByteArray &s)
@@ -708,14 +716,22 @@ public:
typedef const QChar *const_iterator;
typedef iterator Iterator;
typedef const_iterator ConstIterator;
- iterator begin();
- const_iterator begin() const;
- const_iterator cbegin() const;
- const_iterator constBegin() const;
- iterator end();
- const_iterator end() const;
- const_iterator cend() const;
- const_iterator constEnd() const;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ inline iterator begin();
+ inline const_iterator begin() const;
+ inline const_iterator cbegin() const;
+ inline const_iterator constBegin() const;
+ inline iterator end();
+ inline const_iterator end() const;
+ inline const_iterator cend() const;
+ inline const_iterator constEnd() const;
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
// STL compatibility
typedef int size_type;
@@ -1211,30 +1227,30 @@ inline QT_ASCII_CAST_WARN bool QLatin1String::operator>=(const QByteArray &s) co
{ return QString::fromUtf8(s) <= *this; }
inline QT_ASCII_CAST_WARN bool QString::operator==(const QByteArray &s) const
-{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) == 0; }
+{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) == 0; }
inline QT_ASCII_CAST_WARN bool QString::operator!=(const QByteArray &s) const
-{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) != 0; }
+{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) != 0; }
inline QT_ASCII_CAST_WARN bool QString::operator<(const QByteArray &s) const
-{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) < 0; }
+{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; }
inline QT_ASCII_CAST_WARN bool QString::operator>(const QByteArray &s) const
-{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) > 0; }
+{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) > 0; }
inline QT_ASCII_CAST_WARN bool QString::operator<=(const QByteArray &s) const
-{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) <= 0; }
+{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) <= 0; }
inline QT_ASCII_CAST_WARN bool QString::operator>=(const QByteArray &s) const
-{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) >= 0; }
+{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) >= 0; }
inline bool QByteArray::operator==(const QString &s) const
-{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) == 0; }
+{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) == 0; }
inline bool QByteArray::operator!=(const QString &s) const
-{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) != 0; }
+{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) != 0; }
inline bool QByteArray::operator<(const QString &s) const
-{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) < 0; }
+{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) < 0; }
inline bool QByteArray::operator>(const QString &s) const
-{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) > 0; }
+{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) > 0; }
inline bool QByteArray::operator<=(const QString &s) const
-{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) <= 0; }
+{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) <= 0; }
inline bool QByteArray::operator>=(const QString &s) const
-{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) >= 0; }
+{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) >= 0; }
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
#ifndef QT_NO_CAST_TO_ASCII
@@ -1343,28 +1359,32 @@ public:
typedef QString::const_reference const_reference;
// ### Qt 6: make this constructor constexpr, after the destructor is made trivial
- inline QStringRef():m_string(0), m_position(0), m_size(0){}
+ inline QStringRef() : m_string(Q_NULLPTR), m_position(0), m_size(0) {}
inline QStringRef(const QString *string, int position, int size);
inline QStringRef(const QString *string);
- // ### Qt 6: remove this copy constructor, the implicit one is fine
- inline QStringRef(const QStringRef &other)
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ // ### Qt 6: remove all of these, the implicit ones are fine
+ QStringRef(const QStringRef &other) Q_DECL_NOTHROW
:m_string(other.m_string), m_position(other.m_position), m_size(other.m_size)
{}
-
- // ### Qt 6: remove this destructor, the implicit one is fine
+#ifdef Q_COMPILER_RVALUE_REFS
+ QStringRef(QStringRef &&other) Q_DECL_NOTHROW : m_string(other.m_string), m_position(other.m_position), m_size(other.m_size) {}
+ QStringRef &operator=(QStringRef &&other) Q_DECL_NOTHROW { return *this = other; }
+#endif
+ QStringRef &operator=(const QStringRef &other) Q_DECL_NOTHROW {
+ m_string = other.m_string; m_position = other.m_position;
+ m_size = other.m_size; return *this;
+ }
inline ~QStringRef(){}
+#endif // Qt < 6.0.0
+
inline const QString *string() const { return m_string; }
inline int position() const { return m_position; }
inline int size() const { return m_size; }
inline int count() const { return m_size; }
inline int length() const { return m_size; }
- inline QStringRef &operator=(const QStringRef &other) {
- m_string = other.m_string; m_position = other.m_position;
- m_size = other.m_size; return *this;
- }
-
int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int indexOf(QLatin1String str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@@ -1392,6 +1412,8 @@ public:
QStringRef right(int n) const Q_REQUIRED_RESULT;
QStringRef mid(int pos, int n = -1) const Q_REQUIRED_RESULT;
+ void truncate(int pos) Q_DECL_NOTHROW { m_size = qBound(0, pos, m_size); }
+
bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@@ -1425,10 +1447,10 @@ public:
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT;
QVector<uint> toUcs4() const Q_REQUIRED_RESULT;
- inline void clear() { m_string = 0; m_position = m_size = 0; }
+ inline void clear() { m_string = Q_NULLPTR; m_position = m_size = 0; }
QString toString() const;
inline bool isEmpty() const { return m_size == 0; }
- inline bool isNull() const { return m_string == 0 || m_string->isNull(); }
+ inline bool isNull() const { return m_string == Q_NULLPTR || m_string->isNull(); }
QStringRef appendTo(QString *string) const;
@@ -1461,16 +1483,16 @@ public:
static int localeAwareCompare(const QStringRef &s1, const QStringRef &s2);
QStringRef trimmed() const Q_REQUIRED_RESULT;
- short toShort(bool *ok = 0, int base = 10) const;
- ushort toUShort(bool *ok = 0, int base = 10) const;
- int toInt(bool *ok = 0, int base = 10) const;
- uint toUInt(bool *ok = 0, int base = 10) const;
- long toLong(bool *ok = 0, int base = 10) const;
- ulong toULong(bool *ok = 0, int base = 10) const;
- qlonglong toLongLong(bool *ok = 0, int base = 10) const;
- qulonglong toULongLong(bool *ok = 0, int base = 10) const;
- float toFloat(bool *ok = 0) const;
- double toDouble(bool *ok = 0) const;
+ short toShort(bool *ok = Q_NULLPTR, int base = 10) const;
+ ushort toUShort(bool *ok = Q_NULLPTR, int base = 10) const;
+ int toInt(bool *ok = Q_NULLPTR, int base = 10) const;
+ uint toUInt(bool *ok = Q_NULLPTR, int base = 10) const;
+ long toLong(bool *ok = Q_NULLPTR, int base = 10) const;
+ ulong toULong(bool *ok = Q_NULLPTR, int base = 10) const;
+ qlonglong toLongLong(bool *ok = Q_NULLPTR, int base = 10) const;
+ qulonglong toULongLong(bool *ok = Q_NULLPTR, int base = 10) const;
+ float toFloat(bool *ok = Q_NULLPTR) const;
+ double toDouble(bool *ok = Q_NULLPTR) const;
};
Q_DECLARE_TYPEINFO(QStringRef, Q_PRIMITIVE_TYPE);
@@ -1576,6 +1598,9 @@ inline bool QStringRef::contains(QChar c, Qt::CaseSensitivity cs) const
inline bool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
+inline QString &QString::insert(int i, const QStringRef &s)
+{ return insert(i, s.constData(), s.length()); }
+
namespace Qt {
#if QT_DEPRECATED_SINCE(5, 0)
QT_DEPRECATED inline QString escape(const QString &plain) {
diff --git a/src/corelib/tools/qtextboundaryfinder.h b/src/corelib/tools/qtextboundaryfinder.h
index beec5de607..a79fb50dad 100644
--- a/src/corelib/tools/qtextboundaryfinder.h
+++ b/src/corelib/tools/qtextboundaryfinder.h
@@ -68,7 +68,7 @@ public:
Q_DECLARE_FLAGS( BoundaryReasons, BoundaryReason )
QTextBoundaryFinder(BoundaryType type, const QString &string);
- QTextBoundaryFinder(BoundaryType type, const QChar *chars, int length, unsigned char *buffer = 0, int bufferSize = 0);
+ QTextBoundaryFinder(BoundaryType type, const QChar *chars, int length, unsigned char *buffer = Q_NULLPTR, int bufferSize = 0);
inline bool isValid() const { return d; }
diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h
index 21139b37a8..94e60dce45 100644
--- a/src/corelib/tools/qtimeline.h
+++ b/src/corelib/tools/qtimeline.h
@@ -70,7 +70,7 @@ public:
CosineCurve
};
- explicit QTimeLine(int duration = 1000, QObject *parent = 0);
+ explicit QTimeLine(int duration = 1000, QObject *parent = Q_NULLPTR);
virtual ~QTimeLine();
State state() const;
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index 3627045a40..900c8ff14e 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -310,9 +310,8 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
/*!
\typedef QTimeZone::OffsetDataList
- \relates QTimeZone
- Synonym for QList<OffsetData>.
+ Synonym for QVector<OffsetData>.
*/
/*!
@@ -764,6 +763,7 @@ QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
if (hasTransitions()) {
QTimeZonePrivate::DataList plist = d->transitions(fromDateTime.toMSecsSinceEpoch(),
toDateTime.toMSecsSinceEpoch());
+ list.reserve(plist.count());
foreach (const QTimeZonePrivate::Data &pdata, plist)
list.append(d->toOffsetData(pdata));
}
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index 8e6a0a0578..5bc3610af0 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -700,6 +700,7 @@ QByteArray QUtcTimeZonePrivate::systemTimeZoneId() const
QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const
{
QList<QByteArray> result;
+ result.reserve(utcDataTableSize);
for (int i = 0; i < utcDataTableSize; ++i)
result << utcId(utcData(i));
std::sort(result.begin(), result.end()); // ### or already sorted??
diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h
index e15ac801bc..14aeac3a02 100644
--- a/src/corelib/tools/qtimezoneprivate_p.h
+++ b/src/corelib/tools/qtimezoneprivate_p.h
@@ -165,6 +165,7 @@ public:
protected:
QByteArray m_id;
};
+Q_DECLARE_TYPEINFO(QTimeZonePrivate::Data, Q_MOVABLE_TYPE);
template<> QTimeZonePrivate *QSharedDataPointer<QTimeZonePrivate>::clone();
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 35380b882a..90ce8e3b68 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -637,6 +637,7 @@ void QTzTimeZonePrivate::init(const QByteArray &ianaId)
}
// Now for each transition time calculate our rule and save them
+ m_tranTimes.reserve(tranList.count());
foreach (const QTzTransition &tz_tran, tranList) {
QTzTransitionTime tran;
QTzTransitionRule rule;
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 90b54b7297..bb15d66439 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -45,6 +45,7 @@
#ifdef Q_COMPILER_INITIALIZER_LISTS
#include <initializer_list>
#endif
+#include <iterator>
QT_BEGIN_NAMESPACE
@@ -174,6 +175,8 @@ public:
typedef T* iterator;
typedef const T* const_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
inline iterator begin() { return ptr; }
inline const_iterator begin() const { return ptr; }
@@ -183,6 +186,12 @@ public:
inline const_iterator end() const { return ptr + s; }
inline const_iterator cend() const { return ptr + s; }
inline const_iterator constEnd() const { return ptr + s; }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
iterator insert(const_iterator before, int n, const T &x);
inline iterator insert(const_iterator before, const T &x) { return insert(before, 1, x); }
iterator erase(const_iterator begin, const_iterator end);
@@ -489,6 +498,36 @@ bool operator!=(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T,
return !(l == r);
}
+template <typename T, int Prealloc1, int Prealloc2>
+bool operator<(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengthArray<T, Prealloc2> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(),
+ rhs.begin(), rhs.end())))
+{
+ return std::lexicographical_compare(lhs.begin(), lhs.end(),
+ rhs.begin(), rhs.end());
+}
+
+template <typename T, int Prealloc1, int Prealloc2>
+inline bool operator>(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengthArray<T, Prealloc2> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return rhs < lhs;
+}
+
+template <typename T, int Prealloc1, int Prealloc2>
+inline bool operator<=(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengthArray<T, Prealloc2> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return !(lhs > rhs);
+}
+
+template <typename T, int Prealloc1, int Prealloc2>
+inline bool operator>=(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengthArray<T, Prealloc2> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return !(lhs < rhs);
+}
+
QT_END_NAMESPACE
#endif // QVARLENGTHARRAY_H
diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc
index a2d4c55f7a..2b7f9c5241 100644
--- a/src/corelib/tools/qvarlengtharray.qdoc
+++ b/src/corelib/tools/qvarlengtharray.qdoc
@@ -468,6 +468,20 @@
Typedef for T *. Provided for STL compatibility.
*/
+/*!
+ \typedef QVarLengthArray::const_reverse_iterator
+ \since 5.6
+
+ Typedef for \c{std::reverse_iterator<const T*>}. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QVarLengthArray::reverse_iterator
+ \since 5.6
+
+ Typedef for \c{std::reverse_iterator<T*>}. Provided for STL compatibility.
+*/
+
/*! \fn void QVarLengthArray::prepend(const T &value)
\since 4.8
@@ -582,6 +596,52 @@
\sa constBegin(), end()
*/
+/*! \fn QVarLengthArray::reverse_iterator QVarLengthArray::rbegin()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ item in the variable length array, in reverse order.
+
+ \sa begin(), crbegin(), rend()
+*/
+
+/*! \fn QVarLengthArray::const_reverse_iterator QVarLengthArray::rbegin() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QVarLengthArray::const_reverse_iterator QVarLengthArray::crbegin() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ item in the variable length array, in reverse order.
+
+ \sa begin(), rbegin(), rend()
+*/
+
+/*! \fn QVarLengthArray::reverse_iterator QVarLengthArray::rend()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past
+ the last item in the variable length array, in reverse order.
+
+ \sa end(), crend(), rbegin()
+*/
+
+/*! \fn QVarLengthArray::const_reverse_iterator QVarLengthArray::rend() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QVarLengthArray::const_reverse_iterator QVarLengthArray::crend() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one
+ past the last item in the variable length array, in reverse order.
+
+ \sa end(), rend(), rbegin()
+*/
+
/*! \fn QVarLengthArray::iterator QVarLengthArray::erase(const_iterator pos)
\since 4.8
@@ -676,6 +736,54 @@
\sa operator==()
*/
+/*! \fn bool operator<(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs)
+ \since 5.6
+ \relates QVarLengthArray
+
+ Returns \c true if variable length array \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically less than} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator<=(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs)
+ \since 5.6
+ \relates QVarLengthArray
+
+ Returns \c true if variable length array \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically less than or equal to} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator>(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs)
+ \since 5.6
+ \relates QVarLengthArray
+
+ Returns \c true if variable length array \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically greater than} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator>=(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs)
+ \since 5.6
+ \relates QVarLengthArray
+
+ Returns \c true if variable length array \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically greater than or equal to} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
/*! \fn QVarLengthArray &QVarLengthArray::operator<<(const T &value)
\since 4.8
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index d10f82fbb4..9afd2c624a 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -45,34 +45,42 @@
stores its items in adjacent memory locations and provides fast
index-based access.
- QList\<T\>, QLinkedList\<T\>, and QVarLengthArray\<T\> provide
- similar functionality. Here's an overview:
+ QList\<T\>, QLinkedList\<T\>, QVector\<T\>, and QVarLengthArray\<T\>
+ provide similar APIs and functionality. They are often interchangeable,
+ but there are performance consequences. Here is an overview of use cases:
\list
- \li For most purposes, QList is the right class to use. Operations
- like prepend() and insert() are usually faster than with
- QVector because of the way QList stores its items in memory
- (see \l{Algorithmic Complexity} for details),
- and its index-based API is more convenient than QLinkedList's
- iterator-based API. It also expands to less code in your
- executable.
- \li If you need a real linked list, with guarantees of \l{constant
- time} insertions in the middle of the list and iterators to
- items rather than indexes, use QLinkedList.
- \li If you want the items to occupy adjacent memory positions, or
- if your items are larger than a pointer and you want to avoid
- the overhead of allocating them on the heap individually at
- insertion time, then use QVector.
- \li If you want a low-level variable-size array, QVarLengthArray
- may be sufficient.
+ \li QVector should be your default first choice.
+ QVector\<T\> will usually give better performance than QList\<T\>,
+ because QVector\<T\> always stores its items sequentially in memory,
+ where QList\<T\> will allocate its items on the heap unless
+ \c {sizeof(T) <= sizeof(void*)} and T has been declared to be
+ either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using
+ \l {Q_DECLARE_TYPEINFO}. See the \l {Pros and Cons of Using QList}
+ for an explanation.
+ \li However, QList is used throughout the Qt APIs for passing
+ parameters and for returning values. Use QList to interface with
+ those APIs.
+ \li If you need a real linked list, which guarantees
+ \l{Algorithmic Complexity}{constant time} insertions mid-list and
+ uses iterators to items rather than indexes, use QLinkedList.
\endlist
+ \note QVector and QVarLengthArray both guarantee C-compatible
+ array layout. QList does not. This might be important if your
+ application must interface with a C API.
+
+ \note Iterators into a QLinkedList and references into
+ heap-allocating QLists remain valid long as the referenced items
+ remain in the container. This is not true for iterators and
+ references into a QVector and non-heap-allocating QLists.
+
Here's an example of a QVector that stores integers and a QVector
that stores QString values:
\snippet code/src_corelib_tools_qvector.cpp 0
- QVector stores a vector (or array) of items. Typically, vectors
+ QVector stores its items in a vector (array). Typically, vectors
are created with an initial size. For example, the following code
constructs a QVector with 200 elements:
@@ -166,6 +174,11 @@
with references to its own values. Doing so will cause your application to
abort with an error message.
+ \section2 More Information on Using Qt Containers
+
+ For a detailed discussion comparing Qt containers with each other and
+ with STL containers, see \l {Understand the Qt Containers}.
+
\sa QVectorIterator, QMutableVectorIterator, QList, QLinkedList
*/
@@ -218,10 +231,11 @@
Constructs a copy of \a other.
- This operation takes \l{constant time}, because QVector is
- \l{implicitly shared}. This makes returning a QVector from a
- function very fast. If a shared instance is modified, it will be
- copied (copy-on-write), and that takes \l{linear time}.
+ This operation takes \l{Algorithmic Complexity}{constant time},
+ because QVector is \l{implicitly shared}. This makes returning
+ a QVector from a function very fast. If a shared instance is
+ modified, it will be copied (copy-on-write), and that takes
+ \l{Algorithmic Complexity}{linear time}.
\sa operator=()
*/
@@ -290,6 +304,65 @@
\sa operator==()
*/
+/*! \fn bool operator<(const QVector<T> &lhs, const QVector<T> &rhs)
+ \since 5.6
+ \relates QVector
+
+ Returns \c true if vector \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically less than} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator<=(const QVector<T> &lhs, const QVector<T> &rhs)
+ \since 5.6
+ \relates QVector
+
+ Returns \c true if vector \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically less than or equal to} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator>(const QVector<T> &lhs, const QVector<T> &rhs)
+ \since 5.6
+ \relates QVector
+
+ Returns \c true if vector \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically greater than} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*! \fn bool operator>=(const QVector<T> &lhs, const QVector<T> &rhs)
+ \since 5.6
+ \relates QVector
+
+ Returns \c true if vector \a lhs is
+ \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare}
+ {lexicographically greater than or equal to} \a rhs; otherwise returns \c false.
+
+ This function requires the value type to have an implementation
+ of \c operator<().
+*/
+
+/*!
+ \fn uint qHash(const QVector<T> &key, uint seed = 0)
+ \since 5.6
+ \relates QVector
+
+ Returns the hash value for \a key,
+ using \a seed to seed the calculation.
+
+ This function requires qHash() to be overloaded for the value type \c T.
+*/
+
/*! \fn int QVector::size() const
Returns the number of items in the vector.
@@ -463,6 +536,16 @@
\sa operator<<(), prepend(), insert()
*/
+/*!
+ \fn void QVector::append(T &&value)
+ \since 5.6
+
+ \overload
+
+ Example:
+ \snippet code/src_corelib_tools_qvector.cpp move-append
+*/
+
/*! \fn void QVector::append(const QVector<T> &value)
\overload
@@ -629,6 +712,16 @@
\sa takeFirst(), takeLast(), QList::takeAt()
*/
+/*! \fn void QVector::move(int from, int to)
+ \since 5.6
+
+ Moves the item at index position \a from to index position \a to.
+
+ Provided for compatibility with QList.
+
+ \sa QList::move()
+*/
+
/*! \fn void QVector::removeFirst()
\since 5.1
Removes the first item in the vector. Calling this function is
@@ -823,6 +916,52 @@
\sa constBegin(), end()
*/
+/*! \fn QVector::reverse_iterator QVector::rbegin()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ item in the vector, in reverse order.
+
+ \sa begin(), crbegin(), rend()
+*/
+
+/*! \fn QVector::const_reverse_iterator QVector::rbegin() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QVector::const_reverse_iterator QVector::crbegin() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ item in the vector, in reverse order.
+
+ \sa begin(), rbegin(), rend()
+*/
+
+/*! \fn QVector::reverse_iterator QVector::rend()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past
+ the last item in the vector, in reverse order.
+
+ \sa end(), crend(), rbegin()
+*/
+
+/*! \fn QVector::const_reverse_iterator QVector::rend() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QVector::const_reverse_iterator QVector::crend() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one
+ past the last item in the vector, in reverse order.
+
+ \sa end(), rend(), rbegin()
+*/
+
/*! \fn QVector::iterator QVector::erase(iterator pos)
Removes the item pointed to by the iterator \a pos from the
@@ -846,7 +985,7 @@
Returns a reference to the first item in the vector. This
function assumes that the vector isn't empty.
- \sa last(), isEmpty()
+ \sa last(), isEmpty(), constFirst()
*/
/*! \fn const T& QVector::first() const
@@ -854,12 +993,21 @@
\overload
*/
+/*! \fn const T& QVector::constFirst() const
+ \since 5.6
+
+ Returns a const reference to the first item in the vector. This
+ function assumes that the vector isn't empty.
+
+ \sa constLast(), isEmpty(), first()
+*/
+
/*! \fn T& QVector::last()
Returns a reference to the last item in the vector. This function
assumes that the vector isn't empty.
- \sa first(), isEmpty()
+ \sa first(), isEmpty(), constLast()
*/
/*! \fn const T& QVector::last() const
@@ -867,6 +1015,15 @@
\overload
*/
+/*! \fn const T& QVector::constLast() const
+ \since 5.6
+
+ Returns a const reference to the last item in the vector. This function
+ assumes that the vector isn't empty.
+
+ \sa constFirst(), isEmpty(), last()
+*/
+
/*! \fn T QVector::value(int i) const
Returns the value at index position \a i in the vector.
@@ -893,6 +1050,11 @@
to append(\a value).
*/
+/*! \fn void QVector::push_back(T &&value)
+ \since 5.6
+ \overload
+*/
+
/*! \fn void QVector::push_front(const T &value)
This function is provided for STL compatibility. It is equivalent
@@ -1013,6 +1175,38 @@
\sa QVector::constBegin(), QVector::constEnd(), QVector::iterator, QVectorIterator
*/
+/*! \typedef QVector::reverse_iterator
+ \since 5.6
+
+ The QVector::reverse_iterator typedef provides an STL-style non-const
+ reverse iterator for QVector.
+
+ It is simply a typedef for \c{std::reverse_iterator<T*>}.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
+ \sa QVector::rbegin(), QVector::rend(), QVector::const_reverse_iterator, QVector::iterator
+*/
+
+/*! \typedef QVector::const_reverse_iterator
+ \since 5.6
+
+ The QVector::const_reverse_iterator typedef provides an STL-style const
+ reverse iterator for QVector.
+
+ It is simply a typedef for \c{std::reverse_iterator<const T*>}.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
+ \sa QVector::rbegin(), QVector::rend(), QVector::reverse_iterator, QVector::const_iterator
+*/
+
/*! \typedef QVector::Iterator
Qt-style synonym for QVector::iterator.
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index eed5d17cad..890dbd317d 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -39,6 +39,7 @@
#include <QtCore/qlist.h>
#include <QtCore/qrefcount.h>
#include <QtCore/qarraydata.h>
+#include <QtCore/qhashfunctions.h>
#include <iterator>
#include <vector>
@@ -68,11 +69,11 @@ public:
inline ~QVector() { if (!d->ref.deref()) freeData(d); }
QVector<T> &operator=(const QVector<T> &v);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QVector(QVector<T> &&other) : d(other.d) { other.d = Data::sharedNull(); }
- inline QVector<T> operator=(QVector<T> &&other)
- { qSwap(d, other.d); return *this; }
+ QVector(QVector<T> &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); }
+ QVector<T> &operator=(QVector<T> &&other) Q_DECL_NOTHROW
+ { QVector moved(std::move(other)); swap(moved); return *this; }
#endif
- inline void swap(QVector<T> &other) { qSwap(d, other.d); }
+ void swap(QVector<T> &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QVector(std::initializer_list<T> args);
#endif
@@ -128,6 +129,9 @@ public:
T &operator[](int i);
const T &operator[](int i) const;
void append(const T &t);
+#ifdef Q_COMPILER_RVALUE_REFS
+ void append(T &&t);
+#endif
inline void append(const QVector<T> &l) { *this += l; }
void prepend(const T &t);
void insert(int i, const T &t);
@@ -171,29 +175,50 @@ public:
}
int length() const { return size(); }
T takeAt(int i) { T t = at(i); remove(i); return t; }
+ void move(int from, int to)
+ {
+ Q_ASSERT_X(from >= 0 && from < size(), "QVector::move(int,int)", "'from' is out-of-range");
+ Q_ASSERT_X(to >= 0 && to < size(), "QVector::move(int,int)", "'to' is out-of-range");
+ if (from == to) // don't detach when no-op
+ return;
+ detach();
+ T * const b = d->begin();
+ if (from < to)
+ std::rotate(b + from, b + from + 1, b + to + 1);
+ else
+ std::rotate(b + to, b + from, b + from + 1);
+ }
// STL-style
typedef typename Data::iterator iterator;
typedef typename Data::const_iterator const_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
#if !defined(QT_STRICT_ITERATORS) || defined(Q_QDOC)
inline iterator begin() { detach(); return d->begin(); }
- inline const_iterator begin() const { return d->constBegin(); }
- inline const_iterator cbegin() const { return d->constBegin(); }
- inline const_iterator constBegin() const { return d->constBegin(); }
+ inline const_iterator begin() const Q_DECL_NOTHROW { return d->constBegin(); }
+ inline const_iterator cbegin() const Q_DECL_NOTHROW { return d->constBegin(); }
+ inline const_iterator constBegin() const Q_DECL_NOTHROW { return d->constBegin(); }
inline iterator end() { detach(); return d->end(); }
- inline const_iterator end() const { return d->constEnd(); }
- inline const_iterator cend() const { return d->constEnd(); }
- inline const_iterator constEnd() const { return d->constEnd(); }
+ inline const_iterator end() const Q_DECL_NOTHROW { return d->constEnd(); }
+ inline const_iterator cend() const Q_DECL_NOTHROW { return d->constEnd(); }
+ inline const_iterator constEnd() const Q_DECL_NOTHROW { return d->constEnd(); }
#else
inline iterator begin(iterator = iterator()) { detach(); return d->begin(); }
- inline const_iterator begin(const_iterator = const_iterator()) const { return d->constBegin(); }
- inline const_iterator cbegin(const_iterator = const_iterator()) const { return d->constBegin(); }
- inline const_iterator constBegin(const_iterator = const_iterator()) const { return d->constBegin(); }
+ inline const_iterator begin(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constBegin(); }
+ inline const_iterator cbegin(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constBegin(); }
+ inline const_iterator constBegin(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constBegin(); }
inline iterator end(iterator = iterator()) { detach(); return d->end(); }
- inline const_iterator end(const_iterator = const_iterator()) const { return d->constEnd(); }
- inline const_iterator cend(const_iterator = const_iterator()) const { return d->constEnd(); }
- inline const_iterator constEnd(const_iterator = const_iterator()) const { return d->constEnd(); }
+ inline const_iterator end(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constEnd(); }
+ inline const_iterator cend(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constEnd(); }
+ inline const_iterator constEnd(const_iterator = const_iterator()) const Q_DECL_NOTHROW { return d->constEnd(); }
#endif
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
+ const_reverse_iterator crend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
iterator insert(iterator before, int n, const T &x);
inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
iterator erase(iterator begin, iterator end);
@@ -203,8 +228,10 @@ public:
inline int count() const { return d->size; }
inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
inline const T &first() const { Q_ASSERT(!isEmpty()); return *begin(); }
+ inline const T &constFirst() const { Q_ASSERT(!isEmpty()); return *begin(); }
inline T& last() { Q_ASSERT(!isEmpty()); return *(end()-1); }
inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
+ inline const T &constLast() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
QVector<T> mid(int pos, int len = -1) const;
@@ -223,6 +250,9 @@ public:
typedef const_iterator ConstIterator;
typedef int size_type;
inline void push_back(const T &t) { append(t); }
+#ifdef Q_COMPILER_RVALUE_REFS
+ void push_back(T &&t) { append(std::move(t)); }
+#endif
inline void push_front(const T &t) { prepend(t); }
void pop_back() { removeLast(); }
void pop_front() { removeFirst(); }
@@ -265,7 +295,6 @@ private:
{
return (i <= d->end()) && (d->begin() <= i);
}
- iterator c2m(const_iterator it) { return begin() + (it - cbegin()); }
class AlignmentDummy { Data header; T array[1]; };
};
@@ -602,14 +631,14 @@ void QVector<T>::append(const T &t)
{
const bool isTooSmall = uint(d->size + 1) > d->alloc;
if (!isDetached() || isTooSmall) {
- const T copy(t);
+ T copy(t);
QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt);
if (QTypeInfo<T>::isComplex)
- new (d->end()) T(copy);
+ new (d->end()) T(qMove(copy));
else
- *d->end() = copy;
+ *d->end() = qMove(copy);
} else {
if (QTypeInfo<T>::isComplex)
@@ -620,6 +649,22 @@ void QVector<T>::append(const T &t)
++d->size;
}
+#ifdef Q_COMPILER_RVALUE_REFS
+template <typename T>
+void QVector<T>::append(T &&t)
+{
+ const bool isTooSmall = uint(d->size + 1) > d->alloc;
+ if (!isDetached() || isTooSmall) {
+ QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
+ reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt);
+ }
+
+ new (d->end()) T(std::move(t));
+
+ ++d->size;
+}
+#endif
+
template <typename T>
void QVector<T>::removeLast()
{
@@ -873,6 +918,43 @@ QList<T> QList<T>::fromVector(const QVector<T> &vector)
Q_DECLARE_SEQUENTIAL_ITERATOR(Vector)
Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Vector)
+template <typename T>
+uint qHash(const QVector<T> &key, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHashRange(key.cbegin(), key.cend(), seed)))
+{
+ return qHashRange(key.cbegin(), key.cend(), seed);
+}
+
+template <typename T>
+bool operator<(const QVector<T> &lhs, const QVector<T> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(),
+ rhs.begin(), rhs.end())))
+{
+ return std::lexicographical_compare(lhs.begin(), lhs.end(),
+ rhs.begin(), rhs.end());
+}
+
+template <typename T>
+inline bool operator>(const QVector<T> &lhs, const QVector<T> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return rhs < lhs;
+}
+
+template <typename T>
+inline bool operator<=(const QVector<T> &lhs, const QVector<T> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return !(lhs > rhs);
+}
+
+template <typename T>
+inline bool operator>=(const QVector<T> &lhs, const QVector<T> &rhs)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+{
+ return !(lhs < rhs);
+}
+
/*
### Qt 5:
### This needs to be removed for next releases of Qt. It is a workaround for vc++ because
diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp
index 660f40b107..4197fc47b1 100644
--- a/src/corelib/tools/qversionnumber.cpp
+++ b/src/corelib/tools/qversionnumber.cpp
@@ -32,7 +32,7 @@
**
****************************************************************************/
-#include <QtCore/private/qversionnumber_p.h>
+#include <QtCore/qversionnumber.h>
#include <QtCore/qhash.h>
#include <QtCore/private/qlocale_tools_p.h>
#include <QtCore/qcollator.h>
@@ -53,8 +53,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QVersionNumber
\inmodule QtCore
- \internal
- \since 5.4
+ \since 5.6
\brief The QVersionNumber class contains a version number with an arbitrary
number of segments.
@@ -168,6 +167,17 @@ QT_BEGIN_NAMESPACE
\sa majorVersion(), minorVersion(), microVersion()
*/
+QVector<int> QVersionNumber::segments() const
+{
+ if (m_segments.isUsingPointer())
+ return *m_segments.pointer_segments;
+
+ QVector<int> result;
+ result.resize(segmentCount());
+ for (int i = 0; i < segmentCount(); ++i)
+ result[i] = segmentAt(i);
+ return result;
+}
/*!
\fn int QVersionNumber::segmentAt(int index) const
@@ -196,6 +206,17 @@ QT_BEGIN_NAMESPACE
\snippet qversionnumber/main.cpp 4
*/
+QVersionNumber QVersionNumber::normalized() const
+{
+ int i;
+ for (i = m_segments.size(); i; --i)
+ if (m_segments.at(i - 1) != 0)
+ break;
+
+ QVersionNumber result(*this);
+ result.m_segments.resize(i);
+ return result;
+}
/*!
\fn bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const
@@ -209,8 +230,13 @@ QT_BEGIN_NAMESPACE
*/
bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW
{
- return m_segments.size() <= other.m_segments.size() &&
- std::equal(m_segments.begin(), m_segments.end(), other.m_segments.begin());
+ if (segmentCount() > other.segmentCount())
+ return false;
+ for (int i = 0; i < segmentCount(); ++i) {
+ if (segmentAt(i) != other.segmentAt(i))
+ return false;
+ }
+ return true;
}
/*!
@@ -228,30 +254,37 @@ bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHRO
*/
int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW
{
- QVector<int>::const_iterator i1 = v1.m_segments.constBegin();
- const QVector<int>::const_iterator e1 = v1.m_segments.constEnd();
- QVector<int>::const_iterator i2 = v2.m_segments.constBegin();
- const QVector<int>::const_iterator e2 = v2.m_segments.constEnd();
-
- while (i1 != e1 && i2 != e2) {
- if (*i1 != *i2)
- return (*i1 - *i2);
- ++i1;
- ++i2;
+ int commonlen;
+
+ if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) {
+ // we can't use memcmp because it interprets the data as unsigned bytes
+ const qint8 *ptr1 = v1.m_segments.inline_segments + InlineSegmentStartIdx;
+ const qint8 *ptr2 = v2.m_segments.inline_segments + InlineSegmentStartIdx;
+ commonlen = qMin(v1.m_segments.size(),
+ v2.m_segments.size());
+ for (int i = 0; i < commonlen; ++i)
+ if (int x = ptr1[i] - ptr2[i])
+ return x;
+ } else {
+ commonlen = qMin(v1.segmentCount(), v2.segmentCount());
+ for (int i = 0; i < commonlen; ++i) {
+ if (v1.segmentAt(i) != v2.segmentAt(i))
+ return v1.segmentAt(i) - v2.segmentAt(i);
+ }
}
// ran out of segments in v1 and/or v2 and need to check the first trailing
// segment to finish the compare
- if (i1 != e1) {
+ if (v1.segmentCount() > commonlen) {
// v1 is longer
- if (*i1 != 0)
- return *i1;
+ if (v1.segmentAt(commonlen) != 0)
+ return v1.segmentAt(commonlen);
else
return 1;
- } else if (i2 != e2) {
+ } else if (v2.segmentCount() > commonlen) {
// v2 is longer
- if (*i2 != 0)
- return -*i2;
+ if (v2.segmentAt(commonlen) != 0)
+ return -v2.segmentAt(commonlen);
else
return -1;
}
@@ -271,13 +304,20 @@ int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2)
QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1,
const QVersionNumber &v2)
{
- int min = qMin(v1.m_segments.size(), v2.m_segments.size());
- QVector<int>::const_iterator i1 = v1.m_segments.begin();
- QVector<int>::const_iterator e1;
- e1 = std::mismatch(i1,
- v1.m_segments.begin() + min,
- v2.m_segments.begin()).first;
- return QVersionNumber(v1.m_segments.mid(0, e1 - i1));
+ int commonlen = qMin(v1.segmentCount(), v2.segmentCount());
+ int i;
+ for (i = 0; i < commonlen; ++i) {
+ if (v1.segmentAt(i) != v2.segmentAt(i))
+ break;
+ }
+
+ if (i == 0)
+ return QVersionNumber();
+
+ // try to use the one with inline segments, if there's one
+ QVersionNumber result(!v1.m_segments.isUsingPointer() ? v1 : v2);
+ result.m_segments.resize(i);
+ return result;
}
/*!
@@ -348,12 +388,12 @@ QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1,
QString QVersionNumber::toString() const
{
QString version;
- version.reserve(qMax(m_segments.size() * 2 - 1, 0));
+ version.reserve(qMax(segmentCount() * 2 - 1, 0));
bool first = true;
- for (QVector<int>::const_iterator it = m_segments.begin(), end = m_segments.end(); it != end; ++it) {
+ for (int i = 0; i < segmentCount(); ++i) {
if (!first)
version += QLatin1Char('.');
- version += QString::number(*it);
+ version += QString::number(segmentAt(i));
first = false;
}
return version;
@@ -401,19 +441,17 @@ QVersionNumber QVersionNumber::fromString(const QString &string, int *suffixInde
return QVersionNumber(qMove(seg));
}
-/*!
- \fn QVersionNumber QVersionNumber::normalizedImpl(QVector<int> &segs)
-
- Implementation of the normalized() function. Takes the movable list \a segs
- and normalizes them.
-
- \internal
- */
-QVersionNumber QVersionNumber::normalizedImpl(QVector<int> &segs)
+void QVersionNumber::SegmentStorage::setVector(int len, int maj, int min, int mic)
{
- while (segs.size() && segs.last() == 0)
- segs.pop_back();
- return QVersionNumber(qMove(segs));
+ pointer_segments = new QVector<int>;
+ pointer_segments->resize(len);
+ pointer_segments->data()[0] = maj;
+ if (len > 1) {
+ pointer_segments->data()[1] = min;
+ if (len > 2) {
+ pointer_segments->data()[2] = mic;
+ }
+ }
}
#ifndef QT_NO_DATASTREAM
@@ -442,7 +480,9 @@ QDataStream& operator<<(QDataStream &out, const QVersionNumber &version)
*/
QDataStream& operator>>(QDataStream &in, QVersionNumber &version)
{
- in >> version.m_segments;
+ if (!version.m_segments.isUsingPointer())
+ version.m_segments.pointer_segments = new QVector<int>;
+ in >> *version.m_segments.pointer_segments;
return in;
}
#endif
@@ -459,14 +499,18 @@ QDebug operator<<(QDebug debug, const QVersionNumber &version)
/*!
\fn uint qHash(const QVersionNumber &key, uint seed)
\relates QHash
- \since 5.4
+ \since 5.6
Returns the hash value for the \a key, using \a seed to seed the
calculation.
*/
uint qHash(const QVersionNumber &key, uint seed)
{
- return qHashRange(key.m_segments.begin(), key.m_segments.end(), seed);
+ QtPrivate::QHashCombine hash;
+ for (int i = 0; i < key.segmentCount(); ++i)
+ seed = hash(seed, key.segmentAt(i));
+ return seed;
}
QT_END_NAMESPACE
+
diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h
new file mode 100644
index 0000000000..ebf1844f38
--- /dev/null
+++ b/src/corelib/tools/qversionnumber.h
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QVERSIONNUMBER_H
+#define QVERSIONNUMBER_H
+
+#include <QtCore/qnamespace.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qmetatype.h>
+#include <QtCore/qtypeinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVersionNumber;
+Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed = 0);
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream& operator<<(QDataStream &out, const QVersionNumber &version);
+Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version);
+#endif
+
+class QVersionNumber
+{
+ /*
+ * QVersionNumber stores small values inline, without memory allocation.
+ * We do that by setting the LSB in the pointer that would otherwise hold
+ * the longer form of the segments.
+ * The constants below help us deal with the permutations for 32- and 64-bit,
+ * little- and big-endian architectures.
+ */
+ enum {
+ // in little-endian, inline_segments[0] is shared with the pointer's LSB, while
+ // in big-endian, it's inline_segments[7]
+ InlineSegmentMarker = Q_BYTE_ORDER == Q_LITTLE_ENDIAN ? 0 : sizeof(void*) - 1,
+ InlineSegmentStartIdx = !InlineSegmentMarker, // 0 for BE, 1 for LE
+ InlineSegmentCount = sizeof(void*) - 1
+ };
+ Q_STATIC_ASSERT(InlineSegmentCount >= 3); // at least major, minor, micro
+
+ struct SegmentStorage {
+ // Note: we alias the use of dummy and inline_segments in the use of the
+ // union below. This is undefined behavior in C++98, but most compilers implement
+ // the C++11 behavior. The one known exception is older versions of Sun Studio.
+ union {
+ quintptr dummy;
+ qint8 inline_segments[sizeof(void*)];
+ QVector<int> *pointer_segments;
+ };
+
+ // set the InlineSegmentMarker and set length to zero
+ SegmentStorage() Q_DECL_NOTHROW : dummy(1) {}
+
+ SegmentStorage(const QVector<int> &seg)
+ {
+ if (dataFitsInline(seg.begin(), seg.size()))
+ setInlineData(seg.begin(), seg.size());
+ else
+ pointer_segments = new QVector<int>(seg);
+ }
+
+ SegmentStorage(const SegmentStorage &other)
+ {
+ if (other.isUsingPointer())
+ pointer_segments = new QVector<int>(*other.pointer_segments);
+ else
+ dummy = other.dummy;
+ }
+
+ SegmentStorage &operator=(const SegmentStorage &other)
+ {
+ if (isUsingPointer() && other.isUsingPointer()) {
+ *pointer_segments = *other.pointer_segments;
+ } else if (other.isUsingPointer()) {
+ pointer_segments = new QVector<int>(*other.pointer_segments);
+ } else {
+ if (isUsingPointer())
+ delete pointer_segments;
+ dummy = other.dummy;
+ }
+ return *this;
+ }
+
+#ifdef Q_COMPILER_RVALUE_REFS
+ SegmentStorage(SegmentStorage &&other) Q_DECL_NOTHROW
+ : dummy(other.dummy)
+ {
+ other.dummy = 1;
+ }
+
+ SegmentStorage &operator=(SegmentStorage &&other) Q_DECL_NOTHROW
+ {
+ qSwap(dummy, other.dummy);
+ return *this;
+ }
+
+ explicit SegmentStorage(QVector<int> &&seg)
+ {
+ if (dataFitsInline(seg.begin(), seg.size()))
+ setInlineData(seg.begin(), seg.size());
+ else
+ pointer_segments = new QVector<int>(std::move(seg));
+ }
+#endif
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ SegmentStorage(std::initializer_list<int> args)
+ {
+ if (dataFitsInline(args.begin(), int(args.size()))) {
+ setInlineData(args.begin(), int(args.size()));
+ } else {
+ pointer_segments = new QVector<int>(args);
+ }
+ }
+#endif
+
+ ~SegmentStorage() { if (isUsingPointer()) delete pointer_segments; }
+
+ bool isUsingPointer() const Q_DECL_NOTHROW
+ { return (inline_segments[InlineSegmentMarker] & 1) == 0; }
+
+ int size() const Q_DECL_NOTHROW
+ { return isUsingPointer() ? pointer_segments->size() : (inline_segments[InlineSegmentMarker] >> 1); }
+
+ void setInlineSize(int len)
+ { inline_segments[InlineSegmentMarker] = 1 + 2 * len; }
+
+ void resize(int len)
+ {
+ if (isUsingPointer())
+ pointer_segments->resize(len);
+ else
+ setInlineSize(len);
+ }
+
+ int at(int index) const
+ {
+ return isUsingPointer() ?
+ pointer_segments->at(index) :
+ inline_segments[InlineSegmentStartIdx + index];
+ }
+
+ void setSegments(int len, int maj, int min = 0, int mic = 0)
+ {
+ if (maj == qint8(maj) && min == qint8(min) && mic == qint8(mic)) {
+ int data[] = { maj, min, mic };
+ setInlineData(data, len);
+ } else {
+ setVector(len, maj, min, mic);
+ }
+ }
+
+ private:
+ static bool dataFitsInline(const int *data, int len)
+ {
+ if (len > InlineSegmentCount)
+ return false;
+ for (int i = 0; i < len; ++i)
+ if (data[i] != qint8(data[i]))
+ return false;
+ return true;
+ }
+ void setInlineData(const int *data, int len)
+ {
+ dummy = 1 + len * 2;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ for (int i = 0; i < len; ++i)
+ dummy |= quintptr(data[i] & 0xFF) << (8 * (i + 1));
+#elif Q_BYTE_ORDER == Q_BIG_ENDIAN
+ for (int i = 0; i < len; ++i)
+ dummy |= quintptr(data[i] & 0xFF) << (8 * (sizeof(void *) - i - 1));
+#else
+ // the code above is equivalent to:
+ setInlineSize(len);
+ for (int i = 0; i < len; ++i)
+ inline_segments[InlineSegmentStartIdx + i] = data[i] & 0xFF;
+#endif
+ }
+
+ Q_CORE_EXPORT void setVector(int len, int maj, int min, int mic);
+ } m_segments;
+
+public:
+ inline QVersionNumber() Q_DECL_NOTHROW
+ : m_segments()
+ {}
+ inline explicit QVersionNumber(const QVector<int> &seg)
+ : m_segments(seg)
+ {}
+
+ // compiler-generated copy/move ctor/assignment operators and the destructor are ok
+
+#ifdef Q_COMPILER_RVALUE_REFS
+ explicit QVersionNumber(QVector<int> &&seg)
+ : m_segments(std::move(seg))
+ {}
+#endif
+
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ inline QVersionNumber(std::initializer_list<int> args)
+ : m_segments(args)
+ {}
+#endif
+
+ inline explicit QVersionNumber(int maj)
+ { m_segments.setSegments(1, maj); }
+
+ inline explicit QVersionNumber(int maj, int min)
+ { m_segments.setSegments(2, maj, min); }
+
+ inline explicit QVersionNumber(int maj, int min, int mic)
+ { m_segments.setSegments(3, maj, min, mic); }
+
+ inline bool isNull() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
+ { return segmentCount() == 0; }
+
+ inline bool isNormalized() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
+ { return isNull() || segmentAt(segmentCount() - 1) != 0; }
+
+ inline int majorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
+ { return segmentAt(0); }
+
+ inline int minorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
+ { return segmentAt(1); }
+
+ inline int microVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
+ { return segmentAt(2); }
+
+ Q_CORE_EXPORT QVersionNumber normalized() const Q_REQUIRED_RESULT;
+
+ Q_CORE_EXPORT QVector<int> segments() const Q_REQUIRED_RESULT;
+
+ inline int segmentAt(int index) const Q_DECL_NOTHROW Q_REQUIRED_RESULT
+ { return (m_segments.size() > index) ? m_segments.at(index) : 0; }
+
+ inline int segmentCount() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
+ { return m_segments.size(); }
+
+ Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW Q_REQUIRED_RESULT;
+
+ Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW Q_REQUIRED_RESULT;
+
+ Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2) Q_REQUIRED_RESULT;
+
+ Q_CORE_EXPORT QString toString() const Q_REQUIRED_RESULT;
+ Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = 0) Q_REQUIRED_RESULT;
+
+private:
+#ifndef QT_NO_DATASTREAM
+ friend Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version);
+#endif
+ friend Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed);
+};
+
+Q_DECLARE_TYPEINFO(QVersionNumber, Q_MOVABLE_TYPE);
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QVersionNumber &version);
+#endif
+
+Q_REQUIRED_RESULT inline bool operator> (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
+{ return QVersionNumber::compare(lhs, rhs) > 0; }
+
+Q_REQUIRED_RESULT inline bool operator>=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
+{ return QVersionNumber::compare(lhs, rhs) >= 0; }
+
+Q_REQUIRED_RESULT inline bool operator< (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
+{ return QVersionNumber::compare(lhs, rhs) < 0; }
+
+Q_REQUIRED_RESULT inline bool operator<=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
+{ return QVersionNumber::compare(lhs, rhs) <= 0; }
+
+Q_REQUIRED_RESULT inline bool operator==(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
+{ return QVersionNumber::compare(lhs, rhs) == 0; }
+
+Q_REQUIRED_RESULT inline bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
+{ return QVersionNumber::compare(lhs, rhs) != 0; }
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QVersionNumber)
+
+#endif //QVERSIONNUMBER_H
diff --git a/src/corelib/tools/qversionnumber_p.h b/src/corelib/tools/qversionnumber_p.h
deleted file mode 100644
index 2da3103be3..0000000000
--- a/src/corelib/tools/qversionnumber_p.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVERSIONNUMBER_H
-#define QVERSIONNUMBER_H
-
-#include <QtCore/qnamespace.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qmetatype.h>
-#include <QtCore/qtypeinfo.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVersionNumber;
-Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed = 0);
-
-#ifndef QT_NO_DATASTREAM
-Q_CORE_EXPORT QDataStream& operator<<(QDataStream &out, const QVersionNumber &version);
-Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version);
-#endif
-
-class QVersionNumber
-{
-public:
- inline QVersionNumber() Q_DECL_NOTHROW
- : m_segments()
- {}
- // compiler-generated copy/move ctor/assignment operators are ok
-
- inline explicit QVersionNumber(const QVector<int> &seg) Q_DECL_NOTHROW
- : m_segments(seg)
- {}
-#ifdef Q_COMPILER_RVALUE_REFS
- inline explicit QVersionNumber(QVector<int> &&seg) Q_DECL_NOTHROW
- : m_segments(qMove(seg))
- {}
-#endif
-#ifdef Q_COMPILER_INITIALIZER_LISTS
- inline QVersionNumber(std::initializer_list<int> args)
- : m_segments(args)
- {}
-#endif
-
- inline explicit QVersionNumber(int maj)
- { m_segments.reserve(1); m_segments << maj; }
-
- inline explicit QVersionNumber(int maj, int min)
- { m_segments.reserve(2); m_segments << maj << min; }
-
- inline explicit QVersionNumber(int maj, int min, int mic)
- { m_segments.reserve(3); m_segments << maj << min << mic; }
-
- inline bool isNull() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return m_segments.isEmpty(); }
-
- inline bool isNormalized() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return isNull() || m_segments.last() != 0; }
-
- inline int majorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return segmentAt(0); }
-
- inline int minorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return segmentAt(1); }
-
- inline int microVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return segmentAt(2); }
-
-#if defined(Q_COMPILER_REF_QUALIFIERS)
-# if defined(Q_CC_GNU)
- // required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941
-# pragma push_macro("Q_REQUIRED_RESULT")
-# undef Q_REQUIRED_RESULT
-# define Q_REQUIRED_RESULT
-# define Q_REQUIRED_RESULT_pushed
-# endif
- inline QVersionNumber normalized() const & Q_REQUIRED_RESULT
- {
- QVector<int> segs(m_segments);
- return normalizedImpl(segs);
- }
-
- inline QVersionNumber normalized() && Q_REQUIRED_RESULT
- {
- return normalizedImpl(m_segments);
- }
-
- inline QVector<int> segments() const & Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return m_segments; }
-
- inline QVector<int> segments() && Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return qMove(m_segments); }
-
-# ifdef Q_REQUIRED_RESULT_pushed
-# pragma pop_macro("Q_REQUIRED_RESULT")
-# endif
-#else
- inline QVersionNumber normalized() const Q_REQUIRED_RESULT
- {
- QVector<int> segs(m_segments);
- return normalizedImpl(segs);
- }
-
- inline QVector<int> segments() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return m_segments; }
-#endif
-
- inline int segmentAt(int index) const Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return (m_segments.size() > index) ? m_segments.at(index) : 0; }
-
- inline int segmentCount() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
- { return m_segments.size(); }
-
- Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW Q_REQUIRED_RESULT;
-
- Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW Q_REQUIRED_RESULT;
-
- Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2) Q_REQUIRED_RESULT;
-
- Q_CORE_EXPORT QString toString() const Q_REQUIRED_RESULT;
- Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = 0) Q_REQUIRED_RESULT;
-
-private:
- Q_CORE_EXPORT static QVersionNumber normalizedImpl(QVector<int> &segs) Q_REQUIRED_RESULT;
-
-#ifndef QT_NO_DATASTREAM
- friend Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version);
-#endif
- friend Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed);
-
- QVector<int> m_segments;
-};
-
-Q_DECLARE_TYPEINFO(QVersionNumber, Q_MOVABLE_TYPE);
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_CORE_EXPORT QDebug operator<<(QDebug, const QVersionNumber &version);
-#endif
-
-Q_REQUIRED_RESULT inline bool operator> (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
-{ return QVersionNumber::compare(lhs, rhs) > 0; }
-
-Q_REQUIRED_RESULT inline bool operator>=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
-{ return QVersionNumber::compare(lhs, rhs) >= 0; }
-
-Q_REQUIRED_RESULT inline bool operator< (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
-{ return QVersionNumber::compare(lhs, rhs) < 0; }
-
-Q_REQUIRED_RESULT inline bool operator<=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
-{ return QVersionNumber::compare(lhs, rhs) <= 0; }
-
-Q_REQUIRED_RESULT inline bool operator==(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
-{ return QVersionNumber::compare(lhs, rhs) == 0; }
-
-Q_REQUIRED_RESULT inline bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
-{ return QVersionNumber::compare(lhs, rhs) != 0; }
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QVersionNumber)
-
-#endif //QVERSIONNUMBER_H
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 5de0c09a4d..c43fd761d8 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -9,6 +9,7 @@ HEADERS += \
tools/qarraydatapointer.h \
tools/qbitarray.h \
tools/qbytearray.h \
+ tools/qbytearray_p.h \
tools/qbytearraylist.h \
tools/qbytearraymatcher.h \
tools/qbytedata_p.h \
@@ -26,6 +27,7 @@ HEADERS += \
tools/qeasingcurve.h \
tools/qfreelist_p.h \
tools/qhash.h \
+ tools/qhashfunctions.h \
tools/qiterator.h \
tools/qline.h \
tools/qlinkedlist.h \
@@ -73,7 +75,7 @@ HEADERS += \
tools/qunicodetools_p.h \
tools/qvarlengtharray.h \
tools/qvector.h \
- tools/qversionnumber_p.h
+ tools/qversionnumber.h
SOURCES += \
@@ -105,6 +107,7 @@ SOURCES += \
tools/qrect.cpp \
tools/qregexp.cpp \
tools/qrefcount.cpp \
+ tools/qringbuffer.cpp \
tools/qshareddata.cpp \
tools/qsharedpointer.cpp \
tools/qsimd.cpp \
diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h
index 21188bc5e0..7b1ea624c5 100644
--- a/src/corelib/xml/qxmlstream.h
+++ b/src/corelib/xml/qxmlstream.h
@@ -75,6 +75,28 @@ public:
QXmlStreamAttribute(const QString &qualifiedName, const QString &value);
QXmlStreamAttribute(const QString &namespaceUri, const QString &name, const QString &value);
QXmlStreamAttribute(const QXmlStreamAttribute &);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QXmlStreamAttribute(QXmlStreamAttribute &&other) Q_DECL_NOTHROW // = default;
+ : m_name(std::move(other.m_name)),
+ m_namespaceUri(std::move(other.m_namespaceUri)),
+ m_qualifiedName(std::move(other.m_qualifiedName)),
+ m_value(std::move(other.m_value)),
+ reserved(other.reserved),
+ m_isDefault(other.m_isDefault)
+ {
+ other.reserved = Q_NULLPTR;
+ }
+ QXmlStreamAttribute &operator=(QXmlStreamAttribute &&other) Q_DECL_NOTHROW // = default;
+ {
+ m_name = std::move(other.m_name);
+ m_namespaceUri = std::move(other.m_namespaceUri);
+ m_qualifiedName = std::move(other.m_qualifiedName);
+ m_value = std::move(other.m_value);
+ qSwap(reserved, other.reserved);
+ m_isDefault = other.m_isDefault;
+ return *this;
+ }
+#endif
QXmlStreamAttribute& operator=(const QXmlStreamAttribute &);
~QXmlStreamAttribute();
inline QStringRef namespaceUri() const { return m_namespaceUri; }