summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/.prev_CMakeLists.txt20
-rw-r--r--src/corelib/CMakeLists.txt30
-rw-r--r--src/corelib/Qt6CoreMacros.cmake5
-rw-r--r--src/corelib/animation/qabstractanimation.cpp4
-rw-r--r--src/corelib/animation/qanimationgroup.cpp25
-rw-r--r--src/corelib/animation/qanimationgroup_p.h2
-rw-r--r--src/corelib/animation/qsequentialanimationgroup.cpp3
-rw-r--r--src/corelib/animation/qvariantanimation.cpp4
-rw-r--r--src/corelib/codecs/qlatincodec.cpp4
-rw-r--r--src/corelib/codecs/qsimplecodec.cpp6
-rw-r--r--src/corelib/codecs/qtextcodec.cpp24
-rw-r--r--src/corelib/doc/qtcore.qdocconf1
-rw-r--r--src/corelib/doc/snippets/code/doc_src_qset.cpp12
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qlinkedlist.cpp8
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp2
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp12
-rw-r--r--src/corelib/doc/src/cmake-macros.qdoc2
-rw-r--r--src/corelib/doc/src/containers.qdoc2
-rw-r--r--src/corelib/doc/src/dontdocument.qdoc41
-rw-r--r--src/corelib/global/global.pri15
-rw-r--r--src/corelib/global/qfloat16.cpp1
-rw-r--r--src/corelib/global/qfloat16tables.cpp3266
-rw-r--r--src/corelib/global/qglobal.cpp11
-rw-r--r--src/corelib/global/qglobal.h2
-rw-r--r--src/corelib/global/qglobalstatic.h14
-rw-r--r--src/corelib/global/qlibraryinfo.cpp35
-rw-r--r--src/corelib/global/qlibraryinfo.h1
-rw-r--r--src/corelib/global/qlogging.cpp79
-rw-r--r--src/corelib/global/qmalloc.cpp8
-rw-r--r--src/corelib/global/qnamespace.qdoc2
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp8
-rw-r--r--src/corelib/global/qoperatingsystemversion.h1
-rw-r--r--src/corelib/global/qrandom.cpp30
-rw-r--r--src/corelib/global/qrandom.h10
-rw-r--r--src/corelib/global/qrandom_p.h4
-rw-r--r--src/corelib/io/forkfd_qt.cpp2
-rw-r--r--src/corelib/io/qabstractfileengine.cpp10
-rw-r--r--src/corelib/io/qbuffer.cpp2
-rw-r--r--src/corelib/io/qdebug.cpp36
-rw-r--r--src/corelib/io/qdebug.h9
-rw-r--r--src/corelib/io/qdir.cpp4
-rw-r--r--src/corelib/io/qdiriterator.cpp38
-rw-r--r--src/corelib/io/qfile.cpp8
-rw-r--r--src/corelib/io/qfiledevice.cpp4
-rw-r--r--src/corelib/io/qfileinfo.cpp16
-rw-r--r--src/corelib/io/qfileselector.cpp11
-rw-r--r--src/corelib/io/qfilesystemengine.cpp4
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp4
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp6
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm30
-rw-r--r--src/corelib/io/qfilesystemwatcher_polling.cpp17
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp6
-rw-r--r--src/corelib/io/qfsfileengine.cpp16
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp20
-rw-r--r--src/corelib/io/qiodevice.cpp2
-rw-r--r--src/corelib/io/qipaddress.cpp10
-rw-r--r--src/corelib/io/qipaddress_p.h2
-rw-r--r--src/corelib/io/qloggingcategory.cpp18
-rw-r--r--src/corelib/io/qloggingcategory.h16
-rw-r--r--src/corelib/io/qloggingregistry.cpp4
-rw-r--r--src/corelib/io/qprocess_p.h2
-rw-r--r--src/corelib/io/qprocess_unix.cpp2
-rw-r--r--src/corelib/io/qresource.cpp22
-rw-r--r--src/corelib/io/qsavefile.cpp12
-rw-r--r--src/corelib/io/qsettings.cpp4
-rw-r--r--src/corelib/io/qstandardpaths_android.cpp2
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp7
-rw-r--r--src/corelib/io/qtemporaryfile.cpp6
-rw-r--r--src/corelib/io/qtemporaryfile_p.h6
-rw-r--r--src/corelib/io/qurl.cpp67
-rw-r--r--src/corelib/io/qurlidna.cpp6
-rw-r--r--src/corelib/io/qurlquery.cpp14
-rw-r--r--src/corelib/io/qurlrecode.cpp2
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp2
-rw-r--r--src/corelib/itemmodels/qtransposeproxymodel.cpp2
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp2
-rw-r--r--src/corelib/kernel/qbasictimer.cpp2
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm31
-rw-r--r--src/corelib/kernel/qcore_mac_p.h71
-rw-r--r--src/corelib/kernel/qcore_unix_p.h6
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp69
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h4
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp12
-rw-r--r--src/corelib/kernel/qcoreevent.cpp6
-rw-r--r--src/corelib/kernel/qcoreglobaldata.cpp4
-rw-r--r--src/corelib/kernel/qelapsedtimer.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp6
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp8
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp58
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h4
-rw-r--r--src/corelib/kernel/qeventloop.cpp12
-rw-r--r--src/corelib/kernel/qeventloop_p.h4
-rw-r--r--src/corelib/kernel/qjni.cpp8
-rw-r--r--src/corelib/kernel/qmetatype.cpp74
-rw-r--r--src/corelib/kernel/qmetatype.h9
-rw-r--r--src/corelib/kernel/qmetatype_p.h18
-rw-r--r--src/corelib/kernel/qmetatypeswitcher_p.h2
-rw-r--r--src/corelib/kernel/qobject.cpp335
-rw-r--r--src/corelib/kernel/qobject.h15
-rw-r--r--src/corelib/kernel/qobject_p.h28
-rw-r--r--src/corelib/kernel/qobjectdefs.h14
-rw-r--r--src/corelib/kernel/qpointer.h3
-rw-r--r--src/corelib/kernel/qpoll.cpp9
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp19
-rw-r--r--src/corelib/kernel/qsharedmemory.h29
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h12
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp7
-rw-r--r--src/corelib/kernel/qsharedmemory_win.cpp5
-rw-r--r--src/corelib/kernel/qsocketnotifier.cpp6
-rw-r--r--src/corelib/kernel/qsystemerror.cpp2
-rw-r--r--src/corelib/kernel/qsystemsemaphore_systemv.cpp6
-rw-r--r--src/corelib/kernel/qtranslator.cpp7
-rw-r--r--src/corelib/kernel/qvariant.cpp46
-rw-r--r--src/corelib/kernel/qvariant.h2
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp6
-rw-r--r--src/corelib/mimetypes/qmimetype.cpp26
-rw-r--r--src/corelib/mimetypes/qmimetype.h2
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp2
-rw-r--r--src/corelib/plugin/qlibrary.cpp16
-rw-r--r--src/corelib/plugin/qlibrary_p.h2
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp12
-rw-r--r--src/corelib/serialization/qcborstream.h4
-rw-r--r--src/corelib/serialization/qcborvalue.cpp16
-rw-r--r--src/corelib/serialization/qdatastream.cpp14
-rw-r--r--src/corelib/serialization/qjson_p.h2
-rw-r--r--src/corelib/serialization/qjsonarray.cpp8
-rw-r--r--src/corelib/serialization/qjsoncbor.cpp10
-rw-r--r--src/corelib/serialization/qjsondocument.cpp10
-rw-r--r--src/corelib/serialization/qjsonobject.cpp10
-rw-r--r--src/corelib/serialization/qjsonparser.cpp4
-rw-r--r--src/corelib/serialization/qjsonvalue.cpp16
-rw-r--r--src/corelib/serialization/qjsonwriter.cpp6
-rw-r--r--src/corelib/serialization/qtextstream.cpp26
-rw-r--r--src/corelib/serialization/qxmlstream.cpp26
-rw-r--r--src/corelib/serialization/qxmlstream.g2
-rw-r--r--src/corelib/thread/qatomic.cpp75
-rw-r--r--src/corelib/thread/qatomic.h6
-rw-r--r--src/corelib/thread/qatomic_cxx11.h18
-rw-r--r--src/corelib/thread/qbasicatomic.h14
-rw-r--r--src/corelib/thread/qfuture.h82
-rw-r--r--src/corelib/thread/qfuture.qdoc8
-rw-r--r--src/corelib/thread/qfutureinterface.cpp42
-rw-r--r--src/corelib/thread/qfutureinterface_p.h4
-rw-r--r--src/corelib/thread/qfuturewatcher.cpp16
-rw-r--r--src/corelib/thread/qgenericatomic.h22
-rw-r--r--src/corelib/thread/qmutex.cpp144
-rw-r--r--src/corelib/thread/qmutex.h36
-rw-r--r--src/corelib/thread/qmutex_linux.cpp4
-rw-r--r--src/corelib/thread/qmutex_p.h10
-rw-r--r--src/corelib/thread/qmutexpool.cpp11
-rw-r--r--src/corelib/thread/qmutexpool_p.h2
-rw-r--r--src/corelib/thread/qreadwritelock.cpp12
-rw-r--r--src/corelib/thread/qsemaphore.cpp6
-rw-r--r--src/corelib/thread/qthread.cpp27
-rw-r--r--src/corelib/thread/qthread_p.h7
-rw-r--r--src/corelib/thread/qthread_unix.cpp51
-rw-r--r--src/corelib/thread/qthread_win.cpp12
-rw-r--r--src/corelib/thread/qthreadstorage.cpp6
-rw-r--r--src/corelib/time/qdatetime.cpp324
-rw-r--r--src/corelib/time/qdatetime.h4
-rw-r--r--src/corelib/time/qdatetime_p.h4
-rw-r--r--src/corelib/time/qdatetimeparser.cpp27
-rw-r--r--src/corelib/time/qtimezoneprivate_tz.cpp52
-rw-r--r--src/corelib/tools/qarraydata.cpp6
-rw-r--r--src/corelib/tools/qarraydata.h10
-rw-r--r--src/corelib/tools/qarraydataops.h4
-rw-r--r--src/corelib/tools/qbytearray.cpp23
-rw-r--r--src/corelib/tools/qbytearray.h2
-rw-r--r--src/corelib/tools/qbytearraylist.h3
-rw-r--r--src/corelib/tools/qbytearraymatcher.cpp10
-rw-r--r--src/corelib/tools/qchar.cpp2
-rw-r--r--src/corelib/tools/qcollator.cpp2
-rw-r--r--src/corelib/tools/qcontiguouscache.h14
-rw-r--r--src/corelib/tools/qfreelist_p.h14
-rw-r--r--src/corelib/tools/qhash.cpp16
-rw-r--r--src/corelib/tools/qiterator.h13
-rw-r--r--src/corelib/tools/qlinkedlist.cpp6
-rw-r--r--src/corelib/tools/qlinkedlist.h2
-rw-r--r--src/corelib/tools/qlist.cpp2
-rw-r--r--src/corelib/tools/qlocale.cpp8
-rw-r--r--src/corelib/tools/qlocale_p.h6
-rw-r--r--src/corelib/tools/qlocale_tools.cpp4
-rw-r--r--src/corelib/tools/qmap.cpp30
-rw-r--r--src/corelib/tools/qrect.cpp4
-rw-r--r--src/corelib/tools/qrefcount.h14
-rw-r--r--src/corelib/tools/qregexp.cpp26
-rw-r--r--src/corelib/tools/qregularexpression.cpp29
-rw-r--r--src/corelib/tools/qringbuffer.cpp2
-rw-r--r--src/corelib/tools/qset.h27
-rw-r--r--src/corelib/tools/qshareddata.h4
-rw-r--r--src/corelib/tools/qsharedpointer.cpp10
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h44
-rw-r--r--src/corelib/tools/qsimd.cpp4
-rw-r--r--src/corelib/tools/qsimd_p.h4
-rw-r--r--src/corelib/tools/qstring.cpp553
-rw-r--r--src/corelib/tools/qstring.h111
-rw-r--r--src/corelib/tools/qstringalgorithms.h5
-rw-r--r--src/corelib/tools/qstringlist.cpp64
-rw-r--r--src/corelib/tools/qstringlist.h54
-rw-r--r--src/corelib/tools/qstringmatcher.cpp6
-rw-r--r--src/corelib/tools/qstringview.cpp36
-rw-r--r--src/corelib/tools/qstringview.h9
-rw-r--r--src/corelib/tools/qunicodetools.cpp2
-rw-r--r--src/corelib/tools/qvarlengtharray.h12
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc8
-rw-r--r--src/corelib/tools/qvector.h1
-rw-r--r--src/corelib/tools/qvector.qdoc23
208 files changed, 5978 insertions, 1601 deletions
diff --git a/src/corelib/.prev_CMakeLists.txt b/src/corelib/.prev_CMakeLists.txt
index f1000e6301..bab176c132 100644
--- a/src/corelib/.prev_CMakeLists.txt
+++ b/src/corelib/.prev_CMakeLists.txt
@@ -409,19 +409,19 @@ extend_target(Core CONDITION INTEGRITY
# CMAKE_INSTALL_DATA_DIR = "$$[QT_HOST_DATA]/"
# CMAKE_INSTALL_DATA_DIR_IS_ABSOLUTE = "True"
-#### Keys ignored in scope 17:.:global:global/global.pri:QT_CPU_FEATURES__ss_QT_ARCH___contains___f16c:
+#### Keys ignored in scope 18:.:global:global/global.pri:QT_CPU_FEATURES__ss_QT_ARCH___contains___f16c:
# f16c_cxx = "true"
-#### Keys ignored in scope 19:.:global:global/global.pri:CLANG OR intel_icl OR ICC:
+#### Keys ignored in scope 20:.:global:global/global.pri:CLANG OR intel_icl OR ICC:
# f16c_cxx = "false"
-#### Keys ignored in scope 21:.:global:global/global.pri:GCC AND f16c AND x86SimdAlways:
+#### Keys ignored in scope 22:.:global:global/global.pri:GCC AND f16c AND x86SimdAlways:
# f16c_cxx = "true"
-#### Keys ignored in scope 23:.:global:global/global.pri:MSVC AND QT_CPU_FEATURES__ss_QT_ARCH___contains___avx:
+#### Keys ignored in scope 24:.:global:global/global.pri:MSVC AND QT_CPU_FEATURES__ss_QT_ARCH___contains___avx:
# f16c_cxx = "true"
-#### Keys ignored in scope 24:.:global:global/global.pri:else:
+#### Keys ignored in scope 25:.:global:global/global.pri:else:
# f16c_cxx = "false"
extend_target(Core CONDITION _ss_f16c_cxx
@@ -429,7 +429,7 @@ extend_target(Core CONDITION _ss_f16c_cxx
QFLOAT16_INCLUDE_FAST
)
-#### Keys ignored in scope 26:.:global:global/global.pri:else:
+#### Keys ignored in scope 27:.:global:global/global.pri:else:
# F16C_SOURCES = "global/qfloat16_f16c.c"
extend_target(Core CONDITION linux_x_ OR hurd_x_ AND NOT cross_compile AND NOT static AND NOT _x_-armcc_x_
@@ -444,7 +444,7 @@ extend_target(Core CONDITION LINUX AND NOT static
global/minimum-linux_p.h
)
-#### Keys ignored in scope 31:.:global:global/global.pri:precompile_header:
+#### Keys ignored in scope 32:.:global:global/global.pri:precompile_header:
# NO_PCH_ASM = "global/minimum-linux.S"
# QMAKE_EXTRA_COMPILERS = "no_pch_assembler"
# no_pch_assembler.commands = "$$QMAKE_CC" "-c" "$(CFLAGS)" "$(INCPATH)" "${QMAKE_FILE_IN}" "-o" "${QMAKE_FILE_OUT}"
@@ -453,7 +453,7 @@ extend_target(Core CONDITION LINUX AND NOT static
# no_pch_assembler.name = "compiling[no_pch]" "${QMAKE_FILE_IN}"
# no_pch_assembler.output = "${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${firstQMAKE_EXT_OBJ}"
-#### Keys ignored in scope 32:.:global:global/global.pri:silent:
+#### Keys ignored in scope 33:.:global:global/global.pri:silent:
# no_pch_assembler.commands = "@echo" "compiling[no_pch]" "${QMAKE_FILE_IN}" "&&"
extend_target(Core CONDITION LINUX AND NOT precompile_header AND NOT static
@@ -471,7 +471,7 @@ extend_target(Core CONDITION QT_FEATURE_journald
PkgConfig::Libsystemd
)
-#### Keys ignored in scope 36:.:global:global/global.pri:GCC AND ltcg:
+#### Keys ignored in scope 37:.:global:global/global.pri:GCC AND ltcg:
# QMAKE_EXTRA_COMPILERS = "versiontagging_compiler"
# versiontagging_compiler.commands = "$$QMAKE_CXX" "-c" "$(CXXFLAGS)" "$(INCPATH)" "-fno-lto" "-o" "${QMAKE_FILE_OUT}" "${QMAKE_FILE_IN}"
# versiontagging_compiler.dependency_type = "TYPE_C"
@@ -480,7 +480,7 @@ extend_target(Core CONDITION QT_FEATURE_journald
# versiontagging_compiler.output = "${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${firstQMAKE_EXT_OBJ}"
# versiontagging_compiler.variable_out = "OBJECTS"
-#### Keys ignored in scope 37:.:global:global/global.pri:silent:
+#### Keys ignored in scope 38:.:global:global/global.pri:silent:
# versiontagging_compiler.commands = "@echo" "compiling[versiontagging]" "${QMAKE_FILE_IN}" "&&"
extend_target(Core CONDITION UNIX
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index 4d23f0f892..c901169735 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -490,24 +490,24 @@ extend_target(Core CONDITION INTEGRITY
# CMAKE_INSTALL_DATA_DIR = "$$[QT_HOST_DATA]/"
# CMAKE_INSTALL_DATA_DIR_IS_ABSOLUTE = "True"
-#### Keys ignored in scope 17:.:global:global/global.pri:QT_CPU_FEATURES__ss_QT_ARCH___contains___f16c:
+#### Keys ignored in scope 18:.:global:global/global.pri:QT_CPU_FEATURES__ss_QT_ARCH___contains___f16c:
# f16c_cxx = "true"
-#### Keys ignored in scope 19:.:global:global/global.pri:CLANG OR intel_icl OR ICC:
+#### Keys ignored in scope 20:.:global:global/global.pri:CLANG OR intel_icl OR ICC:
# f16c_cxx = "false"
-#### Keys ignored in scope 21:.:global:global/global.pri:GCC AND f16c AND x86SimdAlways:
+#### Keys ignored in scope 22:.:global:global/global.pri:GCC AND f16c AND x86SimdAlways:
# f16c_cxx = "true"
-#### Keys ignored in scope 23:.:global:global/global.pri:MSVC AND QT_CPU_FEATURES__ss_QT_ARCH___contains___avx:
+#### Keys ignored in scope 24:.:global:global/global.pri:MSVC AND QT_CPU_FEATURES__ss_QT_ARCH___contains___avx:
# f16c_cxx = "true"
-#### Keys ignored in scope 24:.:global:global/global.pri:else:
+#### Keys ignored in scope 25:.:global:global/global.pri:else:
# f16c_cxx = "false"
# extend_target(Core CONDITION _ss_f16c_cxx ... # special case: Handled manually:
-#### Keys ignored in scope 26:.:global:global/global.pri:else:
+#### Keys ignored in scope 27:.:global:global/global.pri:else:
# F16C_SOURCES = "global/qfloat16_f16c.c"
extend_target(Core CONDITION linux_x_ OR hurd_x_ AND NOT cross_compile AND NOT static AND NOT _x_-armcc_x_
@@ -522,7 +522,7 @@ extend_target(Core CONDITION LINUX AND NOT static
global/minimum-linux_p.h
)
-#### Keys ignored in scope 31:.:global:global/global.pri:precompile_header:
+#### Keys ignored in scope 32:.:global:global/global.pri:precompile_header:
# NO_PCH_ASM = "global/minimum-linux.S"
# QMAKE_EXTRA_COMPILERS = "no_pch_assembler"
# no_pch_assembler.commands = "$$QMAKE_CC" "-c" "$(CFLAGS)" "$(INCPATH)" "${QMAKE_FILE_IN}" "-o" "${QMAKE_FILE_OUT}"
@@ -531,7 +531,7 @@ extend_target(Core CONDITION LINUX AND NOT static
# no_pch_assembler.name = "compiling[no_pch]" "${QMAKE_FILE_IN}"
# no_pch_assembler.output = "${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${firstQMAKE_EXT_OBJ}"
-#### Keys ignored in scope 32:.:global:global/global.pri:silent:
+#### Keys ignored in scope 33:.:global:global/global.pri:silent:
# no_pch_assembler.commands = "@echo" "compiling[no_pch]" "${QMAKE_FILE_IN}" "&&"
extend_target(Core CONDITION LINUX AND NOT precompile_header AND NOT static
@@ -549,7 +549,7 @@ extend_target(Core CONDITION QT_FEATURE_journald
PkgConfig::Libsystemd
)
-#### Keys ignored in scope 36:.:global:global/global.pri:GCC AND ltcg:
+#### Keys ignored in scope 37:.:global:global/global.pri:GCC AND ltcg:
# QMAKE_EXTRA_COMPILERS = "versiontagging_compiler"
# versiontagging_compiler.commands = "$$QMAKE_CXX" "-c" "$(CXXFLAGS)" "$(INCPATH)" "-fno-lto" "-o" "${QMAKE_FILE_OUT}" "${QMAKE_FILE_IN}"
# versiontagging_compiler.dependency_type = "TYPE_C"
@@ -558,7 +558,7 @@ extend_target(Core CONDITION QT_FEATURE_journald
# versiontagging_compiler.output = "${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${firstQMAKE_EXT_OBJ}"
# versiontagging_compiler.variable_out = "OBJECTS"
-#### Keys ignored in scope 37:.:global:global/global.pri:silent:
+#### Keys ignored in scope 38:.:global:global/global.pri:silent:
# versiontagging_compiler.commands = "@echo" "compiling[versiontagging]" "${QMAKE_FILE_IN}" "&&"
extend_target(Core CONDITION UNIX
@@ -1063,16 +1063,6 @@ else()
)
endif()
-
-add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/global/qfloat16tables.cpp"
- COMMAND ${QT_CMAKE_EXPORT_NAMESPACE}::qfloat16-tables
- ARGS "${CMAKE_CURRENT_BINARY_DIR}/global/qfloat16tables.cpp"
- DEPENDS global/qfloat16.h
- COMMENT qfloat16-tables
- VERBATIM)
-target_sources(Core PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/global/qfloat16tables.cpp")
-
-
set_source_files_properties(
thread/qmutex_linux.cpp
thread/qmutex_mac.cpp
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index 31e5a37cd7..d5eb346871 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -296,6 +296,9 @@ endfunction()
# qt5_add_big_resources(outfiles inputfile ... )
function(QT5_ADD_BIG_RESOURCES outfiles )
+ if (CMAKE_VERSION VERSION_LESS 3.9)
+ message(FATAL_ERROR, "qt5_add_big_resources requires CMake 3.9 or newer")
+ endif()
set(options)
set(oneValueArgs)
@@ -326,6 +329,8 @@ function(QT5_ADD_BIG_RESOURCES outfiles )
set_target_properties(rcc_object_${outfilename} PROPERTIES AUTOMOC OFF)
set_target_properties(rcc_object_${outfilename} PROPERTIES AUTOUIC OFF)
add_dependencies(rcc_object_${outfilename} big_resources_${outfilename})
+ # The modification of TARGET_OBJECTS needs the following change in cmake
+ # https://gitlab.kitware.com/cmake/cmake/commit/93c89bc75ceee599ba7c08b8fe1ac5104942054f
add_custom_command(OUTPUT ${outfile}
COMMAND ${QT_CMAKE_EXPORT_NAMESPACE}::rcc
ARGS ${rcc_options} --name ${outfilename} --pass 2 --temp $<TARGET_OBJECTS:rcc_object_${outfilename}> --output ${outfile} ${infile}
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 0be37b7dca..46b01449d4 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -1063,10 +1063,12 @@ QAbstractAnimation::~QAbstractAnimation()
if (d->state != Stopped) {
QAbstractAnimation::State oldState = d->state;
d->state = Stopped;
- emit stateChanged(oldState, d->state);
+ emit stateChanged(d->state, oldState);
if (oldState == QAbstractAnimation::Running)
QAnimationTimer::unregisterAnimation(this);
}
+ if (d->group)
+ d->group->removeAnimation(this);
}
/*!
diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp
index f47d99eb68..ed40817222 100644
--- a/src/corelib/animation/qanimationgroup.cpp
+++ b/src/corelib/animation/qanimationgroup.cpp
@@ -113,6 +113,11 @@ QAnimationGroup::QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent)
*/
QAnimationGroup::~QAnimationGroup()
{
+ Q_D(QAnimationGroup);
+ // We need to clear the animations now while we are still a valid QAnimationGroup.
+ // If we wait until ~QObject() the QAbstractAnimation's pointer back to us would
+ // point to a QObject, not a valid QAnimationGroup.
+ d->clear(true);
}
/*!
@@ -256,7 +261,7 @@ QAbstractAnimation *QAnimationGroup::takeAnimation(int index)
void QAnimationGroup::clear()
{
Q_D(QAnimationGroup);
- qDeleteAll(d->animations);
+ d->clear(false);
}
/*!
@@ -284,6 +289,24 @@ bool QAnimationGroup::event(QEvent *event)
return QAbstractAnimation::event(event);
}
+void QAnimationGroupPrivate::clear(bool onDestruction)
+{
+ const QList<QAbstractAnimation *> animationsCopy = animations; // taking a copy
+ animations.clear();
+ // Clearing backwards so the indices doesn't change while we remove animations.
+ for (int i = animationsCopy.count() - 1; i >= 0; --i) {
+ QAbstractAnimation *animation = animationsCopy.at(i);
+ animation->setParent(nullptr);
+ QAbstractAnimationPrivate::get(animation)->group = nullptr;
+ // If we are in ~QAnimationGroup() it is not safe to called the virtual
+ // animationRemoved method, which can still be a method in a
+ // QAnimationGroupPrivate derived class that assumes q_ptr is still
+ // a valid derived class of QAnimationGroup.
+ if (!onDestruction)
+ animationRemoved(i, animation);
+ delete animation;
+ }
+}
void QAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *)
{
diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h
index 215734b656..4d1d690e69 100644
--- a/src/corelib/animation/qanimationgroup_p.h
+++ b/src/corelib/animation/qanimationgroup_p.h
@@ -73,6 +73,8 @@ public:
virtual void animationInsertedAt(int) { }
virtual void animationRemoved(int, QAbstractAnimation *);
+ void clear(bool onDestruction);
+
void disconnectUncontrolledAnimation(QAbstractAnimation *anim)
{
//0 for the signal here because we might be called from the animation destructor
diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp
index 150e74d7d6..66e346a2fe 100644
--- a/src/corelib/animation/qsequentialanimationgroup.cpp
+++ b/src/corelib/animation/qsequentialanimationgroup.cpp
@@ -532,7 +532,8 @@ void QSequentialAnimationGroupPrivate::animationRemoved(int index, QAbstractAnim
Q_Q(QSequentialAnimationGroup);
QAnimationGroupPrivate::animationRemoved(index, anim);
- Q_ASSERT(currentAnimation); // currentAnimation should always be set
+ if (!currentAnimation)
+ return;
if (actualDuration.size() > index)
actualDuration.removeAt(index);
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index ac81f89ed4..01a699c5dc 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -283,11 +283,11 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
qSwap(currentValue, ret);
q->updateCurrentValue(currentValue);
static QBasicAtomicInt changedSignalIndex = Q_BASIC_ATOMIC_INITIALIZER(0);
- if (!changedSignalIndex.load()) {
+ if (!changedSignalIndex.loadRelaxed()) {
//we keep the mask so that we emit valueChanged only when needed (for performance reasons)
changedSignalIndex.testAndSetRelaxed(0, signalIndex("valueChanged(QVariant)"));
}
- if (isSignalConnected(changedSignalIndex.load()) && currentValue != ret) {
+ if (isSignalConnected(changedSignalIndex.loadRelaxed()) && currentValue != ret) {
//the value has changed
emit q->valueChanged(currentValue);
}
diff --git a/src/corelib/codecs/qlatincodec.cpp b/src/corelib/codecs/qlatincodec.cpp
index 1b53d26ef4..463c5a56ae 100644
--- a/src/corelib/codecs/qlatincodec.cpp
+++ b/src/corelib/codecs/qlatincodec.cpp
@@ -48,7 +48,7 @@ QLatin1Codec::~QLatin1Codec()
QString QLatin1Codec::convertToUnicode(const char *chars, int len, ConverterState *) const
{
- if (chars == 0)
+ if (chars == nullptr)
return QString();
return QString::fromLatin1(chars, len);
@@ -104,7 +104,7 @@ QLatin15Codec::~QLatin15Codec()
QString QLatin15Codec::convertToUnicode(const char* chars, int len, ConverterState *) const
{
- if (chars == 0)
+ if (chars == nullptr)
return QString();
QString str = QString::fromLatin1(chars, len);
diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp
index 9ab545d783..16a9b8a7c3 100644
--- a/src/corelib/codecs/qsimplecodec.cpp
+++ b/src/corelib/codecs/qsimplecodec.cpp
@@ -610,7 +610,7 @@ QSimpleTextCodec::QSimpleTextCodec(int i) : forwardIndex(i), reverseMap(0)
QSimpleTextCodec::~QSimpleTextCodec()
{
- delete reverseMap.load();
+ delete reverseMap.loadAcquire();
}
static QByteArray *buildReverseMap(int forwardIndex)
@@ -662,12 +662,12 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con
const char replacement = (state && state->flags & ConvertInvalidToNull) ? 0 : '?';
int invalid = 0;
- QByteArray *rmap = reverseMap.load();
+ QByteArray *rmap = reverseMap.loadAcquire();
if (!rmap){
rmap = buildReverseMap(this->forwardIndex);
if (!reverseMap.testAndSetRelease(0, rmap)) {
delete rmap;
- rmap = reverseMap.load();
+ rmap = reverseMap.loadAcquire();
}
}
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index a86db142f9..85cfcdbf48 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -159,7 +159,7 @@ static QTextCodec *setupLocaleMapper()
{
QCoreGlobalData *globalData = QCoreGlobalData::instance();
- QTextCodec *locale = 0;
+ QTextCodec *locale = nullptr;
{
QMutexLocker locker(textCodecsMutex());
@@ -208,7 +208,7 @@ static QTextCodec *setupLocaleMapper()
// First part is getting that locale name. First try setlocale() which
// definitely knows it, but since we cannot fully trust it, get ready
// to fall back to environment variables.
- const QByteArray ctype = setlocale(LC_CTYPE, 0);
+ const QByteArray ctype = setlocale(LC_CTYPE, nullptr);
// Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG
// environment variables.
@@ -532,13 +532,13 @@ QTextCodec::~QTextCodec()
QTextCodec *QTextCodec::codecForName(const QByteArray &name)
{
if (name.isEmpty())
- return 0;
+ return nullptr;
QMutexLocker locker(textCodecsMutex());
QCoreGlobalData *globalData = QCoreGlobalData::instance();
if (!globalData)
- return 0;
+ return nullptr;
setup();
#if !QT_CONFIG(icu)
@@ -567,7 +567,7 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name)
}
}
- return 0;
+ return nullptr;
#else
return QIcuCodec::codecForNameUnlocked(name);
#endif
@@ -585,7 +585,7 @@ QTextCodec* QTextCodec::codecForMib(int mib)
QCoreGlobalData *globalData = QCoreGlobalData::instance();
if (!globalData)
- return 0;
+ return nullptr;
if (globalData->allCodecs.isEmpty())
setup();
@@ -611,7 +611,7 @@ QTextCodec* QTextCodec::codecForMib(int mib)
#if QT_CONFIG(icu)
return QIcuCodec::codecForMibUnlocked(mib);
#else
- return 0;
+ return nullptr;
#endif
}
@@ -704,7 +704,7 @@ QTextCodec* QTextCodec::codecForLocale()
{
QCoreGlobalData *globalData = QCoreGlobalData::instance();
if (!globalData)
- return 0;
+ return nullptr;
QTextCodec *codec = globalData->codecForLocale.loadAcquire();
if (!codec) {
@@ -830,7 +830,7 @@ QTextEncoder* QTextCodec::makeEncoder(QTextCodec::ConversionFlags flags) const
*/
QByteArray QTextCodec::fromUnicode(const QString& str) const
{
- return convertFromUnicode(str.constData(), str.length(), 0);
+ return convertFromUnicode(str.constData(), str.length(), nullptr);
}
#endif
@@ -863,7 +863,7 @@ QByteArray QTextCodec::fromUnicode(QStringView str) const
*/
QString QTextCodec::toUnicode(const QByteArray& a) const
{
- return convertToUnicode(a.constData(), a.length(), 0);
+ return convertToUnicode(a.constData(), a.length(), nullptr);
}
/*!
@@ -915,7 +915,7 @@ bool QTextCodec::canEncode(QStringView s) const
QString QTextCodec::toUnicode(const char *chars) const
{
int len = qstrlen(chars);
- return convertToUnicode(chars, len, 0);
+ return convertToUnicode(chars, len, nullptr);
}
@@ -1110,7 +1110,7 @@ QString QTextDecoder::toUnicode(const QByteArray &ba)
QTextCodec *QTextCodec::codecForHtml(const QByteArray &ba, QTextCodec *defaultCodec)
{
// determine charset
- QTextCodec *c = QTextCodec::codecForUtfText(ba, 0);
+ QTextCodec *c = QTextCodec::codecForUtfText(ba, nullptr);
if (!c) {
static Q_RELAXED_CONSTEXPR auto matcher = qMakeStaticByteArrayMatcher("meta ");
QByteArray header = ba.left(1024).toLower();
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 85dcde4607..15b1925e51 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtbase.qdocconf)
project = QtCore
description = Qt Core Reference Documentation
diff --git a/src/corelib/doc/snippets/code/doc_src_qset.cpp b/src/corelib/doc/snippets/code/doc_src_qset.cpp
index 7f7cec8b45..96ef07738b 100644
--- a/src/corelib/doc/snippets/code/doc_src_qset.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_qset.cpp
@@ -131,9 +131,10 @@ while (i != set.end()) {
//! [10]
QSet<QString> set;
...
-QSet<QString>::iterator it = qFind(set.begin(), set.end(), "Jeanette");
+const auto predicate = [](const QString &s) { return s.compare("Jeanette", Qt::CaseInsensitive) == 0; };
+QSet<QString>::iterator it = std::find_if(set.begin(), set.end(), predicate);
if (it != set.end())
- cout << "Found Jeanette" << Qt::endl;
+ cout << "Found Jeanette" << endl;
//! [10]
@@ -150,9 +151,10 @@ for (i = set.begin(); i != set.end(); ++i)
//! [12]
QSet<QString> set;
...
-QSet<QString>::iterator it = qFind(set.begin(), set.end(), "Jeanette");
+const auto predicate = [](const QString &s) { return s.compare("Jeanette", Qt::CaseInsensitive) == 0; };
+QSet<QString>::const_iterator it = std::find_if(set.cbegin(), set.cend(), predicate);
if (it != set.constEnd())
- cout << "Found Jeanette" << Qt::endl;
+ cout << "Found Jeanette" << endl;
//! [12]
@@ -161,7 +163,7 @@ QSet<QString> set;
set << "red" << "green" << "blue" << ... << "black";
QList<QString> list = set.toList();
-qSort(list);
+std::sort(list.begin(), list.end());
//! [13]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qlinkedlist.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qlinkedlist.cpp
index e0d3c71dc5..e8754a5f34 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qlinkedlist.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qlinkedlist.cpp
@@ -119,8 +119,8 @@ for (i = list.begin(); i != list.end(); ++i)
//! [8]
QLinkedList<QString> list;
...
-QLinkedList<QString>::iterator it = qFind(list.begin(),
- list.end(), "Joel");
+QLinkedList<QString>::iterator it = std::find(list.begin(),
+ list.end(), "Joel");
if (it != list.end())
cout << "Found Joel" << Qt::endl;
//! [8]
@@ -189,8 +189,8 @@ for (i = list.constBegin(); i != list.constEnd(); ++i)
//! [15]
QLinkedList<QString> list;
...
-QLinkedList<QString>::iterator it = qFind(list.constBegin(),
- list.constEnd(), "Joel");
+QLinkedList<QString>::const_iterator it = std::find(list.constBegin(),
+ list.constEnd(), "Joel");
if (it != list.constEnd())
cout << "Found Joel" << Qt::endl;
//! [15]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
index a24e599f2f..38fa526ef4 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
@@ -247,7 +247,7 @@ QSet<int> set;
set << 20 << 30 << 40 << ... << 70;
QList<int> list = QList<int>::fromSet(set);
-qSort(list);
+std::sort(list.begin(), list.end());
//! [23]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
index afdd9c3d25..99cd4ea7a2 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
@@ -286,15 +286,11 @@ if (!invalidRe.isValid()) {
{
//! [24]
-QRegularExpression re("^this pattern must match exactly$");
-//! [24]
-}
-
-{
-//! [25]
QString p("a .*|pattern");
-QRegularExpression re("\\A(?:" + p + ")\\z"); // re matches exactly the pattern string p
-//! [25]
+
+// re matches exactly the pattern string p
+QRegularExpression re(QRegularExpression::anchoredPattern(p));
+//! [24]
}
{
diff --git a/src/corelib/doc/src/cmake-macros.qdoc b/src/corelib/doc/src/cmake-macros.qdoc
index 6140e8be44..7fb133020f 100644
--- a/src/corelib/doc/src/cmake-macros.qdoc
+++ b/src/corelib/doc/src/cmake-macros.qdoc
@@ -131,6 +131,8 @@ files (\c .o, \c .obj) files instead of C++ source code. This allows to
embed bigger resources, where compiling to C++ sources and then to
binaries would be too time consuming or memory intensive.
+Note that this macro is only available if using \c{CMake} 3.9 or later.
+
\section1 Arguments
You can set additional \c{OPTIONS} that should be added to the \c{rcc} calls.
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index e6c95129db..919533f651 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -666,7 +666,7 @@
\li \b{Logarithmic time:} O(log \e n). A function that runs in
logarithmic time is a function whose running time is
proportional to the logarithm of the number of items in the
- container. One example is qBinaryFind().
+ container. One example is the binary search algorithm.
\li \b{Linear time:} O(\e n). A function that runs in linear time
will execute in a time directly proportional to the number of
diff --git a/src/corelib/doc/src/dontdocument.qdoc b/src/corelib/doc/src/dontdocument.qdoc
new file mode 100644
index 0000000000..19ca7db299
--- /dev/null
+++ b/src/corelib/doc/src/dontdocument.qdoc
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \dontdocument (QMacAutoReleasePool QIncompatibleFlag QGenericAtomicOps QAtomicTraits
+ QAtomicOps QBasicAtomicInteger QBasicAtomicPointer QBasicMutex QInternal
+ QArgument QReturnArgument QArrayData QTypedArrayData QStaticByteArrayData
+ QByteRef QStaticStringData QListSpecialMethods QListData QScopedPointerDeleter
+ QScopedPointerArrayDeleter QScopedPointerPodDeleter QScopedPointerObjectDeleteLater
+ QMetaTypeId2 QObjectData QObjectUserData QMapNodeBase QMapNode QMapDataBase
+ QMapData QHashData QHashNode QArrayDataPointer QTextStreamManipulator
+ QContiguousCacheData QContiguousCacheTypedData QNoDebug QUrlTwoFlags
+ QCborValueRef qfloat16 QDeferredDeleteEvent QSpecialInteger QLittleEndianStorageType
+ QBigEndianStorageType QFactoryInterface QFutureWatcherBase QJsonValuePtr
+ QJsonValueRefPtr QLinkedListNode QAbstractConcatenable QStringBuilderCommon
+ QTextCodec::ConverterState QThreadStorageData)
+*/
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index 10af46b41a..1da69aba9b 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -40,6 +40,10 @@ SOURCES += \
global/qrandom.cpp \
global/qhooks.cpp
+# To get listed in IDEs
+false: SOURCES += \
+ global/qfloat16tables.cpp
+
# Only add global/qfloat16_f16c.c if qfloat16.cpp can't #include it.
# Any compiler: if it is already generating F16C code, let qfloat16.cpp do it
# Clang: ICE if not generating F16C code, so use qfloat16_f16c.c
@@ -124,14 +128,3 @@ gcc:ltcg {
} else {
SOURCES += $$VERSIONTAGGING_SOURCES
}
-
-QMAKE_QFLOAT16_TABLES_GENERATE = global/qfloat16.h
-
-qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables)
-
-qfloat16_tables.commands = $$QMAKE_QFLOAT16_TABLES ${QMAKE_FILE_OUT}
-qfloat16_tables.output = global/qfloat16tables.cpp
-qfloat16_tables.depends = $$QMAKE_QFLOAT16_TABLES_EXE
-qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE
-qfloat16_tables.variable_out = SOURCES
-QMAKE_EXTRA_COMPILERS += qfloat16_tables
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp
index 68763c0606..ff2997b73a 100644
--- a/src/corelib/global/qfloat16.cpp
+++ b/src/corelib/global/qfloat16.cpp
@@ -239,6 +239,7 @@ Q_CORE_EXPORT void qFloatFromFloat16(float *out, const qfloat16 *in, qsizetype l
QT_END_NAMESPACE
+#include "qfloat16tables.cpp"
#ifdef QFLOAT16_INCLUDE_FAST
# include "qfloat16_f16c.c"
#endif
diff --git a/src/corelib/global/qfloat16tables.cpp b/src/corelib/global/qfloat16tables.cpp
new file mode 100644
index 0000000000..3d764937d7
--- /dev/null
+++ b/src/corelib/global/qfloat16tables.cpp
@@ -0,0 +1,3266 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 by Southwest Research Institute (R)
+** Copyright (C) 2019 Intel Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* This file was generated by gen_qfloat16_tables.cpp */
+
+#include <QtCore/qfloat16.h>
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(__F16C__) && !defined(__ARM_FP16_FORMAT_IEEE)
+
+const quint32 qfloat16::mantissatable[2048] = {
+0,
+0x33800000U,
+0x34000000U,
+0x34400000U,
+0x34800000U,
+0x34A00000U,
+0x34C00000U,
+0x34E00000U,
+0x35000000U,
+0x35100000U,
+0x35200000U,
+0x35300000U,
+0x35400000U,
+0x35500000U,
+0x35600000U,
+0x35700000U,
+0x35800000U,
+0x35880000U,
+0x35900000U,
+0x35980000U,
+0x35A00000U,
+0x35A80000U,
+0x35B00000U,
+0x35B80000U,
+0x35C00000U,
+0x35C80000U,
+0x35D00000U,
+0x35D80000U,
+0x35E00000U,
+0x35E80000U,
+0x35F00000U,
+0x35F80000U,
+0x36000000U,
+0x36040000U,
+0x36080000U,
+0x360C0000U,
+0x36100000U,
+0x36140000U,
+0x36180000U,
+0x361C0000U,
+0x36200000U,
+0x36240000U,
+0x36280000U,
+0x362C0000U,
+0x36300000U,
+0x36340000U,
+0x36380000U,
+0x363C0000U,
+0x36400000U,
+0x36440000U,
+0x36480000U,
+0x364C0000U,
+0x36500000U,
+0x36540000U,
+0x36580000U,
+0x365C0000U,
+0x36600000U,
+0x36640000U,
+0x36680000U,
+0x366C0000U,
+0x36700000U,
+0x36740000U,
+0x36780000U,
+0x367C0000U,
+0x36800000U,
+0x36820000U,
+0x36840000U,
+0x36860000U,
+0x36880000U,
+0x368A0000U,
+0x368C0000U,
+0x368E0000U,
+0x36900000U,
+0x36920000U,
+0x36940000U,
+0x36960000U,
+0x36980000U,
+0x369A0000U,
+0x369C0000U,
+0x369E0000U,
+0x36A00000U,
+0x36A20000U,
+0x36A40000U,
+0x36A60000U,
+0x36A80000U,
+0x36AA0000U,
+0x36AC0000U,
+0x36AE0000U,
+0x36B00000U,
+0x36B20000U,
+0x36B40000U,
+0x36B60000U,
+0x36B80000U,
+0x36BA0000U,
+0x36BC0000U,
+0x36BE0000U,
+0x36C00000U,
+0x36C20000U,
+0x36C40000U,
+0x36C60000U,
+0x36C80000U,
+0x36CA0000U,
+0x36CC0000U,
+0x36CE0000U,
+0x36D00000U,
+0x36D20000U,
+0x36D40000U,
+0x36D60000U,
+0x36D80000U,
+0x36DA0000U,
+0x36DC0000U,
+0x36DE0000U,
+0x36E00000U,
+0x36E20000U,
+0x36E40000U,
+0x36E60000U,
+0x36E80000U,
+0x36EA0000U,
+0x36EC0000U,
+0x36EE0000U,
+0x36F00000U,
+0x36F20000U,
+0x36F40000U,
+0x36F60000U,
+0x36F80000U,
+0x36FA0000U,
+0x36FC0000U,
+0x36FE0000U,
+0x37000000U,
+0x37010000U,
+0x37020000U,
+0x37030000U,
+0x37040000U,
+0x37050000U,
+0x37060000U,
+0x37070000U,
+0x37080000U,
+0x37090000U,
+0x370A0000U,
+0x370B0000U,
+0x370C0000U,
+0x370D0000U,
+0x370E0000U,
+0x370F0000U,
+0x37100000U,
+0x37110000U,
+0x37120000U,
+0x37130000U,
+0x37140000U,
+0x37150000U,
+0x37160000U,
+0x37170000U,
+0x37180000U,
+0x37190000U,
+0x371A0000U,
+0x371B0000U,
+0x371C0000U,
+0x371D0000U,
+0x371E0000U,
+0x371F0000U,
+0x37200000U,
+0x37210000U,
+0x37220000U,
+0x37230000U,
+0x37240000U,
+0x37250000U,
+0x37260000U,
+0x37270000U,
+0x37280000U,
+0x37290000U,
+0x372A0000U,
+0x372B0000U,
+0x372C0000U,
+0x372D0000U,
+0x372E0000U,
+0x372F0000U,
+0x37300000U,
+0x37310000U,
+0x37320000U,
+0x37330000U,
+0x37340000U,
+0x37350000U,
+0x37360000U,
+0x37370000U,
+0x37380000U,
+0x37390000U,
+0x373A0000U,
+0x373B0000U,
+0x373C0000U,
+0x373D0000U,
+0x373E0000U,
+0x373F0000U,
+0x37400000U,
+0x37410000U,
+0x37420000U,
+0x37430000U,
+0x37440000U,
+0x37450000U,
+0x37460000U,
+0x37470000U,
+0x37480000U,
+0x37490000U,
+0x374A0000U,
+0x374B0000U,
+0x374C0000U,
+0x374D0000U,
+0x374E0000U,
+0x374F0000U,
+0x37500000U,
+0x37510000U,
+0x37520000U,
+0x37530000U,
+0x37540000U,
+0x37550000U,
+0x37560000U,
+0x37570000U,
+0x37580000U,
+0x37590000U,
+0x375A0000U,
+0x375B0000U,
+0x375C0000U,
+0x375D0000U,
+0x375E0000U,
+0x375F0000U,
+0x37600000U,
+0x37610000U,
+0x37620000U,
+0x37630000U,
+0x37640000U,
+0x37650000U,
+0x37660000U,
+0x37670000U,
+0x37680000U,
+0x37690000U,
+0x376A0000U,
+0x376B0000U,
+0x376C0000U,
+0x376D0000U,
+0x376E0000U,
+0x376F0000U,
+0x37700000U,
+0x37710000U,
+0x37720000U,
+0x37730000U,
+0x37740000U,
+0x37750000U,
+0x37760000U,
+0x37770000U,
+0x37780000U,
+0x37790000U,
+0x377A0000U,
+0x377B0000U,
+0x377C0000U,
+0x377D0000U,
+0x377E0000U,
+0x377F0000U,
+0x37800000U,
+0x37808000U,
+0x37810000U,
+0x37818000U,
+0x37820000U,
+0x37828000U,
+0x37830000U,
+0x37838000U,
+0x37840000U,
+0x37848000U,
+0x37850000U,
+0x37858000U,
+0x37860000U,
+0x37868000U,
+0x37870000U,
+0x37878000U,
+0x37880000U,
+0x37888000U,
+0x37890000U,
+0x37898000U,
+0x378A0000U,
+0x378A8000U,
+0x378B0000U,
+0x378B8000U,
+0x378C0000U,
+0x378C8000U,
+0x378D0000U,
+0x378D8000U,
+0x378E0000U,
+0x378E8000U,
+0x378F0000U,
+0x378F8000U,
+0x37900000U,
+0x37908000U,
+0x37910000U,
+0x37918000U,
+0x37920000U,
+0x37928000U,
+0x37930000U,
+0x37938000U,
+0x37940000U,
+0x37948000U,
+0x37950000U,
+0x37958000U,
+0x37960000U,
+0x37968000U,
+0x37970000U,
+0x37978000U,
+0x37980000U,
+0x37988000U,
+0x37990000U,
+0x37998000U,
+0x379A0000U,
+0x379A8000U,
+0x379B0000U,
+0x379B8000U,
+0x379C0000U,
+0x379C8000U,
+0x379D0000U,
+0x379D8000U,
+0x379E0000U,
+0x379E8000U,
+0x379F0000U,
+0x379F8000U,
+0x37A00000U,
+0x37A08000U,
+0x37A10000U,
+0x37A18000U,
+0x37A20000U,
+0x37A28000U,
+0x37A30000U,
+0x37A38000U,
+0x37A40000U,
+0x37A48000U,
+0x37A50000U,
+0x37A58000U,
+0x37A60000U,
+0x37A68000U,
+0x37A70000U,
+0x37A78000U,
+0x37A80000U,
+0x37A88000U,
+0x37A90000U,
+0x37A98000U,
+0x37AA0000U,
+0x37AA8000U,
+0x37AB0000U,
+0x37AB8000U,
+0x37AC0000U,
+0x37AC8000U,
+0x37AD0000U,
+0x37AD8000U,
+0x37AE0000U,
+0x37AE8000U,
+0x37AF0000U,
+0x37AF8000U,
+0x37B00000U,
+0x37B08000U,
+0x37B10000U,
+0x37B18000U,
+0x37B20000U,
+0x37B28000U,
+0x37B30000U,
+0x37B38000U,
+0x37B40000U,
+0x37B48000U,
+0x37B50000U,
+0x37B58000U,
+0x37B60000U,
+0x37B68000U,
+0x37B70000U,
+0x37B78000U,
+0x37B80000U,
+0x37B88000U,
+0x37B90000U,
+0x37B98000U,
+0x37BA0000U,
+0x37BA8000U,
+0x37BB0000U,
+0x37BB8000U,
+0x37BC0000U,
+0x37BC8000U,
+0x37BD0000U,
+0x37BD8000U,
+0x37BE0000U,
+0x37BE8000U,
+0x37BF0000U,
+0x37BF8000U,
+0x37C00000U,
+0x37C08000U,
+0x37C10000U,
+0x37C18000U,
+0x37C20000U,
+0x37C28000U,
+0x37C30000U,
+0x37C38000U,
+0x37C40000U,
+0x37C48000U,
+0x37C50000U,
+0x37C58000U,
+0x37C60000U,
+0x37C68000U,
+0x37C70000U,
+0x37C78000U,
+0x37C80000U,
+0x37C88000U,
+0x37C90000U,
+0x37C98000U,
+0x37CA0000U,
+0x37CA8000U,
+0x37CB0000U,
+0x37CB8000U,
+0x37CC0000U,
+0x37CC8000U,
+0x37CD0000U,
+0x37CD8000U,
+0x37CE0000U,
+0x37CE8000U,
+0x37CF0000U,
+0x37CF8000U,
+0x37D00000U,
+0x37D08000U,
+0x37D10000U,
+0x37D18000U,
+0x37D20000U,
+0x37D28000U,
+0x37D30000U,
+0x37D38000U,
+0x37D40000U,
+0x37D48000U,
+0x37D50000U,
+0x37D58000U,
+0x37D60000U,
+0x37D68000U,
+0x37D70000U,
+0x37D78000U,
+0x37D80000U,
+0x37D88000U,
+0x37D90000U,
+0x37D98000U,
+0x37DA0000U,
+0x37DA8000U,
+0x37DB0000U,
+0x37DB8000U,
+0x37DC0000U,
+0x37DC8000U,
+0x37DD0000U,
+0x37DD8000U,
+0x37DE0000U,
+0x37DE8000U,
+0x37DF0000U,
+0x37DF8000U,
+0x37E00000U,
+0x37E08000U,
+0x37E10000U,
+0x37E18000U,
+0x37E20000U,
+0x37E28000U,
+0x37E30000U,
+0x37E38000U,
+0x37E40000U,
+0x37E48000U,
+0x37E50000U,
+0x37E58000U,
+0x37E60000U,
+0x37E68000U,
+0x37E70000U,
+0x37E78000U,
+0x37E80000U,
+0x37E88000U,
+0x37E90000U,
+0x37E98000U,
+0x37EA0000U,
+0x37EA8000U,
+0x37EB0000U,
+0x37EB8000U,
+0x37EC0000U,
+0x37EC8000U,
+0x37ED0000U,
+0x37ED8000U,
+0x37EE0000U,
+0x37EE8000U,
+0x37EF0000U,
+0x37EF8000U,
+0x37F00000U,
+0x37F08000U,
+0x37F10000U,
+0x37F18000U,
+0x37F20000U,
+0x37F28000U,
+0x37F30000U,
+0x37F38000U,
+0x37F40000U,
+0x37F48000U,
+0x37F50000U,
+0x37F58000U,
+0x37F60000U,
+0x37F68000U,
+0x37F70000U,
+0x37F78000U,
+0x37F80000U,
+0x37F88000U,
+0x37F90000U,
+0x37F98000U,
+0x37FA0000U,
+0x37FA8000U,
+0x37FB0000U,
+0x37FB8000U,
+0x37FC0000U,
+0x37FC8000U,
+0x37FD0000U,
+0x37FD8000U,
+0x37FE0000U,
+0x37FE8000U,
+0x37FF0000U,
+0x37FF8000U,
+0x38000000U,
+0x38004000U,
+0x38008000U,
+0x3800C000U,
+0x38010000U,
+0x38014000U,
+0x38018000U,
+0x3801C000U,
+0x38020000U,
+0x38024000U,
+0x38028000U,
+0x3802C000U,
+0x38030000U,
+0x38034000U,
+0x38038000U,
+0x3803C000U,
+0x38040000U,
+0x38044000U,
+0x38048000U,
+0x3804C000U,
+0x38050000U,
+0x38054000U,
+0x38058000U,
+0x3805C000U,
+0x38060000U,
+0x38064000U,
+0x38068000U,
+0x3806C000U,
+0x38070000U,
+0x38074000U,
+0x38078000U,
+0x3807C000U,
+0x38080000U,
+0x38084000U,
+0x38088000U,
+0x3808C000U,
+0x38090000U,
+0x38094000U,
+0x38098000U,
+0x3809C000U,
+0x380A0000U,
+0x380A4000U,
+0x380A8000U,
+0x380AC000U,
+0x380B0000U,
+0x380B4000U,
+0x380B8000U,
+0x380BC000U,
+0x380C0000U,
+0x380C4000U,
+0x380C8000U,
+0x380CC000U,
+0x380D0000U,
+0x380D4000U,
+0x380D8000U,
+0x380DC000U,
+0x380E0000U,
+0x380E4000U,
+0x380E8000U,
+0x380EC000U,
+0x380F0000U,
+0x380F4000U,
+0x380F8000U,
+0x380FC000U,
+0x38100000U,
+0x38104000U,
+0x38108000U,
+0x3810C000U,
+0x38110000U,
+0x38114000U,
+0x38118000U,
+0x3811C000U,
+0x38120000U,
+0x38124000U,
+0x38128000U,
+0x3812C000U,
+0x38130000U,
+0x38134000U,
+0x38138000U,
+0x3813C000U,
+0x38140000U,
+0x38144000U,
+0x38148000U,
+0x3814C000U,
+0x38150000U,
+0x38154000U,
+0x38158000U,
+0x3815C000U,
+0x38160000U,
+0x38164000U,
+0x38168000U,
+0x3816C000U,
+0x38170000U,
+0x38174000U,
+0x38178000U,
+0x3817C000U,
+0x38180000U,
+0x38184000U,
+0x38188000U,
+0x3818C000U,
+0x38190000U,
+0x38194000U,
+0x38198000U,
+0x3819C000U,
+0x381A0000U,
+0x381A4000U,
+0x381A8000U,
+0x381AC000U,
+0x381B0000U,
+0x381B4000U,
+0x381B8000U,
+0x381BC000U,
+0x381C0000U,
+0x381C4000U,
+0x381C8000U,
+0x381CC000U,
+0x381D0000U,
+0x381D4000U,
+0x381D8000U,
+0x381DC000U,
+0x381E0000U,
+0x381E4000U,
+0x381E8000U,
+0x381EC000U,
+0x381F0000U,
+0x381F4000U,
+0x381F8000U,
+0x381FC000U,
+0x38200000U,
+0x38204000U,
+0x38208000U,
+0x3820C000U,
+0x38210000U,
+0x38214000U,
+0x38218000U,
+0x3821C000U,
+0x38220000U,
+0x38224000U,
+0x38228000U,
+0x3822C000U,
+0x38230000U,
+0x38234000U,
+0x38238000U,
+0x3823C000U,
+0x38240000U,
+0x38244000U,
+0x38248000U,
+0x3824C000U,
+0x38250000U,
+0x38254000U,
+0x38258000U,
+0x3825C000U,
+0x38260000U,
+0x38264000U,
+0x38268000U,
+0x3826C000U,
+0x38270000U,
+0x38274000U,
+0x38278000U,
+0x3827C000U,
+0x38280000U,
+0x38284000U,
+0x38288000U,
+0x3828C000U,
+0x38290000U,
+0x38294000U,
+0x38298000U,
+0x3829C000U,
+0x382A0000U,
+0x382A4000U,
+0x382A8000U,
+0x382AC000U,
+0x382B0000U,
+0x382B4000U,
+0x382B8000U,
+0x382BC000U,
+0x382C0000U,
+0x382C4000U,
+0x382C8000U,
+0x382CC000U,
+0x382D0000U,
+0x382D4000U,
+0x382D8000U,
+0x382DC000U,
+0x382E0000U,
+0x382E4000U,
+0x382E8000U,
+0x382EC000U,
+0x382F0000U,
+0x382F4000U,
+0x382F8000U,
+0x382FC000U,
+0x38300000U,
+0x38304000U,
+0x38308000U,
+0x3830C000U,
+0x38310000U,
+0x38314000U,
+0x38318000U,
+0x3831C000U,
+0x38320000U,
+0x38324000U,
+0x38328000U,
+0x3832C000U,
+0x38330000U,
+0x38334000U,
+0x38338000U,
+0x3833C000U,
+0x38340000U,
+0x38344000U,
+0x38348000U,
+0x3834C000U,
+0x38350000U,
+0x38354000U,
+0x38358000U,
+0x3835C000U,
+0x38360000U,
+0x38364000U,
+0x38368000U,
+0x3836C000U,
+0x38370000U,
+0x38374000U,
+0x38378000U,
+0x3837C000U,
+0x38380000U,
+0x38384000U,
+0x38388000U,
+0x3838C000U,
+0x38390000U,
+0x38394000U,
+0x38398000U,
+0x3839C000U,
+0x383A0000U,
+0x383A4000U,
+0x383A8000U,
+0x383AC000U,
+0x383B0000U,
+0x383B4000U,
+0x383B8000U,
+0x383BC000U,
+0x383C0000U,
+0x383C4000U,
+0x383C8000U,
+0x383CC000U,
+0x383D0000U,
+0x383D4000U,
+0x383D8000U,
+0x383DC000U,
+0x383E0000U,
+0x383E4000U,
+0x383E8000U,
+0x383EC000U,
+0x383F0000U,
+0x383F4000U,
+0x383F8000U,
+0x383FC000U,
+0x38400000U,
+0x38404000U,
+0x38408000U,
+0x3840C000U,
+0x38410000U,
+0x38414000U,
+0x38418000U,
+0x3841C000U,
+0x38420000U,
+0x38424000U,
+0x38428000U,
+0x3842C000U,
+0x38430000U,
+0x38434000U,
+0x38438000U,
+0x3843C000U,
+0x38440000U,
+0x38444000U,
+0x38448000U,
+0x3844C000U,
+0x38450000U,
+0x38454000U,
+0x38458000U,
+0x3845C000U,
+0x38460000U,
+0x38464000U,
+0x38468000U,
+0x3846C000U,
+0x38470000U,
+0x38474000U,
+0x38478000U,
+0x3847C000U,
+0x38480000U,
+0x38484000U,
+0x38488000U,
+0x3848C000U,
+0x38490000U,
+0x38494000U,
+0x38498000U,
+0x3849C000U,
+0x384A0000U,
+0x384A4000U,
+0x384A8000U,
+0x384AC000U,
+0x384B0000U,
+0x384B4000U,
+0x384B8000U,
+0x384BC000U,
+0x384C0000U,
+0x384C4000U,
+0x384C8000U,
+0x384CC000U,
+0x384D0000U,
+0x384D4000U,
+0x384D8000U,
+0x384DC000U,
+0x384E0000U,
+0x384E4000U,
+0x384E8000U,
+0x384EC000U,
+0x384F0000U,
+0x384F4000U,
+0x384F8000U,
+0x384FC000U,
+0x38500000U,
+0x38504000U,
+0x38508000U,
+0x3850C000U,
+0x38510000U,
+0x38514000U,
+0x38518000U,
+0x3851C000U,
+0x38520000U,
+0x38524000U,
+0x38528000U,
+0x3852C000U,
+0x38530000U,
+0x38534000U,
+0x38538000U,
+0x3853C000U,
+0x38540000U,
+0x38544000U,
+0x38548000U,
+0x3854C000U,
+0x38550000U,
+0x38554000U,
+0x38558000U,
+0x3855C000U,
+0x38560000U,
+0x38564000U,
+0x38568000U,
+0x3856C000U,
+0x38570000U,
+0x38574000U,
+0x38578000U,
+0x3857C000U,
+0x38580000U,
+0x38584000U,
+0x38588000U,
+0x3858C000U,
+0x38590000U,
+0x38594000U,
+0x38598000U,
+0x3859C000U,
+0x385A0000U,
+0x385A4000U,
+0x385A8000U,
+0x385AC000U,
+0x385B0000U,
+0x385B4000U,
+0x385B8000U,
+0x385BC000U,
+0x385C0000U,
+0x385C4000U,
+0x385C8000U,
+0x385CC000U,
+0x385D0000U,
+0x385D4000U,
+0x385D8000U,
+0x385DC000U,
+0x385E0000U,
+0x385E4000U,
+0x385E8000U,
+0x385EC000U,
+0x385F0000U,
+0x385F4000U,
+0x385F8000U,
+0x385FC000U,
+0x38600000U,
+0x38604000U,
+0x38608000U,
+0x3860C000U,
+0x38610000U,
+0x38614000U,
+0x38618000U,
+0x3861C000U,
+0x38620000U,
+0x38624000U,
+0x38628000U,
+0x3862C000U,
+0x38630000U,
+0x38634000U,
+0x38638000U,
+0x3863C000U,
+0x38640000U,
+0x38644000U,
+0x38648000U,
+0x3864C000U,
+0x38650000U,
+0x38654000U,
+0x38658000U,
+0x3865C000U,
+0x38660000U,
+0x38664000U,
+0x38668000U,
+0x3866C000U,
+0x38670000U,
+0x38674000U,
+0x38678000U,
+0x3867C000U,
+0x38680000U,
+0x38684000U,
+0x38688000U,
+0x3868C000U,
+0x38690000U,
+0x38694000U,
+0x38698000U,
+0x3869C000U,
+0x386A0000U,
+0x386A4000U,
+0x386A8000U,
+0x386AC000U,
+0x386B0000U,
+0x386B4000U,
+0x386B8000U,
+0x386BC000U,
+0x386C0000U,
+0x386C4000U,
+0x386C8000U,
+0x386CC000U,
+0x386D0000U,
+0x386D4000U,
+0x386D8000U,
+0x386DC000U,
+0x386E0000U,
+0x386E4000U,
+0x386E8000U,
+0x386EC000U,
+0x386F0000U,
+0x386F4000U,
+0x386F8000U,
+0x386FC000U,
+0x38700000U,
+0x38704000U,
+0x38708000U,
+0x3870C000U,
+0x38710000U,
+0x38714000U,
+0x38718000U,
+0x3871C000U,
+0x38720000U,
+0x38724000U,
+0x38728000U,
+0x3872C000U,
+0x38730000U,
+0x38734000U,
+0x38738000U,
+0x3873C000U,
+0x38740000U,
+0x38744000U,
+0x38748000U,
+0x3874C000U,
+0x38750000U,
+0x38754000U,
+0x38758000U,
+0x3875C000U,
+0x38760000U,
+0x38764000U,
+0x38768000U,
+0x3876C000U,
+0x38770000U,
+0x38774000U,
+0x38778000U,
+0x3877C000U,
+0x38780000U,
+0x38784000U,
+0x38788000U,
+0x3878C000U,
+0x38790000U,
+0x38794000U,
+0x38798000U,
+0x3879C000U,
+0x387A0000U,
+0x387A4000U,
+0x387A8000U,
+0x387AC000U,
+0x387B0000U,
+0x387B4000U,
+0x387B8000U,
+0x387BC000U,
+0x387C0000U,
+0x387C4000U,
+0x387C8000U,
+0x387CC000U,
+0x387D0000U,
+0x387D4000U,
+0x387D8000U,
+0x387DC000U,
+0x387E0000U,
+0x387E4000U,
+0x387E8000U,
+0x387EC000U,
+0x387F0000U,
+0x387F4000U,
+0x387F8000U,
+0x387FC000U,
+0x38000000U,
+0x38002000U,
+0x38004000U,
+0x38006000U,
+0x38008000U,
+0x3800A000U,
+0x3800C000U,
+0x3800E000U,
+0x38010000U,
+0x38012000U,
+0x38014000U,
+0x38016000U,
+0x38018000U,
+0x3801A000U,
+0x3801C000U,
+0x3801E000U,
+0x38020000U,
+0x38022000U,
+0x38024000U,
+0x38026000U,
+0x38028000U,
+0x3802A000U,
+0x3802C000U,
+0x3802E000U,
+0x38030000U,
+0x38032000U,
+0x38034000U,
+0x38036000U,
+0x38038000U,
+0x3803A000U,
+0x3803C000U,
+0x3803E000U,
+0x38040000U,
+0x38042000U,
+0x38044000U,
+0x38046000U,
+0x38048000U,
+0x3804A000U,
+0x3804C000U,
+0x3804E000U,
+0x38050000U,
+0x38052000U,
+0x38054000U,
+0x38056000U,
+0x38058000U,
+0x3805A000U,
+0x3805C000U,
+0x3805E000U,
+0x38060000U,
+0x38062000U,
+0x38064000U,
+0x38066000U,
+0x38068000U,
+0x3806A000U,
+0x3806C000U,
+0x3806E000U,
+0x38070000U,
+0x38072000U,
+0x38074000U,
+0x38076000U,
+0x38078000U,
+0x3807A000U,
+0x3807C000U,
+0x3807E000U,
+0x38080000U,
+0x38082000U,
+0x38084000U,
+0x38086000U,
+0x38088000U,
+0x3808A000U,
+0x3808C000U,
+0x3808E000U,
+0x38090000U,
+0x38092000U,
+0x38094000U,
+0x38096000U,
+0x38098000U,
+0x3809A000U,
+0x3809C000U,
+0x3809E000U,
+0x380A0000U,
+0x380A2000U,
+0x380A4000U,
+0x380A6000U,
+0x380A8000U,
+0x380AA000U,
+0x380AC000U,
+0x380AE000U,
+0x380B0000U,
+0x380B2000U,
+0x380B4000U,
+0x380B6000U,
+0x380B8000U,
+0x380BA000U,
+0x380BC000U,
+0x380BE000U,
+0x380C0000U,
+0x380C2000U,
+0x380C4000U,
+0x380C6000U,
+0x380C8000U,
+0x380CA000U,
+0x380CC000U,
+0x380CE000U,
+0x380D0000U,
+0x380D2000U,
+0x380D4000U,
+0x380D6000U,
+0x380D8000U,
+0x380DA000U,
+0x380DC000U,
+0x380DE000U,
+0x380E0000U,
+0x380E2000U,
+0x380E4000U,
+0x380E6000U,
+0x380E8000U,
+0x380EA000U,
+0x380EC000U,
+0x380EE000U,
+0x380F0000U,
+0x380F2000U,
+0x380F4000U,
+0x380F6000U,
+0x380F8000U,
+0x380FA000U,
+0x380FC000U,
+0x380FE000U,
+0x38100000U,
+0x38102000U,
+0x38104000U,
+0x38106000U,
+0x38108000U,
+0x3810A000U,
+0x3810C000U,
+0x3810E000U,
+0x38110000U,
+0x38112000U,
+0x38114000U,
+0x38116000U,
+0x38118000U,
+0x3811A000U,
+0x3811C000U,
+0x3811E000U,
+0x38120000U,
+0x38122000U,
+0x38124000U,
+0x38126000U,
+0x38128000U,
+0x3812A000U,
+0x3812C000U,
+0x3812E000U,
+0x38130000U,
+0x38132000U,
+0x38134000U,
+0x38136000U,
+0x38138000U,
+0x3813A000U,
+0x3813C000U,
+0x3813E000U,
+0x38140000U,
+0x38142000U,
+0x38144000U,
+0x38146000U,
+0x38148000U,
+0x3814A000U,
+0x3814C000U,
+0x3814E000U,
+0x38150000U,
+0x38152000U,
+0x38154000U,
+0x38156000U,
+0x38158000U,
+0x3815A000U,
+0x3815C000U,
+0x3815E000U,
+0x38160000U,
+0x38162000U,
+0x38164000U,
+0x38166000U,
+0x38168000U,
+0x3816A000U,
+0x3816C000U,
+0x3816E000U,
+0x38170000U,
+0x38172000U,
+0x38174000U,
+0x38176000U,
+0x38178000U,
+0x3817A000U,
+0x3817C000U,
+0x3817E000U,
+0x38180000U,
+0x38182000U,
+0x38184000U,
+0x38186000U,
+0x38188000U,
+0x3818A000U,
+0x3818C000U,
+0x3818E000U,
+0x38190000U,
+0x38192000U,
+0x38194000U,
+0x38196000U,
+0x38198000U,
+0x3819A000U,
+0x3819C000U,
+0x3819E000U,
+0x381A0000U,
+0x381A2000U,
+0x381A4000U,
+0x381A6000U,
+0x381A8000U,
+0x381AA000U,
+0x381AC000U,
+0x381AE000U,
+0x381B0000U,
+0x381B2000U,
+0x381B4000U,
+0x381B6000U,
+0x381B8000U,
+0x381BA000U,
+0x381BC000U,
+0x381BE000U,
+0x381C0000U,
+0x381C2000U,
+0x381C4000U,
+0x381C6000U,
+0x381C8000U,
+0x381CA000U,
+0x381CC000U,
+0x381CE000U,
+0x381D0000U,
+0x381D2000U,
+0x381D4000U,
+0x381D6000U,
+0x381D8000U,
+0x381DA000U,
+0x381DC000U,
+0x381DE000U,
+0x381E0000U,
+0x381E2000U,
+0x381E4000U,
+0x381E6000U,
+0x381E8000U,
+0x381EA000U,
+0x381EC000U,
+0x381EE000U,
+0x381F0000U,
+0x381F2000U,
+0x381F4000U,
+0x381F6000U,
+0x381F8000U,
+0x381FA000U,
+0x381FC000U,
+0x381FE000U,
+0x38200000U,
+0x38202000U,
+0x38204000U,
+0x38206000U,
+0x38208000U,
+0x3820A000U,
+0x3820C000U,
+0x3820E000U,
+0x38210000U,
+0x38212000U,
+0x38214000U,
+0x38216000U,
+0x38218000U,
+0x3821A000U,
+0x3821C000U,
+0x3821E000U,
+0x38220000U,
+0x38222000U,
+0x38224000U,
+0x38226000U,
+0x38228000U,
+0x3822A000U,
+0x3822C000U,
+0x3822E000U,
+0x38230000U,
+0x38232000U,
+0x38234000U,
+0x38236000U,
+0x38238000U,
+0x3823A000U,
+0x3823C000U,
+0x3823E000U,
+0x38240000U,
+0x38242000U,
+0x38244000U,
+0x38246000U,
+0x38248000U,
+0x3824A000U,
+0x3824C000U,
+0x3824E000U,
+0x38250000U,
+0x38252000U,
+0x38254000U,
+0x38256000U,
+0x38258000U,
+0x3825A000U,
+0x3825C000U,
+0x3825E000U,
+0x38260000U,
+0x38262000U,
+0x38264000U,
+0x38266000U,
+0x38268000U,
+0x3826A000U,
+0x3826C000U,
+0x3826E000U,
+0x38270000U,
+0x38272000U,
+0x38274000U,
+0x38276000U,
+0x38278000U,
+0x3827A000U,
+0x3827C000U,
+0x3827E000U,
+0x38280000U,
+0x38282000U,
+0x38284000U,
+0x38286000U,
+0x38288000U,
+0x3828A000U,
+0x3828C000U,
+0x3828E000U,
+0x38290000U,
+0x38292000U,
+0x38294000U,
+0x38296000U,
+0x38298000U,
+0x3829A000U,
+0x3829C000U,
+0x3829E000U,
+0x382A0000U,
+0x382A2000U,
+0x382A4000U,
+0x382A6000U,
+0x382A8000U,
+0x382AA000U,
+0x382AC000U,
+0x382AE000U,
+0x382B0000U,
+0x382B2000U,
+0x382B4000U,
+0x382B6000U,
+0x382B8000U,
+0x382BA000U,
+0x382BC000U,
+0x382BE000U,
+0x382C0000U,
+0x382C2000U,
+0x382C4000U,
+0x382C6000U,
+0x382C8000U,
+0x382CA000U,
+0x382CC000U,
+0x382CE000U,
+0x382D0000U,
+0x382D2000U,
+0x382D4000U,
+0x382D6000U,
+0x382D8000U,
+0x382DA000U,
+0x382DC000U,
+0x382DE000U,
+0x382E0000U,
+0x382E2000U,
+0x382E4000U,
+0x382E6000U,
+0x382E8000U,
+0x382EA000U,
+0x382EC000U,
+0x382EE000U,
+0x382F0000U,
+0x382F2000U,
+0x382F4000U,
+0x382F6000U,
+0x382F8000U,
+0x382FA000U,
+0x382FC000U,
+0x382FE000U,
+0x38300000U,
+0x38302000U,
+0x38304000U,
+0x38306000U,
+0x38308000U,
+0x3830A000U,
+0x3830C000U,
+0x3830E000U,
+0x38310000U,
+0x38312000U,
+0x38314000U,
+0x38316000U,
+0x38318000U,
+0x3831A000U,
+0x3831C000U,
+0x3831E000U,
+0x38320000U,
+0x38322000U,
+0x38324000U,
+0x38326000U,
+0x38328000U,
+0x3832A000U,
+0x3832C000U,
+0x3832E000U,
+0x38330000U,
+0x38332000U,
+0x38334000U,
+0x38336000U,
+0x38338000U,
+0x3833A000U,
+0x3833C000U,
+0x3833E000U,
+0x38340000U,
+0x38342000U,
+0x38344000U,
+0x38346000U,
+0x38348000U,
+0x3834A000U,
+0x3834C000U,
+0x3834E000U,
+0x38350000U,
+0x38352000U,
+0x38354000U,
+0x38356000U,
+0x38358000U,
+0x3835A000U,
+0x3835C000U,
+0x3835E000U,
+0x38360000U,
+0x38362000U,
+0x38364000U,
+0x38366000U,
+0x38368000U,
+0x3836A000U,
+0x3836C000U,
+0x3836E000U,
+0x38370000U,
+0x38372000U,
+0x38374000U,
+0x38376000U,
+0x38378000U,
+0x3837A000U,
+0x3837C000U,
+0x3837E000U,
+0x38380000U,
+0x38382000U,
+0x38384000U,
+0x38386000U,
+0x38388000U,
+0x3838A000U,
+0x3838C000U,
+0x3838E000U,
+0x38390000U,
+0x38392000U,
+0x38394000U,
+0x38396000U,
+0x38398000U,
+0x3839A000U,
+0x3839C000U,
+0x3839E000U,
+0x383A0000U,
+0x383A2000U,
+0x383A4000U,
+0x383A6000U,
+0x383A8000U,
+0x383AA000U,
+0x383AC000U,
+0x383AE000U,
+0x383B0000U,
+0x383B2000U,
+0x383B4000U,
+0x383B6000U,
+0x383B8000U,
+0x383BA000U,
+0x383BC000U,
+0x383BE000U,
+0x383C0000U,
+0x383C2000U,
+0x383C4000U,
+0x383C6000U,
+0x383C8000U,
+0x383CA000U,
+0x383CC000U,
+0x383CE000U,
+0x383D0000U,
+0x383D2000U,
+0x383D4000U,
+0x383D6000U,
+0x383D8000U,
+0x383DA000U,
+0x383DC000U,
+0x383DE000U,
+0x383E0000U,
+0x383E2000U,
+0x383E4000U,
+0x383E6000U,
+0x383E8000U,
+0x383EA000U,
+0x383EC000U,
+0x383EE000U,
+0x383F0000U,
+0x383F2000U,
+0x383F4000U,
+0x383F6000U,
+0x383F8000U,
+0x383FA000U,
+0x383FC000U,
+0x383FE000U,
+0x38400000U,
+0x38402000U,
+0x38404000U,
+0x38406000U,
+0x38408000U,
+0x3840A000U,
+0x3840C000U,
+0x3840E000U,
+0x38410000U,
+0x38412000U,
+0x38414000U,
+0x38416000U,
+0x38418000U,
+0x3841A000U,
+0x3841C000U,
+0x3841E000U,
+0x38420000U,
+0x38422000U,
+0x38424000U,
+0x38426000U,
+0x38428000U,
+0x3842A000U,
+0x3842C000U,
+0x3842E000U,
+0x38430000U,
+0x38432000U,
+0x38434000U,
+0x38436000U,
+0x38438000U,
+0x3843A000U,
+0x3843C000U,
+0x3843E000U,
+0x38440000U,
+0x38442000U,
+0x38444000U,
+0x38446000U,
+0x38448000U,
+0x3844A000U,
+0x3844C000U,
+0x3844E000U,
+0x38450000U,
+0x38452000U,
+0x38454000U,
+0x38456000U,
+0x38458000U,
+0x3845A000U,
+0x3845C000U,
+0x3845E000U,
+0x38460000U,
+0x38462000U,
+0x38464000U,
+0x38466000U,
+0x38468000U,
+0x3846A000U,
+0x3846C000U,
+0x3846E000U,
+0x38470000U,
+0x38472000U,
+0x38474000U,
+0x38476000U,
+0x38478000U,
+0x3847A000U,
+0x3847C000U,
+0x3847E000U,
+0x38480000U,
+0x38482000U,
+0x38484000U,
+0x38486000U,
+0x38488000U,
+0x3848A000U,
+0x3848C000U,
+0x3848E000U,
+0x38490000U,
+0x38492000U,
+0x38494000U,
+0x38496000U,
+0x38498000U,
+0x3849A000U,
+0x3849C000U,
+0x3849E000U,
+0x384A0000U,
+0x384A2000U,
+0x384A4000U,
+0x384A6000U,
+0x384A8000U,
+0x384AA000U,
+0x384AC000U,
+0x384AE000U,
+0x384B0000U,
+0x384B2000U,
+0x384B4000U,
+0x384B6000U,
+0x384B8000U,
+0x384BA000U,
+0x384BC000U,
+0x384BE000U,
+0x384C0000U,
+0x384C2000U,
+0x384C4000U,
+0x384C6000U,
+0x384C8000U,
+0x384CA000U,
+0x384CC000U,
+0x384CE000U,
+0x384D0000U,
+0x384D2000U,
+0x384D4000U,
+0x384D6000U,
+0x384D8000U,
+0x384DA000U,
+0x384DC000U,
+0x384DE000U,
+0x384E0000U,
+0x384E2000U,
+0x384E4000U,
+0x384E6000U,
+0x384E8000U,
+0x384EA000U,
+0x384EC000U,
+0x384EE000U,
+0x384F0000U,
+0x384F2000U,
+0x384F4000U,
+0x384F6000U,
+0x384F8000U,
+0x384FA000U,
+0x384FC000U,
+0x384FE000U,
+0x38500000U,
+0x38502000U,
+0x38504000U,
+0x38506000U,
+0x38508000U,
+0x3850A000U,
+0x3850C000U,
+0x3850E000U,
+0x38510000U,
+0x38512000U,
+0x38514000U,
+0x38516000U,
+0x38518000U,
+0x3851A000U,
+0x3851C000U,
+0x3851E000U,
+0x38520000U,
+0x38522000U,
+0x38524000U,
+0x38526000U,
+0x38528000U,
+0x3852A000U,
+0x3852C000U,
+0x3852E000U,
+0x38530000U,
+0x38532000U,
+0x38534000U,
+0x38536000U,
+0x38538000U,
+0x3853A000U,
+0x3853C000U,
+0x3853E000U,
+0x38540000U,
+0x38542000U,
+0x38544000U,
+0x38546000U,
+0x38548000U,
+0x3854A000U,
+0x3854C000U,
+0x3854E000U,
+0x38550000U,
+0x38552000U,
+0x38554000U,
+0x38556000U,
+0x38558000U,
+0x3855A000U,
+0x3855C000U,
+0x3855E000U,
+0x38560000U,
+0x38562000U,
+0x38564000U,
+0x38566000U,
+0x38568000U,
+0x3856A000U,
+0x3856C000U,
+0x3856E000U,
+0x38570000U,
+0x38572000U,
+0x38574000U,
+0x38576000U,
+0x38578000U,
+0x3857A000U,
+0x3857C000U,
+0x3857E000U,
+0x38580000U,
+0x38582000U,
+0x38584000U,
+0x38586000U,
+0x38588000U,
+0x3858A000U,
+0x3858C000U,
+0x3858E000U,
+0x38590000U,
+0x38592000U,
+0x38594000U,
+0x38596000U,
+0x38598000U,
+0x3859A000U,
+0x3859C000U,
+0x3859E000U,
+0x385A0000U,
+0x385A2000U,
+0x385A4000U,
+0x385A6000U,
+0x385A8000U,
+0x385AA000U,
+0x385AC000U,
+0x385AE000U,
+0x385B0000U,
+0x385B2000U,
+0x385B4000U,
+0x385B6000U,
+0x385B8000U,
+0x385BA000U,
+0x385BC000U,
+0x385BE000U,
+0x385C0000U,
+0x385C2000U,
+0x385C4000U,
+0x385C6000U,
+0x385C8000U,
+0x385CA000U,
+0x385CC000U,
+0x385CE000U,
+0x385D0000U,
+0x385D2000U,
+0x385D4000U,
+0x385D6000U,
+0x385D8000U,
+0x385DA000U,
+0x385DC000U,
+0x385DE000U,
+0x385E0000U,
+0x385E2000U,
+0x385E4000U,
+0x385E6000U,
+0x385E8000U,
+0x385EA000U,
+0x385EC000U,
+0x385EE000U,
+0x385F0000U,
+0x385F2000U,
+0x385F4000U,
+0x385F6000U,
+0x385F8000U,
+0x385FA000U,
+0x385FC000U,
+0x385FE000U,
+0x38600000U,
+0x38602000U,
+0x38604000U,
+0x38606000U,
+0x38608000U,
+0x3860A000U,
+0x3860C000U,
+0x3860E000U,
+0x38610000U,
+0x38612000U,
+0x38614000U,
+0x38616000U,
+0x38618000U,
+0x3861A000U,
+0x3861C000U,
+0x3861E000U,
+0x38620000U,
+0x38622000U,
+0x38624000U,
+0x38626000U,
+0x38628000U,
+0x3862A000U,
+0x3862C000U,
+0x3862E000U,
+0x38630000U,
+0x38632000U,
+0x38634000U,
+0x38636000U,
+0x38638000U,
+0x3863A000U,
+0x3863C000U,
+0x3863E000U,
+0x38640000U,
+0x38642000U,
+0x38644000U,
+0x38646000U,
+0x38648000U,
+0x3864A000U,
+0x3864C000U,
+0x3864E000U,
+0x38650000U,
+0x38652000U,
+0x38654000U,
+0x38656000U,
+0x38658000U,
+0x3865A000U,
+0x3865C000U,
+0x3865E000U,
+0x38660000U,
+0x38662000U,
+0x38664000U,
+0x38666000U,
+0x38668000U,
+0x3866A000U,
+0x3866C000U,
+0x3866E000U,
+0x38670000U,
+0x38672000U,
+0x38674000U,
+0x38676000U,
+0x38678000U,
+0x3867A000U,
+0x3867C000U,
+0x3867E000U,
+0x38680000U,
+0x38682000U,
+0x38684000U,
+0x38686000U,
+0x38688000U,
+0x3868A000U,
+0x3868C000U,
+0x3868E000U,
+0x38690000U,
+0x38692000U,
+0x38694000U,
+0x38696000U,
+0x38698000U,
+0x3869A000U,
+0x3869C000U,
+0x3869E000U,
+0x386A0000U,
+0x386A2000U,
+0x386A4000U,
+0x386A6000U,
+0x386A8000U,
+0x386AA000U,
+0x386AC000U,
+0x386AE000U,
+0x386B0000U,
+0x386B2000U,
+0x386B4000U,
+0x386B6000U,
+0x386B8000U,
+0x386BA000U,
+0x386BC000U,
+0x386BE000U,
+0x386C0000U,
+0x386C2000U,
+0x386C4000U,
+0x386C6000U,
+0x386C8000U,
+0x386CA000U,
+0x386CC000U,
+0x386CE000U,
+0x386D0000U,
+0x386D2000U,
+0x386D4000U,
+0x386D6000U,
+0x386D8000U,
+0x386DA000U,
+0x386DC000U,
+0x386DE000U,
+0x386E0000U,
+0x386E2000U,
+0x386E4000U,
+0x386E6000U,
+0x386E8000U,
+0x386EA000U,
+0x386EC000U,
+0x386EE000U,
+0x386F0000U,
+0x386F2000U,
+0x386F4000U,
+0x386F6000U,
+0x386F8000U,
+0x386FA000U,
+0x386FC000U,
+0x386FE000U,
+0x38700000U,
+0x38702000U,
+0x38704000U,
+0x38706000U,
+0x38708000U,
+0x3870A000U,
+0x3870C000U,
+0x3870E000U,
+0x38710000U,
+0x38712000U,
+0x38714000U,
+0x38716000U,
+0x38718000U,
+0x3871A000U,
+0x3871C000U,
+0x3871E000U,
+0x38720000U,
+0x38722000U,
+0x38724000U,
+0x38726000U,
+0x38728000U,
+0x3872A000U,
+0x3872C000U,
+0x3872E000U,
+0x38730000U,
+0x38732000U,
+0x38734000U,
+0x38736000U,
+0x38738000U,
+0x3873A000U,
+0x3873C000U,
+0x3873E000U,
+0x38740000U,
+0x38742000U,
+0x38744000U,
+0x38746000U,
+0x38748000U,
+0x3874A000U,
+0x3874C000U,
+0x3874E000U,
+0x38750000U,
+0x38752000U,
+0x38754000U,
+0x38756000U,
+0x38758000U,
+0x3875A000U,
+0x3875C000U,
+0x3875E000U,
+0x38760000U,
+0x38762000U,
+0x38764000U,
+0x38766000U,
+0x38768000U,
+0x3876A000U,
+0x3876C000U,
+0x3876E000U,
+0x38770000U,
+0x38772000U,
+0x38774000U,
+0x38776000U,
+0x38778000U,
+0x3877A000U,
+0x3877C000U,
+0x3877E000U,
+0x38780000U,
+0x38782000U,
+0x38784000U,
+0x38786000U,
+0x38788000U,
+0x3878A000U,
+0x3878C000U,
+0x3878E000U,
+0x38790000U,
+0x38792000U,
+0x38794000U,
+0x38796000U,
+0x38798000U,
+0x3879A000U,
+0x3879C000U,
+0x3879E000U,
+0x387A0000U,
+0x387A2000U,
+0x387A4000U,
+0x387A6000U,
+0x387A8000U,
+0x387AA000U,
+0x387AC000U,
+0x387AE000U,
+0x387B0000U,
+0x387B2000U,
+0x387B4000U,
+0x387B6000U,
+0x387B8000U,
+0x387BA000U,
+0x387BC000U,
+0x387BE000U,
+0x387C0000U,
+0x387C2000U,
+0x387C4000U,
+0x387C6000U,
+0x387C8000U,
+0x387CA000U,
+0x387CC000U,
+0x387CE000U,
+0x387D0000U,
+0x387D2000U,
+0x387D4000U,
+0x387D6000U,
+0x387D8000U,
+0x387DA000U,
+0x387DC000U,
+0x387DE000U,
+0x387E0000U,
+0x387E2000U,
+0x387E4000U,
+0x387E6000U,
+0x387E8000U,
+0x387EA000U,
+0x387EC000U,
+0x387EE000U,
+0x387F0000U,
+0x387F2000U,
+0x387F4000U,
+0x387F6000U,
+0x387F8000U,
+0x387FA000U,
+0x387FC000U,
+0x387FE000U,
+};
+
+const quint32 qfloat16::exponenttable[64] = {
+0,
+0x800000U,
+0x1000000U,
+0x1800000U,
+0x2000000U,
+0x2800000U,
+0x3000000U,
+0x3800000U,
+0x4000000U,
+0x4800000U,
+0x5000000U,
+0x5800000U,
+0x6000000U,
+0x6800000U,
+0x7000000U,
+0x7800000U,
+0x8000000U,
+0x8800000U,
+0x9000000U,
+0x9800000U,
+0xA000000U,
+0xA800000U,
+0xB000000U,
+0xB800000U,
+0xC000000U,
+0xC800000U,
+0xD000000U,
+0xD800000U,
+0xE000000U,
+0xE800000U,
+0xF000000U,
+0x47800000U,
+0x80000000U,
+0x80800000U,
+0x81000000U,
+0x81800000U,
+0x82000000U,
+0x82800000U,
+0x83000000U,
+0x83800000U,
+0x84000000U,
+0x84800000U,
+0x85000000U,
+0x85800000U,
+0x86000000U,
+0x86800000U,
+0x87000000U,
+0x87800000U,
+0x88000000U,
+0x88800000U,
+0x89000000U,
+0x89800000U,
+0x8A000000U,
+0x8A800000U,
+0x8B000000U,
+0x8B800000U,
+0x8C000000U,
+0x8C800000U,
+0x8D000000U,
+0x8D800000U,
+0x8E000000U,
+0x8E800000U,
+0x8F000000U,
+0xC7800000U,
+};
+
+const quint32 qfloat16::offsettable[64] = {
+0,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+0,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+1024U,
+};
+
+const quint32 qfloat16::basetable[512] = {
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x0U,
+0x1U,
+0x2U,
+0x4U,
+0x8U,
+0x10U,
+0x20U,
+0x40U,
+0x80U,
+0x100U,
+0x200U,
+0x400U,
+0x800U,
+0xC00U,
+0x1000U,
+0x1400U,
+0x1800U,
+0x1C00U,
+0x2000U,
+0x2400U,
+0x2800U,
+0x2C00U,
+0x3000U,
+0x3400U,
+0x3800U,
+0x3C00U,
+0x4000U,
+0x4400U,
+0x4800U,
+0x4C00U,
+0x5000U,
+0x5400U,
+0x5800U,
+0x5C00U,
+0x6000U,
+0x6400U,
+0x6800U,
+0x6C00U,
+0x7000U,
+0x7400U,
+0x7800U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x7C00U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8000U,
+0x8001U,
+0x8002U,
+0x8004U,
+0x8008U,
+0x8010U,
+0x8020U,
+0x8040U,
+0x8080U,
+0x8100U,
+0x8200U,
+0x8400U,
+0x8800U,
+0x8C00U,
+0x9000U,
+0x9400U,
+0x9800U,
+0x9C00U,
+0xA000U,
+0xA400U,
+0xA800U,
+0xAC00U,
+0xB000U,
+0xB400U,
+0xB800U,
+0xBC00U,
+0xC000U,
+0xC400U,
+0xC800U,
+0xCC00U,
+0xD000U,
+0xD400U,
+0xD800U,
+0xDC00U,
+0xE000U,
+0xE400U,
+0xE800U,
+0xEC00U,
+0xF000U,
+0xF400U,
+0xF800U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+0xFC00U,
+};
+
+const quint32 qfloat16::shifttable[512] = {
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x17U,
+0x16U,
+0x15U,
+0x14U,
+0x13U,
+0x12U,
+0x11U,
+0x10U,
+0xFU,
+0xEU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0xDU,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x17U,
+0x16U,
+0x15U,
+0x14U,
+0x13U,
+0x12U,
+0x11U,
+0x10U,
+0xFU,
+0xEU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0xDU,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0x18U,
+0xDU,
+};
+
+#endif // !__F16C__ && !__ARM_FP16_FORMAT_IEEE
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index be01e5a605..a8ed8ca6fd 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1553,6 +1553,13 @@ bool qSharedBuild() noexcept
*/
/*!
+ \macro Q_OS_WASM
+ \relates <QtGlobal>
+
+ Defined on Web Assembly.
+*/
+
+/*!
\macro Q_CC_SYM
\relates <QtGlobal>
@@ -2945,6 +2952,7 @@ QString QSysInfo::machineHostName()
struct utsname u;
if (uname(&u) == 0)
return QString::fromLocal8Bit(u.nodename);
+ return QString();
#else
# ifdef Q_OS_WIN
// Important: QtNetwork depends on machineHostName() initializing ws2_32.dll
@@ -2957,7 +2965,6 @@ QString QSysInfo::machineHostName()
hostName[sizeof(hostName) - 1] = '\0';
return QString::fromLocal8Bit(hostName);
#endif
- return QString();
}
#endif // QT_BOOTSTRAPPED
@@ -3612,7 +3619,7 @@ bool qEnvironmentVariableIsSet(const char *varName) noexcept
(void)getenv_s(&requiredSize, 0, 0, varName);
return requiredSize != 0;
#else
- return ::getenv(varName) != 0;
+ return ::getenv(varName) != nullptr;
#endif
}
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 630a3265e2..f85824c7b3 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1097,7 +1097,7 @@ for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
#endif
template <typename T> inline T *qGetPtrHelper(T *ptr) { return ptr; }
-template <typename Ptr> inline auto qGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
+template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
// The body must be a statement:
#define Q_CAST_IGNORE_ALIGN(body) QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wcast-align") body QT_WARNING_POP
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index 4f89876793..7a7d65ed76 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -80,15 +80,15 @@ enum GuardValues {
{ \
struct HolderBase { \
~HolderBase() noexcept \
- { if (guard.load() == QtGlobalStatic::Initialized) \
- guard.store(QtGlobalStatic::Destroyed); } \
+ { if (guard.loadRelaxed() == QtGlobalStatic::Initialized) \
+ guard.storeRelaxed(QtGlobalStatic::Destroyed); } \
}; \
static struct Holder : public HolderBase { \
Type value; \
Holder() \
noexcept(noexcept(Type ARGS)) \
: value ARGS \
- { guard.store(QtGlobalStatic::Initialized); } \
+ { guard.storeRelaxed(QtGlobalStatic::Initialized); } \
} holder; \
return &holder.value; \
}
@@ -108,12 +108,12 @@ QT_BEGIN_NAMESPACE
int x = guard.loadAcquire(); \
if (Q_UNLIKELY(x >= QtGlobalStatic::Uninitialized)) { \
QMutexLocker locker(&mutex); \
- if (guard.load() == QtGlobalStatic::Uninitialized) { \
+ if (guard.loadRelaxed() == QtGlobalStatic::Uninitialized) { \
d = new Type ARGS; \
static struct Cleanup { \
~Cleanup() { \
delete d; \
- guard.store(QtGlobalStatic::Destroyed); \
+ guard.storeRelaxed(QtGlobalStatic::Destroyed); \
} \
} cleanup; \
guard.storeRelease(QtGlobalStatic::Initialized); \
@@ -129,8 +129,8 @@ struct QGlobalStatic
{
typedef T Type;
- bool isDestroyed() const { return guard.load() <= QtGlobalStatic::Destroyed; }
- bool exists() const { return guard.load() == QtGlobalStatic::Initialized; }
+ bool isDestroyed() const { return guard.loadRelaxed() <= QtGlobalStatic::Destroyed; }
+ bool exists() const { return guard.loadRelaxed() == QtGlobalStatic::Initialized; }
operator Type *() { if (isDestroyed()) return nullptr; return innerFunction(); }
Type *operator()() { if (isDestroyed()) return nullptr; return innerFunction(); }
Type *operator->()
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index c3eb469767..e82939dcd9 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -432,7 +432,24 @@ void QLibraryInfo::reload()
{
QLibraryInfoPrivate::reload();
}
-#endif
+
+void QLibraryInfo::sysrootify(QString *path)
+{
+ if (!QVariant::fromValue(rawLocation(SysrootifyPrefixPath, FinalPaths)).toBool())
+ return;
+
+ const QString sysroot = rawLocation(SysrootPath, FinalPaths);
+ if (sysroot.isEmpty())
+ return;
+
+ if (path->length() > 2 && path->at(1) == QLatin1Char(':')
+ && (path->at(2) == QLatin1Char('/') || path->at(2) == QLatin1Char('\\'))) {
+ path->replace(0, 2, sysroot); // Strip out the drive on Windows targets
+ } else {
+ path->prepend(sysroot);
+ }
+}
+#endif // QT_BUILD_QMAKE
/*!
Returns the location specified by \a loc.
@@ -444,18 +461,8 @@ QLibraryInfo::location(LibraryLocation loc)
QString ret = rawLocation(loc, FinalPaths);
// Automatically prepend the sysroot to target paths
- if (loc < SysrootPath || loc > LastHostPath) {
- QString sysroot = rawLocation(SysrootPath, FinalPaths);
- if (!sysroot.isEmpty()
- && QVariant::fromValue(rawLocation(SysrootifyPrefixPath, FinalPaths)).toBool()) {
- if (ret.length() > 2 && ret.at(1) == QLatin1Char(':')
- && (ret.at(2) == QLatin1Char('/') || ret.at(2) == QLatin1Char('\\'))) {
- ret.replace(0, 2, sysroot); // Strip out the drive on Windows targets
- } else {
- ret.prepend(sysroot);
- }
- }
- }
+ if (loc < SysrootPath || loc > LastHostPath)
+ sysrootify(&ret);
return ret;
}
@@ -598,6 +605,8 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
} else {
// we make any other path absolute to the prefix directory
baseDir = rawLocation(PrefixPath, group);
+ if (group == EffectivePaths)
+ sysrootify(&baseDir);
}
#else
if (loc == PrefixPath) {
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index 20fd3897f7..ed60b170a5 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -107,6 +107,7 @@ public:
enum PathGroup { FinalPaths, EffectivePaths, EffectiveSourcePaths, DevicePaths };
static QString rawLocation(LibraryLocation, PathGroup);
static void reload();
+ static void sysrootify(QString *path);
#endif
static QStringList platformPluginArguments(const QString &platformName);
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 499ea3cdfb..f635a84e21 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -44,6 +44,7 @@
#include "qlogging_p.h"
#include "qlist.h"
#include "qbytearray.h"
+#include "qscopeguard.h"
#include "qstring.h"
#include "qvarlengtharray.h"
#include "qdebug.h"
@@ -158,6 +159,9 @@ static QT_PREPEND_NAMESPACE(qint64) qt_gettid()
#endif // !QT_BOOTSTRAPPED
#include <cstdlib>
+#include <algorithm>
+#include <memory>
+#include <vector>
#include <stdio.h>
@@ -194,7 +198,7 @@ static bool isFatal(QtMsgType msgType)
// it's fatal if the current value is exactly 1,
// otherwise decrement if it's non-zero
- return fatalCriticals.load() && fatalCriticals.fetchAndAddRelaxed(-1) == 1;
+ return fatalCriticals.loadRelaxed() && fatalCriticals.fetchAndAddRelaxed(-1) == 1;
}
if (msgType == QtWarningMsg || msgType == QtCriticalMsg) {
@@ -202,7 +206,7 @@ static bool isFatal(QtMsgType msgType)
// it's fatal if the current value is exactly 1,
// otherwise decrement if it's non-zero
- return fatalWarnings.load() && fatalWarnings.fetchAndAddRelaxed(-1) == 1;
+ return fatalWarnings.loadRelaxed() && fatalWarnings.fetchAndAddRelaxed(-1) == 1;
}
return false;
@@ -1076,8 +1080,8 @@ struct QMessagePattern {
void setPattern(const QString &pattern);
// 0 terminated arrays of literal tokens / literal or placeholder tokens
- const char **literals;
- const char **tokens;
+ std::unique_ptr<std::unique_ptr<const char[]>[]> literals;
+ std::unique_ptr<const char*[]> tokens;
QList<QString> timeArgs; // timeFormats in sequence of %{time
#ifndef QT_BOOTSTRAPPED
QElapsedTimer timer;
@@ -1100,9 +1104,6 @@ Q_DECLARE_TYPEINFO(QMessagePattern::BacktraceParams, Q_MOVABLE_TYPE);
QBasicMutex QMessagePattern::mutex;
QMessagePattern::QMessagePattern()
- : literals(0)
- , tokens(0)
- , fromEnvironment(false)
{
#ifndef QT_BOOTSTRAPPED
timer.start();
@@ -1110,6 +1111,7 @@ QMessagePattern::QMessagePattern()
const QString envPattern = QString::fromLocal8Bit(qgetenv("QT_MESSAGE_PATTERN"));
if (envPattern.isEmpty()) {
setPattern(QLatin1String(defaultPattern));
+ fromEnvironment = false;
} else {
setPattern(envPattern);
fromEnvironment = true;
@@ -1117,23 +1119,10 @@ QMessagePattern::QMessagePattern()
}
QMessagePattern::~QMessagePattern()
-{
- for (int i = 0; literals[i]; ++i)
- delete [] literals[i];
- delete [] literals;
- literals = 0;
- delete [] tokens;
- tokens = 0;
-}
+ = default;
void QMessagePattern::setPattern(const QString &pattern)
{
- if (literals) {
- for (int i = 0; literals[i]; ++i)
- delete [] literals[i];
- delete [] literals;
- }
- delete [] tokens;
timeArgs.clear();
#ifdef QLOGGING_HAVE_BACKTRACE
backtraceArgs.clear();
@@ -1171,9 +1160,9 @@ void QMessagePattern::setPattern(const QString &pattern)
lexemes.append(lexeme);
// tokenizer
- QVarLengthArray<const char*> literalsVar;
- tokens = new const char*[lexemes.size() + 1];
- tokens[lexemes.size()] = 0;
+ std::vector<std::unique_ptr<const char[]>> literalsVar;
+ tokens.reset(new const char*[lexemes.size() + 1]);
+ tokens[lexemes.size()] = nullptr;
bool nestedIfError = false;
bool inIf = false;
@@ -1267,7 +1256,7 @@ void QMessagePattern::setPattern(const QString &pattern)
char *literal = new char[lexeme.size() + 1];
strncpy(literal, lexeme.toLatin1().constData(), lexeme.size());
literal[lexeme.size()] = '\0';
- literalsVar.append(literal);
+ literalsVar.emplace_back(literal);
tokens[i] = literal;
}
}
@@ -1279,9 +1268,8 @@ void QMessagePattern::setPattern(const QString &pattern)
if (!error.isEmpty())
qt_message_print(error);
- literals = new const char*[literalsVar.size() + 1];
- literals[literalsVar.size()] = 0;
- memcpy(literals, literalsVar.constData(), literalsVar.size() * sizeof(const char*));
+ literals.reset(new std::unique_ptr<const char[]>[literalsVar.size() + 1]);
+ std::move(literalsVar.begin(), literalsVar.end(), &literals[0]);
}
#if defined(QLOGGING_HAVE_BACKTRACE) && !defined(QT_BOOTSTRAPPED)
@@ -1406,7 +1394,7 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
#endif
// we do not convert file, function, line literals to local encoding due to overhead
- for (int i = 0; pattern->tokens[i] != 0; ++i) {
+ for (int i = 0; pattern->tokens[i]; ++i) {
const char *token = pattern->tokens[i];
if (token == endifTokenC) {
skip = false;
@@ -1512,9 +1500,9 @@ static void qDefaultMsgHandler(QtMsgType type, const char *buf);
static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &buf);
// pointer to QtMsgHandler debug handler (without context)
-static QBasicAtomicPointer<void (QtMsgType, const char*)> msgHandler = Q_BASIC_ATOMIC_INITIALIZER(qDefaultMsgHandler);
+static QBasicAtomicPointer<void (QtMsgType, const char*)> msgHandler = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
// pointer to QtMessageHandler debug handler (with context)
-static QBasicAtomicPointer<void (QtMsgType, const QMessageLogContext &, const QString &)> messageHandler = Q_BASIC_ATOMIC_INITIALIZER(qDefaultMessageHandler);
+static QBasicAtomicPointer<void (QtMsgType, const QMessageLogContext &, const QString &)> messageHandler = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
// ------------------------ Alternate logging sinks -------------------------
@@ -1826,14 +1814,15 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
// prevent recursion in case the message handler generates messages
// itself, e.g. by using Qt API
if (grabMessageHandler()) {
+ const auto ungrab = qScopeGuard([]{ ungrabMessageHandler(); });
+ auto oldStyle = msgHandler.loadAcquire();
+ auto newStye = messageHandler.loadAcquire();
// prefer new message handler over the old one
- if (msgHandler.load() == qDefaultMsgHandler
- || messageHandler.load() != qDefaultMessageHandler) {
- (*messageHandler.load())(msgType, context, message);
+ if (newStye || !oldStyle) {
+ (newStye ? newStye : qDefaultMessageHandler)(msgType, context, message);
} else {
- (*msgHandler.load())(msgType, message.toLocal8Bit().constData());
+ (oldStyle ? oldStyle : qDefaultMsgHandler)(msgType, message.toLocal8Bit().constData());
}
- ungrabMessageHandler();
} else {
fprintf(stderr, "%s\n", message.toLocal8Bit().constData());
}
@@ -2084,18 +2073,20 @@ void qErrnoWarning(int code, const char *msg, ...)
QtMessageHandler qInstallMessageHandler(QtMessageHandler h)
{
- if (!h)
- h = qDefaultMessageHandler;
- //set 'h' and return old message handler
- return messageHandler.fetchAndStoreRelaxed(h);
+ const auto old = messageHandler.fetchAndStoreOrdered(h);
+ if (old)
+ return old;
+ else
+ return qDefaultMessageHandler;
}
QtMsgHandler qInstallMsgHandler(QtMsgHandler h)
{
- if (!h)
- h = qDefaultMsgHandler;
- //set 'h' and return old message handler
- return msgHandler.fetchAndStoreRelaxed(h);
+ const auto old = msgHandler.fetchAndStoreOrdered(h);
+ if (old)
+ return old;
+ else
+ return qDefaultMsgHandler;
}
void qSetMessagePattern(const QString &pattern)
diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp
index 05676a0da2..b071c1df62 100644
--- a/src/corelib/global/qmalloc.cpp
+++ b/src/corelib/global/qmalloc.cpp
@@ -74,18 +74,18 @@ void *qRealloc(void *ptr, size_t size)
void *qMallocAligned(size_t size, size_t alignment)
{
- return qReallocAligned(0, size, 0, alignment);
+ return qReallocAligned(nullptr, size, 0, alignment);
}
void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t alignment)
{
// fake an aligned allocation
- void *actualptr = oldptr ? static_cast<void **>(oldptr)[-1] : 0;
+ void *actualptr = oldptr ? static_cast<void **>(oldptr)[-1] : nullptr;
if (alignment <= sizeof(void*)) {
// special, fast case
void **newptr = static_cast<void **>(realloc(actualptr, newsize + sizeof(void*)));
if (!newptr)
- return 0;
+ return nullptr;
if (newptr == actualptr) {
// realloc succeeded without reallocating
return oldptr;
@@ -105,7 +105,7 @@ void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t align
void *real = realloc(actualptr, newsize + alignment);
if (!real)
- return 0;
+ return nullptr;
quintptr faked = reinterpret_cast<quintptr>(real) + alignment;
faked &= ~(alignment - 1);
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 45d79902c7..0ff6be2049 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -2369,7 +2369,7 @@
*/
/*!
- \enum Qt::SplitBehavior
+ \enum Qt::SplitBehaviorFlags
\since 5.14
This enum specifies how the split() functions should behave with
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
index 42a1275621..9084ad933c 100644
--- a/src/corelib/global/qoperatingsystemversion.cpp
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -356,6 +356,14 @@ bool QOperatingSystemVersion::isAnyOfType(std::initializer_list<OSType> types) c
}
/*!
+ \variable QOperatingSystemVersion::WindowsVista
+ \brief a version corresponding to Windows Vista (version 6.0).
+ \since 6.0
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::WindowsVista =
+ QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 0);
+
+/*!
\variable QOperatingSystemVersion::Windows7
\brief a version corresponding to Windows 7 (version 6.1).
\since 5.9
diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h
index e99e4f8997..75c54b60df 100644
--- a/src/corelib/global/qoperatingsystemversion.h
+++ b/src/corelib/global/qoperatingsystemversion.h
@@ -60,6 +60,7 @@ public:
Android
};
+ static const QOperatingSystemVersion WindowsVista;
static const QOperatingSystemVersion Windows7;
static const QOperatingSystemVersion Windows8;
static const QOperatingSystemVersion Windows8_1;
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 2ee8f0dd01..711eb8f4d5 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -186,7 +186,7 @@ struct QRandomGenerator::SystemGenerator
#endif
static void closeDevice()
{
- int fd = self().fdp1.load() - 1;
+ int fd = self().fdp1.loadRelaxed() - 1;
if (fd >= 0)
qt_safe_close(fd);
}
@@ -310,7 +310,7 @@ static void fallback_fill(quint32 *ptr, qsizetype left) noexcept
*end++ = quint32(nsecs); // 5
#endif
- if (quint32 v = seed.load())
+ if (quint32 v = seed.loadRelaxed())
*end++ = v; // 6
#if QT_CONFIG(getauxval)
@@ -359,17 +359,17 @@ Q_NEVER_INLINE void QRandomGenerator::SystemGenerator::generate(quint32 *begin,
quint32 *buffer = begin;
qsizetype count = end - begin;
- if (Q_UNLIKELY(uint(qt_randomdevice_control) & SetRandomData)) {
- uint value = uint(qt_randomdevice_control) & RandomDataMask;
+ if (Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & SetRandomData)) {
+ uint value = uint(qt_randomdevice_control.loadAcquire()) & RandomDataMask;
std::fill_n(buffer, count, value);
return;
}
qsizetype filled = 0;
- if (qt_has_hwrng() && (uint(qt_randomdevice_control) & SkipHWRNG) == 0)
+ if (qt_has_hwrng() && (uint(qt_randomdevice_control.loadAcquire()) & SkipHWRNG) == 0)
filled += qt_random_cpu(buffer, count);
- if (filled != count && (uint(qt_randomdevice_control) & SkipSystemRNG) == 0) {
+ if (filled != count && (uint(qt_randomdevice_control.loadAcquire()) & SkipSystemRNG) == 0) {
qsizetype bytesFilled =
fillBuffer(buffer + filled, (count - filled) * qsizetype(sizeof(*buffer)));
filled += bytesFilled / qsizetype(sizeof(*buffer));
@@ -903,6 +903,10 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\snippet code/src_corelib_global_qrandom.cpp 12
+ If the \a highest parameter is negative, the result will be negative too;
+ if it is infinite or NaN, the result will be infinite or NaN too (that is,
+ not random).
+
\sa generateDouble(), bounded()
*/
@@ -934,7 +938,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\overload
Generates one random 32-bit quantity in the range between 0 (inclusive) and
- \a highest (exclusive). \a highest must not be negative.
+ \a highest (exclusive). \a highest must be positive.
Note that this function cannot be used to obtain values in the full 32-bit
range of int. Instead, use generate() and cast to int.
@@ -946,8 +950,11 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\fn quint32 QRandomGenerator::bounded(quint32 lowest, quint32 highest)
\overload
- Generates one random 32-bit quantity in the range between \a lowest (inclusive)
- and \a highest (exclusive). The same result may also be obtained by using
+ Generates one random 32-bit quantity in the range between \a lowest
+ (inclusive) and \a highest (exclusive). The \a highest parameter must be
+ greater than \a lowest.
+
+ The same result may also be obtained by using
\l{http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution}{\c std::uniform_int_distribution}
with parameters \a lowest and \c{\a highest - 1}. That class can also be used to
obtain quantities larger than 32 bits.
@@ -968,7 +975,8 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\overload
Generates one random 32-bit quantity in the range between \a lowest
- (inclusive) and \a highest (exclusive), both of which may be negative.
+ (inclusive) and \a highest (exclusive), both of which may be negative, but
+ \a highest must be greater than \a lowest.
Note that this function cannot be used to obtain values in the full 32-bit
range of int. Instead, use generate() and cast to int.
@@ -1222,7 +1230,7 @@ void QRandomGenerator::_fillRange(void *buffer, void *bufferEnd)
quint32 *begin = static_cast<quint32 *>(buffer);
quint32 *end = static_cast<quint32 *>(bufferEnd);
- if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control) & (UseSystemRNG|SetRandomData)))
+ if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & (UseSystemRNG|SetRandomData)))
return SystemGenerator::self().generate(begin, end);
SystemAndGlobalGenerators::PRNGLocker lock(this);
diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h
index 2f72528266..445b520c76 100644
--- a/src/corelib/global/qrandom.h
+++ b/src/corelib/global/qrandom.h
@@ -122,14 +122,16 @@ public:
return quint32(value);
}
- int bounded(int highest)
+ quint32 bounded(quint32 lowest, quint32 highest)
{
- return int(bounded(quint32(highest)));
+ Q_ASSERT(highest > lowest);
+ return bounded(highest - lowest) + lowest;
}
- quint32 bounded(quint32 lowest, quint32 highest)
+ int bounded(int highest)
{
- return bounded(highest - lowest) + lowest;
+ Q_ASSERT(highest > 0);
+ return int(bounded(0U, quint32(highest)));
}
int bounded(int lowest, int highest)
diff --git a/src/corelib/global/qrandom_p.h b/src/corelib/global/qrandom_p.h
index 917a91098e..167f4cc57d 100644
--- a/src/corelib/global/qrandom_p.h
+++ b/src/corelib/global/qrandom_p.h
@@ -76,7 +76,9 @@ Q_CORE_EXPORT QBasicAtomicInteger<uint> qt_randomdevice_control = Q_BASIC_ATOMIC
#elif defined(QT_BUILD_INTERNAL)
extern Q_CORE_EXPORT QBasicAtomicInteger<uint> qt_randomdevice_control;
#else
-enum { qt_randomdevice_control = 0 };
+static const struct {
+ uint loadAcquire() const { return 0; }
+} qt_randomdevice_control;
#endif
inline bool qt_has_hwrng()
diff --git a/src/corelib/io/forkfd_qt.cpp b/src/corelib/io/forkfd_qt.cpp
index dce0ebb4da..80d1cd54d7 100644
--- a/src/corelib/io/forkfd_qt.cpp
+++ b/src/corelib/io/forkfd_qt.cpp
@@ -56,8 +56,6 @@ QT_BEGIN_NAMESPACE
#define FFD_ATOMIC_RELAXED Relaxed
#define FFD_ATOMIC_ACQUIRE Acquire
#define FFD_ATOMIC_RELEASE Release
-#define loadRelaxed load
-#define storeRelaxed store
#define FFD_CONCAT(x, y) x ## y
diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp
index f2a895bbb8..8a1679c5af 100644
--- a/src/corelib/io/qabstractfileengine.cpp
+++ b/src/corelib/io/qabstractfileengine.cpp
@@ -159,7 +159,7 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandler()
*/
QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path)
{
- QAbstractFileEngine *engine = 0;
+ QAbstractFileEngine *engine = nullptr;
if (qt_file_engine_handlers_in_use) {
QReadLocker locker(fileEngineHandlerMutex());
@@ -658,7 +658,7 @@ QStringList QAbstractFileEngine::entryList(QDir::Filters filters, const QStringL
QAbstractFileEngine::FileFlags QAbstractFileEngine::fileFlags(FileFlags type) const
{
Q_UNUSED(type);
- return 0;
+ return nullptr;
}
/*!
@@ -838,7 +838,7 @@ uchar *QAbstractFileEngine::map(qint64 offset, qint64 size, QFile::MemoryMapFlag
option.flags = flags;
MapExtensionReturn r;
if (!extension(MapExtension, &option, &r))
- return 0;
+ return nullptr;
return r.address;
}
@@ -1118,7 +1118,7 @@ QAbstractFileEngine::Iterator *QAbstractFileEngine::beginEntryList(QDir::Filters
{
Q_UNUSED(filters);
Q_UNUSED(filterNames);
- return 0;
+ return nullptr;
}
/*!
@@ -1126,7 +1126,7 @@ QAbstractFileEngine::Iterator *QAbstractFileEngine::beginEntryList(QDir::Filters
*/
QAbstractFileEngine::Iterator *QAbstractFileEngine::endEntryList()
{
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp
index 7b3fa2ccad..8e980733de 100644
--- a/src/corelib/io/qbuffer.cpp
+++ b/src/corelib/io/qbuffer.cpp
@@ -50,7 +50,7 @@ class QBufferPrivate : public QIODevicePrivate
public:
QBufferPrivate()
- : buf(0)
+ : buf(nullptr)
#ifndef QT_NO_QOBJECT
, writtenSinceLastEmit(0), signalConnectionCount(0), signalsEmitted(false)
#endif
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 6dc12cd83f..d13e94e096 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -147,7 +147,7 @@ using QtMiscUtils::fromHex;
// Has been defined in the header / inlined before Qt 5.4
QDebug::~QDebug()
{
- if (!--stream->ref) {
+ if (stream && !--stream->ref) {
if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
stream->buffer.chop(1);
if (stream->message_output) {
@@ -843,36 +843,34 @@ QDebug &QDebug::resetFormat()
class QDebugStateSaverPrivate
{
public:
- QDebugStateSaverPrivate(QDebug &dbg)
- : m_dbg(dbg),
- m_spaces(dbg.autoInsertSpaces()),
- m_flags(0),
- m_streamParams(dbg.stream->ts.d_ptr->params)
+ QDebugStateSaverPrivate(QDebug::Stream *stream)
+ : m_stream(stream),
+ m_spaces(stream->space),
+ m_flags(stream->context.version > 1 ? stream->flags : 0),
+ m_streamParams(stream->ts.d_ptr->params)
{
- if (m_dbg.stream->context.version > 1)
- m_flags = m_dbg.stream->flags;
}
void restoreState()
{
- const bool currentSpaces = m_dbg.autoInsertSpaces();
+ const bool currentSpaces = m_stream->space;
if (currentSpaces && !m_spaces)
- if (m_dbg.stream->buffer.endsWith(QLatin1Char(' ')))
- m_dbg.stream->buffer.chop(1);
+ if (m_stream->buffer.endsWith(QLatin1Char(' ')))
+ m_stream->buffer.chop(1);
- m_dbg.setAutoInsertSpaces(m_spaces);
- m_dbg.stream->ts.d_ptr->params = m_streamParams;
- if (m_dbg.stream->context.version > 1)
- m_dbg.stream->flags = m_flags;
+ m_stream->space = m_spaces;
+ m_stream->ts.d_ptr->params = m_streamParams;
+ if (m_stream->context.version > 1)
+ m_stream->flags = m_flags;
if (!currentSpaces && m_spaces)
- m_dbg.stream->ts << ' ';
+ m_stream->ts << ' ';
}
- QDebug &m_dbg;
+ QDebug::Stream *m_stream;
// QDebug state
const bool m_spaces;
- int m_flags;
+ const int m_flags;
// QTextStream state
const QTextStreamPrivate::Params m_streamParams;
@@ -886,7 +884,7 @@ public:
\sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
*/
QDebugStateSaver::QDebugStateSaver(QDebug &dbg)
- : d(new QDebugStateSaverPrivate(dbg))
+ : d(new QDebugStateSaverPrivate(dbg.stream))
{
}
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 889fb6b571..421c5d933b 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT QDebug
{
friend class QMessageLogger;
+ friend class QDebugStateSaver;
friend class QDebugStateSaverPrivate;
struct Stream {
enum { VerbosityShift = 29, VerbosityMask = 0x7 };
@@ -114,7 +115,10 @@ public:
inline QDebug(QString *string) : stream(new Stream(string)) {}
inline QDebug(QtMsgType t) : stream(new Stream(t)) {}
inline QDebug(const QDebug &o):stream(o.stream) { ++stream->ref; }
+ QDebug(QDebug &&other) noexcept : stream{qExchange(other.stream, nullptr)} {}
inline QDebug &operator=(const QDebug &other);
+ QDebug &operator=(QDebug &&other) noexcept
+ { QDebug{std::move(other)}.swap(*this); return *this; }
~QDebug();
inline void swap(QDebug &other) noexcept { qSwap(stream, other.stream); }
@@ -203,10 +207,7 @@ public:
inline QDebug &QDebug::operator=(const QDebug &other)
{
- if (this != &other) {
- QDebug copy(other);
- qSwap(stream, copy.stream);
- }
+ QDebug{other}.swap(*this);
return *this;
}
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 671913e92f..62dae3577c 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -1431,7 +1431,7 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters,
l.append(it.fileInfo());
}
QStringList ret;
- d->sortFileList(sort, l, &ret, 0);
+ d->sortFileList(sort, l, &ret, nullptr);
return ret;
}
@@ -1473,7 +1473,7 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter
l.append(it.fileInfo());
}
QFileInfoList ret;
- d->sortFileList(sort, l, 0, &ret);
+ d->sortFileList(sort, l, nullptr, &ret);
return ret;
}
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp
index 21214ee273..303caf29a4 100644
--- a/src/corelib/io/qdiriterator.cpp
+++ b/src/corelib/io/qdiriterator.cpp
@@ -97,6 +97,9 @@
#include <QtCore/qset.h>
#include <QtCore/qstack.h>
#include <QtCore/qvariant.h>
+#if QT_CONFIG(regularexpression)
+#include <QtCore/qregularexpression.h>
+#endif
#include <QtCore/private/qfilesystemiterator_p.h>
#include <QtCore/private/qfilesystementry_p.h>
@@ -136,8 +139,11 @@ public:
const QDir::Filters filters;
const QDirIterator::IteratorFlags iteratorFlags;
-#ifndef QT_NO_REGEXP
+#if defined(QT_BOOTSTRAPPED)
+ // ### Qt6: Get rid of this once we don't bootstrap qmake anymore
QVector<QRegExp> nameRegExps;
+#elif QT_CONFIG(regularexpression)
+ QVector<QRegularExpression> nameRegExps;
#endif
QDirIteratorPrivateIteratorStack<QAbstractFileEngineIterator> fileEngineIterators;
@@ -162,13 +168,21 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QFileSystemEntry &entry, const QS
, filters(QDir::NoFilter == filters ? QDir::AllEntries : filters)
, iteratorFlags(flags)
{
-#ifndef QT_NO_REGEXP
+#if defined(QT_BOOTSTRAPPED)
nameRegExps.reserve(nameFilters.size());
- for (int i = 0; i < nameFilters.size(); ++i)
+ for (const auto &filter : nameFilters) {
nameRegExps.append(
- QRegExp(nameFilters.at(i),
+ QRegExp(filter,
(filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive,
QRegExp::Wildcard));
+ }
+#elif QT_CONFIG(regularexpression)
+ nameRegExps.reserve(nameFilters.size());
+ for (const auto &filter : nameFilters) {
+ QString re = QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(filter));
+ nameRegExps.append(
+ QRegularExpression(re, (filters & QDir::CaseSensitive) ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption));
+ }
#endif
QFileSystemMetaData metaData;
if (resolveEngine)
@@ -335,19 +349,23 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf
return false;
// name filter
-#ifndef QT_NO_REGEXP
+#if QT_CONFIG(regularexpression) || defined(QT_BOOTSTRAPPED)
// Pass all entries through name filters, except dirs if the AllDirs
if (!nameFilters.isEmpty() && !((filters & QDir::AllDirs) && fi.isDir())) {
bool matched = false;
- for (QVector<QRegExp>::const_iterator iter = nameRegExps.constBegin(),
- end = nameRegExps.constEnd();
- iter != end; ++iter) {
-
- QRegExp copy = *iter;
+ for (const auto &re : nameRegExps) {
+#if defined(QT_BOOTSTRAPPED)
+ QRegExp copy = re;
if (copy.exactMatch(fileName)) {
matched = true;
break;
}
+#else
+ if (re.match(fileName).hasMatch()) {
+ matched = true;
+ break;
+ }
+#endif
}
if (!matched)
return false;
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 8d871904bc..9f9a9e3040 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -86,7 +86,7 @@ QFilePrivate::openExternalFile(int flags, int fd, QFile::FileHandleFlags handleF
return false;
#else
delete fileEngine;
- fileEngine = 0;
+ fileEngine = nullptr;
QFSFileEngine *fe = new QFSFileEngine;
fileEngine = fe;
return fe->open(QIODevice::OpenMode(flags), fd, handleFlags);
@@ -102,7 +102,7 @@ QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handl
return false;
#else
delete fileEngine;
- fileEngine = 0;
+ fileEngine = nullptr;
QFSFileEngine *fe = new QFSFileEngine;
fileEngine = fe;
return fe->open(QIODevice::OpenMode(flags), fh, handleFlags);
@@ -336,7 +336,7 @@ QFile::setFileName(const QString &name)
}
if(d->fileEngine) { //get a new file engine later
delete d->fileEngine;
- d->fileEngine = 0;
+ d->fileEngine = nullptr;
}
d->fileName = name;
}
@@ -810,7 +810,7 @@ QFile::copy(const QString &newName)
error = true;
d->setError(QFile::CopyError, tr("Cannot open %1 for input").arg(d->fileName));
} else {
- QString fileTemplate = QLatin1String("%1/qt_temp.XXXXXX");
+ const auto fileTemplate = QLatin1String("%1/qt_temp.XXXXXX");
#ifdef QT_NO_TEMPORARYFILE
QFile out(fileTemplate.arg(QFileInfo(newName).path()));
if (!out.open(QIODevice::ReadWrite))
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index 0689118f3e..2f74547054 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
#endif
QFileDevicePrivate::QFileDevicePrivate()
- : fileEngine(0),
+ : fileEngine(nullptr),
cachedSize(0),
error(QFile::NoError), lastWasWrite(false)
{
@@ -63,7 +63,7 @@ QFileDevicePrivate::QFileDevicePrivate()
QFileDevicePrivate::~QFileDevicePrivate()
{
delete fileEngine;
- fileEngine = 0;
+ fileEngine = nullptr;
}
QAbstractFileEngine * QFileDevicePrivate::engine() const
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 998382021d..f5b398feae 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -52,7 +52,7 @@ QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
return fileNames[(int)name];
QString ret;
- if (fileEngine == 0) { // local file; use the QFileSystemEngine directly
+ if (fileEngine == nullptr) { // local file; use the QFileSystemEngine directly
switch (name) {
case QAbstractFileEngine::CanonicalName:
case QAbstractFileEngine::CanonicalPathName: {
@@ -103,7 +103,7 @@ QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const
if (cache_enabled && !fileOwners[(int)own].isNull())
return fileOwners[(int)own];
QString ret;
- if (fileEngine == 0) {
+ if (fileEngine == nullptr) {
switch (own) {
case QAbstractFileEngine::OwnerUser:
ret = QFileSystemEngine::resolveUserName(fileEntry, metaData);
@@ -134,7 +134,7 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons
// extra syscall. Bundle detecton on Mac can be slow, expecially on network
// paths, so we separate out that as well.
- QAbstractFileEngine::FileFlags req = 0;
+ QAbstractFileEngine::FileFlags req = nullptr;
uint cachedFlags = 0;
if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) {
@@ -434,7 +434,7 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const
return true;
Qt::CaseSensitivity sensitive;
- if (d->fileEngine == 0 || fileinfo.d_ptr->fileEngine == 0) {
+ if (d->fileEngine == nullptr || fileinfo.d_ptr->fileEngine == nullptr) {
if (d->fileEngine != fileinfo.d_ptr->fileEngine) // one is native, the other is a custom file-engine
return false;
@@ -649,7 +649,7 @@ bool QFileInfo::isRelative() const
Q_D(const QFileInfo);
if (d->isDefaultConstructed)
return true;
- if (d->fileEngine == 0)
+ if (d->fileEngine == nullptr)
return d->fileEntry.isRelative();
return d->fileEngine->isRelativePath();
}
@@ -682,7 +682,7 @@ bool QFileInfo::exists() const
Q_D(const QFileInfo);
if (d->isDefaultConstructed)
return false;
- if (d->fileEngine == 0) {
+ if (d->fileEngine == nullptr) {
if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute))
QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute);
return d->metaData.exists();
@@ -982,7 +982,7 @@ bool QFileInfo::isNativePath() const
Q_D(const QFileInfo);
if (d->isDefaultConstructed)
return false;
- if (d->fileEngine == 0)
+ if (d->fileEngine == nullptr)
return true;
return d->getFileFlags(QAbstractFileEngine::LocalDiskFlag);
}
@@ -1075,7 +1075,7 @@ bool QFileInfo::isRoot() const
Q_D(const QFileInfo);
if (d->isDefaultConstructed)
return false;
- if (d->fileEngine == 0) {
+ if (d->fileEngine == nullptr) {
if (d->fileEntry.isRoot()) {
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
//the path is a drive root, but the drive may not exist
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index 7f65b0f8f7..b1c2d84cdb 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -228,7 +228,18 @@ QUrl QFileSelector::select(const QUrl &filePath) const
QString selectedPath = d->select(equivalentPath);
ret.setPath(selectedPath.remove(0, scheme.size()));
} else {
+ // we need to store the original query and fragment, since toLocalFile() will strip it off
+ QString frag;
+ if (ret.hasFragment())
+ frag = ret.fragment();
+ QString query;
+ if (ret.hasQuery())
+ query= ret.query();
ret = QUrl::fromLocalFile(d->select(ret.toLocalFile()));
+ if (!frag.isNull())
+ ret.setFragment(frag);
+ if (!query.isNull())
+ ret.setQuery(query);
}
return ret;
}
diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp
index 7abdf90bf5..21847c2a7c 100644
--- a/src/corelib/io/qfilesystemengine.cpp
+++ b/src/corelib/io/qfilesystemengine.cpp
@@ -124,7 +124,7 @@ static inline bool _q_checkEntry(QAbstractFileEngine *&engine, bool resolvingEnt
if (resolvingEntry) {
if (!(engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag)) {
delete engine;
- engine = 0;
+ engine = nullptr;
return false;
}
}
@@ -191,7 +191,7 @@ static bool _q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry &ent
QAbstractFileEngine *QFileSystemEngine::resolveEntryAndCreateLegacyEngine(
QFileSystemEntry &entry, QFileSystemMetaData &data) {
QFileSystemEntry copy = entry;
- QAbstractFileEngine *engine = 0;
+ QAbstractFileEngine *engine = nullptr;
if (_q_resolveEntryAndCreateLegacyEngine_recursive(copy, data, engine))
// Reset entry to resolved copy.
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index b78e037865..066a7c3f01 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -813,7 +813,7 @@ QString QFileSystemEngine::resolveUserName(uint userId)
#endif
#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_WASM)
- struct passwd *pw = 0;
+ struct passwd *pw = nullptr;
#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS)
struct passwd entry;
getpwuid_r(userId, &entry, buf.data(), buf.size(), &pw);
@@ -837,7 +837,7 @@ QString QFileSystemEngine::resolveGroupName(uint groupId)
#endif
#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_WASM)
- struct group *gr = 0;
+ struct group *gr = nullptr;
#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID) && (__ANDROID_API__ >= 24))
size_max = sysconf(_SC_GETGR_R_SIZE_MAX);
if (size_max == -1)
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp
index a9acf542d4..5ac7e13a2e 100644
--- a/src/corelib/io/qfilesystemiterator_unix.cpp
+++ b/src/corelib/io/qfilesystemiterator_unix.cpp
@@ -50,15 +50,15 @@ QT_BEGIN_NAMESPACE
QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters,
const QStringList &nameFilters, QDirIterator::IteratorFlags flags)
: nativePath(entry.nativeFilePath())
- , dir(0)
- , dirEntry(0)
+ , dir(nullptr)
+ , dirEntry(nullptr)
, lastError(0)
{
Q_UNUSED(filters)
Q_UNUSED(nameFilters)
Q_UNUSED(flags)
- if ((dir = QT_OPENDIR(nativePath.constData())) == 0) {
+ if ((dir = QT_OPENDIR(nativePath.constData())) == nullptr) {
lastError = errno;
} else {
if (!nativePath.endsWith('/'))
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index e3e4433a6b..64c422c55a 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -47,7 +47,7 @@
#include <qset.h>
#include <qtimer.h>
-#if defined(Q_OS_LINUX) || (defined(Q_OS_QNX) && !defined(QT_NO_INOTIFY))
+#if (defined(Q_OS_LINUX) || defined(Q_OS_QNX)) && QT_CONFIG(inotify)
#define USE_INOTIFY
#endif
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index fb3b6f86fd..6194bf7c71 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -50,6 +50,7 @@
#include <qfile.h>
#include <qfileinfo.h>
#include <qvarlengtharray.h>
+#include <qscopeguard.h>
#undef FSEVENT_DEBUG
#ifdef FSEVENT_DEBUG
@@ -338,10 +339,10 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
bool needsRestart = false;
WatchingState oldState = watchingState;
- QStringList p = paths;
- QMutableListIterator<QString> it(p);
- while (it.hasNext()) {
- QString origPath = it.next().normalized(QString::NormalizationForm_C);
+ QStringList unhandled;
+ for (const QString &path : paths) {
+ auto sg = qScopeGuard([&]{ unhandled.push_back(path); });
+ QString origPath = path.normalized(QString::NormalizationForm_C);
QString realPath = origPath;
if (realPath.endsWith(QDir::separator()))
realPath = realPath.mid(0, realPath.size() - 1);
@@ -362,17 +363,17 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
continue;
directories->append(origPath);
watchedPath = realPath;
- it.remove();
} else {
if (files->contains(origPath))
continue;
files->append(origPath);
- it.remove();
watchedPath = fi.path();
parentPath = watchedPath;
}
+ sg.dismiss();
+
for (PathRefCounts::const_iterator i = watchingState.watchedPaths.begin(),
ei = watchingState.watchedPaths.end(); i != ei; ++i) {
if (watchedPath.startsWith(i.key() % QDir::separator())) {
@@ -409,14 +410,14 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
// ok, something went wrong, let's try to restore the previous state
watchingState = std::move(oldState);
// and because we don't know which path caused the issue (if any), fail on all of them
- p = paths;
+ unhandled = paths;
if (wasRunning)
startStream();
}
}
- return p;
+ return unhandled;
}
QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &paths,
@@ -430,10 +431,9 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
bool needsRestart = false;
WatchingState oldState = watchingState;
- QStringList p = paths;
- QMutableListIterator<QString> it(p);
- while (it.hasNext()) {
- QString origPath = it.next();
+ QStringList unhandled;
+ for (const QString &origPath : paths) {
+ auto sg = qScopeGuard([&]{ unhandled.push_back(origPath); });
QString realPath = origPath;
if (realPath.endsWith(QDir::separator()))
realPath = realPath.mid(0, realPath.size() - 1);
@@ -447,7 +447,7 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
needsRestart |= derefPath(dirIt->dirInfo.watchedPath);
watchingState.watchedDirectories.erase(dirIt);
directories->removeAll(origPath);
- it.remove();
+ sg.dismiss();
DEBUG("Removed directory '%s'", qPrintable(realPath));
}
} else {
@@ -463,7 +463,7 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
if (filesInDir.isEmpty())
watchingState.watchedFiles.erase(pIt);
files->removeAll(origPath);
- it.remove();
+ sg.dismiss();
DEBUG("Removed file '%s'", qPrintable(realPath));
}
}
@@ -479,7 +479,7 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
}
}
- return p;
+ return unhandled;
}
// Returns false if FSEventStream* calls failed for some mysterious reason, true if things got a
diff --git a/src/corelib/io/qfilesystemwatcher_polling.cpp b/src/corelib/io/qfilesystemwatcher_polling.cpp
index a95a48cc8f..e07b02f7c2 100644
--- a/src/corelib/io/qfilesystemwatcher_polling.cpp
+++ b/src/corelib/io/qfilesystemwatcher_polling.cpp
@@ -110,33 +110,32 @@ QStringList QPollingFileSystemWatcherEngine::removePaths(const QStringList &path
void QPollingFileSystemWatcherEngine::timeout()
{
- QMutableHashIterator<QString, FileInfo> fit(files);
- while (fit.hasNext()) {
- QHash<QString, FileInfo>::iterator x = fit.next();
+ for (auto it = files.begin(), end = files.end(); it != end; /*erasing*/) {
+ auto x = it++;
QString path = x.key();
QFileInfo fi(path);
if (!fi.exists()) {
- fit.remove();
+ files.erase(x);
emit fileChanged(path, true);
} else if (x.value() != fi) {
x.value() = fi;
emit fileChanged(path, false);
}
}
- QMutableHashIterator<QString, FileInfo> dit(directories);
- while (dit.hasNext()) {
- QHash<QString, FileInfo>::iterator x = dit.next();
+
+ for (auto it = directories.begin(), end = directories.end(); it != end; /*erasing*/) {
+ auto x = it++;
QString path = x.key();
QFileInfo fi(path);
if (!path.endsWith(QLatin1Char('/')))
fi = QFileInfo(path + QLatin1Char('/'));
if (!fi.exists()) {
- dit.remove();
+ directories.erase(x);
emit directoryChanged(path, true);
} else if (x.value() != fi) {
fi.refresh();
if (!fi.exists()) {
- dit.remove();
+ directories.erase(x);
emit directoryChanged(path, true);
} else {
x.value() = fi;
diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp
index c568369a06..bdbd3ba868 100644
--- a/src/corelib/io/qfilesystemwatcher_win.cpp
+++ b/src/corelib/io/qfilesystemwatcher_win.cpp
@@ -695,9 +695,8 @@ void QWindowsFileSystemWatcherEngineThread::run()
qErrnoWarning(error, "%ls", qUtf16Printable(msgFindNextFailed(h)));
}
- QMutableHashIterator<QFileSystemWatcherPathKey, QWindowsFileSystemWatcherEngine::PathInfo> it(h);
- while (it.hasNext()) {
- QWindowsFileSystemWatcherEngineThread::PathInfoHash::iterator x = it.next();
+ for (auto it = h.begin(), end = h.end(); it != end; /*erasing*/ ) {
+ auto x = it++;
QString absolutePath = x.value().absolutePath;
QFileInfo fileInfo(x.value().path);
DEBUG() << "checking" << x.key();
@@ -723,6 +722,7 @@ void QWindowsFileSystemWatcherEngineThread::run()
handleForDir.remove(QFileSystemWatcherPathKey(absolutePath));
// h is now invalid
+ break;
}
} else if (x.value().isDir) {
DEBUG() << x.key() << "directory changed!";
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 387990ed79..0db27f3e25 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -127,7 +127,7 @@ void QFSFileEnginePrivate::init()
is_link = 0;
openMode = QIODevice::NotOpen;
fd = -1;
- fh = 0;
+ fh = nullptr;
lastIOCommand = IOFlushCommand;
lastFlushFailed = false;
closeFileHandle = false;
@@ -240,7 +240,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode)
d->openMode = openMode;
d->lastFlushFailed = false;
d->tried_stat = 0;
- d->fh = 0;
+ d->fh = nullptr;
d->fd = -1;
return d->nativeOpen(openMode);
@@ -299,7 +299,7 @@ bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh)
QSystemError::stdString());
this->openMode = QIODevice::NotOpen;
- this->fh = 0;
+ this->fh = nullptr;
return false;
}
@@ -328,7 +328,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle
d->lastFlushFailed = false;
d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle);
d->fileEntry.clear();
- d->fh = 0;
+ d->fh = nullptr;
d->fd = -1;
d->tried_stat = 0;
@@ -344,7 +344,7 @@ bool QFSFileEnginePrivate::openFd(QIODevice::OpenMode openMode, int fd)
{
Q_Q(QFSFileEngine);
this->fd = fd;
- fh = 0;
+ fh = nullptr;
// Seek to the end when in Append mode.
if (openMode & QFile::Append) {
@@ -405,7 +405,7 @@ bool QFSFileEnginePrivate::closeFdFh()
// We must reset these guys regardless; calling close again after a
// failed close causes crashes on some systems.
- fh = 0;
+ fh = nullptr;
fd = -1;
closed = (ret == 0);
}
@@ -822,7 +822,7 @@ QAbstractFileEngine::Iterator *QFSFileEngine::beginEntryList(QDir::Filters filte
*/
QAbstractFileEngine::Iterator *QFSFileEngine::endEntryList()
{
- return 0;
+ return nullptr;
}
#endif // QT_NO_FILESYSTEMITERATOR
@@ -870,7 +870,7 @@ bool QFSFileEngine::extension(Extension extension, const ExtensionOption *option
const MapExtensionOption *options = (const MapExtensionOption*)(option);
MapExtensionReturn *returnValue = static_cast<MapExtensionReturn*>(output);
returnValue->address = d->map(options->offset, options->size, options->flags);
- return (returnValue->address != 0);
+ return (returnValue->address != nullptr);
}
if (extension == UnMapExtension) {
const UnMapExtensionOption *options = (const UnMapExtensionOption*)option;
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 90ad0126d6..d4983c72af 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -153,7 +153,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
}
}
- fh = 0;
+ fh = nullptr;
}
closeFileHandle = true;
@@ -451,14 +451,14 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
if (type & Refresh)
d->metaData.clear();
- QAbstractFileEngine::FileFlags ret = 0;
+ QAbstractFileEngine::FileFlags ret = { };
if (type & FlagsMask)
ret |= LocalDiskFlag;
bool exists;
{
- QFileSystemMetaData::MetaDataFlags queryFlags = 0;
+ QFileSystemMetaData::MetaDataFlags queryFlags = { };
queryFlags |= QFileSystemMetaData::MetaDataFlags(uint(type))
& QFileSystemMetaData::Permissions;
@@ -590,9 +590,9 @@ bool QFSFileEngine::setPermissions(uint perms)
QSystemError error;
bool ok;
if (d->fd != -1)
- ok = QFileSystemEngine::setPermissions(d->fd, QFile::Permissions(perms), error, 0);
+ ok = QFileSystemEngine::setPermissions(d->fd, QFile::Permissions(perms), error);
else
- ok = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error, 0);
+ ok = QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), error);
if (!ok) {
setError(QFile::PermissionsError, error.toString());
return false;
@@ -651,13 +651,13 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
Q_Q(QFSFileEngine);
if (openMode == QIODevice::NotOpen) {
q->setError(QFile::PermissionsError, qt_error_string(int(EACCES)));
- return 0;
+ return nullptr;
}
if (offset < 0 || offset > maxFileOffset
|| size < 0 || quint64(size) > quint64(size_t(-1))) {
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
- return 0;
+ return nullptr;
}
// If we know the mapping will extend beyond EOF, fail early to avoid
@@ -685,14 +685,14 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
if (quint64(size + extra) > quint64((size_t)-1)) {
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
- return 0;
+ return nullptr;
}
size_t realSize = (size_t)size + extra;
QT_OFF_T realOffset = QT_OFF_T(offset);
realOffset &= ~(QT_OFF_T(pageSize - 1));
- void *mapAddress = QT_MMAP((void*)0, realSize,
+ void *mapAddress = QT_MMAP((void*)nullptr, realSize,
access, sharemode, nativeHandle(), realOffset);
if (MAP_FAILED != mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);
@@ -714,7 +714,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
q->setError(QFile::UnspecifiedError, qt_error_string(int(errno)));
break;
}
- return 0;
+ return nullptr;
}
bool QFSFileEnginePrivate::unmap(uchar *ptr)
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 74df0f71ef..e26508e631 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -169,7 +169,7 @@ QIODevicePrivate::QIODevicePrivate()
, baseReadLineDataCalled(false)
, accessMode(Unset)
#ifdef QT_NO_QOBJECT
- , q_ptr(0)
+ , q_ptr(nullptr)
#endif
{
}
diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp
index d9f7916dd4..b3421fca8f 100644
--- a/src/corelib/io/qipaddress.cpp
+++ b/src/corelib/io/qipaddress.cpp
@@ -67,7 +67,7 @@ static const QChar *checkedToAscii(Buffer &buffer, const QChar *begin, const QCh
*dst++ = *src++;
}
*dst = '\0';
- return 0;
+ return nullptr;
}
static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptLeadingZero);
@@ -175,7 +175,7 @@ const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end
memset(address, 0, sizeof address);
if (colonCount == 2 && end - begin == 2) // "::"
- return 0;
+ return nullptr;
// if there's a double colon ("::"), this is how many zeroes it means
int zeroWordsToFill;
@@ -236,7 +236,7 @@ const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end
address[13] = ip4 >> 16;
address[14] = ip4 >> 8;
address[15] = ip4;
- return 0;
+ return nullptr;
}
address[pos++] = x >> 8;
@@ -248,7 +248,7 @@ const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end
return begin + (endptr - buffer.data());
ptr = endptr + 1;
}
- return pos == 16 ? 0 : end;
+ return pos == 16 ? nullptr : end;
}
static inline QChar toHex(uchar c)
@@ -256,7 +256,7 @@ static inline QChar toHex(uchar c)
return QChar::fromLatin1(QtMiscUtils::toHexLower(c));
}
-void toString(QString &appendTo, IPv6Address address)
+void toString(QString &appendTo, const IPv6Address address)
{
// the longest IPv6 address possible is:
// "1111:2222:3333:4444:5555:6666:255.255.255.255"
diff --git a/src/corelib/io/qipaddress_p.h b/src/corelib/io/qipaddress_p.h
index d95cccb3bd..ea31e5883d 100644
--- a/src/corelib/io/qipaddress_p.h
+++ b/src/corelib/io/qipaddress_p.h
@@ -64,7 +64,7 @@ typedef quint8 IPv6Address[16];
Q_CORE_EXPORT bool parseIp4(IPv4Address &address, const QChar *begin, const QChar *end);
Q_CORE_EXPORT const QChar *parseIp6(IPv6Address &address, const QChar *begin, const QChar *end);
Q_CORE_EXPORT void toString(QString &appendTo, IPv4Address address);
-Q_CORE_EXPORT void toString(QString &appendTo, IPv6Address address);
+Q_CORE_EXPORT void toString(QString &appendTo, const IPv6Address address);
} // namespace
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 33253429a2..f6ff56c83c 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -214,8 +214,8 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
Note that \a category must be kept valid during the lifetime of this object.
*/
QLoggingCategory::QLoggingCategory(const char *category)
- : d(0),
- name(0)
+ : d(nullptr),
+ name(nullptr)
{
init(category, QtDebugMsg);
}
@@ -231,15 +231,15 @@ QLoggingCategory::QLoggingCategory(const char *category)
\since 5.4
*/
QLoggingCategory::QLoggingCategory(const char *category, QtMsgType enableForLevel)
- : d(0),
- name(0)
+ : d(nullptr),
+ name(nullptr)
{
init(category, enableForLevel);
}
void QLoggingCategory::init(const char *category, QtMsgType severityLevel)
{
- enabled.store(0x01010101); // enabledDebug = enabledWarning = enabledCritical = true;
+ enabled.storeRelaxed(0x01010101); // enabledDebug = enabledWarning = enabledCritical = true;
if (category)
name = category;
@@ -342,10 +342,10 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
{
switch (type) {
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
- case QtDebugMsg: bools.enabledDebug.store(enable); break;
- case QtInfoMsg: bools.enabledInfo.store(enable); break;
- case QtWarningMsg: bools.enabledWarning.store(enable); break;
- case QtCriticalMsg: bools.enabledCritical.store(enable); break;
+ case QtDebugMsg: bools.enabledDebug.storeRelaxed(enable); break;
+ case QtInfoMsg: bools.enabledInfo.storeRelaxed(enable); break;
+ case QtWarningMsg: bools.enabledWarning.storeRelaxed(enable); break;
+ case QtCriticalMsg: bools.enabledCritical.storeRelaxed(enable); break;
#else
case QtDebugMsg: setBoolLane(&enabled, enable, DebugShift); break;
case QtInfoMsg: setBoolLane(&enabled, enable, InfoShift); break;
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 5825095729..1c3e10b493 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -58,15 +58,15 @@ public:
void setEnabled(QtMsgType type, bool enable);
#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
- bool isDebugEnabled() const { return bools.enabledDebug.load(); }
- bool isInfoEnabled() const { return bools.enabledInfo.load(); }
- bool isWarningEnabled() const { return bools.enabledWarning.load(); }
- bool isCriticalEnabled() const { return bools.enabledCritical.load(); }
+ bool isDebugEnabled() const { return bools.enabledDebug.loadRelaxed(); }
+ bool isInfoEnabled() const { return bools.enabledInfo.loadRelaxed(); }
+ bool isWarningEnabled() const { return bools.enabledWarning.loadRelaxed(); }
+ bool isCriticalEnabled() const { return bools.enabledCritical.loadRelaxed(); }
#else
- bool isDebugEnabled() const { return enabled.load() >> DebugShift & 1; }
- bool isInfoEnabled() const { return enabled.load() >> InfoShift & 1; }
- bool isWarningEnabled() const { return enabled.load() >> WarningShift & 1; }
- bool isCriticalEnabled() const { return enabled.load() >> CriticalShift & 1; }
+ bool isDebugEnabled() const { return enabled.loadRelaxed() >> DebugShift & 1; }
+ bool isInfoEnabled() const { return enabled.loadRelaxed() >> InfoShift & 1; }
+ bool isWarningEnabled() const { return enabled.loadRelaxed() >> WarningShift & 1; }
+ bool isCriticalEnabled() const { return enabled.loadRelaxed() >> CriticalShift & 1; }
#endif
const char *categoryName() const { return name; }
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 9792d956cc..7849dfd14c 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -165,7 +165,7 @@ void QLoggingRule::parse(const QStringRef &pattern)
p = QStringRef(p.string(), p.position() + 1, p.length() - 1);
}
if (p.contains(QLatin1Char('*'))) // '*' only supported at start/end
- flags = 0;
+ flags = PatternFlags();
}
category = p.toString();
@@ -415,7 +415,7 @@ QLoggingRegistry::installFilter(QLoggingCategory::CategoryFilter filter)
{
QMutexLocker locker(&registryMutex);
- if (filter == 0)
+ if (!filter)
filter = defaultCategoryFilter;
QLoggingCategory::CategoryFilter old = categoryFilter;
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 00acb81158..d02e87837c 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -220,7 +220,7 @@ public:
template<> Q_INLINE_TEMPLATE void QSharedDataPointer<QProcessEnvironmentPrivate>::detach()
{
- if (d && d->ref.load() == 1)
+ if (d && d->ref.loadRelaxed() == 1)
return;
QProcessEnvironmentPrivate *x = (d ? new QProcessEnvironmentPrivate(*d)
: new QProcessEnvironmentPrivate);
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 3a29a0d842..1d5b76a8a4 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -517,7 +517,7 @@ void QProcessPrivate::startProcess()
if (stderrChannel.pipe[0] != -1)
::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK);
- if (threadData->eventDispatcher) {
+ if (threadData->eventDispatcher.loadAcquire()) {
deathNotifier = new QSocketNotifier(forkfd, QSocketNotifier::Read, q);
QObject::connect(deathNotifier, SIGNAL(activated(int)),
q, SLOT(_q_processDied()));
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index e7d739b4dc..fcc5b69179 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -147,7 +147,7 @@ private:
public:
mutable QAtomicInt ref;
- inline QResourceRoot(): tree(0), names(0), payloads(0), version(0) {}
+ inline QResourceRoot(): tree(nullptr), names(nullptr), payloads(nullptr), version(0) {}
inline QResourceRoot(int version, const uchar *t, const uchar *n, const uchar *d) { setSource(version, t, n, d); }
virtual ~QResourceRoot() { }
int findNode(const QString &path, const QLocale &locale=QLocale()) const;
@@ -165,7 +165,7 @@ public:
quint64 lastModified(int node) const;
QStringList children(int node) const;
virtual QString mappingRoot() const { return QString(); }
- bool mappingRootSubdir(const QString &path, QString *match=0) const;
+ bool mappingRootSubdir(const QString &path, QString *match = nullptr) const;
inline bool operator==(const QResourceRoot &other) const
{ return tree == other.tree && names == other.names && payloads == other.payloads && version == other.version; }
inline bool operator!=(const QResourceRoot &other) const
@@ -197,13 +197,13 @@ Q_DECLARE_TYPEINFO(QResourceRoot, Q_MOVABLE_TYPE);
typedef QList<QResourceRoot*> ResourceList;
struct QResourceGlobalData
{
- QMutex resourceMutex{QMutex::Recursive};
+ QRecursiveMutex resourceMutex;
ResourceList resourceList;
QStringList resourceSearchPaths;
};
Q_GLOBAL_STATIC(QResourceGlobalData, resourceGlobalData)
-static inline QMutex *resourceMutex()
+static inline QRecursiveMutex *resourceMutex()
{ return &resourceGlobalData->resourceMutex; }
static inline ResourceList *resourceList()
@@ -320,7 +320,7 @@ QResourcePrivate::clear()
{
absoluteFilePath.clear();
compressionAlgo = QResource::NoCompression;
- data = 0;
+ data = nullptr;
size = 0;
children.clear();
lastModified = 0;
@@ -864,7 +864,7 @@ const uchar *QResourceRoot::data(int node, qint64 *size) const
{
if(node == -1) {
*size = 0;
- return 0;
+ return nullptr;
}
int offset = findOffset(node) + 4; //jump past name
@@ -881,7 +881,7 @@ const uchar *QResourceRoot::data(int node, qint64 *size) const
return ret;
}
*size = 0;
- return 0;
+ return nullptr;
}
quint64 QResourceRoot::lastModified(int node) const
@@ -991,7 +991,7 @@ class QDynamicBufferResourceRoot: public QResourceRoot
const uchar *buffer;
public:
- inline QDynamicBufferResourceRoot(const QString &_root) : root(_root), buffer(0) { }
+ inline QDynamicBufferResourceRoot(const QString &_root) : root(_root), buffer(nullptr) { }
inline ~QDynamicBufferResourceRoot() { }
inline const uchar *mappingBuffer() const { return buffer; }
QString mappingRoot() const override { return root; }
@@ -1063,12 +1063,14 @@ class QDynamicFileResourceRoot: public QDynamicBufferResourceRoot
qsizetype unmapLength;
public:
- inline QDynamicFileResourceRoot(const QString &_root) : QDynamicBufferResourceRoot(_root), unmapPointer(0), unmapLength(0) { }
+ QDynamicFileResourceRoot(const QString &_root)
+ : QDynamicBufferResourceRoot(_root), unmapPointer(nullptr), unmapLength(0)
+ { }
~QDynamicFileResourceRoot() {
#if defined(QT_USE_MMAP)
if (unmapPointer) {
munmap((char*)unmapPointer, unmapLength);
- unmapPointer = 0;
+ unmapPointer = nullptr;
unmapLength = 0;
} else
#endif
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index bde5133cb3..915d0a0a00 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -151,7 +151,7 @@ QSaveFile::~QSaveFile()
if (d->fileEngine) {
d->fileEngine->remove();
delete d->fileEngine;
- d->fileEngine = 0;
+ d->fileEngine = nullptr;
}
}
@@ -252,7 +252,7 @@ bool QSaveFile::open(OpenMode mode)
return true;
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
delete d->fileEngine;
- d->fileEngine = 0;
+ d->fileEngine = nullptr;
} else {
QString msg =
QSaveFile::tr("QSaveFile cannot open '%1' without direct write fallback "
@@ -285,7 +285,7 @@ bool QSaveFile::open(OpenMode mode)
err = QFileDevice::OpenError;
d->setError(err, d->fileEngine->errorString());
delete d->fileEngine;
- d->fileEngine = 0;
+ d->fileEngine = nullptr;
return false;
}
@@ -339,7 +339,7 @@ bool QSaveFile::commit()
d->fileEngine->remove();
d->writeError = QFileDevice::NoError;
delete d->fileEngine;
- d->fileEngine = 0;
+ d->fileEngine = nullptr;
return false;
}
// atomically replace old file with new file
@@ -349,12 +349,12 @@ bool QSaveFile::commit()
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
d->fileEngine->remove();
delete d->fileEngine;
- d->fileEngine = 0;
+ d->fileEngine = nullptr;
return false;
}
}
delete d->fileEngine;
- d->fileEngine = 0;
+ d->fileEngine = nullptr;
return true;
}
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 9234a23f3a..accde01f16 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -2048,8 +2048,8 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
QPixmap, which are part of Qt GUI. In other words, there is no
\c toColor(), \c toImage(), or \c toPixmap() functions in QVariant.
- Instead, you can use the QVariant::value() or the qVariantValue()
- template function. For example:
+ Instead, you can use the QVariant::value() template function.
+ For example:
\snippet code/src_corelib_io_qsettings.cpp 0
diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp
index 83108e4387..1f4e0de1e7 100644
--- a/src/corelib/io/qstandardpaths_android.cpp
+++ b/src/corelib/io/qstandardpaths_android.cpp
@@ -136,7 +136,7 @@ static QString getExternalStoragePublicDirectory(const char *directoryField)
*/
static QString getExternalFilesDir(const char *directoryField = 0)
{
- QString &path = (*androidDirCache)[QString(QLatin1String("APPNAME_%1")).arg(QLatin1String(directoryField))];
+ QString &path = (*androidDirCache)[QLatin1String("APPNAME_%1").arg(QLatin1String(directoryField))];
if (!path.isEmpty())
return path;
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index d25a607d9f..4669c20711 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -220,7 +220,7 @@ static bool shouldIncludeFs(const QStorageIterator &it)
return false;
}
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
if (it.fileSystemType() == "rootfs")
return false;
#endif
@@ -846,7 +846,10 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
const QString mountDir = it.rootPath();
QStorageInfo info(mountDir);
- if (info.bytesTotal() == 0)
+ info.d->device = it.device();
+ info.d->fileSystemType = it.fileSystemType();
+ info.d->subvolume = it.subvolume();
+ if (info.bytesTotal() == 0 && info != root())
continue;
volumes.append(info);
}
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index ced08a9a87..c89ad06a1f 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -327,7 +327,7 @@ bool QTemporaryFileEngine::isReallyOpen() const
{
Q_D(const QFSFileEngine);
- if (!((0 == d->fh) && (-1 == d->fd)
+ if (!((nullptr == d->fh) && (-1 == d->fd)
#if defined Q_OS_WIN
&& (INVALID_HANDLE_VALUE == d->fileHandle)
#endif
@@ -902,7 +902,7 @@ QTemporaryFile *QTemporaryFile::createNativeFile(QFile &file)
{
if (QAbstractFileEngine *engine = file.d_func()->engine()) {
if(engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)
- return 0; //native already
+ return nullptr; // native already
//cache
bool wasOpen = file.isOpen();
qint64 old_off = 0;
@@ -934,7 +934,7 @@ QTemporaryFile *QTemporaryFile::createNativeFile(QFile &file)
//done
return ret;
}
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h
index 0fec88d3cd..6bcff936b4 100644
--- a/src/corelib/io/qtemporaryfile_p.h
+++ b/src/corelib/io/qtemporaryfile_p.h
@@ -145,10 +145,10 @@ public:
bool isUnnamedFile() const override final;
const QString &templateName;
- quint32 fileMode;
+ quint32 fileMode = 0;
int flags = 0;
- bool filePathIsTemplate;
- bool filePathWasTemplate;
+ bool filePathIsTemplate = true;
+ bool filePathWasTemplate = true;
bool unnamedFile = false;
};
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 681a0c7ef2..d9ebc6c750 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -421,6 +421,7 @@
#include "private/qipaddress_p.h"
#include "qurlquery.h"
#include "private/qdir_p.h"
+#include <private/qmemory_p.h>
QT_BEGIN_NAMESPACE
@@ -520,10 +521,10 @@ public:
bool isEmpty() const
{ return sectionIsPresent == 0 && port == -1 && path.isEmpty(); }
- Error *cloneError() const;
+ std::unique_ptr<Error> cloneError() const;
void clearError();
void setError(ErrorCode errorCode, const QString &source, int supplement = -1);
- ErrorCode validityError(QString *source = 0, int *position = 0) const;
+ ErrorCode validityError(QString *source = nullptr, int *position = nullptr) const;
bool validateComponent(Section section, const QString &input, int begin, int end);
bool validateComponent(Section section, const QString &input)
{ return validateComponent(section, input, 0, uint(input.length())); }
@@ -576,7 +577,7 @@ public:
QString query;
QString fragment;
- Error *error;
+ std::unique_ptr<Error> error;
// not used for:
// - Port (port == -1 means absence)
@@ -591,7 +592,6 @@ public:
inline QUrlPrivate::QUrlPrivate()
: ref(1), port(-1),
- error(0),
sectionIsPresent(0),
flags(0)
{
@@ -613,19 +613,16 @@ inline QUrlPrivate::QUrlPrivate(const QUrlPrivate &copy)
}
inline QUrlPrivate::~QUrlPrivate()
-{
- delete error;
-}
+ = default;
-inline QUrlPrivate::Error *QUrlPrivate::cloneError() const
+std::unique_ptr<QUrlPrivate::Error> QUrlPrivate::cloneError() const
{
- return error ? new Error(*error) : 0;
+ return error ? qt_make_unique<Error>(*error) : nullptr;
}
inline void QUrlPrivate::clearError()
{
- delete error;
- error = 0;
+ error.reset();
}
inline void QUrlPrivate::setError(ErrorCode errorCode, const QString &source, int supplement)
@@ -634,7 +631,7 @@ inline void QUrlPrivate::setError(ErrorCode errorCode, const QString &source, in
// don't overwrite an error set in a previous section during parsing
return;
}
- error = new Error;
+ error = qt_make_unique<Error>();
error->code = errorCode;
error->source = source;
error->position = supplement;
@@ -826,7 +823,7 @@ recodeFromUser(const QString &input, const ushort *actions, int from, int to)
QString output;
const QChar *begin = input.constData() + from;
const QChar *end = input.constData() + to;
- if (qt_urlRecode(output, begin, end, 0, actions))
+ if (qt_urlRecode(output, begin, end, nullptr, actions))
return output;
return input.mid(from, to - from);
@@ -954,7 +951,7 @@ inline void QUrlPrivate::appendFragment(QString &appendTo, QUrl::FormattingOptio
{
appendToUser(appendTo, fragment, options,
options & QUrl::EncodeDelimiters ? fragmentInUrl :
- appendingTo == FullUrl ? 0 : fragmentInIsolation);
+ appendingTo == FullUrl ? nullptr : fragmentInIsolation);
}
inline void QUrlPrivate::appendQuery(QString &appendTo, QUrl::FormattingOptions options, Section appendingTo) const
@@ -1179,7 +1176,7 @@ inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions o
if (host.at(0).unicode() == '[') {
// IPv6 addresses might contain a zone-id which needs to be recoded
if (options != 0)
- if (qt_urlRecode(appendTo, host.constBegin(), host.constEnd(), options, 0))
+ if (qt_urlRecode(appendTo, host.constBegin(), host.constEnd(), options, nullptr))
return;
appendTo += host;
} else {
@@ -1221,7 +1218,7 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
--end;
QString decoded;
- if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, QUrl::FullyDecoded, 0)) {
+ if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, QUrl::FullyDecoded, nullptr)) {
begin = decoded.constBegin();
end = decoded.constEnd();
}
@@ -1233,13 +1230,13 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
host += *begin;
else if (begin->unicode() >= '0' && begin->unicode() <= '9')
host += *begin;
- else if (begin->unicode() < 0x80 && strchr(acceptable, begin->unicode()) != 0)
+ else if (begin->unicode() < 0x80 && strchr(acceptable, begin->unicode()) != nullptr)
host += *begin;
else
return decoded.isEmpty() ? begin : &origBegin[2];
}
host += QLatin1Char(']');
- return 0;
+ return nullptr;
}
return &origBegin[2];
}
@@ -1286,7 +1283,7 @@ static const QChar *parseIp6(QString &host, const QChar *begin, const QChar *end
host += zoneId;
}
host += QLatin1Char(']');
- return 0;
+ return nullptr;
}
inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl::ParsingMode mode)
@@ -1352,7 +1349,7 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl:
// check for percent-encoding first
QString s;
- if (mode == QUrl::TolerantMode && qt_urlRecode(s, begin, end, 0, 0)) {
+ if (mode == QUrl::TolerantMode && qt_urlRecode(s, begin, end, { }, nullptr)) {
// something was decoded
// anything encoded left?
int pos = s.indexOf(QChar(0x25)); // '%'
@@ -1837,7 +1834,7 @@ inline void QUrlPrivate::validate() const
\sa setUrl(), fromEncoded(), TolerantMode
*/
-QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(0)
+QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(nullptr)
{
setUrl(url, parsingMode);
}
@@ -1845,7 +1842,7 @@ QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(0)
/*!
Constructs an empty QUrl object.
*/
-QUrl::QUrl() : d(0)
+QUrl::QUrl() : d(nullptr)
{
}
@@ -1879,7 +1876,7 @@ QUrl::~QUrl()
bool QUrl::isValid() const
{
if (isEmpty()) {
- // also catches d == 0
+ // also catches d == nullptr
return false;
}
return d->validityError() == QUrlPrivate::NoError;
@@ -1907,7 +1904,7 @@ void QUrl::clear()
{
if (d && !d->ref.deref())
delete d;
- d = 0;
+ d = nullptr;
}
/*!
@@ -3805,7 +3802,7 @@ void QUrl::detach()
*/
bool QUrl::isDetached() const
{
- return !d || d->ref.load() == 1;
+ return !d || d->ref.loadRelaxed() == 1;
}
@@ -3994,21 +3991,21 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err
return QString();
case QUrlPrivate::InvalidSchemeError: {
- QString msg = QStringLiteral("Invalid scheme (character '%1' not permitted)");
+ auto msg = QLatin1String("Invalid scheme (character '%1' not permitted)");
return msg.arg(c);
}
case QUrlPrivate::InvalidUserNameError:
- return QString(QStringLiteral("Invalid user name (character '%1' not permitted)"))
+ return QLatin1String("Invalid user name (character '%1' not permitted)")
.arg(c);
case QUrlPrivate::InvalidPasswordError:
- return QString(QStringLiteral("Invalid password (character '%1' not permitted)"))
+ return QLatin1String("Invalid password (character '%1' not permitted)")
.arg(c);
case QUrlPrivate::InvalidRegNameError:
if (errorPosition != -1)
- return QString(QStringLiteral("Invalid hostname (character '%1' not permitted)"))
+ return QLatin1String("Invalid hostname (character '%1' not permitted)")
.arg(c);
else
return QStringLiteral("Invalid hostname (contains invalid characters)");
@@ -4017,9 +4014,9 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err
case QUrlPrivate::InvalidIPv6AddressError:
return QStringLiteral("Invalid IPv6 address");
case QUrlPrivate::InvalidCharacterInIPv6Error:
- return QStringLiteral("Invalid IPv6 address (character '%1' not permitted)").arg(c);
+ return QLatin1String("Invalid IPv6 address (character '%1' not permitted)").arg(c);
case QUrlPrivate::InvalidIPvFutureError:
- return QStringLiteral("Invalid IPvFuture address (character '%1' not permitted)").arg(c);
+ return QLatin1String("Invalid IPvFuture address (character '%1' not permitted)").arg(c);
case QUrlPrivate::HostMissingEndBracket:
return QStringLiteral("Expected ']' to match '[' in hostname");
@@ -4029,15 +4026,15 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err
return QStringLiteral("Port field was empty");
case QUrlPrivate::InvalidPathError:
- return QString(QStringLiteral("Invalid path (character '%1' not permitted)"))
+ return QLatin1String("Invalid path (character '%1' not permitted)")
.arg(c);
case QUrlPrivate::InvalidQueryError:
- return QString(QStringLiteral("Invalid query (character '%1' not permitted)"))
+ return QLatin1String("Invalid query (character '%1' not permitted)")
.arg(c);
case QUrlPrivate::InvalidFragmentError:
- return QString(QStringLiteral("Invalid fragment (character '%1' not permitted)"))
+ return QLatin1String("Invalid fragment (character '%1' not permitted)")
.arg(c);
case QUrlPrivate::AuthorityPresentAndPathIsRelative:
@@ -4187,7 +4184,7 @@ static QUrl adjustFtpPath(QUrl url)
static bool isIp6(const QString &text)
{
QIPAddressUtils::IPv6Address address;
- return !text.isEmpty() && QIPAddressUtils::parseIp6(address, text.begin(), text.end()) == 0;
+ return !text.isEmpty() && QIPAddressUtils::parseIp6(address, text.begin(), text.end()) == nullptr;
}
/*!
diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp
index 2305e66407..2f89d22660 100644
--- a/src/corelib/io/qurlidna.cpp
+++ b/src/corelib/io/qurlidna.cpp
@@ -1444,7 +1444,7 @@ static void mapToLowerCase(QString *str, int from)
{
int N = sizeof(NameprepCaseFolding) / sizeof(NameprepCaseFolding[0]);
- ushort *d = 0;
+ ushort *d = nullptr;
for (int i = from; i < str->size(); ++i) {
uint uc = str->at(i).unicode();
if (uc < 0x80) {
@@ -1474,7 +1474,7 @@ static void mapToLowerCase(QString *str, int from)
else
str->replace(--i, 2, reinterpret_cast<const QChar *>(&entry->mapping[0]), l);
i += l - 1;
- d = 0;
+ d = nullptr;
} else {
if (!d)
d = reinterpret_cast<ushort *>(str->data());
@@ -2404,7 +2404,7 @@ static const char * const idn_whitelist[] = {
};
static const size_t idn_whitelist_size = sizeof idn_whitelist / sizeof *idn_whitelist;
-static QStringList *user_idn_whitelist = 0;
+static QStringList *user_idn_whitelist = nullptr;
static bool lessThan(const QChar *a, int l, const char *c)
{
diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp
index d76107abfd..36a2880bf1 100644
--- a/src/corelib/io/qurlquery.cpp
+++ b/src/corelib/io/qurlquery.cpp
@@ -189,7 +189,7 @@ public:
template<> void QSharedDataPointer<QUrlQueryPrivate>::detach()
{
- if (d && d->ref.load() == 1)
+ if (d && d->ref.loadRelaxed() == 1)
return;
QUrlQueryPrivate *x = (d ? new QUrlQueryPrivate(*d)
: new QUrlQueryPrivate);
@@ -262,7 +262,7 @@ inline QString QUrlQueryPrivate::recodeToUser(const QString &input, QUrl::Compon
if (!(encoding & QUrl::EncodeDelimiters)) {
QString output;
if (qt_urlRecode(output, input.constData(), input.constData() + input.length(),
- encoding, 0))
+ encoding, nullptr))
return output;
return input;
}
@@ -290,7 +290,7 @@ void QUrlQueryPrivate::setQuery(const QString &query)
const QChar *const end = pos + query.size();
while (pos != end) {
const QChar *begin = pos;
- const QChar *delimiter = 0;
+ const QChar *delimiter = nullptr;
while (pos != end) {
// scan for the component parts of this pair
if (!delimiter && pos->unicode() == valueDelimiter)
@@ -345,7 +345,7 @@ QSharedDataPointer<QUrlQueryPrivate>::clone()
\sa setQuery(), addQueryItem()
*/
QUrlQuery::QUrlQuery()
- : d(0)
+ : d(nullptr)
{
}
@@ -356,7 +356,7 @@ QUrlQuery::QUrlQuery()
set the query with setQuery().
*/
QUrlQuery::QUrlQuery(const QString &queryString)
- : d(queryString.isEmpty() ? 0 : new QUrlQueryPrivate(queryString))
+ : d(queryString.isEmpty() ? nullptr : new QUrlQueryPrivate(queryString))
{
}
@@ -369,7 +369,7 @@ QUrlQuery::QUrlQuery(const QString &queryString)
\sa QUrl::query()
*/
QUrlQuery::QUrlQuery(const QUrl &url)
- : d(0)
+ : d(nullptr)
{
// use internals to avoid unnecessary recoding
// ### FIXME: actually do it
@@ -462,7 +462,7 @@ bool QUrlQuery::isEmpty() const
*/
bool QUrlQuery::isDetached() const
{
- return d && d->ref.load() == 1;
+ return d && d->ref.loadRelaxed() == 1;
}
/*!
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index f23480c755..35ede8d078 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -377,7 +377,7 @@ static int recode(QString &result, const ushort *begin, const ushort *end, QUrl:
{
const int origSize = result.size();
const ushort *input = begin;
- ushort *output = 0;
+ ushort *output = nullptr;
EncodingAction action = EncodeCharacter;
for ( ; input != end; ++input) {
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index ad857612b6..2eacb3cc94 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -77,7 +77,7 @@ QPersistentModelIndexData *QPersistentModelIndexData::create(const QModelIndex &
void QPersistentModelIndexData::destroy(QPersistentModelIndexData *data)
{
Q_ASSERT(data);
- Q_ASSERT(data->ref.load() == 0);
+ Q_ASSERT(data->ref.loadRelaxed() == 0);
QAbstractItemModel *model = const_cast<QAbstractItemModel *>(data->index.model());
// a valid persistent model index with a null model pointer can only happen if the model was destroyed
if (model) {
diff --git a/src/corelib/itemmodels/qtransposeproxymodel.cpp b/src/corelib/itemmodels/qtransposeproxymodel.cpp
index d4f379bc64..4853f90632 100644
--- a/src/corelib/itemmodels/qtransposeproxymodel.cpp
+++ b/src/corelib/itemmodels/qtransposeproxymodel.cpp
@@ -445,3 +445,5 @@ void QTransposeProxyModel::sort(int column, Qt::SortOrder order)
}
QT_END_NAMESPACE
+
+#include "moc_qtransposeproxymodel.cpp"
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index 186c2e743b..7215b3f2bd 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -170,7 +170,7 @@ QAbstractEventDispatcher::~QAbstractEventDispatcher()
QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
{
QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current();
- return data->eventDispatcher.load();
+ return data->eventDispatcher.loadRelaxed();
}
/*!
diff --git a/src/corelib/kernel/qbasictimer.cpp b/src/corelib/kernel/qbasictimer.cpp
index b16833b34c..ea8f8e2c77 100644
--- a/src/corelib/kernel/qbasictimer.cpp
+++ b/src/corelib/kernel/qbasictimer.cpp
@@ -105,6 +105,7 @@ QT_BEGIN_NAMESPACE
\sa stop(), isActive(), swap()
*/
+#if QT_DEPRECATED_SINCE(5, 14)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
\internal
@@ -125,6 +126,7 @@ QBasicTimer &QBasicTimer::operator=(const QBasicTimer &other)
return *this;
}
#endif
+#endif
/*!
\fn QBasicTimer::~QBasicTimer()
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 6b51eb65d9..15b69acbd4 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -514,5 +514,36 @@ Q_CONSTRUCTOR_FUNCTION(qt_apple_check_os_version);
// -------------------------------------------------------------------------
+void QMacKeyValueObserver::addObserver()
+{
+ [object addObserver:observer forKeyPath:keyPath
+ options:NSKeyValueObservingOptionNew context:callback.get()];
+}
+
+void QMacKeyValueObserver::removeObserver() {
+ if (object)
+ [object removeObserver:observer forKeyPath:keyPath context:callback.get()];
+ object = nil;
+}
+
+KeyValueObserver *QMacKeyValueObserver::observer = [[KeyValueObserver alloc] init];
+
+QT_END_NAMESPACE
+@implementation KeyValueObserver
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
+ change:(NSDictionary<NSKeyValueChangeKey, id> *)change context:(void *)context
+{
+ Q_UNUSED(keyPath);
+ Q_UNUSED(object);
+ Q_UNUSED(change);
+
+ (*reinterpret_cast<QMacKeyValueObserver::Callback*>(context))();
+}
+@end
+QT_BEGIN_NAMESPACE
+
+// -------------------------------------------------------------------------
+
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 920105ee9e..0e1a5fe345 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -67,6 +67,7 @@
#ifdef __OBJC__
#include <Foundation/Foundation.h>
+#include <functional>
#endif
#include "qstring.h"
@@ -295,13 +296,13 @@ QT_MAC_WEAK_IMPORT(_os_activity_current);
// -------------------------------------------------------------------------
#if defined( __OBJC__)
-class QMacScopedObserver
+class QMacNotificationObserver
{
public:
- QMacScopedObserver() {}
+ QMacNotificationObserver() {}
template<typename Functor>
- QMacScopedObserver(id object, NSNotificationName name, Functor callback) {
+ QMacNotificationObserver(id object, NSNotificationName name, Functor callback) {
observer = [[NSNotificationCenter defaultCenter] addObserverForName:name
object:object queue:nil usingBlock:^(NSNotification *) {
callback();
@@ -309,13 +310,13 @@ public:
];
}
- QMacScopedObserver(const QMacScopedObserver& other) = delete;
- QMacScopedObserver(QMacScopedObserver&& other) : observer(other.observer) {
+ QMacNotificationObserver(const QMacNotificationObserver& other) = delete;
+ QMacNotificationObserver(QMacNotificationObserver&& other) : observer(other.observer) {
other.observer = nil;
}
- QMacScopedObserver &operator=(const QMacScopedObserver& other) = delete;
- QMacScopedObserver &operator=(QMacScopedObserver&& other) {
+ QMacNotificationObserver &operator=(const QMacNotificationObserver& other) = delete;
+ QMacNotificationObserver &operator=(QMacNotificationObserver&& other) {
if (this != &other) {
remove();
observer = other.observer;
@@ -329,11 +330,65 @@ public:
[[NSNotificationCenter defaultCenter] removeObserver:observer];
observer = nil;
}
- ~QMacScopedObserver() { remove(); }
+ ~QMacNotificationObserver() { remove(); }
private:
id observer = nil;
};
+
+QT_END_NAMESPACE
+@interface QT_MANGLE_NAMESPACE(KeyValueObserver) : NSObject
+@end
+QT_NAMESPACE_ALIAS_OBJC_CLASS(KeyValueObserver);
+QT_BEGIN_NAMESPACE
+
+class Q_CORE_EXPORT QMacKeyValueObserver
+{
+public:
+ using Callback = std::function<void()>;
+
+ QMacKeyValueObserver() {}
+
+ // Note: QMacKeyValueObserver must not outlive the object observed!
+ QMacKeyValueObserver(id object, NSString *keyPath, Callback callback)
+ : object(object), keyPath(keyPath), callback(new Callback(callback)) { addObserver(); }
+
+ QMacKeyValueObserver(const QMacKeyValueObserver &other)
+ : QMacKeyValueObserver(other.object, other.keyPath, *other.callback.get()) {}
+
+ QMacKeyValueObserver(QMacKeyValueObserver &&other) { swap(other, *this); }
+
+ ~QMacKeyValueObserver() { removeObserver(); }
+
+ QMacKeyValueObserver &operator=(const QMacKeyValueObserver &other) {
+ QMacKeyValueObserver tmp(other);
+ swap(tmp, *this);
+ return *this;
+ }
+
+ QMacKeyValueObserver &operator=(QMacKeyValueObserver &&other) {
+ QMacKeyValueObserver tmp(std::move(other));
+ swap(tmp, *this);
+ return *this;
+ }
+
+ void removeObserver();
+
+private:
+ void swap(QMacKeyValueObserver &first, QMacKeyValueObserver &second) {
+ std::swap(first.object, second.object);
+ std::swap(first.keyPath, second.keyPath);
+ std::swap(first.callback, second.callback);
+ }
+
+ void addObserver();
+
+ id object = nil;
+ NSString *keyPath = nullptr;
+ std::unique_ptr<Callback> callback;
+
+ static KeyValueObserver *observer;
+};
#endif
// -------------------------------------------------------------------------
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 7f58813535..6ec7d28318 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -52,8 +52,8 @@
// We mean it.
//
-#include <QtCore/private/qglobal_p.h>
#include "qplatformdefs.h"
+#include <QtCore/private/qglobal_p.h>
#include "qatomic.h"
#include "qbytearray.h"
@@ -164,7 +164,7 @@ inline void qt_ignore_sigpipe()
{
// Set to ignore SIGPIPE once only.
static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
- if (!atom.load()) {
+ if (!atom.loadRelaxed()) {
// More than one thread could turn off SIGPIPE at the same time
// But that's acceptable because they all would be doing the same
// action
@@ -172,7 +172,7 @@ inline void qt_ignore_sigpipe()
memset(&noaction, 0, sizeof(noaction));
noaction.sa_handler = SIG_IGN;
::sigaction(SIGPIPE, &noaction, nullptr);
- atom.store(1);
+ atom.storeRelaxed(1);
}
}
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 865e16a3f0..2feeae5394 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -120,6 +120,7 @@
#ifdef Q_OS_WASM
#include <emscripten.h>
+#include <emscripten/val.h>
#endif
#ifdef QT_BOOTSTRAPPED
@@ -216,22 +217,24 @@ QString QCoreApplicationPrivate::appVersion() const
}
#endif
-QString *QCoreApplicationPrivate::cachedApplicationFilePath = 0;
+QString *QCoreApplicationPrivate::cachedApplicationFilePath = nullptr;
bool QCoreApplicationPrivate::checkInstance(const char *function)
{
- bool b = (QCoreApplication::self != 0);
+ bool b = (QCoreApplication::self != nullptr);
if (!b)
qWarning("QApplication::%s: Please instantiate the QApplication object first", function);
return b;
}
+#if QT_CONFIG(commandlineparser)
void QCoreApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options)
{
options->append(QCommandLineOption(QStringLiteral("qmljsdebugger"),
QStringLiteral("Activates the QML/JS debugger with a specified port. The value must be of format port:1234[,block]. \"block\" makes the application wait for a connection."),
QStringLiteral("value")));
}
+#endif
void QCoreApplicationPrivate::processCommandLineArguments()
{
@@ -257,7 +260,7 @@ void QCoreApplicationPrivate::processCommandLineArguments()
}
if (j < argc) {
- argv[j] = 0;
+ argv[j] = nullptr;
argc = j;
}
}
@@ -367,11 +370,11 @@ Q_CORE_EXPORT uint qGlobalPostedEventsCount()
return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
}
-QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;
+QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = nullptr;
#endif // QT_NO_QOBJECT
-QCoreApplication *QCoreApplication::self = 0;
+QCoreApplication *QCoreApplication::self = nullptr;
uint QCoreApplicationPrivate::attribs =
(1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) |
(1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
@@ -384,8 +387,8 @@ struct QCoreApplicationData {
~QCoreApplicationData() {
#ifndef QT_NO_QOBJECT
// cleanup the QAdoptedThread created for the main() thread
- if (QCoreApplicationPrivate::theMainThread) {
- QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread);
+ if (auto *t = QCoreApplicationPrivate::theMainThread.loadAcquire()) {
+ QThreadData *data = QThreadData::get2(t);
data->deref(); // deletes the data and the adopted thread
}
#endif
@@ -455,12 +458,12 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
, aboutToQuitEmitted(false)
, threadData_clean(false)
#else
- , q_ptr(0)
+ , q_ptr(nullptr)
#endif
{
app_compile_version = flags & 0xffffff;
static const char *const empty = "";
- if (argc == 0 || argv == 0) {
+ if (argc == 0 || argv == nullptr) {
argc = 0;
argv = const_cast<char **>(&empty);
}
@@ -485,7 +488,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
#endif
QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread!
- if (cur != theMainThread)
+ if (cur != theMainThread.loadAcquire())
qWarning("WARNING: QApplication was not created in the main() thread.");
#endif
}
@@ -551,8 +554,8 @@ void QCoreApplicationPrivate::eventDispatcherReady()
QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(0);
QThread *QCoreApplicationPrivate::mainThread()
{
- Q_ASSERT(theMainThread.load() != 0);
- return theMainThread.load();
+ Q_ASSERT(theMainThread.loadRelaxed() != 0);
+ return theMainThread.loadRelaxed();
}
bool QCoreApplicationPrivate::threadRequiresCoreApplication()
@@ -799,6 +802,10 @@ void QCoreApplicationPrivate::init()
Module.print(err);
});
);
+
+#if QT_CONFIG(thread)
+ QThreadPrivate::idealThreadCount = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>();
+#endif
#endif
// Store app name/version (so they're still available after QCoreApplication is destroyed)
@@ -849,7 +856,7 @@ void QCoreApplicationPrivate::init()
#ifndef QT_NO_QOBJECT
// use the event dispatcher created by the app programmer (if any)
Q_ASSERT(!eventDispatcher);
- eventDispatcher = threadData->eventDispatcher.load();
+ eventDispatcher = threadData->eventDispatcher.loadRelaxed();
// otherwise we create one
if (!eventDispatcher)
@@ -857,7 +864,7 @@ void QCoreApplicationPrivate::init()
Q_ASSERT(eventDispatcher);
if (!eventDispatcher->parent()) {
- eventDispatcher->moveToThread(threadData->thread);
+ eventDispatcher->moveToThread(threadData->thread.loadAcquire());
eventDispatcher->setParent(q);
}
@@ -886,7 +893,7 @@ QCoreApplication::~QCoreApplication()
{
qt_call_post_routines();
- self = 0;
+ self = nullptr;
#ifndef QT_NO_QOBJECT
QCoreApplicationPrivate::is_app_closing = true;
QCoreApplicationPrivate::is_app_running = false;
@@ -894,7 +901,7 @@ QCoreApplication::~QCoreApplication()
#if QT_CONFIG(thread)
// Synchronize and stop the global thread pool threads.
- QThreadPool *globalThreadPool = 0;
+ QThreadPool *globalThreadPool = nullptr;
QT_TRY {
globalThreadPool = QThreadPool::globalInstance();
} QT_CATCH (...) {
@@ -905,10 +912,10 @@ QCoreApplication::~QCoreApplication()
#endif
#ifndef QT_NO_QOBJECT
- d_func()->threadData->eventDispatcher = 0;
+ d_func()->threadData->eventDispatcher = nullptr;
if (QCoreApplicationPrivate::eventDispatcher)
QCoreApplicationPrivate::eventDispatcher->closingDown();
- QCoreApplicationPrivate::eventDispatcher = 0;
+ QCoreApplicationPrivate::eventDispatcher = nullptr;
#endif
#if QT_CONFIG(library)
@@ -972,7 +979,11 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
QCoreApplicationPrivate::attribs |= 1 << attribute;
else
QCoreApplicationPrivate::attribs &= ~(1 << attribute);
+#if defined(QT_NO_QOBJECT)
if (Q_UNLIKELY(qApp)) {
+#else
+ if (Q_UNLIKELY(QCoreApplicationPrivate::is_app_running)) {
+#endif
switch (attribute) {
case Qt::AA_EnableHighDpiScaling:
case Qt::AA_DisableHighDpiScaling:
@@ -1172,7 +1183,7 @@ static bool doNotify(QObject *receiver, QEvent *event)
bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
{
// We can't access the application event filters outside of the main thread (race conditions)
- Q_ASSERT(receiver->d_func()->threadData->thread == mainThread());
+ Q_ASSERT(receiver->d_func()->threadData->thread.loadAcquire() == mainThread());
if (extraData) {
// application event filters are only called for objects in the GUI thread
@@ -1225,7 +1236,7 @@ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
// send to all application event filters (only does anything in the main thread)
if (QCoreApplication::self
- && receiver->d_func()->threadData->thread == mainThread()
+ && receiver->d_func()->threadData->thread.loadAcquire() == mainThread()
&& QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
filtered = true;
return filtered;
@@ -1297,7 +1308,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
QThreadData *data = QThreadData::current();
if (!data->hasEventDispatcher())
return;
- data->eventDispatcher.load()->processEvents(flags);
+ data->eventDispatcher.loadRelaxed()->processEvents(flags);
}
/*!
@@ -1329,7 +1340,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m
return;
QElapsedTimer start;
start.start();
- while (data->eventDispatcher.load()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
+ while (data->eventDispatcher.loadRelaxed()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
if (start.elapsed() > ms)
break;
}
@@ -1733,7 +1744,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
--data->postEventList.recursion;
if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher())
- data->eventDispatcher.load()->wakeUp();
+ data->eventDispatcher.loadRelaxed()->wakeUp();
// clear the global list, i.e. remove everything that was
// delivered.
@@ -1984,7 +1995,7 @@ void QCoreApplicationPrivate::deref()
void QCoreApplicationPrivate::maybeQuit()
{
- if (quitLockRef.load() == 0 && in_exec && quitLockRefEnabled && shouldQuit())
+ if (quitLockRef.loadRelaxed() == 0 && in_exec && quitLockRefEnabled && shouldQuit())
QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::Quit));
}
@@ -2646,7 +2657,7 @@ QString QCoreApplication::applicationVersion()
#if QT_CONFIG(library)
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
+Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
/*!
Returns a list of paths that the application will search when
@@ -2896,7 +2907,7 @@ void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filt
return;
}
- QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread);
+ QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
if (!filterObj || !eventDispatcher)
return;
eventDispatcher->installNativeEventFilter(filterObj);
@@ -2952,8 +2963,8 @@ bool QCoreApplication::hasPendingEvents()
*/
QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
{
- if (QCoreApplicationPrivate::theMainThread)
- return QCoreApplicationPrivate::theMainThread.load()->eventDispatcher();
+ if (QCoreApplicationPrivate::theMainThread.loadAcquire())
+ return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher();
return 0;
}
@@ -2965,7 +2976,7 @@ QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
*/
void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
{
- QThread *mainThread = QCoreApplicationPrivate::theMainThread;
+ QThread *mainThread = QCoreApplicationPrivate::theMainThread.loadAcquire();
if (!mainThread)
mainThread = QThread::currentThread(); // will also setup theMainThread
mainThread->setEventDispatcher(eventDispatcher);
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 0b9029b5fe..3bad42d076 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -52,7 +52,9 @@
//
#include "QtCore/qcoreapplication.h"
+#if QT_CONFIG(commandlineparser)
#include "QtCore/qcommandlineoption.h"
+#endif
#include "QtCore/qtranslator.h"
#if QT_CONFIG(settings)
#include "QtCore/qsettings.h"
@@ -105,7 +107,9 @@ public:
static bool checkInstance(const char *method);
+#if QT_CONFIG(commandlineparser)
virtual void addQtOptions(QList<QCommandLineOption> *options);
+#endif
#ifndef QT_NO_QOBJECT
bool sendThroughApplicationEventFilters(QObject *, QEvent *);
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 6995f9bbab..3f22c309ff 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -688,6 +688,12 @@ static const char *winPosInsertAfter(quintptr h)
static const char *sessionMgrLogOffOption(uint p)
{
+#ifndef ENDSESSION_CLOSEAPP
+#define ENDSESSION_CLOSEAPP 0x00000001
+#endif
+#ifndef ENDSESSION_CRITICAL
+#define ENDSESSION_CRITICAL 0x40000000
+#endif
static const QWinMessageMapping<uint> values[] = {
{ENDSESSION_CLOSEAPP, "Close application"},
{ENDSESSION_CRITICAL, "Force application end"},
@@ -881,12 +887,6 @@ QString decodeMSG(const MSG& msg)
parameters += QLatin1Char(')');
}
break;
-#ifndef ENDSESSION_CLOSEAPP
-#define ENDSESSION_CLOSEAPP 0x00000001
-#endif
-#ifndef ENDSESSION_CRITICAL
-#define ENDSESSION_CRITICAL 0x40000000
-#endif
case WM_QUERYENDSESSION:
parameters = QLatin1String("End session: ");
if (const char *logoffOption = sessionMgrLogOffOption(uint(wParam)))
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index aabd32b4a8..4cfc749386 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -424,7 +424,7 @@ struct QBasicAtomicBitField {
bool allocateSpecific(int which) noexcept
{
QBasicAtomicInteger<uint> &entry = data[which / BitsPerInt];
- const uint old = entry.load();
+ const uint old = entry.loadRelaxed();
const uint bit = 1U << (which % BitsPerInt);
return !(old & bit) // wasn't taken
&& entry.testAndSetRelaxed(old, old | bit); // still wasn't taken
@@ -445,10 +445,10 @@ struct QBasicAtomicBitField {
// Then again, this should never execute many iterations, so
// leave like this for now:
- for (uint i = next.load(); i < NumBits; ++i) {
+ for (uint i = next.loadRelaxed(); i < NumBits; ++i) {
if (allocateSpecific(i)) {
// remember next (possibly) free id:
- const uint oldNext = next.load();
+ const uint oldNext = next.loadRelaxed();
next.testAndSetRelaxed(oldNext, qMax(i + 1, oldNext));
return i;
}
diff --git a/src/corelib/kernel/qcoreglobaldata.cpp b/src/corelib/kernel/qcoreglobaldata.cpp
index 104be1b87b..7ff222f170 100644
--- a/src/corelib/kernel/qcoreglobaldata.cpp
+++ b/src/corelib/kernel/qcoreglobaldata.cpp
@@ -48,7 +48,7 @@ Q_GLOBAL_STATIC(QCoreGlobalData, globalInstance)
QCoreGlobalData::QCoreGlobalData()
#if QT_CONFIG(textcodec)
- : codecForLocale(0)
+ : codecForLocale(nullptr)
#endif
{
}
@@ -56,7 +56,7 @@ QCoreGlobalData::QCoreGlobalData()
QCoreGlobalData::~QCoreGlobalData()
{
#if QT_CONFIG(textcodec)
- codecForLocale = 0;
+ codecForLocale = nullptr;
QList<QTextCodec *> tmp = allCodecs;
allCodecs.clear();
codecCache.clear();
diff --git a/src/corelib/kernel/qelapsedtimer.cpp b/src/corelib/kernel/qelapsedtimer.cpp
index adb554b624..57825583dd 100644
--- a/src/corelib/kernel/qelapsedtimer.cpp
+++ b/src/corelib/kernel/qelapsedtimer.cpp
@@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE
\snippet qelapsedtimer/main.cpp 0
In this example, the timer is started by a call to start() and the
- elapsed timer is calculated by the elapsed() function.
+ elapsed time is calculated by the elapsed() function.
The time elapsed can also be used to recalculate the time available for
another operation, after the first one is complete. This is useful when
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 34c2dde6a8..d9746ef6e2 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -261,7 +261,7 @@ static gboolean postEventSourcePrepare(GSource *s, gint *timeout)
*timeout = canWait ? -1 : 0;
GPostEventSource *source = reinterpret_cast<GPostEventSource *>(s);
- source->d->wakeUpCalled = source->serialNumber.load() != source->lastSerialNumber;
+ source->d->wakeUpCalled = source->serialNumber.loadRelaxed() != source->lastSerialNumber;
return !canWait || source->d->wakeUpCalled;
}
@@ -273,7 +273,7 @@ static gboolean postEventSourceCheck(GSource *source)
static gboolean postEventSourceDispatch(GSource *s, GSourceFunc, gpointer)
{
GPostEventSource *source = reinterpret_cast<GPostEventSource *>(s);
- source->lastSerialNumber = source->serialNumber.load();
+ source->lastSerialNumber = source->serialNumber.loadRelaxed();
QCoreApplication::sendPostedEvents();
source->d->runTimersOnceWithNormalPriority();
return true; // i dunno, george...
@@ -320,7 +320,7 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context)
// setup post event source
postEventSource = reinterpret_cast<GPostEventSource *>(g_source_new(&postEventSourceFuncs,
sizeof(GPostEventSource)));
- postEventSource->serialNumber.store(1);
+ postEventSource->serialNumber.storeRelaxed(1);
postEventSource->d = this;
g_source_set_can_recurse(&postEventSource->source, true);
g_source_attach(&postEventSource->source, mainContext);
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index df0cac0239..5bc65b7110 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -459,7 +459,7 @@ void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier)
bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherUNIX);
- d->interrupt.store(0);
+ d->interrupt.storeRelaxed(0);
// we are awake, broadcast it
emit awake();
@@ -470,13 +470,13 @@ bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
const bool wait_for_events = flags & QEventLoop::WaitForMoreEvents;
const bool canWait = (d->threadData->canWaitLocked()
- && !d->interrupt.load()
+ && !d->interrupt.loadRelaxed()
&& wait_for_events);
if (canWait)
emit aboutToBlock();
- if (d->interrupt.load())
+ if (d->interrupt.loadRelaxed())
return false;
timespec *tm = nullptr;
@@ -545,7 +545,7 @@ void QEventDispatcherUNIX::wakeUp()
void QEventDispatcherUNIX::interrupt()
{
Q_D(QEventDispatcherUNIX);
- d->interrupt.store(1);
+ d->interrupt.storeRelaxed(1);
wakeUp();
}
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index e0641a0282..c15d740f9e 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -52,7 +52,6 @@
#include "qelapsedtimer.h"
#include "qcoreapplication_p.h"
#include <private/qthread_p.h>
-#include <private/qmutexpool_p.h>
#include <private/qwineventnotifier_p.h>
QT_BEGIN_NAMESPACE
@@ -101,7 +100,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
: threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0),
- getMessageHook(0), wakeUps(0), activateNotifiersPosted(false),
+ wakeUps(0), activateNotifiersPosted(false),
winEventNotifierActivatedEvent(NULL)
{
}
@@ -247,7 +246,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
Q_ASSERT(d != 0);
// Allow posting WM_QT_SENDPOSTEDEVENTS message.
- d->wakeUps.store(0);
+ d->wakeUps.storeRelaxed(0);
// We send posted events manually, if the window procedure was invoked
// by the foreign event loop (e.g. from the native modal dialog).
@@ -270,14 +269,6 @@ static inline UINT inputTimerMask()
return result;
}
-LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
-{
- QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
- Q_ASSERT(q != 0);
-
- return q->d_func()->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0;
-}
-
// Provide class name and atom for the message window used by
// QEventDispatcherWin32Private via Q_GLOBAL_STATIC shared between threads.
struct QWindowsMessageWindowClassContext
@@ -456,38 +447,11 @@ void QEventDispatcherWin32::createInternalHwnd()
return;
d->internalHwnd = qt_create_internal_window(this);
- installMessageHook();
-
// start all normal timers
for (int i = 0; i < d->timerVec.count(); ++i)
d->registerTimer(d->timerVec.at(i));
}
-void QEventDispatcherWin32::installMessageHook()
-{
- Q_D(QEventDispatcherWin32);
-
- if (d->getMessageHook)
- return;
-
- // setup GetMessage hook needed to drive our posted events
- d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
- if (Q_UNLIKELY(!d->getMessageHook)) {
- int errorCode = GetLastError();
- qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %ls",
- errorCode, qUtf16Printable(qt_error_string(errorCode)));
- }
-}
-
-void QEventDispatcherWin32::uninstallMessageHook()
-{
- Q_D(QEventDispatcherWin32);
-
- if (d->getMessageHook)
- UnhookWindowsHookEx(d->getMessageHook);
- d->getMessageHook = 0;
-}
-
QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent)
: QAbstractEventDispatcher(*new QEventDispatcherWin32Private, parent)
{
@@ -526,7 +490,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
wakeUp(); // trigger a call to sendPostedEvents()
}
- d->interrupt.store(false);
+ d->interrupt.storeRelaxed(false);
emit awake();
// To prevent livelocks, send posted events once per iteration.
@@ -545,7 +509,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
pHandles = &d->winEventNotifierActivatedEvent;
}
QVarLengthArray<MSG> processedTimers;
- while (!d->interrupt.load()) {
+ while (!d->interrupt.loadRelaxed()) {
MSG msg;
bool haveMessage;
@@ -583,14 +547,10 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
}
}
if (haveMessage) {
- // The Direct2d integration unsets getMessageHook. See QTBUG-42428
- if (!d->getMessageHook)
- (void) qt_GetMessageHook(0, PM_REMOVE, reinterpret_cast<LPARAM>(&msg));
-
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
// Set result to 'true', if the message was sent by wakeUp().
if (msg.wParam == WMWP_QT_FROMWAKEUP) {
- d->wakeUps.store(0);
+ d->wakeUps.storeRelaxed(0);
retVal = true;
}
needWM_QT_SENDPOSTEDEVENTS = true;
@@ -639,7 +599,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
// still nothing - wait for message or signalled objects
canWait = (!retVal
- && !d->interrupt.load()
+ && !d->interrupt.loadRelaxed()
&& (flags & QEventLoop::WaitForMoreEvents));
if (canWait) {
emit aboutToBlock();
@@ -949,7 +909,7 @@ void QEventDispatcherWin32::activateEventNotifiers()
for (int i = 0; i < d->winEventNotifierList.count(); ++i) {
QWinEventNotifier *notifier = d->winEventNotifierList.at(i);
QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
- if (nd->signaledCount.load() != 0) {
+ if (nd->signaledCount.loadRelaxed() != 0) {
--nd->signaledCount;
nd->unregisterWaitObject();
d->activateEventNotifier(notifier);
@@ -1014,7 +974,7 @@ void QEventDispatcherWin32::wakeUp()
void QEventDispatcherWin32::interrupt()
{
Q_D(QEventDispatcherWin32);
- d->interrupt.store(true);
+ d->interrupt.storeRelaxed(true);
wakeUp();
}
@@ -1044,8 +1004,6 @@ void QEventDispatcherWin32::closingDown()
d->timerDict.clear();
d->closingDown = true;
-
- uninstallMessageHook();
}
bool QEventDispatcherWin32::event(QEvent *e)
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index f672530ff8..697c07f912 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -73,8 +73,6 @@ class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher
protected:
void createInternalHwnd();
- void installMessageHook();
- void uninstallMessageHook();
public:
explicit QEventDispatcherWin32(QObject *parent = 0);
@@ -115,7 +113,6 @@ protected:
private:
friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
- friend LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM);
};
struct QSockNot {
@@ -169,7 +166,6 @@ public:
// internal window handle used for socketnotifiers/timers/etc
HWND internalHwnd;
- HHOOK getMessageHook;
// for controlling when to send posted events
QAtomicInt wakeUps;
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index a6cc51621a..eacd0c4e73 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -135,7 +135,7 @@ bool QEventLoop::processEvents(ProcessEventsFlags flags)
Q_D(QEventLoop);
if (!d->threadData->hasEventDispatcher())
return false;
- return d->threadData->eventDispatcher.load()->processEvents(flags);
+ return d->threadData->eventDispatcher.loadRelaxed()->processEvents(flags);
}
/*!
@@ -165,7 +165,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
//we need to protect from race condition with QThread::exit
- QMutexLocker locker(&static_cast<QThreadPrivate *>(QObjectPrivate::get(d->threadData->thread))->mutex);
+ QMutexLocker locker(&static_cast<QThreadPrivate *>(QObjectPrivate::get(d->threadData->thread.loadAcquire()))->mutex);
if (d->threadData->quitNow)
return -1;
@@ -225,7 +225,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
processEvents(flags | WaitForMoreEvents | EventLoopExec);
ref.exceptionCaught = false;
- return d->returnCode.load();
+ return d->returnCode.loadRelaxed();
}
/*!
@@ -279,9 +279,9 @@ void QEventLoop::exit(int returnCode)
if (!d->threadData->hasEventDispatcher())
return;
- d->returnCode.store(returnCode);
+ d->returnCode.storeRelaxed(returnCode);
d->exit.storeRelease(true);
- d->threadData->eventDispatcher.load()->interrupt();
+ d->threadData->eventDispatcher.loadRelaxed()->interrupt();
#ifdef Q_OS_WASM
// QEventLoop::exec() never returns in emscripten. We implement approximate behavior here.
@@ -318,7 +318,7 @@ void QEventLoop::wakeUp()
Q_D(QEventLoop);
if (!d->threadData->hasEventDispatcher())
return;
- d->threadData->eventDispatcher.load()->wakeUp();
+ d->threadData->eventDispatcher.loadRelaxed()->wakeUp();
}
diff --git a/src/corelib/kernel/qeventloop_p.h b/src/corelib/kernel/qeventloop_p.h
index dcbb5c63c6..4ad6d92007 100644
--- a/src/corelib/kernel/qeventloop_p.h
+++ b/src/corelib/kernel/qeventloop_p.h
@@ -63,8 +63,8 @@ public:
inline QEventLoopPrivate()
: inExec(false)
{
- returnCode.store(-1);
- exit.store(true);
+ returnCode.storeRelaxed(-1);
+ exit.storeRelaxed(true);
}
QAtomicInt quitLockRef;
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 75a2436d9d..5f652d70e3 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -47,9 +47,9 @@
QT_BEGIN_NAMESPACE
-static inline QString keyBase()
+static inline QLatin1String keyBase()
{
- return QStringLiteral("%1%2:%3");
+ return QLatin1String("%1%2:%3");
}
static QString qt_convertJString(jstring string)
@@ -154,7 +154,7 @@ static jmethodID getCachedMethodID(JNIEnv *env,
if (className.isEmpty())
return getMethodID(env, clazz, name, sig, isStatic);
- const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig));
+ const QString key = keyBase().arg(QLatin1String(className), QLatin1String(name), QLatin1String(sig));
QHash<QString, jmethodID>::const_iterator it;
{
@@ -206,7 +206,7 @@ static jfieldID getCachedFieldID(JNIEnv *env,
if (className.isNull())
return getFieldID(env, clazz, name, sig, isStatic);
- const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig));
+ const QString key = keyBase().arg(QLatin1String(className), QLatin1String(name), QLatin1String(sig));
QHash<QString, jfieldID>::const_iterator it;
{
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 855d36794d..754f5a13e4 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -517,12 +517,12 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ
QT_FOR_EACH_STATIC_TYPE(QT_ADD_STATIC_METATYPE)
QT_FOR_EACH_STATIC_ALIAS_TYPE(QT_ADD_STATIC_METATYPE_ALIASES_ITER)
QT_FOR_EACH_STATIC_HACKS_TYPE(QT_ADD_STATIC_METATYPE_HACKS_ITER)
- {0, 0, QMetaType::UnknownType}
+ {nullptr, 0, QMetaType::UnknownType}
};
-Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = 0;
-Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = 0;
-Q_CORE_EXPORT const QMetaObject *qMetaObjectWidgetsHelper = 0;
+Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeGuiHelper = nullptr;
+Q_CORE_EXPORT const QMetaTypeInterface *qMetaTypeWidgetsHelper = nullptr;
+Q_CORE_EXPORT const QMetaObject *qMetaObjectWidgetsHelper = nullptr;
class QCustomTypeInfo : public QMetaTypeInterface
{
@@ -557,7 +557,7 @@ public:
{
const QWriteLocker locker(&lock);
const T* &fun = map[k];
- if (fun != 0)
+ if (fun)
return false;
fun = f;
return true;
@@ -566,7 +566,7 @@ public:
const T *function(Key k) const
{
const QReadLocker locker(&lock);
- return map.value(k, 0);
+ return map.value(k, nullptr);
}
void remove(int from, int to)
@@ -587,13 +587,7 @@ QMetaTypeComparatorRegistry;
typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractDebugStreamFunction,int>
QMetaTypeDebugStreamRegistry;
-namespace
-{
-union CheckThatItIsPod
-{ // This should break if QMetaTypeInterface is not a POD type
- QMetaTypeInterface iface;
-};
-}
+Q_STATIC_ASSERT(std::is_pod<QMetaTypeInterface>::value);
Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
@@ -973,7 +967,7 @@ static inline int qMetaTypeStaticType(const char *typeName, int length)
The extra \a firstInvalidIndex parameter is an easy way to avoid
iterating over customTypes() a second time in registerNormalizedType().
*/
-static int qMetaTypeCustomType_unlocked(const char *typeName, int length, int *firstInvalidIndex = 0)
+static int qMetaTypeCustomType_unlocked(const char *typeName, int length, int *firstInvalidIndex = nullptr)
{
const QVector<QCustomTypeInfo> * const ct = customTypes();
if (!ct)
@@ -1006,7 +1000,7 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
{
return registerType(typeName, deleter, creator,
QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Destruct,
- QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct, 0, TypeFlags(), 0);
+ QtMetaTypePrivate::QMetaTypeFunctionHelper<void>::Construct, 0, TypeFlags(), nullptr);
}
/*!
@@ -1613,7 +1607,7 @@ void *QMetaType::create(int type, const void *copy)
QMetaType info(type);
if (int size = info.sizeOf())
return info.construct(operator new(size), copy);
- return 0;
+ return nullptr;
}
/*!
@@ -1639,14 +1633,18 @@ class TypeConstructor {
static void *Construct(const int type, void *where, const void *copy)
{
if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
- return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy) : 0;
+ return Q_LIKELY(qMetaTypeGuiHelper)
+ ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor(where, copy)
+ : nullptr;
if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
- return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy) : 0;
+ return Q_LIKELY(qMetaTypeWidgetsHelper)
+ ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor(where, copy)
+ : nullptr;
// This point can be reached only for known types that definition is not available, for example
// in bootstrap mode. We have no other choice then ignore it.
- return 0;
+ return nullptr;
}
};
public:
@@ -1670,7 +1668,7 @@ private:
{
QReadLocker locker(customTypesLock());
if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
- return 0;
+ return nullptr;
const auto &typeInfo = ct->at(type - QMetaType::User);
ctor = typeInfo.constructor;
tctor = typeInfo.typedConstructor;
@@ -1715,7 +1713,7 @@ private:
void *QMetaType::construct(int type, void *where, const void *copy)
{
if (!where)
- return 0;
+ return nullptr;
TypeConstructor constructor(type, where);
return QMetaTypeSwitcher::switcher<void*>(constructor, type, copy);
}
@@ -1861,7 +1859,7 @@ private:
int QMetaType::sizeOf(int type)
{
SizeOf sizeOf(type);
- return QMetaTypeSwitcher::switcher<int>(sizeOf, type, 0);
+ return QMetaTypeSwitcher::switcher<int>(sizeOf, type);
}
namespace {
@@ -1925,7 +1923,7 @@ private:
QMetaType::TypeFlags QMetaType::typeFlags(int type)
{
Flags flags(type);
- return static_cast<QMetaType::TypeFlags>(QMetaTypeSwitcher::switcher<quint32>(flags, type, 0));
+ return static_cast<QMetaType::TypeFlags>(QMetaTypeSwitcher::switcher<quint32>(flags, type));
}
#ifndef QT_BOOTSTRAPPED
@@ -1948,17 +1946,21 @@ public:
{
static const QMetaObject *MetaObject(int type) {
if (QModulesPrivate::QTypeModuleInfo<T>::IsGui)
- return Q_LIKELY(qMetaTypeGuiHelper) ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].metaObject : 0;
+ return Q_LIKELY(qMetaTypeGuiHelper)
+ ? qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].metaObject
+ : nullptr;
if (QModulesPrivate::QTypeModuleInfo<T>::IsWidget)
- return Q_LIKELY(qMetaTypeWidgetsHelper) ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].metaObject : 0;
+ return Q_LIKELY(qMetaTypeWidgetsHelper)
+ ? qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].metaObject
+ : nullptr;
return 0;
}
};
template <typename T>
const QMetaObject *delegate(const T *) { return MetaObjectImpl<T>::MetaObject(m_type); }
- const QMetaObject *delegate(const void*) { return 0; }
- const QMetaObject *delegate(const QMetaTypeSwitcher::UnknownType*) { return 0; }
+ const QMetaObject *delegate(const void*) { return nullptr; }
+ const QMetaObject *delegate(const QMetaTypeSwitcher::UnknownType*) { return nullptr; }
const QMetaObject *delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return customMetaObject(m_type); }
private:
const int m_type;
@@ -1966,10 +1968,10 @@ private:
{
const QVector<QCustomTypeInfo> * const ct = customTypes();
if (Q_UNLIKELY(!ct || type < QMetaType::User))
- return 0;
+ return nullptr;
QReadLocker locker(customTypesLock());
if (Q_UNLIKELY(ct->count() <= type - QMetaType::User))
- return 0;
+ return nullptr;
return ct->at(type - QMetaType::User).metaObject;
}
};
@@ -1987,10 +1989,10 @@ const QMetaObject *QMetaType::metaObjectForType(int type)
{
#ifndef QT_BOOTSTRAPPED
MetaObject mo(type);
- return QMetaTypeSwitcher::switcher<const QMetaObject*>(mo, type, 0);
+ return QMetaTypeSwitcher::switcher<const QMetaObject*>(mo, type);
#else
Q_UNUSED(type);
- return 0;
+ return nullptr;
#endif
}
@@ -2187,7 +2189,7 @@ private:
QMetaType QMetaType::typeInfo(const int type)
{
TypeInfo typeInfo(type);
- QMetaTypeSwitcher::switcher<void>(typeInfo, type, 0);
+ QMetaTypeSwitcher::switcher<void>(typeInfo, type);
return (typeInfo.info.constructor || typeInfo.info.typedConstructor)
? QMetaType(static_cast<ExtensionFlag>(QMetaType::CreateEx | QMetaType::DestroyEx |
(typeInfo.info.typedConstructor ? QMetaType::ConstructEx | QMetaType::DestructEx : 0))
@@ -2307,7 +2309,7 @@ void QMetaType::dtor()
void *QMetaType::createExtended(const void *copy) const
{
if (m_typeId == QMetaType::UnknownType)
- return 0;
+ return nullptr;
if (Q_UNLIKELY(m_typedConstructor && !m_constructor))
return m_typedConstructor(m_typeId, operator new(m_size), copy);
return m_constructor(operator new(m_size), copy);
@@ -2387,7 +2389,7 @@ uint QMetaType::sizeExtended() const
*/
QMetaType::TypeFlags QMetaType::flagsExtended() const
{
- return 0;
+ return { };
}
/*!
@@ -2400,7 +2402,7 @@ QMetaType::TypeFlags QMetaType::flagsExtended() const
*/
const QMetaObject *QMetaType::metaObjectExtended() const
{
- return 0;
+ return nullptr;
}
@@ -2409,7 +2411,7 @@ namespace QtPrivate
const QMetaObject *metaObjectForQWidget()
{
if (!qMetaTypeWidgetsHelper)
- return 0;
+ return nullptr;
return qMetaObjectWidgetsHelper;
}
}
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 12d4bc97aa..a97764ede4 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -1715,12 +1715,17 @@ namespace QtPrivate {
}
};
+ // hack to delay name lookup to instantiation time by making
+ // EnableInternalData a dependent name:
+ template <typename T>
+ struct EnableInternalDataWrap;
+
template<typename T>
struct QSmartPointerConvertFunctor<QWeakPointer<T> >
{
QObject* operator()(const QWeakPointer<T> &p) const
{
- return p.internalData();
+ return QtPrivate::EnableInternalDataWrap<T>::internalData(p);
}
};
}
@@ -1994,7 +1999,7 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE<T> > \
static int qt_metatype_id() \
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
- if (const int id = metatype_id.load()) \
+ if (const int id = metatype_id.loadRelaxed()) \
return id; \
const char *tName = QMetaType::typeName(qMetaTypeId<T>()); \
Q_ASSERT(tName); \
diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h
index 0846193e66..fa7208369a 100644
--- a/src/corelib/kernel/qmetatype_p.h
+++ b/src/corelib/kernel/qmetatype_p.h
@@ -74,7 +74,7 @@ template <typename T>
class QTypeModuleInfo
{
public:
- enum Module {
+ enum Module : bool {
IsCore = false,
IsWidget = false,
IsGui = false,
@@ -140,12 +140,12 @@ public:
/*saveOp*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Save), \
/*loadOp*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Load),
# define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \
- /*saveOp*/ 0, \
- /*loadOp*/ 0,
+ /*saveOp*/ nullptr, \
+ /*loadOp*/ nullptr,
#else
# define QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type) \
- /*saveOp*/ 0, \
- /*loadOp*/ 0,
+ /*saveOp*/ nullptr, \
+ /*loadOp*/ nullptr,
# define QT_METATYPE_INTERFACE_INIT_DATASTREAM_IMPL(Type) \
QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(Type)
#endif
@@ -153,7 +153,7 @@ public:
#ifndef QT_BOOTSTRAPPED
#define METAOBJECT_DELEGATE(Type) (QtPrivate::MetaObjectForType<Type>::value())
#else
-#define METAOBJECT_DELEGATE(Type) 0
+#define METAOBJECT_DELEGATE(Type) nullptr
#endif
#define QT_METATYPE_INTERFACE_INIT_IMPL(Type, DATASTREAM_DELEGATE) \
@@ -184,11 +184,11 @@ public:
#define QT_METATYPE_INTERFACE_INIT_EMPTY() \
{ \
QT_METATYPE_INTERFACE_INIT_EMPTY_DATASTREAM_IMPL(void) \
- /*constructor*/ 0, \
- /*destructor*/ 0, \
+ /*constructor*/ nullptr, \
+ /*destructor*/ nullptr, \
/*size*/ 0, \
/*flags*/ 0, \
- /*metaObject*/ 0 , \
+ /*metaObject*/ nullptr , \
/*typedConstructor*/ nullptr, \
/*typedDestructor*/ nullptr \
}
diff --git a/src/corelib/kernel/qmetatypeswitcher_p.h b/src/corelib/kernel/qmetatypeswitcher_p.h
index 154fb8ab7f..dabc70f4b0 100644
--- a/src/corelib/kernel/qmetatypeswitcher_p.h
+++ b/src/corelib/kernel/qmetatypeswitcher_p.h
@@ -60,7 +60,7 @@ public:
class NotBuiltinType; // type is not a built-in type, but it may be a custom type or an unknown type
class UnknownType; // type not known to QMetaType system
template<class ReturnType, class DelegateObject>
- static ReturnType switcher(DelegateObject &logic, int type, const void *data);
+ static ReturnType switcher(DelegateObject &logic, int type, const void *data = nullptr);
};
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 965857d408..5c1ae8aa43 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -58,6 +58,7 @@
#include <qdebug.h>
#include <qpair.h>
#include <qvarlengtharray.h>
+#include <qscopeguard.h>
#include <qset.h>
#if QT_CONFIG(thread)
#include <qsemaphore.h>
@@ -81,7 +82,7 @@ Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_
void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set)
{
- qt_signal_spy_callback_set.store(callback_set);
+ qt_signal_spy_callback_set.storeRelease(callback_set);
}
QDynamicMetaObjectData::~QDynamicMetaObjectData()
@@ -218,10 +219,10 @@ QObjectPrivate::QObjectPrivate(int version)
QObjectPrivate::~QObjectPrivate()
{
if (extraData && !extraData->runningTimers.isEmpty()) {
- if (Q_LIKELY(threadData->thread == QThread::currentThread())) {
+ if (Q_LIKELY(threadData->thread.loadAcquire() == QThread::currentThread())) {
// unregister pending timers
if (threadData->hasEventDispatcher())
- threadData->eventDispatcher.load()->unregisterTimers(q_ptr);
+ threadData->eventDispatcher.loadRelaxed()->unregisterTimers(q_ptr);
// release the timer ids back to the pool
for (int i = 0; i < extraData->runningTimers.size(); ++i)
@@ -267,17 +268,17 @@ bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
{
Q_Q(const QObject);
int signal_index = signalIndex(signal);
- ConnectionData *cd = connections.load();
+ ConnectionData *cd = connections.loadRelaxed();
if (signal_index < 0 || !cd)
return false;
QBasicMutexLocker locker(signalSlotLock(q));
if (signal_index < cd->signalVectorCount()) {
- const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
+ const QObjectPrivate::Connection *c = cd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed();
while (c) {
- if (c->receiver.load() == receiver)
+ if (c->receiver.loadRelaxed() == receiver)
return true;
- c = c->nextConnectionList.load();
+ c = c->nextConnectionList.loadRelaxed();
}
}
return false;
@@ -288,17 +289,17 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const
{
QObjectList returnValue;
int signal_index = signalIndex(signal);
- ConnectionData *cd = connections.load();
+ ConnectionData *cd = connections.loadRelaxed();
if (signal_index < 0 || !cd)
return returnValue;
if (signal_index < cd->signalVectorCount()) {
- const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
+ const QObjectPrivate::Connection *c = cd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed();
while (c) {
- QObject *r = c->receiver.load();
+ QObject *r = c->receiver.loadRelaxed();
if (r)
returnValue << r;
- c = c->nextConnectionList.load();
+ c = c->nextConnectionList.loadRelaxed();
}
}
return returnValue;
@@ -308,7 +309,7 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const
QObjectList QObjectPrivate::senderList() const
{
QObjectList returnValue;
- ConnectionData *cd = connections.load();
+ ConnectionData *cd = connections.loadRelaxed();
if (cd) {
QBasicMutexLocker locker(signalSlotLock(q_func()));
for (Connection *c = cd->senders; c; c = c->next)
@@ -331,24 +332,24 @@ void QObjectPrivate::addConnection(int signal, Connection *c)
{
Q_ASSERT(c->sender == q_ptr);
ensureConnectionData();
- ConnectionData *cd = connections.load();
+ ConnectionData *cd = connections.loadRelaxed();
cd->resizeSignalVector(signal + 1);
ConnectionList &connectionList = cd->connectionsForSignal(signal);
- if (connectionList.last.load()) {
- Q_ASSERT(connectionList.last.load()->receiver.load());
- connectionList.last.load()->nextConnectionList.store(c);
+ if (connectionList.last.loadRelaxed()) {
+ Q_ASSERT(connectionList.last.loadRelaxed()->receiver.loadRelaxed());
+ connectionList.last.loadRelaxed()->nextConnectionList.storeRelaxed(c);
} else {
- connectionList.first.store(c);
+ connectionList.first.storeRelaxed(c);
}
c->id = ++cd->currentConnectionId;
- c->prevConnectionList = connectionList.last.load();
- connectionList.last.store(c);
+ c->prevConnectionList = connectionList.last.loadRelaxed();
+ connectionList.last.storeRelaxed(c);
- QObjectPrivate *rd = QObjectPrivate::get(c->receiver.load());
+ QObjectPrivate *rd = QObjectPrivate::get(c->receiver.loadRelaxed());
rd->ensureConnectionData();
- c->prev = &(rd->connections.load()->senders);
+ c->prev = &(rd->connections.loadRelaxed()->senders);
c->next = *c->prev;
*c->prev = c;
if (c->next)
@@ -357,17 +358,17 @@ void QObjectPrivate::addConnection(int signal, Connection *c)
void QObjectPrivate::ConnectionData::removeConnection(QObjectPrivate::Connection *c)
{
- Q_ASSERT(c->receiver.load());
- ConnectionList &connections = signalVector.load()->at(c->signal_index);
- c->receiver.store(nullptr);
- QThreadData *td = c->receiverThreadData.load();
+ Q_ASSERT(c->receiver.loadRelaxed());
+ ConnectionList &connections = signalVector.loadRelaxed()->at(c->signal_index);
+ c->receiver.storeRelaxed(nullptr);
+ QThreadData *td = c->receiverThreadData.loadRelaxed();
if (td)
td->deref();
- c->receiverThreadData.store(nullptr);
+ c->receiverThreadData.storeRelaxed(nullptr);
#ifndef QT_NO_DEBUG
bool found = false;
- for (Connection *cc = connections.first.load(); cc; cc = cc->nextConnectionList.load()) {
+ for (Connection *cc = connections.first.loadRelaxed(); cc; cc = cc->nextConnectionList.loadRelaxed()) {
if (cc == c) {
found = true;
break;
@@ -382,29 +383,29 @@ void QObjectPrivate::ConnectionData::removeConnection(QObjectPrivate::Connection
c->next->prev = c->prev;
c->prev = nullptr;
- if (connections.first.load() == c)
- connections.first.store(c->nextConnectionList.load());
- if (connections.last.load() == c)
- connections.last.store(c->prevConnectionList);
- Q_ASSERT(signalVector.load()->at(c->signal_index).first.load() != c);
- Q_ASSERT(signalVector.load()->at(c->signal_index).last.load() != c);
+ if (connections.first.loadRelaxed() == c)
+ connections.first.storeRelaxed(c->nextConnectionList.loadRelaxed());
+ if (connections.last.loadRelaxed() == c)
+ connections.last.storeRelaxed(c->prevConnectionList);
+ Q_ASSERT(signalVector.loadRelaxed()->at(c->signal_index).first.loadRelaxed() != c);
+ Q_ASSERT(signalVector.loadRelaxed()->at(c->signal_index).last.loadRelaxed() != c);
// keep c->nextConnectionList intact, as it might still get accessed by activate
- Connection *n = c->nextConnectionList.load();
+ Connection *n = c->nextConnectionList.loadRelaxed();
if (n)
n->prevConnectionList = c->prevConnectionList;
if (c->prevConnectionList)
- c->prevConnectionList->nextConnectionList.store(n);
+ c->prevConnectionList->nextConnectionList.storeRelaxed(n);
c->prevConnectionList = nullptr;
- Q_ASSERT(c != orphaned.load());
+ Q_ASSERT(c != orphaned.loadRelaxed());
// add c to orphanedConnections
- c->nextInOrphanList = orphaned.load();
- orphaned.store(c);
+ c->nextInOrphanList = orphaned.loadRelaxed();
+ orphaned.storeRelaxed(c);
#ifndef QT_NO_DEBUG
found = false;
- for (Connection *cc = connections.first.load(); cc; cc = cc->nextConnectionList.load()) {
+ for (Connection *cc = connections.first.loadRelaxed(); cc; cc = cc->nextConnectionList.loadRelaxed()) {
if (cc == c) {
found = true;
break;
@@ -420,14 +421,14 @@ void QObjectPrivate::ConnectionData::cleanOrphanedConnectionsImpl(QObject *sende
ConnectionOrSignalVector *c = nullptr;
{
QBasicMutexLocker l(signalSlotLock(sender));
- if (ref > 1)
+ if (ref.loadAcquire() > 1)
return;
// Since ref == 1, no activate() is in process since we locked the mutex. That implies,
// that nothing can reference the orphaned connection objects anymore and they can
// be safely deleted
- c = orphaned.load();
- orphaned.store(nullptr);
+ c = orphaned.loadRelaxed();
+ orphaned.storeRelaxed(nullptr);
}
deleteOrphaned(c);
}
@@ -442,7 +443,7 @@ void QObjectPrivate::ConnectionData::deleteOrphaned(QObjectPrivate::ConnectionOr
} else {
QObjectPrivate::Connection *c = static_cast<Connection *>(o);
next = c->nextInOrphanList;
- Q_ASSERT(!c->receiver.load());
+ Q_ASSERT(!c->receiver.loadRelaxed());
Q_ASSERT(!c->prev);
c->freeSlotObject();
c->deref();
@@ -462,22 +463,22 @@ bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative)
if (checkDeclarative && isDeclarativeSignalConnected(signalIndex))
return true;
- ConnectionData *cd = connections.load();
+ ConnectionData *cd = connections.loadRelaxed();
if (!cd)
return false;
- SignalVector *signalVector = cd->signalVector.load();
+ SignalVector *signalVector = cd->signalVector.loadRelaxed();
if (!signalVector)
return false;
- if (signalVector->at(-1).first.load())
+ if (signalVector->at(-1).first.loadRelaxed())
return true;
if (signalIndex < uint(cd->signalVectorCount())) {
- const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first.load();
+ const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first.loadRelaxed();
while (c) {
- if (c->receiver.load())
+ if (c->receiver.loadRelaxed())
return true;
- c = c->nextConnectionList.load();
+ c = c->nextConnectionList.loadRelaxed();
}
}
return false;
@@ -485,18 +486,18 @@ bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative)
bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const
{
- ConnectionData *cd = connections.load();
+ ConnectionData *cd = connections.loadRelaxed();
if (!cd)
return false;
- SignalVector *signalVector = cd->signalVector.load();
+ SignalVector *signalVector = cd->signalVector.loadRelaxed();
if (!signalVector)
return false;
- if (signalVector->at(-1).first)
+ if (signalVector->at(-1).first.loadAcquire())
return true;
if (signalIndex < uint(cd->signalVectorCount())) {
- const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first;
+ const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first.loadAcquire();
return c != nullptr;
}
return false;
@@ -818,8 +819,8 @@ static bool check_parent_thread(QObject *parent,
QThreadData *currentThreadData)
{
if (parent && parentThreadData != currentThreadData) {
- QThread *parentThread = parentThreadData->thread;
- QThread *currentThread = currentThreadData->thread;
+ QThread *parentThread = parentThreadData->thread.loadAcquire();
+ QThread *currentThread = currentThreadData->thread.loadAcquire();
qWarning("QObject: Cannot create children for a parent that is in a different thread.\n"
"(Parent is %s(%p), parent's thread is %s(%p), current thread is %s(%p)",
parent->metaObject()->className(),
@@ -851,6 +852,8 @@ static bool check_parent_thread(QObject *parent,
QObject::QObject(QObject *parent)
: d_ptr(new QObjectPrivate)
{
+ Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself");
+
Q_D(QObject);
d_ptr->q_ptr = this;
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
@@ -879,6 +882,8 @@ QObject::QObject(QObject *parent)
QObject::QObject(QObjectPrivate &dd, QObject *parent)
: d_ptr(&dd)
{
+ Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself");
+
Q_D(QObject);
d_ptr->q_ptr = this;
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
@@ -939,15 +944,15 @@ QObject::~QObject()
d->wasDeleted = true;
d->blockSig = 0; // unblock signals so we always emit destroyed()
- QtSharedPointer::ExternalRefCountData *sharedRefcount = d->sharedRefcount.load();
+ QtSharedPointer::ExternalRefCountData *sharedRefcount = d->sharedRefcount.loadRelaxed();
if (sharedRefcount) {
- if (sharedRefcount->strongref.load() > 0) {
+ if (sharedRefcount->strongref.loadRelaxed() > 0) {
qWarning("QObject: shared QObject was deleted directly. The program is malformed and may crash.");
// but continue deleting, it's too late to stop anyway
}
// indicate to all QWeakPointers that this QObject has now been deleted
- sharedRefcount->strongref.store(0);
+ sharedRefcount->strongref.storeRelaxed(0);
if (!sharedRefcount->weakref.deref())
delete sharedRefcount;
}
@@ -966,7 +971,7 @@ QObject::~QObject()
}
}
- QObjectPrivate::ConnectionData *cd = d->connections.load();
+ QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
if (cd) {
if (cd->currentSender) {
cd->currentSender->receiverDeleted();
@@ -981,14 +986,14 @@ QObject::~QObject()
for (int signal = -1; signal < receiverCount; ++signal) {
QObjectPrivate::ConnectionList &connectionList = cd->connectionsForSignal(signal);
- while (QObjectPrivate::Connection *c = connectionList.first.load()) {
- Q_ASSERT(c->receiver);
+ while (QObjectPrivate::Connection *c = connectionList.first.loadRelaxed()) {
+ Q_ASSERT(c->receiver.loadAcquire());
- QBasicMutex *m = signalSlotLock(c->receiver.load());
+ QBasicMutex *m = signalSlotLock(c->receiver.loadRelaxed());
bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
- if (c->receiver) {
+ if (c->receiver.loadAcquire()) {
cd->removeConnection(c);
- Q_ASSERT(connectionList.first.load() != c);
+ Q_ASSERT(connectionList.first.loadRelaxed() != c);
}
if (needToUnlock)
m->unlock();
@@ -998,7 +1003,7 @@ QObject::~QObject()
/* Disconnect all senders:
*/
while (QObjectPrivate::Connection *node = cd->senders) {
- Q_ASSERT(node->receiver);
+ Q_ASSERT(node->receiver.loadAcquire());
QObject *sender = node->sender;
// Send disconnectNotify before removing the connection from sender's connection list.
// This ensures any eventual destructor of sender will block on getting receiver's lock
@@ -1014,7 +1019,7 @@ QObject::~QObject()
continue;
}
- QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections.load();
+ QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections.loadRelaxed();
Q_ASSERT(senderData);
QtPrivate::QSlotObjectBase *slotObj = nullptr;
@@ -1036,11 +1041,11 @@ QObject::~QObject()
// invalidate all connections on the object and make sure
// activate() will skip them
- cd->currentConnectionId.store(0);
+ cd->currentConnectionId.storeRelaxed(0);
}
if (cd && !cd->ref.deref())
delete cd;
- d->connections.store(nullptr);
+ d->connections.storeRelaxed(nullptr);
if (!d->children.isEmpty())
d->deleteChildren();
@@ -1060,7 +1065,7 @@ QObject::~QObject()
QObjectPrivate::Connection::~Connection()
{
if (ownArgumentTypes) {
- const int *v = argumentTypes.load();
+ const int *v = argumentTypes.loadRelaxed();
if (v != &DIRECT_CONNECTION_ONLY)
delete [] v;
}
@@ -1269,7 +1274,7 @@ bool QObject::event(QEvent *e)
{
QAbstractMetaCallEvent *mce = static_cast<QAbstractMetaCallEvent*>(e);
- if (!d_func()->connections.load()) {
+ if (!d_func()->connections.loadRelaxed()) {
QBasicMutexLocker locker(signalSlotLock(this));
d_func()->ensureConnectionData();
}
@@ -1282,7 +1287,7 @@ bool QObject::event(QEvent *e)
case QEvent::ThreadChange: {
Q_D(QObject);
QThreadData *threadData = d->threadData;
- QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.loadRelaxed();
if (eventDispatcher) {
QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(this);
if (!timers.isEmpty()) {
@@ -1448,7 +1453,7 @@ bool QObject::blockSignals(bool block) noexcept
*/
QThread *QObject::thread() const
{
- return d_func()->threadData->thread;
+ return d_func()->threadData->thread.loadAcquire();
}
/*!
@@ -1495,7 +1500,7 @@ void QObject::moveToThread(QThread *targetThread)
{
Q_D(QObject);
- if (d->threadData->thread == targetThread) {
+ if (d->threadData->thread.loadAcquire() == targetThread) {
// object is already in this thread
return;
}
@@ -1511,13 +1516,13 @@ void QObject::moveToThread(QThread *targetThread)
QThreadData *currentData = QThreadData::current();
QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
- if (d->threadData->thread == 0 && currentData == targetData) {
+ if (d->threadData->thread.loadAcquire() == 0 && currentData == targetData) {
// one exception to the rule: we allow moving objects with no thread affinity to the current thread
currentData = d->threadData;
} else if (d->threadData != currentData) {
qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n"
"Cannot move to target thread (%p)\n",
- currentData->thread.load(), d->threadData->thread.load(), targetData ? targetData->thread.load() : nullptr);
+ currentData->thread.loadRelaxed(), d->threadData->thread.loadRelaxed(), targetData ? targetData->thread.loadRelaxed() : nullptr);
#ifdef Q_OS_MAC
qWarning("You might be loading two sets of Qt binaries into the same process. "
@@ -1582,11 +1587,11 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
}
if (eventsMoved > 0 && targetData->hasEventDispatcher()) {
targetData->canWait = false;
- targetData->eventDispatcher.load()->wakeUp();
+ targetData->eventDispatcher.loadRelaxed()->wakeUp();
}
// the current emitting thread shouldn't restore currentSender after calling moveToThread()
- ConnectionData *cd = connections.load();
+ ConnectionData *cd = connections.loadRelaxed();
if (cd) {
if (cd->currentSender) {
cd->currentSender->receiverDeleted();
@@ -1597,14 +1602,14 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
if (cd) {
auto *c = cd->senders;
while (c) {
- QObject *r = c->receiver.load();
+ QObject *r = c->receiver.loadRelaxed();
if (r) {
Q_ASSERT(r == q);
targetData->ref();
- QThreadData *old = c->receiverThreadData.load();
+ QThreadData *old = c->receiverThreadData.loadRelaxed();
if (old)
old->deref();
- c->receiverThreadData.store(targetData);
+ c->receiverThreadData.storeRelaxed(targetData);
}
c = c->next;
}
@@ -1627,7 +1632,7 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer)
{
Q_Q(QObject);
QList<QAbstractEventDispatcher::TimerInfo> *timerList = reinterpret_cast<QList<QAbstractEventDispatcher::TimerInfo> *>(pointer);
- QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.loadRelaxed();
for (int i = 0; i < timerList->size(); ++i) {
const QAbstractEventDispatcher::TimerInfo &ti = timerList->at(i);
eventDispatcher->registerTimer(ti.timerId, ti.interval, ti.timerType, q);
@@ -1693,7 +1698,7 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
qWarning("QObject::startTimer: Timers cannot be started from another thread");
return 0;
}
- int timerId = d->threadData->eventDispatcher.load()->registerTimer(interval, timerType, this);
+ int timerId = d->threadData->eventDispatcher.loadRelaxed()->registerTimer(interval, timerType, this);
if (!d->extraData)
d->extraData = new QObjectPrivate::ExtraData;
d->extraData->runningTimers.append(timerId);
@@ -1768,7 +1773,7 @@ void QObject::killTimer(int id)
}
if (d->threadData->hasEventDispatcher())
- d->threadData->eventDispatcher.load()->unregisterTimer(id);
+ d->threadData->eventDispatcher.loadRelaxed()->unregisterTimer(id);
d->extraData->runningTimers.remove(at);
QAbstractEventDispatcherPrivate::releaseTimerId(id);
@@ -2069,8 +2074,25 @@ void QObjectPrivate::deleteChildren()
void QObjectPrivate::setParent_helper(QObject *o)
{
Q_Q(QObject);
+ Q_ASSERT_X(q != o, Q_FUNC_INFO, "Cannot parent a QObject to itself");
+#ifdef QT_DEBUG
+ const auto checkForParentChildLoops = qScopeGuard([&](){
+ int depth = 0;
+ auto p = parent;
+ while (p) {
+ if (++depth == CheckForParentChildLoopsWarnDepth) {
+ qWarning("QObject %p (class: '%s', object name: '%s') may have a loop in its parent-child chain; "
+ "this is undefined behavior",
+ q, q->metaObject()->className(), qPrintable(q->objectName()));
+ }
+ p = p->parent();
+ }
+ });
+#endif
+
if (o == parent)
return;
+
if (parent) {
QObjectPrivate *parentD = parent->d_func();
if (parentD->isDeletingChildren && wasDeleted
@@ -2210,6 +2232,8 @@ void QObject::removeEventFilter(QObject *obj)
*/
/*!
+ \threadsafe
+
Schedules this object for deletion.
The object will be deleted when control returns to the event
@@ -2420,7 +2444,7 @@ QObject *QObject::sender() const
Q_D(const QObject);
QBasicMutexLocker locker(signalSlotLock(this));
- QObjectPrivate::ConnectionData *cd = d->connections.load();
+ QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
if (!cd || !cd->currentSender)
return nullptr;
@@ -2462,7 +2486,7 @@ int QObject::senderSignalIndex() const
Q_D(const QObject);
QBasicMutexLocker locker(signalSlotLock(this));
- QObjectPrivate::ConnectionData *cd = d->connections.load();
+ QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
if (!cd || !cd->currentSender)
return -1;
@@ -2525,13 +2549,13 @@ int QObject::receivers(const char *signal) const
signal_index);
}
- QObjectPrivate::ConnectionData *cd = d->connections.load();
+ QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
QBasicMutexLocker locker(signalSlotLock(this));
if (cd && signal_index < cd->signalVectorCount()) {
- const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
+ const QObjectPrivate::Connection *c = cd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed();
while (c) {
- receivers += c->receiver.load() ? 1 : 0;
- c = c->nextConnectionList.load();
+ receivers += c->receiver.loadRelaxed() ? 1 : 0;
+ c = c->nextConnectionList.loadRelaxed();
}
}
}
@@ -3340,17 +3364,17 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
- QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load();
+ QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.loadRelaxed();
if (type & Qt::UniqueConnection && scd) {
if (scd->signalVectorCount() > signal_index) {
- const QObjectPrivate::Connection *c2 = scd->signalVector.load()->at(signal_index).first.load();
+ const QObjectPrivate::Connection *c2 = scd->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed();
int method_index_absolute = method_index + method_offset;
while (c2) {
- if (!c2->isSlotObject && c2->receiver.load() == receiver && c2->method() == method_index_absolute)
+ if (!c2->isSlotObject && c2->receiver.loadRelaxed() == receiver && c2->method() == method_index_absolute)
return nullptr;
- c2 = c2->nextConnectionList.load();
+ c2 = c2->nextConnectionList.loadRelaxed();
}
}
type &= Qt::UniqueConnection - 1;
@@ -3359,15 +3383,15 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
c->sender = s;
c->signal_index = signal_index;
- c->receiver.store(r);
+ c->receiver.storeRelaxed(r);
QThreadData *td = r->d_func()->threadData;
td->ref();
- c->receiverThreadData.store(td);
+ c->receiverThreadData.storeRelaxed(td);
c->method_relative = method_index;
c->method_offset = method_offset;
c->connectionType = type;
c->isSlotObject = false;
- c->argumentTypes.store(types);
+ c->argumentTypes.storeRelaxed(types);
c->callFunction = callFunction;
QObjectPrivate::get(s)->addConnection(signal_index, c.data());
@@ -3420,9 +3444,9 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connec
bool success = false;
auto &connectionList = connections->connectionsForSignal(signalIndex);
- auto *c = connectionList.first.load();
+ auto *c = connectionList.first.loadRelaxed();
while (c) {
- QObject *r = c->receiver.load();
+ QObject *r = c->receiver.loadRelaxed();
if (r && (receiver == nullptr || (r == receiver
&& (method_index < 0 || (!c->isSlotObject && c->method() == method_index))
&& (slot == nullptr || (c->isSlotObject && c->slotObj->compare(slot)))))) {
@@ -3433,7 +3457,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connec
// need to relock this receiver and sender in the correct order
needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
}
- if (c->receiver.load())
+ if (c->receiver.loadRelaxed())
connections->removeConnection(c);
if (needToUnlock)
@@ -3444,7 +3468,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connec
if (disconnectType == DisconnectOne)
return success;
}
- c = c->nextConnectionList.load();
+ c = c->nextConnectionList.loadRelaxed();
}
return success;
}
@@ -3466,7 +3490,7 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender,
QBasicMutex *senderMutex = signalSlotLock(sender);
QBasicMutexLocker locker(senderMutex);
- QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load();
+ QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.loadRelaxed();
if (!scd)
return false;
@@ -3608,7 +3632,7 @@ void QMetaObject::connectSlotsByName(QObject *o)
*/
static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
{
- const int *argumentTypes = c->argumentTypes.load();
+ const int *argumentTypes = c->argumentTypes.loadRelaxed();
if (!argumentTypes) {
QMetaMethod m = QMetaObjectPrivate::signal(sender->metaObject(), signal);
argumentTypes = queuedConnectionTypes(m.parameterTypes());
@@ -3617,7 +3641,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) {
if (argumentTypes != &DIRECT_CONNECTION_ONLY)
delete [] argumentTypes;
- argumentTypes = c->argumentTypes.load();
+ argumentTypes = c->argumentTypes.loadRelaxed();
}
}
if (argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
@@ -3640,8 +3664,8 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
args[n] = QMetaType::create(types[n], argv[n]);
}
- QBasicMutexLocker locker(signalSlotLock(c->receiver.load()));
- if (!c->receiver.load()) {
+ QBasicMutexLocker locker(signalSlotLock(c->receiver.loadRelaxed()));
+ if (!c->receiver.loadRelaxed()) {
// the connection has been disconnected before we got the lock
locker.unlock();
for (int n = 1; n < nargs; ++n)
@@ -3654,7 +3678,7 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
QMetaCallEvent *ev = c->isSlotObject ?
new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
- QCoreApplication::postEvent(c->receiver.load(), ev);
+ QCoreApplication::postEvent(c->receiver.loadRelaxed(), ev);
}
template <bool callbacks_enabled>
@@ -3674,7 +3698,7 @@ void doActivate(QObject *sender, int signal_index, void **argv)
signal_index, argv);
}
- const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.load() : nullptr;
+ const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.loadAcquire() : nullptr;
void *empty_argv[] = { nullptr };
if (!argv)
@@ -3694,9 +3718,9 @@ void doActivate(QObject *sender, int signal_index, void **argv)
bool senderDeleted = false;
{
- Q_ASSERT(sp->connections);
- QObjectPrivate::ConnectionDataPointer connections(sp->connections.load());
- QObjectPrivate::SignalVector *signalVector = connections->signalVector.load();
+ Q_ASSERT(sp->connections.loadAcquire());
+ QObjectPrivate::ConnectionDataPointer connections(sp->connections.loadRelaxed());
+ QObjectPrivate::SignalVector *signalVector = connections->signalVector.loadRelaxed();
const QObjectPrivate::ConnectionList *list;
if (signal_index < signalVector->count())
@@ -3705,32 +3729,32 @@ void doActivate(QObject *sender, int signal_index, void **argv)
list = &signalVector->at(-1);
Qt::HANDLE currentThreadId = QThread::currentThreadId();
- bool inSenderThread = currentThreadId == QObjectPrivate::get(sender)->threadData->threadId.load();
+ bool inSenderThread = currentThreadId == QObjectPrivate::get(sender)->threadData->threadId.loadRelaxed();
// We need to check against the highest connection id to ensure that signals added
// during the signal emission are not emitted in this emission.
- uint highestConnectionId = connections->currentConnectionId.load();
+ uint highestConnectionId = connections->currentConnectionId.loadRelaxed();
do {
- QObjectPrivate::Connection *c = list->first.load();
+ QObjectPrivate::Connection *c = list->first.loadRelaxed();
if (!c)
continue;
do {
- QObject * const receiver = c->receiver.load();
+ QObject * const receiver = c->receiver.loadRelaxed();
if (!receiver)
continue;
- QThreadData *td = c->receiverThreadData.load();
+ QThreadData *td = c->receiverThreadData.loadRelaxed();
if (!td)
continue;
bool receiverInSameThread;
if (inSenderThread) {
- receiverInSameThread = currentThreadId == td->threadId.load();
+ receiverInSameThread = currentThreadId == td->threadId.loadRelaxed();
} else {
// need to lock before reading the threadId, because moveToThread() could interfere
QMutexLocker lock(signalSlotLock(receiver));
- receiverInSameThread = currentThreadId == td->threadId.load();
+ receiverInSameThread = currentThreadId == td->threadId.loadRelaxed();
}
@@ -3751,7 +3775,7 @@ void doActivate(QObject *sender, int signal_index, void **argv)
QSemaphore semaphore;
{
QBasicMutexLocker locker(signalSlotLock(sender));
- if (!c->receiver)
+ if (!c->receiver.loadAcquire())
continue;
QMetaCallEvent *ev = c->isSlotObject ?
new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv, &semaphore) :
@@ -3803,17 +3827,17 @@ void doActivate(QObject *sender, int signal_index, void **argv)
if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr)
signal_spy_set->slot_end_callback(receiver, method);
}
- } while ((c = c->nextConnectionList.load()) != nullptr && c->id <= highestConnectionId);
+ } while ((c = c->nextConnectionList.loadRelaxed()) != nullptr && c->id <= highestConnectionId);
} while (list != &signalVector->at(-1) &&
//start over for all signals;
((list = &signalVector->at(-1)), true));
- if (connections->currentConnectionId.load() == 0)
+ if (connections->currentConnectionId.loadRelaxed() == 0)
senderDeleted = true;
}
if (!senderDeleted)
- sp->connections.load()->cleanOrphanedConnections(sender);
+ sp->connections.loadRelaxed()->cleanOrphanedConnections(sender);
if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
signal_spy_set->signal_end_callback(sender, signal_index);
@@ -3827,7 +3851,7 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
{
int signal_index = local_signal_index + QMetaObjectPrivate::signalOffset(m);
- if (Q_UNLIKELY(qt_signal_spy_callback_set.load()))
+ if (Q_UNLIKELY(qt_signal_spy_callback_set.loadRelaxed()))
doActivate<true>(sender, signal_index, argv);
else
doActivate<false>(sender, signal_index, argv);
@@ -3840,7 +3864,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
{
int signal_index = signalOffset + local_signal_index;
- if (Q_UNLIKELY(qt_signal_spy_callback_set.load()))
+ if (Q_UNLIKELY(qt_signal_spy_callback_set.loadRelaxed()))
doActivate<true>(sender, signal_index, argv);
else
doActivate<false>(sender, signal_index, argv);
@@ -4109,11 +4133,11 @@ void QObject::dumpObjectInfo() const
// first, look for connections where this object is the sender
qDebug(" SIGNALS OUT");
- QObjectPrivate::ConnectionData *cd = d->connections.load();
+ QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed();
if (cd && cd->signalVectorCount()) {
- QObjectPrivate::SignalVector *signalVector = cd->signalVector.load();
+ QObjectPrivate::SignalVector *signalVector = cd->signalVector.loadRelaxed();
for (int signal_index = 0; signal_index < signalVector->count(); ++signal_index) {
- const QObjectPrivate::Connection *c = signalVector->at(signal_index).first.load();
+ const QObjectPrivate::Connection *c = signalVector->at(signal_index).first.loadRelaxed();
if (!c)
continue;
const QMetaMethod signal = QMetaObjectPrivate::signal(metaObject(), signal_index);
@@ -4121,23 +4145,23 @@ void QObject::dumpObjectInfo() const
// receivers
while (c) {
- if (!c->receiver.load()) {
+ if (!c->receiver.loadRelaxed()) {
qDebug(" <Disconnected receiver>");
- c = c->nextConnectionList.load();
+ c = c->nextConnectionList.loadRelaxed();
continue;
}
if (c->isSlotObject) {
qDebug(" <functor or function pointer>");
- c = c->nextConnectionList.load();
+ c = c->nextConnectionList.loadRelaxed();
continue;
}
- const QMetaObject *receiverMetaObject = c->receiver.load()->metaObject();
+ const QMetaObject *receiverMetaObject = c->receiver.loadRelaxed()->metaObject();
const QMetaMethod method = receiverMetaObject->method(c->method());
qDebug(" --> %s::%s %s",
receiverMetaObject->className(),
- c->receiver.load()->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver.load()->objectName()),
+ c->receiver.loadRelaxed()->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver.loadRelaxed()->objectName()),
method.methodSignature().constData());
- c = c->nextConnectionList.load();
+ c = c->nextConnectionList.loadRelaxed();
}
}
} else {
@@ -4165,13 +4189,14 @@ void QObject::dumpObjectInfo() const
}
#ifndef QT_NO_USERDATA
+static QBasicAtomicInteger<uint> user_data_registration = Q_BASIC_ATOMIC_INITIALIZER(0);
+
/*!
\internal
*/
uint QObject::registerUserData()
{
- static int user_data_registration = 0;
- return user_data_registration++;
+ return user_data_registration.fetchAndAddRelaxed(1);
}
/*!
@@ -4504,6 +4529,24 @@ QDebug operator<<(QDebug dbg, const QObject *o)
Q_NAMESPACE makes an external variable, \c{staticMetaObject}, available.
\c{staticMetaObject} is of type QMetaObject and provides access to the
enums declared with Q_ENUM_NS/Q_FLAG_NS.
+
+ \sa Q_NAMESPACE_EXPORT
+*/
+
+/*!
+ \macro Q_NAMESPACE_EXPORT(EXPORT_MACRO)
+ \relates QObject
+ \since 5.14
+
+ The Q_NAMESPACE_EXPORT macro can be used to add QMetaObject capabilities
+ to a namespace.
+
+ It works exactly like the Q_NAMESPACE macro. However, the external
+ \c{staticMetaObject} variable that gets defined in the namespace
+ is declared with the supplied \c{EXPORT_MACRO} qualifier. This is
+ useful f.i. if the object needs to be exported from a dynamic library.
+
+ \sa Q_NAMESPACE, {Creating Shared Libraries}
*/
/*!
@@ -4888,17 +4931,17 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
- if (type & Qt::UniqueConnection && slot && QObjectPrivate::get(s)->connections.load()) {
- QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(s)->connections.load();
+ if (type & Qt::UniqueConnection && slot && QObjectPrivate::get(s)->connections.loadRelaxed()) {
+ QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(s)->connections.loadRelaxed();
if (connections->signalVectorCount() > signal_index) {
- const QObjectPrivate::Connection *c2 = connections->signalVector.load()->at(signal_index).first.load();
+ const QObjectPrivate::Connection *c2 = connections->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed();
while (c2) {
- if (c2->receiver.load() == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
+ if (c2->receiver.loadRelaxed() == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
}
- c2 = c2->nextConnectionList.load();
+ c2 = c2->nextConnectionList.loadRelaxed();
}
}
type = static_cast<Qt::ConnectionType>(type ^ Qt::UniqueConnection);
@@ -4909,13 +4952,13 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
c->signal_index = signal_index;
QThreadData *td = r->d_func()->threadData;
td->ref();
- c->receiverThreadData.store(td);
- c->receiver.store(r);
+ c->receiverThreadData.storeRelaxed(td);
+ c->receiver.storeRelaxed(r);
c->slotObj = slotObj;
c->connectionType = type;
c->isSlotObject = true;
if (types) {
- c->argumentTypes.store(types);
+ c->argumentTypes.storeRelaxed(types);
c->ownArgumentTypes = false;
}
@@ -4944,7 +4987,7 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
if (!c)
return false;
- QObject *receiver = c->receiver.load();
+ QObject *receiver = c->receiver.loadRelaxed();
if (!receiver)
return false;
@@ -4956,11 +4999,11 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
QOrderedMutexLocker locker(senderMutex, receiverMutex);
// load receiver once again and recheck to ensure nobody else has removed the connection in the meantime
- receiver = c->receiver.load();
+ receiver = c->receiver.loadRelaxed();
if (!receiver)
return false;
- connections = QObjectPrivate::get(c->sender)->connections.load();
+ connections = QObjectPrivate::get(c->sender)->connections.loadRelaxed();
Q_ASSERT(connections);
connections->removeConnection(c);
}
@@ -5152,7 +5195,7 @@ bool QMetaObject::Connection::isConnected_helper() const
Q_ASSERT(d_ptr); // we're only called from operator RestrictedBool() const
QObjectPrivate::Connection *c = static_cast<QObjectPrivate::Connection *>(d_ptr);
- return c->receiver.load();
+ return c->receiver.loadRelaxed();
}
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 12512e74c5..540b8b32c1 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -71,12 +71,16 @@ class QObjectPrivate;
class QObject;
class QThread;
class QWidget;
+class QAccessibleWidget;
#ifndef QT_NO_REGEXP
class QRegExp;
#endif
#if QT_CONFIG(regularexpression)
class QRegularExpression;
#endif
+#if !QT_DEPRECATED_SINCE(5, 14) || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+# define QT_NO_USERDATA
+#endif
#ifndef QT_NO_USERDATA
class QObjectUserData;
#endif
@@ -113,12 +117,17 @@ public:
int postedEvents;
QDynamicMetaObjectData *metaObject;
QMetaObject *dynamicMetaObject() const;
+
+#ifdef QT_DEBUG
+ enum { CheckForParentChildLoopsWarnDepth = 4096 };
+#endif
};
class Q_CORE_EXPORT QObject
{
Q_OBJECT
+
Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged)
Q_DECLARE_PRIVATE(QObject)
@@ -129,7 +138,7 @@ public:
virtual bool event(QEvent *event);
virtual bool eventFilter(QObject *watched, QEvent *event);
-#if defined(QT_NO_TRANSLATION)
+#if defined(QT_NO_TRANSLATION) || defined(Q_CLANG_QDOC)
static QString tr(const char *sourceText, const char * = nullptr, int = -1)
{ return QString::fromUtf8(sourceText); }
#if QT_DEPRECATED_SINCE(5, 0)
@@ -400,8 +409,11 @@ public:
#endif // QT_NO_PROPERTIES
#ifndef QT_NO_USERDATA
+ QT_DEPRECATED_VERSION_5_14
static uint registerUserData();
+ QT_DEPRECATED_VERSION_X_5_14("Use setProperty()")
void setUserData(uint id, QObjectUserData* data);
+ QT_DEPRECATED_VERSION_X_5_14("Use property()")
QObjectUserData* userData(uint id) const;
#endif // QT_NO_USERDATA
@@ -448,6 +460,7 @@ protected:
friend class QCoreApplication;
friend class QCoreApplicationPrivate;
friend class QWidget;
+ friend class QAccessibleWidget;
friend class QThreadData;
private:
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index e6e57b29b9..9cf1bfed08 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -184,7 +184,7 @@ public:
}
void deref() {
if (!ref_.deref()) {
- Q_ASSERT(!receiver.load());
+ Q_ASSERT(!receiver.loadRelaxed());
Q_ASSERT(!isSlotObject);
delete this;
}
@@ -202,7 +202,7 @@ public:
: receiver(receiver), sender(sender), signal(signal)
{
if (receiver) {
- ConnectionData *cd = receiver->d_func()->connections.load();
+ ConnectionData *cd = receiver->d_func()->connections.loadRelaxed();
previous = cd->currentSender;
cd->currentSender = this;
}
@@ -210,7 +210,7 @@ public:
~Sender()
{
if (receiver)
- receiver->d_func()->connections.load()->currentSender = previous;
+ receiver->d_func()->connections.loadRelaxed()->currentSender = previous;
}
void receiverDeleted()
{
@@ -268,8 +268,8 @@ public:
~ConnectionData()
{
- deleteOrphaned(orphaned.load());
- SignalVector *v = signalVector.load();
+ deleteOrphaned(orphaned.loadRelaxed());
+ SignalVector *v = signalVector.loadRelaxed();
if (v)
free(v);
}
@@ -279,18 +279,18 @@ public:
void removeConnection(Connection *c);
void cleanOrphanedConnections(QObject *sender)
{
- if (orphaned.load() && ref == 1)
+ if (orphaned.loadRelaxed() && ref.loadAcquire() == 1)
cleanOrphanedConnectionsImpl(sender);
}
void cleanOrphanedConnectionsImpl(QObject *sender);
ConnectionList &connectionsForSignal(int signal)
{
- return signalVector.load()->at(signal);
+ return signalVector.loadRelaxed()->at(signal);
}
void resizeSignalVector(uint size) {
- SignalVector *vector = this->signalVector.load();
+ SignalVector *vector = this->signalVector.loadRelaxed();
if (vector && vector->allocated > size)
return;
size = (size + 7) & ~7;
@@ -305,14 +305,14 @@ public:
newVector->next = nullptr;
newVector->allocated = size;
- signalVector.store(newVector);
+ signalVector.storeRelaxed(newVector);
if (vector) {
- vector->nextInOrphanList = orphaned.load();
- orphaned.store(ConnectionOrSignalVector::fromSignalVector(vector));
+ vector->nextInOrphanList = orphaned.loadRelaxed();
+ orphaned.storeRelaxed(ConnectionOrSignalVector::fromSignalVector(vector));
}
}
int signalVectorCount() const {
- return signalVector ? signalVector.load()->count() : -1;
+ return signalVector.loadAcquire() ? signalVector.loadRelaxed()->count() : -1;
}
static void deleteOrphaned(ConnectionOrSignalVector *c);
@@ -366,11 +366,11 @@ public:
void ensureConnectionData()
{
- if (connections.load())
+ if (connections.loadRelaxed())
return;
ConnectionData *cd = new ConnectionData;
cd->ref.ref();
- connections.store(cd);
+ connections.storeRelaxed(cd);
}
public:
ExtraData *extraData; // extra data set by the user
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 0bceab6fb4..ef22b6e67f 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -138,6 +138,10 @@ class QString;
# define QT_TR_FUNCTIONS
#endif
+#ifdef Q_CLANG_QDOC
+#define QT_TR_FUNCTIONS
+#endif
+
// ### Qt6: remove
#define Q_OBJECT_CHECK /* empty, unused since Qt 5.2 */
@@ -197,12 +201,16 @@ private: \
QT_ANNOTATE_CLASS(qt_qgadget, "") \
/*end*/
-/* qmake ignore Q_NAMESPACE */
-#define Q_NAMESPACE \
- extern const QMetaObject staticMetaObject; \
+/* qmake ignore Q_NAMESPACE_EXPORT */
+#define Q_NAMESPACE_EXPORT(...) \
+ extern __VA_ARGS__ const QMetaObject staticMetaObject; \
QT_ANNOTATE_CLASS(qt_qnamespace, "") \
/*end*/
+/* qmake ignore Q_NAMESPACE */
+#define Q_NAMESPACE Q_NAMESPACE_EXPORT() \
+ /*end*/
+
#endif // QT_NO_META_MACROS
#else // Q_MOC_RUN
diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h
index 80faef2990..7052bcf0d4 100644
--- a/src/corelib/kernel/qpointer.h
+++ b/src/corelib/kernel/qpointer.h
@@ -143,7 +143,8 @@ template<typename T>
QPointer<T>
qPointerFromVariant(const QVariant &variant)
{
- return QPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).internalData()));
+ const auto wp = QtSharedPointer::weakPointerFromVariant_internal(variant);
+ return QPointer<T>{qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(wp))};
}
template <class T>
diff --git a/src/corelib/kernel/qpoll.cpp b/src/corelib/kernel/qpoll.cpp
index 8e93c4d363..8b87bfe79d 100644
--- a/src/corelib/kernel/qpoll.cpp
+++ b/src/corelib/kernel/qpoll.cpp
@@ -39,6 +39,10 @@
#include "qcore_unix_p.h"
+#ifdef Q_OS_RTEMS
+#include <rtems/rtems_bsdnet_internal.h>
+#endif
+
QT_BEGIN_NAMESPACE
#define QT_POLL_READ_MASK (POLLIN | POLLRDNORM)
@@ -135,6 +139,11 @@ static inline int qt_poll_sweep(struct pollfd *fds, nfds_t nfds,
static inline bool qt_poll_is_bad_fd(int fd)
{
+#ifdef Q_OS_RTEMS
+ if (!rtems_bsdnet_fdToSocket(fd))
+ return true;
+#endif
+
int ret;
EINTR_LOOP(ret, fcntl(fd, F_GETFD));
return (ret == -1 && errno == EBADF);
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index c952655cb8..39f3002394 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -150,11 +150,18 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
\sa setKey()
*/
+
+#ifndef QT_NO_QOBJECT
QSharedMemory::QSharedMemory(QObject *parent)
: QObject(*new QSharedMemoryPrivate, parent)
{
}
-
+#else
+QSharedMemory::QSharedMemory()
+ : d_ptr(new QSharedMemoryPrivate)
+{
+}
+#endif
/*!
Constructs a shared memory object with the given \a parent and with
its key set to \a key. Because its key is set, its create() and
@@ -162,11 +169,19 @@ QSharedMemory::QSharedMemory(QObject *parent)
\sa setKey(), create(), attach()
*/
+#ifndef QT_NO_QOBJECT
QSharedMemory::QSharedMemory(const QString &key, QObject *parent)
: QObject(*new QSharedMemoryPrivate, parent)
{
setKey(key);
}
+#else
+QSharedMemory::QSharedMemory(const QString &key)
+ : d_ptr(new QSharedMemoryPrivate)
+{
+ setKey(key);
+}
+#endif
/*!
The destructor clears the key, which forces the shared memory object
@@ -604,4 +619,6 @@ QString QSharedMemory::errorString() const
QT_END_NAMESPACE
+#ifndef QT_NO_QOBJECT
#include "moc_qsharedmemory.cpp"
+#endif
diff --git a/src/corelib/kernel/qsharedmemory.h b/src/corelib/kernel/qsharedmemory.h
index 67cf52ac17..6236c6aa4c 100644
--- a/src/corelib/kernel/qsharedmemory.h
+++ b/src/corelib/kernel/qsharedmemory.h
@@ -40,8 +40,14 @@
#ifndef QSHAREDMEMORY_H
#define QSHAREDMEMORY_H
-#include <QtCore/qobject.h>
-
+#include <QtCore/qglobal.h>
+#ifndef QT_NO_QOBJECT
+# include <QtCore/qobject.h>
+#else
+# include <QtCore/qobjectdefs.h>
+# include <QtCore/qscopedpointer.h>
+# include <QtCore/qstring.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -49,9 +55,14 @@ QT_BEGIN_NAMESPACE
class QSharedMemoryPrivate;
-class Q_CORE_EXPORT QSharedMemory : public QObject
+class Q_CORE_EXPORT QSharedMemory
+#ifndef QT_NO_QOBJECT
+ : public QObject
+#endif
{
+#ifndef QT_NO_QOBJECT
Q_OBJECT
+#endif
Q_DECLARE_PRIVATE(QSharedMemory)
public:
@@ -74,8 +85,17 @@ public:
UnknownError
};
+#ifndef QT_NO_QOBJECT
QSharedMemory(QObject *parent = nullptr);
QSharedMemory(const QString &key, QObject *parent = nullptr);
+#else
+ QSharedMemory();
+ QSharedMemory(const QString &key);
+ static QString tr(const char * str)
+ {
+ return QString::fromLatin1(str);
+ }
+#endif
~QSharedMemory();
void setKey(const QString &key);
@@ -104,6 +124,9 @@ public:
private:
Q_DISABLE_COPY(QSharedMemory)
+#ifdef QT_NO_QOBJECT
+ QScopedPointer<QSharedMemoryPrivate> d_ptr;
+#endif
};
#endif // QT_NO_SHAREDMEMORY
diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h
index bf7c42dc62..e6e989abda 100644
--- a/src/corelib/kernel/qsharedmemory_p.h
+++ b/src/corelib/kernel/qsharedmemory_p.h
@@ -67,7 +67,10 @@ namespace QSharedMemoryPrivate
#else
#include "qsystemsemaphore.h"
-#include "private/qobject_p.h"
+
+#ifndef QT_NO_QOBJECT
+# include "private/qobject_p.h"
+#endif
#if !defined(Q_OS_WIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_RTEMS)
# include <sys/sem.h>
@@ -107,9 +110,14 @@ private:
};
#endif // QT_NO_SYSTEMSEMAPHORE
-class Q_AUTOTEST_EXPORT QSharedMemoryPrivate : public QObjectPrivate
+class Q_AUTOTEST_EXPORT QSharedMemoryPrivate
+#ifndef QT_NO_QOBJECT
+ : public QObjectPrivate
+#endif
{
+#ifndef QT_NO_QOBJECT
Q_DECLARE_PUBLIC(QSharedMemory)
+#endif
public:
QSharedMemoryPrivate();
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index d1d44747e0..f6d7e78441 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -64,8 +64,11 @@
#ifndef QT_NO_SHAREDMEMORY
QT_BEGIN_NAMESPACE
-QSharedMemoryPrivate::QSharedMemoryPrivate()
- : QObjectPrivate(), memory(0), size(0), error(QSharedMemory::NoError),
+QSharedMemoryPrivate::QSharedMemoryPrivate() :
+#ifndef QT_NO_QOBJECT
+ QObjectPrivate(),
+#endif
+ memory(0), size(0), error(QSharedMemory::NoError),
#ifndef QT_NO_SYSTEMSEMAPHORE
systemSemaphore(QString()), lockedByMe(false),
#endif
diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp
index c1dba30e2b..02de2339a5 100644
--- a/src/corelib/kernel/qsharedmemory_win.cpp
+++ b/src/corelib/kernel/qsharedmemory_win.cpp
@@ -47,7 +47,10 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_SHAREDMEMORY
-QSharedMemoryPrivate::QSharedMemoryPrivate() : QObjectPrivate(),
+QSharedMemoryPrivate::QSharedMemoryPrivate() :
+#ifndef QT_NO_QOBJECT
+ QObjectPrivate(),
+#endif
memory(0), size(0), error(QSharedMemory::NoError),
systemSemaphore(QString()), lockedByMe(false), hand(0)
{
diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp
index 6ff8268978..2a246b1204 100644
--- a/src/corelib/kernel/qsocketnotifier.cpp
+++ b/src/corelib/kernel/qsocketnotifier.cpp
@@ -152,7 +152,7 @@ QSocketNotifier::QSocketNotifier(qintptr socket, Type type, QObject *parent)
else if (!d->threadData->hasEventDispatcher())
qWarning("QSocketNotifier: Can only be used with threads started with QThread");
else
- d->threadData->eventDispatcher.load()->registerSocketNotifier(this);
+ d->threadData->eventDispatcher.loadRelaxed()->registerSocketNotifier(this);
}
/*!
@@ -241,9 +241,9 @@ void QSocketNotifier::setEnabled(bool enable)
return;
}
if (d->snenabled)
- d->threadData->eventDispatcher.load()->registerSocketNotifier(this);
+ d->threadData->eventDispatcher.loadRelaxed()->registerSocketNotifier(this);
else
- d->threadData->eventDispatcher.load()->unregisterSocketNotifier(this);
+ d->threadData->eventDispatcher.loadRelaxed()->unregisterSocketNotifier(this);
}
diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp
index 9d0394e4a5..a735e12925 100644
--- a/src/corelib/kernel/qsystemerror.cpp
+++ b/src/corelib/kernel/qsystemerror.cpp
@@ -112,7 +112,7 @@ static QString windowsErrorString(int errorCode)
static QString standardLibraryErrorString(int errorCode)
{
- const char *s = 0;
+ const char *s = nullptr;
QString ret;
switch (errorCode) {
case 0:
diff --git a/src/corelib/kernel/qsystemsemaphore_systemv.cpp b/src/corelib/kernel/qsystemsemaphore_systemv.cpp
index 9e438ae2a6..2c38d74d2d 100644
--- a/src/corelib/kernel/qsystemsemaphore_systemv.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_systemv.cpp
@@ -76,7 +76,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
#if QT_CONFIG(translation)
QCoreApplication::tr("%1: key is empty", "QSystemSemaphore")
#else
- QString::fromLatin1("%1: key is empty")
+ QLatin1String("%1: key is empty")
#endif
.arg(QLatin1String("QSystemSemaphore::handle:"));
error = QSystemSemaphore::KeyError;
@@ -94,7 +94,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
#if QT_CONFIG(translation)
QCoreApplication::tr("%1: unable to make key", "QSystemSemaphore")
#else
- QString::fromLatin1("%1: unable to make key")
+ QLatin1String("%1: unable to make key")
#endif
.arg(QLatin1String("QSystemSemaphore::handle:"));
error = QSystemSemaphore::KeyError;
@@ -111,7 +111,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
#if QT_CONFIG(translation)
QCoreApplication::tr("%1: ftok failed", "QSystemSemaphore")
#else
- QString::fromLatin1("%1: ftok failed")
+ QLatin1String("%1: ftok failed")
#endif
.arg(QLatin1String("QSystemSemaphore::handle:"));
error = QSystemSemaphore::KeyError;
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index dc0ab9f08a..637ef84d21 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -948,11 +948,8 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
end:
if (!tn)
return QString();
- QString str = QString((const QChar *)tn, tn_length/2);
- if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
- QChar *data = str.data();
- qbswap<sizeof(QChar)>(data, str.length(), data);
- }
+ QString str(tn_length / 2, Qt::Uninitialized);
+ qFromBigEndian<ushort>(tn, str.length(), str.data());
return str;
}
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 0ecd17df09..1cd812ee0b 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -119,19 +119,19 @@ namespace { // annonymous used to hide QVariant handlers
static void construct(QVariant::Private *x, const void *copy)
{
QVariantConstructor<CoreTypesFilter> constructor(x, copy);
- QMetaTypeSwitcher::switcher<void>(constructor, x->type, 0);
+ QMetaTypeSwitcher::switcher<void>(constructor, x->type);
}
static void clear(QVariant::Private *d)
{
QVariantDestructor<CoreTypesFilter> cleaner(d);
- QMetaTypeSwitcher::switcher<void>(cleaner, d->type, 0);
+ QMetaTypeSwitcher::switcher<void>(cleaner, d->type);
}
static bool isNull(const QVariant::Private *d)
{
QVariantIsNull<CoreTypesFilter> isNull(d);
- return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, 0);
+ return QMetaTypeSwitcher::switcher<bool>(isNull, d->type);
}
/*!
@@ -143,7 +143,7 @@ static bool isNull(const QVariant::Private *d)
static bool compare(const QVariant::Private *a, const QVariant::Private *b)
{
QVariantComparator<CoreTypesFilter> comparator(a, b);
- return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, 0);
+ return QMetaTypeSwitcher::switcher<bool>(comparator, a->type);
}
/*!
@@ -1401,7 +1401,7 @@ static void streamDebug(QDebug dbg, const QVariant &v)
{
QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
QVariantDebugStream<CoreTypesFilter> stream(dbg, d);
- QMetaTypeSwitcher::switcher<void>(stream, d->type, 0);
+ QMetaTypeSwitcher::switcher<void>(stream, d->type);
}
#endif
@@ -1410,16 +1410,16 @@ const QVariant::Handler qt_kernel_variant_handler = {
clear,
isNull,
#ifndef QT_NO_DATASTREAM
- 0,
- 0,
+ nullptr,
+ nullptr,
#endif
compare,
convert,
- 0,
+ nullptr,
#if !defined(QT_NO_DEBUG_STREAM)
streamDebug
#else
- 0
+ nullptr
#endif
};
@@ -1436,16 +1436,16 @@ const QVariant::Handler qt_dummy_variant_handler = {
dummyClear,
dummyIsNull,
#ifndef QT_NO_DATASTREAM
- 0,
- 0,
+ nullptr,
+ nullptr,
#endif
dummyCompare,
dummyConvert,
- 0,
+ nullptr,
#if !defined(QT_NO_DEBUG_STREAM)
dummyStreamDebug
#else
- 0
+ nullptr
#endif
};
@@ -1555,16 +1555,16 @@ const QVariant::Handler qt_custom_variant_handler = {
customClear,
customIsNull,
#ifndef QT_NO_DATASTREAM
- 0,
- 0,
+ nullptr,
+ nullptr,
#endif
customCompare,
customConvert,
- 0,
+ nullptr,
#if !defined(QT_NO_DEBUG_STREAM)
customStreamDebug
#else
- 0
+ nullptr
#endif
};
@@ -2125,7 +2125,7 @@ QVariant::QVariant(const char *val)
*/
QVariant::QVariant(Type type)
-{ create(type, 0); }
+{ create(type, nullptr); }
QVariant::QVariant(int typeId, const void *copy)
{ create(typeId, copy); d.is_null = false; }
@@ -2366,7 +2366,7 @@ QVariant& QVariant::operator=(const QVariant &variant)
void QVariant::detach()
{
- if (!d.is_shared || d.data.shared->ref.load() == 1)
+ if (!d.is_shared || d.data.shared->ref.loadRelaxed() == 1)
return;
Private dd;
@@ -2667,7 +2667,7 @@ inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &han
return ret;
}
- handlerManager[d.type]->convert(&d, targetType, &ret, 0);
+ handlerManager[d.type]->convert(&d, targetType, &ret, nullptr);
return ret;
}
@@ -3217,7 +3217,7 @@ bool QVariant::toBool() const
return d.data.b;
bool res = false;
- handlerManager[d.type]->convert(&d, Bool, &res, 0);
+ handlerManager[d.type]->convert(&d, Bool, &res, nullptr);
return res;
}
@@ -3735,7 +3735,7 @@ bool QVariant::convert(int targetTypeId)
if (!oldValue.canConvert(targetTypeId))
return false;
- create(targetTypeId, 0);
+ create(targetTypeId, nullptr);
// Fail if the value is not initialized or was forced null by a previous failed convert.
if (oldValue.d.is_null && oldValue.d.type != QMetaType::Nullptr)
return false;
@@ -3760,7 +3760,7 @@ bool QVariant::convert(int targetTypeId)
*/
bool QVariant::convert(const int type, void *ptr) const
{
- return handlerManager[type]->convert(&d, type, ptr, 0);
+ return handlerManager[type]->convert(&d, type, ptr, nullptr);
}
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index e094ebff52..c8cb551863 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -577,7 +577,7 @@ Q_CORE_EXPORT QDataStream& operator<< (QDataStream& s, const QVariant::Type p);
#endif
inline bool QVariant::isDetached() const
-{ return !d.is_shared || d.data.shared->ref.load() == 1; }
+{ return !d.is_shared || d.data.shared->ref.loadRelaxed() == 1; }
#ifdef Q_QDOC
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index 3c73c0b851..d2ae9668fe 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -124,7 +124,7 @@ QWinEventNotifier::QWinEventNotifier(HANDLE hEvent, QObject *parent)
: QObject(*new QWinEventNotifierPrivate(hEvent, false), parent)
{
Q_D(QWinEventNotifier);
- QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.loadRelaxed();
if (Q_UNLIKELY(!eventDispatcher)) {
qWarning("QWinEventNotifier: Can only be used with threads started with QThread");
return;
@@ -197,7 +197,7 @@ void QWinEventNotifier::setEnabled(bool enable)
return;
d->enabled = enable;
- QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.loadRelaxed();
if (!eventDispatcher) { // perhaps application is shutting down
if (!enable && d->waitHandle != nullptr)
d->unregisterWaitObject();
@@ -256,7 +256,7 @@ void QWinEventNotifierPrivate::unregisterWaitObject()
static void CALLBACK wfsoCallback(void *context, BOOLEAN /*ignore*/)
{
QWinEventNotifierPrivate *nd = reinterpret_cast<QWinEventNotifierPrivate *>(context);
- QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.loadRelaxed();
// Happens when Q(Core)Application is destroyed before QWinEventNotifier.
// https://bugreports.qt.io/browse/QTBUG-70214
diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
index cf01c9503b..de450c68f4 100644
--- a/src/corelib/mimetypes/qmimetype.cpp
+++ b/src/corelib/mimetypes/qmimetype.cpp
@@ -253,7 +253,7 @@ QString QMimeType::name() const
*/
QString QMimeType::comment() const
{
- QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
QStringList languageList;
languageList << QLocale().name();
@@ -294,7 +294,7 @@ QString QMimeType::comment() const
*/
QString QMimeType::genericIconName() const
{
- QMimeDatabasePrivate::instance()->loadGenericIcon(*d);
+ QMimeDatabasePrivate::instance()->loadGenericIcon(const_cast<QMimeTypePrivate&>(*d));
if (d->genericIconName.isEmpty()) {
// From the spec:
// If the generic icon name is empty (not specified by the mimetype definition)
@@ -311,6 +311,14 @@ QString QMimeType::genericIconName() const
return d->genericIconName;
}
+static QString make_default_icon_name_from_mimetype_name(QString iconName)
+{
+ const int slashindex = iconName.indexOf(QLatin1Char('/'));
+ if (slashindex != -1)
+ iconName[slashindex] = QLatin1Char('-');
+ return iconName;
+}
+
/*!
\property QMimeType::iconName
\brief the file name of an icon image that represents the MIME type
@@ -322,13 +330,9 @@ QString QMimeType::genericIconName() const
*/
QString QMimeType::iconName() const
{
- QMimeDatabasePrivate::instance()->loadIcon(*d);
+ QMimeDatabasePrivate::instance()->loadIcon(const_cast<QMimeTypePrivate&>(*d));
if (d->iconName.isEmpty()) {
- // Make default icon name from the mimetype name
- d->iconName = name();
- const int slashindex = d->iconName.indexOf(QLatin1Char('/'));
- if (slashindex != -1)
- d->iconName[slashindex] = QLatin1Char('-');
+ return make_default_icon_name_from_mimetype_name(name());
}
return d->iconName;
}
@@ -342,7 +346,7 @@ QString QMimeType::iconName() const
*/
QStringList QMimeType::globPatterns() const
{
- QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
return d->globPatterns;
}
@@ -437,7 +441,7 @@ QStringList QMimeType::aliases() const
*/
QStringList QMimeType::suffixes() const
{
- QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
QStringList result;
for (const QString &pattern : qAsConst(d->globPatterns)) {
@@ -480,7 +484,7 @@ QString QMimeType::preferredSuffix() const
*/
QString QMimeType::filterString() const
{
- QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
QString filter;
if (!d->globPatterns.empty()) {
diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h
index 6d6f9eb488..df1b60f2ce 100644
--- a/src/corelib/mimetypes/qmimetype.h
+++ b/src/corelib/mimetypes/qmimetype.h
@@ -48,11 +48,11 @@ QT_REQUIRE_CONFIG(mimetype);
#include <QtCore/qobjectdefs.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
QT_BEGIN_NAMESPACE
class QMimeTypePrivate;
-class QStringList;
class QMimeType;
Q_CORE_EXPORT uint qHash(const QMimeType &key, uint seed = 0) noexcept;
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 8e349f23ce..6737aeccd2 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -170,7 +170,7 @@ public:
Q_GLOBAL_STATIC(QList<QFactoryLoader *>, qt_factory_loaders)
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_factoryloader_mutex, (QMutex::Recursive))
+Q_GLOBAL_STATIC(QRecursiveMutex, qt_factoryloader_mutex)
QFactoryLoaderPrivate::~QFactoryLoaderPrivate()
{
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index a707ea64ee..a8db108eeb 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -405,10 +405,10 @@ inline void QLibraryStore::cleanup()
LibraryMap::Iterator it = data->libraryMap.begin();
for (; it != data->libraryMap.end(); ++it) {
QLibraryPrivate *lib = it.value();
- if (lib->libraryRefCount.load() == 1) {
- if (lib->libraryUnloadCount.load() > 0) {
+ if (lib->libraryRefCount.loadRelaxed() == 1) {
+ if (lib->libraryUnloadCount.loadRelaxed() > 0) {
Q_ASSERT(lib->pHnd);
- lib->libraryUnloadCount.store(1);
+ lib->libraryUnloadCount.storeRelaxed(1);
#ifdef __GLIBC__
// glibc has a bug in unloading from global destructors
// see https://bugzilla.novell.com/show_bug.cgi?id=622977
@@ -428,7 +428,7 @@ inline void QLibraryStore::cleanup()
for (QLibraryPrivate *lib : qAsConst(data->libraryMap)) {
if (lib)
qDebug() << "On QtCore unload," << lib->fileName << "was leaked, with"
- << lib->libraryRefCount.load() << "users";
+ << lib->libraryRefCount.loadRelaxed() << "users";
}
}
@@ -487,7 +487,7 @@ inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib)
}
// no one else is using
- Q_ASSERT(lib->libraryUnloadCount.load() == 0);
+ Q_ASSERT(lib->libraryUnloadCount.loadRelaxed() == 0);
if (Q_LIKELY(data) && !lib->fileName.isEmpty()) {
QLibraryPrivate *that = data->libraryMap.take(lib->fileName);
@@ -501,7 +501,7 @@ QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString
: pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0),
libraryRefCount(0), libraryUnloadCount(0), pluginState(MightBeAPlugin)
{
- loadHintsInt.store(loadHints);
+ loadHintsInt.storeRelaxed(loadHints);
if (canonicalFileName.isEmpty())
errorString = QLibrary::tr("The shared library was not found.");
}
@@ -522,7 +522,7 @@ void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
if (pHnd)
return;
- loadHintsInt.store(lh);
+ loadHintsInt.storeRelaxed(lh);
}
QFunctionPointer QLibraryPrivate::resolve(const char *symbol)
@@ -575,7 +575,7 @@ bool QLibraryPrivate::unload(UnloadFlag flag)
{
if (!pHnd)
return false;
- if (libraryUnloadCount.load() > 0 && !libraryUnloadCount.deref()) { // only unload if ALL QLibrary instance wanted to
+ if (libraryUnloadCount.loadRelaxed() > 0 && !libraryUnloadCount.deref()) { // only unload if ALL QLibrary instance wanted to
delete inst.data();
if (flag == NoUnloadSys || unload_sys()) {
if (qt_debug_component())
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index 1a216c98b5..db5afac98e 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -92,7 +92,7 @@ public:
QFunctionPointer resolve(const char *);
QLibrary::LoadHints loadHints() const
- { return QLibrary::LoadHints(loadHintsInt.load()); }
+ { return QLibrary::LoadHints(loadHintsInt.loadRelaxed()); }
void setLoadHints(QLibrary::LoadHints lh);
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString(),
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index e03814984c..84fcc53d52 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -77,14 +77,14 @@ QStringList QLibraryPrivate::suffixes_sys(const QString& fullVersion)
// .so is preferred.
# if defined(__ia64)
if (!fullVersion.isEmpty()) {
- suffixes << QString::fromLatin1(".so.%1").arg(fullVersion);
+ suffixes << QLatin1String(".so.%1").arg(fullVersion);
} else {
suffixes << QLatin1String(".so");
}
# endif
if (!fullVersion.isEmpty()) {
- suffixes << QString::fromLatin1(".sl.%1").arg(fullVersion);
- suffixes << QString::fromLatin1(".%1").arg(fullVersion);
+ suffixes << QLatin1String(".sl.%1").arg(fullVersion);
+ suffixes << QLatin1String(".%1").arg(fullVersion);
} else {
suffixes << QLatin1String(".sl");
}
@@ -93,15 +93,15 @@ QStringList QLibraryPrivate::suffixes_sys(const QString& fullVersion)
#else
if (!fullVersion.isEmpty()) {
- suffixes << QString::fromLatin1(".so.%1").arg(fullVersion);
+ suffixes << QLatin1String(".so.%1").arg(fullVersion);
} else {
suffixes << QLatin1String(".so");
}
#endif
# ifdef Q_OS_MAC
if (!fullVersion.isEmpty()) {
- suffixes << QString::fromLatin1(".%1.bundle").arg(fullVersion);
- suffixes << QString::fromLatin1(".%1.dylib").arg(fullVersion);
+ suffixes << QLatin1String(".%1.bundle").arg(fullVersion);
+ suffixes << QLatin1String(".%1.dylib").arg(fullVersion);
} else {
suffixes << QLatin1String(".bundle") << QLatin1String(".dylib");
}
diff --git a/src/corelib/serialization/qcborstream.h b/src/corelib/serialization/qcborstream.h
index 3b13a309ab..7a451e63ac 100644
--- a/src/corelib/serialization/qcborstream.h
+++ b/src/corelib/serialization/qcborstream.h
@@ -242,8 +242,8 @@ private:
template <typename FP> FP _toFloatingPoint() const noexcept
{
- using UInt = typename QIntegerForSizeof<FP>::Unsigned;
- UInt u = UInt(value64);
+ using UIntFP = typename QIntegerForSizeof<FP>::Unsigned;
+ UIntFP u = UIntFP(value64);
FP f;
memcpy(static_cast<void *>(&f), &u, sizeof(f));
return f;
diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp
index b2e0ba6d53..ba616c0a7d 100644
--- a/src/corelib/serialization/qcborvalue.cpp
+++ b/src/corelib/serialization/qcborvalue.cpp
@@ -849,7 +849,7 @@ QCborContainerPrivate *QCborContainerPrivate::clone(QCborContainerPrivate *d, qs
QCborContainerPrivate *QCborContainerPrivate::detach(QCborContainerPrivate *d, qsizetype reserved)
{
- if (!d || d->ref.load() != 1)
+ if (!d || d->ref.loadRelaxed() != 1)
return clone(d, reserved);
return d;
}
@@ -884,12 +884,12 @@ void QCborContainerPrivate::replaceAt_complex(Element &e, const QCborValue &valu
// detect self-assignment
if (Q_UNLIKELY(this == value.container)) {
- Q_ASSERT(ref.load() >= 2);
+ Q_ASSERT(ref.loadRelaxed() >= 2);
if (disp == MoveContainer)
ref.deref(); // not deref() because it can't drop to 0
QCborContainerPrivate *d = QCborContainerPrivate::clone(this);
d->elements.detach();
- d->ref.store(1);
+ d->ref.storeRelaxed(1);
e.container = d;
} else {
e.container = value.container;
@@ -1368,7 +1368,7 @@ static Element decodeBasicValueFromCbor(QCborStreamReader &reader)
static inline QCborContainerPrivate *createContainerFromCbor(QCborStreamReader &reader)
{
auto d = new QCborContainerPrivate;
- d->ref.store(1);
+ d->ref.storeRelaxed(1);
d->decodeFromCbor(reader);
return d;
}
@@ -1643,7 +1643,7 @@ QCborValue::QCborValue(const QByteArray &ba)
: n(0), container(new QCborContainerPrivate), t(ByteArray)
{
container->appendByteData(ba.constData(), ba.size(), t);
- container->ref.store(1);
+ container->ref.storeRelaxed(1);
}
/*!
@@ -1656,7 +1656,7 @@ QCborValue::QCborValue(const QString &s)
: n(0), container(new QCborContainerPrivate), t(String)
{
container->append(s);
- container->ref.store(1);
+ container->ref.storeRelaxed(1);
}
/*!
@@ -1671,7 +1671,7 @@ QCborValue::QCborValue(QLatin1String s)
: n(0), container(new QCborContainerPrivate), t(String)
{
container->append(s);
- container->ref.store(1);
+ container->ref.storeRelaxed(1);
}
/*!
@@ -1719,7 +1719,7 @@ QCborValue::QCborValue(const QCborMap &m)
QCborValue::QCborValue(QCborTag t, const QCborValue &tv)
: n(-1), container(new QCborContainerPrivate), t(Tag)
{
- container->ref.store(1);
+ container->ref.storeRelaxed(1);
container->append(t);
container->append(tv);
}
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index 2c29b81f7c..b3330d6cea 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -277,7 +277,7 @@ QT_BEGIN_NAMESPACE
QDataStream::QDataStream()
{
- dev = 0;
+ dev = nullptr;
owndev = false;
byteorder = BigEndian;
ver = Qt_DefaultCompiledVersion;
@@ -433,7 +433,7 @@ bool QDataStream::atEnd() const
*/
QDataStream::FloatingPointPrecision QDataStream::floatingPointPrecision() const
{
- return d == 0 ? QDataStream::DoublePrecision : d->floatingPointPrecision;
+ return d ? d->floatingPointPrecision : QDataStream::DoublePrecision;
}
/*!
@@ -458,7 +458,7 @@ QDataStream::FloatingPointPrecision QDataStream::floatingPointPrecision() const
*/
void QDataStream::setFloatingPointPrecision(QDataStream::FloatingPointPrecision precision)
{
- if (d == 0)
+ if (!d)
d.reset(new QDataStreamPrivate());
d->floatingPointPrecision = precision;
}
@@ -639,7 +639,7 @@ void QDataStream::startTransaction()
{
CHECK_STREAM_PRECOND(Q_VOID)
- if (d == 0)
+ if (!d)
d.reset(new QDataStreamPrivate());
if (++d->transactionDepth == 1) {
@@ -1043,7 +1043,7 @@ QDataStream &QDataStream::operator>>(char *&s)
QDataStream &QDataStream::readBytes(char *&s, uint &l)
{
- s = 0;
+ s = nullptr;
l = 0;
CHECK_STREAM_PRECOND(*this)
@@ -1054,8 +1054,8 @@ QDataStream &QDataStream::readBytes(char *&s, uint &l)
const quint32 Step = 1024 * 1024;
quint32 allocated = 0;
- char *prevBuf = 0;
- char *curBuf = 0;
+ char *prevBuf = nullptr;
+ char *curBuf = nullptr;
do {
int blockSize = qMin(Step, len - allocated);
diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h
index 85fb2a1254..9de53d5b74 100644
--- a/src/corelib/serialization/qjson_p.h
+++ b/src/corelib/serialization/qjson_p.h
@@ -719,7 +719,7 @@ public:
Data *clone(Base *b, int reserve = 0)
{
int size = sizeof(Header) + b->size;
- if (b == header->root() && ref.load() == 1 && alloc >= size + reserve)
+ if (b == header->root() && ref.loadRelaxed() == 1 && alloc >= size + reserve)
return this;
if (reserve) {
diff --git a/src/corelib/serialization/qjsonarray.cpp b/src/corelib/serialization/qjsonarray.cpp
index 7dfa9b43f0..6b327619ad 100644
--- a/src/corelib/serialization/qjsonarray.cpp
+++ b/src/corelib/serialization/qjsonarray.cpp
@@ -132,7 +132,7 @@ QT_BEGIN_NAMESPACE
Creates an empty array.
*/
QJsonArray::QJsonArray()
- : d(0), a(0)
+ : d(nullptr), a(nullptr)
{
}
@@ -168,8 +168,8 @@ QJsonArray::QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array)
*/
void QJsonArray::initialize()
{
- d = 0;
- a = 0;
+ d = nullptr;
+ a = nullptr;
}
/*!
@@ -1226,7 +1226,7 @@ bool QJsonArray::detach2(uint reserve)
d->ref.ref();
return true;
}
- if (reserve == 0 && d->ref.load() == 1)
+ if (reserve == 0 && d->ref.loadRelaxed() == 1)
return true;
QJsonPrivate::Data *x = d->clone(a, reserve);
diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp
index dc5f384108..e0c390f610 100644
--- a/src/corelib/serialization/qjsoncbor.cpp
+++ b/src/corelib/serialization/qjsoncbor.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -598,10 +598,12 @@ QCborValue QCborValue::fromJsonValue(const QJsonValue &v)
switch (v.type()) {
case QJsonValue::Bool:
return v.b;
- case QJsonValue::Double:
- if (v.dbl == qint64(v.dbl))
- return qint64(v.dbl);
+ case QJsonValue::Double: {
+ qint64 i;
+ if (convertDoubleTo(v.dbl, &i))
+ return i;
return v.dbl;
+ }
case QJsonValue::String:
return v.toString();
case QJsonValue::Array:
diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp
index 179a87c699..f8027efb58 100644
--- a/src/corelib/serialization/qjsondocument.cpp
+++ b/src/corelib/serialization/qjsondocument.cpp
@@ -84,7 +84,7 @@ QT_BEGIN_NAMESPACE
* Constructs an empty and invalid document.
*/
QJsonDocument::QJsonDocument()
- : d(0)
+ : d(nullptr)
{
}
@@ -92,7 +92,7 @@ QJsonDocument::QJsonDocument()
* Creates a QJsonDocument from \a object.
*/
QJsonDocument::QJsonDocument(const QJsonObject &object)
- : d(0)
+ : d(nullptr)
{
setObject(object);
}
@@ -101,7 +101,7 @@ QJsonDocument::QJsonDocument(const QJsonObject &object)
* Constructs a QJsonDocument from \a array.
*/
QJsonDocument::QJsonDocument(const QJsonArray &array)
- : d(0)
+ : d(nullptr)
{
setArray(array);
}
@@ -236,7 +236,7 @@ const char *QJsonDocument::rawData(int *size) const
{
if (!d) {
*size = 0;
- return 0;
+ return nullptr;
}
*size = d->alloc;
return d->rawData;
@@ -635,7 +635,7 @@ bool QJsonDocument::operator==(const QJsonDocument &other) const
*/
bool QJsonDocument::isNull() const
{
- return (d == 0);
+ return (d == nullptr);
}
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp
index a9f25a119c..c1a6328b2f 100644
--- a/src/corelib/serialization/qjsonobject.cpp
+++ b/src/corelib/serialization/qjsonobject.cpp
@@ -110,7 +110,7 @@ QT_BEGIN_NAMESPACE
\sa isEmpty()
*/
QJsonObject::QJsonObject()
- : d(0), o(0)
+ : d(nullptr), o(nullptr)
{
}
@@ -149,8 +149,8 @@ QJsonObject::QJsonObject(QJsonPrivate::Data *data, QJsonPrivate::Object *object)
void QJsonObject::initialize()
{
- d = 0;
- o = 0;
+ d = nullptr;
+ o = nullptr;
}
/*!
@@ -646,7 +646,7 @@ bool QJsonObject::operator!=(const QJsonObject &other) const
*/
QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it)
{
- Q_ASSERT(d && d->ref.load() == 1);
+ Q_ASSERT(d && d->ref.loadRelaxed() == 1);
if (it.o != this || it.i < 0 || it.i >= (int)o->length)
return iterator(this, o->length);
@@ -1231,7 +1231,7 @@ bool QJsonObject::detach2(uint reserve)
d->ref.ref();
return true;
}
- if (reserve == 0 && d->ref.load() == 1)
+ if (reserve == 0 && d->ref.loadRelaxed() == 1)
return true;
QJsonPrivate::Data *x = d->clone(o, reserve);
diff --git a/src/corelib/serialization/qjsonparser.cpp b/src/corelib/serialization/qjsonparser.cpp
index f29348d593..cd36bd5a5b 100644
--- a/src/corelib/serialization/qjsonparser.cpp
+++ b/src/corelib/serialization/qjsonparser.cpp
@@ -198,7 +198,9 @@ QString QJsonParseError::errorString() const
using namespace QJsonPrivate;
Parser::Parser(const char *json, int length)
- : head(json), json(json), data(0), dataLength(0), current(0), nestingLevel(0), lastError(QJsonParseError::NoError)
+ : head(json), json(json), data(nullptr)
+ , dataLength(0), current(0), nestingLevel(0)
+ , lastError(QJsonParseError::NoError)
{
end = json + length;
}
diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp
index 1fc610d7c7..0bd28581f3 100644
--- a/src/corelib/serialization/qjsonvalue.cpp
+++ b/src/corelib/serialization/qjsonvalue.cpp
@@ -112,7 +112,7 @@ QT_BEGIN_NAMESPACE
The default is to create a Null value.
*/
QJsonValue::QJsonValue(Type type)
- : ui(0), d(0), t(type)
+ : ui(0), d(nullptr), t(type)
{
}
@@ -120,7 +120,7 @@ QJsonValue::QJsonValue(Type type)
\internal
*/
QJsonValue::QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *base, const QJsonPrivate::Value &v)
- : d(0)
+ : d(nullptr)
{
t = (Type)(uint)v.type;
switch (t) {
@@ -154,7 +154,7 @@ QJsonValue::QJsonValue(QJsonPrivate::Data *data, QJsonPrivate::Base *base, const
Creates a value of type Bool, with value \a b.
*/
QJsonValue::QJsonValue(bool b)
- : d(0), t(Bool)
+ : d(nullptr), t(Bool)
{
this->b = b;
}
@@ -163,7 +163,7 @@ QJsonValue::QJsonValue(bool b)
Creates a value of type Double, with value \a n.
*/
QJsonValue::QJsonValue(double n)
- : d(0), t(Double)
+ : d(nullptr), t(Double)
{
this->dbl = n;
}
@@ -173,7 +173,7 @@ QJsonValue::QJsonValue(double n)
Creates a value of type Double, with value \a n.
*/
QJsonValue::QJsonValue(int n)
- : d(0), t(Double)
+ : d(nullptr), t(Double)
{
this->dbl = n;
}
@@ -185,7 +185,7 @@ QJsonValue::QJsonValue(int n)
If you pass in values outside this range expect a loss of precision to occur.
*/
QJsonValue::QJsonValue(qint64 n)
- : d(0), t(Double)
+ : d(nullptr), t(Double)
{
this->dbl = double(n);
}
@@ -194,7 +194,7 @@ QJsonValue::QJsonValue(qint64 n)
Creates a value of type String, with value \a s.
*/
QJsonValue::QJsonValue(const QString &s)
- : d(0), t(String)
+ : d(nullptr), t(String)
{
stringDataFromQStringHelper(s);
}
@@ -221,7 +221,7 @@ void QJsonValue::stringDataFromQStringHelper(const QString &string)
Creates a value of type String, with value \a s.
*/
QJsonValue::QJsonValue(QLatin1String s)
- : d(0), t(String)
+ : d(nullptr), t(String)
{
// ### FIXME: Avoid creating the temp QString below
QString str(s);
diff --git a/src/corelib/serialization/qjsonwriter.cpp b/src/corelib/serialization/qjsonwriter.cpp
index 5b246837d2..012d3bea86 100644
--- a/src/corelib/serialization/qjsonwriter.cpp
+++ b/src/corelib/serialization/qjsonwriter.cpp
@@ -43,6 +43,7 @@
#include "qjsonwriter_p.h"
#include "qjson_p.h"
#include "private/qutfcodec_p.h"
+#include <private/qnumeric_p.h>
QT_BEGIN_NAMESPACE
@@ -135,8 +136,9 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value &
case QJsonValue::Double: {
const double d = v.toDouble(b);
if (qIsFinite(d)) { // +2 to format to ensure the expected precision
- const double abs = std::abs(d);
- json += QByteArray::number(d, abs == static_cast<quint64>(abs) ? 'f' : 'g', QLocale::FloatingPointShortest);
+ quint64 absInt;
+ json += QByteArray::number(d, convertDoubleTo(std::abs(d), &absInt) ? 'f' : 'g',
+ QLocale::FloatingPointShortest);
} else {
json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
}
diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp
index ef2a9c97ee..9d4bc223ab 100644
--- a/src/corelib/serialization/qtextstream.cpp
+++ b/src/corelib/serialization/qtextstream.cpp
@@ -327,7 +327,7 @@ QT_BEGIN_NAMESPACE
QTextStreamPrivate::QTextStreamPrivate(QTextStream *q_ptr)
:
#if QT_CONFIG(textcodec)
- readConverterSavedState(0),
+ readConverterSavedState(nullptr),
#endif
readConverterSavedStateOffset(0),
locale(QLocale::c())
@@ -381,7 +381,7 @@ void QTextStreamPrivate::Params::reset()
padChar = QLatin1Char(' ');
fieldAlignment = QTextStream::AlignRight;
realNumberNotation = QTextStream::SmartNotation;
- numberFlags = 0;
+ numberFlags = { };
}
/*!
@@ -391,9 +391,9 @@ void QTextStreamPrivate::reset()
{
params.reset();
- device = 0;
+ device = nullptr;
deleteDevice = false;
- string = 0;
+ string = nullptr;
stringOffset = 0;
stringOpenMode = QIODevice::NotOpen;
@@ -406,7 +406,7 @@ void QTextStreamPrivate::reset()
resetCodecConverterStateHelper(&readConverterState);
resetCodecConverterStateHelper(&writeConverterState);
delete readConverterSavedState;
- readConverterSavedState = 0;
+ readConverterSavedState = nullptr;
writeConverterState.flags |= QTextCodec::IgnoreHeader;
autoDetectUnicode = true;
#endif
@@ -1207,7 +1207,7 @@ bool QTextStream::seek(qint64 pos)
resetCodecConverterStateHelper(&d->readConverterState);
resetCodecConverterStateHelper(&d->writeConverterState);
delete d->readConverterSavedState;
- d->readConverterSavedState = 0;
+ d->readConverterSavedState = nullptr;
d->writeConverterState.flags |= QTextCodec::IgnoreHeader;
#endif
return true;
@@ -1295,7 +1295,7 @@ void QTextStream::skipWhiteSpace()
{
Q_D(QTextStream);
CHECK_VALID_STREAM(Q_VOID);
- d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
+ d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
d->consumeLastToken();
}
@@ -1751,7 +1751,7 @@ QString QTextStream::read(qint64 maxlen)
*/
QTextStreamPrivate::NumberParsingStatus QTextStreamPrivate::getNumber(qulonglong *ret)
{
- scan(0, 0, 0, NotSpace);
+ scan(nullptr, nullptr, 0, NotSpace);
consumeLastToken();
// detect int encoding
@@ -1980,7 +1980,7 @@ bool QTextStreamPrivate::getReal(double *f)
ParserState state = Init;
InputToken input = None;
- scan(0, 0, 0, NotSpace);
+ scan(nullptr, nullptr, 0, NotSpace);
consumeLastToken();
const int BufferSize = 128;
@@ -2084,7 +2084,7 @@ QTextStream &QTextStream::operator>>(QChar &c)
{
Q_D(QTextStream);
CHECK_VALID_STREAM(*this);
- d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
+ d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
if (!d->getChar(&c))
setStatus(ReadPastEnd);
return *this;
@@ -2245,7 +2245,7 @@ QTextStream &QTextStream::operator>>(QString &str)
CHECK_VALID_STREAM(*this);
str.clear();
- d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
+ d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
d->consumeLastToken();
const QChar *ptr;
@@ -2273,7 +2273,7 @@ QTextStream &QTextStream::operator>>(QByteArray &array)
CHECK_VALID_STREAM(*this);
array.clear();
- d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
+ d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
d->consumeLastToken();
const QChar *ptr;
@@ -2308,7 +2308,7 @@ QTextStream &QTextStream::operator>>(char *c)
Q_D(QTextStream);
*c = 0;
CHECK_VALID_STREAM(*this);
- d->scan(0, 0, 0, QTextStreamPrivate::NotSpace);
+ d->scan(nullptr, nullptr, 0, QTextStreamPrivate::NotSpace);
d->consumeLastToken();
const QChar *ptr;
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index d43d9c4e14..be3a476cb2 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -58,9 +58,9 @@
// case for most bootstrapped applications.
#define Q_DECLARE_TR_FUNCTIONS(context) \
public: \
- static inline QString tr(const char *sourceText, const char *comment = 0) \
+ static inline QString tr(const char *sourceText, const char *comment = nullptr) \
{ Q_UNUSED(comment); return QString::fromLatin1(sourceText); } \
- static inline QString trUtf8(const char *sourceText, const char *comment = 0) \
+ static inline QString trUtf8(const char *sourceText, const char *comment = nullptr) \
{ Q_UNUSED(comment); return QString::fromLatin1(sourceText); } \
static inline QString tr(const char *sourceText, const char*, int) \
{ return QString::fromLatin1(sourceText); } \
@@ -548,7 +548,7 @@ void QXmlStreamReader::clear()
if (d->device) {
if (d->deleteDevice)
delete d->device;
- d->device = 0;
+ d->device = nullptr;
}
}
@@ -792,16 +792,16 @@ QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack()
QXmlStreamReaderPrivate::QXmlStreamReaderPrivate(QXmlStreamReader *q)
:q_ptr(q)
{
- device = 0;
+ device = nullptr;
deleteDevice = false;
#if QT_CONFIG(textcodec)
- decoder = 0;
+ decoder = nullptr;
#endif
stack_size = 64;
- sym_stack = 0;
- state_stack = 0;
+ sym_stack = nullptr;
+ state_stack = nullptr;
reallocateStack();
- entityResolver = 0;
+ entityResolver = nullptr;
init();
#define ADD_PREDEFINED(n, v) \
do { \
@@ -843,11 +843,11 @@ void QXmlStreamReaderPrivate::init()
#if QT_CONFIG(textcodec)
codec = QTextCodec::codecForMib(106); // utf8
delete decoder;
- decoder = 0;
+ decoder = nullptr;
#endif
attributeStack.clear();
attributeStack.reserve(16);
- entityParser = 0;
+ entityParser = nullptr;
hasCheckedStartDocument = false;
normalizeLiterals = false;
hasSeenTag = false;
@@ -3024,8 +3024,8 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q)
:autoFormattingIndent(4, ' ')
{
q_ptr = q;
- device = 0;
- stringDevice = 0;
+ device = nullptr;
+ stringDevice = nullptr;
deleteDevice = false;
#if QT_CONFIG(textcodec)
codec = QTextCodec::codecForMib(106); // utf8
@@ -3315,7 +3315,7 @@ void QXmlStreamWriter::setDevice(QIODevice *device)
Q_D(QXmlStreamWriter);
if (device == d->device)
return;
- d->stringDevice = 0;
+ d->stringDevice = nullptr;
if (d->deleteDevice) {
delete d->device;
d->deleteDevice = false;
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g
index e6328a11ac..12ecc9bdb2 100644
--- a/src/corelib/serialization/qxmlstream.g
+++ b/src/corelib/serialization/qxmlstream.g
@@ -506,7 +506,7 @@ public:
int fastScanLiteralContent();
int fastScanSpace();
int fastScanContentCharList();
- int fastScanName(int *prefix = 0);
+ int fastScanName(int *prefix = nullptr);
inline int fastScanNMTOKEN();
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index c161bec537..b1a7edad91 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -258,12 +258,26 @@
/*!
\fn template <typename T> T QAtomicInteger<T>::load() const
+ \obsolete
+
+ Use loadRelaxed() instead.
Atomically loads the value of this QAtomicInteger using relaxed memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
- \sa store(), loadAcquire()
+ \sa storeRelaxed(), loadAcquire()
+*/
+
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::loadRelaxed() const
+ \since 5.14
+
+ Atomically loads the value of this QAtomicInteger using relaxed memory
+ ordering. The value is not modified in any way, but note that there's no
+ guarantee that it remains so.
+
+ \sa storeRelaxed(), loadAcquire()
*/
/*!
@@ -273,16 +287,29 @@
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
- \sa store(), load()
+ \sa storeRelaxed(), loadRelaxed()
*/
/*!
\fn template <typename T> void QAtomicInteger<T>::store(T newValue)
+ \obsolete
+
+ Use storeRelaxed() instead.
Atomically stores the \a newValue value into this atomic type, using
relaxed memory ordering.
- \sa storeRelease(), load()
+ \sa storeRelease(), loadRelaxed()
+*/
+
+/*!
+ \fn template <typename T> void QAtomicInteger<T>::storeRelaxed(T newValue)
+ \since 5.14
+
+ Atomically stores the \a newValue value into this atomic type, using
+ relaxed memory ordering.
+
+ \sa storeRelease(), loadRelaxed()
*/
/*!
@@ -291,7 +318,7 @@
Atomically stores the \a newValue value into this atomic type, using
the "Release" memory ordering.
- \sa store(), load()
+ \sa store(), loadAcquire()
*/
/*!
@@ -303,7 +330,7 @@
value is not modified in any way, but note that there's no guarantee that
it remains so.
- \sa load(), loadAcquire()
+ \sa loadRelaxed(), loadAcquire()
*/
/*!
@@ -314,7 +341,7 @@
sequentially consistent memory ordering if possible; or "Release" ordering
if not. This function returns a reference to this object.
- \sa store(), storeRelease()
+ \sa storeRelaxed(), storeRelease()
*/
/*! \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingNative()
@@ -1278,31 +1305,59 @@
/*!
\fn template <typename T> T *QAtomicPointer<T>::load() const
+ \obsolete
+
+ Use loadRelaxed() instead.
Atomically loads the value of this QAtomicPointer using relaxed memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
- \sa store(), loadAcquire()
+ \sa storeRelaxed(), loadAcquire()
*/
/*!
+ \fn template <typename T> T *QAtomicPointer<T>::loadRelaxed() const
+ \since 5.14
+
+ Atomically loads the value of this QAtomicPointer using relaxed memory
+ ordering. The value is not modified in any way, but note that there's no
+ guarantee that it remains so.
+
+ \sa storeRelaxed(), loadAcquire()
+*/
+
+
+/*!
\fn template <typename T> T *QAtomicPointer<T>::loadAcquire() const
Atomically loads the value of this QAtomicPointer using the "Acquire" memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
- \sa store(), load()
+ \sa storeRelease(), loadRelaxed()
*/
/*!
\fn template <typename T> void QAtomicPointer<T>::store(T *newValue)
+ \obsolete
+
+ Use storeRelaxed() instead.
+
+ Atomically stores the \a newValue value into this atomic type, using
+ relaxed memory ordering.
+
+ \sa storeRelease(), loadRelaxed()
+*/
+
+/*!
+ \fn template <typename T> void QAtomicPointer<T>::storeRelaxed(T *newValue)
+ \since 5.14
Atomically stores the \a newValue value into this atomic type, using
relaxed memory ordering.
- \sa storeRelease(), load()
+ \sa storeRelease(), loadRelaxed()
*/
/*!
@@ -1311,7 +1366,7 @@
Atomically stores the \a newValue value into this atomic type, using
the "Release" memory ordering.
- \sa store(), load()
+ \sa storeRelaxed(), loadRelaxed()
*/
/*! \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetNative()
diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h
index 280ce96b76..a3b9be0729 100644
--- a/src/corelib/thread/qatomic.h
+++ b/src/corelib/thread/qatomic.h
@@ -81,8 +81,10 @@ public:
#ifdef Q_CLANG_QDOC
T load() const;
+ T loadRelaxed() const;
T loadAcquire() const;
void store(T newValue);
+ void storeRelaxed(T newValue);
void storeRelease(T newValue);
operator T() const;
@@ -172,7 +174,7 @@ public:
#else
inline QAtomicPointer(T *value = nullptr) noexcept
{
- this->store(value);
+ this->storeRelaxed(value);
}
#endif
inline QAtomicPointer(const QAtomicPointer<T> &other) noexcept
@@ -255,7 +257,7 @@ inline void qAtomicAssign(T *&d, T *x)
template <typename T>
inline void qAtomicDetach(T *&d)
{
- if (d->ref.load() == 1)
+ if (d->ref.loadRelaxed() == 1)
return;
T *x = d;
d = new T(*d);
diff --git a/src/corelib/thread/qatomic_cxx11.h b/src/corelib/thread/qatomic_cxx11.h
index 2851bae73e..7386aee126 100644
--- a/src/corelib/thread/qatomic_cxx11.h
+++ b/src/corelib/thread/qatomic_cxx11.h
@@ -234,6 +234,18 @@ template <typename X> struct QAtomicOps
}
template <typename T> static inline
+ T loadRelaxed(const std::atomic<T> &_q_value) noexcept
+ {
+ return _q_value.load(std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
+ T loadRelaxed(const volatile std::atomic<T> &_q_value) noexcept
+ {
+ return _q_value.load(std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
T loadAcquire(const std::atomic<T> &_q_value) noexcept
{
return _q_value.load(std::memory_order_acquire);
@@ -252,6 +264,12 @@ template <typename X> struct QAtomicOps
}
template <typename T> static inline
+ void storeRelaxed(std::atomic<T> &_q_value, T newValue) noexcept
+ {
+ _q_value.store(newValue, std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
void storeRelease(std::atomic<T> &_q_value, T newValue) noexcept
{
_q_value.store(newValue, std::memory_order_release);
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 7d2e06a499..dc976819ef 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -99,9 +99,11 @@ public:
typename Ops::Type _q_value;
// Everything below is either implemented in ../arch/qatomic_XXX.h or (as fallback) in qgenericatomic.h
+ T load() const noexcept { return loadRelaxed(); }
+ void store(T newValue) noexcept { storeRelaxed(newValue); }
- T load() const noexcept { return Ops::load(_q_value); }
- void store(T newValue) noexcept { Ops::store(_q_value, newValue); }
+ T loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
+ void storeRelaxed(T newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
T loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); }
void storeRelease(T newValue) noexcept { Ops::storeRelease(_q_value, newValue); }
@@ -236,8 +238,12 @@ public:
AtomicType _q_value;
- Type load() const noexcept { return Ops::load(_q_value); }
- void store(Type newValue) noexcept { Ops::store(_q_value, newValue); }
+ Type load() const noexcept { return loadRelaxed(); }
+ void store(Type newValue) noexcept { storeRelaxed(newValue); }
+
+ Type loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
+ void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
+
operator Type() const noexcept { return loadAcquire(); }
Type operator=(Type newValue) noexcept { storeRelease(newValue); return newValue; }
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h
index a456dd9139..d3135510b3 100644
--- a/src/corelib/thread/qfuture.h
+++ b/src/corelib/thread/qfuture.h
@@ -111,33 +111,79 @@ public:
typedef const T &reference;
inline const_iterator() {}
- inline const_iterator(QFuture const * const _future, int _index) : future(_future), index(_index) {}
+ inline const_iterator(QFuture const * const _future, int _index)
+ : future(_future), index(advanceIndex(_index, 0)) { }
inline const_iterator(const const_iterator &o) : future(o.future), index(o.index) {}
inline const_iterator &operator=(const const_iterator &o)
{ future = o.future; index = o.index; return *this; }
inline const T &operator*() const { return future->d.resultReference(index); }
inline const T *operator->() const { return future->d.resultPointer(index); }
-
- inline bool operator!=(const const_iterator &other) const
+ inline bool operator!=(const const_iterator &other) const { return index != other.index; }
+ inline bool operator==(const const_iterator &o) const { return !operator!=(o); }
+ inline const_iterator &operator++()
+ { index = advanceIndex(index, 1); return *this; }
+ inline const_iterator &operator--()
+ { index = advanceIndex(index, -1); return *this; }
+ inline const_iterator operator++(int)
+ {
+ const_iterator r = *this;
+ index = advanceIndex(index, 1);
+ return r;
+ }
+ inline const_iterator operator--(int)
{
- if (index == -1 && other.index == -1) // comparing end != end?
- return false;
- if (other.index == -1)
- return (future->isRunning() || (index < future->resultCount()));
- return (index != other.index);
+ const_iterator r = *this;
+ index = advanceIndex(index, -1);
+ return r;
}
+ inline const_iterator operator+(int j) const
+ { return const_iterator(future, advanceIndex(index, j)); }
+ inline const_iterator operator-(int j) const
+ { return const_iterator(future, advanceIndex(index, -j)); }
+ inline const_iterator &operator+=(int j)
+ { index = advanceIndex(index, j); return *this; }
+ inline const_iterator &operator-=(int j)
+ { index = advanceIndex(index, -j); return *this; }
+ friend inline const_iterator operator+(int j, const_iterator k)
+ { return const_iterator(k.future, k.advanceIndex(k.index, j)); }
- inline bool operator==(const const_iterator &o) const { return !operator!=(o); }
- inline const_iterator &operator++() { ++index; return *this; }
- inline const_iterator operator++(int) { const_iterator r = *this; ++index; return r; }
- inline const_iterator &operator--() { --index; return *this; }
- inline const_iterator operator--(int) { const_iterator r = *this; --index; return r; }
- inline const_iterator operator+(int j) const { return const_iterator(future, index + j); }
- inline const_iterator operator-(int j) const { return const_iterator(future, index - j); }
- inline const_iterator &operator+=(int j) { index += j; return *this; }
- inline const_iterator &operator-=(int j) { index -= j; return *this; }
- friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
private:
+ /*! \internal
+
+ Advances the iterator index \a idx \a n steps, waits for the
+ result at the target index, and returns the target index.
+
+ The index may be -1, indicating the end iterator, either
+ as the argument or as the return value. The end iterator
+ may be decremented.
+
+ The caller is responsible for not advancing the iterator
+ before begin() or past end(), with the exception that
+ attempting to advance a non-end iterator past end() for
+ a running future is allowed and will return the end iterator.
+
+ Note that n == 0 is valid and will wait for the result
+ at the given index.
+ */
+ int advanceIndex(int idx, int n) const
+ {
+ // The end iterator can be decremented, leave as-is for other cases
+ if (idx == -1 && n >= 0)
+ return idx;
+
+ // Special case for decrementing the end iterator: wait for
+ // finished to get the total result count.
+ if (idx == -1 && future->isRunning())
+ future->d.waitForFinished();
+
+ // Wait for result at target index
+ const int targetIndex = (idx == -1) ? future->resultCount() + n : idx + n;
+ future->d.waitForResult(targetIndex);
+
+ // After waiting there is either a result or the end was reached
+ return (targetIndex < future->resultCount()) ? targetIndex : -1;
+ }
+
QFuture const * future;
int index;
};
diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc
index 7db65dacd3..076725e19c 100644
--- a/src/corelib/thread/qfuture.qdoc
+++ b/src/corelib/thread/qfuture.qdoc
@@ -55,8 +55,8 @@
instance, the computation can be canceled with the cancel() function. To
pause the computation, use the setPaused() function or one of the pause(),
resume(), or togglePaused() convenience functions. Be aware that not all
- asynchronous computations can be canceled or paused. For example, the
- future returned by QtConcurrent::run() cannot be canceled; but the
+ running asynchronous computations can be canceled or paused. For example,
+ the future returned by QtConcurrent::run() cannot be canceled; but the
future returned by QtConcurrent::mappedReduced() can.
Progress information is provided by the progressValue(),
@@ -133,8 +133,8 @@
Any QFutureWatcher object that is watching this future will not deliver
progress and result ready signals on a canceled future.
- Be aware that not all asynchronous computations can be canceled. For
- example, the future returned by QtConcurrent::run() cannot be canceled;
+ Be aware that not all running asynchronous computations can be canceled.
+ For example, the future returned by QtConcurrent::run() cannot be canceled;
but the future returned by QtConcurrent::mappedReduced() can.
*/
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index dfbed5fb0f..8f4cae8816 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -97,7 +97,7 @@ static inline int switch_off(QAtomicInt &a, int which)
static inline int switch_from_to(QAtomicInt &a, int from, int to)
{
int newValue;
- int expected = a.load();
+ int expected = a.loadRelaxed();
do {
newValue = (expected & ~from) | to;
} while (!a.testAndSetRelaxed(expected, newValue, expected));
@@ -107,7 +107,7 @@ static inline int switch_from_to(QAtomicInt &a, int from, int to)
void QFutureInterfaceBase::cancel()
{
QMutexLocker locker(&d->m_mutex);
- if (d->state.load() & Canceled)
+ if (d->state.loadRelaxed() & Canceled)
return;
switch_from_to(d->state, Paused, Canceled);
@@ -132,7 +132,7 @@ void QFutureInterfaceBase::setPaused(bool paused)
void QFutureInterfaceBase::togglePaused()
{
QMutexLocker locker(&d->m_mutex);
- if (d->state.load() & Paused) {
+ if (d->state.loadRelaxed() & Paused) {
switch_off(d->state, Paused);
d->pausedWaitCondition.wakeAll();
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Resumed));
@@ -149,7 +149,7 @@ void QFutureInterfaceBase::setThrottled(bool enable)
switch_on(d->state, Throttled);
} else {
switch_off(d->state, Throttled);
- if (!(d->state.load() & Paused))
+ if (!(d->state.loadRelaxed() & Paused))
d->pausedWaitCondition.wakeAll();
}
}
@@ -201,13 +201,13 @@ void QFutureInterfaceBase::waitForResume()
{
// return early if possible to avoid taking the mutex lock.
{
- const int state = d->state.load();
+ const int state = d->state.loadRelaxed();
if (!(state & Paused) || (state & Canceled))
return;
}
QMutexLocker lock(&d->m_mutex);
- const int state = d->state.load();
+ const int state = d->state.loadRelaxed();
if (!(state & Paused) || (state & Canceled))
return;
@@ -256,7 +256,7 @@ bool QFutureInterfaceBase::isProgressUpdateNeeded() const
void QFutureInterfaceBase::reportStarted()
{
QMutexLocker locker(&d->m_mutex);
- if (d->state.load() & (Started|Canceled|Finished))
+ if (d->state.loadRelaxed() & (Started|Canceled|Finished))
return;
d->setState(State(Started | Running));
@@ -272,7 +272,7 @@ void QFutureInterfaceBase::reportCanceled()
void QFutureInterfaceBase::reportException(const QException &exception)
{
QMutexLocker locker(&d->m_mutex);
- if (d->state.load() & (Canceled|Finished))
+ if (d->state.loadRelaxed() & (Canceled|Finished))
return;
d->m_exceptionStore.setException(exception);
@@ -307,7 +307,7 @@ int QFutureInterfaceBase::expectedResultCount()
bool QFutureInterfaceBase::queryState(State state) const
{
- return d->state.load() & state;
+ return d->state.loadRelaxed() & state;
}
void QFutureInterfaceBase::waitForResult(int resultIndex)
@@ -352,7 +352,7 @@ void QFutureInterfaceBase::waitForFinished()
void QFutureInterfaceBase::reportResultsReady(int beginIndex, int endIndex)
{
- if (beginIndex == endIndex || (d->state.load() & (Canceled|Finished)))
+ if (beginIndex == endIndex || (d->state.loadRelaxed() & (Canceled|Finished)))
return;
d->waitCondition.wakeAll();
@@ -414,7 +414,7 @@ void QFutureInterfaceBase::setProgressValueAndText(int progressValue,
if (d->m_progressValue >= progressValue)
return;
- if (d->state.load() & (Canceled|Finished))
+ if (d->state.loadRelaxed() & (Canceled|Finished))
return;
if (d->internal_updateProgress(progressValue, progressText)) {
@@ -486,10 +486,10 @@ bool QFutureInterfaceBasePrivate::internal_waitForNextResult()
if (m_results.hasNextResult())
return true;
- while ((state.load() & QFutureInterfaceBase::Running) && m_results.hasNextResult() == false)
+ while ((state.loadRelaxed() & QFutureInterfaceBase::Running) && m_results.hasNextResult() == false)
waitCondition.wait(&m_mutex);
- return !(state.load() & QFutureInterfaceBase::Canceled) && m_results.hasNextResult();
+ return !(state.loadRelaxed() & QFutureInterfaceBase::Canceled) && m_results.hasNextResult();
}
bool QFutureInterfaceBasePrivate::internal_updateProgress(int progress,
@@ -512,8 +512,8 @@ bool QFutureInterfaceBasePrivate::internal_updateProgress(int progress,
void QFutureInterfaceBasePrivate::internal_setThrottled(bool enable)
{
// bail out if we are not changing the state
- if ((enable && (state.load() & QFutureInterfaceBase::Throttled))
- || (!enable && !(state.load() & QFutureInterfaceBase::Throttled)))
+ if ((enable && (state.loadRelaxed() & QFutureInterfaceBase::Throttled))
+ || (!enable && !(state.loadRelaxed() & QFutureInterfaceBase::Throttled)))
return;
// change the state
@@ -521,7 +521,7 @@ void QFutureInterfaceBasePrivate::internal_setThrottled(bool enable)
switch_on(state, QFutureInterfaceBase::Throttled);
} else {
switch_off(state, QFutureInterfaceBase::Throttled);
- if (!(state.load() & QFutureInterfaceBase::Paused))
+ if (!(state.loadRelaxed() & QFutureInterfaceBase::Paused))
pausedWaitCondition.wakeAll();
}
}
@@ -556,7 +556,7 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface
{
QMutexLocker locker(&m_mutex);
- if (state.load() & QFutureInterfaceBase::Started) {
+ if (state.loadRelaxed() & QFutureInterfaceBase::Started) {
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Started));
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::ProgressRange,
m_progressMinimum,
@@ -576,13 +576,13 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface
it.batchedAdvance();
}
- if (state.load() & QFutureInterfaceBase::Paused)
+ if (state.loadRelaxed() & QFutureInterfaceBase::Paused)
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Paused));
- if (state.load() & QFutureInterfaceBase::Canceled)
+ if (state.loadRelaxed() & QFutureInterfaceBase::Canceled)
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Canceled));
- if (state.load() & QFutureInterfaceBase::Finished)
+ if (state.loadRelaxed() & QFutureInterfaceBase::Finished)
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Finished));
outputConnections.append(interface);
@@ -601,7 +601,7 @@ void QFutureInterfaceBasePrivate::disconnectOutputInterface(QFutureCallOutInterf
void QFutureInterfaceBasePrivate::setState(QFutureInterfaceBase::State newState)
{
- state.store(newState);
+ state.storeRelaxed(newState);
}
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h
index 63e534464f..b297dff633 100644
--- a/src/corelib/thread/qfutureinterface_p.h
+++ b/src/corelib/thread/qfutureinterface_p.h
@@ -144,11 +144,11 @@ public:
// Default ref counter for QFIBP
inline bool ref() { return m_refCount.ref(); }
inline bool deref() { return m_refCount.deref(); }
- inline int load() const { return m_refCount.load(); }
+ inline int load() const { return m_refCount.loadRelaxed(); }
// Ref counter for type T
inline bool refT() { return m_refCountT.ref(); }
inline bool derefT() { return m_refCountT.deref(); }
- inline int loadT() const { return m_refCountT.load(); }
+ inline int loadT() const { return m_refCountT.loadRelaxed(); }
private:
QAtomicInt m_refCount;
diff --git a/src/corelib/thread/qfuturewatcher.cpp b/src/corelib/thread/qfuturewatcher.cpp
index 4ee7693ace..06bc4740f9 100644
--- a/src/corelib/thread/qfuturewatcher.cpp
+++ b/src/corelib/thread/qfuturewatcher.cpp
@@ -84,8 +84,8 @@ QT_BEGIN_NAMESPACE
\snippet code/src_corelib_thread_qfuturewatcher.cpp 0
- Be aware that not all asynchronous computations can be canceled or paused.
- For example, the future returned by QtConcurrent::run() cannot be
+ Be aware that not all running asynchronous computations can be canceled or
+ paused. For example, the future returned by QtConcurrent::run() cannot be
canceled; but the future returned by QtConcurrent::mappedReduced() can.
QFutureWatcher<void> is specialized to not contain any of the result
@@ -124,9 +124,9 @@ QFutureWatcherBase::QFutureWatcherBase(QObject *parent)
progressRangeChanged(), progressTextChanged(), resultReadyAt(), and
resultsReadyAt() signals.
- Be aware that not all asynchronous computations can be canceled. For
- example, the QFuture returned by QtConcurrent::run() cannot be canceled;
- but the QFuture returned by QtConcurrent::mappedReduced() can.
+ Be aware that not all running asynchronous computations can be canceled.
+ For example, the QFuture returned by QtConcurrent::run() cannot be
+ canceled; but the QFuture returned by QtConcurrent::mappedReduced() can.
*/
void QFutureWatcherBase::cancel()
{
@@ -402,7 +402,7 @@ void QFutureWatcherBase::disconnectOutputInterface(bool pendingAssignment)
{
if (pendingAssignment) {
Q_D(QFutureWatcherBase);
- d->pendingResultsReady.store(0);
+ d->pendingResultsReady.storeRelaxed(0);
qDeleteAll(d->pendingCallOutEvents);
d->pendingCallOutEvents.clear();
d->finished = false; /* May soon be amended, during connectOutputInterface() */
@@ -441,7 +441,7 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
emit q->finished();
break;
case QFutureCallOutEvent::Canceled:
- pendingResultsReady.store(0);
+ pendingResultsReady.storeRelaxed(0);
emit q->canceled();
break;
case QFutureCallOutEvent::Paused:
@@ -466,7 +466,7 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
emit q->resultsReadyAt(beginIndex, endIndex);
- if (resultAtConnected.load() <= 0)
+ if (resultAtConnected.loadRelaxed() <= 0)
break;
for (int i = beginIndex; i < endIndex; ++i)
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index f8333e7de6..e9e5f3c74b 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -97,6 +97,18 @@ template <typename BaseClass> struct QGenericAtomicOps
}
template <typename T> static Q_ALWAYS_INLINE
+ T loadRelaxed(const T &_q_value) noexcept
+ {
+ return _q_value;
+ }
+
+ template <typename T, typename X> static Q_ALWAYS_INLINE
+ void storeRelaxed(T &_q_value, X newValue) noexcept
+ {
+ _q_value = newValue;
+ }
+
+ template <typename T> static Q_ALWAYS_INLINE
T loadAcquire(const T &_q_value) noexcept
{
T tmp = *static_cast<const volatile T *>(&_q_value);
@@ -190,7 +202,7 @@ template <typename BaseClass> struct QGenericAtomicOps
{
// implement fetchAndStore on top of testAndSet
Q_FOREVER {
- T tmp = load(_q_value);
+ T tmp = loadRelaxed(_q_value);
if (BaseClass::testAndSetRelaxed(_q_value, tmp, newValue))
return tmp;
}
@@ -225,7 +237,7 @@ template <typename BaseClass> struct QGenericAtomicOps
{
// implement fetchAndAdd on top of testAndSet
Q_FOREVER {
- T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::loadRelaxed(_q_value);
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp + valueToAdd)))
return tmp;
}
@@ -289,7 +301,7 @@ QT_WARNING_POP
T fetchAndAndRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
// implement fetchAndAnd on top of testAndSet
- T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::loadRelaxed(_q_value);
Q_FOREVER {
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp & operand), &tmp))
return tmp;
@@ -322,7 +334,7 @@ QT_WARNING_POP
T fetchAndOrRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
// implement fetchAndOr on top of testAndSet
- T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::loadRelaxed(_q_value);
Q_FOREVER {
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp | operand), &tmp))
return tmp;
@@ -355,7 +367,7 @@ QT_WARNING_POP
T fetchAndXorRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
// implement fetchAndXor on top of testAndSet
- T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::loadRelaxed(_q_value);
Q_FOREVER {
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp ^ operand), &tmp))
return tmp;
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 4f55e50fe5..9e52f286ee 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -147,7 +147,7 @@ public:
It is constructed and destroyed with almost no overhead,
which means it is fine to have many mutexes as part of other classes.
- \sa QMutexLocker, QReadWriteLock, QSemaphore, QWaitCondition
+ \sa QRecursiveMutex, QMutexLocker, QReadWriteLock, QSemaphore, QWaitCondition
*/
/*!
@@ -156,12 +156,19 @@ public:
\value Recursive In this mode, a thread can lock the same mutex
multiple times and the mutex won't be unlocked
until a corresponding number of unlock() calls
- have been made.
+ have been made. You should use QRecursiveMutex
+ for this use-case.
\value NonRecursive In this mode, a thread may only lock a mutex
once.
- \sa QMutex()
+ \sa QMutex(), QRecursiveMutex
+*/
+
+/*!
+ \fn QMutex::QMutex()
+
+ Constructs a new mutex. The mutex is created in an unlocked state.
*/
/*!
@@ -179,7 +186,7 @@ public:
*/
QMutex::QMutex(RecursionMode mode)
{
- d_ptr.store(mode == Recursive ? new QRecursiveMutexPrivate : 0);
+ d_ptr.storeRelaxed(mode == Recursive ? new QRecursiveMutexPrivate : 0);
}
/*!
@@ -189,12 +196,12 @@ QMutex::QMutex(RecursionMode mode)
*/
QMutex::~QMutex()
{
- QMutexData *d = d_ptr.load();
+ QMutexData *d = d_ptr.loadRelaxed();
if (isRecursive()) {
delete static_cast<QRecursiveMutexPrivate *>(d);
} else if (d) {
#ifndef QT_LINUX_FUTEX
- if (d != dummyLocked() && static_cast<QMutexPrivate *>(d)->possiblyUnlocked.load()
+ if (d != dummyLocked() && static_cast<QMutexPrivate *>(d)->possiblyUnlocked.loadRelaxed()
&& tryLock()) {
unlock();
return;
@@ -205,13 +212,15 @@ QMutex::~QMutex()
}
/*! \fn void QMutex::lock()
+ \fn QRecursiveMutex::lock()
+
Locks the mutex. If another thread has locked the mutex then this
call will block until that thread has unlocked it.
Calling this function multiple times on the same mutex from the
same thread is allowed if this mutex is a
- \l{QMutex::Recursive}{recursive mutex}. If this mutex is a
- \l{QMutex::NonRecursive}{non-recursive mutex}, this function will
+ \l{QRecursiveMutex}{recursive mutex}. If this mutex is a
+ \l{QMutex}{non-recursive mutex}, this function will
\e dead-lock when the mutex is locked recursively.
\sa unlock()
@@ -228,6 +237,7 @@ void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
}
/*! \fn bool QMutex::tryLock(int timeout)
+ \fn bool QRecursiveMutex::tryLock(int timeout)
Attempts to lock the mutex. This function returns \c true if the lock
was obtained; otherwise it returns \c false. If another thread has
@@ -243,8 +253,8 @@ void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
Calling this function multiple times on the same mutex from the
same thread is allowed if this mutex is a
- \l{QMutex::Recursive}{recursive mutex}. If this mutex is a
- \l{QMutex::NonRecursive}{non-recursive mutex}, this function will
+ \l{QRecursiveMutex}{recursive mutex}. If this mutex is a
+ \l{QMutex}{non-recursive mutex}, this function will
\e always return false when attempting to lock the mutex
recursively.
@@ -262,6 +272,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
}
/*! \fn bool QMutex::try_lock()
+ \fn bool QRecursiveMutex::try_lock()
\since 5.8
Attempts to lock the mutex. This function returns \c true if the lock
@@ -275,6 +286,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
/*! \fn template <class Rep, class Period> bool QMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
+ \fn template <class Rep, class Period> bool QRecursiveMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
\since 5.8
Attempts to lock the mutex. This function returns \c true if the lock
@@ -290,8 +302,8 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
Calling this function multiple times on the same mutex from the
same thread is allowed if this mutex is a
- \l{QMutex::Recursive}{recursive mutex}. If this mutex is a
- \l{QMutex::NonRecursive}{non-recursive mutex}, this function will
+ \l{QRecursiveMutex}{recursive mutex}. If this mutex is a
+ \l{QMutex}{non-recursive mutex}, this function will
\e always return false when attempting to lock the mutex
recursively.
@@ -299,6 +311,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
/*! \fn template<class Clock, class Duration> bool QMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
+ \fn template<class Clock, class Duration> bool QRecursiveMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
\since 5.8
Attempts to lock the mutex. This function returns \c true if the lock
@@ -314,8 +327,8 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
Calling this function multiple times on the same mutex from the
same thread is allowed if this mutex is a
- \l{QMutex::Recursive}{recursive mutex}. If this mutex is a
- \l{QMutex::NonRecursive}{non-recursive mutex}, this function will
+ \l{QRecursiveMutex}{recursive mutex}. If this mutex is a
+ \l{QMutex}{non-recursive mutex}, this function will
\e always return false when attempting to lock the mutex
recursively.
@@ -323,6 +336,8 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
/*! \fn void QMutex::unlock()
+ \fn void QRecursiveMutex::unlock()
+
Unlocks the mutex. Attempting to unlock a mutex in a different
thread to the one that locked it results in an error. Unlocking a
mutex that is not locked results in undefined behavior.
@@ -364,6 +379,58 @@ bool QBasicMutex::isRecursive() const noexcept
}
/*!
+ \class QRecursiveMutex
+ \inmodule QtCore
+ \since 5.14
+ \brief The QRecursiveMutex class provides access serialization between threads.
+
+ \threadsafe
+
+ \ingroup thread
+
+ The QRecursiveMutex class is a mutex, like QMutex, with which it is
+ API-compatible. It differs from QMutex by accepting lock() calls from
+ the same thread any number of times. QMutex would deadlock in this situation.
+
+ QRecursiveMutex is much more expensive to construct and operate on, so
+ use a plain QMutex whenever you can. Sometimes, one public function,
+ however, calls another public function, and they both need to lock the
+ same mutex. In this case, you have two options:
+
+ \list
+ \li Factor the code that needs mutex protection into private functions,
+ which assume that the mutex is held when they are called, and lock a
+ plain QMutex in the public functions before you call the private
+ implementation ones.
+ \li Or use a recursive mutex, so it doesn't matter that the first public
+ function has already locked the mutex when the second one wishes to do so.
+ \endlist
+
+ \sa QMutex, QMutexLocker, QReadWriteLock, QSemaphore, QWaitCondition
+*/
+
+/*!
+ Constructs a new recursive mutex. The mutex is created in an unlocked state.
+
+ \sa lock(), unlock()
+*/
+QRecursiveMutex::QRecursiveMutex()
+ : QMutex()
+{
+ d_ptr.storeRelaxed(new QRecursiveMutexPrivate);
+}
+
+/*!
+ Destroys the mutex.
+
+ \warning Destroying a locked mutex may result in undefined behavior.
+*/
+QRecursiveMutex::~QRecursiveMutex()
+{
+ delete static_cast<QRecursiveMutexPrivate*>(d_ptr.fetchAndStoreAcquire(nullptr));
+}
+
+/*!
\class QMutexLocker
\inmodule QtCore
\brief The QMutexLocker class is a convenience class that simplifies
@@ -427,6 +494,17 @@ bool QBasicMutex::isRecursive() const noexcept
*/
/*!
+ \fn QMutexLocker::QMutexLocker(QRecursiveMutex *mutex)
+ \since 5.14
+
+ Constructs a QMutexLocker and locks \a mutex. The mutex will be
+ unlocked (unlock() called) when the QMutexLocker is destroyed.
+ If \a mutex is \nullptr, QMutexLocker does nothing.
+
+ \sa QMutex::lock()
+*/
+
+/*!
\fn QMutexLocker::~QMutexLocker()
Destroys the QMutexLocker and unlocks the mutex that was locked
@@ -517,7 +595,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
}
QMutexPrivate *d = static_cast<QMutexPrivate *>(copy);
- if (timeout == 0 && !d->possiblyUnlocked.load())
+ if (timeout == 0 && !d->possiblyUnlocked.loadRelaxed())
return false;
// At this point we have a pointer to a QMutexPrivate. But the other thread
@@ -541,7 +619,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
// is set to the BigNumber magic value set in unlockInternal()
int old_waiters;
do {
- old_waiters = d->waiters.load();
+ old_waiters = d->waiters.loadRelaxed();
if (old_waiters == -QMutexPrivate::BigNumber) {
// we are unlocking, and the thread that unlocks is about to change d to 0
// we try to acquire the mutex by changing to dummyLocked()
@@ -550,7 +628,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
d->deref();
return true;
} else {
- Q_ASSERT(d != d_ptr.load()); //else testAndSetAcquire should have succeeded
+ Q_ASSERT(d != d_ptr.loadRelaxed()); //else testAndSetAcquire should have succeeded
// Mutex is likely to bo 0, we should continue the outer-loop,
// set old_waiters to the magic value of BigNumber
old_waiters = QMutexPrivate::BigNumber;
@@ -563,7 +641,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
// The mutex was unlocked before we incremented waiters.
if (old_waiters != QMutexPrivate::BigNumber) {
//we did not break the previous loop
- Q_ASSERT(d->waiters.load() >= 1);
+ Q_ASSERT(d->waiters.loadRelaxed() >= 1);
d->waiters.deref();
}
d->deref();
@@ -572,11 +650,11 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
if (d->wait(timeout)) {
// reset the possiblyUnlocked flag if needed (and deref its corresponding reference)
- if (d->possiblyUnlocked.load() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
+ if (d->possiblyUnlocked.loadRelaxed() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
d->deref();
d->derefWaiters(1);
//we got the lock. (do not deref)
- Q_ASSERT(d == d_ptr.load());
+ Q_ASSERT(d == d_ptr.loadRelaxed());
return true;
} else {
Q_ASSERT(timeout >= 0);
@@ -593,7 +671,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
return false;
}
}
- Q_ASSERT(d_ptr.load() != 0);
+ Q_ASSERT(d_ptr.loadRelaxed() != 0);
return true;
}
@@ -618,7 +696,7 @@ void QBasicMutex::unlockInternal() noexcept
//there is no one waiting on this mutex anymore, set the mutex as unlocked (d = 0)
if (d_ptr.testAndSetRelease(d, 0)) {
// reset the possiblyUnlocked flag if needed (and deref its corresponding reference)
- if (d->possiblyUnlocked.load() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
+ if (d->possiblyUnlocked.loadRelaxed() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
d->deref();
}
d->derefWaiters(0);
@@ -657,20 +735,20 @@ QMutexPrivate *QMutexPrivate::allocate()
int i = freelist()->next();
QMutexPrivate *d = &(*freelist())[i];
d->id = i;
- Q_ASSERT(d->refCount.load() == 0);
+ Q_ASSERT(d->refCount.loadRelaxed() == 0);
Q_ASSERT(!d->recursive);
- Q_ASSERT(!d->possiblyUnlocked.load());
- Q_ASSERT(d->waiters.load() == 0);
- d->refCount.store(1);
+ Q_ASSERT(!d->possiblyUnlocked.loadRelaxed());
+ Q_ASSERT(d->waiters.loadRelaxed() == 0);
+ d->refCount.storeRelaxed(1);
return d;
}
void QMutexPrivate::release()
{
Q_ASSERT(!recursive);
- Q_ASSERT(refCount.load() == 0);
- Q_ASSERT(!possiblyUnlocked.load());
- Q_ASSERT(waiters.load() == 0);
+ Q_ASSERT(refCount.loadRelaxed() == 0);
+ Q_ASSERT(!possiblyUnlocked.loadRelaxed());
+ Q_ASSERT(waiters.loadRelaxed() == 0);
freelist()->release(id);
}
@@ -680,7 +758,7 @@ void QMutexPrivate::derefWaiters(int value) noexcept
int old_waiters;
int new_waiters;
do {
- old_waiters = waiters.load();
+ old_waiters = waiters.loadRelaxed();
new_waiters = old_waiters;
if (new_waiters < 0) {
new_waiters += QMutexPrivate::BigNumber;
@@ -696,7 +774,7 @@ void QMutexPrivate::derefWaiters(int value) noexcept
inline bool QRecursiveMutexPrivate::lock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
{
Qt::HANDLE self = QThread::currentThreadId();
- if (owner.load() == self) {
+ if (owner.loadRelaxed() == self) {
++count;
Q_ASSERT_X(count != 0, "QMutex::lock", "Overflow in recursion counter");
return true;
@@ -709,7 +787,7 @@ inline bool QRecursiveMutexPrivate::lock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
}
if (success)
- owner.store(self);
+ owner.storeRelaxed(self);
return success;
}
@@ -721,7 +799,7 @@ inline void QRecursiveMutexPrivate::unlock() noexcept
if (count > 0) {
count--;
} else {
- owner.store(0);
+ owner.storeRelaxed(0);
mutex.QBasicMutex::unlock();
}
}
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index d7796092d1..c693ff65d8 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -62,6 +62,8 @@ QT_BEGIN_NAMESPACE
# define QT_MUTEX_LOCK_NOEXCEPT
#endif
+class QMutex;
+class QRecursiveMutex;
class QMutexData;
class Q_CORE_EXPORT QBasicMutex
@@ -81,7 +83,7 @@ public:
// BasicLockable concept
inline void unlock() noexcept {
- Q_ASSERT(d_ptr.load()); //mutex must be locked
+ Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked
if (!fastTryUnlock())
unlockInternal();
}
@@ -120,14 +122,20 @@ private:
}
friend class QMutex;
+ friend class QRecursiveMutex;
friend class QMutexData;
};
class Q_CORE_EXPORT QMutex : public QBasicMutex
{
public:
+#if defined(Q_COMPILER_CONSTEXPR)
+ constexpr QMutex() = default;
+#else
+ QMutex() { d_ptr.storeRelaxed(nullptr); }
+#endif
enum RecursionMode { NonRecursive, Recursive };
- explicit QMutex(RecursionMode mode = NonRecursive);
+ explicit QMutex(RecursionMode mode);
~QMutex();
// BasicLockable concept
@@ -164,6 +172,7 @@ public:
private:
Q_DISABLE_COPY(QMutex)
friend class QMutexLocker;
+ friend class QRecursiveMutex;
friend class ::tst_QMutex;
#if QT_HAS_INCLUDE(<chrono>)
@@ -192,6 +201,24 @@ private:
#endif
};
+class QRecursiveMutex : private QMutex
+{
+ // ### Qt 6: make it independent of QMutex
+ friend class QMutexLocker;
+public:
+ Q_CORE_EXPORT QRecursiveMutex();
+ Q_CORE_EXPORT ~QRecursiveMutex();
+
+ using QMutex::lock;
+ using QMutex::tryLock;
+ using QMutex::unlock;
+ using QMutex::try_lock;
+#if QT_HAS_INCLUDE(<chrono>)
+ using QMutex::try_lock_for;
+ using QMutex::try_lock_until;
+#endif
+};
+
class Q_CORE_EXPORT QMutexLocker
{
public:
@@ -207,8 +234,11 @@ public:
val |= 1;
}
}
+ explicit QMutexLocker(QRecursiveMutex *m) QT_MUTEX_LOCK_NOEXCEPT
+ : QMutexLocker{static_cast<QBasicMutex*>(m)} {}
#else
QMutexLocker(QMutex *) { }
+ QMutexLocker(QRecursiveMutex *) {}
#endif
inline ~QMutexLocker() { unlock(); }
@@ -285,6 +315,8 @@ private:
Q_DISABLE_COPY(QMutex)
};
+class QRecursiveMutex : public QMutex {};
+
class Q_CORE_EXPORT QMutexLocker
{
public:
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
index b006ff1033..3270875471 100644
--- a/src/corelib/thread/qmutex_linux.cpp
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -149,7 +149,7 @@ bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -
}
}
- Q_ASSERT(d_ptr.load());
+ Q_ASSERT(d_ptr.loadRelaxed());
return true;
}
@@ -169,7 +169,7 @@ bool QBasicMutex::lockInternal(int timeout) noexcept
void QBasicMutex::unlockInternal() noexcept
{
- QMutexData *d = d_ptr.load();
+ QMutexData *d = d_ptr.loadRelaxed();
Q_ASSERT(d); //we must be locked
Q_ASSERT(d != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed
Q_UNUSED(d);
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index 5025f836b9..048d8707c4 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -99,21 +99,21 @@ public:
int id;
bool ref() {
- Q_ASSERT(refCount.load() >= 0);
+ Q_ASSERT(refCount.loadRelaxed() >= 0);
int c;
do {
- c = refCount.load();
+ c = refCount.loadRelaxed();
if (c == 0)
return false;
} while (!refCount.testAndSetRelaxed(c, c + 1));
- Q_ASSERT(refCount.load() >= 0);
+ Q_ASSERT(refCount.loadRelaxed() >= 0);
return true;
}
void deref() {
- Q_ASSERT(refCount.load() >= 0);
+ Q_ASSERT(refCount.loadRelaxed() >= 0);
if (!refCount.deref())
release();
- Q_ASSERT(refCount.load() >= 0);
+ Q_ASSERT(refCount.loadRelaxed() >= 0);
}
void release();
static QMutexPrivate *allocate();
diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp
index 3f9e8da942..3ece30c01c 100644
--- a/src/corelib/thread/qmutexpool.cpp
+++ b/src/corelib/thread/qmutexpool.cpp
@@ -93,7 +93,7 @@ QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size)
: mutexes(size), recursionMode(recursionMode)
{
for (int index = 0; index < mutexes.count(); ++index) {
- mutexes[index].store(0);
+ mutexes[index].storeRelaxed(0);
}
}
@@ -104,7 +104,7 @@ QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size)
QMutexPool::~QMutexPool()
{
for (int index = 0; index < mutexes.count(); ++index)
- delete mutexes[index].load();
+ delete mutexes[index].loadAcquire();
}
/*!
@@ -129,9 +129,12 @@ QMutex *QMutexPool::createMutex(int index)
{
// mutex not created, create one
QMutex *newMutex = new QMutex(recursionMode);
- if (!mutexes[index].testAndSetRelease(0, newMutex))
+ if (!mutexes[index].testAndSetRelease(nullptr, newMutex)) {
delete newMutex;
- return mutexes[index].load();
+ return mutexes[index].loadAcquire();
+ } else {
+ return newMutex;
+ }
}
/*!
diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h
index 89d006ac29..00710199b8 100644
--- a/src/corelib/thread/qmutexpool_p.h
+++ b/src/corelib/thread/qmutexpool_p.h
@@ -68,7 +68,7 @@ public:
inline QMutex *get(const void *address) {
int index = uint(quintptr(address)) % mutexes.count();
- QMutex *m = mutexes[index].load();
+ QMutex *m = mutexes[index].loadAcquire();
if (m)
return m;
else
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index d7cf7a7284..30e9b95a52 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -143,7 +143,7 @@ inline bool isUncontendedLocked(const QReadWriteLockPrivate *d)
QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
: d_ptr(recursionMode == Recursive ? new QReadWriteLockPrivate(true) : nullptr)
{
- Q_ASSERT_X(!(quintptr(d_ptr.load()) & StateMask), "QReadWriteLock::QReadWriteLock", "bad d_ptr alignment");
+ Q_ASSERT_X(!(quintptr(d_ptr.loadRelaxed()) & StateMask), "QReadWriteLock::QReadWriteLock", "bad d_ptr alignment");
}
/*!
@@ -154,7 +154,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
*/
QReadWriteLock::~QReadWriteLock()
{
- auto d = d_ptr.load();
+ auto d = d_ptr.loadRelaxed();
if (isUncontendedLocked(d)) {
qWarning("QReadWriteLock: destroying locked QReadWriteLock");
return;
@@ -263,7 +263,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
return d->recursiveLockForRead(timeout);
QMutexLocker lock(&d->mutex);
- if (d != d_ptr.load()) {
+ if (d != d_ptr.loadRelaxed()) {
// d_ptr has changed: this QReadWriteLock was unlocked before we had
// time to lock d->mutex.
// We are holding a lock to a mutex within a QReadWriteLockPrivate
@@ -370,7 +370,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
return d->recursiveLockForWrite(timeout);
QMutexLocker lock(&d->mutex);
- if (d != d_ptr.load()) {
+ if (d != d_ptr.loadRelaxed()) {
// The mutex was unlocked before we had time to lock the mutex.
// We are holding to a mutex within a QReadWriteLockPrivate that is already released
// (or even is already re-used) but that's ok because the QFreeList never frees them.
@@ -433,7 +433,7 @@ void QReadWriteLock::unlock()
if (d->waitingReaders || d->waitingWriters) {
d->unlock();
} else {
- Q_ASSERT(d_ptr.load() == d); // should not change when we still hold the mutex
+ Q_ASSERT(d_ptr.loadRelaxed() == d); // should not change when we still hold the mutex
d_ptr.storeRelease(nullptr);
d->release();
}
@@ -444,7 +444,7 @@ void QReadWriteLock::unlock()
/*! \internal Helper for QWaitCondition::wait */
QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
{
- QReadWriteLockPrivate *d = d_ptr.load();
+ QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
switch (quintptr(d) & StateMask) {
case StateLockedForRead: return LockedForRead;
case StateLockedForWrite: return LockedForWrite;
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 2e0b6f2bc0..d4fb756b94 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -264,7 +264,7 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
if (futexHasWaiterCount) {
// decrement the number of threads waiting
- Q_ASSERT(futexHigh32(&u)->load() & 0x7fffffffU);
+ Q_ASSERT(futexHigh32(&u)->loadRelaxed() & 0x7fffffffU);
u.fetchAndSubRelaxed(oneWaiter);
}
return false;
@@ -293,7 +293,7 @@ QSemaphore::QSemaphore(int n)
quintptr nn = unsigned(n);
if (futexHasWaiterCount)
nn |= quint64(nn) << 32; // token count replicated in high word
- u.store(nn);
+ u.storeRelaxed(nn);
} else {
d = new QSemaphorePrivate(n);
}
@@ -425,7 +425,7 @@ void QSemaphore::release(int n)
int QSemaphore::available() const
{
if (futexAvailable())
- return futexAvailCounter(u.load());
+ return futexAvailCounter(u.loadRelaxed());
QMutexLocker locker(&d->mutex);
return d->avail;
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index b9b9f3e354..280c785049 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -65,7 +65,7 @@ QThreadData::QThreadData(int initialRefCount)
QThreadData::~QThreadData()
{
- Q_ASSERT(_ref.load() == 0);
+ Q_ASSERT(_ref.loadRelaxed() == 0);
// In the odd case that Qt is running on a secondary thread, the main
// thread instance will have been dereffed asunder because of the deref in
@@ -73,8 +73,8 @@ QThreadData::~QThreadData()
// crashing during QCoreApplicationData's global static cleanup we need to
// safeguard the main thread here.. This fix is a bit crude, but it solves
// the problem...
- if (this->thread == QCoreApplicationPrivate::theMainThread) {
- QCoreApplicationPrivate::theMainThread = 0;
+ if (this->thread.loadAcquire() == QCoreApplicationPrivate::theMainThread.loadAcquire()) {
+ QCoreApplicationPrivate::theMainThread.storeRelease(nullptr);
QThreadData::clearCurrentThreadData();
}
@@ -85,8 +85,8 @@ QThreadData::~QThreadData()
// because this destructor is still running (the _ref sub-object has not
// been destroyed) and there's no reentrancy. The refcount will become
// negative, but that's acceptable.
- QThread *t = thread;
- thread = 0;
+ QThread *t = thread.loadAcquire();
+ thread.storeRelease(nullptr);
delete t;
for (int i = 0; i < postEventList.size(); ++i) {
@@ -105,7 +105,7 @@ void QThreadData::ref()
{
#if QT_CONFIG(thread)
(void) _ref.ref();
- Q_ASSERT(_ref.load() != 0);
+ Q_ASSERT(_ref.loadRelaxed() != 0);
#endif
}
@@ -171,6 +171,11 @@ QThreadPrivate::QThreadPrivate(QThreadData *d)
// to 128K.
#ifdef Q_OS_INTEGRITY
stackSize = 128 * 1024;
+#elif defined(Q_OS_RTEMS)
+ static bool envStackSizeOk = false;
+ static const int envStackSize = qEnvironmentVariableIntValue("QT_DEFAULT_THREAD_STACK_SIZE", &envStackSizeOk);
+ if (envStackSizeOk)
+ stackSize = envStackSize;
#endif
#if defined (Q_OS_WIN)
@@ -393,7 +398,7 @@ QThread *QThread::currentThread()
{
QThreadData *data = QThreadData::current();
Q_ASSERT(data != 0);
- return data->thread;
+ return data->thread.loadAcquire();
}
/*!
@@ -878,11 +883,11 @@ QThreadData *QThreadData::current(bool createIfNecessary)
if (!data && createIfNecessary) {
data = new QThreadData;
data->thread = new QAdoptedThread(data);
- data->threadId.store(Qt::HANDLE(data->thread));
+ data->threadId.storeRelaxed(Qt::HANDLE(data->thread));
data->deref();
data->isAdopted = true;
if (!QCoreApplicationPrivate::theMainThread)
- QCoreApplicationPrivate::theMainThread = data->thread.load();
+ QCoreApplicationPrivate::theMainThread = data->thread.loadRelaxed();
}
return data;
}
@@ -925,7 +930,7 @@ QThreadPrivate::~QThreadPrivate()
QAbstractEventDispatcher *QThread::eventDispatcher() const
{
Q_D(const QThread);
- return d->data->eventDispatcher.load();
+ return d->data->eventDispatcher.loadRelaxed();
}
/*!
@@ -980,7 +985,7 @@ bool QThread::event(QEvent *event)
void QThread::requestInterruption()
{
- if (this == QCoreApplicationPrivate::theMainThread) {
+ if (this == QCoreApplicationPrivate::theMainThread.loadAcquire()) {
qWarning("QThread::requestInterruption has no effect on the main thread");
return;
}
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 209225de98..b2d1628e6e 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -195,6 +195,9 @@ public:
int waiters;
bool terminationEnabled, terminatePending;
#endif // Q_OS_WIN
+#ifdef Q_OS_WASM
+ static int idealThreadCount;
+#endif
QThreadData *data;
static QAbstractEventDispatcher *createEventDispatcher(QThreadData *data);
@@ -254,11 +257,11 @@ public:
void ref();
void deref();
inline bool hasEventDispatcher() const
- { return eventDispatcher.load() != nullptr; }
+ { return eventDispatcher.loadRelaxed() != nullptr; }
QAbstractEventDispatcher *createEventDispatcher();
QAbstractEventDispatcher *ensureEventDispatcher()
{
- QAbstractEventDispatcher *ed = eventDispatcher.load();
+ QAbstractEventDispatcher *ed = eventDispatcher.loadRelaxed();
if (Q_LIKELY(ed))
return ed;
return createEventDispatcher();
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 3d4c906dc2..38e9c1c3ec 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -100,10 +100,6 @@
#include <sys/neutrino.h>
#endif
-#if defined(Q_OS_WASM)
-#include <emscripten/val.h>
-#endif
-
QT_BEGIN_NAMESPACE
#if QT_CONFIG(thread)
@@ -119,6 +115,9 @@ enum { ThreadPriorityResetFlag = 0x80000000 };
#if defined(Q_CC_XLC) || defined (Q_CC_SUN)
#define HAVE_TLS
#endif
+#if defined(Q_OS_RTEMS)
+#define HAVE_TLS
+#endif
#ifdef HAVE_TLS
static __thread QThreadData *currentThreadData = 0;
@@ -142,7 +141,7 @@ static void destroy_current_thread_data(void *p)
pthread_setspecific(current_thread_data_key, p);
QThreadData *data = static_cast<QThreadData *>(p);
if (data->isAdopted) {
- QThread *thread = data->thread;
+ QThread *thread = data->thread.loadAcquire();
Q_ASSERT(thread);
QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
Q_ASSERT(!thread_p->finished);
@@ -253,9 +252,9 @@ QThreadData *QThreadData::current(bool createIfNecessary)
}
data->deref();
data->isAdopted = true;
- data->threadId.store(to_HANDLE(pthread_self()));
- if (!QCoreApplicationPrivate::theMainThread)
- QCoreApplicationPrivate::theMainThread = data->thread.load();
+ data->threadId.storeRelaxed(to_HANDLE(pthread_self()));
+ if (!QCoreApplicationPrivate::theMainThread.loadAcquire())
+ QCoreApplicationPrivate::theMainThread.storeRelease(data->thread.loadRelaxed());
}
return data;
}
@@ -286,7 +285,7 @@ QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *dat
else
return new QEventDispatcherUNIX;
#elif !defined(QT_NO_GLIB)
- const bool isQtMainThread = data->thread == QCoreApplicationPrivate::mainThread();
+ const bool isQtMainThread = data->thread.loadAcquire() == QCoreApplicationPrivate::mainThread();
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
&& (isQtMainThread || qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB"))
&& QEventDispatcherGlib::versionSupported())
@@ -335,7 +334,7 @@ void *QThreadPrivate::start(void *arg)
thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
}
- data->threadId.store(to_HANDLE(pthread_self()));
+ data->threadId.storeRelaxed(to_HANDLE(pthread_self()));
set_thread_data(data);
data->ref();
@@ -405,7 +404,7 @@ void QThreadPrivate::finish(void *arg)
QThreadStorageData::finish((void **)data);
locker.relock();
- QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.loadRelaxed();
if (eventDispatcher) {
d->data->eventDispatcher = 0;
locker.unlock();
@@ -454,6 +453,10 @@ Qt::HANDLE QThread::currentThreadId() noexcept
# define _SC_NPROCESSORS_ONLN 84
#endif
+#ifdef Q_OS_WASM
+int QThreadPrivate::idealThreadCount = 1;
+#endif
+
int QThread::idealThreadCount() noexcept
{
int cores = 1;
@@ -503,7 +506,7 @@ int QThread::idealThreadCount() noexcept
cores = 1;
# endif
#elif defined(Q_OS_WASM)
- cores = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>();
+ cores = QThreadPrivate::idealThreadCount;
#else
// the rest: Linux, Solaris, AIX, Tru64
cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
@@ -724,6 +727,12 @@ void QThread::start(Priority priority)
}
}
+#ifdef Q_OS_INTEGRITY
+ if (Q_LIKELY(objectName().isEmpty()))
+ pthread_attr_setthreadname(&attr, metaObject()->className());
+ else
+ pthread_attr_setthreadname(&attr, objectName().toLocal8Bit());
+#endif
pthread_t threadId;
int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
if (code == EPERM) {
@@ -734,7 +743,7 @@ void QThread::start(Priority priority)
#endif
code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
}
- d->data->threadId.store(to_HANDLE(threadId));
+ d->data->threadId.storeRelaxed(to_HANDLE(threadId));
pthread_attr_destroy(&attr);
@@ -743,7 +752,7 @@ void QThread::start(Priority priority)
d->running = false;
d->finished = false;
- d->data->threadId.store(nullptr);
+ d->data->threadId.storeRelaxed(nullptr);
}
}
@@ -753,10 +762,10 @@ void QThread::terminate()
Q_D(QThread);
QMutexLocker locker(&d->mutex);
- if (!d->data->threadId.load())
+ if (!d->data->threadId.loadRelaxed())
return;
- int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId.load()));
+ int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId.loadRelaxed()));
if (code) {
qErrnoWarning(code, "QThread::start: Thread termination error");
}
@@ -768,7 +777,7 @@ bool QThread::wait(unsigned long time)
Q_D(QThread);
QMutexLocker locker(&d->mutex);
- if (from_HANDLE<pthread_t>(d->data->threadId.load()) == pthread_self()) {
+ if (from_HANDLE<pthread_t>(d->data->threadId.loadRelaxed()) == pthread_self()) {
qWarning("QThread::wait: Thread tried to wait on itself");
return false;
}
@@ -810,7 +819,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
int sched_policy;
sched_param param;
- if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, &param) != 0) {
+ if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()), &sched_policy, &param) != 0) {
// failed to get the scheduling policy, don't bother setting
// the priority
qWarning("QThread::setPriority: Cannot get scheduler parameters");
@@ -826,15 +835,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
}
param.sched_priority = prio;
- int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, &param);
+ int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()), sched_policy, &param);
# ifdef SCHED_IDLE
// were we trying to set to idle priority and failed?
if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
// reset to lowest priority possible
- pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, &param);
+ pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()), &sched_policy, &param);
param.sched_priority = sched_get_priority_min(sched_policy);
- pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, &param);
+ pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()), sched_policy, &param);
}
# else
Q_UNUSED(status);
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index ee73280707..f8a0b0abaa 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -138,11 +138,11 @@ QThreadData *QThreadData::current(bool createIfNecessary)
}
threadData->deref();
threadData->isAdopted = true;
- threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
+ threadData->threadId.storeRelaxed(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
#ifndef Q_OS_WINRT
if (!QCoreApplicationPrivate::theMainThread) {
- QCoreApplicationPrivate::theMainThread = threadData->thread.load();
+ QCoreApplicationPrivate::theMainThread = threadData->thread.loadRelaxed();
} else {
#else
// for winrt the main thread is set explicitly in QCoreApplication's constructor as the
@@ -184,9 +184,9 @@ void QThreadData::setMainThread()
}
threadData->deref();
threadData->isAdopted = true;
- threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
+ threadData->threadId.storeRelaxed(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
}
- QCoreApplicationPrivate::theMainThread = threadData->thread.load();
+ QCoreApplicationPrivate::theMainThread = threadData->thread.loadRelaxed();
}
#endif
@@ -379,7 +379,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.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
+ data->threadId.storeRelaxed(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
QThread::setTerminationEnabled(false);
@@ -421,7 +421,7 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept
QThreadStorageData::finish(tls_data);
locker.relock();
- QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.loadRelaxed();
if (eventDispatcher) {
d->data->eventDispatcher = 0;
locker.unlock();
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index 8b82118a5c..fdc484d2d2 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -126,7 +126,7 @@ void **QThreadStorageData::get() const
DEBUG_MSG("QThreadStorageData: Returning storage %d, data %p, for thread %p",
id,
*v,
- data->thread.load());
+ data->thread.loadRelaxed());
return *v ? v : 0;
}
@@ -148,7 +148,7 @@ void **QThreadStorageData::set(void *p)
DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p",
id,
value,
- data->thread.load());
+ data->thread.loadRelaxed());
QMutexLocker locker(&destructorsMutex);
DestructorMap *destr = destructors();
@@ -164,7 +164,7 @@ void **QThreadStorageData::set(void *p)
// store new data
value = p;
- DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread.load(), p);
+ DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread.loadRelaxed(), p);
return &value;
}
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index 9220d210f1..31206f779d 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -334,19 +334,17 @@ static constexpr int daysInUsualMonth(int month) // (February isn't usual.)
\brief The QDate class provides date functions.
- A QDate object encodes a calendar date, i.e. year, month, and day numbers,
- in the proleptic Gregorian calendar by default. It can read the current date
- from the system clock. It provides functions for comparing dates, and for
- manipulating dates. For example, it is possible to add and subtract days,
- months, and years to dates.
+ A QDate object represents a particular date. This can be expressed as a
+ calendar date, i.e. year, month, and day numbers, in the proleptic Gregorian
+ calendar.
A QDate object is typically created by giving the year, month, and day
- numbers explicitly. Note that QDate interprets two digit years as presented,
- i.e., as years 0 through 99, without adding any offset. A QDate can also be
- constructed with the static function currentDate(), which creates a QDate
- object containing the system clock's date. An explicit date can also be set
- using setDate(). The fromString() function returns a QDate given a string
- and a date format which is used to interpret the date within the string.
+ numbers explicitly. Note that QDate interprets year numbers less than 100 as
+ presented, i.e., as years 1 through 99, without adding any offset. The
+ static function currentDate() creates a QDate object containing the date
+ read from the system clock. An explicit date can also be set using
+ setDate(). The fromString() function returns a QDate given a string and a
+ date format which is used to interpret the date within the string.
The year(), month(), and day() functions provide access to the
year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
@@ -380,7 +378,7 @@ static constexpr int daysInUsualMonth(int month) // (February isn't usual.)
every day in a contiguous range, with 24 November 4714 BCE in the Gregorian
calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar).
As well as being an efficient and accurate way of storing an absolute date,
- it is suitable for converting a Date into other calendar systems such as
+ it is suitable for converting a date into other calendar systems such as
Hebrew, Islamic or Chinese. The Julian Day number can be obtained using
QDate::toJulianDay() and can be set using QDate::fromJulianDay().
@@ -388,7 +386,7 @@ static constexpr int daysInUsualMonth(int month) // (February isn't usual.)
for technical reasons limited to between -784350574879 and 784354017364,
which means from before 2 billion BCE to after 2 billion CE.
- \sa QTime, QDateTime, QDateEdit, QDateTimeEdit, QCalendarWidget
+ \sa QTime, QDateTime, QDateTime::YearRange, QDateEdit, QDateTimeEdit, QCalendarWidget
*/
/*!
@@ -615,7 +613,7 @@ int QDate::weekNumber(int *yearNumber) const
Q_ASSERT(week == 53 || week == 1);
}
- if (yearNumber != 0)
+ if (yearNumber)
*yearNumber = year;
return week;
}
@@ -1516,19 +1514,17 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
if (parts.count() != 4)
return QDate();
- QStringRef monthName = parts.at(1);
- const int month = fromShortMonthName(monthName);
- if (month == -1) {
- // Month name matches neither English nor other localised name.
- return QDate();
- }
-
bool ok = false;
int year = parts.at(3).toInt(&ok);
- if (!ok)
+ int day = ok ? parts.at(2).toInt(&ok) : 0;
+ if (!ok || !day)
+ return QDate();
+
+ const int month = fromShortMonthName(parts.at(1));
+ if (month == -1) // Month name matches no English or localised name.
return QDate();
- return QDate(year, month, parts.at(2).toInt());
+ return QDate(year, month, day);
}
#endif // textdate
case Qt::ISODate: {
@@ -1695,12 +1691,10 @@ bool QDate::isLeapYear(int y)
Unlike QDateTime, QTime knows nothing about time zones or
daylight-saving time (DST).
- A QTime object is typically created either by giving the number
- of hours, minutes, seconds, and milliseconds explicitly, or by
- using the static function currentTime(), which creates a QTime
- object that contains the system's local time. Note that the
- accuracy depends on the accuracy of the underlying operating
- system; not all systems provide 1-millisecond accuracy.
+ A QTime object is typically created either by giving the number of hours,
+ minutes, seconds, and milliseconds explicitly, or by using the static
+ function currentTime(), which creates a QTime object that represents the
+ system's local time.
The hour(), minute(), second(), and msec() functions provide
access to the number of hours, minutes, seconds, and milliseconds
@@ -2157,6 +2151,12 @@ int QTime::msecsTo(const QTime &t) const
Note that the accuracy depends on the accuracy of the underlying
operating system; not all systems provide 1-millisecond accuracy.
+
+ Furthermore, currentTime() only increases within each day; it shall drop by
+ 24 hours each time midnight passes; and, beside this, changes in it may not
+ correspond to elapsed time, if a daylight-saving transition intervenes.
+
+ \sa QDateTime::currentDateTime(), QDateTime::currentDateTimeUtc()
*/
#if QT_CONFIG(datestring)
@@ -2265,7 +2265,7 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
case Qt::ISODateWithMs:
case Qt::TextDate:
default:
- return fromIsoTimeString(QStringRef(&string), format, 0);
+ return fromIsoTimeString(QStringRef(&string), format, nullptr);
}
}
@@ -2464,7 +2464,7 @@ static int qt_timezone()
// - It also takes DST into account, so we need to adjust it to always
// get the Standard Time offset.
return -t.tm_gmtoff + (t.tm_isdst ? (long)SECS_PER_HOUR : 0L);
-#elif defined(Q_OS_INTEGRITY)
+#elif defined(Q_OS_INTEGRITY) || defined(Q_OS_RTEMS)
return 0;
#else
return timezone;
@@ -2512,7 +2512,7 @@ int QDateTimeParser::startsWithLocalTimeZone(const QStringRef name)
// then null date/time will be returned, you should adjust the date first if
// you need a guaranteed result.
static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStatus *daylightStatus,
- QString *abbreviation, bool *ok = 0)
+ QString *abbreviation, bool *ok = nullptr)
{
const qint64 msec = time->msec();
int yy, mm, dd;
@@ -2601,7 +2601,7 @@ static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localT
#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
// Use the reentrant version of localtime() where available
// as is thread-safe and doesn't use a shared static data area
- tm *res = 0;
+ tm *res = nullptr;
res = localtime_r(&secsSinceEpoch, &local);
if (res)
valid = true;
@@ -2611,7 +2611,7 @@ static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localT
#else
// Returns shared static data which may be overwritten at any time
// So copy the result asap
- tm *res = 0;
+ tm *res = nullptr;
res = localtime(&secsSinceEpoch);
if (res) {
local = *res;
@@ -2674,7 +2674,7 @@ static qint64 timeToMSecs(const QDate &date, const QTime &time)
// Convert an MSecs Since Epoch into Local Time
static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTime,
- QDateTimePrivate::DaylightStatus *daylightStatus = 0)
+ QDateTimePrivate::DaylightStatus *daylightStatus = nullptr)
{
if (msecs < 0) {
// Docs state any LocalTime before 1970-01-01 will *not* have any Daylight Time applied
@@ -2714,8 +2714,8 @@ static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTi
// values from mktime for the adjusted local date and time.
static qint64 localMSecsToEpochMSecs(qint64 localMsecs,
QDateTimePrivate::DaylightStatus *daylightStatus,
- QDate *localDate = 0, QTime *localTime = 0,
- QString *abbreviation = 0)
+ QDate *localDate = nullptr, QTime *localTime = nullptr,
+ QString *abbreviation = nullptr)
{
QDate dt;
QTime tm;
@@ -3018,7 +3018,7 @@ static void setDateTime(QDateTimeData &d, const QDate &date, const QTime &time)
if (!useTime.isValid() && date.isValid())
useTime = QTime::fromMSecsSinceStartOfDay(0);
- QDateTimePrivate::StatusFlags newStatus = 0;
+ QDateTimePrivate::StatusFlags newStatus = { };
// Set date value and status
qint64 days = 0;
@@ -3096,7 +3096,7 @@ inline QDateTime::Data::Data(Qt::TimeSpec spec)
// the structure is too small, we need to detach
d = new QDateTimePrivate;
d->ref.ref();
- d->m_status = mergeSpec(0, spec);
+ d->m_status = mergeSpec(nullptr, spec);
}
}
@@ -3181,13 +3181,13 @@ inline void QDateTime::Data::detach()
x->m_status = QDateTimePrivate::StatusFlag(data.status & ~QDateTimePrivate::ShortData);
x->m_msecs = data.msecs;
} else {
- if (d->ref.load() == 1)
+ if (d->ref.loadRelaxed() == 1)
return;
x = new QDateTimePrivate(*d);
}
- x->ref.store(1);
+ x->ref.storeRelaxed(1);
if (!wasShort && !d->ref.deref())
delete d;
d = x;
@@ -3203,7 +3203,7 @@ inline QDateTimePrivate *QDateTime::Data::operator->()
{
// should we attempt to detach here?
Q_ASSERT(!isShort());
- Q_ASSERT(d->ref.load() == 1);
+ Q_ASSERT(d->ref.loadRelaxed() == 1);
return d;
}
@@ -3272,15 +3272,31 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
provides functions for comparing datetimes and for manipulating a
datetime by adding a number of seconds, days, months, or years.
- A QDateTime object is typically created either by giving a date
- and time explicitly in the constructor, or by using the static
- function currentDateTime() that returns a QDateTime object set
- to the system clock's time. The date and time can be changed with
- setDate() and setTime(). A datetime can also be set using the
- setTime_t() function that takes a POSIX-standard "number of
- seconds since 00:00:00 on January 1, 1970" value. The fromString()
- function returns a QDateTime, given a string and a date format
- used to interpret the date within the string.
+ QDateTime can describe datetimes with respect to
+ \l{Qt::LocalTime}{local time}, to \l{Qt::UTC}{UTC}, to a specified
+ \l{Qt::OffsetFromUTC}{offset from UTC} or to a specified
+ \l{Qt::TimeZone}{time zone}, in conjunction
+ with the QTimeZone class. For example, a time zone of "Europe/Berlin" will
+ apply the daylight-saving rules as used in Germany since 1970. In contrast,
+ an offset from UTC of +3600 seconds is one hour ahead of UTC (usually
+ written in ISO standard notation as "UTC+01:00"), with no daylight-saving
+ offset or changes. When using either local time or a specified time zone,
+ time-zone transitions such as the starts and ends of daylight-saving time
+ (DST) are taken into account. The choice of system used to represent a
+ datetime is described as its "timespec".
+
+ A QDateTime object is typically created either by giving a date and time
+ explicitly in the constructor, or by using a static function such as
+ currentDateTime() or fromMSecsSinceEpoch(). The date and time can be changed
+ with setDate() and setTime(). A datetime can also be set using the
+ setMSecsSinceEpoch() function that takes the time, in milliseconds, since
+ 00:00:00 on January 1, 1970. The fromString() function returns a QDateTime,
+ given a string and a date format used to interpret the date within the
+ string.
+
+ QDateTime::currentDateTime() returns a QDateTime that expresses the current
+ time with respect to local time. QDateTime::currentDateTimeUtc() returns a
+ QDateTime that expresses the current time with respect to UTC.
The date() and time() functions provide access to the date and
time parts of the datetime. The same information is provided in
@@ -3291,18 +3307,20 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
later.
You can increment (or decrement) a datetime by a given number of
- milliseconds using addMSecs(), seconds using addSecs(), or days
- using addDays(). Similarly, you can use addMonths() and addYears().
- The daysTo() function returns the number of days between two datetimes,
- secsTo() returns the number of seconds between two datetimes, and
- msecsTo() returns the number of milliseconds between two datetimes.
-
- QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or
- as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a
- QDateTime expressed as local time; use toUTC() to convert it to
- UTC. You can also use timeSpec() to find out if a QDateTime
- object stores a UTC time or a local time. Operations such as
- addSecs() and secsTo() are aware of daylight-saving time (DST).
+ milliseconds using addMSecs(), seconds using addSecs(), or days using
+ addDays(). Similarly, you can use addMonths() and addYears(). The daysTo()
+ function returns the number of days between two datetimes, secsTo() returns
+ the number of seconds between two datetimes, and msecsTo() returns the
+ number of milliseconds between two datetimes. These operations are aware of
+ daylight-saving time (DST) and other time-zone transitions, where
+ applicable.
+
+ Use toTimeSpec() to express a datetime in local time or UTC,
+ toOffsetFromUtc() to express in terms of an offset from UTC, or toTimeZone()
+ to express it with respect to a general time zone. You can use timeSpec() to
+ find out what time-spec a QDateTime object stores its time relative to. When
+ that is Qt::TimeZone, you can use timeZone() to find out which zone it is
+ using.
\note QDateTime does not account for leap seconds.
@@ -3316,72 +3334,79 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
\section2 Range of Valid Dates
- The range of valid values able to be stored in QDateTime is dependent on
- the internal storage implementation. QDateTime is currently stored in a
- qint64 as a serial msecs value encoding the date and time. This restricts
- the date range to about +/- 292 million years, compared to the QDate range
- of +/- 2 billion years. Care must be taken when creating a QDateTime with
- extreme values that you do not overflow the storage. The exact range of
- supported values varies depending on the Qt::TimeSpec and time zone.
+ The range of values that QDateTime can represent is dependent on the
+ internal storage implementation. QDateTime is currently stored in a qint64
+ as a serial msecs value encoding the date and time. This restricts the date
+ range to about +/- 292 million years, compared to the QDate range of +/- 2
+ billion years. Care must be taken when creating a QDateTime with extreme
+ values that you do not overflow the storage. The exact range of supported
+ values varies depending on the Qt::TimeSpec and time zone.
+
+ \section2 Use of Timezones
+
+ QDateTime uses the system's time zone information to determine the current
+ local time zone and its offset from UTC. If the system is not configured
+ correctly or not up-to-date, QDateTime will give wrong results.
- \section2 Use of System Timezone
+ QDateTime likewise uses system-provided information to determine the offsets
+ of other timezones from UTC. If this information is incomplete or out of
+ date, QDateTime will give wrong results. See the QTimeZone documentation for
+ more details.
- QDateTime uses the system's time zone information to determine the
- offset of local time from UTC. If the system is not configured
- correctly or not up-to-date, QDateTime will give wrong results as
- well.
+ On modern Unix systems, this means QDateTime usually has accurate
+ information about historical transitions (including DST, see below) whenever
+ possible. On Windows, where the system doesn't support historical timezone
+ data, historical accuracy is not maintained with respect to timezone
+ transitions, notably including DST.
\section2 Daylight-Saving Time (DST)
- QDateTime takes into account the system's time zone information
- when dealing with DST. On modern Unix systems, this means it
- applies the correct historical DST data whenever possible. On
- Windows, where the system doesn't support historical DST data,
- historical accuracy is not maintained with respect to DST.
-
- The range of valid dates taking DST into account is 1970-01-01 to
- the present, and rules are in place for handling DST correctly
- until 2037-12-31, but these could change. For dates falling
- outside that range, QDateTime makes a \e{best guess} using the
- rules for year 1970 or 2037, but we can't guarantee accuracy. This
- means QDateTime doesn't take into account changes in a locale's
- time zone before 1970, even if the system's time zone database
- supports that information.
-
- QDateTime takes into consideration the Standard Time to Daylight-Saving Time
- transition. For example if the transition is at 2am and the clock goes
- forward to 3am, then there is a "missing" hour from 02:00:00 to 02:59:59.999
- which QDateTime considers to be invalid. Any date maths performed
- will take this missing hour into account and return a valid result.
-
- \section2 Offset From UTC
-
- A Qt::TimeSpec of Qt::OffsetFromUTC is also supported. This allows you
- to define a QDateTime relative to UTC at a fixed offset of a given number
- of seconds from UTC. For example, an offset of +3600 seconds is one hour
- ahead of UTC and is usually written in ISO standard notation as
- "UTC+01:00". Daylight-Saving Time never applies with this TimeSpec.
-
- There is no explicit size restriction to the offset seconds, but there is
- an implicit limit imposed when using the toString() and fromString()
- methods which use a format of [+|-]hh:mm, effectively limiting the range
- to +/- 99 hours and 59 minutes and whole minutes only. Note that currently
- no time zone lies outside the range of +/- 14 hours.
-
- \section2 Time Zone Support
-
- A Qt::TimeSpec of Qt::TimeZone is also supported in conjunction with the
- QTimeZone class. This allows you to define a datetime in a named time zone
- adhering to a consistent set of daylight-saving transition rules. For
- example a time zone of "Europe/Berlin" will apply the daylight-saving
- rules as used in Germany since 1970. Note that the transition rules
- applied depend on the platform support. See the QTimeZone documentation
- for more details.
+ QDateTime takes into account transitions between Standard Time and
+ Daylight-Saving Time. For example, if the transition is at 2am and the clock
+ goes forward to 3am, then there is a "missing" hour from 02:00:00 to
+ 02:59:59.999 which QDateTime considers to be invalid. Any date arithmetic
+ performed will take this missing hour into account and return a valid
+ result. For example, adding one minute to 01:59:59 will get 03:00:00.
+
+ The range of valid dates taking DST into account is 1970-01-01 to the
+ present, and rules are in place for handling DST correctly until 2037-12-31,
+ but these could change. For dates falling outside that range, QDateTime
+ makes a \e{best guess} using the rules for year 1970 or 2037, but we can't
+ guarantee accuracy. This means QDateTime doesn't take into account changes
+ in a time zone before 1970, even if the system's time zone database provides
+ that information.
+
+ \section2 Offsets From UTC
+
+ There is no explicit size restriction on an offset from UTC, but there is an
+ implicit limit imposed when using the toString() and fromString() methods
+ which use a [+|-]hh:mm format, effectively limiting the range to +/- 99
+ hours and 59 minutes and whole minutes only. Note that currently no time
+ zone lies outside the range of +/- 14 hours.
\sa QDate, QTime, QDateTimeEdit, QTimeZone
*/
/*!
+ \enum QDateTime::YearRange
+
+ This enumerated type describes the range of years (in the Gregorian
+ calendar) representable by QDateTime:
+
+ \value First The later parts of this year are representable
+ \value Last The earlier parts of this year are representable
+
+ All dates strictly between these two years are also representable.
+ Note, however, that the Gregorian Calendar has no year zero.
+
+ \note QDate can describe dates in a wider range of years. For most
+ purposes, this makes little difference, as the range of years that QDateTime
+ can support reaches 292 million years either side of 1970.
+
+ \sa isValid(), QDate
+*/
+
+/*!
Constructs a null datetime (i.e. null date and null time). A null
datetime is invalid, since the date is invalid.
@@ -3529,7 +3554,7 @@ bool QDateTime::isNull() const
hour, i.e. if the transition is at 2am and the clock goes forward to 3am
then the time from 02:00:00 to 02:59:59.999 is considered to be invalid.
- \sa QDate::isValid(), QTime::isValid()
+ \sa QDateTime::YearRange, QDate::isValid(), QTime::isValid()
*/
bool QDateTime::isValid() const
@@ -3550,7 +3575,7 @@ QDate QDateTime::date() const
if (!status.testFlag(QDateTimePrivate::ValidDate))
return QDate();
QDate dt;
- msecsToTime(getMSecs(d), &dt, 0);
+ msecsToTime(getMSecs(d), &dt, nullptr);
return dt;
}
@@ -3566,7 +3591,7 @@ QTime QDateTime::time() const
if (!status.testFlag(QDateTimePrivate::ValidTime))
return QTime();
QTime tm;
- msecsToTime(getMSecs(d), 0, &tm);
+ msecsToTime(getMSecs(d), nullptr, &tm);
return tm;
}
@@ -3684,7 +3709,7 @@ QString QDateTime::timeZoneAbbreviation() const
case Qt::LocalTime: {
QString abbrev;
auto status = extractDaylightStatus(getStatus(d));
- localMSecsToEpochMSecs(getMSecs(d), &status, 0, 0, &abbrev);
+ localMSecsToEpochMSecs(getMSecs(d), &status, nullptr, nullptr, &abbrev);
return abbrev;
}
}
@@ -4499,7 +4524,7 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const
Example:
\snippet code/src_corelib_tools_qdatetime.cpp 16
- \sa timeSpec(), toTimeZone(), toUTC(), toLocalTime()
+ \sa timeSpec(), toTimeZone(), toOffsetFromUtc()
*/
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
@@ -4769,14 +4794,14 @@ qint64 QDateTime::currentMSecsSinceEpoch() noexcept
// posix compliant system
// we have milliseconds
struct timeval tv;
- gettimeofday(&tv, 0);
+ gettimeofday(&tv, nullptr);
return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000;
}
qint64 QDateTime::currentSecsSinceEpoch() noexcept
{
struct timeval tv;
- gettimeofday(&tv, 0);
+ gettimeofday(&tv, nullptr);
return qint64(tv.tv_sec);
}
#else
@@ -5098,48 +5123,45 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
return QDateTime();
// Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"
+
+ // Year and time can be in either order.
+ // Guess which by looking for ':' in the time
+ int yearPart = 3;
+ int timePart = 3;
+ if (parts.at(3).contains(QLatin1Char(':')))
+ yearPart = 4;
+ else if (parts.at(4).contains(QLatin1Char(':')))
+ timePart = 4;
+ else
+ return QDateTime();
+
int month = 0;
int day = 0;
bool ok = false;
- // First try month then day
+ int year = parts.at(yearPart).toInt(&ok);
+ if (!ok || year == 0)
+ return QDateTime();
+
+ // Next try month then day
month = fromShortMonthName(parts.at(1));
if (month)
- day = parts.at(2).toInt();
+ day = parts.at(2).toInt(&ok);
- // If failed try day then month
- if (!month || !day) {
+ // If failed, try day then month
+ if (!ok || !month || !day) {
month = fromShortMonthName(parts.at(2));
if (month) {
QStringRef dayStr = parts.at(1);
if (dayStr.endsWith(QLatin1Char('.'))) {
dayStr = dayStr.left(dayStr.size() - 1);
- day = dayStr.toInt();
+ day = dayStr.toInt(&ok);
}
}
}
// If both failed, give up
- if (!month || !day)
- return QDateTime();
-
- // Year can be before or after time, "Sun Dec 1 1974 13:02:00" or "Sun Dec 1 13:02:00 1974"
- // Guess which by looking for ':' in the time
- int year = 0;
- int yearPart = 0;
- int timePart = 0;
- if (parts.at(3).contains(QLatin1Char(':'))) {
- yearPart = 4;
- timePart = 3;
- } else if (parts.at(4).contains(QLatin1Char(':'))) {
- yearPart = 3;
- timePart = 4;
- } else {
- return QDateTime();
- }
-
- year = parts.at(yearPart).toInt(&ok);
- if (!ok)
+ if (!ok || !month || !day)
return QDateTime();
QDate date(year, month, day);
diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h
index 3e3b953b52..89ea4ee24a 100644
--- a/src/corelib/time/qdatetime.h
+++ b/src/corelib/time/qdatetime.h
@@ -384,6 +384,10 @@ public:
NSDate *toNSDate() const Q_DECL_NS_RETURNS_AUTORELEASED;
#endif
+ // (1<<63) ms is 292277024.6 (average Gregorian) years, counted from the start of 1970, so
+ // Last is floor(1970 + 292277024.6); no year 0, so First is floor(1970 - 1 - 292277024.6)
+ enum class YearRange : qint32 { First = -292275056, Last = +292278994 };
+
private:
friend class QDateTimePrivate;
diff --git a/src/corelib/time/qdatetime_p.h b/src/corelib/time/qdatetime_p.h
index 6018f8f7b0..6e4120d762 100644
--- a/src/corelib/time/qdatetime_p.h
+++ b/src/corelib/time/qdatetime_p.h
@@ -140,10 +140,6 @@ public:
// Inlined for its one caller in qdatetime.cpp
inline void setUtcOffsetByTZ(qint64 atMSecsSinceEpoch);
#endif // timezone
-
- // ### Qt 5.14: expose publicly in QDateTime
- // The first and last years of which QDateTime can represent some part:
- enum class YearRange : qint32 { First = -292275056, Last = +292278994 };
};
QT_END_NAMESPACE
diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp
index 728b066db1..fc369bae75 100644
--- a/src/corelib/time/qdatetimeparser.cpp
+++ b/src/corelib/time/qdatetimeparser.cpp
@@ -621,11 +621,11 @@ int QDateTimeParser::sectionMaxSize(Section s, int count) const
case LastSection: return 0;
case AmPmSection: {
- const int lowerMax = qMin(getAmPmText(AmText, LowerCase).size(),
+ const int lowerMax = qMax(getAmPmText(AmText, LowerCase).size(),
getAmPmText(PmText, LowerCase).size());
- const int upperMax = qMin(getAmPmText(AmText, UpperCase).size(),
+ const int upperMax = qMax(getAmPmText(AmText, UpperCase).size(),
getAmPmText(PmText, UpperCase).size());
- return qMin(4, qMin(lowerMax, upperMax));
+ return qMax(lowerMax, upperMax);
}
case Hour24Section:
@@ -1664,13 +1664,16 @@ QDateTimeParser::findTimeZone(QStringRef str, const QDateTime &when,
/*!
\internal
- Returns
- AM if str == tr("AM")
- PM if str == tr("PM")
- PossibleAM if str can become tr("AM")
- PossiblePM if str can become tr("PM")
- PossibleBoth if str can become tr("PM") and can become tr("AM")
- Neither if str can't become anything sensible
+ Compares str to the am/pm texts returned by getAmPmText().
+ Returns AM or PM if str is one of those texts. Failing that, it looks to see
+ whether, ignoring spaces and case, each character of str appears in one of
+ the am/pm texts.
+ If neither text can be the result of the user typing more into str, returns
+ Neither. If both texts are possible results of further typing, returns
+ PossibleBoth. Otherwise, only one of them is a possible completion, so this
+ returns PossibleAM or PossiblePM to indicate which.
+
+ \sa getAmPmText()
*/
QDateTimeParser::AmPmFinder QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const
{
@@ -1699,10 +1702,10 @@ QDateTimeParser::AmPmFinder QDateTimeParser::findAmPm(QString &str, int sectionI
QDTPDEBUG << "findAmPm" << str << ampm[0] << ampm[1];
- if (str.indexOf(ampm[amindex], 0, Qt::CaseInsensitive) == 0) {
+ if (str.startsWith(ampm[amindex], Qt::CaseInsensitive)) {
str = ampm[amindex];
return AM;
- } else if (str.indexOf(ampm[pmindex], 0, Qt::CaseInsensitive) == 0) {
+ } else if (str.startsWith(ampm[pmindex], Qt::CaseInsensitive)) {
str = ampm[pmindex];
return PM;
} else if (context == FromString || (str.count(space) == 0 && str.size() >= size)) {
diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
index 2c845b1bce..3c2695a789 100644
--- a/src/corelib/time/qtimezoneprivate_tz.cpp
+++ b/src/corelib/time/qtimezoneprivate_tz.cpp
@@ -39,7 +39,6 @@
#include "qtimezone.h"
#include "qtimezoneprivate_p.h"
-#include "qdatetime_p.h" // ### Qt 5.14: remove once YearRange is on QDateTime
#include "private/qlocale_tools_p.h"
#include <QtCore/QFile>
@@ -50,6 +49,12 @@
#include <qdebug.h>
#include <algorithm>
+#include <errno.h>
+#include <limits.h>
+#if !defined(Q_OS_INTEGRITY)
+#include <sys/param.h> // to use MAXSYMLINKS constant
+#endif
+#include <unistd.h> // to use _SC_SYMLOOP_MAX constant
QT_BEGIN_NAMESPACE
@@ -583,8 +588,8 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
stdTime = QTime(2, 0, 0);
// Limit year to the range QDateTime can represent:
- const int minYear = int(QDateTimePrivate::YearRange::First);
- const int maxYear = int(QDateTimePrivate::YearRange::Last);
+ const int minYear = int(QDateTime::YearRange::First);
+ const int maxYear = int(QDateTime::YearRange::Last);
startYear = qBound(minYear, startYear, maxYear);
endYear = qBound(minYear, endYear, maxYear);
Q_ASSERT(startYear <= endYear);
@@ -1057,6 +1062,27 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs
return last > m_tranTimes.cbegin() ? dataForTzTransition(*--last) : invalidData();
}
+static long getSymloopMax()
+{
+#if defined(SYMLOOP_MAX)
+ return SYMLOOP_MAX; // if defined, at runtime it can only be greater than this, so this is a safe bet
+#else
+ errno = 0;
+ long result = sysconf(_SC_SYMLOOP_MAX);
+ if (result >= 0)
+ return result;
+ // result is -1, meaning either error or no limit
+ Q_ASSERT(!errno); // ... but it can't be an error, POSIX mandates _SC_SYMLOOP_MAX
+
+ // therefore we can make up our own limit
+# if defined(MAXSYMLINKS)
+ return MAXSYMLINKS;
+# else
+ return 8;
+# endif
+#endif
+}
+
// TODO Could cache the value and monitor the required files for any changes
QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
{
@@ -1074,12 +1100,18 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
// On most distros /etc/localtime is a symlink to a real file so extract name from the path
if (ianaId.isEmpty()) {
- const QString path = QFile::symLinkTarget(QStringLiteral("/etc/localtime"));
- if (!path.isEmpty()) {
+ const QLatin1String zoneinfo("/zoneinfo/");
+ QString path = QFile::symLinkTarget(QStringLiteral("/etc/localtime"));
+ int index = -1;
+ long iteration = getSymloopMax();
+ // Symlink may point to another symlink etc. before being under zoneinfo/
+ // We stop on the first path under /zoneinfo/, even if it is itself a
+ // symlink, like America/Montreal pointing to America/Toronto
+ while (iteration-- > 0 && !path.isEmpty() && (index = path.indexOf(zoneinfo)) < 0)
+ path = QFile::symLinkTarget(path);
+ if (index >= 0) {
// /etc/localtime is a symlink to the current TZ file, so extract from path
- int index = path.indexOf(QLatin1String("/zoneinfo/"));
- if (index != -1)
- ianaId = path.mid(index + 10).toUtf8();
+ ianaId = path.midRef(index + zoneinfo.size()).toUtf8();
}
}
@@ -1105,9 +1137,9 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
while (ianaId.isEmpty() && !ts.atEnd() && ts.status() == QTextStream::Ok) {
line = ts.readLine();
if (line.startsWith(QLatin1String("ZONE="))) {
- ianaId = line.mid(6, line.size() - 7).toUtf8();
+ ianaId = line.midRef(6, line.size() - 7).toUtf8();
} else if (line.startsWith(QLatin1String("TIMEZONE="))) {
- ianaId = line.mid(10, line.size() - 11).toUtf8();
+ ianaId = line.midRef(10, line.size() - 11).toUtf8();
}
}
}
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index 88d8b8244d..234a44f6b6 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -215,7 +215,7 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
headerSize += (alignment - Q_ALIGNOF(QArrayData));
if (headerSize > size_t(MaxAllocSize))
- return 0;
+ return nullptr;
size_t allocSize = calculateBlockSize(capacity, objectSize, headerSize, options);
QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
@@ -224,9 +224,9 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
& ~(alignment - 1);
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
- header->ref.atomic.store(bool(!(options & Unsharable)));
+ header->ref.atomic.storeRelaxed(bool(!(options & Unsharable)));
#else
- header->ref.atomic.store(1);
+ header->ref.atomic.storeRelaxed(1);
#endif
header->size = 0;
header->alloc = capacity;
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index 7e3f8c9dbd..dcd95924c1 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -323,11 +323,17 @@ struct QArrayDataPointerRef
}()) \
/**/
+#ifdef Q_COMPILER_CONSTEXPR
+#define Q_ARRAY_LITERAL_CHECK_LITERAL_TYPE(Type) Q_STATIC_ASSERT(std::is_literal_type<Type>::value)
+#else
+#define Q_ARRAY_LITERAL_CHECK_LITERAL_TYPE(Type) do {} while (0)
+#endif
+
#define Q_ARRAY_LITERAL_IMPL(Type, ...) \
- union { Type type_must_be_POD; } dummy; Q_UNUSED(dummy) \
+ Q_ARRAY_LITERAL_CHECK_LITERAL_TYPE(Type); \
\
/* Portable compile-time array size computation */ \
- Type data[] = { __VA_ARGS__ }; Q_UNUSED(data) \
+ Q_CONSTEXPR Type data[] = { __VA_ARGS__ }; Q_UNUSED(data); \
enum { Size = sizeof(data) / sizeof(data[0]) }; \
\
static const QStaticArrayData<Type, Size> literal = { \
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index 7e1b43f9b1..8e19525f07 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -106,7 +106,7 @@ struct QPodArrayOps
void destroyAll() // Call from destructors, ONLY!
{
Q_ASSERT(this->isMutable());
- Q_ASSERT(this->ref.atomic.load() == 0);
+ Q_ASSERT(this->ref.atomic.loadRelaxed() == 0);
// As this is to be called only from destructor, it doesn't need to be
// exception safe; size not updated.
@@ -204,7 +204,7 @@ struct QGenericArrayOps
// As this is to be called only from destructor, it doesn't need to be
// exception safe; size not updated.
- Q_ASSERT(this->ref.atomic.load() == 0);
+ Q_ASSERT(this->ref.atomic.loadRelaxed() == 0);
const T *const b = this->begin();
const T *i = this->end();
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 9526350126..ecbb4743af 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -943,6 +943,23 @@ QByteArray qUncompress(const uchar* data, int nbytes)
and QByteArray() compares equal to QByteArray(""). We recommend
that you always use isEmpty() and avoid isNull().
+ \section1 Maximum size and out-of-memory conditions
+
+ The current version of QByteArray is limited to just under 2 GB (2^31
+ bytes) in size. The exact value is architecture-dependent, since it depends
+ on the overhead required for managing the data block, but is no more than
+ 32 bytes. Raw data blocks are also limited by the use of \c int type in the
+ current version to 2 GB minus 1 byte.
+
+ In case memory allocation fails, QByteArray will throw a \c std::bad_alloc
+ exception. Out of memory conditions in the Qt containers are the only case
+ where Qt will throw exceptions.
+
+ Note that the operating system may impose further limits on applications
+ holding a lot of allocated memory, especially large, contiguous blocks.
+ Such considerations, the configuration of such behavior or any mitigation
+ are outside the scope of the QByteArray API.
+
\section1 Notes on Locale
\section2 Number-String Conversions
@@ -2072,7 +2089,7 @@ static inline QByteArray &qbytearray_insert(QByteArray *ba,
{
Q_ASSERT(pos >= 0);
- if (pos < 0 || len <= 0 || arr == 0)
+ if (pos < 0 || len <= 0 || arr == nullptr)
return *ba;
int oldsize = ba->size();
@@ -4775,7 +4792,7 @@ static void q_toPercentEncoding(QByteArray *ba, const char *dontEncode, const ch
QByteArray input = *ba;
int len = input.count();
const char *inputData = input.constData();
- char *output = 0;
+ char *output = nullptr;
int length = 0;
for (int i = 0; i < len; ++i) {
@@ -4815,7 +4832,7 @@ void q_toPercentEncoding(QByteArray *ba, const char *exclude, const char *includ
void q_normalizePercentEncoding(QByteArray *ba, const char *exclude)
{
q_fromPercentEncoding(ba, '%');
- q_toPercentEncoding(ba, exclude, 0, '%');
+ q_toPercentEncoding(ba, exclude, nullptr, '%');
}
/*!
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index a81051d309..7c571706d8 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -548,7 +548,7 @@ class
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_CORE_EXPORT
#endif
-QByteRef {
+QByteRef { // ### Qt 7: remove
QByteArray &a;
int i;
inline QByteRef(QByteArray &array, int idx)
diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h
index 1261e1757c..0250b649b8 100644
--- a/src/corelib/tools/qbytearraylist.h
+++ b/src/corelib/tools/qbytearraylist.h
@@ -48,8 +48,11 @@
QT_BEGIN_NAMESPACE
+#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
typedef QListIterator<QByteArray> QByteArrayListIterator;
typedef QMutableListIterator<QByteArray> QMutableByteArrayListIterator;
+#endif
+
#ifndef Q_CLANG_QDOC
typedef QList<QByteArray> QByteArrayList;
diff --git a/src/corelib/tools/qbytearraymatcher.cpp b/src/corelib/tools/qbytearraymatcher.cpp
index d2eb4e0e3c..72e09226af 100644
--- a/src/corelib/tools/qbytearraymatcher.cpp
+++ b/src/corelib/tools/qbytearraymatcher.cpp
@@ -116,9 +116,9 @@ static inline int bm_find(const uchar *cc, int l, int index, const uchar *puc, u
Call setPattern() to give it a pattern to match.
*/
QByteArrayMatcher::QByteArrayMatcher()
- : d(0)
+ : d(nullptr)
{
- p.p = 0;
+ p.p = nullptr;
p.l = 0;
memset(p.q_skiptable, 0, sizeof(p.q_skiptable));
}
@@ -129,7 +129,7 @@ QByteArrayMatcher::QByteArrayMatcher()
the destructor does not delete \a pattern.
*/
QByteArrayMatcher::QByteArrayMatcher(const char *pattern, int length)
- : d(0)
+ : d(nullptr)
{
p.p = reinterpret_cast<const uchar *>(pattern);
p.l = length;
@@ -141,7 +141,7 @@ QByteArrayMatcher::QByteArrayMatcher(const char *pattern, int length)
Call indexIn() to perform a search.
*/
QByteArrayMatcher::QByteArrayMatcher(const QByteArray &pattern)
- : d(0), q_pattern(pattern)
+ : d(nullptr), q_pattern(pattern)
{
p.p = reinterpret_cast<const uchar *>(pattern.constData());
p.l = pattern.size();
@@ -152,7 +152,7 @@ QByteArrayMatcher::QByteArrayMatcher(const QByteArray &pattern)
Copies the \a other byte array matcher to this byte array matcher.
*/
QByteArrayMatcher::QByteArrayMatcher(const QByteArrayMatcher &other)
- : d(0)
+ : d(nullptr)
{
operator=(other);
}
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index d6061defc3..e097e4a5fe 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -1339,7 +1339,7 @@ static const unsigned short * QT_FASTCALL decompositionHelper
if (index == 0xffff) {
*length = 0;
*tag = QChar::NoDecomposition;
- return 0;
+ return nullptr;
}
const unsigned short *decomposition = uc_decomposition_map+index;
diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp
index 6e85027462..958216bde8 100644
--- a/src/corelib/tools/qcollator.cpp
+++ b/src/corelib/tools/qcollator.cpp
@@ -166,7 +166,7 @@ QCollator &QCollator::operator=(const QCollator &other)
*/
void QCollator::detach()
{
- if (d->ref.load() != 1) {
+ if (d->ref.loadRelaxed() != 1) {
QCollatorPrivate *x = new QCollatorPrivate(d->locale);
if (!d->ref.deref())
delete d;
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index 592e31bfd2..7b74b4f526 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -100,8 +100,8 @@ public:
inline ~QContiguousCache() { if (!d) return; if (!d->ref.deref()) freeData(p); }
- inline void detach() { if (d->ref.load() != 1) detach_helper(); }
- inline bool isDetached() const { return d->ref.load() == 1; }
+ inline void detach() { if (d->ref.loadRelaxed() != 1) detach_helper(); }
+ inline bool isDetached() const { return d->ref.loadRelaxed() == 1; }
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
#endif
@@ -176,7 +176,7 @@ void QContiguousCache<T>::detach_helper()
union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; } x;
x.d = allocateData(d->alloc);
- x.d->ref.store(1);
+ x.d->ref.storeRelaxed(1);
x.d->count = d->count;
x.d->start = d->start;
x.d->offset = d->offset;
@@ -215,7 +215,7 @@ void QContiguousCache<T>::setCapacity(int asize)
detach();
union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; } x;
x.d = allocateData(asize);
- x.d->ref.store(1);
+ x.d->ref.storeRelaxed(1);
x.d->alloc = asize;
x.d->count = qMin(d->count, asize);
x.d->offset = d->offset + d->count - x.d->count;
@@ -251,7 +251,7 @@ void QContiguousCache<T>::setCapacity(int asize)
template <typename T>
void QContiguousCache<T>::clear()
{
- if (d->ref.load() == 1) {
+ if (d->ref.loadRelaxed() == 1) {
if (QTypeInfo<T>::isComplex) {
int oldcount = d->count;
T * i = p->array + d->start;
@@ -267,7 +267,7 @@ void QContiguousCache<T>::clear()
} else {
union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; } x;
x.d = allocateData(d->alloc);
- x.d->ref.store(1);
+ x.d->ref.storeRelaxed(1);
x.d->alloc = d->alloc;
x.d->count = x.d->start = x.d->offset = 0;
x.d->sharable = true;
@@ -287,7 +287,7 @@ QContiguousCache<T>::QContiguousCache(int cap)
{
Q_ASSERT(cap >= 0);
d = allocateData(cap);
- d->ref.store(1);
+ d->ref.storeRelaxed(1);
d->alloc = cap;
d->count = d->start = d->offset = 0;
d->sharable = true;
diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h
index d72d6e1b4b..5ba23b344b 100644
--- a/src/corelib/tools/qfreelist_p.h
+++ b/src/corelib/tools/qfreelist_p.h
@@ -171,7 +171,7 @@ class QFreeList
// qDebug("QFreeList: allocating %d elements (%ld bytes) with offset %d", size, size * sizeof(ElementType), offset);
ElementType *v = new ElementType[size];
for (int i = 0; i < size; ++i)
- v[i].next.store(offset + i + 1);
+ v[i].next.storeRelaxed(offset + i + 1);
return v;
}
@@ -218,21 +218,21 @@ template <typename T, typename ConstantsType>
inline QFreeList<T, ConstantsType>::~QFreeList()
{
for (int i = 0; i < ConstantsType::BlockCount; ++i)
- delete [] _v[i].load();
+ delete [] _v[i].loadAcquire();
}
template <typename T, typename ConstantsType>
inline typename QFreeList<T, ConstantsType>::ConstReferenceType QFreeList<T, ConstantsType>::at(int x) const
{
const int block = blockfor(x);
- return (_v[block].load())[x].t();
+ return (_v[block].loadRelaxed())[x].t();
}
template <typename T, typename ConstantsType>
inline typename QFreeList<T, ConstantsType>::ReferenceType QFreeList<T, ConstantsType>::operator[](int x)
{
const int block = blockfor(x);
- return (_v[block].load())[x].t();
+ return (_v[block].loadRelaxed())[x].t();
}
template <typename T, typename ConstantsType>
@@ -257,7 +257,7 @@ inline int QFreeList<T, ConstantsType>::next()
}
}
- newid = v[at].next.load() | (id & ~ConstantsType::IndexMask);
+ newid = v[at].next.loadRelaxed() | (id & ~ConstantsType::IndexMask);
} while (!_next.testAndSetRelease(id, newid));
// qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)",
// id & ConstantsType::IndexMask,
@@ -271,12 +271,12 @@ inline void QFreeList<T, ConstantsType>::release(int id)
{
int at = id & ConstantsType::IndexMask;
const int block = blockfor(at);
- ElementType *v = _v[block].load();
+ ElementType *v = _v[block].loadRelaxed();
int x, newid;
do {
x = _next.loadAcquire();
- v[at].next.store(x & ConstantsType::IndexMask);
+ v[at].next.storeRelaxed(x & ConstantsType::IndexMask);
newid = incrementserial(x, id);
} while (!_next.testAndSetRelease(x, newid));
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 85a3456d71..a53d6db997 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -321,7 +321,7 @@ static QBasicAtomicInt qt_qhash_seed = Q_BASIC_ATOMIC_INITIALIZER(-1);
*/
static void qt_initialize_qhash_seed()
{
- if (qt_qhash_seed.load() == -1) {
+ if (qt_qhash_seed.loadRelaxed() == -1) {
int x(qt_create_qhash_seed() & INT_MAX);
qt_qhash_seed.testAndSetRelaxed(-1, x);
}
@@ -340,7 +340,7 @@ static void qt_initialize_qhash_seed()
int qGlobalQHashSeed()
{
qt_initialize_qhash_seed();
- return qt_qhash_seed.load();
+ return qt_qhash_seed.loadRelaxed();
}
/*! \relates QHash
@@ -372,14 +372,14 @@ void qSetGlobalQHashSeed(int newSeed)
return;
if (newSeed == -1) {
int x(qt_create_qhash_seed() & INT_MAX);
- qt_qhash_seed.store(x);
+ qt_qhash_seed.storeRelaxed(x);
} else {
if (newSeed) {
// can't use qWarning here (reentrancy)
fprintf(stderr, "qSetGlobalQHashSeed: forced seed value is not 0, cannot guarantee that the "
"hashing functions will produce a stable value.");
}
- qt_qhash_seed.store(newSeed & INT_MAX);
+ qt_qhash_seed.storeRelaxed(newSeed & INT_MAX);
}
}
@@ -471,7 +471,7 @@ static int countBits(int hint)
const int MinNumBits = 4;
const QHashData QHashData::shared_null = {
- 0, 0, Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, MinNumBits, 0, 0, 0, true, false, 0
+ nullptr, nullptr, Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, MinNumBits, 0, 0, 0, true, false, 0
};
void *QHashData::allocateNode(int nodeAlign)
@@ -501,15 +501,15 @@ QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *),
if (this == &shared_null)
qt_initialize_qhash_seed(); // may throw
d = new QHashData;
- d->fakeNext = 0;
- d->buckets = 0;
+ d->fakeNext = nullptr;
+ d->buckets = nullptr;
d->ref.initializeOwned();
d->size = size;
d->nodeSize = nodeSize;
d->userNumBits = userNumBits;
d->numBits = numBits;
d->numBuckets = numBuckets;
- d->seed = (this == &shared_null) ? uint(qt_qhash_seed.load()) : seed;
+ d->seed = (this == &shared_null) ? uint(qt_qhash_seed.loadRelaxed()) : seed;
d->sharable = true;
d->strictAlignment = nodeAlign > 8;
d->reserved = 0;
diff --git a/src/corelib/tools/qiterator.h b/src/corelib/tools/qiterator.h
index 82212c3eb5..84a0e116ca 100644
--- a/src/corelib/tools/qiterator.h
+++ b/src/corelib/tools/qiterator.h
@@ -44,6 +44,8 @@
QT_BEGIN_NAMESPACE
+#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
+
#define Q_DECLARE_SEQUENTIAL_ITERATOR(C) \
\
template <class T> \
@@ -115,11 +117,11 @@ template <class Key, class T> \
class Q##C##Iterator \
{ \
typedef typename Q##C<Key,T>::const_iterator const_iterator; \
- typedef const_iterator Item; \
Q##C<Key,T> c; \
const_iterator i, n; \
inline bool item_exists() const { return n != c.constEnd(); } \
public: \
+ typedef const_iterator Item; \
inline Q##C##Iterator(const Q##C<Key,T> &container) \
: c(container), i(c.constBegin()), n(c.constEnd()) {} \
inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
@@ -148,11 +150,11 @@ class QMutable##C##Iterator \
{ \
typedef typename Q##C<Key,T>::iterator iterator; \
typedef typename Q##C<Key,T>::const_iterator const_iterator; \
- typedef iterator Item; \
Q##C<Key,T> *c; \
iterator i, n; \
inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
public: \
+ typedef iterator Item; \
inline QMutable##C##Iterator(Q##C<Key,T> &container) \
: c(&container) \
{ i = c->begin(); n = c->end(); } \
@@ -179,6 +181,13 @@ public: \
n = c->end(); return false; } \
};
+#else // QT_NO_JAVA_STYLE_ITERATORS
+#define Q_DECLARE_SEQUENTIAL_ITERATOR(C)
+#define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C)
+#define Q_DECLARE_ASSOCIATIVE_ITERATOR(C)
+#define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C)
+#endif // QT_NO_JAVA_STYLE_ITERATORS
+
template<typename Key, typename T, class Iterator>
class QKeyValueIterator
{
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index c0450f5cd8..d239fe0ef4 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -742,8 +742,7 @@ const QLinkedListData QLinkedListData::shared_null = {
\snippet code/src_corelib_tools_qlinkedlist.cpp 7
STL-style iterators can be used as arguments to \l{generic
- algorithms}. For example, here's how to find an item in the list
- using the qFind() algorithm:
+ algorithms}. For example, here's how to find an item in the list:
\snippet code/src_corelib_tools_qlinkedlist.cpp 8
@@ -987,8 +986,7 @@ const QLinkedListData QLinkedListData::shared_null = {
\snippet code/src_corelib_tools_qlinkedlist.cpp 14
STL-style iterators can be used as arguments to \l{generic
- algorithms}. For example, here's how to find an item in the list
- using the qFind() algorithm:
+ algorithms}. For example, here's how to find an item in the list:
\snippet code/src_corelib_tools_qlinkedlist.cpp 15
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index 6bc053a4c0..d4e5bca0ed 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -340,7 +340,7 @@ void QLinkedList<T>::freeData(QLinkedListData *x)
{
Node *y = reinterpret_cast<Node*>(x);
Node *i = y->n;
- Q_ASSERT(x->ref.atomic.load() == 0);
+ Q_ASSERT(x->ref.atomic.loadRelaxed() == 0);
while (i != y) {
Node *n = i;
i = i->n;
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 48617f0539..dfebd57e34 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -75,7 +75,7 @@ template class Q_CORE_EXPORT QVector<QPoint>;
the number of elements in the list.
*/
-const QListData::Data QListData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, { 0 } };
+const QListData::Data QListData::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, { nullptr } };
/*!
* Detaches the QListData by allocating new memory for a list which will be bigger
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index c8740e55f3..939f8eb34d 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -301,9 +301,9 @@ QByteArray QLocaleId::name(char separator) const
const unsigned char *lang = language_code_list + 3 * language_id;
const unsigned char *script =
- (script_id != QLocale::AnyScript ? script_code_list + 4 * script_id : 0);
+ (script_id != QLocale::AnyScript ? script_code_list + 4 * script_id : nullptr);
const unsigned char *country =
- (country_id != QLocale::AnyCountry ? country_code_list + 3 * country_id : 0);
+ (country_id != QLocale::AnyCountry ? country_code_list + 3 * country_id : nullptr);
char len = (lang[2] != 0 ? 3 : 2) + (script ? 4+1 : 0) + (country ? (country[2] != 0 ? 3 : 2)+1 : 0);
QByteArray name(len, Qt::Uninitialized);
char *uc = name.data();
@@ -373,7 +373,7 @@ static const QLocaleData *findLocaleDataById(const QLocaleId &localeId)
} while (data->m_language_id && data->m_language_id == localeId.language_id);
}
- return 0;
+ return nullptr;
}
const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country)
@@ -604,7 +604,7 @@ int qt_repeatCount(QStringView s)
return int(j);
}
-static const QLocaleData *default_data = 0;
+static const QLocaleData *default_data = nullptr;
static QLocale::NumberOptions default_number_options = QLocale::DefaultNumberOptions;
static const QLocaleData *const c_data = locale_data;
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 15398ded32..1e3da35a02 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -250,14 +250,14 @@ public:
if (qIsInf(d))
return float(d);
if (std::fabs(d) > std::numeric_limits<float>::max()) {
- if (ok != nullptr)
+ if (ok)
*ok = false;
const float huge = std::numeric_limits<float>::infinity();
return d < 0 ? -huge : huge;
}
if (d != 0 && float(d) == 0) {
// Values that underflow double already failed. Match them:
- if (ok != 0)
+ if (ok)
*ok = false;
return 0;
}
@@ -337,7 +337,7 @@ public:
{
QLocalePrivate *retval = new QLocalePrivate;
retval->m_data = data;
- retval->ref.store(0);
+ retval->ref.storeRelaxed(0);
retval->m_numberOptions = numberOptions;
return retval;
}
diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp
index 53258bec3e..db8c8cd12f 100644
--- a/src/corelib/tools/qlocale_tools.cpp
+++ b/src/corelib/tools/qlocale_tools.cpp
@@ -398,7 +398,7 @@ qstrtoull(const char * nptr, const char **endptr, int base, bool *ok)
*ok = true;
errno = 0;
- char *endptr2 = 0;
+ char *endptr2 = nullptr;
unsigned long long result = qt_strtoull(nptr, &endptr2, base);
if (endptr)
*endptr = endptr2;
@@ -415,7 +415,7 @@ qstrtoll(const char * nptr, const char **endptr, int base, bool *ok)
{
*ok = true;
errno = 0;
- char *endptr2 = 0;
+ char *endptr2 = nullptr;
long long result = qt_strtoll(nptr, &endptr2, base);
if (endptr)
*endptr = endptr2;
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 5f7275c5f8..a0ec372f9a 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
-const QMapDataBase QMapDataBase::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, { 0, 0, 0 }, 0 };
+const QMapDataBase QMapDataBase::shared_null = { Q_REFCOUNT_INITIALIZE_STATIC, 0, { 0, nullptr, nullptr }, nullptr };
const QMapNodeBase *QMapNodeBase::nextNode() const
{
@@ -92,7 +92,7 @@ void QMapDataBase::rotateLeft(QMapNodeBase *x)
QMapNodeBase *&root = header.left;
QMapNodeBase *y = x->right;
x->right = y->left;
- if (y->left != 0)
+ if (y->left != nullptr)
y->left->setParent(x);
y->setParent(x->parent());
if (x == root)
@@ -111,7 +111,7 @@ void QMapDataBase::rotateRight(QMapNodeBase *x)
QMapNodeBase *&root = header.left;
QMapNodeBase *y = x->left;
x->left = y->right;
- if (y->right != 0)
+ if (y->right != nullptr)
y->right->setParent(x);
y->setParent(x->parent());
if (x == root)
@@ -173,7 +173,7 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z)
QMapNodeBase *y = z;
QMapNodeBase *x;
QMapNodeBase *x_parent;
- if (y->left == 0) {
+ if (y->left == nullptr) {
x = y->right;
if (y == mostLeftNode) {
if (x)
@@ -182,11 +182,11 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z)
mostLeftNode = y->parent();
}
} else {
- if (y->right == 0) {
+ if (y->right == nullptr) {
x = y->left;
} else {
y = y->right;
- while (y->left != 0)
+ while (y->left != nullptr)
y = y->left;
x = y->right;
}
@@ -228,7 +228,7 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z)
z->parent()->right = x;
}
if (y->color() != QMapNodeBase::Red) {
- while (x != root && (x == 0 || x->color() == QMapNodeBase::Black)) {
+ while (x != root && (x == nullptr || x->color() == QMapNodeBase::Black)) {
if (x == x_parent->left) {
QMapNodeBase *w = x_parent->right;
if (w->color() == QMapNodeBase::Red) {
@@ -237,13 +237,13 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z)
rotateLeft(x_parent);
w = x_parent->right;
}
- if ((w->left == 0 || w->left->color() == QMapNodeBase::Black) &&
- (w->right == 0 || w->right->color() == QMapNodeBase::Black)) {
+ if ((w->left == nullptr || w->left->color() == QMapNodeBase::Black) &&
+ (w->right == nullptr || w->right->color() == QMapNodeBase::Black)) {
w->setColor(QMapNodeBase::Red);
x = x_parent;
x_parent = x_parent->parent();
} else {
- if (w->right == 0 || w->right->color() == QMapNodeBase::Black) {
+ if (w->right == nullptr || w->right->color() == QMapNodeBase::Black) {
if (w->left)
w->left->setColor(QMapNodeBase::Black);
w->setColor(QMapNodeBase::Red);
@@ -265,13 +265,13 @@ void QMapDataBase::freeNodeAndRebalance(QMapNodeBase *z)
rotateRight(x_parent);
w = x_parent->left;
}
- if ((w->right == 0 || w->right->color() == QMapNodeBase::Black) &&
- (w->left == 0 || w->left->color() == QMapNodeBase::Black)) {
+ if ((w->right == nullptr || w->right->color() == QMapNodeBase::Black) &&
+ (w->left == nullptr|| w->left->color() == QMapNodeBase::Black)) {
w->setColor(QMapNodeBase::Red);
x = x_parent;
x_parent = x_parent->parent();
} else {
- if (w->left == 0 || w->left->color() == QMapNodeBase::Black) {
+ if (w->left == nullptr || w->left->color() == QMapNodeBase::Black) {
if (w->right)
w->right->setColor(QMapNodeBase::Black);
w->setColor(QMapNodeBase::Red);
@@ -363,8 +363,8 @@ QMapDataBase *QMapDataBase::createData()
d->size = 0;
d->header.p = 0;
- d->header.left = 0;
- d->header.right = 0;
+ d->header.left = nullptr;
+ d->header.right = nullptr;
d->mostLeftNode = &(d->header);
return d;
diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp
index d622f92530..cd20102a2b 100644
--- a/src/corelib/tools/qrect.cpp
+++ b/src/corelib/tools/qrect.cpp
@@ -1194,7 +1194,7 @@ bool QRect::intersects(const QRect &r) const noexcept
\fn QRect operator-(const QRect &lhs, const QMargins &rhs)
\relates QRect
- Returns the \a lhs rectangle shrunken by the \a rhs margins.
+ Returns the \a lhs rectangle shrunk by the \a rhs margins.
\since 5.3
*/
@@ -2417,7 +2417,7 @@ QRect QRectF::toAlignedRect() const noexcept
\relates QRectF
\since 5.3
- Returns the \a lhs rectangle grown by the \a rhs margins.
+ Returns the \a lhs rectangle shrunk by the \a rhs margins.
*/
/*!
diff --git a/src/corelib/tools/qrefcount.h b/src/corelib/tools/qrefcount.h
index 71adb41f28..2e5388ad9a 100644
--- a/src/corelib/tools/qrefcount.h
+++ b/src/corelib/tools/qrefcount.h
@@ -52,7 +52,7 @@ class RefCount
{
public:
inline bool ref() noexcept {
- int count = atomic.load();
+ int count = atomic.loadRelaxed();
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
if (count == 0) // !isSharable
return false;
@@ -63,7 +63,7 @@ public:
}
inline bool deref() noexcept {
- int count = atomic.load();
+ int count = atomic.loadRelaxed();
#if !defined(QT_NO_UNSHARABLE_CONTAINERS)
if (count == 0) // !isSharable
return false;
@@ -86,24 +86,24 @@ public:
bool isSharable() const noexcept
{
// Sharable === Shared ownership.
- return atomic.load() != 0;
+ return atomic.loadRelaxed() != 0;
}
#endif
bool isStatic() const noexcept
{
// Persistent object, never deleted
- return atomic.load() == -1;
+ return atomic.loadRelaxed() == -1;
}
bool isShared() const noexcept
{
- int count = atomic.load();
+ int count = atomic.loadRelaxed();
return (count != 1) && (count != 0);
}
- void initializeOwned() noexcept { atomic.store(1); }
- void initializeUnsharable() noexcept { atomic.store(0); }
+ void initializeOwned() noexcept { atomic.storeRelaxed(1); }
+ void initializeUnsharable() noexcept { atomic.storeRelaxed(0); }
QBasicAtomicInt atomic;
};
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index d970843dea..dd38ba0360 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -822,7 +822,7 @@ static QString wc2rx(const QString &wc_str, const bool enableEscaping)
if (wc[i] == QLatin1Char('^'))
rx += wc[i++];
if (i < wclen) {
- if (rx[i] == QLatin1Char(']'))
+ if (wc[i] == QLatin1Char(']'))
rx += wc[i++];
while (i < wclen && wc[i] != QLatin1Char(']')) {
if (wc[i] == QLatin1Char('\\'))
@@ -937,10 +937,10 @@ struct QRegExpMatchState
const QRegExpEngine *eng;
- inline QRegExpMatchState() : bigArray(0), captured(0) {}
+ inline QRegExpMatchState() : bigArray(nullptr), captured(nullptr) {}
inline ~QRegExpMatchState() { free(bigArray); }
- void drain() { free(bigArray); bigArray = 0; captured = 0; } // to save memory
+ void drain() { free(bigArray); bigArray = nullptr; captured = nullptr; } // to save memory
void prepareForMatch(QRegExpEngine *eng);
void match(const QChar *str, int len, int pos, bool minimal,
bool oneTest, int caretIndex);
@@ -1420,7 +1420,7 @@ void QRegExpMatchState::match(const QChar *str0, int len0, int pos0,
#ifndef QT_NO_REGEXP_OPTIM
if (eng->trivial && !oneTest) {
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
pos = int(QtPrivate::findString(QStringView(str0, len0), pos0, QStringView(eng->goodStr.unicode(), eng->goodStr.length()), eng->cs));
matchLen = eng->goodStr.length();
matched = (pos != -1);
@@ -1428,7 +1428,7 @@ void QRegExpMatchState::match(const QChar *str0, int len0, int pos0,
#endif
{
in = str0;
- if (in == 0)
+ if (in == nullptr)
in = &char_null;
pos = pos0;
caretPos = caretIndex;
@@ -1707,7 +1707,7 @@ void QRegExpEngine::dump() const
void QRegExpEngine::setup()
{
- ref.store(1);
+ ref.storeRelaxed(1);
#ifndef QT_NO_REGEXP_CAPTURE
f.resize(32);
nf = 0;
@@ -2910,7 +2910,7 @@ int QRegExpEngine::getEscape()
#ifndef QT_NO_REGEXP_ESCAPE
if ((prevCh & ~0xff) == 0) {
const char *p = strchr(tab, prevCh);
- if (p != 0)
+ if (p != nullptr)
return Tok_Char | backTab[p - tab];
}
#endif
@@ -3530,7 +3530,7 @@ int QRegExpEngine::parse(const QChar *pattern, int len)
#endif
box.cat(middleBox);
box.cat(rightBox);
- yyCharClass.reset(0);
+ yyCharClass.reset();
#ifndef QT_NO_REGEXP_CAPTURE
for (int i = 0; i < nf; ++i) {
@@ -3608,7 +3608,7 @@ int QRegExpEngine::parse(const QChar *pattern, int len)
void QRegExpEngine::parseAtom(Box *box)
{
#ifndef QT_NO_REGEXP_LOOKAHEAD
- QRegExpEngine *eng = 0;
+ QRegExpEngine *eng = nullptr;
bool neg;
int len;
#endif
@@ -3805,9 +3805,9 @@ struct QRegExpPrivate
QRegExpMatchState matchState;
inline QRegExpPrivate()
- : eng(0), engineKey(QString(), QRegExp::RegExp, Qt::CaseSensitive), minimal(false) { }
+ : eng(nullptr), engineKey(QString(), QRegExp::RegExp, Qt::CaseSensitive), minimal(false) { }
inline QRegExpPrivate(const QRegExpEngineKey &key)
- : eng(0), engineKey(key), minimal(false) {}
+ : eng(nullptr), engineKey(key), minimal(false) {}
};
#if !defined(QT_NO_REGEXP_OPTIM)
@@ -3886,9 +3886,9 @@ static void prepareEngineForMatch(QRegExpPrivate *priv, const QString &str)
static void invalidateEngine(QRegExpPrivate *priv)
{
- if (priv->eng != 0) {
+ if (priv->eng) {
derefEngine(priv->eng, priv->engineKey);
- priv->eng = 0;
+ priv->eng = nullptr;
priv->matchState.drain();
}
}
diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp
index 9c201e770b..17acd476b2 100644
--- a/src/corelib/tools/qregularexpression.cpp
+++ b/src/corelib/tools/qregularexpression.cpp
@@ -460,34 +460,13 @@ QT_BEGIN_NAMESPACE
\row \li \c{"[a-z]+\\d+"} \li \b true \li \b true
\endtable
- Exact matching is not reflected in QRegularExpression. If you want to be
- sure that the subject string matches the regular expression exactly, you can wrap the
- pattern between a couple of anchoring expressions. Simply
- putting the pattern between the \c{^} and the \c{$} anchors is enough
- in most cases:
+ Exact matching is not reflected in QRegularExpression. If you want
+ to be sure that the subject string matches the regular expression
+ exactly, you can wrap the pattern using the anchoredPattern()
+ function:
\snippet code/src_corelib_tools_qregularexpression.cpp 24
- However, remember that the \c{$} anchor not only matches at the end of the
- string, but also at a newline character right before the end of the string;
- that is, the previous pattern matches against the string "this pattern must
- match exactly\\n". Also, the behaviour of both the \c{^} and the \c{$}
- anchors changes if the MultiLineOption is set either explicitly (as a
- pattern option) or implicitly (as a directive inside the pattern string).
-
- Therefore, in the most general case, you should wrap the pattern between
- the \c{\A} and the \c{\z} anchors:
-
- \snippet code/src_corelib_tools_qregularexpression.cpp 25
-
- Note the usage of the non-capturing group in order to preserve the meaning
- of the branch operator inside the pattern.
-
- The QRegularExpression::anchoredPattern() helper method does exactly that for
- you.
-
- \sa anchoredPattern
-
\section3 Porting from QRegExp's Partial Matching
When using QRegExp::exactMatch(), if an exact match was not found, one
diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp
index 67cce57d01..311058a776 100644
--- a/src/corelib/tools/qringbuffer.cpp
+++ b/src/corelib/tools/qringbuffer.cpp
@@ -105,7 +105,7 @@ const char *QRingBuffer::readPointerAtPosition(qint64 pos, qint64 &length) const
}
length = 0;
- return 0;
+ return nullptr;
}
void QRingBuffer::free(qint64 bytes)
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 83e574bf1c..19d6982133 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -284,11 +284,9 @@ Q_INLINE_TEMPLATE void QSet<T>::reserve(int asize) { q_hash.reserve(asize); }
template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::unite(const QSet<T> &other)
{
- QSet<T> copy(other);
- typename QSet<T>::const_iterator i = copy.constEnd();
- while (i != copy.constBegin()) {
- --i;
- insert(*i);
+ if (!q_hash.isSharedWith(other.q_hash)) {
+ for (const T &e : other)
+ insert(e);
}
return *this;
}
@@ -306,11 +304,9 @@ Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
copy2 = *this;
*this = copy1;
}
- typename QSet<T>::const_iterator i = copy1.constEnd();
- while (i != copy1.constBegin()) {
- --i;
- if (!copy2.contains(*i))
- remove(*i);
+ for (const auto &e : qAsConst(copy1)) {
+ if (!copy2.contains(e))
+ remove(e);
}
return *this;
}
@@ -346,14 +342,11 @@ Q_INLINE_TEMPLATE bool QSet<T>::intersects(const QSet<T> &other) const
template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::subtract(const QSet<T> &other)
{
- if (&other == this) {
+ if (q_hash.isSharedWith(other.q_hash)) {
clear();
} else {
- auto i = other.constEnd();
- while (i != other.constBegin()) {
- --i;
- remove(*i);
- }
+ for (const auto &e : other)
+ remove(e);
}
return *this;
}
@@ -409,6 +402,7 @@ QList<T> QList<T>::fromSet(const QSet<T> &set)
Q_DECLARE_SEQUENTIAL_ITERATOR(Set)
+#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
template <typename T>
class QMutableSetIterator
{
@@ -440,6 +434,7 @@ public:
{ while (c->constBegin() != i) if (*(n = --i) == t) return true;
n = c->end(); return false; }
};
+#endif // QT_NO_JAVA_STYLE_ITERATORS
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index 816583c766..ab54c76720 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -75,7 +75,7 @@ public:
typedef T Type;
typedef T *pointer;
- inline void detach() { if (d && d->ref.load() != 1) detach_helper(); }
+ inline void detach() { if (d && d->ref.loadRelaxed() != 1) detach_helper(); }
inline T &operator*() { detach(); return *d; }
inline const T &operator*() const { return *d; }
inline T *operator->() { detach(); return d; }
@@ -163,7 +163,7 @@ public:
inline const T *constData() const { return d; }
inline T *take() { T *x = d; d = nullptr; return x; }
- inline void detach() { if (d && d->ref.load() != 1) detach_helper(); }
+ inline void detach() { if (d && d->ref.loadRelaxed() != 1) detach_helper(); }
inline void reset()
{
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index e4de5a2ba9..f185d2f23f 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -1380,7 +1380,7 @@ void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bo
*/
void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *)
{
- if (strongref.load() < 0)
+ if (strongref.loadRelaxed() < 0)
qWarning("QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
}
@@ -1390,7 +1390,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj));
Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted");
- ExternalRefCountData *that = d->sharedRefcount.load();
+ ExternalRefCountData *that = d->sharedRefcount.loadRelaxed();
if (that) {
that->weakref.ref();
return that;
@@ -1398,8 +1398,8 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
// we can create the refcount data because it doesn't exist
ExternalRefCountData *x = new ExternalRefCountData(Qt::Uninitialized);
- x->strongref.store(-1);
- x->weakref.store(2); // the QWeakPointer that called us plus the QObject itself
+ x->strongref.storeRelaxed(-1);
+ x->weakref.storeRelaxed(2); // the QWeakPointer that called us plus the QObject itself
ExternalRefCountData *ret;
if (d->sharedRefcount.testAndSetOrdered(nullptr, x, ret)) { // ought to be release+acquire; this is acq_rel+acquire
@@ -1407,7 +1407,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
} else {
// ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
// only execute this if Q_ASSERTs are enabled
- Q_ASSERT((x->weakref.store(0), true));
+ Q_ASSERT((x->weakref.storeRelaxed(0), true));
delete x;
ret->weakref.ref();
}
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 55f0f17c52..198cc58c38 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -107,6 +107,10 @@ template <class X, class T>
QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &ptr);
#endif
+namespace QtPrivate {
+struct EnableInternalData;
+}
+
namespace QtSharedPointer {
template <class T> class ExternalRefCount;
@@ -150,11 +154,11 @@ namespace QtSharedPointer {
inline ExternalRefCountData(DestroyerFn d)
: destroyer(d)
{
- strongref.store(1);
- weakref.store(1);
+ strongref.storeRelaxed(1);
+ weakref.storeRelaxed(1);
}
inline ExternalRefCountData(Qt::Initialization) { }
- ~ExternalRefCountData() { Q_ASSERT(!weakref.load()); Q_ASSERT(strongref.load() <= 0); }
+ ~ExternalRefCountData() { Q_ASSERT(!weakref.loadRelaxed()); Q_ASSERT(strongref.loadRelaxed() <= 0); }
void destroy() { destroyer(this); }
@@ -518,12 +522,12 @@ public:
if (o) {
// increase the strongref, but never up from zero
// or less (-1 is used by QWeakPointer on untracked QObject)
- int tmp = o->strongref.load();
+ int tmp = o->strongref.loadRelaxed();
while (tmp > 0) {
// try to increment from "tmp" to "tmp + 1"
if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
break; // succeeded
- tmp = o->strongref.load(); // failed, try again
+ tmp = o->strongref.loadRelaxed(); // failed, try again
}
if (tmp > 0) {
@@ -536,7 +540,7 @@ public:
qSwap(d, o);
qSwap(this->value, actual);
- if (!d || d->strongref.load() == 0)
+ if (!d || d->strongref.loadRelaxed() == 0)
this->value = nullptr;
// dereference saved data
@@ -562,7 +566,7 @@ public:
typedef const value_type &const_reference;
typedef qptrdiff difference_type;
- bool isNull() const noexcept { return d == nullptr || d->strongref.load() == 0 || value == nullptr; }
+ bool isNull() const noexcept { return d == nullptr || d->strongref.loadRelaxed() == 0 || value == nullptr; }
operator RestrictedBool() const noexcept { return isNull() ? nullptr : &QWeakPointer::value; }
bool operator !() const noexcept { return isNull(); }
@@ -672,21 +676,12 @@ public:
#endif
private:
-
+ friend struct QtPrivate::EnableInternalData;
#if defined(Q_NO_TEMPLATE_FRIENDS)
public:
#else
template <class X> friend class QSharedPointer;
template <class X> friend class QPointer;
-# ifndef QT_NO_QOBJECT
- template<typename X>
- friend QWeakPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<X*>::Value, X>::type>
- qWeakPointerFromVariant(const QVariant &variant);
-# endif
- template<typename X>
- friend QPointer<X>
- qPointerFromVariant(const QVariant &variant);
- friend QtPrivate::QSmartPointerConvertFunctor<QWeakPointer>;
#endif
template <class X>
@@ -714,13 +709,24 @@ public:
// a weak pointer's data but the weak pointer itself
inline T *internalData() const noexcept
{
- return d == nullptr || d->strongref.load() == 0 ? nullptr : value;
+ return d == nullptr || d->strongref.loadRelaxed() == 0 ? nullptr : value;
}
Data *d;
T *value;
};
+namespace QtPrivate {
+struct EnableInternalData {
+ template <typename T>
+ static T *internalData(const QWeakPointer<T> &p) noexcept { return p.internalData(); }
+};
+// hack to delay name lookup to instantiation time by making
+// EnableInternalData a dependent name:
+template <typename T>
+struct EnableInternalDataWrap : EnableInternalData {};
+}
+
template <class T>
class QEnableSharedFromThis
{
@@ -996,7 +1002,7 @@ template<typename T>
QWeakPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
qWeakPointerFromVariant(const QVariant &variant)
{
- return QWeakPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).internalData()));
+ return QWeakPointer<T>(qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(QtSharedPointer::weakPointerFromVariant_internal(variant))));
}
template<typename T>
QSharedPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type>
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index ddd715f745..ecf1822e42 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -563,9 +563,9 @@ quint64 qDetectCpuFeatures()
features_string + features_indices[qCountTrailingZeroBits(missing)]);
}
- qt_cpu_features[0].store(f | quint32(QSimdInitialized));
+ qt_cpu_features[0].storeRelaxed(f | quint32(QSimdInitialized));
#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
- qt_cpu_features[1].store(f >> 32);
+ qt_cpu_features[1].storeRelaxed(f >> 32);
#endif
return f;
}
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index c36e1e484f..db2f546651 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -348,9 +348,9 @@ Q_CORE_EXPORT quint64 qDetectCpuFeatures();
static inline quint64 qCpuFeatures()
{
- quint64 features = qt_cpu_features[0].load();
+ quint64 features = qt_cpu_features[0].loadRelaxed();
#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
- features |= quint64(qt_cpu_features[1].load()) << 32;
+ features |= quint64(qt_cpu_features[1].loadRelaxed()) << 32;
#endif
if (Q_UNLIKELY(features == 0)) {
features = qDetectCpuFeatures();
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 963c2a4d34..47db97cdfc 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -145,7 +145,8 @@ extern "C" void qt_toLatin1_mips_dsp_asm(uchar *dst, const ushort *src, int leng
// internal
qsizetype qFindStringBoyerMoore(QStringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs);
static inline qsizetype qFindChar(QStringView str, QChar ch, qsizetype from, Qt::CaseSensitivity cs) noexcept;
-static inline qsizetype qt_last_index_of(QStringView haystack, QChar needle, qsizetype from, Qt::CaseSensitivity cs);
+template <typename Haystack>
+static inline qsizetype qLastIndexOf(Haystack haystack, QChar needle, qsizetype from, Qt::CaseSensitivity cs) noexcept;
static inline qsizetype qt_string_count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs);
static inline qsizetype qt_string_count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs);
@@ -1738,6 +1739,24 @@ const QString::Null QString::null = { };
and the \c{'+'} will automatically be performed as the
\c{QStringBuilder} \c{'%'} everywhere.
+ \section1 Maximum size and out-of-memory conditions
+
+ The current version of QString is limited to just under 2 GB (2^31 bytes)
+ in size. The exact value is architecture-dependent, since it depends on the
+ overhead required for managing the data block, but is no more than 32
+ bytes. Raw data blocks are also limited by the use of \c int type in the
+ current version to 2 GB minus 1 byte. Since QString uses two bytes per
+ character, that translates to just under 2^30 characters in one QString.
+
+ In case memory allocation fails, QString will throw a \c std::bad_alloc
+ exception. Out of memory conditions in the Qt containers are the only case
+ where Qt will throw exceptions.
+
+ Note that the operating system may impose further limits on applications
+ holding a lot of allocated memory, especially large, contiguous blocks.
+ Such considerations, the configuration of such behavior or any mitigation
+ are outside the scope of the Qt API.
+
\sa fromRawData(), QChar, QLatin1String, QByteArray, QStringRef
*/
@@ -3044,7 +3063,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
{
// Copy after if it lies inside our own d->data() area (which we could
// possibly invalidate via a realloc or modify by replacement).
- QChar *afterBuffer = 0;
+ QChar *afterBuffer = nullptr;
if (pointsIntoRange(after, d->data(), d->size)) // Use copy in place of vulnerable original:
after = afterBuffer = textCopy(after, alen);
@@ -3129,7 +3148,7 @@ QString &QString::replace(const QChar *before, int blen,
return *this;
QStringMatcher matcher(before, blen, cs);
- QChar *beforeBuffer = 0, *afterBuffer = 0;
+ QChar *beforeBuffer = nullptr, *afterBuffer = nullptr;
int index = 0;
while (1) {
@@ -3700,7 +3719,7 @@ bool QString::operator>(QLatin1String other) const noexcept
*/
int QString::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(QtPrivate::findString(QStringView(unicode(), length()), from, QStringView(str.unicode(), str.length()), cs));
}
#endif // QT_STRINGVIEW_LEVEL < 2
@@ -3744,7 +3763,7 @@ int QString::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
int QString::indexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(QtPrivate::findString(QStringView(unicode(), size()), from, str, cs));
}
@@ -3757,7 +3776,7 @@ int QString::indexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
*/
int QString::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(qFindChar(QStringView(unicode(), length()), ch, from, cs));
}
@@ -3776,77 +3795,9 @@ int QString::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
*/
int QString::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(QtPrivate::findString(QStringView(unicode(), length()), from, QStringView(str.unicode(), str.length()), cs));
}
-#endif // QT_STRINGVIEW_LEVEL < 2
-
-static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *needle, int sl, Qt::CaseSensitivity cs)
-{
- /*
- See indexOf() for explanations.
- */
-
- auto sv = [sl](const ushort *v) { return QStringView(v, sl); };
-
- const ushort *end = haystack;
- haystack += from;
- const uint sl_minus_1 = sl - 1;
- const ushort *n = needle+sl_minus_1;
- const ushort *h = haystack+sl_minus_1;
- uint hashNeedle = 0, hashHaystack = 0;
- int idx;
-
- if (cs == Qt::CaseSensitive) {
- for (idx = 0; idx < sl; ++idx) {
- hashNeedle = ((hashNeedle<<1) + *(n-idx));
- hashHaystack = ((hashHaystack<<1) + *(h-idx));
- }
- hashHaystack -= *haystack;
-
- while (haystack >= end) {
- hashHaystack += *haystack;
- if (hashHaystack == hashNeedle
- && qt_compare_strings(sv(needle), sv(haystack), Qt::CaseSensitive) == 0)
- return haystack - end;
- --haystack;
- REHASH(haystack[sl]);
- }
- } else {
- for (idx = 0; idx < sl; ++idx) {
- hashNeedle = ((hashNeedle<<1) + foldCase(n-idx, needle));
- hashHaystack = ((hashHaystack<<1) + foldCase(h-idx, end));
- }
- hashHaystack -= foldCase(haystack, end);
-
- while (haystack >= end) {
- hashHaystack += foldCase(haystack, end);
- if (hashHaystack == hashNeedle
- && qt_compare_strings(sv(haystack), sv(needle), Qt::CaseInsensitive) == 0)
- return haystack - end;
- --haystack;
- REHASH(foldCase(haystack + sl, end));
- }
- }
- return -1;
-}
-
-static inline int lastIndexOfHelper(
- const QStringRef &haystack, int from, const QStringRef &needle, Qt::CaseSensitivity cs)
-{
- return lastIndexOfHelper(reinterpret_cast<const ushort*>(haystack.unicode()), from,
- reinterpret_cast<const ushort*>(needle.unicode()), needle.size(), cs);
-}
-
-static inline int lastIndexOfHelper(
- const QStringRef &haystack, int from, QLatin1String needle, Qt::CaseSensitivity cs)
-{
- const int size = needle.size();
- QVarLengthArray<ushort> s(size);
- qt_from_latin1(s.data(), needle.latin1(), size);
- return lastIndexOfHelper(reinterpret_cast<const ushort*>(haystack.unicode()), from,
- s.data(), size, cs);
-}
/*!
Returns the index position of the last occurrence of the string \a
@@ -3866,9 +3817,12 @@ static inline int lastIndexOfHelper(
*/
int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
{
- return QStringRef(this).lastIndexOf(QStringRef(&str), from, cs);
+ // ### Qt6: qsizetype
+ return int(QtPrivate::lastIndexOf(*this, from, str, cs));
}
+#endif // QT_STRINGVIEW_LEVEL < 2
+
/*!
\since 4.5
\overload lastIndexOf()
@@ -3890,7 +3844,8 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
*/
int QString::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
{
- return QStringRef(this).lastIndexOf(str, from, cs);
+ // ### Qt6: qsizetype
+ return int(QtPrivate::lastIndexOf(*this, from, str, cs));
}
/*!
@@ -3901,10 +3856,11 @@ int QString::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) co
*/
int QString::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
- return int(qt_last_index_of(QStringView(unicode(), size()), ch, from, cs));
+ // ### Qt6: qsizetype
+ return int(qLastIndexOf(*this, ch, from, cs));
}
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\since 4.8
\overload lastIndexOf()
@@ -3922,8 +3878,27 @@ int QString::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
*/
int QString::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
{
- return QStringRef(this).lastIndexOf(str, from, cs);
+ // ### Qt6: qsizetype
+ return int(QtPrivate::lastIndexOf(*this, from, str, cs));
}
+#endif // QT_STRINGVIEW_LEVEL < 2
+
+/*!
+ \fn int QString::lastIndexOf(QStringView str, int from, Qt::CaseSensitivity cs) const
+ \since 5.14
+ \overload lastIndexOf()
+
+ Returns the index position of the last occurrence of the string view \a
+ str in this string, searching backward from index position \a
+ from. If \a from is -1 (default), the search starts at the last
+ character; if \a from is -2, at the next to last character and so
+ on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa indexOf(), contains(), count()
+*/
#if !(defined(QT_NO_REGEXP) && !QT_CONFIG(regularexpression))
@@ -4235,7 +4210,7 @@ QString &QString::replace(const QRegularExpression &re, const QString &after)
int QString::count(const QString &str, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
@@ -4252,7 +4227,7 @@ int QString::count(const QString &str, Qt::CaseSensitivity cs) const
int QString::count(QChar ch, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(qt_string_count(QStringView(unicode(), size()), ch, cs));
}
@@ -4269,7 +4244,7 @@ int QString::count(QChar ch, Qt::CaseSensitivity cs) const
*/
int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
@@ -5591,7 +5566,7 @@ QString QString::fromUtf16(const ushort *unicode, int size)
while (unicode[size] != 0)
++size;
}
- return QUtf16::convertToUnicode((const char *)unicode, size*2, 0);
+ return QUtf16::convertToUnicode((const char *)unicode, size*2, nullptr);
}
/*!
@@ -5645,7 +5620,7 @@ QString QString::fromUcs4(const uint *unicode, int size)
while (unicode[size] != 0)
++size;
}
- return QUtf32::convertToUnicode((const char *)unicode, size*4, 0);
+ return QUtf32::convertToUnicode((const char *)unicode, size*4, nullptr);
}
@@ -8060,7 +8035,7 @@ void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::
version = QChar::currentUnicodeVersion();
} else if (int(version) <= NormalizationCorrectionsVersionMax) {
const QString &s = *data;
- QChar *d = 0;
+ QChar *d = nullptr;
for (int i = 0; i < NumNormalizationCorrections; ++i) {
const NormalizationCorrection &n = uc_normalization_corrections[i];
if (n.version > version) {
@@ -8797,19 +8772,23 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, QChar fillCha
return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
}
-static int getEscape(const QChar *uc, int *pos, int len, int maxNumber = 999)
+static inline ushort to_unicode(const QChar c) { return c.unicode(); }
+static inline ushort to_unicode(const char c) { return QLatin1Char{c}.unicode(); }
+
+template <typename Char>
+static int getEscape(const Char *uc, qsizetype *pos, qsizetype len, int maxNumber = 999)
{
int i = *pos;
++i;
if (i < len && uc[i] == QLatin1Char('L'))
++i;
if (i < len) {
- int escape = uc[i].unicode() - '0';
+ int escape = to_unicode(uc[i]) - '0';
if (uint(escape) >= 10U)
return -1;
++i;
while (i < len) {
- int digit = uc[i].unicode() - '0';
+ int digit = to_unicode(uc[i]) - '0';
if (uint(digit) >= 10U)
break;
escape = (escape * 10) + digit;
@@ -8860,18 +8839,23 @@ static int getEscape(const QChar *uc, int *pos, int len, int maxNumber = 999)
namespace {
struct Part
{
- Part() : stringRef(), number(0) {}
- Part(const QString &s, int pos, int len, int num = -1) noexcept
- : stringRef(&s, pos, len), number(num) {}
+ Part() = default; // for QVarLengthArray; do not use
+ Q_DECL_CONSTEXPR Part(QStringView s, int num = -1)
+ : tag{QtPrivate::ArgBase::U16}, number{num}, data{s.utf16()}, size{s.size()} {}
+ Q_DECL_CONSTEXPR Part(QLatin1String s, int num = -1)
+ : tag{QtPrivate::ArgBase::L1}, number{num}, data{s.data()}, size{s.size()} {}
+
+ void reset(QStringView s) noexcept { *this = {s, number}; }
+ void reset(QLatin1String s) noexcept { *this = {s, number}; }
- QStringRef stringRef;
+ QtPrivate::ArgBase::Tag tag;
int number;
+ const void *data;
+ qsizetype size;
};
} // unnamed namespace
-template <>
-class QTypeInfo<Part> : public QTypeInfoMerger<Part, QStringRef, int> {}; // Q_DECLARE_METATYPE
-
+Q_DECLARE_TYPEINFO(Part, Q_PRIMITIVE_TYPE);
namespace {
@@ -8880,24 +8864,25 @@ enum { ExpectedParts = 32 };
typedef QVarLengthArray<Part, ExpectedParts> ParseResult;
typedef QVarLengthArray<int, ExpectedParts/2> ArgIndexToPlaceholderMap;
-static ParseResult parseMultiArgFormatString(const QString &s)
+template <typename StringView>
+static ParseResult parseMultiArgFormatString(StringView s)
{
ParseResult result;
- const QChar *uc = s.constData();
- const int len = s.size();
- const int end = len - 1;
- int i = 0;
- int last = 0;
+ const auto uc = s.data();
+ const auto len = s.size();
+ const auto end = len - 1;
+ qsizetype i = 0;
+ qsizetype last = 0;
while (i < end) {
if (uc[i] == QLatin1Char('%')) {
- int percent = i;
+ qsizetype percent = i;
int number = getEscape(uc, &i, len);
if (number != -1) {
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
+ result.push_back(Part{s.mid(last, percent - last)}); // literal text (incl. failed placeholders)
+ result.push_back(Part{s.mid(percent, i - percent), number}); // parsed placeholder
last = i;
continue;
}
@@ -8906,7 +8891,7 @@ static ParseResult parseMultiArgFormatString(const QString &s)
}
if (last < len)
- result.push_back(Part(s, last, len - last)); // trailing literal text
+ result.push_back(Part{s.mid(last, len - last)}); // trailing literal text
return result;
}
@@ -8915,9 +8900,9 @@ static ArgIndexToPlaceholderMap makeArgIndexToPlaceholderMap(const ParseResult &
{
ArgIndexToPlaceholderMap result;
- for (ParseResult::const_iterator it = parts.begin(), end = parts.end(); it != end; ++it) {
- if (it->number >= 0)
- result.push_back(it->number);
+ for (Part part : parts) {
+ if (part.number >= 0)
+ result.push_back(part.number);
}
std::sort(result.begin(), result.end());
@@ -8927,54 +8912,107 @@ static ArgIndexToPlaceholderMap makeArgIndexToPlaceholderMap(const ParseResult &
return result;
}
-static int resolveStringRefsAndReturnTotalSize(ParseResult &parts, const ArgIndexToPlaceholderMap &argIndexToPlaceholderMap, const QString *args[])
+static qsizetype resolveStringRefsAndReturnTotalSize(ParseResult &parts, const ArgIndexToPlaceholderMap &argIndexToPlaceholderMap, const QtPrivate::ArgBase *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()]);
+ using namespace QtPrivate;
+ qsizetype totalSize = 0;
+ for (Part &part : parts) {
+ if (part.number != -1) {
+ const auto it = std::find(argIndexToPlaceholderMap.begin(), argIndexToPlaceholderMap.end(), part.number);
+ if (it != argIndexToPlaceholderMap.end()) {
+ const auto &arg = *args[it - argIndexToPlaceholderMap.begin()];
+ switch (arg.tag) {
+ case ArgBase::L1:
+ part.reset(static_cast<const QLatin1StringArg&>(arg).string);
+ break;
+ case ArgBase::U8:
+ Q_UNREACHABLE(); // waiting for QUtf8String...
+ break;
+ case ArgBase::U16:
+ part.reset(static_cast<const QStringViewArg&>(arg).string);
+ break;
+ }
+ }
}
- totalSize += pit->stringRef.size();
+ totalSize += part.size;
}
return totalSize;
}
} // unnamed namespace
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QString QString::multiArg(int numArgs, const QString **args) const
{
+ QVarLengthArray<QtPrivate::QStringViewArg, 9> sva;
+ sva.reserve(numArgs);
+ QVarLengthArray<const QtPrivate::ArgBase *, 9> pointers;
+ pointers.reserve(numArgs);
+ for (int i = 0; i < numArgs; ++i) {
+ sva.push_back(QtPrivate::qStringLikeToArg(*args[i]));
+ pointers.push_back(&sva.back());
+ }
+ return QtPrivate::argToQString(qToStringViewIgnoringNull(*this), static_cast<size_t>(numArgs), pointers.data());
+}
+#endif
+
+Q_ALWAYS_INLINE QString to_string(QLatin1String s) noexcept { return s; }
+Q_ALWAYS_INLINE QString to_string(QStringView s) noexcept { return s.toString(); }
+
+template <typename StringView>
+static QString argToQStringImpl(StringView pattern, size_t numArgs, const QtPrivate::ArgBase **args)
+{
// Step 1-2 above
- ParseResult parts = parseMultiArgFormatString(*this);
+ ParseResult parts = parseMultiArgFormatString(pattern);
// 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());
+ if (static_cast<size_t>(argIndexToPlaceholderMap.size()) > numArgs) // 3a
+ argIndexToPlaceholderMap.resize(int(numArgs));
+ else if (Q_UNLIKELY(static_cast<size_t>(argIndexToPlaceholderMap.size()) < numArgs)) // 3b
+ qWarning("QString::arg: %d argument(s) missing in %ls",
+ int(numArgs - argIndexToPlaceholderMap.size()), qUtf16Printable(to_string(pattern)));
// 5
- const int totalSize = resolveStringRefsAndReturnTotalSize(parts, argIndexToPlaceholderMap, args);
+ const qsizetype 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;
+ auto out = const_cast<QChar*>(result.constData());
+
+ for (Part part : parts) {
+ switch (part.tag) {
+ case QtPrivate::ArgBase::L1:
+ if (part.size) {
+ qt_from_latin1(reinterpret_cast<ushort*>(out),
+ reinterpret_cast<const char*>(part.data), part.size);
+ }
+ break;
+ case QtPrivate::ArgBase::U8:
+ Q_UNREACHABLE(); // waiting for QUtf8String
+ break;
+ case QtPrivate::ArgBase::U16:
+ if (part.size)
+ memcpy(out, part.data, part.size * sizeof(QChar));
+ break;
}
+ out += part.size;
}
return result;
}
+QString QtPrivate::argToQString(QStringView pattern, size_t n, const ArgBase **args)
+{
+ return argToQStringImpl(pattern, n, args);
+}
+
+QString QtPrivate::argToQString(QLatin1String pattern, size_t n, const ArgBase **args)
+{
+ return argToQStringImpl(pattern, n, args);
+}
+
/*! \fn bool QString::isSimpleText() const
\internal
@@ -9562,6 +9600,24 @@ QString &QString::setRawData(const QChar *unicode, int size)
*/
/*!
+ \fn int QLatin1String::lastIndexOf(QStringView str, int from, Qt::CaseSensitivity cs) const
+ \fn int QLatin1String::lastIndexOf(QLatin1String l1, int from, Qt::CaseSensitivity cs) const
+ \fn int QLatin1String::lastIndexOf(QChar c, int from, Qt::CaseSensitivity cs) const
+ \since 5.14
+
+ Returns the index position of the last occurrence of the string-view \a str,
+ Latin-1 string \a l1, or character \a ch, respectively, in this Latin-1 string,
+ searching backward from index position \a from. If \a from is -1 (default),
+ the search starts at the last character; if \a from is -2, at the next to last
+ character and so on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa indexOf(), QStringView::lastIndexOf(), QStringView::indexOf(), QString::indexOf()
+*/
+
+/*!
\fn QLatin1String::const_iterator QLatin1String::begin() const
\since 5.10
@@ -11134,7 +11190,7 @@ QStringRef QString::midRef(int position, int n) const
*/
int QStringRef::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(QtPrivate::findString(QStringView(unicode(), length()), from, QStringView(str.unicode(), str.length()), cs));
}
#endif // QT_STRINGVIEW_LEVEL < 2
@@ -11169,7 +11225,7 @@ int QStringRef::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) co
*/
int QStringRef::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(qFindChar(QStringView(unicode(), length()), ch, from, cs));
}
@@ -11190,7 +11246,7 @@ int QStringRef::indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
*/
int QStringRef::indexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(QtPrivate::findString(QStringView(unicode(), size()), from, str, cs));
}
@@ -11211,7 +11267,7 @@ int QStringRef::indexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) con
*/
int QStringRef::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(QtPrivate::findString(QStringView(unicode(), size()), from, QStringView(str.unicode(), str.size()), cs));
}
#endif // QT_STRINGVIEW_LEVEL < 2
@@ -11232,7 +11288,8 @@ int QStringRef::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs)
*/
int QStringRef::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
{
- return lastIndexOf(QStringRef(&str), from, cs);
+ // ### Qt6: qsizetype
+ return int(QtPrivate::lastIndexOf(*this, from, str, cs));
}
/*!
@@ -11246,29 +11303,8 @@ int QStringRef::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs
*/
int QStringRef::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
- return int(qt_last_index_of(QStringView(unicode(), size()), ch, from, cs));
-}
-
-template<typename T>
-static int last_index_of_impl(const QStringRef &haystack, int from, const T &needle, Qt::CaseSensitivity cs)
-{
- const int sl = needle.size();
- if (sl == 1)
- return haystack.lastIndexOf(needle.at(0), from, cs);
-
- const int l = haystack.size();
- if (from < 0)
- from += l;
- int delta = l - sl;
- if (from == l && sl == 0)
- return from;
- if (uint(from) >= uint(l) || delta < 0)
- return -1;
- if (from > delta)
- from = delta;
-
- return lastIndexOfHelper(haystack, from, needle, cs);
+ // ### Qt6: qsizetype
+ return int(qLastIndexOf(*this, ch, from, cs));
}
/*!
@@ -11288,7 +11324,8 @@ static int last_index_of_impl(const QStringRef &haystack, int from, const T &nee
*/
int QStringRef::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
{
- return last_index_of_impl(*this, from, str, cs);
+ // ### Qt6: qsizetype
+ return int(QtPrivate::lastIndexOf(*this, from, str, cs));
}
/*!
@@ -11308,10 +11345,28 @@ int QStringRef::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs)
*/
int QStringRef::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) const
{
- return last_index_of_impl(*this, from, str, cs);
+ // ### Qt6: qsizetype
+ return int(QtPrivate::lastIndexOf(*this, from, str, cs));
}
/*!
+ \fn int QStringRef::lastIndexOf(QStringView str, int from, Qt::CaseSensitivity cs) const
+ \since 5.14
+ \overload lastIndexOf()
+
+ Returns the index position of the last occurrence of the string view \a
+ str in this string, searching backward from index position \a
+ from. If \a from is -1 (default), the search starts at the last
+ character; if \a from is -2, at the next to last character and so
+ on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa indexOf(), contains(), count()
+*/
+
+/*!
\since 4.8
Returns the number of (potentially overlapping) occurrences of
the string \a str in this string reference.
@@ -11323,7 +11378,7 @@ int QStringRef::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity
*/
int QStringRef::count(const QString &str, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
@@ -11341,7 +11396,7 @@ int QStringRef::count(const QString &str, Qt::CaseSensitivity cs) const
*/
int QStringRef::count(QChar ch, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(qt_string_count(QStringView(unicode(), size()), ch, cs));
}
@@ -11359,7 +11414,7 @@ int QStringRef::count(QChar ch, Qt::CaseSensitivity cs) const
*/
int QStringRef::count(const QStringRef &str, Qt::CaseSensitivity cs) const
{
- // ### Qt6: qsize
+ // ### Qt6: qsizetype
return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
@@ -11613,33 +11668,6 @@ bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
-static inline qsizetype qt_last_index_of(QStringView haystack, QChar needle,
- qsizetype from, Qt::CaseSensitivity cs)
-{
- if (from < 0)
- from += haystack.size();
- if (std::size_t(from) >= std::size_t(haystack.size()))
- return -1;
- if (from >= 0) {
- ushort c = needle.unicode();
- const ushort *b = reinterpret_cast<const ushort*>(haystack.data());
- const ushort *n = b + from;
- if (cs == Qt::CaseSensitive) {
- for (; n >= b; --n)
- if (*n == c)
- return n - b;
- } else {
- c = foldCase(c);
- for (; n >= b; --n)
- if (foldCase(*n) == c)
- return n - b;
- }
- }
- return -1;
-
-
-}
-
static inline qsizetype qt_string_count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs)
{
qsizetype num = 0;
@@ -11821,6 +11849,38 @@ bool QtPrivate::endsWith(QLatin1String haystack, QLatin1String needle, Qt::CaseS
return qt_ends_with_impl(haystack, needle, cs);
}
+namespace {
+template <typename Pointer>
+uint foldCaseHelper(Pointer ch, Pointer start) = delete;
+
+template <>
+uint foldCaseHelper<const QChar*>(const QChar* ch, const QChar* start)
+{
+ return foldCase(reinterpret_cast<const ushort*>(ch), reinterpret_cast<const ushort*>(start));
+}
+
+template <>
+uint foldCaseHelper<const char*>(const char* ch, const char*)
+{
+ return foldCase(ushort(uchar(*ch)));
+}
+
+template <typename T>
+ushort valueTypeToUtf16(T t) = delete;
+
+template <>
+ushort valueTypeToUtf16<QChar>(QChar t)
+{
+ return t.unicode();
+}
+
+template <>
+ushort valueTypeToUtf16<char>(char t)
+{
+ return ushort(uchar(t));
+}
+}
+
/*!
\internal
@@ -11929,6 +11989,97 @@ qsizetype QtPrivate::findString(QStringView haystack0, qsizetype from, QStringVi
return -1;
}
+template <typename Haystack>
+static inline qsizetype qLastIndexOf(Haystack haystack, QChar needle,
+ qsizetype from, Qt::CaseSensitivity cs) noexcept
+{
+ if (from < 0)
+ from += haystack.size();
+ if (std::size_t(from) >= std::size_t(haystack.size()))
+ return -1;
+ if (from >= 0) {
+ ushort c = needle.unicode();
+ const auto b = haystack.data();
+ auto n = b + from;
+ if (cs == Qt::CaseSensitive) {
+ for (; n >= b; --n)
+ if (valueTypeToUtf16(*n) == c)
+ return n - b;
+ } else {
+ c = foldCase(c);
+ for (; n >= b; --n)
+ if (foldCase(valueTypeToUtf16(*n)) == c)
+ return n - b;
+ }
+ }
+ return -1;
+}
+
+template<typename Haystack, typename Needle>
+static qsizetype qLastIndexOf(Haystack haystack0, qsizetype from,
+ Needle needle0, Qt::CaseSensitivity cs) noexcept
+{
+ const qsizetype sl = needle0.size();
+ if (sl == 1)
+ return qLastIndexOf(haystack0, needle0.front(), from, cs);
+
+ const qsizetype l = haystack0.size();
+ if (from < 0)
+ from += l;
+ if (from == l && sl == 0)
+ return from;
+ const qsizetype delta = l - sl;
+ if (std::size_t(from) >= std::size_t(l) || delta < 0)
+ return -1;
+ if (from > delta)
+ from = delta;
+
+ auto sv = [sl](const typename Haystack::value_type *v) { return Haystack(v, sl); };
+
+ auto haystack = haystack0.data();
+ const auto needle = needle0.data();
+ const auto *end = haystack;
+ haystack += from;
+ const std::size_t sl_minus_1 = sl - 1;
+ const auto *n = needle + sl_minus_1;
+ const auto *h = haystack + sl_minus_1;
+ std::size_t hashNeedle = 0, hashHaystack = 0;
+ qsizetype idx;
+
+ if (cs == Qt::CaseSensitive) {
+ for (idx = 0; idx < sl; ++idx) {
+ hashNeedle = (hashNeedle << 1) + valueTypeToUtf16(*(n - idx));
+ hashHaystack = (hashHaystack << 1) + valueTypeToUtf16(*(h - idx));
+ }
+ hashHaystack -= valueTypeToUtf16(*haystack);
+
+ while (haystack >= end) {
+ hashHaystack += valueTypeToUtf16(*haystack);
+ if (hashHaystack == hashNeedle
+ && qt_compare_strings(needle0, sv(haystack), Qt::CaseSensitive) == 0)
+ return haystack - end;
+ --haystack;
+ REHASH(valueTypeToUtf16(haystack[sl]));
+ }
+ } else {
+ for (idx = 0; idx < sl; ++idx) {
+ hashNeedle = (hashNeedle << 1) + foldCaseHelper(n - idx, needle);
+ hashHaystack = (hashHaystack << 1) + foldCaseHelper(h - idx, end);
+ }
+ hashHaystack -= foldCaseHelper(haystack, end);
+
+ while (haystack >= end) {
+ hashHaystack += foldCaseHelper(haystack, end);
+ if (hashHaystack == hashNeedle
+ && qt_compare_strings(sv(haystack), needle0, Qt::CaseInsensitive) == 0)
+ return haystack - end;
+ --haystack;
+ REHASH(foldCaseHelper(haystack + sl, end));
+ }
+ }
+ return -1;
+}
+
qsizetype QtPrivate::findString(QStringView haystack, qsizetype from, QLatin1String needle, Qt::CaseSensitivity cs) noexcept
{
if (haystack.size() < needle.size())
@@ -11962,6 +12113,26 @@ qsizetype QtPrivate::findString(QLatin1String haystack, qsizetype from, QLatin1S
QStringView(reinterpret_cast<const QChar*>(n.constData()), n.size()), cs);
}
+qsizetype QtPrivate::lastIndexOf(QStringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs) noexcept
+{
+ return qLastIndexOf(haystack, from, needle, cs);
+}
+
+qsizetype QtPrivate::lastIndexOf(QStringView haystack, qsizetype from, QLatin1String needle, Qt::CaseSensitivity cs) noexcept
+{
+ return qLastIndexOf(haystack, from, needle, cs);
+}
+
+qsizetype QtPrivate::lastIndexOf(QLatin1String haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs) noexcept
+{
+ return qLastIndexOf(haystack, from, needle, cs);
+}
+
+qsizetype QtPrivate::lastIndexOf(QLatin1String haystack, qsizetype from, QLatin1String needle, Qt::CaseSensitivity cs) noexcept
+{
+ return qLastIndexOf(haystack, from, needle, cs);
+}
+
/*!
\since 4.8
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index da8260a999..6788e53057 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -106,6 +106,9 @@ public:
Q_DECL_CONSTEXPR bool isNull() const noexcept { return !data(); }
Q_DECL_CONSTEXPR bool isEmpty() const noexcept { return !size(); }
+ template <typename...Args>
+ Q_REQUIRED_RESULT inline QString arg(Args &&...args) const;
+
Q_DECL_CONSTEXPR QLatin1Char at(int i) const
{ return Q_ASSERT(i >= 0), Q_ASSERT(i < size()), QLatin1Char(m_data[i]); }
Q_DECL_CONSTEXPR QLatin1Char operator[](int i) const { return at(i); }
@@ -132,11 +135,11 @@ public:
{ return QtPrivate::endsWith(*this, QStringView(&c, 1), cs); }
Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
- { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsize
+ { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
Q_REQUIRED_RESULT int indexOf(QLatin1String s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
- { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsize
+ { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
Q_REQUIRED_RESULT inline int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
- { return int(QtPrivate::findString(*this, from, QStringView(&c, 1), cs)); } // ### Qt6: qsize
+ { return int(QtPrivate::findString(*this, from, QStringView(&c, 1), cs)); } // ### Qt6: qsizetype
Q_REQUIRED_RESULT bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(s, 0, cs) != -1; }
@@ -145,6 +148,13 @@ public:
Q_REQUIRED_RESULT inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(QStringView(&c, 1), 0, cs) != -1; }
+ Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
+ Q_REQUIRED_RESULT int lastIndexOf(QLatin1String s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
+ Q_REQUIRED_RESULT inline int lastIndexOf(QChar c, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ { return int(QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs)); } // ### Qt6: qsizetype
+
using value_type = const char;
using reference = value_type&;
using const_reference = reference;
@@ -214,7 +224,9 @@ private:
Q_DECLARE_TYPEINFO(QLatin1String, Q_MOVABLE_TYPE);
// Qt 4.x compatibility
-typedef QLatin1String QLatin1Literal;
+#if QT_DEPRECATED_SINCE(5, 14)
+QT_DEPRECATED_X("Use QLatin1String") typedef QLatin1String QLatin1Literal;
+#endif
//
// QLatin1String inline implementations
@@ -233,6 +245,8 @@ qsizetype QStringView::indexOf(QLatin1String s, qsizetype from, Qt::CaseSensitiv
{ return QtPrivate::findString(*this, from, s, cs); }
bool QStringView::contains(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
{ return indexOf(s, 0, cs) != qsizetype(-1); }
+qsizetype QStringView::lastIndexOf(QLatin1String s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
+{ return QtPrivate::lastIndexOf(*this, from, s, cs); }
class Q_CORE_EXPORT QString
{
@@ -353,11 +367,16 @@ public:
int indexOf(const QStringRef &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
- { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsize
+ { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
int lastIndexOf(QChar c, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
- int lastIndexOf(const QString &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(QLatin1String s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+#if QT_STRINGVIEW_LEVEL < 2
+ int lastIndexOf(const QString &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(const QStringRef &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+#endif
+
+ Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2
@@ -905,8 +924,8 @@ private:
void reallocData(uint alloc, bool grow = false);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
void expand(int i);
-#endif
QString multiArg(int numArgs, const QString **args) const;
+#endif
static int compare_helper(const QChar *data1, int length1,
const QChar *data2, int length2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
@@ -1035,30 +1054,30 @@ inline QString QString::arg(short a, int fieldWidth, int base, QChar fillChar) c
inline QString QString::arg(ushort a, int fieldWidth, int base, QChar fillChar) const
{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
inline QString QString::arg(const QString &a1, const QString &a2) const
-{ const QString *args[2] = { &a1, &a2 }; return multiArg(2, args); }
+{ return qToStringViewIgnoringNull(*this).arg(a1, a2); }
inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3) const
-{ const QString *args[3] = { &a1, &a2, &a3 }; return multiArg(3, args); }
+{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3); }
inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
const QString &a4) const
-{ const QString *args[4] = { &a1, &a2, &a3, &a4 }; return multiArg(4, args); }
+{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4); }
inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
const QString &a4, const QString &a5) const
-{ const QString *args[5] = { &a1, &a2, &a3, &a4, &a5 }; return multiArg(5, args); }
+{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5); }
inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
const QString &a4, const QString &a5, const QString &a6) const
-{ const QString *args[6] = { &a1, &a2, &a3, &a4, &a5, &a6 }; return multiArg(6, args); }
+{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6); }
inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
const QString &a4, const QString &a5, const QString &a6,
const QString &a7) const
-{ const QString *args[7] = { &a1, &a2, &a3, &a4, &a5, &a6, &a7 }; return multiArg(7, args); }
+{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6, a7); }
inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
const QString &a4, const QString &a5, const QString &a6,
const QString &a7, const QString &a8) const
-{ const QString *args[8] = { &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8 }; return multiArg(8, args); }
+{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6, a7, a8); }
inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
const QString &a4, const QString &a5, const QString &a6,
const QString &a7, const QString &a8, const QString &a9) const
-{ const QString *args[9] = { &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9 }; return multiArg(9, args); }
+{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6, a7, a8, a9); }
inline QString QString::section(QChar asep, int astart, int aend, SectionFlags aflags) const
{ return section(QString(asep), astart, aend, aflags); }
@@ -1084,7 +1103,7 @@ class
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_CORE_EXPORT
#endif
-QCharRef {
+QCharRef { // ### Qt 7: remove
QString &s;
int i;
inline QCharRef(QString &str, int idx)
@@ -1536,13 +1555,17 @@ public:
int indexOf(const QStringRef &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
- { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsize
+ { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
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;
+#if QT_STRINGVIEW_LEVEL < 2
+ int lastIndexOf(const QStringRef &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(const QString &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+#endif
int lastIndexOf(QChar ch, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(QLatin1String str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
- int lastIndexOf(const QStringRef &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
#if QT_STRINGVIEW_LEVEL < 2
inline bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@@ -1959,6 +1982,58 @@ inline const QString &asString(const QString &s) { return s; }
inline QString &&asString(QString &&s) { return std::move(s); }
}
+//
+// QStringView::arg() implementation
+//
+
+namespace QtPrivate {
+
+struct ArgBase {
+ enum Tag : uchar { L1, U8, U16 } tag;
+};
+
+struct QStringViewArg : ArgBase {
+ QStringView string;
+ QStringViewArg() = default;
+ Q_DECL_CONSTEXPR explicit QStringViewArg(QStringView v) noexcept : ArgBase{U16}, string{v} {}
+};
+
+struct QLatin1StringArg : ArgBase {
+ QLatin1String string;
+ QLatin1StringArg() = default;
+ Q_DECL_CONSTEXPR explicit QLatin1StringArg(QLatin1String v) noexcept : ArgBase{L1}, string{v} {}
+};
+
+Q_REQUIRED_RESULT Q_CORE_EXPORT QString argToQString(QStringView pattern, size_t n, const ArgBase **args);
+Q_REQUIRED_RESULT Q_CORE_EXPORT QString argToQString(QLatin1String pattern, size_t n, const ArgBase **args);
+
+template <typename StringView, typename...Args>
+Q_REQUIRED_RESULT Q_ALWAYS_INLINE QString argToQStringDispatch(StringView pattern, const Args &...args)
+{
+ const ArgBase *argBases[] = {&args..., /* avoid zero-sized array */ nullptr};
+ return QtPrivate::argToQString(pattern, sizeof...(Args), argBases);
+}
+
+Q_DECL_CONSTEXPR inline QStringViewArg qStringLikeToArg(QStringView s) noexcept { return QStringViewArg{s}; }
+ inline QStringViewArg qStringLikeToArg(const QChar &c) noexcept { return QStringViewArg{QStringView{&c, 1}}; }
+Q_DECL_CONSTEXPR inline QLatin1StringArg qStringLikeToArg(QLatin1String s) noexcept { return QLatin1StringArg{s}; }
+
+} // namespace QtPrivate
+
+template <typename...Args>
+Q_ALWAYS_INLINE
+QString QStringView::arg(Args &&...args) const
+{
+ return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
+}
+
+template <typename...Args>
+Q_ALWAYS_INLINE
+QString QLatin1String::arg(Args &&...args) const
+{
+ return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
+}
+
QT_END_NAMESPACE
#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
diff --git a/src/corelib/tools/qstringalgorithms.h b/src/corelib/tools/qstringalgorithms.h
index 51a86cfeb5..2b480b1e4c 100644
--- a/src/corelib/tools/qstringalgorithms.h
+++ b/src/corelib/tools/qstringalgorithms.h
@@ -80,6 +80,11 @@ Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QStrin
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QLatin1String haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype findString(QLatin1String haystack, qsizetype from, QLatin1String needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QStringView haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QStringView haystack, qsizetype from, QLatin1String needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QLatin1String haystack, qsizetype from, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QLatin1String haystack, qsizetype from, QLatin1String needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
+
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QStringView trimmed(QStringView s) noexcept;
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QLatin1String trimmed(QLatin1String s) noexcept;
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index f6da7b1428..4bbe424ed2 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -283,6 +283,7 @@ void QtPrivate::QStringList_sort(QStringList *that, Qt::CaseSensitivity cs)
}
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn QStringList QStringList::filter(const QString &str, Qt::CaseSensitivity cs) const
@@ -302,6 +303,26 @@ void QtPrivate::QStringList_sort(QStringList *that, Qt::CaseSensitivity cs)
\sa contains()
*/
+#endif
+
+/*!
+ \fn QStringList QStringList::filter(QStringView str, Qt::CaseSensitivity cs) const
+ \overload
+ \since 5.14
+*/
+QStringList QtPrivate::QStringList_filter(const QStringList *that, QStringView str,
+ Qt::CaseSensitivity cs)
+{
+ QStringMatcher matcher(str, cs);
+ QStringList res;
+ for (int i = 0; i < that->size(); ++i)
+ if (matcher.indexIn(that->at(i)) != -1)
+ res << that->at(i);
+ return res;
+}
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/// Not really needed anymore, but kept for binary compatibility
QStringList QtPrivate::QStringList_filter(const QStringList *that, const QString &str,
Qt::CaseSensitivity cs)
{
@@ -312,6 +333,7 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QString
res << that->at(i);
return res;
}
+#endif
template<typename T>
static bool stringList_contains(const QStringList &stringList, const T &str, Qt::CaseSensitivity cs)
@@ -466,6 +488,7 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegula
}
#endif // QT_CONFIG(regularexpression)
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn QStringList &QStringList::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
@@ -481,12 +504,41 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegula
\sa QString::replace()
*/
+
+/*!
+ \fn QStringList &QStringList::replaceInStrings(QStringView before, const QString &after, Qt::CaseSensitivity cs)
+ \overload
+ \since 5.14
+*/
+
+/*!
+ \fn QStringList &QStringList::replaceInStrings(const QString &before, QStringView after, Qt::CaseSensitivity cs)
+ \overload
+ \since 5.14
+*/
+#endif
+
+/*!
+ \fn QStringList &QStringList::replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs)
+ \overload
+ \since 5.14
+*/
+void QtPrivate::QStringList_replaceInStrings(QStringList *that, QStringView before,
+ QStringView after, Qt::CaseSensitivity cs)
+{
+ for (int i = 0; i < that->size(); ++i)
+ (*that)[i].replace(before.data(), before.length(), after.data(), after.length(), cs);
+}
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/// Not really needed anymore, but kept for binary compatibility
void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QString &before,
const QString &after, Qt::CaseSensitivity cs)
{
for (int i = 0; i < that->size(); ++i)
(*that)[i].replace(before, after, cs);
}
+#endif
#ifndef QT_NO_REGEXP
@@ -561,6 +613,7 @@ static int accumulatedSize(const QStringList &list, int seplen)
return result;
}
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn QString QStringList::join(const QString &separator) const
@@ -570,6 +623,7 @@ static int accumulatedSize(const QStringList &list, int seplen)
\sa QString::split()
*/
+#endif
/*!
\fn QString QStringList::join(QChar separator) const
@@ -615,6 +669,16 @@ QString QtPrivate::QStringList_join(const QStringList &list, QLatin1String sep)
}
/*!
+ \fn QString QStringList::join(QStringView separator) const
+ \overload
+ \since 5.14
+*/
+QString QtPrivate::QStringList_join(const QStringList *that, QStringView sep)
+{
+ return QStringList_join(that, sep.data(), sep.length());
+}
+
+/*!
\fn QStringList QStringList::operator+(const QStringList &other) const
Returns a string list that is the concatenation of this string
diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h
index 3bb657069b..a464d443dc 100644
--- a/src/corelib/tools/qstringlist.h
+++ b/src/corelib/tools/qstringlist.h
@@ -54,8 +54,10 @@ QT_BEGIN_NAMESPACE
class QRegExp;
class QRegularExpression;
+#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
typedef QListIterator<QString> QStringListIterator;
typedef QMutableListIterator<QString> QMutableStringListIterator;
+#endif
class QStringList;
@@ -73,12 +75,21 @@ public:
inline void sort(Qt::CaseSensitivity cs = Qt::CaseSensitive);
inline int removeDuplicates();
+#if QT_STRINGVIEW_LEVEL < 2
inline QString join(const QString &sep) const;
+#endif
+ inline QString join(QStringView sep) const;
inline QString join(QLatin1String sep) const;
inline QString join(QChar sep) const;
+ inline QStringList filter(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline QStringList &replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+#if QT_STRINGVIEW_LEVEL < 2
inline QStringList filter(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline QStringList &replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ inline QStringList &replaceInStrings(const QString &before, QStringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ inline QStringList &replaceInStrings(QStringView before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
+#endif
#ifndef QT_NO_REGEXP
inline QStringList filter(const QRegExp &rx) const;
@@ -163,18 +174,27 @@ inline const QStringList *QListSpecialMethods<QString>::self() const
namespace QtPrivate {
void Q_CORE_EXPORT QStringList_sort(QStringList *that, Qt::CaseSensitivity cs);
int Q_CORE_EXPORT QStringList_removeDuplicates(QStringList *that);
+ QString Q_CORE_EXPORT QStringList_join(const QStringList *that, QStringView sep);
QString Q_CORE_EXPORT QStringList_join(const QStringList *that, const QChar *sep, int seplen);
Q_CORE_EXPORT QString QStringList_join(const QStringList &list, QLatin1String sep);
+ QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, QStringView str,
+ Qt::CaseSensitivity cs);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QString &str,
Qt::CaseSensitivity cs);
+#endif
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, const QString &str, Qt::CaseSensitivity cs);
#endif
bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, QStringView str, Qt::CaseSensitivity cs);
bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, QLatin1String str, Qt::CaseSensitivity cs);
+ void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, QStringView before, QStringView after,
+ Qt::CaseSensitivity cs);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QString &before, const QString &after,
Qt::CaseSensitivity cs);
+#endif
#ifndef QT_NO_REGEXP
void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QRegExp &rx, const QString &after);
@@ -203,10 +223,17 @@ inline int QListSpecialMethods<QString>::removeDuplicates()
return QtPrivate::QStringList_removeDuplicates(self());
}
+#if QT_STRINGVIEW_LEVEL < 2
inline QString QListSpecialMethods<QString>::join(const QString &sep) const
{
return QtPrivate::QStringList_join(self(), sep.constData(), sep.length());
}
+#endif
+
+inline QString QListSpecialMethods<QString>::join(QStringView sep) const
+{
+ return QtPrivate::QStringList_join(self(), sep);
+}
QString QListSpecialMethods<QString>::join(QLatin1String sep) const
{
@@ -218,10 +245,17 @@ inline QString QListSpecialMethods<QString>::join(QChar sep) const
return QtPrivate::QStringList_join(self(), &sep, 1);
}
+inline QStringList QListSpecialMethods<QString>::filter(QStringView str, Qt::CaseSensitivity cs) const
+{
+ return QtPrivate::QStringList_filter(self(), str, cs);
+}
+
+#if QT_STRINGVIEW_LEVEL < 2
inline QStringList QListSpecialMethods<QString>::filter(const QString &str, Qt::CaseSensitivity cs) const
{
return QtPrivate::QStringList_filter(self(), str, cs);
}
+#endif
#if QT_STRINGVIEW_LEVEL < 2
inline bool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const
@@ -240,12 +274,32 @@ inline bool QStringList::contains(QStringView str, Qt::CaseSensitivity cs) const
return QtPrivate::QStringList_contains(this, str, cs);
}
+inline QStringList &QListSpecialMethods<QString>::replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs)
+{
+ QtPrivate::QStringList_replaceInStrings(self(), before, after, cs);
+ return *self();
+}
+
+#if QT_STRINGVIEW_LEVEL < 2
inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
{
QtPrivate::QStringList_replaceInStrings(self(), before, after, cs);
return *self();
}
+inline QStringList &QListSpecialMethods<QString>::replaceInStrings(QStringView before, const QString &after, Qt::CaseSensitivity cs)
+{
+ QtPrivate::QStringList_replaceInStrings(self(), before, qToStringViewIgnoringNull(after), cs);
+ return *self();
+}
+
+inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QString &before, QStringView after, Qt::CaseSensitivity cs)
+{
+ QtPrivate::QStringList_replaceInStrings(self(), QStringView(before), after, cs);
+ return *self();
+}
+#endif
+
inline QStringList operator+(const QList<QString> &one, const QStringList &other)
{
QStringList n = one;
diff --git a/src/corelib/tools/qstringmatcher.cpp b/src/corelib/tools/qstringmatcher.cpp
index 2e2ae18b9a..167a467480 100644
--- a/src/corelib/tools/qstringmatcher.cpp
+++ b/src/corelib/tools/qstringmatcher.cpp
@@ -149,7 +149,7 @@ static inline qsizetype bm_find(const ushort *uc, qsizetype l, qsizetype index,
Call setPattern() to give it a pattern to match.
*/
QStringMatcher::QStringMatcher()
- : d_ptr(0), q_cs(Qt::CaseSensitive)
+ : d_ptr(nullptr), q_cs(Qt::CaseSensitive)
{
memset(q_data, 0, sizeof(q_data));
}
@@ -161,7 +161,7 @@ QStringMatcher::QStringMatcher()
Call indexIn() to perform a search.
*/
QStringMatcher::QStringMatcher(const QString &pattern, Qt::CaseSensitivity cs)
- : d_ptr(0), q_pattern(pattern), q_cs(cs)
+ : d_ptr(nullptr), q_pattern(pattern), q_cs(cs)
{
p.uc = pattern.unicode();
p.len = pattern.size();
@@ -200,7 +200,7 @@ QStringMatcher::QStringMatcher(QStringView str, Qt::CaseSensitivity cs)
Copies the \a other string matcher to this string matcher.
*/
QStringMatcher::QStringMatcher(const QStringMatcher &other)
- : d_ptr(0)
+ : d_ptr(nullptr)
{
operator=(other);
}
diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp
index 050097b443..cc852dd042 100644
--- a/src/corelib/tools/qstringview.cpp
+++ b/src/corelib/tools/qstringview.cpp
@@ -530,6 +530,24 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn QString QStringView::arg(Args &&...args) const
+ \fn QString QLatin1String::arg(Args &&...args) const
+ \since 5.14
+
+ Replaces occurrences of \c{%N} in this string with the corresponding
+ argument from \a args. The arguments are not positional: the first of
+ the \a args replaces the \c{%N} with the lowest \c{N} (all of them), the
+ second of the \a args the \c{%N} with the next-lowest \c{N} etc.
+
+ \c Args can consist of anything that implicitly converts to QStringView
+ or QLatin1String.
+
+ In addition, the following types are also supported: QChar, QLatin1Char.
+
+ \sa QString::arg()
+*/
+
+/*!
\fn QChar QStringView::front() const
Returns the first character in the string. Same as first().
@@ -755,6 +773,24 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn qsizetype QStringView::lastIndexOf(QStringView str, qsizetype from, Qt::CaseSensitivity cs) const
+ \fn qsizetype QStringView::lastIndexOf(QLatin1String l1, qsizetype from, Qt::CaseSensitivity cs) const
+ \fn qsizetype QStringView::lastIndexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const
+ \since 5.14
+
+ Returns the index position of the last occurrence of the string-view \a str,
+ Latin-1 string \a l1, or character \a ch, respectively, in this string-view,
+ searching backward from index position \a from. If \a from is -1 (default),
+ the search starts at the last character; if \a from is -2, at the next to last
+ character and so on. Returns -1 if \a str is not found.
+
+ If \a cs is Qt::CaseSensitive (default), the search is case
+ sensitive; otherwise the search is case insensitive.
+
+ \sa QString::lastIndexOf()
+*/
+
+/*!
\fn QByteArray QStringView::toLatin1() const
Returns a Latin-1 representation of the string as a QByteArray.
diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h
index 2c93b31385..b84b2995b9 100644
--- a/src/corelib/tools/qstringview.h
+++ b/src/corelib/tools/qstringview.h
@@ -226,6 +226,9 @@ public:
// QString API
//
+ template <typename...Args>
+ Q_REQUIRED_RESULT inline QString arg(Args &&...args) const; // defined in qstring.h
+
Q_REQUIRED_RESULT QByteArray toLatin1() const { return QtPrivate::convertToLatin1(*this); }
Q_REQUIRED_RESULT QByteArray toUtf8() const { return QtPrivate::convertToUtf8(*this); }
Q_REQUIRED_RESULT QByteArray toLocal8Bit() const { return QtPrivate::convertToLocal8Bit(*this); }
@@ -282,6 +285,12 @@ public:
{ return indexOf(s, 0, cs) != qsizetype(-1); }
Q_REQUIRED_RESULT inline bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
+ Q_REQUIRED_RESULT qsizetype lastIndexOf(QChar c, qsizetype from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ { return QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs); }
+ Q_REQUIRED_RESULT qsizetype lastIndexOf(QStringView s, qsizetype from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ { return QtPrivate::lastIndexOf(*this, from, s, cs); }
+ Q_REQUIRED_RESULT inline qsizetype lastIndexOf(QLatin1String s, qsizetype from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
+
Q_REQUIRED_RESULT bool isRightToLeft() const noexcept
{ return QtPrivate::isRightToLeft(*this); }
diff --git a/src/corelib/tools/qunicodetools.cpp b/src/corelib/tools/qunicodetools.cpp
index d14118abf7..08e1146c59 100644
--- a/src/corelib/tools/qunicodetools.cpp
+++ b/src/corelib/tools/qunicodetools.cpp
@@ -327,7 +327,7 @@ static const uchar breakTable[BAfter + 1][QUnicodeTables::NumSentenceBreakClasse
// Any CR LF Sep Extend Sp Lower Upper OLetter Numeric ATerm SContinue STerm Close
{ Initial, BAfterC, BAfter , BAfter , Initial, Initial, Lower , Upper , Initial, Initial, ATerm , Initial, STerm , Initial }, // Initial
{ Initial, BAfterC, BAfter , BAfter , Lower , Initial, Initial, Initial, Initial, Initial, LUATerm, Initial, STerm , Initial }, // Lower
- { Initial, BAfterC, BAfter , BAfter , Upper , Initial, Initial, Upper , Initial, Initial, LUATerm, STerm , STerm , Initial }, // Upper
+ { Initial, BAfterC, BAfter , BAfter , Upper , Initial, Initial, Upper , Initial, Initial, LUATerm, Initial, STerm , Initial }, // Upper
{ Lookup , BAfterC, BAfter , BAfter , LUATerm, ACS , Initial, Upper , Break , Initial, ATerm , STerm , STerm , ATermC }, // LUATerm
{ Lookup , BAfterC, BAfter , BAfter , ATerm , ACS , Initial, Break , Break , Initial, ATerm , STerm , STerm , ATermC }, // ATerm
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 01fc63b677..ba65ae7ef2 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -44,6 +44,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qalgorithms.h>
#include <QtCore/qcontainertools_impl.h>
+#include <QtCore/qhashfunctions.h>
#include <algorithm>
#include <initializer_list>
@@ -60,7 +61,9 @@ template<class T, int Prealloc>
class QVarLengthArray
{
public:
- inline explicit QVarLengthArray(int size = 0);
+ QVarLengthArray() : QVarLengthArray(0) {}
+
+ inline explicit QVarLengthArray(int size);
inline QVarLengthArray(const QVarLengthArray<T, Prealloc> &other)
: a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array))
@@ -599,6 +602,13 @@ inline bool operator>=(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengt
return !(lhs < rhs);
}
+template <typename T, int Prealloc>
+uint qHash(const QVarLengthArray<T, Prealloc> &key, uint seed = 0)
+ noexcept(noexcept(qHashRange(key.cbegin(), key.cend(), seed)))
+{
+ return qHashRange(key.cbegin(), key.cend(), seed);
+}
+
QT_END_NAMESPACE
#endif // QVARLENGTHARRAY_H
diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc
index 80769e3769..e5ba47b8ef 100644
--- a/src/corelib/tools/qvarlengtharray.qdoc
+++ b/src/corelib/tools/qvarlengtharray.qdoc
@@ -903,3 +903,11 @@
\sa indexOf(), lastIndexOf()
*/
+/*!
+ template <typename T, int Prealloc> uint qHash(const QVarLengthArray<T, Prealloc> &key, uint seed = 0)
+ \relates QVarLengthArray
+ \since 5.14
+
+ Returns the hash value for \a key, using \a seed to seed the
+ calculation.
+*/
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 5d68a283bd..65a5174abf 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -80,6 +80,7 @@ public:
QVector<T> &operator=(std::initializer_list<T> args);
template <typename InputIterator, QtPrivate::IfIsInputIterator<InputIterator> = true>
inline QVector(InputIterator first, InputIterator last);
+ explicit QVector(QArrayDataPointerRef<T> ref) noexcept : d(ref.ptr) {}
bool operator==(const QVector<T> &v) const;
inline bool operator!=(const QVector<T> &v) const { return !(*this == v); }
diff --git a/src/corelib/tools/qvector.qdoc b/src/corelib/tools/qvector.qdoc
index c1b5054f93..8765b7fbd6 100644
--- a/src/corelib/tools/qvector.qdoc
+++ b/src/corelib/tools/qvector.qdoc
@@ -173,6 +173,24 @@
For a detailed discussion comparing Qt containers with each other and
with STL containers, see \l {Understand the Qt Containers}.
+ \section1 Maximum size and out-of-memory conditions
+
+ The current version of QVector is limited to just under 2 GB (2^31 bytes)
+ in size. The exact value is architecture-dependent, since it depends on the
+ overhead required for managing the data block, but is no more than 32
+ bytes. The number of elements that can be stored in a QVector is that size
+ divided by the size of each element.
+
+ In case memory allocation fails, QVector will use the \l Q_CHECK_PTR macro,
+ which will throw a \c std::bad_alloc exception if the application is being
+ compiled with exception support. If exceptions are disabled, then running
+ out of memory is undefined behavior.
+
+ Note that the operating system may impose further limits on applications
+ holding a lot of allocated memory, especially large, contiguous blocks.
+ Such considerations, the configuration of such behavior or any mitigation
+ are outside the scope of the Qt API.
+
\sa QVectorIterator, QMutableVectorIterator, QList, QLinkedList
*/
@@ -251,6 +269,11 @@
The value type of \c InputIterator must be convertible to \c T.
*/
+/*!
+ \fn template <typename T> QVector<T>::QVector(QArrayDataPointerRef<T> ref)
+ \internal
+*/
+
/*! \fn template <typename T> QVector<T>::~QVector()
Destroys the vector.