summaryrefslogtreecommitdiffstats
path: root/src/corelib/global
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global')
-rw-r--r--src/corelib/global/archdetect.cpp52
-rw-r--r--src/corelib/global/minimum-linux.S81
-rw-r--r--src/corelib/global/minimum-linux_p.h76
-rw-r--r--src/corelib/global/q20algorithm.h191
-rw-r--r--src/corelib/global/q20chrono.h62
-rw-r--r--src/corelib/global/q20functional.h46
-rw-r--r--src/corelib/global/q20iterator.h54
-rw-r--r--src/corelib/global/q20map.h72
-rw-r--r--src/corelib/global/q20memory.h93
-rw-r--r--src/corelib/global/q20type_traits.h81
-rw-r--r--src/corelib/global/q20vector.h90
-rw-r--r--src/corelib/global/q23functional.h49
-rw-r--r--src/corelib/global/q23utility.cpp25
-rw-r--r--src/corelib/global/q23utility.h75
-rw-r--r--src/corelib/global/qassert.cpp277
-rw-r--r--src/corelib/global/qassert.h116
-rw-r--r--src/corelib/global/qcompare.cpp1357
-rw-r--r--src/corelib/global/qcompare.h903
-rw-r--r--src/corelib/global/qcompare.qdoc137
-rw-r--r--src/corelib/global/qcompare_impl.h51
-rw-r--r--src/corelib/global/qcomparehelpers.h567
-rw-r--r--src/corelib/global/qcompilerdetection.h746
-rw-r--r--src/corelib/global/qcompilerdetection.qdoc427
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h63
-rw-r--r--src/corelib/global/qconfig.cpp.in21
-rw-r--r--src/corelib/global/qconstructormacros.h38
-rw-r--r--src/corelib/global/qcontainerinfo.h45
-rw-r--r--src/corelib/global/qdarwinhelpers.h37
-rw-r--r--src/corelib/global/qdarwinhelpers.qdoc34
-rw-r--r--src/corelib/global/qendian.cpp63
-rw-r--r--src/corelib/global/qendian.h81
-rw-r--r--src/corelib/global/qendian_p.h258
-rw-r--r--src/corelib/global/qexceptionhandling.cpp20
-rw-r--r--src/corelib/global/qexceptionhandling.h46
-rw-r--r--src/corelib/global/qflags.h91
-rw-r--r--src/corelib/global/qflags.qdoc459
-rw-r--r--src/corelib/global/qfloat16.cpp249
-rw-r--r--src/corelib/global/qfloat16.h358
-rw-r--r--src/corelib/global/qfloat16_f16c.c88
-rw-r--r--src/corelib/global/qfloat16tables.cpp44
-rw-r--r--src/corelib/global/qforeach.h84
-rw-r--r--src/corelib/global/qforeach.qdoc72
-rw-r--r--src/corelib/global/qfunctionpointer.h23
-rw-r--r--src/corelib/global/qfunctionpointer.qdoc9
-rw-r--r--src/corelib/global/qglobal.cpp4708
-rw-r--r--src/corelib/global/qglobal.h1457
-rw-r--r--src/corelib/global/qglobal_p.h77
-rw-r--r--src/corelib/global/qglobalstatic.h168
-rw-r--r--src/corelib/global/qglobalstatic.qdoc149
-rw-r--r--src/corelib/global/qhooks.cpp42
-rw-r--r--src/corelib/global/qhooks_p.h40
-rw-r--r--src/corelib/global/qlibraryinfo.cpp437
-rw-r--r--src/corelib/global/qlibraryinfo.h50
-rw-r--r--src/corelib/global/qlibraryinfo_p.h63
-rw-r--r--src/corelib/global/qlogging.cpp1161
-rw-r--r--src/corelib/global/qlogging.h88
-rw-r--r--src/corelib/global/qlogging_p.h42
-rw-r--r--src/corelib/global/qmalloc.cpp43
-rw-r--r--src/corelib/global/qmalloc.h26
-rw-r--r--src/corelib/global/qminmax.h88
-rw-r--r--src/corelib/global/qminmax.qdoc39
-rw-r--r--src/corelib/global/qnamespace.h85
-rw-r--r--src/corelib/global/qnamespace.qdoc214
-rw-r--r--src/corelib/global/qnativeinterface.h81
-rw-r--r--src/corelib/global/qnativeinterface_p.h63
-rw-r--r--src/corelib/global/qnumeric.cpp244
-rw-r--r--src/corelib/global/qnumeric.h145
-rw-r--r--src/corelib/global/qnumeric_p.h309
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp277
-rw-r--r--src/corelib/global/qoperatingsystemversion.h307
-rw-r--r--src/corelib/global/qoperatingsystemversion_darwin.mm91
-rw-r--r--src/corelib/global/qoperatingsystemversion_p.h41
-rw-r--r--src/corelib/global/qoperatingsystemversion_win.cpp72
-rw-r--r--src/corelib/global/qoperatingsystemversion_win_p.h42
-rw-r--r--src/corelib/global/qoverload.h80
-rw-r--r--src/corelib/global/qoverload.qdoc43
-rw-r--r--src/corelib/global/qprocessordetection.h97
-rw-r--r--src/corelib/global/qprocessordetection.qdoc448
-rw-r--r--src/corelib/global/qrandom.cpp72
-rw-r--r--src/corelib/global/qrandom.h54
-rw-r--r--src/corelib/global/qrandom_p.h40
-rw-r--r--src/corelib/global/qsimd.cpp220
-rw-r--r--src/corelib/global/qsimd.h62
-rw-r--r--src/corelib/global/qsimd_p.h348
-rw-r--r--src/corelib/global/qsimd_x86.cpp291
-rw-r--r--src/corelib/global/qsimd_x86_p.h616
-rw-r--r--src/corelib/global/qswap.h38
-rw-r--r--src/corelib/global/qswap.qdoc38
-rw-r--r--src/corelib/global/qsysinfo.cpp1070
-rw-r--r--src/corelib/global/qsysinfo.h50
-rw-r--r--src/corelib/global/qsystemdetection.h214
-rw-r--r--src/corelib/global/qsystemdetection.qdoc212
-rw-r--r--src/corelib/global/qt_pch.h89
-rw-r--r--src/corelib/global/qt_windows.h69
-rw-r--r--src/corelib/global/qtclasshelpermacros.h132
-rw-r--r--src/corelib/global/qtclasshelpermacros.qdoc59
-rw-r--r--src/corelib/global/qtconfiginclude.h22
-rw-r--r--src/corelib/global/qtconfigmacros.h189
-rw-r--r--src/corelib/global/qtdeprecationmarkers.h347
-rw-r--r--src/corelib/global/qtdeprecationmarkers.qdoc64
-rw-r--r--src/corelib/global/qtenvironmentvariables.cpp429
-rw-r--r--src/corelib/global/qtenvironmentvariables.h38
-rw-r--r--src/corelib/global/qtenvironmentvariables_p.h39
-rw-r--r--src/corelib/global/qtnoop.h20
-rw-r--r--src/corelib/global/qtpreprocessorsupport.h26
-rw-r--r--src/corelib/global/qtpreprocessorsupport.qdoc20
-rw-r--r--src/corelib/global/qtrace_p.h173
-rw-r--r--src/corelib/global/qtresource.h21
-rw-r--r--src/corelib/global/qtresource.qdoc54
-rw-r--r--src/corelib/global/qtsymbolmacros.h65
-rw-r--r--src/corelib/global/qttranslation.h44
-rw-r--r--src/corelib/global/qttranslation.qdoc206
-rw-r--r--src/corelib/global/qttypetraits.h65
-rw-r--r--src/corelib/global/qttypetraits.qdoc146
-rw-r--r--src/corelib/global/qtversion.h38
-rw-r--r--src/corelib/global/qtversionchecks.cpp46
-rw-r--r--src/corelib/global/qtversionchecks.h114
-rw-r--r--src/corelib/global/qtypeinfo.h157
-rw-r--r--src/corelib/global/qtypeinfo.qdoc55
-rw-r--r--src/corelib/global/qtypes.cpp528
-rw-r--r--src/corelib/global/qtypes.h283
-rw-r--r--src/corelib/global/qversiontagging.cpp78
-rw-r--r--src/corelib/global/qversiontagging.h184
-rw-r--r--src/corelib/global/qvolatile_p.h42
-rw-r--r--src/corelib/global/qxpfunctional.h195
-rw-r--r--src/corelib/global/qxptype_traits.h121
126 files changed, 16034 insertions, 10577 deletions
diff --git a/src/corelib/global/archdetect.cpp b/src/corelib/global/archdetect.cpp
index b758b2326c..6a1e110a73 100644
--- a/src/corelib/global/archdetect.cpp
+++ b/src/corelib/global/archdetect.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qprocessordetection.h"
@@ -51,14 +15,24 @@
# define ARCH_PROCESSOR "avr32"
#elif defined(Q_PROCESSOR_BLACKFIN)
# define ARCH_PROCESSOR "bfin"
+#elif defined(Q_PROCESSOR_WASM_64)
+# define ARCH_PROCESSOR "wasm64"
#elif defined(Q_PROCESSOR_WASM)
# define ARCH_PROCESSOR "wasm"
+#elif defined(Q_PROCESSOR_HPPA)
+# define ARCH_PROCESSOR "hppa"
#elif defined(Q_PROCESSOR_X86_32)
# define ARCH_PROCESSOR "i386"
#elif defined(Q_PROCESSOR_X86_64)
# define ARCH_PROCESSOR "x86_64"
#elif defined(Q_PROCESSOR_IA64)
# define ARCH_PROCESSOR "ia64"
+#elif defined(Q_PROCESSOR_LOONGARCH_32)
+# define ARCH_PROCESSOR "loongarch32"
+#elif defined(Q_PROCESSOR_LOONGARCH_64)
+# define ARCH_PROCESSOR "loongarch64"
+#elif defined(Q_PROCESSOR_M68K)
+# define ARCH_PROCESSOR "m68k"
#elif defined(Q_PROCESSOR_MIPS_64)
# define ARCH_PROCESSOR "mips64"
#elif defined(Q_PROCESSOR_MIPS)
diff --git a/src/corelib/global/minimum-linux.S b/src/corelib/global/minimum-linux.S
deleted file mode 100644
index e324379efc..0000000000
--- a/src/corelib/global/minimum-linux.S
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "minimum-linux_p.h"
-
-/* Copied from #include <elf.h>:
- */
-#define ELF_NOTE_GNU "GNU"
-#define NT_GNU_ABI_TAG 1
-#define ELF_NOTE_OS_LINUX 0
-
-#ifdef __arm__
-# define progbits %progbits
-# define note %note
-#else
-# define progbits @progbits
-# define note @note
-#endif
-
-/* Add information for the ELF dynamic linker what the minimum Linux version
- * required for Qt is.
- *
- * The .note.ABI-tag note section is defined at
- * https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/noteabitag.html
- */
-
- .section ".note.GNU-stack", "", progbits
- .section ".note.ABI-tag", "a", note
- .balign 4 /* we have 32-bit data */
-
-/* * For the format of the note section's contents, see Elf32_Nhdr / Elf64_Nhdr */
- .long .Lnameend-.Lname /* n_namesz */
- .long 16 /* n_descsz(16 bytes, normative) */
- .long NT_GNU_ABI_TAG /* n_type */
-
-.Lname:
- .asciz ELF_NOTE_GNU
-.Lnameend:
-
-/* Operating systems: */
- .long ELF_NOTE_OS_LINUX
-
- .long MINLINUX_MAJOR
- .long MINLINUX_MINOR
- .long MINLINUX_PATCH
diff --git a/src/corelib/global/minimum-linux_p.h b/src/corelib/global/minimum-linux_p.h
index 5112015663..d52df474fb 100644
--- a/src/corelib/global/minimum-linux_p.h
+++ b/src/corelib/global/minimum-linux_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef MINIMUMLINUX_P_H
#define MINIMUMLINUX_P_H
@@ -58,6 +22,7 @@
//
#include "private/qglobal_p.h"
+#include <sys/stat.h>
QT_BEGIN_NAMESPACE
@@ -71,36 +36,37 @@ QT_BEGIN_NAMESPACE
* - FUTEX_PRIVATE_FLAG 2.6.22
* - O_CLOEXEC 2.6.23
* - eventfd 2.6.23
+ * - FUTEX_WAIT_BITSET 2.6.25
* - pipe2 & dup3 2.6.27
* - accept4 2.6.28
* - renameat2 3.16 QT_CONFIG(renameat2)
* - getrandom 3.17 QT_CONFIG(getentropy)
- * - statx 4.11 QT_CONFIG(statx)
+ * - statx 4.11 STATX_BASIC_STATS
*/
-#if QT_CONFIG(statx) && !QT_CONFIG(glibc)
+#if defined(__GLIBC__) && defined(STATX_BASIC_STATS)
// if using glibc, the statx() function in sysdeps/unix/sysv/linux/statx.c
// falls back to stat() for us.
-// (Using QT_CONFIG(glibc) instead of __GLIBC__ because the macros aren't
-// defined in assembler mode)
-# define MINLINUX_MAJOR 4
-# define MINLINUX_MINOR 11
-# define MINLINUX_PATCH 0
+# define QT_ELF_NOTE_OS_MAJOR 4
+# define QT_ELF_NOTE_OS_MINOR 11
+# define QT_ELF_NOTE_OS_PATCH 0
#elif QT_CONFIG(getentropy)
-# define MINLINUX_MAJOR 3
-# define MINLINUX_MINOR 17
-# define MINLINUX_PATCH 0
+# define QT_ELF_NOTE_OS_MAJOR 3
+# define QT_ELF_NOTE_OS_MINOR 17
+# define QT_ELF_NOTE_OS_PATCH 0
#elif QT_CONFIG(renameat2)
-# define MINLINUX_MAJOR 3
-# define MINLINUX_MINOR 16
-# define MINLINUX_PATCH 0
+# define QT_ELF_NOTE_OS_MAJOR 3
+# define QT_ELF_NOTE_OS_MINOR 16
+# define QT_ELF_NOTE_OS_PATCH 0
#else
-# define MINLINUX_MAJOR 2
-# define MINLINUX_MINOR 6
-# define MINLINUX_PATCH 28
+
+# define QT_ELF_NOTE_OS_MAJOR 2
+# define QT_ELF_NOTE_OS_MINOR 6
+# define QT_ELF_NOTE_OS_PATCH 28
#endif
-#define MINIMUM_LINUX_VERSION QT_VERSION_CHECK(MINLINUX_MAJOR, MINLINUX_MINOR, MINLINUX_PATCH)
+/* you must include <elf.h> */
+#define QT_ELF_NOTE_OS_TYPE ELF_NOTE_OS_LINUX
QT_END_NAMESPACE
diff --git a/src/corelib/global/q20algorithm.h b/src/corelib/global/q20algorithm.h
new file mode 100644
index 0000000000..24d801b2cd
--- /dev/null
+++ b/src/corelib/global/q20algorithm.h
@@ -0,0 +1,191 @@
+// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef Q20ALGORITHM_H
+#define Q20ALGORITHM_H
+
+#include <QtCore/qglobal.h>
+
+#include <algorithm>
+#include <QtCore/q20functional.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+namespace q20 {
+// like std::<algorithm> (ie. not ranged, but constexpr)
+#ifdef __cpp_lib_constexpr_algorithms
+using std::copy;
+using std::copy_if;
+using std::copy_n;
+using std::fill;
+using std::fill_n;
+using std::is_sorted_until;
+using std::is_sorted;
+using std::transform;
+#else
+template <typename InputIterator, typename OutputIterator>
+constexpr OutputIterator
+copy(InputIterator first, InputIterator last, OutputIterator dest)
+{
+ while (first != last) {
+ *dest = *first;
+ ++first;
+ ++dest;
+ }
+ return dest;
+}
+
+template <typename InputIterator, typename OutputIterator, typename UnaryPredicate>
+constexpr OutputIterator
+copy_if(InputIterator first, InputIterator last, OutputIterator dest, UnaryPredicate pred)
+{
+ while (first != last) {
+ if (pred(*first)) {
+ *dest = *first;
+ ++dest;
+ }
+ ++first;
+ }
+ return dest;
+}
+
+template <typename InputIterator, typename Size, typename OutputIterator>
+constexpr OutputIterator
+copy_n(InputIterator first, Size n, OutputIterator dest)
+{
+ while (n > Size{0}) {
+ *dest = *first;
+ ++first;
+ ++dest;
+ --n;
+ }
+ return dest;
+}
+
+template <typename ForwardIterator, typename Value>
+constexpr void
+fill(ForwardIterator first, ForwardIterator last, const Value &value)
+{
+ while (first != last) {
+ *first = value;
+ ++first;
+ }
+}
+
+template <typename OutputIterator, typename Size, typename Value>
+constexpr OutputIterator
+fill_n(OutputIterator first, Size n, const Value &value)
+{
+ while (n > Size{0}) {
+ *first = value;
+ ++first;
+ --n;
+ }
+ return first;
+}
+
+template <typename ForwardIterator, typename BinaryPredicate = std::less<>>
+constexpr ForwardIterator
+is_sorted_until(ForwardIterator first, ForwardIterator last, BinaryPredicate p = {})
+{
+ if (first == last)
+ return first;
+ auto prev = first;
+ while (++first != last) {
+ if (p(*first, *prev))
+ return first;
+ prev = first;
+ }
+ return first;
+}
+
+template <typename ForwardIterator, typename BinaryPredicate = std::less<>>
+constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, BinaryPredicate p = {})
+{
+ return q20::is_sorted_until(first, last, p) == last;
+}
+
+template <typename InputIterator, typename OutputIterator, typename UnaryFunction>
+constexpr OutputIterator
+transform(InputIterator first, InputIterator last, OutputIterator dest, UnaryFunction op)
+{
+ while (first != last) {
+ *dest = op(*first);
+ ++first;
+ ++dest;
+ }
+ return dest;
+}
+
+// binary transform missing on purpose (no users)
+
+#endif
+}
+
+namespace q20::ranges {
+// like std::ranges::{any,all,none}_of, just unconstrained, so no range-overload
+#ifdef __cpp_lib_ranges
+using std::ranges::any_of;
+using std::ranges::all_of;
+using std::ranges::none_of;
+#else
+[[maybe_unused]] inline constexpr struct { // Niebloid
+ template <typename InputIterator, typename Sentinel,
+ typename Predicate, typename Projection = q20::identity>
+ [[maybe_unused]] constexpr bool operator()(InputIterator first, Sentinel last, Predicate pred, Projection proj = {}) const
+ {
+ while (first != last) {
+ if (std::invoke(pred, std::invoke(proj, *first)))
+ return true;
+ ++first;
+ }
+ return false;
+ }
+} any_of;
+[[maybe_unused]] inline constexpr struct { // Niebloid
+ template <typename InputIterator, typename Sentinel,
+ typename Predicate, typename Projection = q20::identity>
+ [[maybe_unused]] constexpr bool operator()(InputIterator first, Sentinel last, Predicate pred, Projection proj = {}) const
+ {
+ while (first != last) {
+ if (!std::invoke(pred, std::invoke(proj, *first)))
+ return false;
+ ++first;
+ }
+ return true;
+ }
+} all_of;
+[[maybe_unused]] inline constexpr struct { // Niebloid
+ template <typename InputIterator, typename Sentinel,
+ typename Predicate, typename Projection = q20::identity>
+ [[maybe_unused]] constexpr bool operator()(InputIterator first, Sentinel last, Predicate pred, Projection proj = {}) const
+ {
+ while (first != last) {
+ if (std::invoke(pred, std::invoke(proj, *first)))
+ return false;
+ ++first;
+ }
+ return true;
+ }
+} none_of;
+#endif // __cpp_lib_ranges
+} // namespace q20::ranges
+
+QT_END_NAMESPACE
+
+#endif /* Q20ALGORITHM_H */
diff --git a/src/corelib/global/q20chrono.h b/src/corelib/global/q20chrono.h
new file mode 100644
index 0000000000..19c2eabe3d
--- /dev/null
+++ b/src/corelib/global/q20chrono.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2023 Ahmad Samir <a.samirh78@gmail.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef Q20CHRONO_H
+#define Q20CHRONO_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#include <chrono>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+namespace q20 {
+namespace chrono {
+
+#if defined(__GLIBCXX__)
+// https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/include/bits/chrono.h
+using IntRep = int64_t;
+#else
+// https://github.com/llvm/llvm-project/blob/main/libcxx/include/__chrono/duration.h
+// https://github.com/microsoft/STL/blob/main/stl/inc/__msvc_chrono.hpp
+using IntRep = int;
+#endif
+
+#if __cpp_lib_chrono >= 201907L
+using std::chrono::days;
+using std::chrono::weeks;
+using std::chrono::years;
+using std::chrono::months;
+
+static_assert(std::is_same_v<days::rep, IntRep>);
+static_assert(std::is_same_v<weeks::rep, IntRep>);
+static_assert(std::is_same_v<years::rep, IntRep>);
+static_assert(std::is_same_v<months::rep, IntRep>);
+#else
+using days = std::chrono::duration<IntRep, std::ratio<86400>>;
+using weeks = std::chrono::duration<IntRep, std::ratio_multiply<std::ratio<7>, days::period>>;
+using years = std::chrono::duration<IntRep, std::ratio_multiply<std::ratio<146097, 400>, days::period>>;
+using months = std::chrono::duration<IntRep, std::ratio_divide<years::period, std::ratio<12>>>;
+#endif // __cpp_lib_chrono >= 201907L
+} // namespace chrono
+} // namespace q20
+
+QT_END_NAMESPACE
+
+#endif /* Q20CHRONO_H */
diff --git a/src/corelib/global/q20functional.h b/src/corelib/global/q20functional.h
new file mode 100644
index 0000000000..a39b4fceb3
--- /dev/null
+++ b/src/corelib/global/q20functional.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef Q20FUNCTIONAL_H
+#define Q20FUNCTIONAL_H
+
+#include <QtCore/qglobal.h>
+
+#include <functional>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+namespace q20 {
+// like std::identity
+#ifdef __cpp_lib_ranges
+using std::identity;
+#else
+struct identity
+{
+ struct is_transparent {};
+ template <typename T>
+ constexpr T &&operator()(T&& t) const noexcept { return std::forward<T>(t); }
+};
+#endif // __cpp_lib_ranges
+} // namespace q20
+
+QT_END_NAMESPACE
+
+#endif /* Q20FUNCTIONAL_H */
diff --git a/src/corelib/global/q20iterator.h b/src/corelib/global/q20iterator.h
new file mode 100644
index 0000000000..9ed4d69965
--- /dev/null
+++ b/src/corelib/global/q20iterator.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef Q20ITERATOR_H
+#define Q20ITERATOR_H
+
+#include <QtCore/qglobal.h>
+
+#include <iterator>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+// like std::ssize
+namespace q20 {
+#ifdef __cpp_lib_ssize
+ using std::ssize;
+#else
+ template<class C> constexpr auto ssize(const C &c)
+ -> std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(c.size())>>
+ { return static_cast<std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(c.size())>>>(c.size()); }
+
+ template<class T, std::ptrdiff_t N> constexpr std::ptrdiff_t ssize(const T (&)[N]) noexcept
+ { return N; }
+#endif
+} // namespace q20
+
+// like q20::iter_reference_t
+namespace q20 {
+#ifdef __cpp_lib_ranges
+ using std::iter_reference_t;
+#else
+ template <typename Dereferencable> // unconstrained (constraint requires concepts)
+ using iter_reference_t = decltype(*std::declval<Dereferencable&>());
+#endif // __cpp_lib_ranges
+} // namespace q20
+
+QT_END_NAMESPACE
+
+#endif /* Q20ITERATOR_H */
diff --git a/src/corelib/global/q20map.h b/src/corelib/global/q20map.h
new file mode 100644
index 0000000000..c719067480
--- /dev/null
+++ b/src/corelib/global/q20map.h
@@ -0,0 +1,72 @@
+// Copyright (C) 2023 Ahmad Samir <a.samirh78@gmail.com>
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef Q20MAP_H
+#define Q20MAP_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#include <map>
+#if __has_include(<memory_resource>)
+# include <memory_resource>
+#endif
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+namespace q20 {
+// like std::erase/std::erase_if for std::map
+#if defined(__cpp_lib_erase_if) && __cpp_lib_erase_if >= 202002L // the one returning size_type
+using std::erase_if;
+#else
+
+// Make it more specialized than the compiler's, so that our implementation is preferred over
+// the compiler's (which may be present, but return void instead of the number of erased elements).
+
+#define MAKE_OVERLOAD(map, allocator) \
+ template <typename Key, typename T, typename Compare, typename Pred> \
+ constexpr typename std::map<Key, T, Compare, std::allocator<std::pair<const Key, T>>>::size_type \
+ erase_if(std::map<Key, T, Compare, std::allocator<std::pair<const Key, T>>> &c, Pred p) \
+ { \
+ const auto origSize = c.size(); \
+ for (auto it = c.begin(), end = c.end(); it != end; /* erasing */) { \
+ if (p(*it)) \
+ it = c.erase(it); \
+ else \
+ ++it; \
+ } \
+ return origSize - c.size(); \
+ } \
+ /* end */
+
+MAKE_OVERLOAD(map, allocator)
+MAKE_OVERLOAD(multimap, allocator)
+#ifdef __cpp_lib_polymorphic_allocator
+MAKE_OVERLOAD(map, pmr::polymorphic_allocator)
+MAKE_OVERLOAD(multimap, pmr::polymorphic_allocator)
+#endif // __cpp_lib_polymorphic_allocator
+
+#undef MAKE_OVERLOAD
+
+#endif // __cpp_lib_erase_if
+} // namespace q20
+
+QT_END_NAMESPACE
+
+#endif /* Q20MAP_H */
diff --git a/src/corelib/global/q20memory.h b/src/corelib/global/q20memory.h
new file mode 100644
index 0000000000..008f4ddeb2
--- /dev/null
+++ b/src/corelib/global/q20memory.h
@@ -0,0 +1,93 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef Q20MEMORY_H
+#define Q20MEMORY_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#include <memory>
+
+#include <type_traits>
+#include <utility>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+// like std::construct_at (but not whitelisted for constexpr)
+namespace q20 {
+#ifdef __cpp_lib_constexpr_dynamic_alloc
+using std::construct_at;
+#else
+template <typename T,
+ typename... Args,
+ typename Enable = std::void_t<decltype(::new (std::declval<void *>()) T(std::declval<Args>()...))> >
+T *construct_at(T *ptr, Args && ... args)
+{
+ return ::new (const_cast<void *>(static_cast<const volatile void *>(ptr)))
+ T(std::forward<Args>(args)...);
+}
+#endif // __cpp_lib_constexpr_dynamic_alloc
+} // namespace q20
+
+
+namespace q20 {
+// like std::to_address
+#ifdef __cpp_lib_to_address
+using std::to_address;
+#else
+// http://eel.is/c++draft/pointer.conversion
+template <typename T>
+constexpr T *to_address(T *p) noexcept {
+ // http://eel.is/c++draft/pointer.conversion#1:
+ // Mandates: T is not a function type.
+ static_assert(!std::is_function_v<T>, "to_address must not be used on function types");
+ return p;
+}
+
+template <typename Ptr, typename std::enable_if_t<!std::is_pointer_v<Ptr>, bool> = true>
+constexpr auto to_address(const Ptr &ptr) noexcept; // fwd declared
+
+namespace detail {
+ // http://eel.is/c++draft/pointer.conversion#3
+ template <typename Ptr, typename = void>
+ struct to_address_helper {
+ static auto get(const Ptr &ptr) noexcept
+ { return q20::to_address(ptr.operator->()); }
+ };
+ template <typename Ptr>
+ struct to_address_helper<Ptr, std::void_t<
+ decltype(std::pointer_traits<Ptr>::to_address(std::declval<const Ptr&>()))
+ >>
+ {
+ static auto get(const Ptr &ptr) noexcept
+ { return std::pointer_traits<Ptr>::to_address(ptr); }
+ };
+} // namespace detail
+
+template <typename Ptr, typename std::enable_if_t<!std::is_pointer_v<Ptr>, bool>>
+constexpr auto to_address(const Ptr &ptr) noexcept
+{ return detail::to_address_helper<Ptr>::get(ptr); }
+
+#endif // __cpp_lib_to_address
+} // namespace q20
+
+QT_END_NAMESPACE
+
+#endif /* Q20MEMORY_H */
diff --git a/src/corelib/global/q20type_traits.h b/src/corelib/global/q20type_traits.h
new file mode 100644
index 0000000000..63a453daca
--- /dev/null
+++ b/src/corelib/global/q20type_traits.h
@@ -0,0 +1,81 @@
+// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef Q20TYPE_TRAITS_H
+#define Q20TYPE_TRAITS_H
+
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qsystemdetection.h>
+#include <QtCore/qtconfigmacros.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+#include <type_traits>
+
+QT_BEGIN_NAMESPACE
+
+namespace q20 {
+// like std::is_constant_evaluated
+#ifdef __cpp_lib_is_constant_evaluated
+using std::is_constant_evaluated;
+#define QT_SUPPORTS_IS_CONSTANT_EVALUATED
+#else
+constexpr bool is_constant_evaluated() noexcept
+{
+#ifdef Q_OS_INTEGRITY
+ // Integrity complains "calling __has_builtin() from a constant expression".
+ // Avoid the __has_builtin check until we know what's going on.
+ return false;
+#elif __has_builtin(__builtin_is_constant_evaluated) || \
+ (defined(Q_CC_MSVC_ONLY) /* >= 1925, but we require 1927 in qglobal.h */)
+# define QT_SUPPORTS_IS_CONSTANT_EVALUATED
+ return __builtin_is_constant_evaluated();
+#else
+ return false;
+#endif
+}
+#endif // __cpp_lib_is_constant_evaluated
+}
+
+namespace q20 {
+// like std::remove_cvref(_t)
+#ifdef __cpp_lib_remove_cvref
+using std::remove_cvref;
+using std::remove_cvref_t;
+#else
+template <typename T>
+using remove_cvref = std::remove_cv<std::remove_reference_t<T>>;
+template <typename T>
+using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
+#endif // __cpp_lib_remove_cvref
+}
+
+namespace q20 {
+// like std::type_identity(_t)
+#ifdef __cpp_lib_type_identity
+using std::type_identity;
+using std::type_identity_t;
+#else
+template <typename T>
+struct type_identity { using type = T; };
+template <typename T>
+using type_identity_t = typename type_identity<T>::type;
+#endif // __cpp_lib_type_identity
+}
+
+QT_END_NAMESPACE
+
+#endif /* Q20TYPE_TRAITS_H */
diff --git a/src/corelib/global/q20vector.h b/src/corelib/global/q20vector.h
new file mode 100644
index 0000000000..9d312355ea
--- /dev/null
+++ b/src/corelib/global/q20vector.h
@@ -0,0 +1,90 @@
+// Copyright (C) 2023 Ahmad Samir <a.samirh78@gmail.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef Q20VECTOR_H
+#define Q20VECTOR_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#include <algorithm>
+#include <vector>
+#if __has_include(<memory_resource>)
+# include <memory_resource>
+#endif
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+namespace q20 {
+// like std::erase/std::erase_if for std::vector
+#if defined(__cpp_lib_erase_if) && __cpp_lib_erase_if >= 202002L // the one returning size_type
+using std::erase;
+using std::erase_if;
+#else
+
+// Make it more specialized than the compiler's, so that our implementation is preferred over
+// the compiler's (which may be present, but return void instead of the number of erased elements).
+
+template <typename T, typename U>
+constexpr typename std::vector<T, std::allocator<T>>::size_type
+erase(std::vector<T, std::allocator<T>> &c, const U &value)
+{
+ const auto origSize = c.size();
+ auto it = std::remove(c.begin(), c.end(), value);
+ c.erase(it, c.end());
+ return origSize - c.size();
+}
+
+template <typename T, typename Pred>
+constexpr typename std::vector<T, std::allocator<T>>::size_type
+erase_if(std::vector<T, std::allocator<T>> &c, Pred pred)
+{
+ const auto origSize = c.size();
+ auto it = std::remove_if(c.begin(), c.end(), pred);
+ c.erase(it, c.end());
+ return origSize - c.size();
+}
+
+#ifdef __cpp_lib_polymorphic_allocator
+template <typename T, typename U>
+constexpr typename std::vector<T, std::pmr::polymorphic_allocator<T>>::size_type
+erase(std::vector<T, std::pmr::polymorphic_allocator<T>> &c, const U &value)
+{
+ const auto origSize = c.size();
+ auto it = std::remove(c.begin(), c.end(), value);
+ c.erase(it, c.end());
+ return origSize - c.size();
+}
+
+template <typename T, typename Pred>
+constexpr typename std::vector<T, std::pmr::polymorphic_allocator<T>>::size_type
+erase_if(std::vector<T, std::pmr::polymorphic_allocator<T>> &c, Pred pred)
+{
+ const auto origSize = c.size();
+ auto it = std::remove_if(c.begin(), c.end(), pred);
+ c.erase(it, c.end());
+ return origSize - c.size();
+}
+#endif // __cpp_lib_polymorphic_allocator
+
+#endif // __cpp_lib_erase_if
+} // namespace q20
+
+QT_END_NAMESPACE
+
+#endif /* Q20VECTOR_H */
diff --git a/src/corelib/global/q23functional.h b/src/corelib/global/q23functional.h
new file mode 100644
index 0000000000..ae8f78a3d0
--- /dev/null
+++ b/src/corelib/global/q23functional.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef Q23FUNCTIONAL_H
+#define Q23FUNCTIONAL_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/q20functional.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+namespace q23 {
+// like std::invoke_r
+#ifdef __cpp_lib_invoke_r
+using std::invoke_r;
+#else
+template <typename R, typename F, typename...Args>
+constexpr
+std::enable_if_t<std::is_invocable_r_v<R, F, Args...>, R>
+invoke_r(F&& f, Args&&... args)
+ noexcept(std::is_nothrow_invocable_r_v<R, F, Args...>)
+{
+ // ### use q20::invoke for a constexpr std::invoke
+ if constexpr (std::is_void_v<R>)
+ std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
+ else
+ return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
+}
+#endif // __cpp_lib_invoke_r
+} // namespace q23
+
+QT_END_NAMESPACE
+
+#endif /* Q23FUNCTIONAL_H */
diff --git a/src/corelib/global/q23utility.cpp b/src/corelib/global/q23utility.cpp
new file mode 100644
index 0000000000..9c5365c547
--- /dev/null
+++ b/src/corelib/global/q23utility.cpp
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtCore/q23utility.h>
+
+QT_BEGIN_NAMESPACE
+
+#define CHECK2(cvref_in, cvref_out) \
+ static_assert(std::is_same_v< \
+ decltype(q23::forward_like<int cvref_in >(std::declval<long&>())), \
+ long cvref_out \
+ >, "oops: cvref '" #cvref_in "' doesn't work") \
+ /* end */
+#define CHECK(cvref) CHECK2(cvref, cvref)
+CHECK2(/**/, &&);
+CHECK(&);
+CHECK(&&);
+CHECK2(const, const &&);
+CHECK(const &);
+CHECK(const &&);
+// volatile is not supported
+#undef CHECK
+#undef CHECK2
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/q23utility.h b/src/corelib/global/q23utility.h
new file mode 100644
index 0000000000..9ae5389b56
--- /dev/null
+++ b/src/corelib/global/q23utility.h
@@ -0,0 +1,75 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef Q23UTILITY_H
+#define Q23UTILITY_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#include <utility>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+namespace q23 {
+// like std::forward_like
+#ifdef __cpp_lib_forward_like
+using std::forward_like;
+#else
+
+namespace _detail {
+
+// [forward]/6.1 COPY_CONST
+template <typename A, typename B>
+using copy_const_t = std::conditional_t<
+ std::is_const_v<A>, const B,
+ /* else */ B
+ >;
+
+// [forward]/6.2 OVERRIDE_REF
+template <typename A, typename B>
+using override_ref_t = std::conditional_t<
+ std::is_rvalue_reference_v<A>, std::remove_reference_t<B>&&,
+ /* else */ B&
+ >;
+
+// [forward]/6.3 "V"
+template <typename T, typename U>
+using forward_like_ret_t = override_ref_t<
+ T&&,
+ copy_const_t<
+ std::remove_reference_t<T>,
+ std::remove_reference_t<U>
+ >
+ >;
+
+} // namespace detail
+
+// http://eel.is/c++draft/forward#lib:forward_like
+template <class T, class U>
+[[nodiscard]] constexpr auto forward_like(U &&x) noexcept
+ -> _detail::forward_like_ret_t<T, U>
+{
+ using V = _detail::forward_like_ret_t<T, U>;
+ return static_cast<V>(x);
+}
+#endif // __cpp_lib_forward_like
+} // namespace q23
+
+QT_END_NAMESPACE
+
+#endif /* Q23UTILITY_H */
diff --git a/src/corelib/global/qassert.cpp b/src/corelib/global/qassert.cpp
new file mode 100644
index 0000000000..6a29cbfa21
--- /dev/null
+++ b/src/corelib/global/qassert.cpp
@@ -0,0 +1,277 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qassert.h"
+
+#include <QtCore/qlogging.h>
+
+#include <cstdlib>
+#include <cstdio>
+#include <exception>
+#ifndef QT_NO_EXCEPTIONS
+#include <new>
+#endif
+
+#if defined(Q_CC_MSVC)
+# include <crtdbg.h>
+#endif
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+void qAbort()
+{
+#ifdef Q_OS_WIN
+ // std::abort() in the MSVC runtime will call _exit(3) if the abort
+ // behavior is _WRITE_ABORT_MSG - see also _set_abort_behavior(). This is
+ // the default for a debug-mode build of the runtime. Worse, MinGW's
+ // std::abort() implementation (in msvcrt.dll) is basically a call to
+ // _exit(3) too. Unfortunately, _exit() and _Exit() *do* run the static
+ // destructors of objects in DLLs, a violation of the C++ standard (see
+ // [support.start.term]). So we bypass std::abort() and directly
+ // terminate the application.
+
+# if defined(Q_CC_MSVC)
+ if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE))
+ __fastfail(FAST_FAIL_FATAL_APP_EXIT);
+# else
+ RaiseFailFastException(nullptr, nullptr, 0);
+# endif
+
+ // Fallback
+ TerminateProcess(GetCurrentProcess(), STATUS_FATAL_APP_EXIT);
+
+ // Tell the compiler the application has stopped.
+ Q_UNREACHABLE_IMPL();
+#else // !Q_OS_WIN
+ std::abort();
+#endif
+}
+
+/*!
+ \macro void Q_ASSERT(bool test)
+ \relates <QtAssert>
+
+ Prints a warning message containing the source code file name and
+ line number if \a test is \c false.
+
+ Q_ASSERT() is useful for testing pre- and post-conditions
+ during development. It does nothing if \c QT_NO_DEBUG was defined
+ during compilation.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 17
+
+ If \c b is zero, the Q_ASSERT statement will output the following
+ message using the qFatal() function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 18
+
+ \sa Q_ASSERT_X(), qFatal(), {Debugging Techniques}
+*/
+
+/*!
+ \macro void Q_ASSERT_X(bool test, const char *where, const char *what)
+ \relates <QtAssert>
+
+ Prints the message \a what together with the location \a where,
+ the source file name and line number if \a test is \c false.
+
+ Q_ASSERT_X is useful for testing pre- and post-conditions during
+ development. It does nothing if \c QT_NO_DEBUG was defined during
+ compilation.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 19
+
+ If \c b is zero, the Q_ASSERT_X statement will output the following
+ message using the qFatal() function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 20
+
+ \sa Q_ASSERT(), qFatal(), {Debugging Techniques}
+*/
+
+/*
+ The Q_ASSERT macro calls this function when the test fails.
+*/
+void qt_assert(const char *assertion, const char *file, int line) noexcept
+{
+ QMessageLogger(file, line, nullptr)
+ .fatal("ASSERT: \"%s\" in file %s, line %d", assertion, file, line);
+}
+
+/*
+ The Q_ASSERT_X macro calls this function when the test fails.
+*/
+void qt_assert_x(const char *where, const char *what, const char *file, int line) noexcept
+{
+ QMessageLogger(file, line, nullptr)
+ .fatal("ASSERT failure in %s: \"%s\", file %s, line %d", where, what, file, line);
+}
+
+/*!
+ \macro void Q_CHECK_PTR(void *pointer)
+ \relates <QtAssert>
+
+ If \a pointer is \nullptr, prints a message containing the source
+ code's file name and line number, saying that the program ran out
+ of memory and aborts program execution. It throws \c std::bad_alloc instead
+ if exceptions are enabled.
+
+ Q_CHECK_PTR does nothing if \c QT_NO_DEBUG and \c QT_NO_EXCEPTIONS were
+ defined during compilation. Therefore you must not use Q_CHECK_PTR to check
+ for successful memory allocations because the check will be disabled in
+ some cases.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 21
+
+ \sa qWarning(), {Debugging Techniques}
+*/
+
+/*!
+ \fn template <typename T> T *q_check_ptr(T *p)
+ \relates <QtAssert>
+
+ Uses Q_CHECK_PTR on \a p, then returns \a p.
+
+ This can be used as an inline version of Q_CHECK_PTR.
+*/
+
+/*!
+ \internal
+ The Q_CHECK_PTR macro calls this function if an allocation check
+ fails.
+*/
+void qt_check_pointer(const char *n, int l) noexcept
+{
+ // make separate printing calls so that the first one may flush;
+ // the second one could want to allocate memory (fputs prints a
+ // newline and stderr auto-flushes).
+ fputs("Out of memory", stderr);
+ fprintf(stderr, " in %s, line %d\n", n, l);
+
+ std::terminate();
+}
+
+/*
+ \internal
+ Allows you to throw an exception without including <new>
+ Called internally from Q_CHECK_PTR on certain OS combinations
+*/
+void qBadAlloc()
+{
+#ifndef QT_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ std::terminate();
+#endif
+}
+
+/*!
+ \macro void Q_ASSUME(bool expr)
+ \deprecated
+ \relates <QtAssert>
+ \since 5.0
+
+ Causes the compiler to assume that \a expr is \c true.
+
+ This macro is known to produce worse code than when no assumption was
+ inserted in the code, with some compiler versions. The arguments passed to
+ it are always evaluated, even in release mode, with some compilers and not
+ others, so application code needs to be aware of those possible differences
+ in behavior.
+
+ Do not use it in new code. It is retained as-is for compatibility with old
+ code and will likely be removed in the next major version Qt.
+
+ \sa Q_ASSERT(), Q_UNREACHABLE(), Q_LIKELY()
+*/
+
+/*!
+ \macro QT_TERMINATE_ON_EXCEPTION(expr)
+ \relates <QtGlobal>
+ \internal
+
+ In general, use of the Q_DECL_NOEXCEPT macro is preferred over
+ Q_DECL_NOTHROW, because it exhibits well-defined behavior and
+ supports the more powerful Q_DECL_NOEXCEPT_EXPR variant. However,
+ use of Q_DECL_NOTHROW has the advantage that Windows builds
+ benefit on a wide range or compiler versions that do not yet
+ support the C++11 noexcept feature.
+
+ It may therefore be beneficial to use Q_DECL_NOTHROW and emulate
+ the C++11 behavior manually with an embedded try/catch.
+
+ Qt provides the QT_TERMINATE_ON_EXCEPTION(expr) macro for this
+ purpose. It either expands to \c expr (if Qt is compiled without
+ exception support or the compiler supports C++11 noexcept
+ semantics) or to
+ \snippet code/src_corelib_global_qglobal.cpp qterminate
+ otherwise.
+
+ Since this macro expands to just \c expr if the compiler supports
+ C++11 noexcept, expecting the compiler to take over responsibility
+ of calling std::terminate() in that case, it should not be used
+ outside Q_DECL_NOTHROW functions.
+
+ \sa Q_DECL_NOEXCEPT, Q_DECL_NOTHROW, qTerminate()
+*/
+
+/*!
+ \macro void Q_UNREACHABLE()
+ \relates <QtAssert>
+ \since 5.0
+
+ Tells the compiler that the current point cannot be reached by any
+ execution, so it may optimize any code paths leading here as dead code, as
+ well as code continuing from here.
+
+ This macro is useful to mark impossible conditions. For example, given the
+ following enum:
+
+ \snippet code/src_corelib_global_qglobal.cpp qunreachable-enum
+
+ One can write a switch table like so:
+
+ \snippet code/src_corelib_global_qglobal.cpp qunreachable-switch
+
+ The advantage of inserting Q_UNREACHABLE() at that point is that the
+ compiler is told not to generate code for a shape variable containing that
+ value. If the macro is missing, the compiler will still generate the
+ necessary comparisons for that value. If the case label were removed, some
+ compilers could produce a warning that some enum values were not checked.
+
+ By using this macro in impossible conditions, code coverage may be improved
+ as dead code paths may be eliminated.
+
+ In debug builds the condition is enforced by an assert to facilitate debugging.
+
+ \note Use the macro Q_UNREACHABLE_RETURN() to insert return statements for
+ compilers that need them, without causing warnings for compilers that
+ complain about its presence.
+
+ \sa Q_ASSERT(), qFatal(), Q_UNREACHABLE_RETURN()
+*/
+
+/*!
+ \macro void Q_UNREACHABLE_RETURN(...)
+ \relates <QtAssert>
+ \since 6.5
+
+ This is equivalent to
+ \code
+ Q_UNREACHABLE();
+ return __VA_ARGS__;
+ \endcode
+ except it omits the return on compilers that would warn about it.
+
+ \sa Q_UNREACHABLE()
+*/
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qassert.h b/src/corelib/global/qassert.h
new file mode 100644
index 0000000000..388932a8f7
--- /dev/null
+++ b/src/corelib/global/qassert.h
@@ -0,0 +1,116 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QASSERT_H
+#define QASSERT_H
+
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtcoreexports.h>
+#include <QtCore/qtnoop.h>
+
+#if 0
+#pragma qt_class(QtAssert)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if defined(__cplusplus)
+
+#if !defined(Q_CC_MSVC_ONLY)
+Q_NORETURN
+#endif
+Q_DECL_COLD_FUNCTION
+Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line) noexcept;
+
+#if !defined(Q_ASSERT)
+# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
+# define Q_ASSERT(cond) static_cast<void>(false && (cond))
+# else
+# define Q_ASSERT(cond) ((cond) ? static_cast<void>(0) : qt_assert(#cond, __FILE__, __LINE__))
+# endif
+#endif
+
+#if !defined(Q_CC_MSVC_ONLY)
+Q_NORETURN
+#endif
+Q_DECL_COLD_FUNCTION
+Q_CORE_EXPORT
+void qt_assert_x(const char *where, const char *what, const char *file, int line) noexcept;
+
+#if !defined(Q_ASSERT_X)
+# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
+# define Q_ASSERT_X(cond, where, what) static_cast<void>(false && (cond))
+# else
+# define Q_ASSERT_X(cond, where, what) ((cond) ? static_cast<void>(0) : qt_assert_x(where, what, __FILE__, __LINE__))
+# endif
+#endif
+
+Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) noexcept;
+Q_NORETURN Q_DECL_COLD_FUNCTION
+Q_CORE_EXPORT void qBadAlloc();
+
+#ifdef QT_NO_EXCEPTIONS
+# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
+# define Q_CHECK_PTR(p) qt_noop()
+# else
+# define Q_CHECK_PTR(p) do {if (!(p)) qt_check_pointer(__FILE__,__LINE__);} while (false)
+# endif
+#else
+# define Q_CHECK_PTR(p) do { if (!(p)) qBadAlloc(); } while (false)
+#endif
+
+template <typename T>
+inline T *q_check_ptr(T *p) { Q_CHECK_PTR(p); return p; }
+
+// Q_UNREACHABLE_IMPL() and Q_ASSUME_IMPL() used below are defined in qcompilerdetection.h
+#define Q_UNREACHABLE() \
+ do {\
+ Q_ASSERT_X(false, "Q_UNREACHABLE()", "Q_UNREACHABLE was reached");\
+ Q_UNREACHABLE_IMPL();\
+ } while (false)
+
+#ifndef Q_UNREACHABLE_RETURN
+# ifdef Q_COMPILER_COMPLAINS_ABOUT_RETURN_AFTER_UNREACHABLE
+# define Q_UNREACHABLE_RETURN(...) Q_UNREACHABLE()
+# else
+# define Q_UNREACHABLE_RETURN(...) do { Q_UNREACHABLE(); return __VA_ARGS__; } while (0)
+# endif
+#endif
+
+Q_DECL_DEPRECATED_X("Q_ASSUME() is deprecated because it can produce worse code than when it's absent; "
+ "use C++23 [[assume]] instead")
+inline bool qt_assume_is_deprecated(bool cond) noexcept { return cond; }
+#define Q_ASSUME(Expr) \
+ [] (bool valueOfExpression) {\
+ Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\
+ Q_ASSUME_IMPL(valueOfExpression);\
+ }(qt_assume_is_deprecated(Expr))
+
+// Don't use these in C++ mode, use static_assert directly.
+// These are here only to keep old code compiling.
+# define Q_STATIC_ASSERT(Condition) static_assert(bool(Condition), #Condition)
+# define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
+
+#elif defined(Q_COMPILER_STATIC_ASSERT)
+// C11 mode - using the _S version in case <assert.h> doesn't do the right thing
+# define Q_STATIC_ASSERT(Condition) _Static_assert(!!(Condition), #Condition)
+# define Q_STATIC_ASSERT_X(Condition, Message) _Static_assert(!!(Condition), Message)
+#else
+// C89 & C99 version
+# define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B)
+# define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B
+# ifdef __COUNTER__
+# define Q_STATIC_ASSERT(Condition) \
+ typedef char Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __COUNTER__) [(Condition) ? 1 : -1];
+# else
+# define Q_STATIC_ASSERT(Condition) \
+ typedef char Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) [(Condition) ? 1 : -1];
+# endif /* __COUNTER__ */
+# define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
+#endif // __cplusplus
+
+QT_END_NAMESPACE
+
+#endif // QASSERT_H
diff --git a/src/corelib/global/qcompare.cpp b/src/corelib/global/qcompare.cpp
new file mode 100644
index 0000000000..ac220b8434
--- /dev/null
+++ b/src/corelib/global/qcompare.cpp
@@ -0,0 +1,1357 @@
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qcompare.h"
+
+#ifdef __cpp_lib_bit_cast
+#include <bit>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef __cpp_lib_three_way_comparison
+#ifdef __cpp_lib_bit_cast
+#define CHECK(type, flag) \
+ static_assert(std::bit_cast<Qt:: type ## _ordering>(std:: type ## _ordering:: flag) \
+ == Qt:: type ## _ordering :: flag); \
+ static_assert(std::bit_cast<std:: type ## _ordering>(Qt:: type ## _ordering:: flag) \
+ == std:: type ## _ordering :: flag) \
+ /* end */
+CHECK(partial, unordered);
+CHECK(partial, less);
+CHECK(partial, greater);
+CHECK(partial, equivalent);
+CHECK(weak, less);
+CHECK(weak, greater);
+CHECK(weak, equivalent);
+CHECK(strong, less);
+CHECK(strong, greater);
+CHECK(strong, equal);
+CHECK(strong, equivalent);
+#undef CHECK
+#endif // __cpp_lib_bit_cast
+#endif //__cpp_lib_three_way_comparison
+
+
+/*!
+ \page comparison-types.html overview
+ \title Comparison types overview
+ \keyword three-way comparison
+ \inmodule QtCore
+ \sa Qt::strong_ordering, Qt::weak_ordering, Qt::partial_ordering
+
+ \note Qt's comparison types provide functionality equivalent to their C++20
+ standard counterparts. The only reason why they exist is to make the
+ functionality available in C++17 builds, too. In a C++20 build, they
+ implicitly convert to and from the \c std types, making them fully
+ interchangeable. We therefore recommended that you prefer to use the C++
+ standard types in your code, if you can use C++20 in your projects already.
+ The Qt comparison types will be removed in Qt 7.
+
+ Qt provides several comparison types for a \l
+ {https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison}
+ {three-way comparison}, which are comparable against a \e {zero literal}.
+ To use these comparison types, you need to include the \c <QtCompare>
+ header. These comparison types are categorized based on their \e order,
+ which is a mathematical concept used to describe the arrangement or ranking
+ of elements. The following categories are provided:
+
+ \table 100 %
+ \header
+ \li C++ type
+ \li Qt type
+ \li strict
+ \li total
+ \li Example
+ \row
+ \li \l {https://en.cppreference.com/w/cpp/utility/compare/strong_ordering}
+ {std::strong_ordering}
+ \li Qt::strong_ordering
+ \li yes
+ \li yes
+ \li integral types, case-sensitive strings, QDate, QTime
+ \row
+ \li \l {https://en.cppreference.com/w/cpp/utility/compare/weak_ordering}
+ {std::weak_ordering}
+ \li Qt::weak_ordering
+ \li no
+ \li yes
+ \li case-insensitive strings, unordered associative containers, QDateTime
+ \row
+ \li \l {https://en.cppreference.com/w/cpp/utility/compare/partial_ordering}
+ {std::partial_ordering}
+ \li Qt::partial_ordering
+ \li no
+ \li no
+ \li floating-point types, QOperatingSystemVersion, QVariant
+ \endtable
+
+ The strongest comparison type, Qt::strong_ordering, represents a strict total
+ order. It requires that any two elements be comparable in a way where
+ equality implies substitutability. In other words, equivalent values
+ cannot be distinguished from each other. A practical example would be the
+ case-sensitive comparison of two strings. For instance, when comparing the
+ values \c "Qt" and \c "Qt" the result would be \l Qt::strong_ordering::equal.
+ Both values are indistinguishable and all deterministic operations performed
+ on these values would yield identical results.
+
+ Qt::weak_ordering represents a total order. While any two values still need to
+ be comparable, equivalent values may be distinguishable. The canonical
+ example here would be the case-insensitive comparison of two strings. For
+ instance, when comparing the values \c "Qt" and \c "qt" both hold the same
+ letters but with different representations. This comparison would
+ result in \l Qt::weak_ordering::equivalent, but not actually \c Equal.
+ Another example would be QDateTime, which can represent a given instant in
+ time in terms of local time or any other time-zone, including UTC. The
+ different representations are equivalent, even though their \c time() and
+ sometimes \c date() may differ.
+
+ Qt::partial_ordering represents, as the name implies, a partial ordering. It
+ allows for the possibility that two values may not be comparable, resulting
+ in an \l {Qt::partial_ordering::}{unordered} state. Additionally, equivalent
+ values may still be distinguishable. A practical example would be the
+ comparison of two floating-point values, comparing with NaN (Not-a-Number)
+ would yield an unordered result. Another example is the comparison of two
+ QOperatingSystemVersion objects. Comparing versions of two different
+ operating systems, such as Android and Windows, would produce an unordered
+ result.
+
+ Utilizing these comparison types enhances the expressiveness of defining
+ relations. Furthermore, they serve as a fundamental component for
+ implementing three-way comparison with C++17.
+*/
+
+/*!
+ \headerfile <QtCompare>
+ \inmodule QtCore
+ \title Classes and helpers for defining comparison operators
+ \keyword qtcompare
+
+ \brief The <QtCompare> header file defines \c {Qt::*_ordering} types and helper
+ macros for defining comparison operators.
+
+ This header introduces the \l Qt::partial_ordering, \l Qt::weak_ordering, and
+ \l Qt::strong_ordering types, which are Qt's C++17 backports of
+ \c {std::*_ordering} types.
+
+ This header also contains functions for implementing three-way comparison
+ in C++17.
+
+ The \c {Qt::compareThreeWay()} function overloads provide three-way
+ comparison for built-in C++ types.
+
+ The \l qCompareThreeWay() template serves as a generic three-way comparison
+ implementation. It relies on \c {Qt::compareThreeWay()} and free
+ \c {compareThreeWay()} functions in its implementation.
+*/
+
+/*!
+ \class Qt::strong_ordering
+ \inmodule QtCore
+ \brief Qt::strong_ordering represents a comparison where equivalent values are
+ indistinguishable.
+ \sa Qt::weak_ordering, Qt::partial_ordering, {Comparison types overview}
+ \since 6.7
+
+ A value of type Qt::strong_ordering is typically returned from a three-way
+ comparison function. Such a function compares two objects and establishes
+ how they are ordered. It uses this return type to indicate that the ordering
+ is strict; that is, the function establishes a well-defined total order.
+
+ Qt::strong_ordering has four values, represented by the following symbolic
+ constants:
+
+ \list
+ \li \l less represents that the left operand is less than the right;
+ \li \l equal represents that the left operand is equivalent to the right;
+ \li \l equivalent is an alias for \c equal;
+ \li \l greater represents that the left operand is greater than the right.
+ \endlist
+
+ Qt::strong_ordering is idiomatically used by comparing an instance against a
+ literal zero, for instance like this:
+
+ \code
+
+ // given a, b, c, d as objects of some type that allows for a 3-way compare,
+ // and a compare function declared as follows:
+
+ Qt::strong_ordering compare(T lhs, T rhs); // defined out-of-line
+ ~~~
+
+ Qt::strong_ordering result = compare(a, b);
+ if (result < 0) {
+ // a is less than b
+ }
+
+ if (compare(c, d) >= 0) {
+ // c is greater than or equal to d
+ }
+
+ \endcode
+*/
+
+/*!
+ \fn Qt::strong_ordering::operator Qt::partial_ordering() const
+
+ Converts this Qt::strong_ordering value to a Qt::partial_ordering object using the
+ following rules:
+
+ \list
+ \li \l less converts to \l {Qt::partial_ordering::less}.
+ \li \l equivalent converts to \l {Qt::partial_ordering::equivalent}.
+ \li \l equal converts to \l {Qt::partial_ordering::equivalent}.
+ \li \l greater converts to \l {Qt::partial_ordering::greater}.
+ \endlist
+*/
+
+/*!
+ \fn Qt::strong_ordering::operator Qt::weak_ordering() const
+
+ Converts this Qt::strong_ordering value to a Qt::weak_ordering object using the
+ following rules:
+
+ \list
+ \li \l less converts to \l {Qt::weak_ordering::less}.
+ \li \l equivalent converts to \l {Qt::weak_ordering::equivalent}.
+ \li \l equal converts to \l {Qt::weak_ordering::equivalent}.
+ \li \l greater converts to \l {Qt::weak_ordering::greater}.
+ \endlist
+*/
+
+/*!
+ \fn Qt::strong_ordering::strong_ordering(std::strong_ordering stdorder)
+
+ Constructs a Qt::strong_ordering object from \a stdorder using the following rules:
+
+ \list
+ \li std::strong_ordering::less converts to \l less.
+ \li std::strong_ordering::equivalent converts to \l equivalent.
+ \li std::strong_ordering::equal converts to \l equal.
+ \li std::strong_ordering::greater converts to \l greater.
+ \endlist
+*/
+
+/*!
+ \fn Qt::strong_ordering::operator std::strong_ordering() const
+
+ Converts this Qt::strong_ordering value to a std::strong_ordering object using
+ the following rules:
+
+ \list
+ \li \l less converts to std::strong_ordering::less.
+ \li \l equivalent converts to std::strong_ordering::equivalent.
+ \li \l equal converts to std::strong_ordering::equal.
+ \li \l greater converts to std::strong_ordering::greater.
+ \endlist
+*/
+
+/*!
+ \fn bool Qt::strong_ordering::operator==(Qt::strong_ordering lhs, Qt::strong_ordering rhs)
+
+ Returns true if \a lhs and \a rhs represent the same result;
+ otherwise, returns false.
+*/
+
+/*!
+ \fn bool Qt::strong_ordering::operator!=(Qt::strong_ordering lhs, Qt::strong_ordering rhs)
+
+ Returns true if \a lhs and \a rhs represent different results;
+ otherwise, returns true.
+*/
+
+/*!
+ \internal
+ \relates Qt::strong_ordering
+ \fn bool operator==(Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator!=(Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator< (Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator<=(Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator> (Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator>=(Qt::strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+
+ \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
+ \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
+ \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
+ \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
+ \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
+ \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, Qt::strong_ordering rhs)
+*/
+
+/*!
+ \fn Qt::strong_ordering::is_eq (Qt::strong_ordering o)
+ \fn Qt::strong_ordering::is_neq (Qt::strong_ordering o)
+ \fn Qt::strong_ordering::is_lt (Qt::strong_ordering o)
+ \fn Qt::strong_ordering::is_lteq(Qt::strong_ordering o)
+ \fn Qt::strong_ordering::is_gt (Qt::strong_ordering o)
+ \fn Qt::strong_ordering::is_gteq(Qt::strong_ordering o)
+
+//! [is_eq_table]
+ Converts \a o into the result of one of the six relational operators:
+ \table
+ \header \li Function \li Operation
+ \row \li \c{is_eq} \li \a o \c{== 0}
+ \row \li \c{is_neq} \li \a o \c{!= 0}
+ \row \li \c{is_lt} \li \a o \c{< 0}
+ \row \li \c{is_lteq} \li \a o \c{<= 0}
+ \row \li \c{is_gt} \li \a o \c{> 0}
+ \row \li \c{is_gteq} \li \a o \c{>= 0}
+ \endtable
+//! [is_eq_table]
+
+ These functions are provided for compatibility with \c{std::strong_ordering}.
+*/
+
+/*!
+ \variable Qt::strong_ordering::less
+
+ Represents the result of a comparison where the left operand is less
+ than the right operand.
+*/
+
+/*!
+ \variable Qt::strong_ordering::equivalent
+
+ Represents the result of a comparison where the left operand is equal
+ to the right operand. Same as \l {Qt::strong_ordering::equal}.
+*/
+
+/*!
+ \variable Qt::strong_ordering::equal
+
+ Represents the result of a comparison where the left operand is equal
+ to the right operand. Same as \l {Qt::strong_ordering::equivalent}.
+*/
+
+/*!
+ \variable Qt::strong_ordering::greater
+
+ Represents the result of a comparison where the left operand is greater
+ than the right operand.
+*/
+
+/*!
+ \class Qt::weak_ordering
+ \inmodule QtCore
+ \brief Qt::weak_ordering represents a comparison where equivalent values are
+ still distinguishable.
+ \sa Qt::strong_ordering, Qt::partial_ordering, {Comparison types overview}
+ \since 6.7
+
+ A value of type Qt::weak_ordering is typically returned from a three-way
+ comparison function. Such a function compares two objects and establishes
+ how they are ordered. It uses this return type to indicate that the ordering
+ is weak; that is, equivalent values may be distinguishable.
+
+ Qt::weak_ordering has three values, represented by the following symbolic
+ constants:
+
+ \list
+ \li \l less represents that the left operand is less than the right;
+ \li \l equivalent represents that the left operand is equivalent to the
+ right;
+ \li \l greater represents that the left operand is greater than the right,
+ \endlist
+
+ Qt::weak_ordering is idiomatically used by comparing an instance against a
+ literal zero, for instance like this:
+
+ \code
+
+ // given a, b, c, d as objects of some type that allows for a 3-way compare,
+ // and a compare function declared as follows:
+
+ Qt::weak_ordering compare(T lhs, T rhs); // defined out-of-line
+ ~~~
+
+ Qt::weak_ordering result = compare(a, b);
+ if (result < 0) {
+ // a is less than b
+ }
+
+ if (compare(c, d) >= 0) {
+ // c is greater than or equivalent to d
+ }
+
+ \endcode
+*/
+
+/*!
+ \fn Qt::weak_ordering::operator Qt::partial_ordering() const
+
+ Converts this Qt::weak_ordering value to a Qt::partial_ordering object using the
+ following rules:
+
+ \list
+ \li \l less converts to \l {Qt::partial_ordering::less}.
+ \li \l equivalent converts to \l {Qt::partial_ordering::equivalent}.
+ \li \l greater converts to \l {Qt::partial_ordering::greater}.
+ \endlist
+*/
+
+/*!
+ \fn Qt::weak_ordering::weak_ordering(std::weak_ordering stdorder)
+
+ Constructs a Qt::weak_ordering object from \a stdorder using the following rules:
+
+ \list
+ \li std::weak_ordering::less converts to \l less.
+ \li std::weak_ordering::equivalent converts to \l equivalent.
+ \li std::weak_ordering::greater converts to \l greater.
+ \endlist
+*/
+
+/*!
+ \fn Qt::weak_ordering::operator std::weak_ordering() const
+
+ Converts this Qt::weak_ordering value to a std::weak_ordering object using
+ the following rules:
+
+ \list
+ \li \l less converts to std::weak_ordering::less.
+ \li \l equivalent converts to std::weak_ordering::equivalent.
+ \li \l greater converts to std::weak_ordering::greater.
+ \endlist
+*/
+
+/*!
+ \fn bool Qt::weak_ordering::operator==(Qt::weak_ordering lhs, Qt::weak_ordering rhs)
+
+ Return true if \a lhs and \a rhs represent the same result;
+ otherwise, returns false.
+*/
+
+/*!
+ \fn bool Qt::weak_ordering::operator!=(Qt::weak_ordering lhs, Qt::weak_ordering rhs)
+
+ Return true if \a lhs and \a rhs represent different results;
+ otherwise, returns true.
+*/
+
+/*!
+ \internal
+ \relates Qt::weak_ordering
+ \fn bool operator==(Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator!=(Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator< (Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator<=(Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator> (Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator>=(Qt::weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+
+ \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
+ \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
+ \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
+ \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
+ \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
+ \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, Qt::weak_ordering rhs)
+*/
+
+/*!
+ \fn Qt::weak_ordering::is_eq (Qt::weak_ordering o)
+ \fn Qt::weak_ordering::is_neq (Qt::weak_ordering o)
+ \fn Qt::weak_ordering::is_lt (Qt::weak_ordering o)
+ \fn Qt::weak_ordering::is_lteq(Qt::weak_ordering o)
+ \fn Qt::weak_ordering::is_gt (Qt::weak_ordering o)
+ \fn Qt::weak_ordering::is_gteq(Qt::weak_ordering o)
+
+ \include qcompare.cpp is_eq_table
+
+ These functions are provided for compatibility with \c{std::weak_ordering}.
+*/
+
+/*!
+ \variable Qt::weak_ordering::less
+
+ Represents the result of a comparison where the left operand is less than
+ the right operand.
+*/
+
+/*!
+ \variable Qt::weak_ordering::equivalent
+
+ Represents the result of a comparison where the left operand is equivalent
+ to the right operand.
+*/
+
+/*!
+ \variable Qt::weak_ordering::greater
+
+ Represents the result of a comparison where the left operand is greater
+ than the right operand.
+*/
+
+/*!
+ \class Qt::partial_ordering
+ \inmodule QtCore
+ \brief Qt::partial_ordering represents the result of a comparison that allows
+ for unordered results.
+ \sa Qt::strong_ordering, Qt::weak_ordering, {Comparison types overview}
+ \since 6.7
+
+ A value of type Qt::partial_ordering is typically returned from a
+ three-way comparison function. Such a function compares two objects,
+ establishing whether they are ordered and, if so, their ordering. It uses
+ this return type to indicate that the ordering is partial; that is, not all
+ pairs of values are ordered.
+
+ Qt::partial_ordering has four values, represented by the following symbolic
+ constants:
+
+ \list
+ \li \l less represents that the left operand is less than the right;
+ \li \l equivalent represents that the two operands are equivalent;
+ \li \l greater represents that the left operand is greater than the right;
+ \li \l unordered represents that the two operands are \e {not ordered}.
+ \endlist
+
+ Qt::partial_ordering is idiomatically used by comparing an instance
+ against a literal zero, for instance like this:
+
+ \code
+
+ // given a, b, c, d as objects of some type that allows for a 3-way compare,
+ // and a compare function declared as follows:
+
+ Qt::partial_ordering compare(T lhs, T rhs); // defined out-of-line
+ ~~~
+
+ Qt::partial_ordering result = compare(a, b);
+ if (result < 0) {
+ // a is less than b
+ }
+
+ if (compare(c, d) >= 0) {
+ // c is greater than or equal to d
+ }
+
+ \endcode
+
+ Comparing Qt::partial_ordering::unordered against literal 0 always returns
+ a \c false result.
+*/
+
+/*!
+ \fn Qt::partial_ordering::partial_ordering(std::partial_ordering stdorder)
+
+ Constructs a Qt::partial_ordering object from \a stdorder using the following
+ rules:
+
+ \list
+ \li std::partial_ordering::less converts to \l less.
+ \li std::partial_ordering::equivalent converts to \l equivalent.
+ \li std::partial_ordering::greater converts to \l greater.
+ \li std::partial_ordering::unordered converts to \l unordered
+ \endlist
+*/
+
+/*!
+ \fn Qt::partial_ordering::operator std::partial_ordering() const
+
+ Converts this Qt::partial_ordering value to a std::partial_ordering object using
+ the following rules:
+
+ \list
+ \li \l less converts to std::partial_ordering::less.
+ \li \l equivalent converts to std::partial_ordering::equivalent.
+ \li \l greater converts to std::partial_ordering::greater.
+ \li \l unordered converts to std::partial_ordering::unordered.
+ \endlist
+*/
+
+/*!
+ \fn bool Qt::partial_ordering::operator==(Qt::partial_ordering lhs, Qt::partial_ordering rhs)
+
+ Return true if \a lhs and \a rhs represent the same result;
+ otherwise, returns false.
+*/
+
+/*!
+ \fn bool Qt::partial_ordering::operator!=(Qt::partial_ordering lhs, Qt::partial_ordering rhs)
+
+ Return true if \a lhs and \a rhs represent different results;
+ otherwise, returns true.
+*/
+
+/*!
+ \internal
+ \relates Qt::partial_ordering
+ \fn bool operator==(Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator!=(Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator< (Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator<=(Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator> (Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator>=(Qt::partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero)
+
+ \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
+ \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
+ \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
+ \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
+ \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
+ \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, Qt::partial_ordering rhs)
+*/
+
+/*!
+ \fn Qt::partial_ordering::is_eq (Qt::partial_ordering o)
+ \fn Qt::partial_ordering::is_neq (Qt::partial_ordering o)
+ \fn Qt::partial_ordering::is_lt (Qt::partial_ordering o)
+ \fn Qt::partial_ordering::is_lteq(Qt::partial_ordering o)
+ \fn Qt::partial_ordering::is_gt (Qt::partial_ordering o)
+ \fn Qt::partial_ordering::is_gteq(Qt::partial_ordering o)
+
+ \include qcompare.cpp is_eq_table
+
+ These functions are provided for compatibility with \c{std::partial_ordering}.
+*/
+
+/*!
+ \variable Qt::partial_ordering::less
+
+ Represents the result of a comparison where the left operand is less than
+ the right operand.
+*/
+
+/*!
+ \variable Qt::partial_ordering::equivalent
+
+ Represents the result of a comparison where the two operands are equivalent.
+*/
+
+/*!
+ \variable Qt::partial_ordering::greater
+
+ Represents the result of a comparison where the left operand is greater
+ than the right operand.
+*/
+
+/*!
+ \variable Qt::partial_ordering::unordered
+
+ Represents the result of a comparison where there is no ordering
+ relationship between the two operands.
+*/
+
+/*!
+ \class QPartialOrdering
+ \inmodule QtCore
+ \brief QPartialOrdering represents the result of a comparison that allows
+ for unordered results.
+ \sa Qt::strong_ordering, Qt::weak_ordering, {Comparison types overview}
+ \since 6.0
+
+ A value of type QPartialOrdering is typically returned from a
+ three-way comparison function. Such a function compares two objects,
+ establishing whether they are ordered and, if so, their ordering. It uses
+ this return type to indicate that the ordering is partial; that is, not all
+ pairs of values are ordered.
+
+ QPartialOrdering has four values, represented by the following symbolic
+ constants:
+
+ \list
+ \li \l less represents that the left operand is less than the right;
+ \li \l equivalent represents that the two operands are equivalent;
+ \li \l greater represents that the left operand is greater than the right;
+ \li \l unordered represents that the two operands are \e {not ordered}.
+ \endlist
+
+ QPartialOrdering is idiomatically used by comparing an instance
+ against a literal zero, for instance like this:
+
+ \code
+
+ // given a, b, c, d as objects of some type that allows for a 3-way compare,
+ // and a compare function declared as follows:
+
+ QPartialOrdering compare(T lhs, T rhs); // defined out-of-line
+ ~~~
+
+ QPartialOrdering result = compare(a, b);
+ if (result < 0) {
+ // a is less than b
+ }
+
+ if (compare(c, d) >= 0) {
+ // c is greater than or equal to d
+ }
+
+ \endcode
+
+ Comparing QPartialOrdering::unordered against literal 0 always returns
+ a \c false result.
+*/
+
+/*!
+ \fn QPartialOrdering::QPartialOrdering(std::partial_ordering stdorder)
+
+ Constructs a QPartialOrdering object from \a stdorder using the following
+ rules:
+
+ \list
+ \li std::partial_ordering::less converts to \l less.
+ \li std::partial_ordering::equivalent converts to \l equivalent.
+ \li std::partial_ordering::greater converts to \l greater.
+ \li std::partial_ordering::unordered converts to \l unordered
+ \endlist
+*/
+
+/*!
+ \fn QPartialOrdering::operator std::partial_ordering() const
+
+ Converts this QPartialOrdering value to a std::partial_ordering object using
+ the following rules:
+
+ \list
+ \li \l less converts to std::partial_ordering::less.
+ \li \l equivalent converts to std::partial_ordering::equivalent.
+ \li \l greater converts to std::partial_ordering::greater.
+ \li \l unordered converts to std::partial_ordering::unordered.
+ \endlist
+*/
+
+/*!
+ \fn bool QPartialOrdering::operator==(QPartialOrdering lhs, QPartialOrdering rhs)
+
+ Return true if \a lhs and \a rhs represent the same result;
+ otherwise, returns false.
+*/
+
+/*!
+ \fn bool QPartialOrdering::operator!=(QPartialOrdering lhs, QPartialOrdering rhs)
+
+ Return true if \a lhs and \a rhs represent different results;
+ otherwise, returns true.
+*/
+
+/*!
+ \internal
+ \relates QPartialOrdering
+ \fn bool operator==(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator!=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator< (QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator<=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator> (QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
+ \fn bool operator>=(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero)
+
+ \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
+ \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
+ \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
+ \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
+ \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
+ \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs)
+*/
+
+/*!
+ \fn QPartialOrdering::is_eq (QPartialOrdering o)
+ \fn QPartialOrdering::is_neq (QPartialOrdering o)
+ \fn QPartialOrdering::is_lt (QPartialOrdering o)
+ \fn QPartialOrdering::is_lteq(QPartialOrdering o)
+ \fn QPartialOrdering::is_gt (QPartialOrdering o)
+ \fn QPartialOrdering::is_gteq(QPartialOrdering o)
+
+ \since 6.7
+ \include qcompare.cpp is_eq_table
+
+ These functions are provided for compatibility with \c{std::partial_ordering}.
+*/
+
+/*!
+ \variable QPartialOrdering::less
+
+ Represents the result of a comparison where the left operand is less than
+ the right operand.
+*/
+
+/*!
+ \variable QPartialOrdering::equivalent
+
+ Represents the result of a comparison where the two operands are equivalent.
+*/
+
+/*!
+ \variable QPartialOrdering::greater
+
+ Represents the result of a comparison where the left operand is greater
+ than the right operand.
+*/
+
+/*!
+ \variable QPartialOrdering::unordered
+
+ Represents the result of a comparison where there is no ordering
+ relationship between the two operands.
+*/
+
+/*!
+ \variable QPartialOrdering::Less
+
+ Represents the result of a comparison where the left operand is less than
+ the right operand.
+*/
+
+/*!
+ \variable QPartialOrdering::Equivalent
+
+ Represents the result of a comparison where the two operands are equivalent.
+*/
+
+/*!
+ \variable QPartialOrdering::Greater
+
+ Represents the result of a comparison where the left operand is greater
+ than the right operand.
+*/
+
+/*!
+ \variable QPartialOrdering::Unordered
+
+ Represents the result of a comparison where there is no ordering
+ relationship between the two operands.
+*/
+
+/*!
+ \internal
+ \macro Q_DECLARE_EQUALITY_COMPARABLE(Type)
+ \macro Q_DECLARE_EQUALITY_COMPARABLE(LeftType, RightType)
+ \macro Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(Type)
+ \macro Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(LeftType, RightType)
+ \since 6.7
+ \relates <QtCompare>
+
+ These macros are used to generate \c {operator==()} and \c {operator!=()}.
+
+ In C++17 mode, the mixed-type overloads also generate the reversed
+ operators.
+
+ In C++20 mode, only \c {operator==()} is defined. \c {operator!=()},
+ as well as the reversed operators for mixed-type comparison, are synthesized
+ by the compiler.
+
+ The operators are implemented in terms of a helper function
+ \c {comparesEqual()}.
+ It's the user's responsibility to declare and define this function.
+
+ Consider the following example of a comparison operators declaration:
+
+ \code
+ class MyClass {
+ ...
+ private:
+ friend bool comparesEqual(const MyClass &, const MyClass &) noexcept;
+ Q_DECLARE_EQUALITY_COMPARABLE(MyClass)
+ };
+ \endcode
+
+ When compiled with C++17, the macro will expand into the following code:
+
+ \code
+ friend bool operator==(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ friend bool operator!=(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ \endcode
+
+ When compiled with C++20, the macro will expand only into \c {operator==()}:
+
+ \code
+ friend bool operator==(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ \endcode
+
+ The \c {*_LITERAL_TYPE} versions of the macros are used to generate
+ \c constexpr operators. This means that the helper \c {comparesEqual()}
+ function must also be \c constexpr.
+
+ Consider the following example of a mixed-type \c constexpr comparison
+ operators declaration:
+
+ \code
+ class MyClass {
+ ...
+ private:
+ friend constexpr bool comparesEqual(const MyClass &, int) noexcept;
+ Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(MyClass, int)
+ };
+ \endcode
+
+ When compiled with C++17, the macro will expand into the following code:
+
+ \code
+ friend constexpr bool operator==(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ friend constexpr bool operator!=(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ friend constexpr bool operator==(int lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ friend constexpr bool operator!=(int lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ \endcode
+
+ When compiled with C++20, the macro expands only into \c {operator==()}:
+
+ \code
+ friend constexpr bool operator==(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ \endcode
+*/
+
+/*!
+ \internal
+ \macro Q_DECLARE_PARTIALLY_ORDERED(Type)
+ \macro Q_DECLARE_PARTIALLY_ORDERED(LeftType, RightType)
+ \macro Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(Type)
+ \macro Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(LeftType, RightType)
+ \since 6.7
+ \relates <QtCompare>
+
+ These macros are used to generate all six relational operators.
+ The operators represent
+ \l {https://en.cppreference.com/w/cpp/utility/compare/partial_ordering}
+ {partial ordering}.
+
+ These macros use respective overloads of the
+ \l {Q_DECLARE_EQUALITY_COMPARABLE} macro to generate \c {operator==()} and
+ \c {operator!=()}, and also generate the four relational operators:
+ \c {operator<()}, \c {operator>()}, \c {operator<=()}, and \c {operator>()}.
+
+ In C++17 mode, the mixed-type overloads also generate the reversed
+ operators.
+
+ In C++20 mode, only \c {operator==()} and \c {operator<=>()} are defined.
+ Other operators, as well as the reversed operators for mixed-type
+ comparison, are synthesized by the compiler.
+
+ The (in)equality operators are implemented in terms of a helper function
+ \c {comparesEqual()}. The other relational operators are implemented in
+ terms of a helper function \c {compareThreeWay()}.
+ The \c {compareThreeWay()} function \e must return an object of type
+ \l Qt::partial_ordering. It's the user's responsibility to declare and define
+ both helper functions.
+
+ Consider the following example of a comparison operators declaration:
+
+ \code
+ class MyClass {
+ ...
+ private:
+ friend bool comparesEqual(const MyClass &, const MyClass &) noexcept;
+ friend Qt::partial_ordering compareThreeWay(const MyClass &, const MyClass &) noexcept;
+ Q_DECLARE_PARTIALLY_ORDERED(MyClass)
+ };
+ \endcode
+
+ When compiled with C++17, the macro will expand into the following code:
+
+ \code
+ // operator==() and operator!=() are generated from
+ // Q_DECLARE_EQUALITY_COMPARABLE
+ friend bool operator<(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend bool operator>(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend bool operator<=(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend bool operator>=(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ \endcode
+
+ When compiled with C++20, the macro will expand into \c {operator==()} and
+ \c {operator<=>()}:
+
+ \code
+ friend bool operator==(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ friend std::partial_ordering
+ operator<=>(const MyClass &lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ \endcode
+
+ The \c {*_LITERAL_TYPE} versions of the macros are used to generate
+ \c constexpr operators. This means that the helper \c {comparesEqual()} and
+ \c {compareThreeWay()} functions must also be \c constexpr.
+
+ Consider the following example of a mixed-type \c constexpr comparison
+ operators declaration:
+
+ \code
+ class MyClass {
+ ...
+ private:
+ friend constexpr bool comparesEqual(const MyClass &, int) noexcept;
+ friend constexpr Qt::partial_ordering compareThreeWay(const MyClass &, int) noexcept;
+ Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(MyClass, int)
+ };
+ \endcode
+
+ When compiled with C++17, the macro will expand into the following code:
+
+ \code
+ // operator==(), operator!=(), and their reversed versions are generated
+ // from Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE
+ friend constexpr bool operator<(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend constexpr bool operator>(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend constexpr bool operator<=(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend constexpr bool operator>=(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend constexpr bool operator<(int lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend constexpr bool operator>(int lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend constexpr bool operator<=(int lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ friend constexpr bool operator>=(int lhs, const MyClass &rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ \endcode
+
+ When compiled with C++20, the macro will expand into \c {operator==()} and
+ \c {operator<=>()}:
+
+ \code
+ friend constexpr bool operator==(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses comparesEqual()
+ }
+ friend constexpr std::partial_ordering
+ operator<=>(const MyClass &lhs, int rhs) noexcept
+ {
+ // inline implementation which uses compareThreeWay()
+ }
+ \endcode
+
+ \sa Q_DECLARE_EQUALITY_COMPARABLE, Q_DECLARE_WEAKLY_ORDERED,
+ Q_DECLARE_STRONGLY_ORDERED
+*/
+
+/*!
+ \internal
+ \macro Q_DECLARE_WEAKLY_ORDERED(Type)
+ \macro Q_DECLARE_WEAKLY_ORDERED(LeftType, RightType)
+ \macro Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(Type)
+ \macro Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(LeftType, RightType)
+ \since 6.7
+ \relates <QtCompare>
+
+ These macros behave similarly to the
+ \l {Q_DECLARE_PARTIALLY_ORDERED} overloads, but represent
+ \l {https://en.cppreference.com/w/cpp/utility/compare/weak_ordering}
+ {weak ordering}.
+
+ The (in)equality operators are implemented in terms of a helper function
+ \c {comparesEqual()}. The other relational operators are implemented in
+ terms of a helper function \c {compareThreeWay()}.
+ The \c {compareThreeWay()} function \e must return an object of type
+ \l Qt::weak_ordering. It's the user's responsibility to declare and define both
+ helper functions.
+
+ The \c {*_LITERAL_TYPE} overloads are used to generate \c constexpr
+ operators. This means that the helper \c {comparesEqual()} and
+ \c {compareThreeWay()} functions must also be \c constexpr.
+
+ See \l {Q_DECLARE_PARTIALLY_ORDERED} for usage examples.
+
+ \sa Q_DECLARE_PARTIALLY_ORDERED, Q_DECLARE_STRONGLY_ORDERED,
+ Q_DECLARE_EQUALITY_COMPARABLE
+*/
+
+/*!
+ \internal
+ \macro Q_DECLARE_STRONGLY_ORDERED(Type)
+ \macro Q_DECLARE_STRONGLY_ORDERED(LeftType, RightType)
+ \macro Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(Type)
+ \macro Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(LeftType, RightType)
+ \since 6.7
+ \relates <QtCompare>
+
+ These macros behave similarly to the
+ \l {Q_DECLARE_PARTIALLY_ORDERED} overloads, but represent
+ \l {https://en.cppreference.com/w/cpp/utility/compare/strong_ordering}
+ {strong ordering}.
+
+ The (in)equality operators are implemented in terms of a helper function
+ \c {comparesEqual()}. The other relational operators are implemented in
+ terms of a helper function \c {compareThreeWay()}.
+ The \c {compareThreeWay()} function \e must return an object of type
+ \l Qt::strong_ordering. It's the user's responsibility to declare and define
+ both helper functions.
+
+ The \c {*_LITERAL_TYPE} overloads are used to generate \c constexpr
+ operators. This means that the helper \c {comparesEqual()} and
+ \c {compareThreeWay()} functions must also be \c constexpr.
+
+ See \l {Q_DECLARE_PARTIALLY_ORDERED} for usage examples.
+
+ \sa Q_DECLARE_PARTIALLY_ORDERED, Q_DECLARE_WEAKLY_ORDERED,
+ Q_DECLARE_EQUALITY_COMPARABLE
+*/
+
+/*!
+ \internal
+ \macro Q_DECLARE_EQUALITY_COMPARABLE(LeftType, RightType, Attributes)
+ \macro Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(LeftType, RightType, Attributes)
+ \macro Q_DECLARE_PARTIALLY_ORDERED(LeftType, RightType, Attributes)
+ \macro Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes)
+ \macro Q_DECLARE_WEAKLY_ORDERED(LeftType, RightType, Attributes)
+ \macro Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes)
+ \macro Q_DECLARE_STRONGLY_ORDERED(LeftType, RightType, Attributes)
+ \macro Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes)
+ \since 6.8
+ \relates <QtCompare>
+
+ These macros behave like their two-argument versions, but allow
+ specification of C++ attributes to add before every generated relational
+ operator.
+
+ As an example, the \c Attributes parameter can be used in Qt to pass
+ the \c QT_ASCII_CAST_WARN marco (whose expansion can mark the function as
+ deprecated) when implementing comparison of encoding-aware string types
+ with C-style strings or byte arrays.
+*/
+
+/*!
+ \fn template <typename LeftInt, typename RightInt, Qt::if_integral<LeftInt> = true, Qt::if_integral<RightInt> = true> auto Qt::compareThreeWay(LeftInt lhs, RightInt rhs)
+ \since 6.7
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of integral types.
+
+ \note This function participates in overload resolution only if both
+ \c LeftInt and \c RightInt are built-in integral types.
+
+ Returns \c {lhs <=> rhs}, provided \c LeftInt and \c RightInt are built-in
+ integral types. Unlike \c {operator<=>()}, this function template is also
+ available in C++17. See
+ \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison}
+ {cppreference} for more details.
+
+ This function can also be used in custom \c {compareThreeWay()} functions,
+ when ordering members of a custom class represented by built-in types:
+
+ \code
+ class MyClass {
+ public:
+ ...
+ private:
+ int value;
+ ...
+ friend Qt::strong_ordering
+ compareThreeWay(const MyClass &lhs, const MyClass &rhs) noexcept
+ { return Qt::compareThreeWay(lhs.value, rhs.value); }
+ Q_DECLARE_STRONGLY_ORDERED(MyClass)
+ };
+ \endcode
+
+ Returns an instance of \l Qt::strong_ordering that represents the relation
+ between \a lhs and \a rhs.
+*/
+
+/*!
+ \fn template <typename LeftFloat, typename RightFloat, Qt::if_floating_point<LeftFloat> = true, Qt::if_floating_point<RightFloat> = true> auto Qt::compareThreeWay(LeftFloat lhs, RightFloat rhs)
+ \since 6.7
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of floating point types.
+
+ \note This function participates in overload resolution only if both
+ \c LeftFloat and \c RightFloat are built-in floating-point types.
+
+ Returns \c {lhs <=> rhs}, provided \c LeftFloat and \c RightFloat are
+ built-in floating-point types. Unlike \c {operator<=>()}, this function
+ template is also available in C++17. See
+ \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison}
+ {cppreference} for more details.
+
+ This function can also be used in custom \c {compareThreeWay()} functions,
+ when ordering members of a custom class represented by built-in types:
+
+ \code
+ class MyClass {
+ public:
+ ...
+ private:
+ double value;
+ ...
+ friend Qt::partial_ordering
+ compareThreeWay(const MyClass &lhs, const MyClass &rhs) noexcept
+ { return Qt::compareThreeWay(lhs.value, rhs.value); }
+ Q_DECLARE_PARTIALLY_ORDERED(MyClass)
+ };
+ \endcode
+
+ Returns an instance of \l Qt::partial_ordering that represents the relation
+ between \a lhs and \a rhs. If \a lhs or \a rhs is not a number (NaN),
+ \l Qt::partial_ordering::unordered is returned.
+*/
+
+/*!
+ \fn template <typename IntType, typename FloatType, Qt::if_integral<IntType> = true, Qt::if_floating_point<FloatType> = true> auto Qt::compareThreeWay(IntType lhs, FloatType rhs)
+ \since 6.7
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of integral and floating point types.
+
+ \note This function participates in overload resolution only if \c IntType
+ is a built-in integral type and \c FloatType is a built-in floating-point
+ type.
+
+ This function converts \a lhs to \c FloatType and calls the overload for
+ floating-point types.
+
+ Returns an instance of \l Qt::partial_ordering that represents the relation
+ between \a lhs and \a rhs. If \a rhs is not a number (NaN),
+ \l Qt::partial_ordering::unordered is returned.
+*/
+
+/*!
+ \fn template <typename FloatType, typename IntType, Qt::if_floating_point<FloatType> = true, Qt::if_integral<IntType> = true> auto Qt::compareThreeWay(FloatType lhs, IntType rhs)
+ \since 6.7
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of floating point and integral types.
+
+ \note This function participates in overload resolution only if \c FloatType
+ is a built-in floating-point type and \c IntType is a built-in integral
+ type.
+
+ This function converts \a rhs to \c FloatType and calls the overload for
+ floating-point types.
+
+ Returns an instance of \l Qt::partial_ordering that represents the relation
+ between \a lhs and \a rhs. If \a lhs is not a number (NaN),
+ \l Qt::partial_ordering::unordered is returned.
+*/
+
+/*!
+ \fn template <typename LeftType, typename RightType, Qt::if_compatible_pointers<LeftType, RightType> = true> Qt::compareThreeWay(const LeftType *lhs, const RightType *rhs)
+ \since 6.7
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of pointers.
+
+ \note This function participates in overload resolution if \c LeftType and
+ \c RightType are the same type, or base and derived types. It is also used
+ to compare any pointer to \c {std::nullptr_t}.
+
+ Returns an instance of \l Qt::strong_ordering that represents the relation
+ between \a lhs and \a rhs.
+*/
+
+/*!
+ \fn template <class Enum, Qt::if_enum<Enum> = true> Qt::compareThreeWay(Enum lhs, Enum rhs)
+ \since 6.7
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of enum types.
+
+ \note This function participates in overload resolution only if \c Enum
+ is an enum type.
+
+ This function converts \c Enum to its underlying type and calls the
+ overload for integral types.
+
+ Returns an instance of \l Qt::strong_ordering that represents the relation
+ between \a lhs and \a rhs.
+*/
+
+/*!
+ \fn template <typename LeftType, typename RightType> qCompareThreeWay(const LeftType &lhs, const RightType &rhs)
+ \since 6.7
+ \relates <QtCompare>
+
+ Performs the three-way comparison on \a lhs and \a rhs and returns one of
+ the Qt ordering types as a result. This function is available for both
+ C++17 and C++20.
+
+ The actual returned type depends on \c LeftType and \c RightType.
+
+ \note This function template is only available when \c {compareThreeWay()}
+ is implemented for the \c {(LeftType, RightType)} pair or the reversed
+ \c {(RightType, LeftType)} pair.
+
+ This method is equivalent to
+
+ \code
+ using Qt::compareThreeWay;
+ return compareThreeWay(lhs, rhs);
+ \endcode
+
+ where \c {Qt::compareThreeWay} is the Qt implementation of three-way
+ comparison for built-in types.
+
+ The free \c {compareThreeWay} functions should provide three-way comparison
+ for custom types. The functions should return one of the Qt ordering types.
+
+ Qt provides \c {compareThreeWay} implementation for some of its types.
+
+ \note \b {Do not} re-implement \c {compareThreeWay()} for Qt types, as more
+ Qt types will get support for it in future Qt releases.
+
+ Use this function primarly in generic code, when you know nothing about
+ \c LeftType and \c RightType.
+
+ If you know the types, use
+
+ \list
+ \li \c {Qt::compareThreeWay} for built-in types
+ \li \c {compareThreeWay} for custom types
+ \endlist
+
+ Use \c {operator<=>()} directly in code that will only be compiled with
+ C++20 or later.
+
+ \sa Qt::partial_ordering, Qt::weak_ordering, Qt::strong_ordering
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qcompare.h b/src/corelib/global/qcompare.h
index 8bc3029c89..9dd244c8f9 100644
--- a/src/corelib/global/qcompare.h
+++ b/src/corelib/global/qcompare.h
@@ -1,41 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOMPARE_H
#define QCOMPARE_H
@@ -47,6 +12,13 @@
#include <QtCore/qglobal.h>
#include <QtCore/qcompare_impl.h>
+#ifdef __cpp_lib_bit_cast
+#include <bit>
+#endif
+#ifdef __cpp_lib_three_way_comparison
+#include <compare>
+#endif
+
QT_BEGIN_NAMESPACE
namespace QtPrivate {
@@ -63,11 +35,645 @@ enum class Ordering : CompareUnderlyingType
enum class Uncomparable : CompareUnderlyingType
{
- Unordered = -127
+ Unordered =
+ #if defined(_LIBCPP_VERSION) // libc++
+ -127
+ #elif defined(__GLIBCXX__) // libstdc++
+ 2
+ #else // assume MSSTL
+ -128
+ #endif
};
} // namespace QtPrivate
+namespace QtOrderingPrivate {
+
+template <typename O>
+constexpr O reversed(O o) noexcept
+{
+ // https://eel.is/c++draft/cmp.partialord#5
+ return is_lt(o) ? O::greater :
+ is_gt(o) ? O::less :
+ /*else*/ o ;
+}
+
+} // namespace QtOrderingPrivate
+
+namespace Qt {
+
+class partial_ordering
+{
+public:
+ static const partial_ordering less;
+ static const partial_ordering equivalent;
+ static const partial_ordering greater;
+ static const partial_ordering unordered;
+
+ friend constexpr bool operator==(partial_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order == 0; }
+
+ friend constexpr bool operator!=(partial_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order != 0; }
+
+ friend constexpr bool operator< (partial_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order < 0; }
+
+ friend constexpr bool operator<=(partial_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order <= 0; }
+
+ friend constexpr bool operator> (partial_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order > 0; }
+
+ friend constexpr bool operator>=(partial_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order >= 0; }
+
+
+ friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
+ partial_ordering rhs) noexcept
+ { return rhs.isOrdered() && 0 == rhs.m_order; }
+
+ friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
+ partial_ordering rhs) noexcept
+ { return rhs.isOrdered() && 0 != rhs.m_order; }
+
+ friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
+ partial_ordering rhs) noexcept
+ { return rhs.isOrdered() && 0 < rhs.m_order; }
+
+ friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
+ partial_ordering rhs) noexcept
+ { return rhs.isOrdered() && 0 <= rhs.m_order; }
+
+ friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
+ partial_ordering rhs) noexcept
+ { return rhs.isOrdered() && 0 > rhs.m_order; }
+
+ friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
+ partial_ordering rhs) noexcept
+ { return rhs.isOrdered() && 0 >= rhs.m_order; }
+
+
+#ifdef __cpp_lib_three_way_comparison
+ friend constexpr std::partial_ordering
+ operator<=>(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
+
+ friend constexpr std::partial_ordering
+ operator<=>(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
+ { return QtOrderingPrivate::reversed(rhs); }
+#endif // __cpp_lib_three_way_comparison
+
+
+ friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
+ { return lhs.m_order == rhs.m_order; }
+
+ friend constexpr bool operator!=(partial_ordering lhs, partial_ordering rhs) noexcept
+ { return lhs.m_order != rhs.m_order; }
+
+#ifdef __cpp_lib_three_way_comparison
+ constexpr Q_IMPLICIT partial_ordering(std::partial_ordering stdorder) noexcept
+ {
+ if (stdorder == std::partial_ordering::less)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
+ else if (stdorder == std::partial_ordering::equivalent)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equivalent);
+ else if (stdorder == std::partial_ordering::greater)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
+ else if (stdorder == std::partial_ordering::unordered)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Uncomparable::Unordered);
+ }
+
+ constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
+ {
+ static_assert(sizeof(*this) == sizeof(std::partial_ordering));
+#ifdef __cpp_lib_bit_cast
+ return std::bit_cast<std::partial_ordering>(*this);
+#else
+ using O = QtPrivate::Ordering;
+ using U = QtPrivate::Uncomparable;
+ using R = std::partial_ordering;
+ switch (m_order) {
+ case qToUnderlying(O::Less): return R::less;
+ case qToUnderlying(O::Greater): return R::greater;
+ case qToUnderlying(O::Equivalent): return R::equivalent;
+ case qToUnderlying(U::Unordered): return R::unordered;
+ }
+ Q_UNREACHABLE_RETURN(R::unordered);
+#endif // __cpp_lib_bit_cast
+ }
+
+ friend constexpr bool operator==(partial_ordering lhs, std::partial_ordering rhs) noexcept
+ { return static_cast<std::partial_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(partial_ordering lhs, std::partial_ordering rhs) noexcept
+ { return static_cast<std::partial_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(std::partial_ordering lhs, partial_ordering rhs) noexcept
+ { return lhs == static_cast<std::partial_ordering>(rhs); }
+
+ friend constexpr bool operator!=(std::partial_ordering lhs, partial_ordering rhs) noexcept
+ { return lhs != static_cast<std::partial_ordering>(rhs); }
+#endif // __cpp_lib_three_way_comparison
+
+private:
+ friend class weak_ordering;
+ friend class strong_ordering;
+
+ constexpr explicit partial_ordering(QtPrivate::Ordering order) noexcept
+ : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
+ {}
+ constexpr explicit partial_ordering(QtPrivate::Uncomparable order) noexcept
+ : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
+ {}
+
+ QT_WARNING_PUSH
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
+ QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
+ friend constexpr bool is_eq (partial_ordering o) noexcept { return o == 0; }
+ friend constexpr bool is_neq (partial_ordering o) noexcept { return o != 0; }
+ friend constexpr bool is_lt (partial_ordering o) noexcept { return o < 0; }
+ friend constexpr bool is_lteq(partial_ordering o) noexcept { return o <= 0; }
+ friend constexpr bool is_gt (partial_ordering o) noexcept { return o > 0; }
+ friend constexpr bool is_gteq(partial_ordering o) noexcept { return o >= 0; }
+ QT_WARNING_POP
+
+ // instead of the exposition only is_ordered member in [cmp.partialord],
+ // use a private function
+ constexpr bool isOrdered() const noexcept
+ { return m_order != static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Uncomparable::Unordered); }
+
+ QtPrivate::CompareUnderlyingType m_order;
+};
+
+inline constexpr partial_ordering partial_ordering::less(QtPrivate::Ordering::Less);
+inline constexpr partial_ordering partial_ordering::equivalent(QtPrivate::Ordering::Equivalent);
+inline constexpr partial_ordering partial_ordering::greater(QtPrivate::Ordering::Greater);
+inline constexpr partial_ordering partial_ordering::unordered(QtPrivate::Uncomparable::Unordered);
+
+class weak_ordering
+{
+public:
+ static const weak_ordering less;
+ static const weak_ordering equivalent;
+ static const weak_ordering greater;
+
+ constexpr Q_IMPLICIT operator partial_ordering() const noexcept
+ { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
+
+ friend constexpr bool operator==(weak_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order == 0; }
+
+ friend constexpr bool operator!=(weak_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order != 0; }
+
+ friend constexpr bool operator< (weak_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order < 0; }
+
+ friend constexpr bool operator<=(weak_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order <= 0; }
+
+ friend constexpr bool operator> (weak_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order > 0; }
+
+ friend constexpr bool operator>=(weak_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order >= 0; }
+
+
+ friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
+ weak_ordering rhs) noexcept
+ { return 0 == rhs.m_order; }
+
+ friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
+ weak_ordering rhs) noexcept
+ { return 0 != rhs.m_order; }
+
+ friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
+ weak_ordering rhs) noexcept
+ { return 0 < rhs.m_order; }
+
+ friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
+ weak_ordering rhs) noexcept
+ { return 0 <= rhs.m_order; }
+
+ friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
+ weak_ordering rhs) noexcept
+ { return 0 > rhs.m_order; }
+
+ friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
+ weak_ordering rhs) noexcept
+ { return 0 >= rhs.m_order; }
+
+
+#ifdef __cpp_lib_three_way_comparison
+ friend constexpr std::weak_ordering
+ operator<=>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs; } // https://eel.is/c++draft/cmp.weakord#5
+
+ friend constexpr std::weak_ordering
+ operator<=>(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
+ { return QtOrderingPrivate::reversed(rhs); }
+#endif // __cpp_lib_three_way_comparison
+
+
+ friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs.m_order == rhs.m_order; }
+
+ friend constexpr bool operator!=(weak_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs.m_order != rhs.m_order; }
+
+ friend constexpr bool operator==(weak_ordering lhs, partial_ordering rhs) noexcept
+ { return static_cast<partial_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(weak_ordering lhs, partial_ordering rhs) noexcept
+ { return static_cast<partial_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(partial_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs == static_cast<partial_ordering>(rhs); }
+
+ friend constexpr bool operator!=(partial_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs != static_cast<partial_ordering>(rhs); }
+
+#ifdef __cpp_lib_three_way_comparison
+ constexpr Q_IMPLICIT weak_ordering(std::weak_ordering stdorder) noexcept
+ {
+ if (stdorder == std::weak_ordering::less)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
+ else if (stdorder == std::weak_ordering::equivalent)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equivalent);
+ else if (stdorder == std::weak_ordering::greater)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
+ }
+
+ constexpr Q_IMPLICIT operator std::weak_ordering() const noexcept
+ {
+ static_assert(sizeof(*this) == sizeof(std::weak_ordering));
+#ifdef __cpp_lib_bit_cast
+ return std::bit_cast<std::weak_ordering>(*this);
+#else
+ using O = QtPrivate::Ordering;
+ using R = std::weak_ordering;
+ switch (m_order) {
+ case qToUnderlying(O::Less): return R::less;
+ case qToUnderlying(O::Greater): return R::greater;
+ case qToUnderlying(O::Equivalent): return R::equivalent;
+ }
+ Q_UNREACHABLE_RETURN(R::equivalent);
+#endif // __cpp_lib_bit_cast
+ }
+
+ friend constexpr bool operator==(weak_ordering lhs, std::weak_ordering rhs) noexcept
+ { return static_cast<std::weak_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(weak_ordering lhs, std::weak_ordering rhs) noexcept
+ { return static_cast<std::weak_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(weak_ordering lhs, std::partial_ordering rhs) noexcept
+ { return static_cast<std::weak_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(weak_ordering lhs, std::partial_ordering rhs) noexcept
+ { return static_cast<std::weak_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(weak_ordering lhs, std::strong_ordering rhs) noexcept
+ { return static_cast<std::weak_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(weak_ordering lhs, std::strong_ordering rhs) noexcept
+ { return static_cast<std::weak_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(std::weak_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs == static_cast<std::weak_ordering>(rhs); }
+
+ friend constexpr bool operator!=(std::weak_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs != static_cast<std::weak_ordering>(rhs); }
+
+ friend constexpr bool operator==(std::partial_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs == static_cast<std::weak_ordering>(rhs); }
+
+ friend constexpr bool operator!=(std::partial_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs != static_cast<std::weak_ordering>(rhs); }
+
+ friend constexpr bool operator==(std::strong_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs == static_cast<std::weak_ordering>(rhs); }
+
+ friend constexpr bool operator!=(std::strong_ordering lhs, weak_ordering rhs) noexcept
+ { return lhs != static_cast<std::weak_ordering>(rhs); }
+#endif // __cpp_lib_three_way_comparison
+
+private:
+ friend class strong_ordering;
+
+ constexpr explicit weak_ordering(QtPrivate::Ordering order) noexcept
+ : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
+ {}
+
+ QT_WARNING_PUSH
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
+ QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
+ friend constexpr bool is_eq (weak_ordering o) noexcept { return o == 0; }
+ friend constexpr bool is_neq (weak_ordering o) noexcept { return o != 0; }
+ friend constexpr bool is_lt (weak_ordering o) noexcept { return o < 0; }
+ friend constexpr bool is_lteq(weak_ordering o) noexcept { return o <= 0; }
+ friend constexpr bool is_gt (weak_ordering o) noexcept { return o > 0; }
+ friend constexpr bool is_gteq(weak_ordering o) noexcept { return o >= 0; }
+ QT_WARNING_POP
+
+ QtPrivate::CompareUnderlyingType m_order;
+};
+
+inline constexpr weak_ordering weak_ordering::less(QtPrivate::Ordering::Less);
+inline constexpr weak_ordering weak_ordering::equivalent(QtPrivate::Ordering::Equivalent);
+inline constexpr weak_ordering weak_ordering::greater(QtPrivate::Ordering::Greater);
+
+class strong_ordering
+{
+public:
+ static const strong_ordering less;
+ static const strong_ordering equivalent;
+ static const strong_ordering equal;
+ static const strong_ordering greater;
+
+ constexpr Q_IMPLICIT operator partial_ordering() const noexcept
+ { return partial_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
+
+ constexpr Q_IMPLICIT operator weak_ordering() const noexcept
+ { return weak_ordering(static_cast<QtPrivate::Ordering>(m_order)); }
+
+ friend constexpr bool operator==(strong_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order == 0; }
+
+ friend constexpr bool operator!=(strong_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order != 0; }
+
+ friend constexpr bool operator< (strong_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order < 0; }
+
+ friend constexpr bool operator<=(strong_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order <= 0; }
+
+ friend constexpr bool operator> (strong_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order > 0; }
+
+ friend constexpr bool operator>=(strong_ordering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.m_order >= 0; }
+
+
+ friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
+ strong_ordering rhs) noexcept
+ { return 0 == rhs.m_order; }
+
+ friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
+ strong_ordering rhs) noexcept
+ { return 0 != rhs.m_order; }
+
+ friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
+ strong_ordering rhs) noexcept
+ { return 0 < rhs.m_order; }
+
+ friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
+ strong_ordering rhs) noexcept
+ { return 0 <= rhs.m_order; }
+
+ friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
+ strong_ordering rhs) noexcept
+ { return 0 > rhs.m_order; }
+
+ friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
+ strong_ordering rhs) noexcept
+ { return 0 >= rhs.m_order; }
+
+
+#ifdef __cpp_lib_three_way_comparison
+ friend constexpr std::strong_ordering
+ operator<=>(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs; } // https://eel.is/c++draft/cmp.strongord#6
+
+ friend constexpr std::strong_ordering
+ operator<=>(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
+ { return QtOrderingPrivate::reversed(rhs); }
+#endif // __cpp_lib_three_way_comparison
+
+
+ friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs.m_order == rhs.m_order; }
+
+ friend constexpr bool operator!=(strong_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs.m_order != rhs.m_order; }
+
+ friend constexpr bool operator==(strong_ordering lhs, partial_ordering rhs) noexcept
+ { return static_cast<partial_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(strong_ordering lhs, partial_ordering rhs) noexcept
+ { return static_cast<partial_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator==(partial_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs == static_cast<partial_ordering>(rhs); }
+
+ friend constexpr bool operator!=(partial_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs != static_cast<partial_ordering>(rhs); }
+
+ friend constexpr bool operator==(strong_ordering lhs, weak_ordering rhs) noexcept
+ { return static_cast<weak_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(strong_ordering lhs, weak_ordering rhs) noexcept
+ { return static_cast<weak_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator==(weak_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs == static_cast<weak_ordering>(rhs); }
+
+ friend constexpr bool operator!=(weak_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs != static_cast<weak_ordering>(rhs); }
+
+#ifdef __cpp_lib_three_way_comparison
+ constexpr Q_IMPLICIT strong_ordering(std::strong_ordering stdorder) noexcept
+ {
+ if (stdorder == std::strong_ordering::less)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
+ else if (stdorder == std::strong_ordering::equivalent)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equivalent);
+ else if (stdorder == std::strong_ordering::equal)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equal);
+ else if (stdorder == std::strong_ordering::greater)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
+ }
+
+ constexpr Q_IMPLICIT operator std::strong_ordering() const noexcept
+ {
+ static_assert(sizeof(*this) == sizeof(std::strong_ordering));
+#ifdef __cpp_lib_bit_cast
+ return std::bit_cast<std::strong_ordering>(*this);
+#else
+ using O = QtPrivate::Ordering;
+ using R = std::strong_ordering;
+ switch (m_order) {
+ case qToUnderlying(O::Less): return R::less;
+ case qToUnderlying(O::Greater): return R::greater;
+ case qToUnderlying(O::Equal): return R::equal;
+ }
+ Q_UNREACHABLE_RETURN(R::equal);
+#endif // __cpp_lib_bit_cast
+ }
+
+ friend constexpr bool operator==(strong_ordering lhs, std::strong_ordering rhs) noexcept
+ { return static_cast<std::strong_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(strong_ordering lhs, std::strong_ordering rhs) noexcept
+ { return static_cast<std::strong_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(strong_ordering lhs, std::partial_ordering rhs) noexcept
+ { return static_cast<std::strong_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(strong_ordering lhs, std::partial_ordering rhs) noexcept
+ { return static_cast<std::strong_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(strong_ordering lhs, std::weak_ordering rhs) noexcept
+ { return static_cast<std::strong_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(strong_ordering lhs, std::weak_ordering rhs) noexcept
+ { return static_cast<std::strong_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(std::strong_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs == static_cast<std::strong_ordering>(rhs); }
+
+ friend constexpr bool operator!=(std::strong_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs != static_cast<std::strong_ordering>(rhs); }
+
+ friend constexpr bool operator==(std::partial_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs == static_cast<std::strong_ordering>(rhs); }
+
+ friend constexpr bool operator!=(std::partial_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs != static_cast<std::strong_ordering>(rhs); }
+
+ friend constexpr bool operator==(std::weak_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs == static_cast<std::strong_ordering>(rhs); }
+
+ friend constexpr bool operator!=(std::weak_ordering lhs, strong_ordering rhs) noexcept
+ { return lhs != static_cast<std::strong_ordering>(rhs); }
+#endif // __cpp_lib_three_way_comparison
+
+ private:
+ constexpr explicit strong_ordering(QtPrivate::Ordering order) noexcept
+ : m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
+ {}
+
+ QT_WARNING_PUSH
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
+ QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
+ friend constexpr bool is_eq (strong_ordering o) noexcept { return o == 0; }
+ friend constexpr bool is_neq (strong_ordering o) noexcept { return o != 0; }
+ friend constexpr bool is_lt (strong_ordering o) noexcept { return o < 0; }
+ friend constexpr bool is_lteq(strong_ordering o) noexcept { return o <= 0; }
+ friend constexpr bool is_gt (strong_ordering o) noexcept { return o > 0; }
+ friend constexpr bool is_gteq(strong_ordering o) noexcept { return o >= 0; }
+ QT_WARNING_POP
+
+ QtPrivate::CompareUnderlyingType m_order;
+};
+
+inline constexpr strong_ordering strong_ordering::less(QtPrivate::Ordering::Less);
+inline constexpr strong_ordering strong_ordering::equivalent(QtPrivate::Ordering::Equivalent);
+inline constexpr strong_ordering strong_ordering::equal(QtPrivate::Ordering::Equal);
+inline constexpr strong_ordering strong_ordering::greater(QtPrivate::Ordering::Greater);
+
+} // namespace Qt
+
+QT_BEGIN_INCLUDE_NAMESPACE
+
+// This is intentionally included after Qt::*_ordering types and before
+// qCompareThreeWay. Do not change!
+#include <QtCore/qcomparehelpers.h>
+
+QT_END_INCLUDE_NAMESPACE
+
+namespace QtPrivate {
+
+namespace CompareThreeWayTester {
+
+ using Qt::compareThreeWay;
+
+ // Check if compareThreeWay is implemented for the (LT, RT) argument
+ // pair.
+ template <typename LT, typename RT, typename = void>
+ constexpr bool hasCompareThreeWay = false;
+
+ template <typename LT, typename RT>
+ constexpr bool hasCompareThreeWay<
+ LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
+ > = true;
+
+ // Check if the operation is noexcept. We have two different overloads,
+ // depending on the available compareThreeWay() implementation.
+ // Both are declared, but not implemented. To be used only in unevaluated
+ // context.
+
+ template <typename LT, typename RT,
+ std::enable_if_t<hasCompareThreeWay<LT, RT>, bool> = true>
+ constexpr bool compareThreeWayNoexcept() noexcept
+ { return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
+
+ template <typename LT, typename RT,
+ std::enable_if_t<!hasCompareThreeWay<LT, RT> && hasCompareThreeWay<RT, LT>,
+ bool> = true>
+ constexpr bool compareThreeWayNoexcept() noexcept
+ { return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }
+
+} // namespace CompareThreeWayTester
+
+} // namespace QtPrivate
+
+#if defined(Q_QDOC)
+
+template <typename LeftType, typename RightType>
+auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
+
+#else
+
+template <typename LT, typename RT,
+ std::enable_if_t<QtPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>
+ || QtPrivate::CompareThreeWayTester::hasCompareThreeWay<RT, LT>,
+ bool> = true>
+auto qCompareThreeWay(const LT &lhs, const RT &rhs)
+ noexcept(QtPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
+{
+ using Qt::compareThreeWay;
+ if constexpr (QtPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>) {
+ return compareThreeWay(lhs, rhs);
+ } else {
+ const auto retval = compareThreeWay(rhs, lhs);
+ return QtOrderingPrivate::reversed(retval);
+ }
+}
+
+#endif // defined(Q_QDOC)
+
+//
+// Legacy QPartialOrdering
+//
+
+namespace QtPrivate {
+enum class LegacyUncomparable : CompareUnderlyingType
+{
+ Unordered = -127
+};
+}
+
// [cmp.partialord]
class QPartialOrdering
{
@@ -77,49 +683,195 @@ public:
static const QPartialOrdering Greater;
static const QPartialOrdering Unordered;
- friend constexpr bool operator==(QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- { return p.isOrdered() && p.m_order == 0; }
- friend constexpr bool operator!=(QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- { return p.isOrdered() && p.m_order != 0; }
- friend constexpr bool operator< (QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- { return p.isOrdered() && p.m_order < 0; }
- friend constexpr bool operator<=(QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- { return p.isOrdered() && p.m_order <= 0; }
- friend constexpr bool operator> (QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- { return p.isOrdered() && p.m_order > 0; }
- friend constexpr bool operator>=(QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- { return p.isOrdered() && p.m_order >= 0; }
-
- friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- { return p.isOrdered() && 0 == p.m_order; }
- friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- { return p.isOrdered() && 0 != p.m_order; }
- friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- { return p.isOrdered() && 0 < p.m_order; }
- friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- { return p.isOrdered() && 0 <= p.m_order; }
- friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- { return p.isOrdered() && 0 > p.m_order; }
- friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- { return p.isOrdered() && 0 >= p.m_order; }
-
- friend constexpr bool operator==(QPartialOrdering p1, QPartialOrdering p2) noexcept
- { return p1.m_order == p2.m_order; }
- friend constexpr bool operator!=(QPartialOrdering p1, QPartialOrdering p2) noexcept
- { return p1.m_order != p2.m_order; }
+ static const QPartialOrdering less;
+ static const QPartialOrdering equivalent;
+ static const QPartialOrdering greater;
+ static const QPartialOrdering unordered;
+
+ friend constexpr bool operator==(QPartialOrdering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order == 0; }
+
+ friend constexpr bool operator!=(QPartialOrdering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order != 0; }
+
+ friend constexpr bool operator< (QPartialOrdering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order < 0; }
+
+ friend constexpr bool operator<=(QPartialOrdering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order <= 0; }
+
+ friend constexpr bool operator> (QPartialOrdering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order > 0; }
+
+ friend constexpr bool operator>=(QPartialOrdering lhs,
+ QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs.isOrdered() && lhs.m_order >= 0; }
+
+
+ friend constexpr bool operator==(QtPrivate::CompareAgainstLiteralZero,
+ QPartialOrdering rhs) noexcept
+ { return rhs.isOrdered() && 0 == rhs.m_order; }
+
+ friend constexpr bool operator!=(QtPrivate::CompareAgainstLiteralZero,
+ QPartialOrdering rhs) noexcept
+ { return rhs.isOrdered() && 0 != rhs.m_order; }
+
+ friend constexpr bool operator< (QtPrivate::CompareAgainstLiteralZero,
+ QPartialOrdering rhs) noexcept
+ { return rhs.isOrdered() && 0 < rhs.m_order; }
+
+ friend constexpr bool operator<=(QtPrivate::CompareAgainstLiteralZero,
+ QPartialOrdering rhs) noexcept
+ { return rhs.isOrdered() && 0 <= rhs.m_order; }
+
+ friend constexpr bool operator> (QtPrivate::CompareAgainstLiteralZero,
+ QPartialOrdering rhs) noexcept
+ { return rhs.isOrdered() && 0 > rhs.m_order; }
+
+ friend constexpr bool operator>=(QtPrivate::CompareAgainstLiteralZero,
+ QPartialOrdering rhs) noexcept
+ { return rhs.isOrdered() && 0 >= rhs.m_order; }
+
+
+#ifdef __cpp_lib_three_way_comparison
+ friend constexpr std::partial_ordering
+ operator<=>(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
+ { return lhs; } // https://eel.is/c++draft/cmp.partialord#4
+
+ friend constexpr std::partial_ordering
+ operator<=>(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
+ { return QtOrderingPrivate::reversed(rhs); }
+#endif // __cpp_lib_three_way_comparison
+
+
+ friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
+ { return lhs.m_order == rhs.m_order; }
+
+ friend constexpr bool operator!=(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
+ { return lhs.m_order != rhs.m_order; }
+
+ constexpr Q_IMPLICIT QPartialOrdering(Qt::partial_ordering order) noexcept
+ : m_order{} // == equivalent
+ {
+ if (order == Qt::partial_ordering::less)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
+ else if (order == Qt::partial_ordering::greater)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
+ else if (order == Qt::partial_ordering::unordered)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered);
+ }
+
+ constexpr Q_IMPLICIT QPartialOrdering(Qt::weak_ordering stdorder) noexcept
+ : QPartialOrdering(Qt::partial_ordering{stdorder}) {}
+
+ constexpr Q_IMPLICIT QPartialOrdering(Qt::strong_ordering stdorder) noexcept
+ : QPartialOrdering(Qt::partial_ordering{stdorder}) {}
+
+ constexpr Q_IMPLICIT operator Qt::partial_ordering() const noexcept
+ {
+ using O = QtPrivate::Ordering;
+ using U = QtPrivate::LegacyUncomparable;
+ using R = Qt::partial_ordering;
+ switch (m_order) {
+ case qToUnderlying(O::Less): return R::less;
+ case qToUnderlying(O::Greater): return R::greater;
+ case qToUnderlying(O::Equivalent): return R::equivalent;
+ case qToUnderlying(U::Unordered): return R::unordered;
+ }
+ // GCC 8.x does not treat __builtin_unreachable() as constexpr
+#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
+ // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
+ Q_UNREACHABLE();
+#endif
+ return R::unordered;
+ }
+
+ friend constexpr bool operator==(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
+ { Qt::partial_ordering qt = lhs; return qt == rhs; }
+
+ friend constexpr bool operator!=(QPartialOrdering lhs, Qt::partial_ordering rhs) noexcept
+ { Qt::partial_ordering qt = lhs; return qt != rhs; }
+
+ friend constexpr bool operator==(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
+ { Qt::partial_ordering qt = rhs; return lhs == qt; }
+
+ friend constexpr bool operator!=(Qt::partial_ordering lhs, QPartialOrdering rhs) noexcept
+ { Qt::partial_ordering qt = rhs; return lhs != qt; }
+
+#ifdef __cpp_lib_three_way_comparison
+ constexpr Q_IMPLICIT QPartialOrdering(std::partial_ordering stdorder) noexcept
+ {
+ if (stdorder == std::partial_ordering::less)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Less);
+ else if (stdorder == std::partial_ordering::equivalent)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Equivalent);
+ else if (stdorder == std::partial_ordering::greater)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Ordering::Greater);
+ else if (stdorder == std::partial_ordering::unordered)
+ m_order = static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered);
+ }
+
+ constexpr Q_IMPLICIT QPartialOrdering(std::weak_ordering stdorder) noexcept
+ : QPartialOrdering(std::partial_ordering(stdorder)) {}
+
+ constexpr Q_IMPLICIT QPartialOrdering(std::strong_ordering stdorder) noexcept
+ : QPartialOrdering(std::partial_ordering(stdorder)) {}
+
+ constexpr Q_IMPLICIT operator std::partial_ordering() const noexcept
+ {
+ using O = QtPrivate::Ordering;
+ using U = QtPrivate::LegacyUncomparable;
+ using R = std::partial_ordering;
+ switch (m_order) {
+ case qToUnderlying(O::Less): return R::less;
+ case qToUnderlying(O::Greater): return R::greater;
+ case qToUnderlying(O::Equivalent): return R::equivalent;
+ case qToUnderlying(U::Unordered): return R::unordered;
+ }
+ Q_UNREACHABLE_RETURN(R::unordered);
+ }
+
+ friend constexpr bool operator==(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
+ { return static_cast<std::partial_ordering>(lhs) == rhs; }
+
+ friend constexpr bool operator!=(QPartialOrdering lhs, std::partial_ordering rhs) noexcept
+ { return static_cast<std::partial_ordering>(lhs) != rhs; }
+
+ friend constexpr bool operator==(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
+ { return lhs == static_cast<std::partial_ordering>(rhs); }
+
+ friend constexpr bool operator!=(std::partial_ordering lhs, QPartialOrdering rhs) noexcept
+ { return lhs != static_cast<std::partial_ordering>(rhs); }
+#endif // __cpp_lib_three_way_comparison
private:
constexpr explicit QPartialOrdering(QtPrivate::Ordering order) noexcept
: m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
{}
- constexpr explicit QPartialOrdering(QtPrivate::Uncomparable order) noexcept
+ constexpr explicit QPartialOrdering(QtPrivate::LegacyUncomparable order) noexcept
: m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
{}
+ QT_WARNING_PUSH
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
+ QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
+ friend constexpr bool is_eq (QPartialOrdering o) noexcept { return o == 0; }
+ friend constexpr bool is_neq (QPartialOrdering o) noexcept { return o != 0; }
+ friend constexpr bool is_lt (QPartialOrdering o) noexcept { return o < 0; }
+ friend constexpr bool is_lteq(QPartialOrdering o) noexcept { return o <= 0; }
+ friend constexpr bool is_gt (QPartialOrdering o) noexcept { return o > 0; }
+ friend constexpr bool is_gteq(QPartialOrdering o) noexcept { return o >= 0; }
+ QT_WARNING_POP
+
// instead of the exposition only is_ordered member in [cmp.partialord],
// use a private function
- constexpr bool isOrdered() noexcept
- { return m_order != static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::Uncomparable::Unordered); }
+ constexpr bool isOrdered() const noexcept
+ { return m_order != static_cast<QtPrivate::CompareUnderlyingType>(QtPrivate::LegacyUncomparable::Unordered); }
QtPrivate::CompareUnderlyingType m_order;
};
@@ -127,7 +879,12 @@ private:
inline constexpr QPartialOrdering QPartialOrdering::Less(QtPrivate::Ordering::Less);
inline constexpr QPartialOrdering QPartialOrdering::Equivalent(QtPrivate::Ordering::Equivalent);
inline constexpr QPartialOrdering QPartialOrdering::Greater(QtPrivate::Ordering::Greater);
-inline constexpr QPartialOrdering QPartialOrdering::Unordered(QtPrivate::Uncomparable::Unordered);
+inline constexpr QPartialOrdering QPartialOrdering::Unordered(QtPrivate::LegacyUncomparable::Unordered);
+
+inline constexpr QPartialOrdering QPartialOrdering::less(QtPrivate::Ordering::Less);
+inline constexpr QPartialOrdering QPartialOrdering::equivalent(QtPrivate::Ordering::Equivalent);
+inline constexpr QPartialOrdering QPartialOrdering::greater(QtPrivate::Ordering::Greater);
+inline constexpr QPartialOrdering QPartialOrdering::unordered(QtPrivate::LegacyUncomparable::Unordered);
QT_END_NAMESPACE
diff --git a/src/corelib/global/qcompare.qdoc b/src/corelib/global/qcompare.qdoc
deleted file mode 100644
index 795e908ecf..0000000000
--- a/src/corelib/global/qcompare.qdoc
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: http://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$
-**
-****************************************************************************/
-
-/*!
- \class QPartialOrdering
- \inmodule QtCore
- \brief QPartialOrdering represents the result of a comparison that allows for unordered results.
- \since 6.0
-
- A value of type QPartialOrdering is typically returned from a
- three-way comparison function. Such a function compares two
- objects, and it may either establish that the two objects are
- ordered relative to each other, or that they are not ordered. The
- QPartialOrdering value returned from the comparison function
- represents one of those possibilities.
-
- The possible values of type QPartialOrdering are, in fact, fully
- represented by the following four static values:
-
- \list
-
- \li \c QPartialOrdering::Less represents that the first object is
- less than the second;
-
- \li \c QPartialOrdering::Equivalent represents that the first
- object is equivalent to the second;
-
- \li \c QPartialOrdering::Greater represents that the first object
- is equivalent to the second;
-
- \li \c QPartialOrdering::Unordered represents that the first object
- is \e{not ordered} with respect to the second.
-
- \endlist
-
- QPartialOrdering is idiomatically used by comparing an instance
- against a literal zero, for instance like this:
-
- \code
-
- // given a, b, c, d as objects of some type that allows for a 3-way compare
-
- QPartialOrdering result = a.compare(b);
- if (result < 0) {
- // a is less than b
- }
-
- if (c.compare(d) >= 0) {
- // c is greater than or equal to d
- }
-
- \endcode
-
- A QPartialOrdering value which represents an unordered result will
- always return false when compared against literal 0.
-*/
-
-/*!
- \fn bool QPartialOrdering::operator==(QPartialOrdering p1, QPartialOrdering p2) noexcept
-
- Return true if \a p1 and \a p2 represent the same result;
- otherwise, returns false.
-*/
-
-/*!
- \fn bool QPartialOrdering::operator!=(QPartialOrdering p1, QPartialOrdering p2) noexcept
-
- Return true if \a p1 and \a p2 represent different results;
- otherwise, returns true.
-*/
-
-/*!
- \fn bool operator==(QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- \fn bool operator!=(QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- \fn bool operator< (QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- \fn bool operator<=(QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- \fn bool operator> (QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
- \fn bool operator>=(QPartialOrdering p, QtPrivate::CompareAgainstLiteralZero) noexcept
-
- \fn bool operator==(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- \fn bool operator!=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- \fn bool operator< (QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- \fn bool operator<=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- \fn bool operator> (QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- \fn bool operator>=(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering p) noexcept
- \relates QPartialOrdering
- \internal
-*/
-
-/*!
- \variable QPartialOrdering::Less
- Represents the result of a comparison where the value on the left
- hand side is less than the value on right hand side.
-*/
-
-/*!
- \variable QPartialOrdering::Equivalent
- Represents the result of a comparison where the value on the left
- hand side is equivalent to the value on right hand side.
-*/
-
-/*!
- \variable QPartialOrdering::Greater
- Represents the result of a comparison where the value on the left
- hand side is greater than the value on right hand side.
-*/
-
-/*!
- \variable QPartialOrdering::Unordered
- Represents the result of a comparison where the value on the left
- hand side is not ordered with respect to the value on right hand
- side.
-*/
diff --git a/src/corelib/global/qcompare_impl.h b/src/corelib/global/qcompare_impl.h
index 520922284e..c52417fcec 100644
--- a/src/corelib/global/qcompare_impl.h
+++ b/src/corelib/global/qcompare_impl.h
@@ -1,51 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QCOMPARE_IMPL_H
+#define QCOMPARE_IMPL_H
#if 0
#pragma qt_sync_skip_header_check
#pragma qt_sync_stop_processing
#endif
-#ifndef QCOMPARE_IMPL_H
-#define QCOMPARE_IMPL_H
-
-#include <QtCore/qglobal.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qcompilerdetection.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +23,7 @@ public:
using SafeZero = void (CompareAgainstLiteralZero::*)();
Q_IMPLICIT constexpr CompareAgainstLiteralZero(SafeZero) noexcept {}
- template <typename T, std::enable_if_t<!std::is_same_v<T, int>, bool> = false>
+ template <typename T, std::enable_if_t<std::is_null_pointer_v<T>, bool> = true>
CompareAgainstLiteralZero(T) = delete;
};
diff --git a/src/corelib/global/qcomparehelpers.h b/src/corelib/global/qcomparehelpers.h
new file mode 100644
index 0000000000..0e43ac296b
--- /dev/null
+++ b/src/corelib/global/qcomparehelpers.h
@@ -0,0 +1,567 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QCOMPARE_H
+#error "Do not include qcomparehelpers.h directly. Use qcompare.h instead."
+#endif
+
+#ifndef QCOMPAREHELPERS_H
+#define QCOMPAREHELPERS_H
+
+#if 0
+#pragma qt_no_master_include
+#pragma qt_sync_skip_header_check
+#pragma qt_sync_stop_processing
+#endif
+
+#include <QtCore/qoverload.h>
+#include <QtCore/qttypetraits.h>
+#include <QtCore/qtypes.h>
+
+#ifdef __cpp_lib_three_way_comparison
+#include <compare>
+#endif
+#include <QtCore/q20type_traits.h>
+
+#include <functional> // std::less
+
+QT_BEGIN_NAMESPACE
+
+class QPartialOrdering;
+
+namespace QtOrderingPrivate {
+#ifdef __cpp_lib_three_way_comparison
+
+template <typename QtOrdering> struct StdOrdering;
+template <typename StdOrdering> struct QtOrdering;
+
+#define QT_STD_MAP(x) \
+ template <> struct StdOrdering< Qt::x##_ordering> : q20::type_identity<std::x##_ordering> {};\
+ template <> struct StdOrdering<std::x##_ordering> : q20::type_identity<std::x##_ordering> {};\
+ template <> struct QtOrdering<std::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};\
+ template <> struct QtOrdering< Qt::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};\
+ /* end */
+QT_STD_MAP(partial)
+QT_STD_MAP(weak)
+QT_STD_MAP(strong)
+#undef QT_STD_MAP
+
+template <> struct StdOrdering<QPartialOrdering> : q20::type_identity<std::partial_ordering> {};
+template <> struct QtOrdering<QPartialOrdering> : q20::type_identity< Qt::partial_ordering> {};
+
+template <typename In> constexpr auto to_std(In in) noexcept
+ -> typename QtOrderingPrivate::StdOrdering<In>::type
+{ return in; }
+
+template <typename In> constexpr auto to_Qt(In in) noexcept
+ -> typename QtOrderingPrivate::QtOrdering<In>::type
+{ return in; }
+
+#endif // __cpp_lib_three_way_comparison
+} // namespace QtOrderingPrivate
+
+/*
+ For all the macros these parameter names are used:
+ * LeftType - the type of the left operand of the comparison
+ * RightType - the type of the right operand of the comparison
+ * Constexpr - must be either constexpr or empty. Defines whether the
+ operator is constexpr or not
+ * Attributes - an optional list of attributes. For example, pass
+ \c QT_ASCII_CAST_WARN when defining comparisons between
+ C-style string and an encoding-aware string type.
+
+ The macros require two helper functions. For operators to be constexpr,
+ these must be constexpr, too. Additionally, other attributes (like
+ Q_<Module>_EXPORT, Q_DECL_CONST_FUNCTION, etc) can be applied to them.
+ Aside from that, their declaration should match:
+ bool comparesEqual(LeftType, RightType) noexcept;
+ ReturnType compareThreeWay(LeftType, RightType) noexcept;
+
+ The ReturnType can be one of Qt::{partial,weak,strong}_ordering. The actual
+ type depends on the macro being used.
+ It makes sense to define the helper functions as hidden friends of the
+ class, so that they could be found via ADL, and don't participate in
+ unintended implicit conversions.
+*/
+
+// Seems that qdoc uses C++20 even when Qt is compiled in C++17 mode.
+// Or at least it defines __cpp_lib_three_way_comparison.
+// Let qdoc see only the C++17 operators for now, because that's what our docs
+// currently describe.
+#if defined(__cpp_lib_three_way_comparison) && !defined(Q_QDOC)
+// C++20 - provide operator==() for equality, and operator<=>() for ordering
+
+#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(comparesEqual(lhs, rhs))) \
+ { return comparesEqual(lhs, rhs); }
+
+#define QT_DECLARE_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr std::strong_ordering \
+ operator<=>(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(compareThreeWay(lhs, rhs))) \
+ { \
+ return compareThreeWay(lhs, rhs); \
+ }
+
+#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr std::weak_ordering \
+ operator<=>(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(compareThreeWay(lhs, rhs))) \
+ { \
+ return compareThreeWay(lhs, rhs); \
+ }
+
+#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr std::partial_ordering \
+ operator<=>(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(compareThreeWay(lhs, rhs))) \
+ { \
+ return compareThreeWay(lhs, rhs); \
+ }
+
+#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingType, LeftType, RightType, Constexpr, \
+ Attributes) \
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_3WAY_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Attributes)
+
+#ifdef Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
+
+// define reversed versions of the operators manually, because buggy MSVC versions do not do it
+#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(comparesEqual(rhs, lhs))) \
+ { return comparesEqual(rhs, lhs); }
+
+#define QT_DECLARE_REVERSED_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr std::strong_ordering \
+ operator<=>(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(compareThreeWay(rhs, lhs))) \
+ { \
+ const auto r = compareThreeWay(rhs, lhs); \
+ if (r > 0) return std::strong_ordering::less; \
+ if (r < 0) return std::strong_ordering::greater; \
+ return r; \
+ }
+
+#define QT_DECLARE_REVERSED_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr std::weak_ordering \
+ operator<=>(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(compareThreeWay(rhs, lhs))) \
+ { \
+ const auto r = compareThreeWay(rhs, lhs); \
+ if (r > 0) return std::weak_ordering::less; \
+ if (r < 0) return std::weak_ordering::greater; \
+ return r; \
+ }
+
+#define QT_DECLARE_REVERSED_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr std::partial_ordering \
+ operator<=>(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(compareThreeWay(rhs, lhs))) \
+ { \
+ const auto r = compareThreeWay(rhs, lhs); \
+ if (r > 0) return std::partial_ordering::less; \
+ if (r < 0) return std::partial_ordering::greater; \
+ return r; \
+ }
+
+#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
+ Constexpr, Attributes) \
+ QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_REVERSED_3WAY_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Attributes)
+
+#else
+
+// dummy macros for C++17 compatibility, reversed operators are generated by the compiler
+#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes)
+#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
+ Constexpr, Attributes)
+
+#endif // Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
+
+#else
+// C++17 - provide operator==() and operator!=() for equality,
+// and all 4 comparison operators for ordering
+
+#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(comparesEqual(lhs, rhs))) \
+ { return comparesEqual(lhs, rhs); } \
+ Attributes \
+ friend Constexpr bool operator!=(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(comparesEqual(lhs, rhs))) \
+ { return !comparesEqual(lhs, rhs); }
+
+// Helpers for reversed comparison, using the existing comparesEqual() function.
+#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
+ Attributes \
+ friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(comparesEqual(rhs, lhs))) \
+ { return comparesEqual(rhs, lhs); } \
+ Attributes \
+ friend Constexpr bool operator!=(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(comparesEqual(rhs, lhs))) \
+ { return !comparesEqual(rhs, lhs); }
+
+#define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
+ Attributes) \
+ Attributes \
+ friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(compareThreeWay(lhs, rhs))) \
+ { return compareThreeWay(lhs, rhs) < 0; } \
+ Attributes \
+ friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(compareThreeWay(lhs, rhs))) \
+ { return compareThreeWay(lhs, rhs) > 0; } \
+ Attributes \
+ friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(compareThreeWay(lhs, rhs))) \
+ { return compareThreeWay(lhs, rhs) <= 0; } \
+ Attributes \
+ friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) \
+ noexcept(noexcept(compareThreeWay(lhs, rhs))) \
+ { return compareThreeWay(lhs, rhs) >= 0; }
+
+#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr, \
+ Attributes)
+
+#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr, \
+ Attributes)
+
+#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr, \
+ Attributes)
+
+#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr, \
+ Attributes) \
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Attributes)
+
+// Helpers for reversed ordering, using the existing compareThreeWay() function.
+#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
+ Attributes) \
+ Attributes \
+ friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(compareThreeWay(rhs, lhs))) \
+ { return compareThreeWay(rhs, lhs) > 0; } \
+ Attributes \
+ friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(compareThreeWay(rhs, lhs))) \
+ { return compareThreeWay(rhs, lhs) < 0; } \
+ Attributes \
+ friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(compareThreeWay(rhs, lhs))) \
+ { return compareThreeWay(rhs, lhs) >= 0; } \
+ Attributes \
+ friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) \
+ noexcept(noexcept(compareThreeWay(rhs, lhs))) \
+ { return compareThreeWay(rhs, lhs) <= 0; }
+
+#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, \
+ Constexpr, Attributes)
+
+#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, \
+ Constexpr, Attributes)
+
+#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, \
+ Constexpr, Attributes)
+
+#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
+ Constexpr, Attributes) \
+ QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
+ QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
+ Attributes)
+
+#endif // __cpp_lib_three_way_comparison
+
+/* Public API starts here */
+
+// Equality operators
+#define QT_DECLARE_EQUALITY_COMPARABLE_1(Type) \
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, /* non-constexpr */, /* no attributes */)
+
+#define QT_DECLARE_EQUALITY_COMPARABLE_2(LeftType, RightType) \
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
+ /* no attributes */) \
+ QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
+ /* no attributes */)
+
+#define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType, Attributes) \
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, Attributes) \
+ QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
+ Attributes)
+
+#define Q_DECLARE_EQUALITY_COMPARABLE(...) \
+ QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE, __VA_ARGS__)
+
+#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_1(Type) \
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, constexpr, /* no attributes */)
+
+#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_2(LeftType, RightType) \
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, /* no attributes */) \
+ QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, \
+ /* no attributes */)
+
+#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, Attributes) \
+ QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, Attributes)
+
+#define Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(...) \
+ QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE, __VA_ARGS__)
+
+// Partial ordering operators
+#define QT_DECLARE_PARTIALLY_ORDERED_1(Type) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, /* non-constexpr */, \
+ /* no attributes */)
+
+#define QT_DECLARE_PARTIALLY_ORDERED_2(LeftType, RightType) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
+ /* no attributes */) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
+ /* non-constexpr */, /* no attributes */)
+
+#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
+ Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
+ /* non-constexpr */, Attributes)
+
+#define Q_DECLARE_PARTIALLY_ORDERED(...) \
+ QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED, __VA_ARGS__)
+
+#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_1(Type) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, constexpr, /* no attributes */)
+
+#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, \
+ /* no attributes */) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
+ /* no attributes */)
+
+#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
+ Attributes)
+
+#define Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(...) \
+ QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
+
+// Weak ordering operators
+#define QT_DECLARE_WEAKLY_ORDERED_1(Type) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */, /* no attributes */)
+
+#define QT_DECLARE_WEAKLY_ORDERED_2(LeftType, RightType) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
+ /* no attributes */) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
+ /* no attributes */)
+
+#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
+ Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
+ Attributes)
+
+#define Q_DECLARE_WEAKLY_ORDERED(...) \
+ QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED, __VA_ARGS__)
+
+#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_1(Type) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, constexpr, /* no attributes */)
+
+#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, \
+ /* no attributes */) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
+ /* no attributes */)
+
+#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
+QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
+ Attributes)
+
+#define Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(...) \
+ QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
+
+// Strong ordering operators
+#define QT_DECLARE_STRONGLY_ORDERED_1(Type) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, /* non-constexpr */, \
+ /* no attributes */)
+
+#define QT_DECLARE_STRONGLY_ORDERED_2(LeftType, RightType) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
+ /* no attributes */) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
+ /* non-constexpr */, /* no attributes */)
+
+#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
+ Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
+ /* non-constexpr */, Attributes)
+
+#define Q_DECLARE_STRONGLY_ORDERED(...) \
+ QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED, __VA_ARGS__)
+
+#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_1(Type) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, constexpr, /* no attributes */)
+
+#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, \
+ /* no attributes */) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
+ /* no attributes */)
+
+#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, Attributes) \
+ QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
+ Attributes)
+
+#define Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(...) \
+ QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
+
+namespace QtPrivate {
+
+template <typename T>
+constexpr bool IsIntegralType_v = std::numeric_limits<std::remove_const_t<T>>::is_specialized
+ && std::numeric_limits<std::remove_const_t<T>>::is_integer;
+
+template <typename T>
+constexpr bool IsFloatType_v = std::is_floating_point_v<T>;
+
+#if QFLOAT16_IS_NATIVE
+template <>
+constexpr bool IsFloatType_v<QtPrivate::NativeFloat16Type> = true;
+#endif
+
+} // namespace QtPrivate
+
+namespace Qt {
+
+template <typename T>
+using if_integral = std::enable_if_t<QtPrivate::IsIntegralType_v<T>, bool>;
+
+template <typename T>
+using if_floating_point = std::enable_if_t<QtPrivate::IsFloatType_v<T>, bool>;
+
+template <typename T, typename U>
+using if_compatible_pointers =
+ std::enable_if_t<std::disjunction_v<std::is_same<T, U>,
+ std::is_base_of<T, U>,
+ std::is_base_of<U, T>>,
+ bool>;
+
+template <typename Enum>
+using if_enum = std::enable_if_t<std::is_enum_v<Enum>, bool>;
+
+template <typename LeftInt, typename RightInt,
+ if_integral<LeftInt> = true,
+ if_integral<RightInt> = true>
+constexpr Qt::strong_ordering compareThreeWay(LeftInt lhs, RightInt rhs) noexcept
+{
+ static_assert(std::is_signed_v<LeftInt> == std::is_signed_v<RightInt>,
+ "Qt::compareThreeWay() does not allow mixed-sign comparison.");
+
+#ifdef __cpp_lib_three_way_comparison
+ return lhs <=> rhs;
+#else
+ if (lhs == rhs)
+ return Qt::strong_ordering::equivalent;
+ else if (lhs < rhs)
+ return Qt::strong_ordering::less;
+ else
+ return Qt::strong_ordering::greater;
+#endif // __cpp_lib_three_way_comparison
+}
+
+template <typename LeftFloat, typename RightFloat,
+ if_floating_point<LeftFloat> = true,
+ if_floating_point<RightFloat> = true>
+constexpr Qt::partial_ordering compareThreeWay(LeftFloat lhs, RightFloat rhs) noexcept
+{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_FLOAT_COMPARE
+#ifdef __cpp_lib_three_way_comparison
+ return lhs <=> rhs;
+#else
+ if (lhs < rhs)
+ return Qt::partial_ordering::less;
+ else if (lhs > rhs)
+ return Qt::partial_ordering::greater;
+ else if (lhs == rhs)
+ return Qt::partial_ordering::equivalent;
+ else
+ return Qt::partial_ordering::unordered;
+#endif // __cpp_lib_three_way_comparison
+QT_WARNING_POP
+}
+
+template <typename IntType, typename FloatType,
+ if_integral<IntType> = true,
+ if_floating_point<FloatType> = true>
+constexpr Qt::partial_ordering compareThreeWay(IntType lhs, FloatType rhs) noexcept
+{
+ return compareThreeWay(FloatType(lhs), rhs);
+}
+
+template <typename FloatType, typename IntType,
+ if_floating_point<FloatType> = true,
+ if_integral<IntType> = true>
+constexpr Qt::partial_ordering compareThreeWay(FloatType lhs, IntType rhs) noexcept
+{
+ return compareThreeWay(lhs, FloatType(rhs));
+}
+
+template <typename LeftType, typename RightType,
+ if_compatible_pointers<LeftType, RightType> = true>
+constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightType *rhs) noexcept
+{
+#ifdef __cpp_lib_three_way_comparison
+ return std::compare_three_way{}(lhs, rhs);
+#else
+ if (lhs == rhs)
+ return Qt::strong_ordering::equivalent;
+ else if (std::less<>{}(lhs, rhs))
+ return Qt::strong_ordering::less;
+ else
+ return Qt::strong_ordering::greater;
+#endif // __cpp_lib_three_way_comparison
+}
+
+template <typename T>
+constexpr Qt::strong_ordering compareThreeWay(const T *lhs, std::nullptr_t rhs) noexcept
+{
+ return compareThreeWay(lhs, static_cast<const T *>(rhs));
+}
+
+template <typename T>
+constexpr Qt::strong_ordering compareThreeWay(std::nullptr_t lhs, const T *rhs) noexcept
+{
+ return compareThreeWay(static_cast<const T *>(lhs), rhs);
+}
+
+template <class Enum, if_enum<Enum> = true>
+constexpr Qt::strong_ordering compareThreeWay(Enum lhs, Enum rhs) noexcept
+{
+ return compareThreeWay(qToUnderlying(lhs), qToUnderlying(rhs));
+}
+
+} // namespace Qt
+
+QT_END_NAMESPACE
+
+#endif // QCOMPAREHELPERS_H
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 584f1f79b9..673f1c795b 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -1,53 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLOBAL_H
-# include <QtCore/qglobal.h>
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtCore/qsystemdetection.h>
+
+#if 0
+#pragma qt_class(QtCompilerDetection)
+#pragma qt_sync_skip_header_check
+#pragma qt_sync_stop_processing
#endif
#ifndef QCOMPILERDETECTION_H
#define QCOMPILERDETECTION_H
+#include <QtCore/qprocessordetection.h>
+#include <QtCore/qtconfiginclude.h>
+
/*
The compiler, must be one of: (Q_CC_x)
+ COVERITY - Coverity cov-scan
SYM - Digital Mars C/C++ (used to be Symantec C++)
MSVC - Microsoft Visual C/C++, Intel C++ for Windows
BOR - Borland/Turbo C++
@@ -74,6 +46,11 @@
Should be sorted most to least authoritative.
*/
+#if defined(__COVERITY__)
+# define Q_CC_COVERITY
+# define Q_COMPILER_COMPLAINS_ABOUT_RETURN_AFTER_UNREACHABLE
+#endif
+
/* Symantec C++ is now Digital Mars */
#if defined(__DMC__) || defined(__SC__)
# define Q_CC_SYM
@@ -83,30 +60,26 @@
# endif
#elif defined(_MSC_VER)
+# define Q_CC_MSVC (_MSC_VER)
+# define Q_CC_MSVC_NET
+# define Q_CC_MSVC_ONLY Q_CC_MSVC
# ifdef __clang__
+# undef Q_CC_MSVC_ONLY
# define Q_CC_CLANG ((__clang_major__ * 100) + __clang_minor__)
+# define Q_CC_CLANG_ONLY Q_CC_CLANG
# endif
-# define Q_CC_MSVC (_MSC_VER)
-# define Q_CC_MSVC_NET
# define Q_OUTOFLINE_TEMPLATE inline
# define Q_COMPILER_MANGLES_RETURN_TYPE
+# define Q_COMPILER_MANGLES_ACCESS_SPECIFIER
# define Q_FUNC_INFO __FUNCSIG__
# define Q_ASSUME_IMPL(expr) __assume(expr)
# define Q_UNREACHABLE_IMPL() __assume(0)
-# define Q_NORETURN __declspec(noreturn)
-# define Q_DECL_DEPRECATED __declspec(deprecated)
-# ifndef Q_CC_CLANG
-# define Q_DECL_DEPRECATED_X(text) __declspec(deprecated(text))
-# endif
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
-# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) stdext::make_unchecked_array_iterator(x) // Since _MSC_VER >= 1800
-# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N)) // Since _MSC_VER >= 1500
-/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
-# if defined(__INTEL_COMPILER)
-# define Q_DECL_VARIABLE_DEPRECATED
-# define Q_CC_INTEL __INTEL_COMPILER
+# if _MSC_VER < 1938 // stdext is deprecated since VS 2022 17.8
+# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N)) // Since _MSC_VER >= 1500
# endif
+# define Q_COMPILER_COMPLAINS_ABOUT_RETURN_AFTER_UNREACHABLE
#elif defined(__BORLANDC__) || defined(__TURBOC__)
# define Q_CC_BOR
@@ -141,46 +114,39 @@
# if defined(__MINGW32__)
# define Q_CC_MINGW
# endif
-# if defined(__INTEL_COMPILER)
-/* Intel C++ also masquerades as GCC */
-# define Q_CC_INTEL (__INTEL_COMPILER)
-# ifdef __clang__
-/* Intel C++ masquerades as Clang masquerading as GCC */
-# define Q_CC_CLANG 305
-# endif
-# define Q_ASSUME_IMPL(expr) __assume(expr)
-# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
-# if __INTEL_COMPILER >= 1300 && !defined(__APPLE__)
-# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
-# endif
-# elif defined(__clang__)
+# if defined(__clang__)
/* Clang also masquerades as GCC */
# if defined(__apple_build_version__)
-# /* http://en.wikipedia.org/wiki/Xcode#Toolchain_Versions */
-# if __apple_build_version__ >= 8020041
-# define Q_CC_CLANG 309
-# elif __apple_build_version__ >= 8000038
-# define Q_CC_CLANG 308
-# elif __apple_build_version__ >= 7000053
-# define Q_CC_CLANG 306
-# elif __apple_build_version__ >= 6000051
-# define Q_CC_CLANG 305
-# elif __apple_build_version__ >= 5030038
-# define Q_CC_CLANG 304
-# elif __apple_build_version__ >= 5000275
-# define Q_CC_CLANG 303
-# elif __apple_build_version__ >= 4250024
-# define Q_CC_CLANG 302
-# elif __apple_build_version__ >= 3180045
-# define Q_CC_CLANG 301
-# elif __apple_build_version__ >= 2111001
-# define Q_CC_CLANG 300
+ // The Clang version reported by Apple Clang in __clang_major__
+ // and __clang_minor__ does _not_ reflect the actual upstream
+ // version of the compiler. To allow consumers to use a single
+ // define to verify the Clang version we hard-code the versions
+ // based on the best available info we have about the actual
+ // version: http://en.wikipedia.org/wiki/Xcode#Toolchain_Versions
+# if __apple_build_version__ >= 14030022 // Xcode 14.3
+# define Q_CC_CLANG 1500
+# elif __apple_build_version__ >= 14000029 // Xcode 14.0
+# define Q_CC_CLANG 1400
+# elif __apple_build_version__ >= 13160021 // Xcode 13.3
+# define Q_CC_CLANG 1300
+# elif __apple_build_version__ >= 13000029 // Xcode 13.0
+# define Q_CC_CLANG 1200
+# elif __apple_build_version__ >= 12050022 // Xcode 12.5
+# define Q_CC_CLANG 1110
+# elif __apple_build_version__ >= 12000032 // Xcode 12.0
+# define Q_CC_CLANG 1000
+# elif __apple_build_version__ >= 11030032 // Xcode 11.4
+# define Q_CC_CLANG 900
+# elif __apple_build_version__ >= 11000033 // Xcode 11.0
+# define Q_CC_CLANG 800
# else
-# error "Unknown Apple Clang version"
+# error "Unsupported Apple Clang version"
# endif
# else
+ // Non-Apple Clang, so we trust the versions reported
# define Q_CC_CLANG ((__clang_major__ * 100) + __clang_minor__)
# endif
+# define Q_CC_CLANG_ONLY Q_CC_CLANG
# if __has_builtin(__builtin_assume)
# define Q_ASSUME_IMPL(expr) __builtin_assume(expr)
# else
@@ -203,6 +169,7 @@
# endif
# else
/* Plain GCC */
+# define Q_CC_GNU_ONLY Q_CC_GNU
# if Q_CC_GNU >= 405
# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
@@ -213,8 +180,13 @@
# ifdef Q_OS_WIN
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
-# elif defined(QT_VISIBILITY_AVAILABLE)
-# define Q_DECL_EXPORT __attribute__((visibility("default")))
+# else
+# define Q_DECL_EXPORT_OVERRIDABLE __attribute__((visibility("default"), weak))
+# ifdef QT_USE_PROTECTED_VISIBILITY
+# define Q_DECL_EXPORT __attribute__((visibility("protected")))
+# else
+# define Q_DECL_EXPORT __attribute__((visibility("default")))
+# endif
# define Q_DECL_IMPORT __attribute__((visibility("default")))
# define Q_DECL_HIDDEN __attribute__((visibility("hidden")))
# endif
@@ -264,7 +236,6 @@
but it is not defined on older compilers like C Set 3.1 */
#elif defined(__xlC__)
# define Q_CC_XLC
-# define Q_FULL_TEMPLATE_INSTANTIATION
# if __xlC__ < 0x400
# error "Compiler not supported"
# elif __xlC__ >= 0x0600
@@ -335,10 +306,6 @@
# elif defined(__KCC)
# define Q_CC_KAI
-/* Using the `using' keyword avoids Intel C++ for Linux warnings */
-# elif defined(__INTEL_COMPILER)
-# define Q_CC_INTEL (__INTEL_COMPILER)
-
/* Uses CFront, make sure to read the manual how to tweak templates. */
# elif defined(__ghs)
# define Q_CC_GHS
@@ -409,15 +376,6 @@
documentation. It also follows conventions like _BOOL and this documented */
# elif defined(sinix)
# define Q_CC_CDS
-
-/* The MIPSpro compiler defines __EDG */
-# elif defined(__sgi)
-# define Q_CC_MIPS
-# define Q_NO_TEMPLATE_FRIENDS
-# if defined(_COMPILER_VERSION) && (_COMPILER_VERSION >= 740)
-# define Q_OUTOFLINE_TEMPLATE inline
-# pragma set woff 3624,3625,3649 /* turn off some harmless warnings */
-# endif
# endif
/* VxWorks' DIAB toolchain has an additional EDG type C++ compiler
@@ -446,9 +404,6 @@
# if __SUNPRO_CC >= 0x550
# define Q_DECL_EXPORT __global
# endif
-# if __SUNPRO_CC < 0x5a0
-# define Q_NO_TEMPLATE_FRIENDS
-# endif
# if !defined(_BOOL)
# error "Compiler not supported"
# endif
@@ -467,26 +422,6 @@
# endif
# define Q_BROKEN_TEMPLATE_SPECIALIZATION
-#elif defined(Q_OS_HPUX)
-/* __HP_aCC was not defined in first aCC releases */
-# if defined(__HP_aCC) || __cplusplus >= 199707L
-# define Q_NO_TEMPLATE_FRIENDS
-# define Q_CC_HPACC
-# define Q_FUNC_INFO __PRETTY_FUNCTION__
-# if __HP_aCC-0 < 060000
-# define QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
-# define Q_DECL_EXPORT __declspec(dllexport)
-# define Q_DECL_IMPORT __declspec(dllimport)
-# endif
-# if __HP_aCC-0 >= 062000
-# define Q_DECL_EXPORT __attribute__((visibility("default")))
-# define Q_DECL_HIDDEN __attribute__((visibility("hidden")))
-# define Q_DECL_IMPORT Q_DECL_EXPORT
-# endif
-# else
-# error "Compiler not supported"
-# endif
-
#else
# error "Qt has not been tested with this compiler - see http://www.qt-project.org/"
#endif
@@ -516,13 +451,21 @@
# define __has_include_next(x) 0
#endif
-// Kept around until all submodules have transitioned
-#define QT_HAS_BUILTIN(x) __has_builtin(x)
-#define QT_HAS_FEATURE(x) __has_feature(x)
-#define QT_HAS_ATTRIBUTE(x) __has_attribute(x)
-#define QT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
-#define QT_HAS_INCLUDE(x) __has_include(x)
-#define QT_HAS_INCLUDE_NEXT(x) __has_include_next(x)
+/*
+ detecting ASAN can be helpful to disable slow tests
+ clang uses feature, gcc defines __SANITIZE_ADDRESS__
+ unconditionally check both in case other compilers mirror
+ either of those options
+ */
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+# define QT_ASAN_ENABLED
+#endif
+
+#ifdef __cplusplus
+# if __has_include(<version>) /* remove this check once Integrity, QNX have caught up */
+# include <version>
+# endif
+#endif
/*
* C++11 support
@@ -564,9 +507,14 @@
* N1653 Q_COMPILER_VARIADIC_MACROS
* N2242 N2555 Q_COMPILER_VARIADIC_TEMPLATES __cpp_variadic_templates = 200704
*
- * For any future version of the C++ standard, we use only the SD-6 macro.
- * For full listing, see
- * http://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
+ *
+ * For the C++ standards C++14 and C++17, we use only the SD-6 macro.
+ *
+ * For any future version of the C++ standard, we use only the C++20 feature test macro.
+ * For library features, we assume <version> is present (this header includes it).
+ *
+ * For a full listing of feature test macros, see
+ * https://en.cppreference.com/w/cpp/feature_test
*
* C++ extensions:
* Q_COMPILER_RESTRICTED_VLA variable-length arrays, prior to __cpp_runtime_arrays
@@ -577,88 +525,7 @@
*/
#define Q_COMPILER_THREADSAFE_STATICS
-#ifdef __cplusplus
-# if __cplusplus < 201103L && !defined(Q_CC_MSVC)
-# error Qt requires a C++11 compiler and yours does not seem to be that.
-# endif
-#endif
-
-#if defined(Q_CC_INTEL) && !defined(Q_CC_MSVC)
-# define Q_COMPILER_RESTRICTED_VLA
-# define Q_COMPILER_VARIADIC_MACROS // C++11 feature supported as an extension in other modes, too
-# if __INTEL_COMPILER < 1200
-# define Q_NO_TEMPLATE_FRIENDS
-# endif
-# if __INTEL_COMPILER >= 1310 && !defined(_WIN32)
-// ICC supports C++14 binary literals in C, C++98, and C++11 modes
-// at least since 13.1, but I can't test further back
-# define Q_COMPILER_BINARY_LITERALS
-# endif
-# if __cplusplus >= 201103L || defined(__INTEL_CXX11_MODE__)
-# if __INTEL_COMPILER >= 1200
-# define Q_COMPILER_AUTO_TYPE
-# define Q_COMPILER_CLASS_ENUM
-# define Q_COMPILER_DECLTYPE
-# define Q_COMPILER_DEFAULT_MEMBERS
-# define Q_COMPILER_DELETE_MEMBERS
-# define Q_COMPILER_EXTERN_TEMPLATES
-# define Q_COMPILER_LAMBDA
-# define Q_COMPILER_RVALUE_REFS
-# define Q_COMPILER_STATIC_ASSERT
-# define Q_COMPILER_VARIADIC_MACROS
-# endif
-# if __INTEL_COMPILER >= 1210
-# define Q_COMPILER_ATTRIBUTES
-# define Q_COMPILER_AUTO_FUNCTION
-# define Q_COMPILER_NULLPTR
-# define Q_COMPILER_TEMPLATE_ALIAS
-# ifndef _CHAR16T // MSVC headers
-# define Q_COMPILER_UNICODE_STRINGS
-# endif
-# define Q_COMPILER_VARIADIC_TEMPLATES
-# endif
-# if __INTEL_COMPILER >= 1300
-# define Q_COMPILER_ATOMICS
-// constexpr support is only partial
-//# define Q_COMPILER_CONSTEXPR
-# define Q_COMPILER_INITIALIZER_LISTS
-# define Q_COMPILER_UNIFORM_INIT
-# define Q_COMPILER_NOEXCEPT
-# endif
-# if __INTEL_COMPILER >= 1400
-// causes issues with QArrayData and QtPrivate::RefCount - Intel issue ID 6000056211, bug DPD200534796
-//# define Q_COMPILER_CONSTEXPR
-# define Q_COMPILER_DELEGATING_CONSTRUCTORS
-# define Q_COMPILER_EXPLICIT_CONVERSIONS
-# define Q_COMPILER_EXPLICIT_OVERRIDES
-# define Q_COMPILER_NONSTATIC_MEMBER_INIT
-# define Q_COMPILER_RANGE_FOR
-# define Q_COMPILER_RAW_STRINGS
-# define Q_COMPILER_REF_QUALIFIERS
-# define Q_COMPILER_UNICODE_STRINGS
-# define Q_COMPILER_UNRESTRICTED_UNIONS
-# endif
-# if __INTEL_COMPILER >= 1500
-# if __INTEL_COMPILER * 100 + __INTEL_COMPILER_UPDATE >= 150001
-// the bug mentioned above is fixed in 15.0.1
-# define Q_COMPILER_CONSTEXPR
-# endif
-# define Q_COMPILER_ALIGNAS
-# define Q_COMPILER_ALIGNOF
-# define Q_COMPILER_INHERITING_CONSTRUCTORS
-# define Q_COMPILER_THREAD_LOCAL
-# define Q_COMPILER_UDL
-# endif
-# elif defined(__STDC_VERSION__) && __STDC_VERSION__ > 199901L
-// C11 features supported. Only tested with ICC 17 and up.
-# define Q_COMPILER_STATIC_ASSERT
-# if __has_include(<threads.h>)
-# define Q_COMPILER_THREAD_LOCAL
-# endif
-# endif
-#endif
-
-#if defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !defined(Q_CC_MSVC)
+#if defined(Q_CC_CLANG)
/* General C++ features */
# define Q_COMPILER_RESTRICTED_VLA
# if __has_feature(attribute_deprecated_with_message)
@@ -681,7 +548,8 @@
# endif
/* C++11 features, see http://clang.llvm.org/cxx_status.html */
-# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+# if (defined(__cplusplus) && __cplusplus >= 201103L) \
+ || defined(__GXX_EXPERIMENTAL_CXX0X__)
/* Detect C++ features using __has_feature(), see http://clang.llvm.org/docs/LanguageExtensions.html#cxx11 */
# if __has_feature(cxx_alignas)
# define Q_COMPILER_ALIGNAS
@@ -779,10 +647,10 @@
# if Q_CC_CLANG >= 209 /* since clang 2.9 */
# define Q_COMPILER_EXTERN_TEMPLATES
# endif
-# endif
+# endif // (defined(__cplusplus) && __cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X__)
/* C++1y features, deprecated macros. Do not update this list. */
-# if __cplusplus > 201103L
+# if defined(__cplusplus) && __cplusplus > 201103L
//# if __has_feature(cxx_binary_literals)
//# define Q_COMPILER_BINARY_LITERALS // see above
//# endif
@@ -804,7 +672,7 @@
# if __has_feature(cxx_runtime_array)
# define Q_COMPILER_VLA
# endif
-# endif
+# endif // if defined(__cplusplus) && __cplusplus > 201103L
# if defined(__STDC_VERSION__)
# if __has_feature(c_static_assert)
@@ -817,16 +685,13 @@
# endif
# endif
-#endif // Q_CC_CLANG && !Q_CC_INTEL && !Q_CC_MSVC
-
-#if defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
# ifndef Q_DECL_UNUSED
# define Q_DECL_UNUSED __attribute__((__unused__))
# endif
# define Q_DECL_UNUSED_MEMBER Q_DECL_UNUSED
-#endif
+#endif // defined(Q_CC_CLANG)
-#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
+#if defined(Q_CC_GNU_ONLY)
# define Q_COMPILER_RESTRICTED_VLA
# if Q_CC_GNU >= 403
// GCC supports binary literals in C, C++98 and C++11 modes
@@ -929,7 +794,7 @@
# endif
#endif
-#if defined(Q_CC_MSVC)
+#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
# if defined(__cplusplus)
/* C++11 features supported in VC8 = VC2005: */
# define Q_COMPILER_VARIADIC_MACROS
@@ -986,8 +851,15 @@
# if _MSC_VER >= 1910
# define Q_COMPILER_CONSTEXPR
# endif
+// MSVC versions before 19.36 have a bug in C++20 comparison implementation.
+// This leads to ambiguities when resolving comparison operator overloads in
+// certain scenarios (the buggy MSVC versions were checked using our CI and
+// compiler explorer).
+# if _MSC_VER < 1936
+# define Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
+# endif
# endif /* __cplusplus */
-#endif /* Q_CC_MSVC */
+#endif // defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
#ifdef Q_COMPILER_UNICODE_STRINGS
# define Q_STDLIB_UNICODE_STRINGS
@@ -1031,44 +903,22 @@
# endif // !_HAS_CONSTEXPR
# endif // !__GLIBCXX__ && !_LIBCPP_VERSION
# endif // Q_OS_QNX
-# if (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) && defined(Q_OS_MAC) && defined(__GNUC_LIBSTD__) \
- && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402)
+# if defined(Q_CC_CLANG) && defined(Q_OS_DARWIN)
+# if defined(__GNUC_LIBSTD__) && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402)
// Apple has not updated libstdc++ since 2007, which means it does not have
// <initializer_list> or std::move. Let's disable these features
-# undef Q_COMPILER_INITIALIZER_LISTS
-# undef Q_COMPILER_RVALUE_REFS
-# undef Q_COMPILER_REF_QUALIFIERS
+# undef Q_COMPILER_INITIALIZER_LISTS
+# undef Q_COMPILER_RVALUE_REFS
+# undef Q_COMPILER_REF_QUALIFIERS
// Also disable <atomic>, since it's clearly not there
-# undef Q_COMPILER_ATOMICS
-# endif
-# if defined(Q_CC_CLANG) && defined(Q_CC_INTEL) && Q_CC_INTEL >= 1500
-// ICC 15.x and 16.0 have their own implementation of std::atomic, which is activated when in Clang mode
-// (probably because libc++'s <atomic> on OS X failed to compile), but they're missing some
-// critical definitions. (Reported as Intel Issue ID 6000117277)
-# define __USE_CONSTEXPR 1
-# define __USE_NOEXCEPT 1
-# endif
-#endif
-
-/*
- * C++11 keywords and expressions
- */
-#ifdef Q_COMPILER_NULLPTR
-# define Q_NULLPTR nullptr
-#else
-# define Q_NULLPTR NULL
-#endif
-
-#ifdef Q_COMPILER_DEFAULT_MEMBERS
-# define Q_DECL_EQ_DEFAULT = default
-#else
-# define Q_DECL_EQ_DEFAULT
-#endif
-
-#ifdef Q_COMPILER_DELETE_MEMBERS
-# define Q_DECL_EQ_DELETE = delete
-#else
-# define Q_DECL_EQ_DELETE
+# undef Q_COMPILER_ATOMICS
+# endif
+# if defined(__cpp_lib_memory_resource) \
+ && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 140000) \
+ || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 170000))
+# undef __cpp_lib_memory_resource // Only supported on macOS 14 and iOS 17
+# endif
+# endif // defined(Q_CC_CLANG) && defined(Q_OS_DARWIN)
#endif
// Don't break code that is already using Q_COMPILER_DEFAULT_DELETE_MEMBERS
@@ -1076,65 +926,68 @@
# define Q_COMPILER_DEFAULT_DELETE_MEMBERS
#endif
-#if defined Q_COMPILER_CONSTEXPR
-# if defined(__cpp_constexpr) && __cpp_constexpr-0 >= 201304
-# define Q_DECL_CONSTEXPR constexpr
-# define Q_DECL_RELAXED_CONSTEXPR constexpr
-# define Q_CONSTEXPR constexpr
-# define Q_RELAXED_CONSTEXPR constexpr
-# else
-# define Q_DECL_CONSTEXPR constexpr
-# define Q_DECL_RELAXED_CONSTEXPR
-# define Q_CONSTEXPR constexpr
-# define Q_RELAXED_CONSTEXPR const
-# endif
+/*
+ * Compatibility macros for C++11/14 keywords and expressions.
+ * Don't use in new code and port away whenever you have a chance.
+ */
+#define Q_ALIGNOF(x) alignof(x)
+#define Q_DECL_ALIGN(n) alignas(n)
+#define Q_DECL_NOTHROW Q_DECL_NOEXCEPT
+#ifdef __cplusplus
+# define Q_CONSTEXPR constexpr
+# define Q_DECL_CONSTEXPR constexpr
+# define Q_DECL_EQ_DEFAULT = default
+# define Q_DECL_EQ_DELETE = delete
+# define Q_DECL_FINAL final
+# define Q_DECL_NOEXCEPT noexcept
+# define Q_DECL_NOEXCEPT_EXPR(x) noexcept(x)
+# define Q_DECL_OVERRIDE override
+# define Q_DECL_RELAXED_CONSTEXPR constexpr
+# define Q_NULLPTR nullptr
+# define Q_RELAXED_CONSTEXPR constexpr
#else
+# define Q_CONSTEXPR const
# define Q_DECL_CONSTEXPR
# define Q_DECL_RELAXED_CONSTEXPR
-# define Q_CONSTEXPR const
-# define Q_RELAXED_CONSTEXPR const
-#endif
-
-#ifdef Q_COMPILER_EXPLICIT_OVERRIDES
-# define Q_DECL_OVERRIDE override
-# define Q_DECL_FINAL final
-#else
-# ifndef Q_DECL_OVERRIDE
-# define Q_DECL_OVERRIDE
-# endif
-# ifndef Q_DECL_FINAL
-# define Q_DECL_FINAL
+# define Q_NULLPTR NULL
+# define Q_RELAXED_CONSTEXPR const
+# ifdef Q_CC_GNU
+# define Q_DECL_NOEXCEPT __attribute__((__nothrow__))
+# else
+# define Q_DECL_NOEXCEPT
# endif
#endif
-#ifdef Q_COMPILER_NOEXCEPT
-# define Q_DECL_NOEXCEPT noexcept
-# define Q_DECL_NOEXCEPT_EXPR(x) noexcept(x)
-#else
-# define Q_DECL_NOEXCEPT
-# define Q_DECL_NOEXCEPT_EXPR(x)
-#endif
-#define Q_DECL_NOTHROW Q_DECL_NOEXCEPT
-
-#ifndef Q_ALIGNOF
-# define Q_ALIGNOF(x) alignof(x)
-#endif
-
-#ifndef Q_DECL_ALIGN
-# define Q_DECL_ALIGN(n) alignas(n)
-#endif
-
#if __has_cpp_attribute(nodiscard) && (!defined(Q_CC_CLANG) || __cplusplus > 201402L) // P0188R1
// Can't use [[nodiscard]] with Clang and C++11/14, see https://bugs.llvm.org/show_bug.cgi?id=33518
# undef Q_REQUIRED_RESULT
# define Q_REQUIRED_RESULT [[nodiscard]]
#endif
+#if __has_cpp_attribute(nodiscard) >= 201907L /* used for both P1771 and P1301... */
+// [[nodiscard]] constructor (P1771)
+# ifndef Q_NODISCARD_CTOR
+# define Q_NODISCARD_CTOR [[nodiscard]]
+# endif
+// [[nodiscard("reason")]] (P1301)
+# ifndef Q_NODISCARD_X
+# define Q_NODISCARD_X(message) [[nodiscard(message)]]
+# endif
+# ifndef Q_NODISCARD_CTOR_X
+# define Q_NODISCARD_CTOR_X(message) [[nodiscard(message)]]
+# endif
+#endif
+
#if __has_cpp_attribute(maybe_unused)
# undef Q_DECL_UNUSED
# define Q_DECL_UNUSED [[maybe_unused]]
#endif
+#if __has_cpp_attribute(noreturn)
+# undef Q_NORETURN
+# define Q_NORETURN [[noreturn]]
+#endif
+
#if __has_cpp_attribute(deprecated)
# ifdef Q_DECL_DEPRECATED
# undef Q_DECL_DEPRECATED
@@ -1146,10 +999,8 @@
# define Q_DECL_DEPRECATED_X(x) [[deprecated(x)]]
#endif
-#if defined(__cpp_enumerator_attributes) && __cpp_enumerator_attributes >= 201411
-# define Q_DECL_ENUMERATOR_DEPRECATED Q_DECL_DEPRECATED
-# define Q_DECL_ENUMERATOR_DEPRECATED_X(x) Q_DECL_DEPRECATED_X(x)
-#endif
+#define Q_DECL_ENUMERATOR_DEPRECATED Q_DECL_DEPRECATED
+#define Q_DECL_ENUMERATOR_DEPRECATED_X(x) Q_DECL_DEPRECATED_X(x)
/*
* Fallback macros to certain compiler features
@@ -1176,6 +1027,15 @@
#ifndef Q_REQUIRED_RESULT
# define Q_REQUIRED_RESULT
#endif
+#ifndef Q_NODISCARD_X
+# define Q_NODISCARD_X(message) Q_REQUIRED_RESULT
+#endif
+#ifndef Q_NODISCARD_CTOR
+# define Q_NODISCARD_CTOR
+#endif
+#ifndef Q_NODISCARD_CTOR_X
+# define Q_NODISCARD_CTOR_X(message) Q_NODISCARD_CTOR
+#endif
#ifndef Q_DECL_DEPRECATED
# define Q_DECL_DEPRECATED
#endif
@@ -1185,15 +1045,12 @@
#ifndef Q_DECL_DEPRECATED_X
# define Q_DECL_DEPRECATED_X(text) Q_DECL_DEPRECATED
#endif
-#ifndef Q_DECL_ENUMERATOR_DEPRECATED
-# define Q_DECL_ENUMERATOR_DEPRECATED
-#endif
-#ifndef Q_DECL_ENUMERATOR_DEPRECATED_X
-# define Q_DECL_ENUMERATOR_DEPRECATED_X(x)
-#endif
#ifndef Q_DECL_EXPORT
# define Q_DECL_EXPORT
#endif
+#ifndef Q_DECL_EXPORT_OVERRIDABLE
+# define Q_DECL_EXPORT_OVERRIDABLE Q_DECL_EXPORT
+#endif
#ifndef Q_DECL_IMPORT
# define Q_DECL_IMPORT
#endif
@@ -1239,37 +1096,42 @@
* "Weak overloads" - makes an otherwise confliciting overload weaker
* (by making it a template)
*/
-#define Q_WEAK_OVERLOAD template <typename = void>
+#ifndef Q_QDOC
+# define Q_WEAK_OVERLOAD template <typename = void>
+#else
+# define Q_WEAK_OVERLOAD
+#endif
+
+/*
+ * If one wants to add functions that use post-C++17 APIs, one needs to:
+ *
+ * 1) make them fully inline; and
+ * 2) guard them using the necessary feature-testing macros.
+ *
+ * This decouples the C++ version used to build Qt with the one used by
+ * end-user applications; Qt and the application can either choose any C++
+ * version.
+ *
+ * A problem arises on MSVC for member functions of exported classes. Client
+ * code that tries to use such a function will see it as exported, and simply
+ * try to consume the function's *symbol*. However, if Qt has been built in
+ * C++17, it won't have such a symbol, and linking will fail.
+ *
+ * The workaround: declare such functions as function templates.
+ * (Obviously a function template does not need this marker.)
+*/
+#ifndef Q_QDOC
+# define QT_POST_CXX17_API_IN_EXPORTED_CLASS template <typename = void>
+#else
+# define QT_POST_CXX17_API_IN_EXPORTED_CLASS
+#endif
/*
* Warning/diagnostic handling
*/
#define QT_DO_PRAGMA(text) _Pragma(#text)
-#if defined(Q_CC_INTEL) && defined(Q_CC_MSVC)
-/* icl.exe: Intel compiler on Windows */
-# undef QT_DO_PRAGMA /* not needed */
-# define QT_WARNING_PUSH __pragma(warning(push))
-# define QT_WARNING_POP __pragma(warning(pop))
-# define QT_WARNING_DISABLE_MSVC(number)
-# define QT_WARNING_DISABLE_INTEL(number) __pragma(warning(disable: number))
-# define QT_WARNING_DISABLE_CLANG(text)
-# define QT_WARNING_DISABLE_GCC(text)
-# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1478 1786)
-# define QT_WARNING_DISABLE_FLOAT_COMPARE QT_WARNING_DISABLE_INTEL(1572)
-# define QT_WARNING_DISABLE_INVALID_OFFSETOF
-#elif defined(Q_CC_INTEL)
-/* icc: Intel compiler on Linux or OS X */
-# define QT_WARNING_PUSH QT_DO_PRAGMA(warning(push))
-# define QT_WARNING_POP QT_DO_PRAGMA(warning(pop))
-# define QT_WARNING_DISABLE_INTEL(number) QT_DO_PRAGMA(warning(disable: number))
-# define QT_WARNING_DISABLE_MSVC(number)
-# define QT_WARNING_DISABLE_CLANG(text)
-# define QT_WARNING_DISABLE_GCC(text)
-# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1478 1786)
-# define QT_WARNING_DISABLE_FLOAT_COMPARE QT_WARNING_DISABLE_INTEL(1572)
-# define QT_WARNING_DISABLE_INVALID_OFFSETOF
-#elif defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
+#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
# undef QT_DO_PRAGMA /* not needed */
# define QT_WARNING_PUSH __pragma(warning(push))
# define QT_WARNING_POP __pragma(warning(pop))
@@ -1321,6 +1183,20 @@
QT_WARNING_POP
#endif
+// 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
+
+// This macro can be used to calculate member offsets for types with a non standard layout.
+// It uses the fact that offsetof() is allowed to support those types since C++17 as an optional
+// feature. All our compilers do support this, but some issue a warning, so we wrap the offsetof()
+// call in a macro that disables the compiler warning.
+#define Q_OFFSETOF(Class, member) \
+ []() -> size_t { \
+ QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
+ return offsetof(Class, member); \
+ QT_WARNING_POP \
+ }()
+
/*
Proper for-scoping in MIPSpro CC
*/
@@ -1336,19 +1212,6 @@
#define qMove(x) (x)
#endif
-#define Q_UNREACHABLE() \
- do {\
- Q_ASSERT_X(false, "Q_UNREACHABLE()", "Q_UNREACHABLE was reached");\
- Q_UNREACHABLE_IMPL();\
- } while (false)
-
-#define Q_ASSUME(Expr) \
- do {\
- const bool valueOfExpression = Expr;\
- Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\
- Q_ASSUME_IMPL(valueOfExpression);\
- } while (false)
-
#if defined(__cplusplus)
#if __has_cpp_attribute(clang::fallthrough)
# define Q_FALLTHROUGH() [[clang::fallthrough]]
@@ -1359,11 +1222,11 @@
#endif
#endif
#ifndef Q_FALLTHROUGH
-# if (defined(Q_CC_GNU) && Q_CC_GNU >= 700) && !defined(Q_CC_INTEL)
+# ifdef Q_CC_GNU
# define Q_FALLTHROUGH() __attribute__((fallthrough))
# else
# define Q_FALLTHROUGH() (void)0
-#endif
+# endif
#endif
@@ -1388,4 +1251,173 @@
# undef QT_COMPILER_SUPPORTS_MIPS_DSPR2
#endif
+// Compiler version check
+#if defined(__cplusplus) && (__cplusplus < 201703L)
+# ifdef Q_CC_MSVC
+# error "Qt requires a C++17 compiler, and a suitable value for __cplusplus. On MSVC, you must pass the /Zc:__cplusplus option to the compiler."
+# else
+# error "Qt requires a C++17 compiler"
+# endif
+#endif // __cplusplus
+
+#if defined(__cplusplus) && defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
+# if Q_CC_MSVC < 1927
+ // Check below only works with 16.7 or newer
+# error "Qt requires at least Visual Studio 2019 version 16.7 (VC++ version 14.27). Please upgrade."
+# endif
+
+// On MSVC we require /permissive- set by user code. Check that we are
+// under its rules -- for instance, check that std::nullptr_t->bool is
+// not an implicit conversion, as per
+// https://docs.microsoft.com/en-us/cpp/overview/cpp-conformance-improvements?view=msvc-160#nullptr_t-is-only-convertible-to-bool-as-a-direct-initialization
+static_assert(!std::is_convertible_v<std::nullptr_t, bool>,
+ "On MSVC you must pass the /permissive- option to the compiler.");
+#endif
+
+#if defined(QT_BOOTSTRAPPED) || defined(QT_USE_PROTECTED_VISIBILITY) || !defined(__ELF__) || defined(__PIC__)
+// this is fine
+#elif defined(QT_REDUCE_RELOCATIONS)
+# error "You must build your code with position independent code if Qt was configured with -reduce-relocations. "\
+ "Compile your code with -fPIC (and not with -fPIE)."
+#endif
+
+#ifdef Q_PROCESSOR_X86_32
+# if defined(Q_CC_GNU)
+# define QT_FASTCALL __attribute__((regparm(3)))
+# elif defined(Q_CC_MSVC)
+# define QT_FASTCALL __fastcall
+# else
+# define QT_FASTCALL
+# endif
+#else
+# define QT_FASTCALL
+#endif
+
+// enable gcc warnings for printf-style functions
+#if defined(Q_CC_GNU) && !defined(__INSURE__)
+# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
+# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B) \
+ __attribute__((format(gnu_printf, (A), (B))))
+# else
+# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B) \
+ __attribute__((format(printf, (A), (B))))
+# endif
+#else
+# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B)
+#endif
+
+#ifdef Q_CC_MSVC
+# define Q_NEVER_INLINE __declspec(noinline)
+# define Q_ALWAYS_INLINE __forceinline
+#elif defined(Q_CC_GNU)
+# define Q_NEVER_INLINE __attribute__((noinline))
+# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
+#else
+# define Q_NEVER_INLINE
+# define Q_ALWAYS_INLINE inline
+#endif
+
+//defines the type for the WNDPROC on windows
+//the alignment needs to be forced for sse2 to not crash with mingw
+#if defined(Q_OS_WIN)
+# if defined(Q_CC_MINGW) && defined(Q_PROCESSOR_X86_32)
+# define QT_ENSURE_STACK_ALIGNED_FOR_SSE __attribute__ ((force_align_arg_pointer))
+# else
+# define QT_ENSURE_STACK_ALIGNED_FOR_SSE
+# endif
+# define QT_WIN_CALLBACK CALLBACK QT_ENSURE_STACK_ALIGNED_FOR_SSE
+#endif
+
+#ifdef __cpp_conditional_explicit
+#define Q_IMPLICIT explicit(false)
+#else
+#define Q_IMPLICIT
+#endif
+
+#if defined(__cplusplus)
+
+#ifdef __cpp_constinit
+# if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
+ // https://developercommunity.visualstudio.com/t/C:-constinit-for-an-optional-fails-if-/1406069
+# define Q_CONSTINIT
+# else
+# define Q_CONSTINIT constinit
+# endif
+#elif defined(__has_cpp_attribute) && __has_cpp_attribute(clang::require_constant_initialization)
+# define Q_CONSTINIT [[clang::require_constant_initialization]]
+#elif defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1000
+# define Q_CONSTINIT __constinit
+#else
+# define Q_CONSTINIT
+#endif
+
+#ifndef Q_OUTOFLINE_TEMPLATE
+# define Q_OUTOFLINE_TEMPLATE
+#endif
+#ifndef Q_INLINE_TEMPLATE
+# define Q_INLINE_TEMPLATE inline
+#endif
+
+/*
+ Avoid some particularly useless warnings from some stupid compilers.
+ To get ALL C++ compiler warnings, define QT_CC_WARNINGS or comment out
+ the line "#define QT_NO_WARNINGS". See also QTBUG-26877.
+*/
+#if !defined(QT_CC_WARNINGS)
+# define QT_NO_WARNINGS
+#endif
+#if defined(QT_NO_WARNINGS)
+# if defined(Q_CC_MSVC)
+QT_WARNING_DISABLE_MSVC(4251) /* class 'type' needs to have dll-interface to be used by clients of class 'type2' */
+QT_WARNING_DISABLE_MSVC(4244) /* conversion from 'type1' to 'type2', possible loss of data */
+QT_WARNING_DISABLE_MSVC(4275) /* non - DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier' */
+QT_WARNING_DISABLE_MSVC(4514) /* unreferenced inline function has been removed */
+QT_WARNING_DISABLE_MSVC(4800) /* 'type' : forcing value to bool 'true' or 'false' (performance warning) */
+QT_WARNING_DISABLE_MSVC(4097) /* typedef-name 'identifier1' used as synonym for class-name 'identifier2' */
+QT_WARNING_DISABLE_MSVC(4706) /* assignment within conditional expression */
+QT_WARNING_DISABLE_MSVC(4355) /* 'this' : used in base member initializer list */
+QT_WARNING_DISABLE_MSVC(4710) /* function not inlined */
+QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc */
+# elif defined(Q_CC_BOR)
+# pragma option -w-inl
+# pragma option -w-aus
+# pragma warn -inl
+# pragma warn -pia
+# pragma warn -ccc
+# pragma warn -rch
+# pragma warn -sig
+# endif
+#endif
+
+#if !defined(QT_NO_EXCEPTIONS)
+# if !defined(Q_MOC_RUN)
+# if defined(Q_CC_GNU) && !defined(__cpp_exceptions)
+# define QT_NO_EXCEPTIONS
+# endif
+# elif defined(QT_BOOTSTRAPPED)
+# define QT_NO_EXCEPTIONS
+# endif
+#endif
+
+// libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346
+#if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11)
+# define QT_COMPILER_HAS_LWG3346
+#endif
+
+#if defined(__cplusplus) && __cplusplus >= 202002L // P0846 doesn't have a feature macro :/
+# define QT_COMPILER_HAS_P0846
+#endif
+
+#ifdef QT_COMPILER_HAS_P0846
+# define QT_ENABLE_P0846_SEMANTICS_FOR(func)
+#else
+ class QT_CLASS_JUST_FOR_P0846_SIMULATION;
+# define QT_ENABLE_P0846_SEMANTICS_FOR(func) \
+ template <typename T> \
+ void func (QT_CLASS_JUST_FOR_P0846_SIMULATION *); \
+ /* end */
+#endif // !P0846
+
+#endif // __cplusplus
+
#endif // QCOMPILERDETECTION_H
diff --git a/src/corelib/global/qcompilerdetection.qdoc b/src/corelib/global/qcompilerdetection.qdoc
new file mode 100644
index 0000000000..191f26cc1f
--- /dev/null
+++ b/src/corelib/global/qcompilerdetection.qdoc
@@ -0,0 +1,427 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \headerfile <QtCompilerDetection>
+ \inmodule QtCore
+ \title Compiler-specific Macro Definitions
+ \ingroup funclists
+
+ \brief The <QtCompilerDetection> header file includes various
+ compiler-specific macros.
+
+ The <QtCompilerDetection> header file provides a range of macros (Q_CC_*)
+ that are defined if the application is compiled using the specified
+ compiler. For example, the Q_CC_SUN macro is defined if the application is
+ compiled using Forte Developer, or Sun Studio C++.
+
+ The purpose of these macros is to enable programmers to add
+ compiler-specific code to their application.
+*/
+
+/*!
+ \macro Q_CC_SYM
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Digital Mars C/C++
+ (used to be Symantec C++).
+*/
+
+/*!
+ \macro Q_CC_MSVC
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Microsoft Visual
+ C/C++, Intel C++ for Windows.
+*/
+
+/*!
+ \macro Q_CC_CLANG
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Clang.
+*/
+
+/*!
+ \macro Q_CC_BOR
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Borland/Turbo C++.
+*/
+
+/*!
+ \macro Q_CC_WAT
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Watcom C++.
+*/
+
+/*!
+ \macro Q_CC_GNU
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using GNU Compiler Collection (GCC).
+*/
+
+/*!
+ \macro Q_CC_COMEAU
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Comeau C++.
+*/
+
+/*!
+ \macro Q_CC_EDG
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Edison Design Group
+ C++.
+*/
+
+/*!
+ \macro Q_CC_OC
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using CenterLine C++.
+*/
+
+/*!
+ \macro Q_CC_SUN
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Forte Developer, or
+ Sun Studio C++.
+*/
+
+/*!
+ \macro Q_CC_MIPS
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using MIPSpro C++.
+*/
+
+/*!
+ \macro Q_CC_DEC
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using DEC C++.
+*/
+
+/*!
+ \macro Q_CC_HPACC
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using HP aC++.
+*/
+
+/*!
+ \macro Q_CC_USLC
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using SCO OUDK and UDK.
+*/
+
+/*!
+ \macro Q_CC_CDS
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Reliant C++.
+*/
+
+/*!
+ \macro Q_CC_KAI
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using KAI C++.
+*/
+
+/*!
+ \macro Q_CC_INTEL
+ \relates <QtCompilerDetection>
+ \obsolete
+
+ This macro used to be defined if the application was compiled with the old
+ Intel C++ compiler for Linux, macOS or Windows. The new oneAPI C++ compiler
+ is just a build of Clang and therefore does not define this macro.
+
+ \sa Q_CC_CLANG
+*/
+
+/*!
+ \macro Q_CC_HIGHC
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using MetaWare High C/C++.
+*/
+
+/*!
+ \macro Q_CC_PGI
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Portland Group C++.
+*/
+
+/*!
+ \macro Q_CC_GHS
+ \relates <QtCompilerDetection>
+
+ Defined if the application is compiled using Green Hills
+ Optimizing C++ Compilers.
+*/
+
+/*!
+ \macro void Q_FALLTHROUGH()
+ \relates <QtCompilerDetection>
+ \since 5.8
+
+ Can be used in switch statements at the end of case block to tell the compiler
+ and other developers that the lack of a break statement is intentional.
+
+ This is useful since a missing break statement is often a bug, and some
+ compilers can be configured to emit warnings when one is not found.
+
+ \sa Q_UNREACHABLE(), Q_UNREACHABLE_RETURN()
+*/
+
+/*!
+ \macro Q_LIKELY(expr)
+ \relates <QtCompilerDetection>
+ \since 4.8
+
+ \brief Hints to the compiler that the enclosed condition, \a expr, is
+ likely to evaluate to \c true.
+
+ Use of this macro can help the compiler to optimize the code.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qlikely
+
+ \sa Q_UNLIKELY()
+*/
+
+/*!
+ \macro Q_UNLIKELY(expr)
+ \relates <QtCompilerDetection>
+ \since 4.8
+
+ \brief Hints to the compiler that the enclosed condition, \a expr, is
+ likely to evaluate to \c false.
+
+ Use of this macro can help the compiler to optimize the code.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qunlikely
+
+ \sa Q_LIKELY()
+*/
+
+/*!
+ \macro Q_CONSTINIT
+ \relates <QtCompilerDetection>
+ \since 6.4
+
+ \brief Enforces constant initialization when supported by the compiler.
+
+ If the compiler supports the C++20 \c{constinit} keyword, Clang's
+ \c{[[clang::require_constant_initialization]]} or GCC's \c{__constinit},
+ then this macro expands to the first one of these that is available,
+ otherwise it expands to nothing.
+
+ Variables marked as \c{constinit} cause a compile-error if their
+ initialization would have to be performed at runtime.
+
+ \note Constant-initialized variables may still have load-time impact if
+ they have non-trivial destruction.
+
+ For constants, you can use \c{constexpr} since C++11, but \c{constexpr}
+ makes variables \c{const}, too, whereas \c{constinit} ensures constant
+ initialization, but doesn't make the variable \c{const}:
+
+ \table
+ \header \li Keyword \li Added \li immutable \li constant-initialized
+ \row \li \c{const} \li C++98 \li yes \li not required
+ \row \li \c{constexpr} \li C++11 \li yes \li required
+ \row \li \c{constinit} \li C++20 \li no \li required
+ \endtable
+*/
+
+/*!
+ \macro Q_DECL_EXPORT
+ \relates <QtCompilerDetection>
+
+ This macro marks a symbol for shared library export (see
+ \l{sharedlibrary.html}{Creating Shared Libraries}).
+
+ \sa Q_DECL_IMPORT
+*/
+
+/*!
+ \macro Q_DECL_IMPORT
+ \relates <QtCompilerDetection>
+
+ This macro declares a symbol to be an import from a shared library (see
+ \l{sharedlibrary.html}{Creating Shared Libraries}).
+
+ \sa Q_DECL_EXPORT
+*/
+
+/*!
+ \macro Q_DECL_CONSTEXPR
+ \relates <QtCompilerDetection>
+ \deprecated [6.4] Use the \c constexpr keyword instead.
+
+ This macro can be used to declare variable that should be constructed at compile-time,
+ or an inline function that can be computed at compile-time.
+
+ \sa Q_DECL_RELAXED_CONSTEXPR
+*/
+
+/*!
+ \macro Q_DECL_RELAXED_CONSTEXPR
+ \relates <QtCompilerDetection>
+ \deprecated [6.4] Use the \c constexpr keyword instead.
+
+ This macro can be used to declare an inline function that can be computed
+ at compile-time according to the relaxed rules from C++14.
+
+ \sa Q_DECL_CONSTEXPR
+*/
+
+/*!
+ \macro Q_DECL_NOTHROW
+ \relates <QtCompilerDetection>
+ \since 5.0
+ \deprecated [6.4] Use the \c noexcept keyword instead.
+
+ This macro marks a function as never throwing, under no
+ circumstances. If the function does nevertheless throw, the
+ behavior is undefined.
+
+ \sa Q_DECL_NOEXCEPT, Q_DECL_NOEXCEPT_EXPR()
+*/
+
+/*!
+ \macro Q_DECL_NOEXCEPT
+ \relates <QtCompilerDetection>
+ \since 5.0
+ \deprecated [6.4] Use the \c noexcept keyword instead.
+
+ This macro marks a function as never throwing. If the function
+ does nevertheless throw, the behavior is defined:
+ std::terminate() is called.
+
+
+ \sa Q_DECL_NOTHROW, Q_DECL_NOEXCEPT_EXPR()
+*/
+
+/*!
+ \macro Q_DECL_NOEXCEPT_EXPR(x)
+ \relates <QtCompilerDetection>
+ \since 5.0
+ \deprecated [6.4] Use the \c noexcept keyword instead.
+
+ This macro marks a function as non-throwing if \a x is \c true. If
+ the function does nevertheless throw, the behavior is defined:
+ std::terminate() is called.
+
+
+ \sa Q_DECL_NOTHROW, Q_DECL_NOEXCEPT
+*/
+
+/*!
+ \macro Q_DECL_OVERRIDE
+ \since 5.0
+ \deprecated
+ \relates <QtCompilerDetection>
+
+ This macro can be used to declare an overriding virtual
+ function. Use of this markup will allow the compiler to generate
+ an error if the overriding virtual function does not in fact
+ override anything.
+
+ It expands to "override".
+
+ The macro goes at the end of the function, usually after the
+ \c{const}, if any:
+ \snippet code/src_corelib_global_qglobal.cpp qdecloverride
+
+ \sa Q_DECL_FINAL
+*/
+
+/*!
+ \macro Q_DECL_FINAL
+ \since 5.0
+ \deprecated
+ \relates <QtCompilerDetection>
+
+ This macro can be used to declare an overriding virtual or a class
+ as "final", with Java semantics. Further-derived classes can then
+ no longer override this virtual function, or inherit from this
+ class, respectively.
+
+ It expands to "final".
+
+ The macro goes at the end of the function, usually after the
+ \c{const}, if any:
+ \snippet code/src_corelib_global_qglobal.cpp qdeclfinal-1
+
+ For classes, it goes in front of the \c{:} in the class
+ definition, if any:
+ \snippet code/src_corelib_global_qglobal.cpp qdeclfinal-2
+
+ \sa Q_DECL_OVERRIDE
+*/
+
+/*!
+ \macro const char* Q_FUNC_INFO()
+ \relates <QtCompilerDetection>
+
+ Expands to a string that describe the function the macro resides in. How this string looks
+ more specifically is compiler dependent. With GNU GCC it is typically the function signature,
+ while with other compilers it might be the line and column number.
+
+ Q_FUNC_INFO can be conveniently used with qDebug(). For example, this function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 22
+
+ when instantiated with the integer type, will with the GCC compiler produce:
+
+ \tt{const TInputType& myMin(const TInputType&, const TInputType&) [with TInputType = int] was called with value1: 3 value2: 4}
+
+ If this macro is used outside a function, the behavior is undefined.
+*/
+
+/*!
+ \macro Q_NODISCARD_CTOR
+ \relates <QtCompilerDetection>
+ \since 6.6
+
+ \brief Expands to \c{[[nodiscard]]} on compilers that accept it on constructors.
+
+ Otherwise it expands to nothing.
+
+ Constructors marked as Q_NODISCARD_CTOR cause a compiler warning if a call
+ site doesn't use the resulting object.
+
+ This macro is exists solely to prevent warnings on compilers that don't
+ implement the feature. If your supported platforms all allow \c{[[nodiscard]]}
+ on constructors, we strongly recommend you use the C++ attribute directly instead
+ of this macro.
+
+ \sa Q_NODISCARD_CTOR_X
+*/
+
+/*!
+ \macro Q_NODISCARD_X(message)
+ \macro Q_NODISCARD_CTOR_X(message)
+ \relates <QtCompilerDetection>
+ \since 6.7
+
+ \brief Expand to \c{[[nodiscard(message)]]} on compilers that support the feature.
+
+ Otherwise they expand to \c {[[nodiscard]]} and Q_NODISCARD_CTOR, respectively.
+
+ \sa Q_NODISCARD_CTOR
+*/
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index 4d3f88e071..4d80f23786 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -59,6 +23,8 @@
#ifdef QT_BOOTSTRAPPED
+#include <stdlib.h> // for __GLIBC_PREREQ
+
#ifndef QT_NO_EXCEPTIONS
#define QT_NO_EXCEPTIONS
#endif
@@ -77,8 +43,6 @@
#define QT_FEATURE_cborstreamreader -1
#define QT_FEATURE_cborstreamwriter 1
#define QT_CRYPTOGRAPHICHASH_ONLY_SHA1
-#define QT_FEATURE_cxx11_random (__has_include(<random>) ? 1 : -1)
-#define QT_FEATURE_cxx17_bm_searcher -1
#define QT_FEATURE_cxx17_filesystem -1
#define QT_NO_DATASTREAM
#define QT_FEATURE_datestring 1
@@ -98,7 +62,7 @@
#define QT_FEATURE_jalalicalendar -1
#define QT_FEATURE_journald -1
#define QT_FEATURE_futimens -1
-#define QT_FEATURE_futimes -1
+#undef QT_FEATURE_future
#define QT_FEATURE_future -1
#define QT_FEATURE_itemmodel -1
#define QT_FEATURE_library -1
@@ -116,25 +80,21 @@
#else
# define QT_FEATURE_renameat2 -1
#endif
-#define QT_FEATURE_sharedmemory -1
#define QT_FEATURE_shortcut -1
-#define QT_FEATURE_signaling_nan -1
#define QT_FEATURE_slog2 -1
-#ifdef __GLIBC_PREREQ
-# define QT_FEATURE_statx (__GLIBC_PREREQ(2, 28) ? 1 : -1)
-#else
-# define QT_FEATURE_statx -1
-#endif
#define QT_FEATURE_syslog -1
#define QT_NO_SYSTEMLOCALE
-#define QT_FEATURE_systemsemaphore -1
-#define QT_FEATURE_temporaryfile 1
+#define QT_FEATURE_temporaryfile -1
#define QT_FEATURE_textdate 1
+#undef QT_FEATURE_thread
#define QT_FEATURE_thread -1
#define QT_FEATURE_timezone -1
#define QT_FEATURE_topleveldomain -1
#define QT_NO_TRANSLATION
#define QT_FEATURE_translation -1
+#define QT_NO_VARIANT -1
+
+#define QT_NO_COMPRESS
// rcc.pro will DEFINES+= this
#ifndef QT_FEATURE_zstd
@@ -143,5 +103,8 @@
#define QT_FEATURE_commandlineparser 1
#define QT_FEATURE_settings -1
+#define QT_FEATURE_permissions -1
+
+#define QT_NO_TEMPORARYFILE
#endif // QT_BOOTSTRAPPED
diff --git a/src/corelib/global/qconfig.cpp.in b/src/corelib/global/qconfig.cpp.in
index e6a85feffd..016bdf40d1 100644
--- a/src/corelib/global/qconfig.cpp.in
+++ b/src/corelib/global/qconfig.cpp.in
@@ -1,25 +1,20 @@
/* This file is used to generate the Qt configuration info for the Core library.
* The 'qt_generate_qconfig_cpp' cmake routine
- * contains variables that replace '@' entires in this file. It's important to
+ * contains variables that replace '@' entries in this file. It's important to
* align these values with the following:
*
* - QLibraryInfo::LibraryPath enum in qtbase/src/corelib/global/qlibraryinfo.h
* - qtConfEntries in qtbase/src/corelib/global/qlibraryinfo.cpp
- *
- * The reason for this is pointer mathematics in the QLibraryInfo implementation when iterating
- * qt_configure_strs. Also qtConfEntries are strongly bound to QLibraryInfo::LibraryPath.
*/
+#include "private/qoffsetstringarray_p.h"
-/* Installation date */
-static const char qt_configure_installation [12+11] = "qt_instdate=2012-12-20";
/* Installation Info */
static const char qt_configure_prefix_path_str [12+256] = "qt_prfxpath=@QT_CONFIGURE_PREFIX_PATH_STR@";
-static const short qt_configure_str_offsets[] = {
-@QT_CONFIG_STR_OFFSETS_FIRST@
-};
-static const char qt_configure_strs[] =
-@QT_CONFIG_STRS_FIRST@
-;
+
+static constexpr auto qt_configure_strs = QT_PREPEND_NAMESPACE(qOffsetStringArray)(
+@QT_CONFIG_STRS@
+);
+
#define QT_CONFIGURE_SETTINGS_PATH "@QT_SYS_CONF_DIR@"
-#define QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH "@QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH@"
+#define QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH "@QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH@"_L1
#define QT_CONFIGURE_PREFIX_PATH qt_configure_prefix_path_str + 12
diff --git a/src/corelib/global/qconstructormacros.h b/src/corelib/global/qconstructormacros.h
new file mode 100644
index 0000000000..21492ac31f
--- /dev/null
+++ b/src/corelib/global/qconstructormacros.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QCONSTRUCTORMACROS_H
+#define QCONSTRUCTORMACROS_H
+
+#if 0
+#pragma qt_class(QtConstructorMacros)
+#pragma qt_sync_stop_processing
+#endif
+
+#if defined(__cplusplus)
+
+#ifndef Q_CONSTRUCTOR_FUNCTION
+# define Q_CONSTRUCTOR_FUNCTION0(AFUNC) \
+ namespace { \
+ static const struct AFUNC ## _ctor_class_ { \
+ inline AFUNC ## _ctor_class_() { AFUNC(); } \
+ } AFUNC ## _ctor_instance_; \
+ }
+
+# define Q_CONSTRUCTOR_FUNCTION(AFUNC) Q_CONSTRUCTOR_FUNCTION0(AFUNC)
+#endif
+
+#ifndef Q_DESTRUCTOR_FUNCTION
+# define Q_DESTRUCTOR_FUNCTION0(AFUNC) \
+ namespace { \
+ static const struct AFUNC ## _dtor_class_ { \
+ inline AFUNC ## _dtor_class_() { } \
+ inline ~ AFUNC ## _dtor_class_() { AFUNC(); } \
+ } AFUNC ## _dtor_instance_; \
+ }
+# define Q_DESTRUCTOR_FUNCTION(AFUNC) Q_DESTRUCTOR_FUNCTION0(AFUNC)
+#endif
+
+#endif // __cplusplus
+
+#endif // QCONSTRUCTORMACROS_H
diff --git a/src/corelib/global/qcontainerinfo.h b/src/corelib/global/qcontainerinfo.h
index 21683440f8..14468510a5 100644
--- a/src/corelib/global/qcontainerinfo.h
+++ b/src/corelib/global/qcontainerinfo.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCONTAINERINFO_H
#define QCONTAINERINFO_H
@@ -87,6 +51,11 @@ template<typename C>
inline constexpr bool has_size_v<C, std::void_t<decltype(C().size())>> = true;
template<typename C, typename = void>
+inline constexpr bool has_reserve_v = false;
+template<typename C>
+inline constexpr bool has_reserve_v<C, std::void_t<decltype(C().reserve(0))>> = true;
+
+template<typename C, typename = void>
inline constexpr bool has_clear_v = false;
template<typename C>
inline constexpr bool has_clear_v<C, std::void_t<decltype(C().clear())>> = true;
diff --git a/src/corelib/global/qdarwinhelpers.h b/src/corelib/global/qdarwinhelpers.h
new file mode 100644
index 0000000000..ad72211663
--- /dev/null
+++ b/src/corelib/global/qdarwinhelpers.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTDARWINHELPERS_H
+#define QTDARWINHELPERS_H
+
+#if 0
+#pragma qt_class(QtDarwinHelpers)
+#pragma qt_sync_stop_processing
+#endif
+
+/*
+ Utility macros and inline functions
+*/
+
+#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
+# ifdef __OBJC__
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
+# else
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) class classname
+# endif
+#endif
+#ifndef Q_FORWARD_DECLARE_CF_TYPE
+# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
+#endif
+#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE
+# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
+#endif
+#ifndef Q_FORWARD_DECLARE_CG_TYPE
+# define Q_FORWARD_DECLARE_CG_TYPE(type) typedef const struct type *type##Ref
+#endif
+#ifndef Q_FORWARD_DECLARE_MUTABLE_CG_TYPE
+# define Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(type) typedef struct type *type##Ref
+#endif
+
+
+#endif // QTDARWINHELPERS_H
diff --git a/src/corelib/global/qdarwinhelpers.qdoc b/src/corelib/global/qdarwinhelpers.qdoc
new file mode 100644
index 0000000000..a827526634
--- /dev/null
+++ b/src/corelib/global/qdarwinhelpers.qdoc
@@ -0,0 +1,34 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \macro Q_FORWARD_DECLARE_OBJC_CLASS(classname)
+ \since 5.2
+ \relates <QtDarwinHelpers>
+
+ Forward-declares an Objective-C \a classname in a manner such that it can be
+ compiled as either Objective-C or C++.
+
+ This is primarily intended for use in header files that may be included by
+ both Objective-C and C++ source files.
+*/
+
+/*!
+ \macro Q_FORWARD_DECLARE_CF_TYPE(type)
+ \since 5.2
+ \relates <QtDarwinHelpers>
+
+ Forward-declares a Core Foundation \a type. This includes the actual
+ type and the ref type. For example, Q_FORWARD_DECLARE_CF_TYPE(CFString)
+ declares __CFString and CFStringRef.
+*/
+
+/*!
+ \macro Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type)
+ \since 5.2
+ \relates <QtDarwinHelpers>
+
+ Forward-declares a mutable Core Foundation \a type. This includes the actual
+ type and the ref type. For example, Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(CFMutableString)
+ declares __CFMutableString and CFMutableStringRef.
+*/
diff --git a/src/corelib/global/qendian.cpp b/src/corelib/global/qendian.cpp
index cc9158e34d..5e46109dd1 100644
--- a/src/corelib/global/qendian.cpp
+++ b/src/corelib/global/qendian.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2018 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qendian.h"
@@ -47,6 +11,7 @@ QT_BEGIN_NAMESPACE
/*!
\headerfile <QtEndian>
+ \inmodule QtCore
\title Endian Conversion Functions
\ingroup funclists
\brief The <QtEndian> header provides functions to convert between
@@ -434,28 +399,28 @@ QT_BEGIN_NAMESPACE
/*!
\fn template <typename T> QLEInteger &QLEInteger<T>::operator++()
- Performs a prefix ++ (increment) on this QLEInteger and returns a reference to
+ Performs a prefix \c{++} (increment) on this QLEInteger and returns a reference to
this object.
*/
/*!
\fn template <typename T> QLEInteger QLEInteger<T>::operator++(int)
- Performs a postfix ++ (increment) on this QLEInteger and returns a reference to
+ Performs a postfix \c{++} (increment) on this QLEInteger and returns a reference to
this object.
*/
/*!
\fn template <typename T> QLEInteger &QLEInteger<T>::operator--()
- Performs a prefix -- (decrement) on this QLEInteger and returns a reference to
+ Performs a prefix \c{--} (decrement) on this QLEInteger and returns a reference to
this object.
*/
/*!
\fn template <typename T> QLEInteger QLEInteger<T>::operator--(int)
- Performs a postfix -- (decrement) on this QLEInteger and returns a reference to
+ Performs a postfix \c{--} (decrement) on this QLEInteger and returns a reference to
this object.
*/
@@ -480,8 +445,8 @@ QT_BEGIN_NAMESPACE
The template parameter \c T must be a C++ integer type:
\list
\li 8-bit: char, signed char, unsigned char, qint8, quint8
- \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11)
- \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11)
+ \li 16-bit: short, unsigned short, qint16, quint16, char16_t
+ \li 32-bit: int, unsigned int, qint32, quint32, char32_t
\li 64-bit: long long, unsigned long long, qint64, quint64
\li platform-specific size: long, unsigned long
\li pointer size: qintptr, quintptr, qptrdiff
@@ -593,28 +558,28 @@ QT_BEGIN_NAMESPACE
/*!
\fn template <typename T> QBEInteger &QBEInteger<T>::operator++()
- Performs a prefix ++ (increment) on this QBEInteger and returns a reference to
+ Performs a prefix \c{++} (increment) on this QBEInteger and returns a reference to
this object.
*/
/*!
\fn template <typename T> QBEInteger QBEInteger<T>::operator++(int)
- Performs a postfix ++ (increment) on this QBEInteger and returns a reference to
+ Performs a postfix \c{++} (increment) on this QBEInteger and returns a reference to
this object.
*/
/*!
\fn template <typename T> QBEInteger &QBEInteger<T>::operator--()
- Performs a prefix -- (decrement) on this QBEInteger and returns a reference to
+ Performs a prefix \c{--} (decrement) on this QBEInteger and returns a reference to
this object.
*/
/*!
\fn template <typename T> QBEInteger QBEInteger<T>::operator--(int)
- Performs a postfix -- (decrement) on this QBEInteger and returns a reference to
+ Performs a postfix \c{--} (decrement) on this QBEInteger and returns a reference to
this object.
*/
diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h
index c874c5e47a..8c3b5e4374 100644
--- a/src/corelib/global/qendian.h
+++ b/src/corelib/global/qendian.h
@@ -1,46 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2021 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QENDIAN_H
#define QENDIAN_H
+#if 0
+#pragma qt_class(QtEndian)
+#endif
+
#include <QtCore/qfloat16.h>
#include <QtCore/qglobal.h>
@@ -127,7 +95,7 @@ inline constexpr quint8 qbswap_helper(quint8 source)
/*
* T qbswap(T source).
- * Changes the byte order of a value from big endian to little endian or vice versa.
+ * Changes the byte order of a value from big-endian to little-endian or vice versa.
* This function can be used if you are not concerned about alignment issues,
* and it is therefore a bit more convenient and in most cases more efficient.
*/
@@ -137,6 +105,23 @@ inline constexpr T qbswap(T source)
return T(qbswap_helper(typename QIntegerForSizeof<T>::Unsigned(source)));
}
+#ifdef QT_SUPPORTS_INT128
+// extra definitions for q(u)int128, in case std::is_integral_v<~~> == false
+inline constexpr quint128 qbswap(quint128 source)
+{
+ quint128 result = {};
+ result = qbswap_helper(quint64(source));
+ result <<= 64;
+ result |= qbswap_helper(quint64(source >> 64));
+ return result;
+}
+
+inline constexpr qint128 qbswap(qint128 source)
+{
+ return qint128(qbswap(quint128(source)));
+}
+#endif
+
// floating specializations
template<typename Float>
Float qbswapFloatHelper(Float source)
@@ -164,7 +149,7 @@ inline double qbswap(double source)
/*
* qbswap(const T src, const void *dest);
- * Changes the byte order of \a src from big endian to little endian or vice versa
+ * Changes the byte order of \a src from big-endian to little-endian or vice versa
* and stores the result in \a dest.
* There is no alignment requirements for \a dest.
*/
@@ -313,9 +298,9 @@ public:
}
static constexpr QSpecialInteger max()
- { return QSpecialInteger(std::numeric_limits<T>::max()); }
+ { return QSpecialInteger((std::numeric_limits<T>::max)()); }
static constexpr QSpecialInteger min()
- { return QSpecialInteger(std::numeric_limits<T>::min()); }
+ { return QSpecialInteger((std::numeric_limits<T>::min)()); }
};
template<typename T>
@@ -334,7 +319,7 @@ public:
static constexpr T fromSpecial(T source) { return qFromBigEndian(source); }
};
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
template<typename T>
class QLEInteger {
public:
@@ -355,8 +340,8 @@ public:
QLEInteger &operator ^=(T i);
QLEInteger &operator ++();
QLEInteger &operator --();
- QLEInteger &operator ++(int);
- QLEInteger &operator --(int);
+ QLEInteger operator ++(int);
+ QLEInteger operator --(int);
static constexpr QLEInteger max();
static constexpr QLEInteger min();
@@ -382,8 +367,8 @@ public:
QBEInteger &operator ^=(T i);
QBEInteger &operator ++();
QBEInteger &operator --();
- QBEInteger &operator ++(int);
- QBEInteger &operator --(int);
+ QBEInteger operator ++(int);
+ QBEInteger operator --(int);
static constexpr QBEInteger max();
static constexpr QBEInteger min();
diff --git a/src/corelib/global/qendian_p.h b/src/corelib/global/qendian_p.h
index bc6194fb06..8d96eba60c 100644
--- a/src/corelib/global/qendian_p.h
+++ b/src/corelib/global/qendian_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QENDIAN_P_H
#define QENDIAN_P_H
@@ -52,83 +16,195 @@
//
#include <QtCore/qendian.h>
+#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
-// Note if using multiple of these bitfields in a union; the underlying storage type must
-// match. Since we always use an unsigned storage type, unsigned and signed versions may
-// be used together, but different bit-widths may not.
-template<class S, int pos, int width>
-class QSpecialIntegerBitfield
+enum class QSpecialIntegerBitfieldInitializer {};
+constexpr QSpecialIntegerBitfieldInitializer QSpecialIntegerBitfieldZero{};
+
+template<class S>
+class QSpecialIntegerStorage
{
-protected:
- typedef typename S::StorageType T;
- typedef typename std::make_unsigned<T>::type UT;
+public:
+ using UnsignedStorageType = std::make_unsigned_t<typename S::StorageType>;
- static constexpr UT mask()
+ constexpr QSpecialIntegerStorage() = default;
+ constexpr QSpecialIntegerStorage(QSpecialIntegerBitfieldInitializer) : val(0) {}
+ constexpr QSpecialIntegerStorage(UnsignedStorageType initial) : val(initial) {}
+
+ UnsignedStorageType val;
+};
+
+template<class S, int pos, int width, class T = typename S::StorageType>
+class QSpecialIntegerAccessor;
+
+template<class S, int pos, int width, class T = typename S::StorageType>
+class QSpecialIntegerConstAccessor
+{
+ Q_DISABLE_COPY_MOVE(QSpecialIntegerConstAccessor)
+public:
+ using Storage = const QSpecialIntegerStorage<S>;
+ using Type = T;
+ using UnsignedType = std::make_unsigned_t<T>;
+
+ operator Type() const noexcept
{
- return ((UT(1) << width) - 1) << pos;
+ if constexpr (std::is_signed_v<Type>) {
+ UnsignedType i = S::fromSpecial(storage->val);
+ i <<= (sizeof(Type) * 8) - width - pos;
+ Type t = Type(i);
+ t >>= (sizeof(Type) * 8) - width;
+ return t;
+ }
+ return (S::fromSpecial(storage->val) & mask()) >> pos;
}
+
+ bool operator!() const noexcept { return !(storage->val & S::toSpecial(mask())); }
+
+ static constexpr UnsignedType mask() noexcept
+ {
+ if constexpr (width == sizeof(UnsignedType) * 8) {
+ static_assert(pos == 0);
+ return ~UnsignedType(0);
+ } else {
+ return ((UnsignedType(1) << width) - 1) << pos;
+ }
+ }
+
+private:
+ template<class Storage, typename... Accessors>
+ friend class QSpecialIntegerBitfieldUnion;
+ friend class QSpecialIntegerAccessor<S, pos, width, T>;
+
+ explicit QSpecialIntegerConstAccessor(Storage *storage) : storage(storage) {}
+
+ friend bool operator==(const QSpecialIntegerConstAccessor<S, pos, width, T> &i,
+ const QSpecialIntegerConstAccessor<S, pos, width, T> &j) noexcept
+ {
+ return ((i.storage->val ^ j.storage->val) & S::toSpecial(mask())) == 0;
+ }
+
+ friend bool operator!=(const QSpecialIntegerConstAccessor<S, pos, width, T> &i,
+ const QSpecialIntegerConstAccessor<S, pos, width, T> &j) noexcept
+ {
+ return ((i.storage->val ^ j.storage->val) & S::toSpecial(mask())) != 0;
+ }
+
+ Storage *storage;
+};
+
+template<class S, int pos, int width, class T>
+class QSpecialIntegerAccessor
+{
+ Q_DISABLE_COPY_MOVE(QSpecialIntegerAccessor)
public:
- // FIXME: val is public until qtdeclarative is fixed to not access it directly.
- UT val;
+ using Const = QSpecialIntegerConstAccessor<S, pos, width, T>;
+ using Storage = QSpecialIntegerStorage<S>;
+ using Type = T;
+ using UnsignedType = std::make_unsigned_t<T>;
- QSpecialIntegerBitfield &operator=(T t)
+ QSpecialIntegerAccessor &operator=(Type t)
{
- UT i = S::fromSpecial(val);
- i &= ~mask();
- i |= (UT(t) << pos) & mask();
- val = S::toSpecial(i);
+ UnsignedType i = S::fromSpecial(storage->val);
+ i &= ~Const::mask();
+ i |= (UnsignedType(t) << pos) & Const::mask();
+ storage->val = S::toSpecial(i);
return *this;
}
- operator T() const
+
+ operator Const() { return Const(storage); }
+
+private:
+ template<class Storage, typename... Accessors>
+ friend class QSpecialIntegerBitfieldUnion;
+
+ explicit QSpecialIntegerAccessor(Storage *storage) : storage(storage) {}
+
+ Storage *storage;
+};
+
+template<class S, typename... Accessors>
+class QSpecialIntegerBitfieldUnion
+{
+public:
+ constexpr QSpecialIntegerBitfieldUnion() = default;
+ constexpr QSpecialIntegerBitfieldUnion(QSpecialIntegerBitfieldInitializer initial)
+ : storage(initial)
+ {}
+
+ constexpr QSpecialIntegerBitfieldUnion(
+ typename QSpecialIntegerStorage<S>::UnsignedStorageType initial)
+ : storage(initial)
+ {}
+
+ template<typename A>
+ void set(typename A::Type value)
+ {
+ member<A>() = value;
+ }
+
+ template<typename A>
+ typename A::Type get() const
{
- if (std::is_signed<T>::value) {
- UT i = S::fromSpecial(val);
- i <<= (sizeof(T) * 8) - width - pos;
- T t = T(i);
- t >>= (sizeof(T) * 8) - width;
- return t;
- }
- return (S::fromSpecial(val) & mask()) >> pos;
+ return member<A>();
}
- bool operator!() const { return !(val & S::toSpecial(mask())); }
- bool operator==(QSpecialIntegerBitfield<S, pos, width> i) const
+ typename QSpecialIntegerStorage<S>::UnsignedStorageType data() const
{
- return ((val ^ i.val) & S::toSpecial(mask())) == 0;
+ return storage.val;
}
- bool operator!=(QSpecialIntegerBitfield<S, pos, width> i) const
+
+private:
+ template<typename A>
+ static constexpr bool isAccessor = std::disjunction_v<std::is_same<A, Accessors>...>;
+
+ template<typename A>
+ A member()
+ {
+ static_assert(isAccessor<A>);
+ return A(&storage);
+ }
+
+ template<typename A>
+ typename A::Const member() const
{
- return ((val ^ i.val) & S::toSpecial(mask())) != 0;
+ static_assert(isAccessor<A>);
+ return typename A::Const(&storage);
}
- QSpecialIntegerBitfield &operator+=(T i) { return (*this = (T(*this) + i)); }
- QSpecialIntegerBitfield &operator-=(T i) { return (*this = (T(*this) - i)); }
- QSpecialIntegerBitfield &operator*=(T i) { return (*this = (T(*this) * i)); }
- QSpecialIntegerBitfield &operator/=(T i) { return (*this = (T(*this) / i)); }
- QSpecialIntegerBitfield &operator%=(T i) { return (*this = (T(*this) % i)); }
- QSpecialIntegerBitfield &operator|=(T i) { return (*this = (T(*this) | i)); }
- QSpecialIntegerBitfield &operator&=(T i) { return (*this = (T(*this) & i)); }
- QSpecialIntegerBitfield &operator^=(T i) { return (*this = (T(*this) ^ i)); }
- QSpecialIntegerBitfield &operator>>=(T i) { return (*this = (T(*this) >> i)); }
- QSpecialIntegerBitfield &operator<<=(T i) { return (*this = (T(*this) << i)); }
+ QSpecialIntegerStorage<S> storage;
};
-template<typename T, int pos, int width>
-using QLEIntegerBitfield = QSpecialIntegerBitfield<QLittleEndianStorageType<T>, pos, width>;
+template<typename T, typename... Accessors>
+using QLEIntegerBitfieldUnion
+ = QSpecialIntegerBitfieldUnion<QLittleEndianStorageType<T>, Accessors...>;
+
+template<typename T, typename... Accessors>
+using QBEIntegerBitfieldUnion
+ = QSpecialIntegerBitfieldUnion<QBigEndianStorageType<T>, Accessors...>;
-template<typename T, int pos, int width>
-using QBEIntegerBitfield = QSpecialIntegerBitfield<QBigEndianStorageType<T>, pos, width>;
+template<typename... Accessors>
+using qint32_le_bitfield_union = QLEIntegerBitfieldUnion<int, Accessors...>;
+template<typename... Accessors>
+using quint32_le_bitfield_union = QLEIntegerBitfieldUnion<uint, Accessors...>;
+template<typename... Accessors>
+using qint32_be_bitfield_union = QBEIntegerBitfieldUnion<int, Accessors...>;
+template<typename... Accessors>
+using quint32_be_bitfield_union = QBEIntegerBitfieldUnion<uint, Accessors...>;
-template<int pos, int width>
-using qint32_le_bitfield = QLEIntegerBitfield<int, pos, width>;
-template<int pos, int width>
-using quint32_le_bitfield = QLEIntegerBitfield<uint, pos, width>;
-template<int pos, int width>
-using qint32_be_bitfield = QBEIntegerBitfield<int, pos, width>;
-template<int pos, int width>
-using quint32_be_bitfield = QBEIntegerBitfield<uint, pos, width>;
+template<int pos, int width, typename T = int>
+using qint32_le_bitfield_member
+ = QSpecialIntegerAccessor<QLittleEndianStorageType<int>, pos, width, T>;
+template<int pos, int width, typename T = uint>
+using quint32_le_bitfield_member
+ = QSpecialIntegerAccessor<QLittleEndianStorageType<uint>, pos, width, T>;
+template<int pos, int width, typename T = int>
+using qint32_be_bitfield_member
+ = QSpecialIntegerAccessor<QBigEndianStorageType<int>, pos, width, T>;
+template<int pos, int width, typename T = uint>
+using quint32_be_bitfield_member
+ = QSpecialIntegerAccessor<QBigEndianStorageType<uint>, pos, width, T>;
QT_END_NAMESPACE
diff --git a/src/corelib/global/qexceptionhandling.cpp b/src/corelib/global/qexceptionhandling.cpp
new file mode 100644
index 0000000000..f74eb49546
--- /dev/null
+++ b/src/corelib/global/qexceptionhandling.cpp
@@ -0,0 +1,20 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qexceptionhandling.h"
+
+#include <exception>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ \internal
+ Allows you to call std::terminate() without including <exception>.
+ Called internally from QT_TERMINATE_ON_EXCEPTION
+*/
+Q_NORETURN void qTerminate() noexcept
+{
+ std::terminate();
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qexceptionhandling.h b/src/corelib/global/qexceptionhandling.h
new file mode 100644
index 0000000000..76c6185c3e
--- /dev/null
+++ b/src/corelib/global/qexceptionhandling.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QEXCEPTIONHANDLING_H
+#define QEXCEPTIONHANDLING_H
+
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qtcoreexports.h>
+
+#if 0
+#pragma qt_class(QtExceptionHandling)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/* These wrap try/catch so we can switch off exceptions later.
+
+ Beware - do not use more than one QT_CATCH per QT_TRY, and do not use
+ the exception instance in the catch block.
+ If you can't live with those constraints, don't use these macros.
+ Use the QT_NO_EXCEPTIONS macro to protect your code instead.
+*/
+Q_NORETURN Q_DECL_COLD_FUNCTION Q_CORE_EXPORT void qTerminate() noexcept;
+#ifdef QT_NO_EXCEPTIONS
+# define QT_TRY if (true)
+# define QT_CATCH(A) else
+# define QT_THROW(A) qt_noop()
+# define QT_RETHROW qt_noop()
+# define QT_TERMINATE_ON_EXCEPTION(expr) do { expr; } while (false)
+#else
+# define QT_TRY try
+# define QT_CATCH(A) catch (A)
+# define QT_THROW(A) throw A
+# define QT_RETHROW throw
+# ifdef Q_COMPILER_NOEXCEPT
+# define QT_TERMINATE_ON_EXCEPTION(expr) do { expr; } while (false)
+# else
+# define QT_TERMINATE_ON_EXCEPTION(expr) do { try { expr; } catch (...) { qTerminate(); } } while (false)
+# endif
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QEXCEPTIONHANDLING_H
diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h
index 7f96d900fb..cc028e0095 100644
--- a/src/corelib/global/qflags.h
+++ b/src/corelib/global/qflags.h
@@ -1,48 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qcompare_impl.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFLAGS_H
#define QFLAGS_H
+#include <QtCore/qcompare_impl.h>
+#include <QtCore/qtypeinfo.h>
+
#include <initializer_list>
QT_BEGIN_NAMESPACE
@@ -60,7 +24,7 @@ public:
// Microsoft Visual Studio has buggy behavior when it comes to
// unsigned enums: even if the enum is unsigned, the enum tags are
// always signed
-# if !defined(__LP64__) && !defined(Q_CLANG_QDOC)
+# if !defined(__LP64__) && !defined(Q_QDOC)
constexpr inline Q_IMPLICIT QFlag(long value) noexcept : i(int(value)) {}
constexpr inline Q_IMPLICIT QFlag(ulong value) noexcept : i(int(long(value))) {}
# endif
@@ -93,7 +57,7 @@ class QFlags
static_assert((std::is_enum<Enum>::value), "QFlags is only usable on enumeration types.");
public:
-#if defined(Q_CC_MSVC) || defined(Q_CLANG_QDOC)
+#if defined(Q_CC_MSVC) || defined(Q_QDOC)
// see above for MSVC
// the definition below is too complex for qdoc
typedef int Int;
@@ -215,24 +179,37 @@ typedef QFlags<Enum> Flags;
// These are opt-in, for backwards compatibility
#define QT_DECLARE_TYPESAFE_OPERATORS_FOR_FLAGS_ENUM(Flags) \
+[[maybe_unused]] \
constexpr inline Flags operator~(Flags::enum_type e) noexcept \
{ return ~Flags(e); } \
+[[maybe_unused]] \
constexpr inline void operator|(Flags::enum_type f1, int f2) noexcept = delete;
#else
#define QT_DECLARE_TYPESAFE_OPERATORS_FOR_FLAGS_ENUM(Flags) \
+[[maybe_unused]] \
constexpr inline QIncompatibleFlag operator|(Flags::enum_type f1, int f2) noexcept \
{ return QIncompatibleFlag(int(f1) | f2); }
#endif
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
+[[maybe_unused]] \
constexpr inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) noexcept \
{ return QFlags<Flags::enum_type>(f1) | f2; } \
+[[maybe_unused]] \
constexpr inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept \
{ return f2 | f1; } \
+[[maybe_unused]] \
constexpr inline QFlags<Flags::enum_type> operator&(Flags::enum_type f1, Flags::enum_type f2) noexcept \
{ return QFlags<Flags::enum_type>(f1) & f2; } \
+[[maybe_unused]] \
constexpr inline QFlags<Flags::enum_type> operator&(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept \
{ return f2 & f1; } \
+[[maybe_unused]] \
+constexpr inline QFlags<Flags::enum_type> operator^(Flags::enum_type f1, Flags::enum_type f2) noexcept \
+{ return QFlags<Flags::enum_type>(f1) ^ f2; } \
+[[maybe_unused]] \
+constexpr inline QFlags<Flags::enum_type> operator^(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept \
+{ return f2 ^ f1; } \
constexpr inline void operator+(Flags::enum_type f1, Flags::enum_type f2) noexcept = delete; \
constexpr inline void operator+(Flags::enum_type f1, QFlags<Flags::enum_type> f2) noexcept = delete; \
constexpr inline void operator+(int f1, QFlags<Flags::enum_type> f2) noexcept = delete; \
@@ -245,6 +222,34 @@ constexpr inline void operator-(int f1, Flags::enum_type f2) noexcept = delete;
constexpr inline void operator-(Flags::enum_type f1, int f2) noexcept = delete; \
QT_DECLARE_TYPESAFE_OPERATORS_FOR_FLAGS_ENUM(Flags)
+// restore bit-wise enum-enum operators deprecated in C++20,
+// but used in a few places in the API
+#if __cplusplus > 201702L // assume compilers don't warn if in C++17 mode
+ // in C++20 mode, provide user-defined operators to override the deprecated operations:
+# define Q_DECLARE_MIXED_ENUM_OPERATOR(op, Ret, LHS, RHS) \
+ [[maybe_unused]] \
+ constexpr inline Ret operator op (LHS lhs, RHS rhs) noexcept \
+ { return static_cast<Ret>(qToUnderlying(lhs) op qToUnderlying(rhs)); } \
+ /* end */
+#else
+ // in C++17 mode, statically-assert that this compiler's result of the
+ // operation is the same that the C++20 version would produce:
+# define Q_DECLARE_MIXED_ENUM_OPERATOR(op, Ret, LHS, RHS) \
+ static_assert(std::is_same_v<decltype(std::declval<LHS>() op std::declval<RHS>()), Ret>);
+#endif
+
+#define Q_DECLARE_MIXED_ENUM_OPERATORS(Ret, Flags, Enum) \
+ Q_DECLARE_MIXED_ENUM_OPERATOR(|, Ret, Flags, Enum) \
+ Q_DECLARE_MIXED_ENUM_OPERATOR(&, Ret, Flags, Enum) \
+ Q_DECLARE_MIXED_ENUM_OPERATOR(^, Ret, Flags, Enum) \
+ /* end */
+
+#define Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(Ret, Flags, Enum) \
+ Q_DECLARE_MIXED_ENUM_OPERATORS(Ret, Flags, Enum) \
+ Q_DECLARE_MIXED_ENUM_OPERATORS(Ret, Enum, Flags) \
+ /* end */
+
+
QT_END_NAMESPACE
#endif // QFLAGS_H
diff --git a/src/corelib/global/qflags.qdoc b/src/corelib/global/qflags.qdoc
new file mode 100644
index 0000000000..dd3b1e4c9b
--- /dev/null
+++ b/src/corelib/global/qflags.qdoc
@@ -0,0 +1,459 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \class QFlag
+ \inmodule QtCore
+ \brief The QFlag class is a helper data type for QFlags.
+
+ It is equivalent to a plain \c int, except with respect to
+ function overloading and type conversions. You should never need
+ to use this class in your applications.
+
+ \sa QFlags
+*/
+
+/*!
+ \fn QFlag::QFlag(int value)
+
+ Constructs a QFlag object that stores the \a value.
+*/
+
+/*!
+ \fn QFlag::QFlag(uint value)
+ \since 5.3
+
+ Constructs a QFlag object that stores the \a value.
+*/
+
+/*!
+ \fn QFlag::QFlag(short value)
+ \since 5.3
+
+ Constructs a QFlag object that stores the \a value.
+*/
+
+/*!
+ \fn QFlag::QFlag(ushort value)
+ \since 5.3
+
+ Constructs a QFlag object that stores the \a value.
+*/
+
+/*!
+ \fn QFlag::operator int() const
+
+ Returns the value stored by the QFlag object.
+*/
+
+/*!
+ \fn QFlag::operator uint() const
+ \since 5.3
+
+ Returns the value stored by the QFlag object.
+*/
+
+/*!
+ \class QFlags
+ \inmodule QtCore
+ \brief The QFlags class provides a type-safe way of storing
+ OR-combinations of enum values.
+
+
+ \ingroup tools
+
+ The QFlags<Enum> class is a template class, where Enum is an enum
+ type. QFlags is used throughout Qt for storing combinations of
+ enum values.
+
+ The traditional C++ approach for storing OR-combinations of enum
+ values is to use an \c int or \c uint variable. The inconvenience
+ with this approach is that there's no type checking at all; any
+ enum value can be OR'd with any other enum value and passed on to
+ a function that takes an \c int or \c uint.
+
+ Qt uses QFlags to provide type safety. For example, the
+ Qt::Alignment type is simply a typedef for
+ QFlags<Qt::AlignmentFlag>. QLabel::setAlignment() takes a
+ Qt::Alignment parameter, which means that any combination of
+ Qt::AlignmentFlag values, or \c{{ }}, is legal:
+
+ \snippet code/src_corelib_global_qglobal.cpp 0
+
+ If you try to pass a value from another enum or just a plain
+ integer other than 0, the compiler will report an error. If you
+ need to cast integer values to flags in a untyped fashion, you can
+ use the explicit QFlags constructor as cast operator.
+
+ If you want to use QFlags for your own enum types, use
+ the Q_DECLARE_FLAGS() and Q_DECLARE_OPERATORS_FOR_FLAGS().
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 1
+
+ You can then use the \c MyClass::Options type to store
+ combinations of \c MyClass::Option values.
+
+ \section1 Flags and the Meta-Object System
+
+ The Q_DECLARE_FLAGS() macro does not expose the flags to the meta-object
+ system, so they cannot be used by Qt Script or edited in \QD.
+ To make the flags available for these purposes, the Q_FLAG() macro must
+ be used:
+
+ \snippet code/src_corelib_global_qglobal.cpp meta-object flags
+
+ \section1 Naming Convention
+
+ A sensible naming convention for enum types and associated QFlags
+ types is to give a singular name to the enum type (e.g., \c
+ Option) and a plural name to the QFlags type (e.g., \c Options).
+ When a singular name is desired for the QFlags type (e.g., \c
+ Alignment), you can use \c Flag as the suffix for the enum type
+ (e.g., \c AlignmentFlag).
+
+ \sa QFlag
+*/
+
+/*!
+ \typedef QFlags::Int
+ \since 5.0
+
+ Typedef for the integer type used for storage as well as for
+ implicit conversion. Either \c int or \c{unsigned int}, depending
+ on whether the enum's underlying type is signed or unsigned.
+*/
+
+/*!
+ \typedef QFlags::enum_type
+
+ Typedef for the Enum template type.
+*/
+
+/*!
+ \fn template<typename Enum> QFlags<Enum>::QFlags(const QFlags &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ \fn template <typename Enum> QFlags<Enum>::QFlags(Enum flags)
+
+ Constructs a QFlags object storing the \a flags.
+*/
+
+/*!
+ \fn template <typename Enum> QFlags<Enum>::QFlags()
+ \since 5.15
+
+ Constructs a QFlags object with no flags set.
+*/
+
+/*!
+ \fn template <typename Enum> QFlags<Enum>::QFlags(QFlag flag)
+
+ Constructs a QFlags object initialized with the integer \a flag.
+
+ The QFlag type is a helper type. By using it here instead of \c
+ int, we effectively ensure that arbitrary enum values cannot be
+ cast to a QFlags, whereas untyped enum values (i.e., \c int
+ values) can.
+*/
+
+/*!
+ \fn template <typename Enum> QFlags<Enum>::QFlags(std::initializer_list<Enum> flags)
+ \since 5.4
+
+ Constructs a QFlags object initialized with all \a flags
+ combined using the bitwise OR operator.
+
+ \sa operator|=(), operator|()
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator=(const QFlags &other)
+
+ Assigns \a other to this object and returns a reference to this
+ object.
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator&=(int mask)
+
+ Performs a bitwise AND operation with \a mask and stores the
+ result in this QFlags object. Returns a reference to this object.
+
+ \sa operator&(), operator|=(), operator^=()
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator&=(uint mask)
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator&=(Enum mask)
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator&=(QFlags mask)
+ \since 6.2
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator|=(QFlags other)
+
+ Performs a bitwise OR operation with \a other and stores the
+ result in this QFlags object. Returns a reference to this object.
+
+ \sa operator|(), operator&=(), operator^=()
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator|=(Enum other)
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator^=(QFlags other)
+
+ Performs a bitwise XOR operation with \a other and stores the
+ result in this QFlags object. Returns a reference to this object.
+
+ \sa operator^(), operator&=(), operator|=()
+*/
+
+/*!
+ \fn template <typename Enum> QFlags &QFlags<Enum>::operator^=(Enum other)
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags<Enum>::operator Int() const
+
+ Returns the value stored in the QFlags object as an integer.
+
+ \sa Int
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator|(QFlags other) const
+
+ Returns a QFlags object containing the result of the bitwise OR
+ operation on this object and \a other.
+
+ \sa operator|=(), operator^(), operator&(), operator~()
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator|(Enum other) const
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator^(QFlags other) const
+
+ Returns a QFlags object containing the result of the bitwise XOR
+ operation on this object and \a other.
+
+ \sa operator^=(), operator&(), operator|(), operator~()
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator^(Enum other) const
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator&(int mask) const
+
+ Returns a QFlags object containing the result of the bitwise AND
+ operation on this object and \a mask.
+
+ \sa operator&=(), operator|(), operator^(), operator~()
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator&(uint mask) const
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator&(Enum mask) const
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator&(QFlags mask) const
+ \since 6.2
+
+ \overload
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::operator~() const
+
+ Returns a QFlags object that contains the bitwise negation of
+ this object.
+
+ \sa operator&(), operator|(), operator^()
+*/
+
+/*!
+ \fn template <typename Enum> bool QFlags<Enum>::operator!() const
+
+ Returns \c true if no flag is set (i.e., if the value stored by the
+ QFlags object is 0); otherwise returns \c false.
+*/
+
+/*!
+ \fn template <typename Enum> bool QFlags<Enum>::testFlag(Enum flag) const
+ \since 4.2
+
+ Returns \c true if the flag \a flag is set, otherwise \c false.
+
+ \note if \a flag contains multiple bits set to 1 (for instance, if
+ it's an enumerator equal to the bitwise-OR of other enumerators)
+ then this function will return \c true if and only if all the bits
+ are set in this flags object. On the other hand, if \a flag contains
+ no bits set to 1 (that is, its value as a integer is 0), then this
+ function will return \c true if and only if this flags object also
+ has no bits set to 1.
+
+ \sa testAnyFlag()
+*/
+
+/*!
+ \fn template <typename Enum> bool QFlags<Enum>::testFlags(QFlags flags) const noexcept
+ \since 6.2
+
+ Returns \c true if this flags object matches the given \a flags.
+
+ If \a flags has any flags set, this flags object matches precisely
+ if all flags set in \a flags are also set in this flags object.
+ Otherwise, when \a flags has no flags set, this flags object only
+ matches if it also has no flags set.
+
+ \sa testAnyFlags()
+*/
+
+/*!
+ \fn template <typename Enum> bool QFlags<Enum>::testAnyFlag(Enum flag) const noexcept
+ \since 6.2
+
+ Returns \c true if \b any flag set in \a flag is also set in this
+ flags object, otherwise \c false. If \a flag has no flags set, the
+ return will always be \c false.
+
+ \sa testFlag()
+*/
+
+/*!
+ \fn template <typename Enum> bool QFlags<Enum>::testAnyFlags(QFlags flags) const noexcept
+ \since 6.2
+
+ Returns \c true if \b any flag set in \a flags is also set in this
+ flags object, otherwise \c false. If \a flags has no flags set, the
+ return will always be \c false.
+
+ \sa testFlags()
+*/
+
+/*!
+ \fn template <typename Enum> QFlags QFlags<Enum>::setFlag(Enum flag, bool on)
+ \since 5.7
+
+ Sets the flag \a flag if \a on is \c true or unsets it if
+ \a on is \c false. Returns a reference to this object.
+*/
+
+/*!
+ \fn template <typename Enum> QFlags<Enum> QFlags<Enum>::fromInt(Int i) noexcept
+ \since 6.2
+
+ Constructs a QFlags object representing the integer value \a i.
+*/
+
+/*!
+ \fn template <typename Enum> Int QFlags<Enum>::toInt() const noexcept
+ \since 6.2
+
+ Returns the value stored in the QFlags object as an integer. Note
+ that the returned integer may be signed or unsigned, depending on
+ whether the enum's underlying type is signed or unsigned.
+
+ \sa Int
+*/
+
+/*!
+ \fn template <typename Enum> size_t qHash(QFlags<Enum> flags, size_t seed = 0) noexcept
+ \since 6.2
+ \relates QFlags
+
+ Calculates the hash for the flags \a flags, using \a seed
+ to seed the calculation.
+*/
+
+/*!
+ \fn template <typename Enum> bool operator==(QFlags<Enum> lhs, QFlags<Enum> rhs)
+ \fn template <typename Enum> bool operator==(QFlags<Enum> lhs, Enum rhs)
+ \fn template <typename Enum> bool operator==(Enum lhs, QFlags<Enum> rhs)
+ \since 6.2
+ \relates QFlags
+
+ Compares \a lhs and \a rhs for equality; the two arguments are
+ considered equal if they represent exactly the same value
+ (bitmask).
+*/
+
+/*!
+ \fn template <typename Enum> bool operator!=(QFlags<Enum> lhs, QFlags<Enum> rhs)
+ \fn template <typename Enum> bool operator!=(QFlags<Enum> lhs, Enum rhs)
+ \fn template <typename Enum> bool operator!=(Enum lhs, QFlags<Enum> rhs)
+ \since 6.2
+ \relates QFlags
+
+ Compares \a lhs and \a rhs for inequality; the two arguments are
+ considered different if they don't represent exactly the same value
+ (bitmask).
+*/
+
+/*!
+ \macro Q_DECLARE_FLAGS(Flags, Enum)
+ \relates QFlags
+
+ The Q_DECLARE_FLAGS() macro expands to
+
+ \snippet code/src_corelib_global_qglobal.cpp 2
+
+ \a Enum is the name of an existing enum type, whereas \a Flags is
+ the name of the QFlags<\e{Enum}> typedef.
+
+ See the QFlags documentation for details.
+
+ \sa Q_DECLARE_OPERATORS_FOR_FLAGS()
+*/
+
+/*!
+ \macro Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
+ \relates QFlags
+
+ The Q_DECLARE_OPERATORS_FOR_FLAGS() macro declares global \c
+ operator|() functions for \a Flags, which is of type QFlags<T>.
+
+ See the QFlags documentation for details.
+
+ \sa Q_DECLARE_FLAGS()
+*/
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp
index 9ef197b3a1..f6f782e364 100644
--- a/src/corelib/global/qfloat16.cpp
+++ b/src/corelib/global/qfloat16.cpp
@@ -1,49 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2016 by Southwest Research Institute (R)
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2016 by Southwest Research Institute (R)
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qfloat16.h"
#include "private/qsimd_p.h"
#include <cmath> // for fpclassify()'s return values
+#include <QtCore/qdatastream.h>
+#include <QtCore/qmetatype.h>
+#include <QtCore/qtextstream.h>
+
+QT_DECL_METATYPE_EXTERN(qfloat16, Q_CORE_EXPORT)
QT_BEGIN_NAMESPACE
+QT_IMPL_METATYPE_EXTERN(qfloat16)
+
/*!
\class qfloat16
\keyword 16-bit Floating Point Support
@@ -52,6 +23,15 @@ QT_BEGIN_NAMESPACE
\inheaderfile QFloat16
\brief Provides 16-bit floating point support.
+ \compares partial
+ \compareswith partial float double {long double} qint8 quint8 qint16 quint16 \
+ qint32 quint32 long {unsigned long} qint64 quint64
+ \endcompareswith
+ \compareswith partial qint128 quint128
+ Comparison with 128-bit integral types is only supported if Qt provides
+ these types.
+ \endcompareswith
+
The \c qfloat16 class provides support for half-precision (16-bit) floating
point data. It is fully compliant with IEEE 754 as a storage type. This
implies that any arithmetic operation on a \c qfloat16 instance results in
@@ -189,25 +169,128 @@ int qfloat16::fpClassify() const noexcept
exactness is stronger the smaller the numbers are.
*/
-#if QT_COMPILER_SUPPORTS(F16C)
+#if QT_COMPILER_SUPPORTS_HERE(F16C)
static inline bool hasFastF16()
{
- // All processors with F16C also support AVX, but YMM registers
- // might not be supported by the OS, or they might be disabled.
- return qCpuHasFeature(F16C) && qCpuHasFeature(AVX);
+ // qsimd.cpp:detectProcessorFeatures() turns off this feature if AVX
+ // state-saving is not enabled by the OS
+ return qCpuHasFeature(F16C);
}
-extern "C" {
-#ifdef QFLOAT16_INCLUDE_FAST
-# define f16cextern static
-#else
-# define f16cextern extern
+#if QT_COMPILER_SUPPORTS_HERE(AVX512VL) && QT_COMPILER_SUPPORTS_HERE(AVX512BW)
+static bool hasFastF16Avx256()
+{
+ // 256-bit AVX512 don't have a performance penalty (see qstring.cpp for more info)
+ return qCpuHasFeature(ArchSkylakeAvx512);
+}
+
+static QT_FUNCTION_TARGET(ARCH_SKYLAKE_AVX512)
+void qFloatToFloat16_tail_avx256(quint16 *out, const float *in, qsizetype len) noexcept
+{
+ __mmask16 mask = _bzhi_u32(-1, len);
+ __m256 f32 = _mm256_maskz_loadu_ps(mask, in );
+ __m128i f16 = _mm256_maskz_cvtps_ph(mask, f32, _MM_FROUND_TO_NEAREST_INT);
+ _mm_mask_storeu_epi16(out, mask, f16);
+};
+
+static QT_FUNCTION_TARGET(ARCH_SKYLAKE_AVX512)
+void qFloatFromFloat16_tail_avx256(float *out, const quint16 *in, qsizetype len) noexcept
+{
+ __mmask16 mask = _bzhi_u32(-1, len);
+ __m128i f16 = _mm_maskz_loadu_epi16(mask, in);
+ __m256 f32 = _mm256_cvtph_ps(f16);
+ _mm256_mask_storeu_ps(out, mask, f32);
+};
+#endif
+
+QT_FUNCTION_TARGET(F16C)
+static void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) noexcept
+{
+ constexpr qsizetype Step = sizeof(__m256i) / sizeof(float);
+ constexpr qsizetype HalfStep = sizeof(__m128i) / sizeof(float);
+ qsizetype i = 0;
+
+ if (len >= Step) {
+ auto convertOneChunk = [=](qsizetype offset) QT_FUNCTION_TARGET(F16C) {
+ __m256 f32 = _mm256_loadu_ps(in + offset);
+ __m128i f16 = _mm256_cvtps_ph(f32, _MM_FROUND_TO_NEAREST_INT);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(out + offset), f16);
+ };
+
+ // main loop: convert Step (8) floats per iteration
+ for ( ; i + Step < len; i += Step)
+ convertOneChunk(i);
+
+ // epilogue: convert the last chunk, possibly overlapping with the last
+ // iteration of the loop
+ return convertOneChunk(len - Step);
+ }
+
+#if QT_COMPILER_SUPPORTS_HERE(AVX512VL) && QT_COMPILER_SUPPORTS_HERE(AVX512BW)
+ if (hasFastF16Avx256())
+ return qFloatToFloat16_tail_avx256(out, in, len);
#endif
-f16cextern void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) noexcept;
-f16cextern void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) noexcept;
+ if (len >= HalfStep) {
+ auto convertOneChunk = [=](qsizetype offset) QT_FUNCTION_TARGET(F16C) {
+ __m128 f32 = _mm_loadu_ps(in + offset);
+ __m128i f16 = _mm_cvtps_ph(f32, _MM_FROUND_TO_NEAREST_INT);
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(out + offset), f16);
+ };
+
+ // two conversions, possibly overlapping
+ convertOneChunk(0);
+ return convertOneChunk(len - HalfStep);
+ }
+
+ // Inlining "qfloat16::qfloat16(float f)":
+ for ( ; i < len; ++i)
+ out[i] = _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(in[i]), 0), 0);
+}
+
+QT_FUNCTION_TARGET(F16C)
+static void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) noexcept
+{
+ constexpr qsizetype Step = sizeof(__m256i) / sizeof(float);
+ constexpr qsizetype HalfStep = sizeof(__m128i) / sizeof(float);
+ qsizetype i = 0;
-#undef f16cextern
+ if (len >= Step) {
+ auto convertOneChunk = [=](qsizetype offset) QT_FUNCTION_TARGET(F16C) {
+ __m128i f16 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in + offset));
+ __m256 f32 = _mm256_cvtph_ps(f16);
+ _mm256_storeu_ps(out + offset, f32);
+ };
+
+ // main loop: convert Step (8) floats per iteration
+ for ( ; i + Step < len; i += Step)
+ convertOneChunk(i);
+
+ // epilogue: convert the last chunk, possibly overlapping with the last
+ // iteration of the loop
+ return convertOneChunk(len - Step);
+ }
+
+#if QT_COMPILER_SUPPORTS_HERE(AVX512VL) && QT_COMPILER_SUPPORTS_HERE(AVX512BW)
+ if (hasFastF16Avx256())
+ return qFloatFromFloat16_tail_avx256(out, in, len);
+#endif
+
+ if (len >= HalfStep) {
+ auto convertOneChunk = [=](qsizetype offset) QT_FUNCTION_TARGET(F16C) {
+ __m128i f16 = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(in + offset));
+ __m128 f32 = _mm_cvtph_ps(f16);
+ _mm_storeu_ps(out + offset, f32);
+ };
+
+ // two conversions, possibly overlapping
+ convertOneChunk(0);
+ return convertOneChunk(len - HalfStep);
+ }
+
+ // Inlining "qfloat16::operator float()":
+ for ( ; i < len; ++i)
+ out[i] = _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(in[i])));
}
#elif defined(__ARM_FP16_FORMAT_IEEE) && defined(__ARM_NEON__) && (__ARM_FP & 2)
@@ -289,9 +372,67 @@ Q_CORE_EXPORT void qFloatFromFloat16(float *out, const qfloat16 *in, qsizetype l
out[i] = float(in[i]);
}
+/*!
+ \fn size_t qfloat16::qHash(qfloat16 key, size_t seed)
+ \since 6.5.3
+
+ Returns the hash value for the \a key, using \a seed to seed the
+ calculation.
+
+ \note In Qt versions before 6.5, this operation was provided by the
+ qHash(float) overload. In Qt versions 6.5.0 to 6.5.2, this functionality
+ was broken in various ways. In Qt versions 6.5.3 and 6.6 onwards, this
+ overload restores the Qt 6.4 behavior.
+*/
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn qfloat16::operator<<(QDataStream &ds, qfloat16 f)
+ \relates QDataStream
+ \since 5.9
+
+ Writes a floating point number, \a f, to the stream \a ds using
+ the standard IEEE 754 format. Returns a reference to the stream.
+
+ \note In Qt versions prior to 6.3, this was a member function on
+ QDataStream.
+*/
+QDataStream &operator<<(QDataStream &ds, qfloat16 f)
+{
+ return ds << f.b16;
+}
+
+/*!
+ \fn qfloat16::operator>>(QDataStream &ds, qfloat16 &f)
+ \relates QDataStream
+ \since 5.9
+
+ Reads a floating point number from the stream \a ds into \a f,
+ using the standard IEEE 754 format. Returns a reference to the
+ stream.
+
+ \note In Qt versions prior to 6.3, this was a member function on
+ QDataStream.
+*/
+QDataStream &operator>>(QDataStream &ds, qfloat16 &f)
+{
+ return ds >> f.b16;
+}
+#endif
+
+QTextStream &operator>>(QTextStream &ts, qfloat16 &f16)
+{
+ float f;
+ ts >> f;
+ f16 = qfloat16(f);
+ return ts;
+}
+
+QTextStream &operator<<(QTextStream &ts, qfloat16 f)
+{
+ return ts << float(f);
+}
+
QT_END_NAMESPACE
#include "qfloat16tables.cpp"
-#ifdef QFLOAT16_INCLUDE_FAST
-# include "qfloat16_f16c.c"
-#endif
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h
index c2e5379eb4..30dd9a60af 100644
--- a/src/corelib/global/qfloat16.h
+++ b/src/corelib/global/qfloat16.h
@@ -1,59 +1,30 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2016 by Southwest Research Institute (R)
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2016 by Southwest Research Institute (R)
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFLOAT16_H
#define QFLOAT16_H
+#include <QtCore/qcompare.h>
#include <QtCore/qglobal.h>
-#include <QtCore/qmetatype.h>
+#include <QtCore/qhashfunctions.h>
+#include <QtCore/qmath.h>
#include <QtCore/qnamespace.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtypes.h>
+
#include <limits>
#include <string.h>
+#include <type_traits>
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__AVX2__) && !defined(__F16C__)
-// All processors that support AVX2 do support F16C too. That doesn't mean
-// we're allowed to use the intrinsics directly, so we'll do it only for
-// the Intel and Microsoft's compilers.
-# if defined(Q_CC_INTEL) || defined(Q_CC_MSVC)
+// All processors that support AVX2 do support F16C too, so we could enable the
+// feature unconditionally if __AVX2__ is defined. However, all currently
+// supported compilers except Microsoft's are able to define __F16C__ on their
+// own when the user enables the feature, so we'll trust them.
+# if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
# define __F16C__ 1
-# endif
+# endif
#endif
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
@@ -67,6 +38,11 @@ QT_BEGIN_NAMESPACE
#pragma qt_no_master_include
#endif
+#ifndef QT_NO_DATASTREAM
+class QDataStream;
+#endif
+class QTextStream;
+
class qfloat16
{
struct Wrap
@@ -76,11 +52,38 @@ class qfloat16
quint16 b16;
constexpr inline explicit Wrap(int value) : b16(quint16(value)) {}
};
+
+#ifdef QT_SUPPORTS_INT128
+ template <typename T>
+ using IsIntegral = std::disjunction<std::is_integral<T>,
+ std::is_same<std::remove_const_t<T>, qint128>,
+ std::is_same<std::remove_const_t<T>, quint128>>;
+#else
+ template <typename T>
+ using IsIntegral = std::is_integral<T>;
+#endif
+ template <typename T>
+ using if_type_is_integral = std::enable_if_t<IsIntegral<std::remove_reference_t<T>>::value,
+ bool>;
+
public:
+ using NativeType = QtPrivate::NativeFloat16Type;
+
+ static constexpr bool IsNative = QFLOAT16_IS_NATIVE;
+ using NearestFloat = std::conditional_t<IsNative, NativeType, float>;
+
constexpr inline qfloat16() noexcept : b16(0) {}
explicit qfloat16(Qt::Initialization) noexcept { }
+
+#if QFLOAT16_IS_NATIVE
+ constexpr inline qfloat16(NativeType f) : nf(f) {}
+ constexpr operator NativeType() const noexcept { return nf; }
+#else
inline qfloat16(float f) noexcept;
inline operator float() const noexcept;
+#endif
+ template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T> && !std::is_same_v<T, NearestFloat>>>
+ constexpr explicit qfloat16(T value) noexcept : qfloat16(NearestFloat(value)) {}
// Support for qIs{Inf,NaN,Finite}:
bool isInf() const noexcept { return (b16 & 0x7fff) == 0x7c00; }
@@ -91,6 +94,22 @@ public:
qfloat16 copySign(qfloat16 sign) const noexcept
{ return qfloat16(Wrap((sign.b16 & 0x8000) | (b16 & 0x7fff))); }
// Support for std::numeric_limits<qfloat16>
+
+#ifdef __STDCPP_FLOAT16_T__
+private:
+ using Bounds = std::numeric_limits<NativeType>;
+public:
+ static constexpr qfloat16 _limit_epsilon() noexcept { return Bounds::epsilon(); }
+ static constexpr qfloat16 _limit_min() noexcept { return Bounds::min(); }
+ static constexpr qfloat16 _limit_denorm_min() noexcept { return Bounds::denorm_min(); }
+ static constexpr qfloat16 _limit_max() noexcept { return Bounds::max(); }
+ static constexpr qfloat16 _limit_lowest() noexcept { return Bounds::lowest(); }
+ static constexpr qfloat16 _limit_infinity() noexcept { return Bounds::infinity(); }
+ static constexpr qfloat16 _limit_quiet_NaN() noexcept { return Bounds::quiet_NaN(); }
+#if QT_CONFIG(signaling_nan)
+ static constexpr qfloat16 _limit_signaling_NaN() noexcept { return Bounds::signaling_NaN(); }
+#endif
+#else
static constexpr qfloat16 _limit_epsilon() noexcept { return qfloat16(Wrap(0x1400)); }
static constexpr qfloat16 _limit_min() noexcept { return qfloat16(Wrap(0x400)); }
static constexpr qfloat16 _limit_denorm_min() noexcept { return qfloat16(Wrap(1)); }
@@ -101,11 +120,29 @@ public:
#if QT_CONFIG(signaling_nan)
static constexpr qfloat16 _limit_signaling_NaN() noexcept { return qfloat16(Wrap(0x7d00)); }
#endif
+#endif
inline constexpr bool isNormal() const noexcept
{ return (b16 & 0x7c00) && (b16 & 0x7c00) != 0x7c00; }
private:
- quint16 b16;
- constexpr inline explicit qfloat16(Wrap nibble) noexcept : b16(nibble.b16) {}
+ // ABI note: Qt 6's qfloat16 began with just a quint16 member so it ended
+ // up passed in general purpose registers in any function call taking
+ // qfloat16 by value (it has trivial copy constructors). This means the
+ // integer member in the anonymous union below must remain until a
+ // binary-incompatible version of Qt. If you remove it, on platforms using
+ // the System V ABI for C, the native type is passed in FP registers.
+ union {
+ quint16 b16;
+#if QFLOAT16_IS_NATIVE
+ NativeType nf;
+#endif
+ };
+ constexpr inline explicit qfloat16(Wrap nibble) noexcept :
+#if QFLOAT16_IS_NATIVE && defined(__cpp_lib_bit_cast)
+ nf(std::bit_cast<NativeType>(nibble.b16))
+#else
+ b16(nibble.b16)
+#endif
+ {}
Q_CORE_EXPORT static const quint32 mantissatable[];
Q_CORE_EXPORT static const quint32 exponenttable[];
@@ -123,17 +160,23 @@ private:
return f;
}
- friend inline qfloat16 operator+(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<float>(a) + static_cast<float>(b)); }
- friend inline qfloat16 operator-(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<float>(a) - static_cast<float>(b)); }
- friend inline qfloat16 operator*(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<float>(a) * static_cast<float>(b)); }
- friend inline qfloat16 operator/(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<float>(a) / static_cast<float>(b)); }
+ friend inline qfloat16 operator+(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) + static_cast<NearestFloat>(b)); }
+ friend inline qfloat16 operator-(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) - static_cast<NearestFloat>(b)); }
+ friend inline qfloat16 operator*(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) * static_cast<NearestFloat>(b)); }
+ friend inline qfloat16 operator/(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) / static_cast<NearestFloat>(b)); }
+
+ friend size_t qHash(qfloat16 key, size_t seed = 0) noexcept
+ { return qHash(float(key), seed); } // 6.4 algorithm, so keep using it; ### Qt 7: fix QTBUG-116077
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wfloat-conversion")
#define QF16_MAKE_ARITH_OP_FP(FP, OP) \
friend inline FP operator OP(qfloat16 lhs, FP rhs) noexcept { return static_cast<FP>(lhs) OP rhs; } \
friend inline FP operator OP(FP lhs, qfloat16 rhs) noexcept { return lhs OP static_cast<FP>(rhs); }
#define QF16_MAKE_ARITH_OP_EQ_FP(FP, OP_EQ, OP) \
friend inline qfloat16& operator OP_EQ(qfloat16& lhs, FP rhs) noexcept \
- { lhs = qfloat16(float(static_cast<FP>(lhs) OP rhs)); return lhs; }
+ { lhs = qfloat16(NearestFloat(static_cast<FP>(lhs) OP rhs)); return lhs; }
#define QF16_MAKE_ARITH_OP(FP) \
QF16_MAKE_ARITH_OP_FP(FP, +) \
QF16_MAKE_ARITH_OP_FP(FP, -) \
@@ -147,6 +190,9 @@ private:
QF16_MAKE_ARITH_OP(long double)
QF16_MAKE_ARITH_OP(double)
QF16_MAKE_ARITH_OP(float)
+#if QFLOAT16_IS_NATIVE
+ QF16_MAKE_ARITH_OP(NativeType)
+#endif
#undef QF16_MAKE_ARITH_OP
#undef QF16_MAKE_ARITH_OP_FP
@@ -160,46 +206,72 @@ private:
QF16_MAKE_ARITH_OP_INT(/)
#undef QF16_MAKE_ARITH_OP_INT
-QT_WARNING_PUSH
QT_WARNING_DISABLE_FLOAT_COMPARE
- friend inline bool operator>(qfloat16 a, qfloat16 b) noexcept { return static_cast<float>(a) > static_cast<float>(b); }
- friend inline bool operator<(qfloat16 a, qfloat16 b) noexcept { return static_cast<float>(a) < static_cast<float>(b); }
- friend inline bool operator>=(qfloat16 a, qfloat16 b) noexcept { return static_cast<float>(a) >= static_cast<float>(b); }
- friend inline bool operator<=(qfloat16 a, qfloat16 b) noexcept { return static_cast<float>(a) <= static_cast<float>(b); }
- friend inline bool operator==(qfloat16 a, qfloat16 b) noexcept { return static_cast<float>(a) == static_cast<float>(b); }
- friend inline bool operator!=(qfloat16 a, qfloat16 b) noexcept { return static_cast<float>(a) != static_cast<float>(b); }
-
-#define QF16_MAKE_BOOL_OP_FP(FP, OP) \
- friend inline bool operator OP(qfloat16 lhs, FP rhs) noexcept { return static_cast<FP>(lhs) OP rhs; } \
- friend inline bool operator OP(FP lhs, qfloat16 rhs) noexcept { return lhs OP static_cast<FP>(rhs); }
-#define QF16_MAKE_BOOL_OP(FP) \
- QF16_MAKE_BOOL_OP_FP(FP, <) \
- QF16_MAKE_BOOL_OP_FP(FP, >) \
- QF16_MAKE_BOOL_OP_FP(FP, >=) \
- QF16_MAKE_BOOL_OP_FP(FP, <=) \
- QF16_MAKE_BOOL_OP_FP(FP, ==) \
- QF16_MAKE_BOOL_OP_FP(FP, !=)
-
- QF16_MAKE_BOOL_OP(long double)
- QF16_MAKE_BOOL_OP(double)
- QF16_MAKE_BOOL_OP(float)
-#undef QF16_MAKE_BOOL_OP
-#undef QF16_MAKE_BOOL_OP_FP
-
-#define QF16_MAKE_BOOL_OP_INT(OP) \
- friend inline bool operator OP(qfloat16 a, int b) noexcept { return static_cast<float>(a) OP static_cast<float>(b); } \
- friend inline bool operator OP(int a, qfloat16 b) noexcept { return static_cast<float>(a) OP static_cast<float>(b); }
-
- QF16_MAKE_BOOL_OP_INT(>)
- QF16_MAKE_BOOL_OP_INT(<)
- QF16_MAKE_BOOL_OP_INT(>=)
- QF16_MAKE_BOOL_OP_INT(<=)
- QF16_MAKE_BOOL_OP_INT(==)
- QF16_MAKE_BOOL_OP_INT(!=)
-#undef QF16_MAKE_BOOL_OP_INT
+#if QFLOAT16_IS_NATIVE
+# define QF16_CONSTEXPR constexpr
+# define QF16_PARTIALLY_ORDERED Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE
+#else
+# define QF16_CONSTEXPR
+# define QF16_PARTIALLY_ORDERED Q_DECLARE_PARTIALLY_ORDERED
+#endif
+
+ friend QF16_CONSTEXPR bool comparesEqual(const qfloat16 &lhs, const qfloat16 &rhs) noexcept
+ { return static_cast<NearestFloat>(lhs) == static_cast<NearestFloat>(rhs); }
+ friend QF16_CONSTEXPR
+ Qt::partial_ordering compareThreeWay(const qfloat16 &lhs, const qfloat16 &rhs) noexcept
+ { return Qt::compareThreeWay(static_cast<NearestFloat>(lhs), static_cast<NearestFloat>(rhs)); }
+ QF16_PARTIALLY_ORDERED(qfloat16)
+
+#define QF16_MAKE_ORDER_OP_FP(FP) \
+ friend QF16_CONSTEXPR bool comparesEqual(const qfloat16 &lhs, FP rhs) noexcept \
+ { return static_cast<FP>(lhs) == rhs; } \
+ friend QF16_CONSTEXPR \
+ Qt::partial_ordering compareThreeWay(const qfloat16 &lhs, FP rhs) noexcept \
+ { return Qt::compareThreeWay(static_cast<FP>(lhs), rhs); } \
+ QF16_PARTIALLY_ORDERED(qfloat16, FP)
+
+ QF16_MAKE_ORDER_OP_FP(long double)
+ QF16_MAKE_ORDER_OP_FP(double)
+ QF16_MAKE_ORDER_OP_FP(float)
+#if QFLOAT16_IS_NATIVE
+ QF16_MAKE_ORDER_OP_FP(qfloat16::NativeType)
+#endif
+#undef QF16_MAKE_ORDER_OP_FP
+
+ template <typename T, if_type_is_integral<T> = true>
+ friend QF16_CONSTEXPR bool comparesEqual(const qfloat16 &lhs, T rhs) noexcept
+ { return static_cast<NearestFloat>(lhs) == static_cast<NearestFloat>(rhs); }
+ template <typename T, if_type_is_integral<T> = true>
+ friend QF16_CONSTEXPR Qt::partial_ordering compareThreeWay(const qfloat16 &lhs, T rhs) noexcept
+ { return Qt::compareThreeWay(static_cast<NearestFloat>(lhs), static_cast<NearestFloat>(rhs)); }
+
+ QF16_PARTIALLY_ORDERED(qfloat16, qint8)
+ QF16_PARTIALLY_ORDERED(qfloat16, quint8)
+ QF16_PARTIALLY_ORDERED(qfloat16, qint16)
+ QF16_PARTIALLY_ORDERED(qfloat16, quint16)
+ QF16_PARTIALLY_ORDERED(qfloat16, qint32)
+ QF16_PARTIALLY_ORDERED(qfloat16, quint32)
+ QF16_PARTIALLY_ORDERED(qfloat16, long)
+ QF16_PARTIALLY_ORDERED(qfloat16, unsigned long)
+ QF16_PARTIALLY_ORDERED(qfloat16, qint64)
+ QF16_PARTIALLY_ORDERED(qfloat16, quint64)
+#ifdef QT_SUPPORTS_INT128
+ QF16_PARTIALLY_ORDERED(qfloat16, qint128)
+ QF16_PARTIALLY_ORDERED(qfloat16, quint128)
+#endif
+
+#undef QF16_PARTIALLY_ORDERED
+#undef QF16_CONSTEXPR
QT_WARNING_POP
+
+#ifndef QT_NO_DATASTREAM
+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &ds, qfloat16 f);
+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &ds, qfloat16 &f);
+#endif
+ friend Q_CORE_EXPORT QTextStream &operator<<(QTextStream &ts, qfloat16 f);
+ friend Q_CORE_EXPORT QTextStream &operator>>(QTextStream &ts, qfloat16 &f);
};
Q_DECLARE_TYPEINFO(qfloat16, Q_PRIMITIVE_TYPE);
@@ -214,6 +286,43 @@ Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length
[[nodiscard]] inline int qFpClassify(qfloat16 f) noexcept { return f.fpClassify(); }
// [[nodiscard]] quint32 qFloatDistance(qfloat16 a, qfloat16 b);
+[[nodiscard]] inline qfloat16 qSqrt(qfloat16 f)
+{
+#if defined(__cpp_lib_extended_float) && defined(__STDCPP_FLOAT16_T__) && 0
+ // https://wg21.link/p1467 - disabled until tested
+ using namespace std;
+ return sqrt(f);
+#elif QFLOAT16_IS_NATIVE && defined(__HAVE_FLOAT16) && __HAVE_FLOAT16
+ // This C library (glibc) has sqrtf16().
+ return sqrtf16(f);
+#else
+ bool mathUpdatesErrno = true;
+# if defined(__NO_MATH_ERRNO__) || defined(_M_FP_FAST)
+ mathUpdatesErrno = false;
+# elif defined(math_errhandling)
+ mathUpdatesErrno = (math_errhandling & MATH_ERRNO);
+# endif
+
+ // We don't need to set errno to EDOM if (f >= 0 && f != -0 && !isnan(f))
+ // (or if we don't care about errno in the first place). We can merge the
+ // NaN check with by negating and inverting: !(0 > f), and leaving zero to
+ // sqrtf().
+ if (!mathUpdatesErrno || !(0 > f)) {
+# if defined(__AVX512FP16__)
+ __m128h v = _mm_set_sh(f);
+ v = _mm_sqrt_sh(v, v);
+ return _mm_cvtsh_h(v);
+# endif
+ }
+
+ // WG14's N2601 does not provide a way to tell which types an
+ // implementation supports, so we assume it doesn't and fall back to FP32
+ float f32 = float(f);
+ f32 = sqrtf(f32);
+ return qfloat16::NearestFloat(f32);
+#endif
+}
+
// The remainder of these utility functions complement qglobal.h
[[nodiscard]] inline int qRound(qfloat16 d) noexcept
{ return qRound(static_cast<float>(d)); }
@@ -223,8 +332,8 @@ Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length
[[nodiscard]] inline bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
{
- float f1 = static_cast<float>(p1);
- float f2 = static_cast<float>(p2);
+ qfloat16::NearestFloat f1 = static_cast<qfloat16::NearestFloat>(p1);
+ qfloat16::NearestFloat f2 = static_cast<qfloat16::NearestFloat>(p2);
// The significand precision for IEEE754 half precision is
// 11 bits (10 explicitly stored), or approximately 3 decimal
// digits. In selecting the fuzzy comparison factor of 102.5f
@@ -248,9 +357,9 @@ Q_CORE_EXPORT void qFloatFromFloat16(float *, const qfloat16 *, qsizetype length
}
inline int qIntCast(qfloat16 f) noexcept
-{ return int(static_cast<float>(f)); }
+{ return int(static_cast<qfloat16::NearestFloat>(f)); }
-#ifndef Q_QDOC
+#if !defined(Q_QDOC) && !QFLOAT16_IS_NATIVE
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wc99-extensions")
QT_WARNING_DISABLE_GCC("-Wold-style-cast")
@@ -275,8 +384,12 @@ inline qfloat16::qfloat16(float f) noexcept
if (mantissa) // keep nan from truncating to inf
mantissa = qMax(1U << shift, mantissa);
} else {
- // round half to even
+ // Round half to even. First round up by adding one in the most
+ // significant bit we'll be discarding:
mantissa += round;
+ // If the last bit we'll be keeping is now set, but all later bits are
+ // clear, we were at half and shouldn't have rounded up; decrement will
+ // clear this last kept bit. Any later set bit hides the decrement.
if (mantissa & (1 << shift))
--mantissa;
}
@@ -306,34 +419,53 @@ inline qfloat16::operator float() const noexcept
return f;
#endif
}
-#endif
+#endif // Q_QDOC and non-native
/*
qHypot compatibility; see ../kernel/qmath.h
*/
namespace QtPrivate {
-template <typename R>
-struct QHypotType<R, qfloat16> { using type = decltype(std::hypot(R(1), 1.0f)); };
-template <typename R>
-struct QHypotType<qfloat16, R> { using type = decltype(std::hypot(1.0f, R(1))); };
-template <> struct QHypotType<qfloat16, qfloat16> { using type = qfloat16; };
+template <> struct QHypotType<qfloat16, qfloat16>
+{
+ using type = qfloat16;
+};
+template <typename R> struct QHypotType<R, qfloat16>
+{
+ using type = std::conditional_t<std::is_floating_point_v<R>, R, double>;
+};
+template <typename R> struct QHypotType<qfloat16, R> : QHypotType<R, qfloat16>
+{
+};
}
+
// Avoid passing qfloat16 to std::hypot(), while ensuring return types
// consistent with the above:
-template<typename F, typename ...Fs> auto qHypot(F first, Fs... rest);
-template <typename T, typename std::enable_if<!std::is_same<qfloat16, T>::value, int>::type = 0>
-auto qHypot(T x, qfloat16 y) { return qHypot(x, float(y)); }
-template <typename T, typename std::enable_if<!std::is_same<qfloat16, T>::value, int>::type = 0>
-auto qHypot(qfloat16 x, T y) { return qHypot(float(x), y); }
-template <> inline auto qHypot(qfloat16 x, qfloat16 y)
+inline auto qHypot(qfloat16 x, qfloat16 y)
{
-#if (defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)) || defined (__ARM_FP16_FORMAT_IEEE)
+#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__) || QFLOAT16_IS_NATIVE
return QtPrivate::QHypotHelper<qfloat16>(x).add(y).result();
#else
return qfloat16(qHypot(float(x), float(y)));
#endif
}
-#if __cpp_lib_hypot >= 201603L // Expected to be true
+
+// in ../kernel/qmath.h
+template<typename F, typename ...Fs> auto qHypot(F first, Fs... rest);
+
+template <typename T> typename QtPrivate::QHypotType<T, qfloat16>::type
+qHypot(T x, qfloat16 y)
+{
+ if constexpr (std::is_floating_point_v<T>)
+ return qHypot(x, float(y));
+ else
+ return qHypot(qfloat16(x), y);
+}
+template <typename T> auto qHypot(qfloat16 x, T y)
+{
+ return qHypot(y, x);
+}
+
+#if defined(__cpp_lib_hypot) && __cpp_lib_hypot >= 201603L // Expected to be true
// If any are not qfloat16, convert each qfloat16 to float:
/* (The following splits the some-but-not-all-qfloat16 cases up, using
(X|Y|Z)&~(X&Y&Z) = X ? ~(Y&Z) : Y|Z = X&~(Y&Z) | ~X&Y | ~X&~Y&Z,
@@ -342,22 +474,22 @@ template <typename Ty, typename Tz,
typename std::enable_if<
// Ty, Tz aren't both qfloat16:
!(std::is_same_v<qfloat16, Ty> && std::is_same_v<qfloat16, Tz>), int>::type = 0>
-auto qHypot(qfloat16 x, Ty y, Tz z) { return qHypot(float(x), y, z); }
+auto qHypot(qfloat16 x, Ty y, Tz z) { return qHypot(qfloat16::NearestFloat(x), y, z); }
template <typename Tx, typename Tz,
typename std::enable_if<
// Tx isn't qfloat16:
!std::is_same_v<qfloat16, Tx>, int>::type = 0>
-auto qHypot(Tx x, qfloat16 y, Tz z) { return qHypot(x, float(y), z); }
+auto qHypot(Tx x, qfloat16 y, Tz z) { return qHypot(x, qfloat16::NearestFloat(y), z); }
template <typename Tx, typename Ty,
typename std::enable_if<
// Neither Tx nor Ty is qfloat16:
!std::is_same_v<qfloat16, Tx> && !std::is_same_v<qfloat16, Ty>, int>::type = 0>
-auto qHypot(Tx x, Ty y, qfloat16 z) { return qHypot(x, y, float(z)); }
+auto qHypot(Tx x, Ty y, qfloat16 z) { return qHypot(x, y, qfloat16::NearestFloat(z)); }
+
// If all are qfloat16, stay with qfloat16 (albeit via float, if no native support):
-template <>
inline auto qHypot(qfloat16 x, qfloat16 y, qfloat16 z)
{
-#if (defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)) || defined (__ARM_FP16_FORMAT_IEEE)
+#if (defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)) || QFLOAT16_IS_NATIVE
return QtPrivate::QHypotHelper<qfloat16>(x).add(y).add(z).result();
#else
return qfloat16(qHypot(float(x), float(y), float(z)));
@@ -367,8 +499,6 @@ inline auto qHypot(qfloat16 x, qfloat16 y, qfloat16 z)
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(qfloat16)
-
namespace std {
template<>
class numeric_limits<QT_PREPEND_NAMESPACE(qfloat16)> : public numeric_limits<float>
diff --git a/src/corelib/global/qfloat16_f16c.c b/src/corelib/global/qfloat16_f16c.c
deleted file mode 100644
index d60a021bdb..0000000000
--- a/src/corelib/global/qfloat16_f16c.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qsimd_p.h"
-
-// The x86 F16C instructions operate on AVX registers, so AVX support is
-// required.
-#if QT_COMPILER_SUPPORTS_HERE(AVX)
-
-#ifdef __cplusplus
-QT_BEGIN_NAMESPACE
-extern "C" {
-#endif
-
-QT_FUNCTION_TARGET(F16C)
-void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) Q_DECL_NOEXCEPT
-{
- qsizetype i = 0;
- int epilog_i;
- for (; i < len - 7; i += 8)
- _mm_storeu_si128((__m128i *)(out + i), _mm256_cvtps_ph(_mm256_loadu_ps(in + i), 0));
- if (i < len - 3) {
- _mm_storel_epi64((__m128i *)(out + i), _mm_cvtps_ph(_mm_loadu_ps(in + i), 0));
- i += 4;
- }
- // Inlining "qfloat16::qfloat16(float f)":
- for (epilog_i = 0; i < len && epilog_i < 3; ++i, ++epilog_i)
- out[i] = _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(in[i]), 0), 0);
-}
-
-QT_FUNCTION_TARGET(F16C)
-void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) Q_DECL_NOEXCEPT
-{
- qsizetype i = 0;
- int epilog_i;
- for (; i < len - 7; i += 8)
- _mm256_storeu_ps(out + i, _mm256_cvtph_ps(_mm_loadu_si128((const __m128i *)(in + i))));
- if (i < len - 3) {
- _mm_storeu_ps(out + i, _mm_cvtph_ps(_mm_loadl_epi64((const __m128i *)(in + i))));
- i += 4;
- }
- // Inlining "qfloat16::operator float()":
- for (epilog_i = 0; i < len && epilog_i < 3; ++i, ++epilog_i)
- out[i] = _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(in[i])));
-}
-
-#ifdef __cplusplus
-} // extern "C"
-QT_END_NAMESPACE
-#endif
-
-#endif // QT_COMPILER_SUPPORTS_HERE(AVX)
diff --git a/src/corelib/global/qfloat16tables.cpp b/src/corelib/global/qfloat16tables.cpp
index 55173366c6..4aa620c4e7 100644
--- a/src/corelib/global/qfloat16tables.cpp
+++ b/src/corelib/global/qfloat16tables.cpp
@@ -1,43 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 by Southwest Research Institute (R)
-** Copyright (C) 2019 Intel Corporation.
-** Copyright (C) 2020 The Qt Company Ltd.
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 by Southwest Research Institute (R)
+// Copyright (C) 2019 Intel Corporation.
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/* This file was generated by util/qfloat16-tables/gen_qfloat16_tables.cpp */
diff --git a/src/corelib/global/qforeach.h b/src/corelib/global/qforeach.h
new file mode 100644
index 0000000000..ab0e20b989
--- /dev/null
+++ b/src/corelib/global/qforeach.h
@@ -0,0 +1,84 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2019 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QFOREACH_H
+#define QFOREACH_H
+
+#include <QtCore/qtclasshelpermacros.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtdeprecationmarkers.h>
+#include <QtCore/qttypetraits.h>
+
+QT_BEGIN_NAMESPACE
+
+#if 0
+#pragma qt_class(QForeach)
+#pragma qt_sync_stop_processing
+#endif
+
+#ifndef QT_NO_FOREACH
+
+namespace QtPrivate {
+
+template <typename T>
+class QForeachContainer {
+ Q_DISABLE_COPY_MOVE(QForeachContainer)
+public:
+ QForeachContainer(const T &t) : c(t), i(std::as_const(c).begin()), e(std::as_const(c).end()) {}
+ QForeachContainer(T &&t) : c(std::move(t)), i(std::as_const(c).begin()), e(std::as_const(c).end()) {}
+
+ T c;
+ typename T::const_iterator i, e;
+};
+
+// Containers that have a detach function are considered shared, and are OK in a foreach loop
+template <typename T, typename = decltype(std::declval<T>().detach())>
+inline void warnIfContainerIsNotShared(int) {}
+
+#if QT_DEPRECATED_SINCE(6, 0)
+// Other containers will copy themselves if used in foreach, this use is deprecated
+template <typename T>
+QT_DEPRECATED_VERSION_X_6_0("Do not use foreach/Q_FOREACH with containers which are not implicitly shared. "
+ "Prefer using a range-based for loop with these containers: `for (const auto &it : container)`, "
+ "keeping in mind that range-based for doesn't copy the container as Q_FOREACH does")
+inline void warnIfContainerIsNotShared(...) {}
+#endif
+
+template<typename T>
+QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t)
+{
+ warnIfContainerIsNotShared<typename std::decay<T>::type>(0);
+ return QForeachContainer<typename std::decay<T>::type>(std::forward<T>(t));
+}
+
+}
+
+// Use C++17 if statement with initializer. User's code ends up in a else so
+// scoping of different ifs is not broken
+#define Q_FOREACH_IMPL(variable, name, container) \
+ for (auto name = QtPrivate::qMakeForeachContainer(container); name.i != name.e; ++name.i) \
+ if (variable = *name.i; false) {} else
+
+#define Q_FOREACH_JOIN(A, B) Q_FOREACH_JOIN_IMPL(A, B)
+#define Q_FOREACH_JOIN_IMPL(A, B) A ## B
+
+#define Q_FOREACH(variable, container) \
+ Q_FOREACH_IMPL(variable, Q_FOREACH_JOIN(_container_, __LINE__), container)
+#endif // QT_NO_FOREACH
+
+#define Q_FOREVER for(;;)
+#ifndef QT_NO_KEYWORDS
+# ifndef QT_NO_FOREACH
+# ifndef foreach
+# define foreach Q_FOREACH
+# endif
+# endif // QT_NO_FOREACH
+# ifndef forever
+# define forever Q_FOREVER
+# endif
+#endif
+
+QT_END_NAMESPACE
+
+#endif /* QFOREACH_H */
diff --git a/src/corelib/global/qforeach.qdoc b/src/corelib/global/qforeach.qdoc
new file mode 100644
index 0000000000..e6abf0e29c
--- /dev/null
+++ b/src/corelib/global/qforeach.qdoc
@@ -0,0 +1,72 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \macro forever
+ \relates <QForeach>
+
+ This macro is provided for convenience for writing infinite
+ loops.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 31
+
+ It is equivalent to \c{for (;;)}.
+
+ If you're worried about namespace pollution, you can disable this
+ macro by adding the following line to your \c .pro file:
+
+ \snippet code/src_corelib_global_qglobal.cpp 32
+
+ If using other build systems, you can add \c QT_NO_KEYWORDS to the
+ list of pre-defined macros.
+
+ \sa Q_FOREVER
+*/
+
+/*!
+ \macro Q_FOREVER
+ \relates <QForeach>
+
+ Same as \l{forever}.
+
+ This macro is available even when \c no_keywords is specified
+ using the \c .pro file's \c CONFIG variable.
+
+ \sa foreach()
+*/
+
+/*!
+ \macro foreach(variable, container)
+ \relates <QForeach>
+
+ This macro is used to implement Qt's \c foreach loop. The \a
+ variable parameter is a variable name or variable definition; the
+ \a container parameter is a Qt container whose value type
+ corresponds to the type of the variable. See \l{The foreach
+ Keyword} for details.
+
+ If you're worried about namespace pollution, you can disable this
+ macro by adding the following line to your \c .pro file:
+
+ \snippet code/src_corelib_global_qglobal.cpp 33
+
+ \note Since Qt 5.7, the use of this macro is discouraged.
+ Use C++11 range-based \c for, possibly with \c {std::as_const()},
+ as needed.
+*/
+
+/*!
+ \macro Q_FOREACH(variable, container)
+ \relates <QForeach>
+
+ Same as foreach(\a variable, \a container).
+
+ This macro is available even when \c no_keywords is specified
+ using the \c .pro file's \c CONFIG variable.
+
+ \note Since Qt 5.7, the use of this macro is discouraged.
+ Use C++11 range-based \c for, possibly with \c {std::as_const()},
+ as needed.
+*/
diff --git a/src/corelib/global/qfunctionpointer.h b/src/corelib/global/qfunctionpointer.h
new file mode 100644
index 0000000000..3884954f89
--- /dev/null
+++ b/src/corelib/global/qfunctionpointer.h
@@ -0,0 +1,23 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QFUNCTIONPOINTER_H
+#define QFUNCTIONPOINTER_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#if 0
+#pragma qt_class(QFunctionPointer)
+#endif
+
+#if defined(__cplusplus)
+
+QT_BEGIN_NAMESPACE
+
+typedef void (*QFunctionPointer)();
+
+QT_END_NAMESPACE
+
+#endif // __cplusplus
+
+#endif // QFUNCTIONPOINTER_H
diff --git a/src/corelib/global/qfunctionpointer.qdoc b/src/corelib/global/qfunctionpointer.qdoc
new file mode 100644
index 0000000000..13f82bc011
--- /dev/null
+++ b/src/corelib/global/qfunctionpointer.qdoc
@@ -0,0 +1,9 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*! \typedef QFunctionPointer
+ \relates <QFunctionPointer>
+
+ This is a typedef for \c{void (*)()}, a pointer to a function that takes
+ no arguments and returns void.
+*/
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 00538d6798..9a7531e4c5 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1,74 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2017 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformdefs.h"
#include "qstring.h"
+#include "qbytearrayview.h"
#include "qlist.h"
#include "qdir.h"
#include "qdatetime.h"
-#include "qoperatingsystemversion.h"
-#include "qoperatingsystemversion_p.h"
-#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
-# include "qoperatingsystemversion_win_p.h"
-# include "private/qwinregistry_p.h"
-#endif // Q_OS_WIN || Q_OS_CYGWIN
#include <private/qlocale_tools_p.h>
#include "qnativeinterface.h"
-
-#include <qmutex.h>
-#include <QtCore/private/qlocking_p.h>
-
-#include <stdlib.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include <exception> // For std::terminate
-#ifndef QT_NO_EXCEPTIONS
-#include <new> // For std::bad_alloc
-#endif
-
-#include <errno.h>
-#if defined(Q_CC_MSVC)
-# include <crtdbg.h>
-#endif
+#include "qnativeinterface_p.h"
#ifdef Q_OS_WIN
# include <qt_windows.h>
@@ -78,28 +20,6 @@
# include <envLib.h>
#endif
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
-#include <qjniobject.h>
-#endif
-
-#if defined(Q_OS_SOLARIS)
-# include <sys/systeminfo.h>
-#endif
-
-#if defined(Q_OS_DARWIN) && __has_include(<IOKit/IOKitLib.h>)
-# include <IOKit/IOKitLib.h>
-# include <private/qcore_mac_p.h>
-#endif
-
-#ifdef Q_OS_UNIX
-#include <sys/utsname.h>
-#include <private/qcore_unix_p.h>
-#endif
-
-#ifdef Q_OS_BSD4
-#include <sys/sysctl.h>
-#endif
-
#if defined(Q_OS_INTEGRITY)
extern "C" {
// Function mmap resides in libshm_client.a. To be able to link with it one needs
@@ -113,3182 +33,62 @@ extern "C" {
}
#endif
-#include "archdetect.cpp"
-
-#ifdef qFatal
-// the qFatal in this file are just redirections from elsewhere, so
-// don't capture any context again
-# undef qFatal
-#endif
-
QT_BEGIN_NAMESPACE
-// Statically check assumptions about the environment we're running
-// in. The idea here is to error or warn if otherwise implicit Qt
-// assumptions are not fulfilled on new hardware or compilers
-// (if this list becomes too long, consider factoring into a separate file)
-static_assert(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
-static_assert(sizeof(int) == 4, "Qt assumes that int is 32 bits");
-static_assert(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined incorrectly");
-static_assert(sizeof(float) == 4, "Qt assumes that float is 32 bits");
-static_assert(sizeof(char16_t) == 2, "Qt assumes that char16_t is 16 bits");
-static_assert(sizeof(char32_t) == 4, "Qt assumes that char32_t is 32 bits");
-#if defined(Q_OS_WIN)
-static_assert(sizeof(wchar_t) == sizeof(char16_t));
-#endif
-static_assert(std::numeric_limits<int>::radix == 2,
- "Qt assumes binary integers");
-static_assert((std::numeric_limits<int>::max() + std::numeric_limits<int>::lowest()) == -1,
- "Qt assumes two's complement integers");
-static_assert(sizeof(wchar_t) == sizeof(char32_t) || sizeof(wchar_t) == sizeof(char16_t),
- "Qt assumes wchar_t is compatible with either char32_t or char16_t");
-
-// While we'd like to check for __STDC_IEC_559__, as per ISO/IEC 9899:2011
-// Annex F (C11, normative for C++11), there are a few corner cases regarding
-// denormals where GHS compiler is relying hardware behavior that is not IEC
-// 559 compliant. So split the check in several subchecks.
-
-// On GHC the compiler reports std::numeric_limits<float>::is_iec559 as false.
-// This is all right according to our needs.
-#if !defined(Q_CC_GHS)
-static_assert(std::numeric_limits<float>::is_iec559,
- "Qt assumes IEEE 754 floating point");
-#endif
-
-// Technically, presence of NaN and infinities are implied from the above check,
-// but double checking our environment doesn't hurt...
-static_assert(std::numeric_limits<float>::has_infinity &&
- std::numeric_limits<float>::has_quiet_NaN &&
- std::numeric_limits<float>::has_signaling_NaN,
- "Qt assumes IEEE 754 floating point");
-
-// is_iec559 checks for ISO/IEC/IEEE 60559:2011 (aka IEEE 754-2008) compliance,
-// but that allows for a non-binary radix. We need to recheck that.
-// Note how __STDC_IEC_559__ would instead check for IEC 60559:1989, aka
-// ANSI/IEEE 754−1985, which specifically implies binary floating point numbers.
-static_assert(std::numeric_limits<float>::radix == 2,
- "Qt assumes binary IEEE 754 floating point");
-
-// not required by the definition of size_t, but we depend on this
-static_assert(sizeof(size_t) == sizeof(void *), "size_t and a pointer don't have the same size");
-static_assert(sizeof(size_t) == sizeof(qsizetype)); // implied by the definition
-static_assert((std::is_same<qsizetype, qptrdiff>::value));
-
-// Check that our own typedefs are not broken.
-static_assert(sizeof(qint8) == 1, "Internal error, qint8 is misdefined");
-static_assert(sizeof(qint16)== 2, "Internal error, qint16 is misdefined");
-static_assert(sizeof(qint32) == 4, "Internal error, qint32 is misdefined");
-static_assert(sizeof(qint64) == 8, "Internal error, qint64 is misdefined");
-
-/*!
- \class QFlag
- \inmodule QtCore
- \brief The QFlag class is a helper data type for QFlags.
-
- It is equivalent to a plain \c int, except with respect to
- function overloading and type conversions. You should never need
- to use this class in your applications.
-
- \sa QFlags
-*/
-
-/*!
- \fn QFlag::QFlag(int value)
-
- Constructs a QFlag object that stores the \a value.
-*/
-
-/*!
- \fn QFlag::QFlag(uint value)
- \since 5.3
-
- Constructs a QFlag object that stores the \a value.
-*/
-
-/*!
- \fn QFlag::QFlag(short value)
- \since 5.3
-
- Constructs a QFlag object that stores the \a value.
-*/
-
-/*!
- \fn QFlag::QFlag(ushort value)
- \since 5.3
-
- Constructs a QFlag object that stores the \a value.
-*/
-
-/*!
- \fn QFlag::operator int() const
-
- Returns the value stored by the QFlag object.
-*/
-
-/*!
- \fn QFlag::operator uint() const
- \since 5.3
-
- Returns the value stored by the QFlag object.
-*/
-
-/*!
- \class QFlags
- \inmodule QtCore
- \brief The QFlags class provides a type-safe way of storing
- OR-combinations of enum values.
-
-
- \ingroup tools
-
- The QFlags<Enum> class is a template class, where Enum is an enum
- type. QFlags is used throughout Qt for storing combinations of
- enum values.
-
- The traditional C++ approach for storing OR-combinations of enum
- values is to use an \c int or \c uint variable. The inconvenience
- with this approach is that there's no type checking at all; any
- enum value can be OR'd with any other enum value and passed on to
- a function that takes an \c int or \c uint.
-
- Qt uses QFlags to provide type safety. For example, the
- Qt::Alignment type is simply a typedef for
- QFlags<Qt::AlignmentFlag>. QLabel::setAlignment() takes a
- Qt::Alignment parameter, which means that any combination of
- Qt::AlignmentFlag values, or \c{{ }}, is legal:
-
- \snippet code/src_corelib_global_qglobal.cpp 0
-
- If you try to pass a value from another enum or just a plain
- integer other than 0, the compiler will report an error. If you
- need to cast integer values to flags in a untyped fashion, you can
- use the explicit QFlags constructor as cast operator.
-
- If you want to use QFlags for your own enum types, use
- the Q_DECLARE_FLAGS() and Q_DECLARE_OPERATORS_FOR_FLAGS().
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 1
-
- You can then use the \c MyClass::Options type to store
- combinations of \c MyClass::Option values.
-
- \section1 Flags and the Meta-Object System
-
- The Q_DECLARE_FLAGS() macro does not expose the flags to the meta-object
- system, so they cannot be used by Qt Script or edited in Qt Designer.
- To make the flags available for these purposes, the Q_FLAG() macro must
- be used:
-
- \snippet code/src_corelib_global_qglobal.cpp meta-object flags
-
- \section1 Naming Convention
-
- A sensible naming convention for enum types and associated QFlags
- types is to give a singular name to the enum type (e.g., \c
- Option) and a plural name to the QFlags type (e.g., \c Options).
- When a singular name is desired for the QFlags type (e.g., \c
- Alignment), you can use \c Flag as the suffix for the enum type
- (e.g., \c AlignmentFlag).
-
- \sa QFlag
-*/
-
-/*!
- \typedef QFlags::Int
- \since 5.0
-
- Typedef for the integer type used for storage as well as for
- implicit conversion. Either \c int or \c{unsigned int}, depending
- on whether the enum's underlying type is signed or unsigned.
-*/
-
-/*!
- \typedef QFlags::enum_type
-
- Typedef for the Enum template type.
-*/
-
-/*!
- \fn template<typename Enum> QFlags<Enum>::QFlags(const QFlags &other)
-
- Constructs a copy of \a other.
-*/
-
-/*!
- \fn template <typename Enum> QFlags<Enum>::QFlags(Enum flags)
-
- Constructs a QFlags object storing the \a flags.
-*/
-
-/*!
- \fn template <typename Enum> QFlags<Enum>::QFlags()
- \since 5.15
-
- Constructs a QFlags object with no flags set.
-*/
-
-/*!
- \fn template <typename Enum> QFlags<Enum>::QFlags(QFlag flag)
-
- Constructs a QFlags object initialized with the integer \a flag.
-
- The QFlag type is a helper type. By using it here instead of \c
- int, we effectively ensure that arbitrary enum values cannot be
- cast to a QFlags, whereas untyped enum values (i.e., \c int
- values) can.
-*/
-
-/*!
- \fn template <typename Enum> QFlags<Enum>::QFlags(std::initializer_list<Enum> flags)
- \since 5.4
-
- Constructs a QFlags object initialized with all \a flags
- combined using the bitwise OR operator.
-
- \sa operator|=(), operator|()
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator=(const QFlags &other)
-
- Assigns \a other to this object and returns a reference to this
- object.
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator&=(int mask)
-
- Performs a bitwise AND operation with \a mask and stores the
- result in this QFlags object. Returns a reference to this object.
-
- \sa operator&(), operator|=(), operator^=()
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator&=(uint mask)
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator&=(Enum mask)
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator&=(QFlags mask)
- \since 6.2
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator|=(QFlags other)
-
- Performs a bitwise OR operation with \a other and stores the
- result in this QFlags object. Returns a reference to this object.
-
- \sa operator|(), operator&=(), operator^=()
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator|=(Enum other)
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator^=(QFlags other)
-
- Performs a bitwise XOR operation with \a other and stores the
- result in this QFlags object. Returns a reference to this object.
-
- \sa operator^(), operator&=(), operator|=()
-*/
-
-/*!
- \fn template <typename Enum> QFlags &QFlags<Enum>::operator^=(Enum other)
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags<Enum>::operator Int() const
-
- Returns the value stored in the QFlags object as an integer.
-
- \sa Int
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator|(QFlags other) const
-
- Returns a QFlags object containing the result of the bitwise OR
- operation on this object and \a other.
-
- \sa operator|=(), operator^(), operator&(), operator~()
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator|(Enum other) const
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator^(QFlags other) const
-
- Returns a QFlags object containing the result of the bitwise XOR
- operation on this object and \a other.
-
- \sa operator^=(), operator&(), operator|(), operator~()
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator^(Enum other) const
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator&(int mask) const
-
- Returns a QFlags object containing the result of the bitwise AND
- operation on this object and \a mask.
-
- \sa operator&=(), operator|(), operator^(), operator~()
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator&(uint mask) const
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator&(Enum mask) const
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator&(QFlags mask) const
- \since 6.2
-
- \overload
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::operator~() const
-
- Returns a QFlags object that contains the bitwise negation of
- this object.
-
- \sa operator&(), operator|(), operator^()
-*/
-
-/*!
- \fn template <typename Enum> bool QFlags<Enum>::operator!() const
-
- Returns \c true if no flag is set (i.e., if the value stored by the
- QFlags object is 0); otherwise returns \c false.
-*/
-
-/*!
- \fn template <typename Enum> bool QFlags<Enum>::testFlag(Enum flag) const
- \since 4.2
-
- Returns \c true if the flag \a flag is set, otherwise \c false.
-
- \note if \a flag contains multiple bits set to 1 (for instance, if
- it's an enumerator equal to the bitwise-OR of other enumerators)
- then this function will return \c true if and only if all the bits
- are set in this flags object. On the other hand, if \a flag contains
- no bits set to 1 (that is, its value as a integer is 0), then this
- function will return \c true if and only if this flags object also
- has no bits set to 1.
-
- \sa testAnyFlag()
-*/
-
-/*!
- \fn template <typename Enum> bool QFlags<Enum>::testFlags(QFlags flags) const noexcept
- \since 6.2
-
- Returns \c true if this flags object matches the given \a flags.
-
- If \a flags has any flags set, this flags object matches precisely
- if all flags set in \a flags are also set in this flags object.
- Otherwise, when \a flags has no flags set, this flags object only
- matches if it also has no flags set.
-
- \sa testAnyFlags()
-*/
-
-/*!
- \fn template <typename Enum> bool QFlags<Enum>::testAnyFlag(Enum flag) const noexcept
- \since 6.2
-
- Returns \c true if \b any flag set in \a flag is also set in this
- flags object, otherwise \c false. If \a flag has no flags set, the
- return will always be \c false.
-
- \sa testFlag()
-*/
-
-/*!
- \fn template <typename Enum> bool QFlags<Enum>::testAnyFlags(QFlags flags) const noexcept
- \since 6.2
-
- Returns \c true if \b any flag set in \a flags is also set in this
- flags object, otherwise \c false. If \a flags has no flags set, the
- return will always be \c false.
-
- \sa testFlags()
-*/
-
-/*!
- \fn template <typename Enum> QFlags QFlags<Enum>::setFlag(Enum flag, bool on)
- \since 5.7
-
- Sets the flag \a flag if \a on is \c true or unsets it if
- \a on is \c false. Returns a reference to this object.
-*/
-
-/*!
- \fn template <typename Enum> QFlags<Enum> QFlags<Enum>::fromInt(Int i) noexcept
- \since 6.2
-
- Constructs a QFlags object representing the integer value \a i.
-*/
-
-/*!
- \fn template <typename Enum> Int QFlags<Enum>::toInt() const noexcept
- \since 6.2
-
- Returns the value stored in the QFlags object as an integer. Note
- that the returned integer may be signed or unsigned, depending on
- whether the enum's underlying type is signed or unsigned.
-
- \sa Int
-*/
-
-/*!
- \fn template <typename Enum> size_t qHash(QFlags<Enum> flags, size_t seed = 0) noexcept
- \since 6.2
- \relates QFlags
-
- Calculates the hash for the flags \a flags, using \a seed
- to seed the calcualtion.
-*/
-
-/*!
- \fn template <typename Enum> bool operator==(QFlags<Enum> lhs, QFlags<Enum> rhs)
- \fn template <typename Enum> bool operator==(QFlags<Enum> lhs, Enum rhs)
- \fn template <typename Enum> bool operator==(Enum lhs, QFlags<Enum> rhs)
- \since 6.2
- \relates QFlags
-
- Compares \a lhs and \a rhs for equality; the two arguments are
- considered equal if they represent exactly the same value
- (bitmask).
-*/
-
-/*!
- \fn template <typename Enum> bool operator!=(QFlags<Enum> lhs, QFlags<Enum> rhs)
- \fn template <typename Enum> bool operator!=(QFlags<Enum> lhs, Enum rhs)
- \fn template <typename Enum> bool operator!=(Enum lhs, QFlags<Enum> rhs)
- \since 6.2
- \relates QFlags
-
- Compares \a lhs and \a rhs for inequality; the two arguments are
- considered different if they don't represent exactly the same value
- (bitmask).
-*/
-
-/*!
- \macro Q_DISABLE_COPY(Class)
- \relates QObject
-
- Disables the use of copy constructors and assignment operators
- for the given \a Class.
-
- Instances of subclasses of QObject should not be thought of as
- values that can be copied or assigned, but as unique identities.
- This means that when you create your own subclass of QObject
- (director or indirect), you should \e not give it a copy constructor
- or an assignment operator. However, it may not enough to simply
- omit them from your class, because, if you mistakenly write some code
- that requires a copy constructor or an assignment operator (it's easy
- to do), your compiler will thoughtfully create it for you. You must
- do more.
-
- The curious user will have seen that the Qt classes derived
- from QObject typically include this macro in a private section:
-
- \snippet code/src_corelib_global_qglobal.cpp 43
-
- It declares a copy constructor and an assignment operator in the
- private section, so that if you use them by mistake, the compiler
- will report an error.
-
- \snippet code/src_corelib_global_qglobal.cpp 44
-
- But even this might not catch absolutely every case. You might be
- tempted to do something like this:
-
- \snippet code/src_corelib_global_qglobal.cpp 45
-
- First of all, don't do that. Most compilers will generate code that
- uses the copy constructor, so the privacy violation error will be
- reported, but your C++ compiler is not required to generate code for
- this statement in a specific way. It could generate code using
- \e{neither} the copy constructor \e{nor} the assignment operator we
- made private. In that case, no error would be reported, but your
- application would probably crash when you called a member function
- of \c{w}.
-
- \sa Q_DISABLE_COPY_MOVE
-*/
-
-/*!
- \macro Q_DISABLE_COPY_MOVE(Class)
- \relates QObject
-
- A convenience macro that disables the use of copy constructors, assignment
- operators, move constructors and move assignment operators for the given
- \a Class.
-
- \sa Q_DISABLE_COPY
- \since 5.13
-*/
-
-/*!
- \macro Q_DECLARE_FLAGS(Flags, Enum)
- \relates QFlags
-
- The Q_DECLARE_FLAGS() macro expands to
-
- \snippet code/src_corelib_global_qglobal.cpp 2
-
- \a Enum is the name of an existing enum type, whereas \a Flags is
- the name of the QFlags<\e{Enum}> typedef.
-
- See the QFlags documentation for details.
-
- \sa Q_DECLARE_OPERATORS_FOR_FLAGS()
-*/
-
-/*!
- \macro Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
- \relates QFlags
-
- The Q_DECLARE_OPERATORS_FOR_FLAGS() macro declares global \c
- operator|() functions for \a Flags, which is of type QFlags<T>.
-
- See the QFlags documentation for details.
-
- \sa Q_DECLARE_FLAGS()
-*/
+using namespace Qt::StringLiterals;
/*!
\headerfile <QtGlobal>
+ \inmodule QtCore
\title Global Qt Declarations
\ingroup funclists
- \brief The <QtGlobal> header file includes the fundamental global
- declarations. It is included by most other Qt header files.
-
- The global declarations include \l{types}, \l{functions} and
- \l{macros}.
-
- The type definitions are partly convenience definitions for basic
- types (some of which guarantee certain bit-sizes on all platforms
- supported by Qt), partly types related to Qt message handling. The
- functions are related to generating messages, Qt version handling
- and comparing and adjusting object values. And finally, some of
- the declared macros enable programmers to add compiler or platform
- specific code to their applications, while others are convenience
- macros for larger operations.
-
- \section1 Types
-
- The header file declares several type definitions that guarantee a
- specified bit-size on all platforms supported by Qt for various
- basic types, for example \l qint8 which is a signed char
- guaranteed to be 8-bit on all platforms supported by Qt. The
- header file also declares the \l qlonglong type definition for \c
- {long long int } (\c __int64 on Windows).
-
- Several convenience type definitions are declared: \l qreal for \c
- double or \c float, \l uchar for \c unsigned char, \l uint for \c unsigned
- int, \l ulong for \c unsigned long and \l ushort for \c unsigned
- short.
-
- Finally, the QtMsgType definition identifies the various messages
- that can be generated and sent to a Qt message handler;
- QtMessageHandler is a type definition for a pointer to a function with
- the signature
- \c {void myMessageHandler(QtMsgType, const QMessageLogContext &, const char *)}.
- QMessageLogContext class contains the line, file, and function the
- message was logged at. This information is created by the QMessageLogger
- class.
-
- \section1 Functions
-
- The <QtGlobal> header file contains several functions comparing
- and adjusting an object's value. These functions take a template
- type as argument: You can retrieve the absolute value of an object
- using the qAbs() function, and you can bound a given object's
- value by given minimum and maximum values using the qBound()
- function. You can retrieve the minimum and maximum of two given
- objects using qMin() and qMax() respectively. All these functions
- return a corresponding template type; the template types can be
- replaced by any other type.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 3
-
- <QtGlobal> also contains functions that generate messages from the
- given string argument: qDebug(), qInfo(), qWarning(), qCritical(),
- and qFatal(). These functions call the message handler
- with the given message.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 4
-
- The remaining functions are qRound() and qRound64(), which both
- accept a \c double or \c float value as their argument returning
- the value rounded up to the nearest integer and 64-bit integer
- respectively, the qInstallMessageHandler() function which installs
- the given QtMessageHandler, and the qVersion() function which
- returns the version number of Qt at run-time as a string.
-
- \section1 Macros
-
- The <QtGlobal> header file provides a range of macros (Q_CC_*)
- that are defined if the application is compiled using the
- specified platforms. For example, the Q_CC_SUN macro is defined if
- the application is compiled using Forte Developer, or Sun Studio
- C++. The header file also declares a range of macros (Q_OS_*)
- that are defined for the specified platforms. For example,
- Q_OS_UNIX which is defined for the Unix-based systems.
-
- The purpose of these macros is to enable programmers to add
- compiler or platform specific code to their application.
-
- The remaining macros are convenience macros for larger operations:
- The QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRANSLATE_NOOP3()
- macros provide the possibility of marking strings for delayed
- translation. QT_TR_N_NOOP(), QT_TRANSLATE_N_NOOP(), and
- QT_TRANSLATE_N_NOOP3() are numerator dependent variants of these.
- The Q_ASSERT() and Q_ASSERT_X() enables warning messages of various
- level of refinement. The Q_FOREACH() and foreach() macros
- implement Qt's foreach loop.
-
- The Q_INT64_C() and Q_UINT64_C() macros wrap signed and unsigned
- 64-bit integer literals in a platform-independent way. The
- Q_CHECK_PTR() macro prints a warning containing the source code's
- file name and line number, saying that the program ran out of
- memory, if the pointer is \nullptr. The qPrintable() and qUtf8Printable()
- macros represent an easy way of printing text.
-
- The QT_POINTER_SIZE macro expands to the size of a pointer in bytes.
-
- The macros QT_VERSION and QT_VERSION_STR expand to a numeric value
- or a string, respectively, that specifies the version of Qt that the
- application is compiled against.
-
- \sa <QtAlgorithms>, QSysInfo
-*/
-
-/*!
- \typedef qreal
- \relates <QtGlobal>
-
- Typedef for \c double unless Qt is configured with the
- \c{-qreal float} option.
-*/
-
-/*! \typedef uchar
- \relates <QtGlobal>
-
- Convenience typedef for \c{unsigned char}.
-*/
-
-/*! \typedef ushort
- \relates <QtGlobal>
-
- Convenience typedef for \c{unsigned short}.
-*/
-
-/*! \typedef uint
- \relates <QtGlobal>
-
- Convenience typedef for \c{unsigned int}.
-*/
-
-/*! \typedef ulong
- \relates <QtGlobal>
-
- Convenience typedef for \c{unsigned long}.
-*/
-
-/*! \typedef qint8
- \relates <QtGlobal>
-
- Typedef for \c{signed char}. This type is guaranteed to be 8-bit
- on all platforms supported by Qt.
-*/
-
-/*!
- \typedef quint8
- \relates <QtGlobal>
-
- Typedef for \c{unsigned char}. This type is guaranteed to
- be 8-bit on all platforms supported by Qt.
-*/
-
-/*! \typedef qint16
- \relates <QtGlobal>
-
- Typedef for \c{signed short}. This type is guaranteed to be
- 16-bit on all platforms supported by Qt.
-*/
-
-/*!
- \typedef quint16
- \relates <QtGlobal>
-
- Typedef for \c{unsigned short}. This type is guaranteed to
- be 16-bit on all platforms supported by Qt.
-*/
-
-/*! \typedef qint32
- \relates <QtGlobal>
-
- Typedef for \c{signed int}. This type is guaranteed to be 32-bit
- on all platforms supported by Qt.
-*/
-
-/*!
- \typedef quint32
- \relates <QtGlobal>
-
- Typedef for \c{unsigned int}. This type is guaranteed to
- be 32-bit on all platforms supported by Qt.
-*/
-
-/*! \typedef qint64
- \relates <QtGlobal>
-
- Typedef for \c{long long int}. This type is guaranteed to be 64-bit
- on all platforms supported by Qt.
-
- Literals of this type can be created using the Q_INT64_C() macro:
-
- \snippet code/src_corelib_global_qglobal.cpp 5
-
- \sa Q_INT64_C(), quint64, qlonglong
-*/
-
-/*!
- \typedef quint64
- \relates <QtGlobal>
-
- Typedef for \c{unsigned long long int}. This type is guaranteed to
- be 64-bit on all platforms supported by Qt.
-
- Literals of this type can be created using the Q_UINT64_C()
- macro:
-
- \snippet code/src_corelib_global_qglobal.cpp 6
-
- \sa Q_UINT64_C(), qint64, qulonglong
-*/
-
-/*!
- \typedef qintptr
- \relates <QtGlobal>
-
- Integral type for representing pointers in a signed integer (useful for
- hashing, etc.).
-
- Typedef for either qint32 or qint64. This type is guaranteed to
- be the same size as a pointer on all platforms supported by Qt. On
- a system with 32-bit pointers, qintptr is a typedef for qint32;
- on a system with 64-bit pointers, qintptr is a typedef for
- qint64.
-
- Note that qintptr is signed. Use quintptr for unsigned values.
-
- In order to print values of this type by using formatted-output
- facilities such as \c{printf()}, qDebug(), QString::asprintf() and
- so on, you can use the \c{PRIdQINTPTR} and \c{PRIiQINTPTR}
- macros as format specifiers. They will both print the value as a
- base 10 number.
-
- \code
- qintptr p = 123;
- printf("The pointer is %" PRIdQINTPTR "\n", p);
- \endcode
-
- \sa qptrdiff, qint32, qint64
-*/
-
-/*!
- \macro PRIdQINTPTR
- \macro PRIiQINTPTR
- \since 6.2
- \relates <QtGlobal>
-
- See qintptr.
-*/
-
-/*!
- \typedef quintptr
- \relates <QtGlobal>
-
- Integral type for representing pointers in an unsigned integer (useful for
- hashing, etc.).
-
- Typedef for either quint32 or quint64. This type is guaranteed to
- be the same size as a pointer on all platforms supported by Qt. On
- a system with 32-bit pointers, quintptr is a typedef for quint32;
- on a system with 64-bit pointers, quintptr is a typedef for
- quint64.
-
- Note that quintptr is unsigned. Use qptrdiff for signed values.
-
- In order to print values of this type by using formatted-output
- facilities such as \c{printf()}, qDebug(), QString::asprintf() and
- so on, you can use the following macros as format specifiers:
-
- \list
- \li \c{PRIuQUINTPTR}: prints the value as a base 10 number.
- \li \c{PRIoQUINTPTR}: prints the value as a base 8 number.
- \li \c{PRIxQUINTPTR}: prints the value as a base 16 number, using lowercase \c{a-f} letters.
- \li \c{PRIXQUINTPTR}: prints the value as a base 16 number, using uppercase \c{A-F} letters.
- \endlist
-
- \code
- quintptr p = 123u;
- printf("The pointer value is 0x%" PRIXQUINTPTR "\n", p);
- \endcode
-
- \sa qptrdiff, quint32, quint64
-*/
-
-/*!
- \macro PRIoQUINTPTR
- \macro PRIuQUINTPTR
- \macro PRIxQUINTPTR
- \macro PRIXQUINTPTR
- \since 6.2
- \relates <QtGlobal>
-
- See quintptr.
-*/
-
-/*!
- \typedef qptrdiff
- \relates <QtGlobal>
-
- Integral type for representing pointer differences.
-
- Typedef for either qint32 or qint64. This type is guaranteed to be
- the same size as a pointer on all platforms supported by Qt. On a
- system with 32-bit pointers, quintptr is a typedef for quint32; on
- a system with 64-bit pointers, quintptr is a typedef for quint64.
-
- Note that qptrdiff is signed. Use quintptr for unsigned values.
-
- In order to print values of this type by using formatted-output
- facilities such as \c{printf()}, qDebug(), QString::asprintf() and
- so on, you can use the \c{PRIdQPTRDIFF} and \c{PRIiQPTRDIFF}
- macros as format specifiers. They will both print the value as a
- base 10 number.
-
- \code
- qptrdiff d = 123;
- printf("The difference is %" PRIdQPTRDIFF "\n", d);
- \endcode
-
- \sa quintptr, qint32, qint64
-*/
-
-/*!
- \macro PRIdQPTRDIFF
- \macro PRIiQPTRDIFF
- \since 6.2
- \relates <QtGlobal>
-
- See qptrdiff.
-*/
-
-/*!
- \typedef qsizetype
- \relates <QtGlobal>
- \since 5.10
-
- Integral type providing Posix' \c ssize_t for all platforms.
-
- This type is guaranteed to be the same size as a \c size_t on all
- platforms supported by Qt.
-
- Note that qsizetype is signed. Use \c size_t for unsigned values.
-
- In order to print values of this type by using formatted-output
- facilities such as \c{printf()}, qDebug(), QString::asprintf() and
- so on, you can use the \c{PRIdQSIZETYPE} and \c{PRIiQSIZETYPE}
- macros as format specifiers. They will both print the value as a
- base 10 number.
-
- \code
- qsizetype s = 123;
- printf("The size is %" PRIdQSIZETYPE "\n", s);
- \endcode
-
- \sa qptrdiff
-*/
-
-/*!
- \macro PRIdQSIZETYPE
- \macro PRIiQSIZETYPE
- \since 6.2
- \relates <QtGlobal>
-
- See qsizetype.
-*/
-
-/*!
- \enum QtMsgType
- \relates <QtGlobal>
-
- This enum describes the messages that can be sent to a message
- handler (QtMessageHandler). You can use the enum to identify and
- associate the various message types with the appropriate
- actions.
-
- \value QtDebugMsg
- A message generated by the qDebug() function.
- \value QtInfoMsg
- A message generated by the qInfo() function.
- \value QtWarningMsg
- A message generated by the qWarning() function.
- \value QtCriticalMsg
- A message generated by the qCritical() function.
- \value QtFatalMsg
- A message generated by the qFatal() function.
- \value QtSystemMsg
-
- \c QtInfoMsg was added in Qt 5.5.
-
- \sa QtMessageHandler, qInstallMessageHandler()
-*/
-
-/*! \typedef QFunctionPointer
- \relates <QtGlobal>
-
- This is a typedef for \c{void (*)()}, a pointer to a function that takes
- no arguments and returns void.
-*/
-
-/*! \macro qint64 Q_INT64_C(literal)
- \relates <QtGlobal>
-
- Wraps the signed 64-bit integer \a literal in a
- platform-independent way.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 8
-
- \sa qint64, Q_UINT64_C()
-*/
-
-/*! \macro quint64 Q_UINT64_C(literal)
- \relates <QtGlobal>
-
- Wraps the unsigned 64-bit integer \a literal in a
- platform-independent way.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 9
-
- \sa quint64, Q_INT64_C()
-*/
-
-/*! \typedef qlonglong
- \relates <QtGlobal>
-
- Typedef for \c{long long int} (\c __int64 on Windows). This is
- the same as \l qint64.
-
- \sa qulonglong, qint64
-*/
-
-/*!
- \typedef qulonglong
- \relates <QtGlobal>
-
- Typedef for \c{unsigned long long int} (\c{unsigned __int64} on
- Windows). This is the same as \l quint64.
-
- \sa quint64, qlonglong
-*/
-
-/*! \fn template <typename T> T qAbs(const T &t)
- \relates <QtGlobal>
-
- Compares \a t to the 0 of type T and returns the absolute
- value. Thus if T is \e {double}, then \a t is compared to
- \e{(double) 0}.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 10
-*/
-
-/*! \fn int qRound(double d)
- \relates <QtGlobal>
-
- Rounds \a d to the nearest integer.
-
- Rounds half away from zero (e.g. 0.5 -> 1, -0.5 -> -1).
-
- \note This function does not guarantee correctness for high precisions.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 11A
-*/
-
-/*! \fn int qRound(float d)
- \relates <QtGlobal>
-
- Rounds \a d to the nearest integer.
-
- Rounds half away from zero (e.g. 0.5f -> 1, -0.5f -> -1).
-
- \note This function does not guarantee correctness for high precisions.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 11B
-*/
-
-/*! \fn qint64 qRound64(double d)
- \relates <QtGlobal>
-
- Rounds \a d to the nearest 64-bit integer.
-
- Rounds half away from zero (e.g. 0.5 -> 1, -0.5 -> -1).
-
- \note This function does not guarantee correctness for high precisions.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 12A
-*/
-
-/*! \fn qint64 qRound64(float d)
- \relates <QtGlobal>
-
- Rounds \a d to the nearest 64-bit integer.
-
- Rounds half away from zero (e.g. 0.5f -> 1, -0.5f -> -1).
-
- \note This function does not guarantee correctness for high precisions.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 12B
-*/
-
-/*! \fn template <typename T> const T &qMin(const T &a, const T &b)
- \relates <QtGlobal>
-
- Returns the minimum of \a a and \a b.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 13
-
- \sa qMax(), qBound()
-*/
-
-/*! \fn template <typename T> const T &qMax(const T &a, const T &b)
- \relates <QtGlobal>
-
- Returns the maximum of \a a and \a b.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 14
-
- \sa qMin(), qBound()
-*/
-
-/*! \fn template <typename T> const T &qBound(const T &min, const T &val, const T &max)
- \relates <QtGlobal>
-
- Returns \a val bounded by \a min and \a max. This is equivalent
- to qMax(\a min, qMin(\a val, \a max)).
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 15
-
- \sa qMin(), qMax()
-*/
-
-/*! \fn template <typename T> auto qOverload(T functionPointer)
- \relates <QtGlobal>
- \since 5.7
-
- Returns a pointer to an overloaded function. The template
- parameter is the list of the argument types of the function.
- \a functionPointer is the pointer to the (member) function:
-
- \snippet code/src_corelib_global_qglobal.cpp 52
-
- If a member function is also const-overloaded \l qConstOverload and
- \l qNonConstOverload need to be used.
-
- qOverload() requires C++14 enabled. In C++11-only code, the helper
- classes QOverload, QConstOverload, and QNonConstOverload can be used directly:
-
- \snippet code/src_corelib_global_qglobal.cpp 53
-
- \note Qt detects the necessary C++14 compiler support by way of the feature
- test recommendations from
- \l{https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations}
- {C++ Committee's Standing Document 6}.
-
- \sa qConstOverload(), qNonConstOverload(), {Differences between String-Based
- and Functor-Based Connections}
-*/
-
-/*! \fn template <typename T> auto qConstOverload(T memberFunctionPointer)
- \relates <QtGlobal>
- \since 5.7
-
- Returns the \a memberFunctionPointer pointer to a constant member function:
-
- \snippet code/src_corelib_global_qglobal.cpp 54
-
- \sa qOverload, qNonConstOverload, {Differences between String-Based
- and Functor-Based Connections}
-*/
-
-/*! \fn template <typename T> auto qNonConstOverload(T memberFunctionPointer)
- \relates <QtGlobal>
- \since 5.7
-
- Returns the \a memberFunctionPointer pointer to a non-constant member function:
-
- \snippet code/src_corelib_global_qglobal.cpp 54
-
- \sa qOverload, qNonConstOverload, {Differences between String-Based
- and Functor-Based Connections}
-*/
-
-/*!
- \macro QT_VERSION_CHECK
- \relates <QtGlobal>
-
- Turns the major, minor and patch numbers of a version into an
- integer, 0xMMNNPP (MM = major, NN = minor, PP = patch). This can
- be compared with another similarly processed version id.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qt-version-check
-
- \sa QT_VERSION
-*/
-
-/*!
- \macro QT_VERSION
- \relates <QtGlobal>
-
- This macro expands a numeric value of the form 0xMMNNPP (MM =
- major, NN = minor, PP = patch) that specifies Qt's version
- number. For example, if you compile your application against Qt
- 4.1.2, the QT_VERSION macro will expand to 0x040102.
-
- You can use QT_VERSION to use the latest Qt features where
- available.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 16
-
- \sa QT_VERSION_STR, qVersion()
-*/
-
-/*!
- \macro QT_VERSION_STR
- \relates <QtGlobal>
-
- This macro expands to a string that specifies Qt's version number
- (for example, "4.1.2"). This is the version against which the
- application is compiled.
-
- \sa qVersion(), QT_VERSION
-*/
-
-/*!
- \relates <QtGlobal>
-
- Returns the version number of Qt at run-time as a string (for
- example, "4.1.2"). This may be a different version than the
- version the application was compiled against.
-
- \sa QT_VERSION_STR, QLibraryInfo::version()
-*/
-
-const char *qVersion() noexcept
-{
- return QT_VERSION_STR;
-}
-
-bool qSharedBuild() noexcept
-{
-#ifdef QT_SHARED
- return true;
-#else
- return false;
-#endif
-}
-
-/*****************************************************************************
- System detection routines
- *****************************************************************************/
-
-/*!
- \class QSysInfo
- \inmodule QtCore
- \brief The QSysInfo class provides information about the system.
-
- \list
- \li \l WordSize specifies the size of a pointer for the platform
- on which the application is compiled.
- \li \l ByteOrder specifies whether the platform is big-endian or
- little-endian.
- \endlist
-
- Some constants are defined only on certain platforms. You can use
- the preprocessor symbols Q_OS_WIN and Q_OS_MACOS to test that
- the application is compiled under Windows or \macos.
-
- \sa QLibraryInfo
-*/
-
-/*!
- \enum QSysInfo::Sizes
-
- This enum provides platform-specific information about the sizes of data
- structures used by the underlying architecture.
-
- \value WordSize The size in bits of a pointer for the platform on which
- the application is compiled (32 or 64).
-*/
-
-/*!
- \enum QSysInfo::Endian
-
- \value BigEndian Big-endian byte order (also called Network byte order)
- \value LittleEndian Little-endian byte order
- \value ByteOrder Equals BigEndian or LittleEndian, depending on
- the platform's byte order.
-*/
-
-/*!
- \macro Q_OS_DARWIN
- \relates <QtGlobal>
-
- Defined on Darwin-based operating systems such as \macos, iOS, watchOS, and tvOS.
-*/
-
-/*!
- \macro Q_OS_MAC
- \relates <QtGlobal>
-
- Deprecated synonym for \c Q_OS_DARWIN. Do not use.
- */
-
-/*!
- \macro Q_OS_OSX
- \relates <QtGlobal>
-
- Deprecated synonym for \c Q_OS_MACOS. Do not use.
- */
-
-/*!
- \macro Q_OS_MACOS
- \relates <QtGlobal>
-
- Defined on \macos.
- */
-
-/*!
- \macro Q_OS_IOS
- \relates <QtGlobal>
-
- Defined on iOS.
- */
-
-/*!
- \macro Q_OS_WATCHOS
- \relates <QtGlobal>
-
- Defined on watchOS.
- */
-
-/*!
- \macro Q_OS_TVOS
- \relates <QtGlobal>
-
- Defined on tvOS.
- */
-
-/*!
- \macro Q_OS_WIN
- \relates <QtGlobal>
-
- Defined on all supported versions of Windows. That is, if
- \l Q_OS_WIN32 or \l Q_OS_WIN64 is defined.
-*/
-
-/*!
- \macro Q_OS_WINDOWS
- \relates <QtGlobal>
-
- This is a synonym for Q_OS_WIN.
-*/
-
-/*!
- \macro Q_OS_WIN32
- \relates <QtGlobal>
-
- Defined on 32-bit and 64-bit versions of Windows.
-*/
-
-/*!
- \macro Q_OS_WIN64
- \relates <QtGlobal>
-
- Defined on 64-bit versions of Windows.
-*/
-
-/*!
- \macro Q_OS_CYGWIN
- \relates <QtGlobal>
-
- Defined on Cygwin.
-*/
-
-/*!
- \macro Q_OS_SOLARIS
- \relates <QtGlobal>
-
- Defined on Sun Solaris.
-*/
-
-/*!
- \macro Q_OS_HPUX
- \relates <QtGlobal>
-
- Defined on HP-UX.
-*/
-
-/*!
- \macro Q_OS_LINUX
- \relates <QtGlobal>
-
- Defined on Linux.
-*/
-
-/*!
- \macro Q_OS_ANDROID
- \relates <QtGlobal>
-
- Defined on Android.
-*/
-
-/*!
- \macro Q_OS_FREEBSD
- \relates <QtGlobal>
-
- Defined on FreeBSD.
-*/
-
-/*!
- \macro Q_OS_NETBSD
- \relates <QtGlobal>
-
- Defined on NetBSD.
-*/
-
-/*!
- \macro Q_OS_OPENBSD
- \relates <QtGlobal>
-
- Defined on OpenBSD.
-*/
-
-/*!
- \macro Q_OS_AIX
- \relates <QtGlobal>
-
- Defined on AIX.
-*/
-
-/*!
- \macro Q_OS_HURD
- \relates <QtGlobal>
-
- Defined on GNU Hurd.
-*/
-
-/*!
- \macro Q_OS_QNX
- \relates <QtGlobal>
-
- Defined on QNX Neutrino.
-*/
-
-/*!
- \macro Q_OS_LYNX
- \relates <QtGlobal>
-
- Defined on LynxOS.
-*/
-
-/*!
- \macro Q_OS_BSD4
- \relates <QtGlobal>
-
- Defined on Any BSD 4.4 system.
-*/
-
-/*!
- \macro Q_OS_UNIX
- \relates <QtGlobal>
-
- Defined on Any UNIX BSD/SYSV system.
-*/
-
-/*!
- \macro Q_OS_WASM
- \relates <QtGlobal>
-
- Defined on Web Assembly.
-*/
-
-/*!
- \macro Q_CC_SYM
- \relates <QtGlobal>
-
- Defined if the application is compiled using Digital Mars C/C++
- (used to be Symantec C++).
-*/
-
-/*!
- \macro Q_CC_MSVC
- \relates <QtGlobal>
-
- Defined if the application is compiled using Microsoft Visual
- C/C++, Intel C++ for Windows.
-*/
-
-/*!
- \macro Q_CC_CLANG
- \relates <QtGlobal>
-
- Defined if the application is compiled using Clang.
-*/
-
-/*!
- \macro Q_CC_BOR
- \relates <QtGlobal>
-
- Defined if the application is compiled using Borland/Turbo C++.
-*/
-
-/*!
- \macro Q_CC_WAT
- \relates <QtGlobal>
-
- Defined if the application is compiled using Watcom C++.
-*/
-
-/*!
- \macro Q_CC_GNU
- \relates <QtGlobal>
-
- Defined if the application is compiled using GNU C++.
-*/
-
-/*!
- \macro Q_CC_COMEAU
- \relates <QtGlobal>
-
- Defined if the application is compiled using Comeau C++.
-*/
-
-/*!
- \macro Q_CC_EDG
- \relates <QtGlobal>
-
- Defined if the application is compiled using Edison Design Group
- C++.
-*/
-
-/*!
- \macro Q_CC_OC
- \relates <QtGlobal>
-
- Defined if the application is compiled using CenterLine C++.
-*/
-
-/*!
- \macro Q_CC_SUN
- \relates <QtGlobal>
-
- Defined if the application is compiled using Forte Developer, or
- Sun Studio C++.
-*/
-
-/*!
- \macro Q_CC_MIPS
- \relates <QtGlobal>
-
- Defined if the application is compiled using MIPSpro C++.
-*/
-
-/*!
- \macro Q_CC_DEC
- \relates <QtGlobal>
-
- Defined if the application is compiled using DEC C++.
-*/
-
-/*!
- \macro Q_CC_HPACC
- \relates <QtGlobal>
-
- Defined if the application is compiled using HP aC++.
-*/
-
-/*!
- \macro Q_CC_USLC
- \relates <QtGlobal>
-
- Defined if the application is compiled using SCO OUDK and UDK.
-*/
-
-/*!
- \macro Q_CC_CDS
- \relates <QtGlobal>
-
- Defined if the application is compiled using Reliant C++.
-*/
-
-/*!
- \macro Q_CC_KAI
- \relates <QtGlobal>
-
- Defined if the application is compiled using KAI C++.
-*/
-
-/*!
- \macro Q_CC_INTEL
- \relates <QtGlobal>
-
- Defined if the application is compiled using Intel C++ for Linux,
- Intel C++ for Windows.
-*/
-
-/*!
- \macro Q_CC_HIGHC
- \relates <QtGlobal>
-
- Defined if the application is compiled using MetaWare High C/C++.
-*/
-
-/*!
- \macro Q_CC_PGI
- \relates <QtGlobal>
-
- Defined if the application is compiled using Portland Group C++.
-*/
-
-/*!
- \macro Q_CC_GHS
- \relates <QtGlobal>
-
- Defined if the application is compiled using Green Hills
- Optimizing C++ Compilers.
-*/
-
-/*!
- \macro Q_PROCESSOR_ALPHA
- \relates <QtGlobal>
-
- Defined if the application is compiled for Alpha processors.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_ARM
- \relates <QtGlobal>
-
- Defined if the application is compiled for ARM processors. Qt currently
- supports three optional ARM revisions: \l Q_PROCESSOR_ARM_V5, \l
- Q_PROCESSOR_ARM_V6, and \l Q_PROCESSOR_ARM_V7.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_ARM_V5
- \relates <QtGlobal>
-
- Defined if the application is compiled for ARMv5 processors. The \l
- Q_PROCESSOR_ARM macro is also defined when Q_PROCESSOR_ARM_V5 is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_ARM_V6
- \relates <QtGlobal>
-
- Defined if the application is compiled for ARMv6 processors. The \l
- Q_PROCESSOR_ARM and \l Q_PROCESSOR_ARM_V5 macros are also defined when
- Q_PROCESSOR_ARM_V6 is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_ARM_V7
- \relates <QtGlobal>
-
- Defined if the application is compiled for ARMv7 processors. The \l
- Q_PROCESSOR_ARM, \l Q_PROCESSOR_ARM_V5, and \l Q_PROCESSOR_ARM_V6 macros
- are also defined when Q_PROCESSOR_ARM_V7 is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_AVR32
- \relates <QtGlobal>
-
- Defined if the application is compiled for AVR32 processors.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_BLACKFIN
- \relates <QtGlobal>
-
- Defined if the application is compiled for Blackfin processors.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_IA64
- \relates <QtGlobal>
-
- Defined if the application is compiled for IA-64 processors. This includes
- all Itanium and Itanium 2 processors.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_MIPS
- \relates <QtGlobal>
-
- Defined if the application is compiled for MIPS processors. Qt currently
- supports seven MIPS revisions: \l Q_PROCESSOR_MIPS_I, \l
- Q_PROCESSOR_MIPS_II, \l Q_PROCESSOR_MIPS_III, \l Q_PROCESSOR_MIPS_IV, \l
- Q_PROCESSOR_MIPS_V, \l Q_PROCESSOR_MIPS_32, and \l Q_PROCESSOR_MIPS_64.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_MIPS_I
- \relates <QtGlobal>
-
- Defined if the application is compiled for MIPS-I processors. The \l
- Q_PROCESSOR_MIPS macro is also defined when Q_PROCESSOR_MIPS_I is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_MIPS_II
- \relates <QtGlobal>
-
- Defined if the application is compiled for MIPS-II processors. The \l
- Q_PROCESSOR_MIPS and \l Q_PROCESSOR_MIPS_I macros are also defined when
- Q_PROCESSOR_MIPS_II is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_MIPS_32
- \relates <QtGlobal>
-
- Defined if the application is compiled for MIPS32 processors. The \l
- Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, and \l Q_PROCESSOR_MIPS_II macros
- are also defined when Q_PROCESSOR_MIPS_32 is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_MIPS_III
- \relates <QtGlobal>
-
- Defined if the application is compiled for MIPS-III processors. The \l
- Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, and \l Q_PROCESSOR_MIPS_II macros
- are also defined when Q_PROCESSOR_MIPS_III is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_MIPS_IV
- \relates <QtGlobal>
-
- Defined if the application is compiled for MIPS-IV processors. The \l
- Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, and \l
- Q_PROCESSOR_MIPS_III macros are also defined when Q_PROCESSOR_MIPS_IV is
- defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_MIPS_V
- \relates <QtGlobal>
-
- Defined if the application is compiled for MIPS-V processors. The \l
- Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, \l
- Q_PROCESSOR_MIPS_III, and \l Q_PROCESSOR_MIPS_IV macros are also defined
- when Q_PROCESSOR_MIPS_V is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_MIPS_64
- \relates <QtGlobal>
-
- Defined if the application is compiled for MIPS64 processors. The \l
- Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, \l
- Q_PROCESSOR_MIPS_III, \l Q_PROCESSOR_MIPS_IV, and \l Q_PROCESSOR_MIPS_V
- macros are also defined when Q_PROCESSOR_MIPS_64 is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_POWER
- \relates <QtGlobal>
-
- Defined if the application is compiled for POWER processors. Qt currently
- supports two Power variants: \l Q_PROCESSOR_POWER_32 and \l
- Q_PROCESSOR_POWER_64.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_POWER_32
- \relates <QtGlobal>
-
- Defined if the application is compiled for 32-bit Power processors. The \l
- Q_PROCESSOR_POWER macro is also defined when Q_PROCESSOR_POWER_32 is
- defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_POWER_64
- \relates <QtGlobal>
-
- Defined if the application is compiled for 64-bit Power processors. The \l
- Q_PROCESSOR_POWER macro is also defined when Q_PROCESSOR_POWER_64 is
- defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_RISCV
- \relates <QtGlobal>
- \since 5.13
-
- Defined if the application is compiled for RISC-V processors. Qt currently
- supports two RISC-V variants: \l Q_PROCESSOR_RISCV_32 and \l
- Q_PROCESSOR_RISCV_64.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_RISCV_32
- \relates <QtGlobal>
- \since 5.13
-
- Defined if the application is compiled for 32-bit RISC-V processors. The \l
- Q_PROCESSOR_RISCV macro is also defined when Q_PROCESSOR_RISCV_32 is
- defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_RISCV_64
- \relates <QtGlobal>
- \since 5.13
-
- Defined if the application is compiled for 64-bit RISC-V processors. The \l
- Q_PROCESSOR_RISCV macro is also defined when Q_PROCESSOR_RISCV_64 is
- defined.
+ \brief The <QtGlobal> header file includes an assortment of other headers.
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_S390
- \relates <QtGlobal>
-
- Defined if the application is compiled for S/390 processors. Qt supports
- one optional variant of S/390: Q_PROCESSOR_S390_X.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_S390_X
- \relates <QtGlobal>
-
- Defined if the application is compiled for S/390x processors. The \l
- Q_PROCESSOR_S390 macro is also defined when Q_PROCESSOR_S390_X is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_SH
- \relates <QtGlobal>
-
- Defined if the application is compiled for SuperH processors. Qt currently
- supports one SuperH revision: \l Q_PROCESSOR_SH_4A.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_SH_4A
- \relates <QtGlobal>
-
- Defined if the application is compiled for SuperH 4A processors. The \l
- Q_PROCESSOR_SH macro is also defined when Q_PROCESSOR_SH_4A is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_SPARC
- \relates <QtGlobal>
-
- Defined if the application is compiled for SPARC processors. Qt currently
- supports one optional SPARC revision: \l Q_PROCESSOR_SPARC_V9.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_SPARC_V9
- \relates <QtGlobal>
-
- Defined if the application is compiled for SPARC V9 processors. The \l
- Q_PROCESSOR_SPARC macro is also defined when Q_PROCESSOR_SPARC_V9 is
- defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro Q_PROCESSOR_X86
- \relates <QtGlobal>
-
- Defined if the application is compiled for x86 processors. Qt currently
- supports two x86 variants: \l Q_PROCESSOR_X86_32 and \l Q_PROCESSOR_X86_64.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_X86_32
- \relates <QtGlobal>
-
- Defined if the application is compiled for 32-bit x86 processors. This
- includes all i386, i486, i586, and i686 processors. The \l Q_PROCESSOR_X86
- macro is also defined when Q_PROCESSOR_X86_32 is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-/*!
- \macro Q_PROCESSOR_X86_64
- \relates <QtGlobal>
-
- Defined if the application is compiled for 64-bit x86 processors. This
- includes all AMD64, Intel 64, and other x86_64/x64 processors. The \l
- Q_PROCESSOR_X86 macro is also defined when Q_PROCESSOR_X86_64 is defined.
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-
-/*!
- \macro QT_DISABLE_DEPRECATED_BEFORE
- \relates <QtGlobal>
-
- This macro can be defined in the project file to disable functions deprecated in
- a specified version of Qt or any earlier version. The default version number is 5.0,
- meaning that functions deprecated in or before Qt 5.0 will not be included.
-
- For instance, when using a future release of Qt 5, set
- \c{QT_DISABLE_DEPRECATED_BEFORE=0x050100} to disable functions deprecated in
- Qt 5.1 and earlier. In any release, set
- \c{QT_DISABLE_DEPRECATED_BEFORE=0x000000} to enable all functions, including
- the ones deprecated in Qt 5.0.
-
- \sa QT_DEPRECATED_WARNINGS
- */
-
-
-/*!
- \macro QT_DEPRECATED_WARNINGS
- \relates <QtGlobal>
-
- Since Qt 5.13, this macro has no effect. In Qt 5.12 and before, if this macro
- is defined, the compiler will generate warnings if any API declared as
- deprecated by Qt is used.
+ Up to Qt 6.5, most Qt header files included <QtGlobal>. Before Qt 6.5,
+ <QtGlobal> defined an assortment of global declarations. Most of these
+ have moved, at Qt 6.5, to separate headers, so that source code can
+ include only what it needs, rather than the whole assortment. For now,
+ <QtGlobal> includes those other headers (see next section), but future
+ releases of Qt may remove some of these headers from <QtGlobal> or
+ condition their inclusion on a version check. Likewise, in future
+ releases, some Qt headers that currently include <QtGlobal> may stop
+ doing so. The hope is that this will improve compilation times by
+ avoiding global declarations when they are not used.
- \sa QT_DISABLE_DEPRECATED_BEFORE, QT_NO_DEPRECATED_WARNINGS
- */
-
-/*!
- \macro QT_NO_DEPRECATED_WARNINGS
- \relates <QtGlobal>
- \since 5.13
-
- This macro can be used to suppress deprecation warnings that would otherwise
- be generated when using deprecated APIs.
-
- \sa QT_DISABLE_DEPRECATED_BEFORE
-*/
-
-#if defined(Q_OS_MAC)
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "private/qcore_mac_p.h"
-#include "qnamespace.h"
-QT_END_INCLUDE_NAMESPACE
-
-#ifdef Q_OS_DARWIN
-static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current())
-{
-#ifdef Q_OS_MACOS
- if (version.majorVersion() == 10) {
- switch (version.minorVersion()) {
- case 9:
- return "Mavericks";
- case 10:
- return "Yosemite";
- case 11:
- return "El Capitan";
- case 12:
- return "Sierra";
- case 13:
- return "High Sierra";
- case 14:
- return "Mojave";
- }
- }
- // unknown, future version
-#else
- Q_UNUSED(version);
-#endif
- return 0;
-}
-#endif
-
-#elif defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qt_windows.h"
-QT_END_INCLUDE_NAMESPACE
-
-# ifndef QT_BOOTSTRAPPED
-class QWindowsSockInit
-{
-public:
- QWindowsSockInit();
- ~QWindowsSockInit();
- int version;
-};
-
-QWindowsSockInit::QWindowsSockInit()
-: version(0)
-{
- //### should we try for 2.2 on all platforms ??
- WSAData wsadata;
-
- // IPv6 requires Winsock v2.0 or better.
- if (WSAStartup(MAKEWORD(2, 0), &wsadata) != 0) {
- qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed.");
- } else {
- version = 0x20;
- }
-}
-
-QWindowsSockInit::~QWindowsSockInit()
-{
- WSACleanup();
-}
-Q_GLOBAL_STATIC(QWindowsSockInit, winsockInit)
-# endif // QT_BOOTSTRAPPED
-
-static QString readVersionRegistryString(const wchar_t *subKey)
-{
- return QWinRegistryKey(HKEY_LOCAL_MACHINE, LR"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)")
- .stringValue(subKey);
-}
-
-static inline QString windows10ReleaseId()
-{
- return readVersionRegistryString(L"ReleaseId");
-}
-
-static QString winSp_helper()
-{
- const auto osv = qWindowsVersionInfo();
- const qint16 major = osv.wServicePackMajor;
- if (major) {
- QString sp = QStringLiteral("SP ") + QString::number(major);
- const qint16 minor = osv.wServicePackMinor;
- if (minor)
- sp += QLatin1Char('.') + QString::number(minor);
-
- return sp;
- }
- return QString();
-}
-
-static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current())
-{
- Q_UNUSED(version);
- const OSVERSIONINFOEX osver = qWindowsVersionInfo();
- const bool workstation = osver.wProductType == VER_NT_WORKSTATION;
-
-#define Q_WINVER(major, minor) (major << 8 | minor)
- switch (Q_WINVER(osver.dwMajorVersion, osver.dwMinorVersion)) {
- case Q_WINVER(10, 0):
- return workstation ? "10" : "Server 2016";
- }
-#undef Q_WINVER
- // unknown, future version
- return 0;
-}
-
-#endif
-#if defined(Q_OS_UNIX)
-# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD)
-# define USE_ETC_OS_RELEASE
-struct QUnixOSVersion
-{
- // from /etc/os-release older /etc/lsb-release // redhat /etc/redhat-release // debian /etc/debian_version
- QString productType; // $ID $DISTRIB_ID // single line file containing: // Debian
- QString productVersion; // $VERSION_ID $DISTRIB_RELEASE // <Vendor_ID release Version_ID> // single line file <Release_ID/sid>
- QString prettyName; // $PRETTY_NAME $DISTRIB_DESCRIPTION
-};
-
-static QString unquote(const char *begin, const char *end)
-{
- // man os-release says:
- // Variable assignment values must be enclosed in double
- // or single quotes if they include spaces, semicolons or
- // other special characters outside of A–Z, a–z, 0–9. Shell
- // special characters ("$", quotes, backslash, backtick)
- // must be escaped with backslashes, following shell style.
- // All strings should be in UTF-8 format, and non-printable
- // characters should not be used. It is not supported to
- // concatenate multiple individually quoted strings.
- if (*begin == '"') {
- Q_ASSERT(end[-1] == '"');
- return QString::fromUtf8(begin + 1, end - begin - 2);
- }
- return QString::fromUtf8(begin, end - begin);
-}
-static QByteArray getEtcFileContent(const char *filename)
-{
- // we're avoiding QFile here
- int fd = qt_safe_open(filename, O_RDONLY);
- if (fd == -1)
- return QByteArray();
-
- QT_STATBUF sbuf;
- if (QT_FSTAT(fd, &sbuf) == -1) {
- qt_safe_close(fd);
- return QByteArray();
- }
-
- QByteArray buffer(sbuf.st_size, Qt::Uninitialized);
- buffer.resize(qt_safe_read(fd, buffer.data(), sbuf.st_size));
- qt_safe_close(fd);
- return buffer;
-}
-
-static bool readEtcFile(QUnixOSVersion &v, const char *filename,
- const QByteArray &idKey, const QByteArray &versionKey, const QByteArray &prettyNameKey)
-{
-
- QByteArray buffer = getEtcFileContent(filename);
- if (buffer.isEmpty())
- return false;
-
- const char *ptr = buffer.constData();
- const char *end = buffer.constEnd();
- const char *eol;
- QByteArray line;
- for (; ptr != end; ptr = eol + 1) {
- // find the end of the line after ptr
- eol = static_cast<const char *>(memchr(ptr, '\n', end - ptr));
- if (!eol)
- eol = end - 1;
- line.setRawData(ptr, eol - ptr);
-
- if (line.startsWith(idKey)) {
- ptr += idKey.length();
- v.productType = unquote(ptr, eol);
- continue;
- }
-
- if (line.startsWith(prettyNameKey)) {
- ptr += prettyNameKey.length();
- v.prettyName = unquote(ptr, eol);
- continue;
- }
-
- if (line.startsWith(versionKey)) {
- ptr += versionKey.length();
- v.productVersion = unquote(ptr, eol);
- continue;
- }
- }
-
- return true;
-}
-
-static bool readOsRelease(QUnixOSVersion &v)
-{
- QByteArray id = QByteArrayLiteral("ID=");
- QByteArray versionId = QByteArrayLiteral("VERSION_ID=");
- QByteArray prettyName = QByteArrayLiteral("PRETTY_NAME=");
-
- // man os-release(5) says:
- // The file /etc/os-release takes precedence over /usr/lib/os-release.
- // Applications should check for the former, and exclusively use its data
- // if it exists, and only fall back to /usr/lib/os-release if it is
- // missing.
- return readEtcFile(v, "/etc/os-release", id, versionId, prettyName) ||
- readEtcFile(v, "/usr/lib/os-release", id, versionId, prettyName);
-}
-
-static bool readEtcLsbRelease(QUnixOSVersion &v)
-{
- bool ok = readEtcFile(v, "/etc/lsb-release", QByteArrayLiteral("DISTRIB_ID="),
- QByteArrayLiteral("DISTRIB_RELEASE="), QByteArrayLiteral("DISTRIB_DESCRIPTION="));
- if (ok && (v.prettyName.isEmpty() || v.prettyName == v.productType)) {
- // some distributions have redundant information for the pretty name,
- // so try /etc/<lowercasename>-release
-
- // we're still avoiding QFile here
- QByteArray distrorelease = "/etc/" + v.productType.toLatin1().toLower() + "-release";
- int fd = qt_safe_open(distrorelease, O_RDONLY);
- if (fd != -1) {
- QT_STATBUF sbuf;
- if (QT_FSTAT(fd, &sbuf) != -1 && sbuf.st_size > v.prettyName.length()) {
- // file apparently contains interesting information
- QByteArray buffer(sbuf.st_size, Qt::Uninitialized);
- buffer.resize(qt_safe_read(fd, buffer.data(), sbuf.st_size));
- v.prettyName = QString::fromLatin1(buffer.trimmed());
- }
- qt_safe_close(fd);
- }
- }
-
- // some distributions have a /etc/lsb-release file that does not provide the values
- // we are looking for, i.e. DISTRIB_ID, DISTRIB_RELEASE and DISTRIB_DESCRIPTION.
- // Assuming that neither DISTRIB_ID nor DISTRIB_RELEASE were found, or contained valid values,
- // returning false for readEtcLsbRelease will allow further /etc/<lowercasename>-release parsing.
- return ok && !(v.productType.isEmpty() && v.productVersion.isEmpty());
-}
-
-#if defined(Q_OS_LINUX)
-static QByteArray getEtcFileFirstLine(const char *fileName)
-{
- QByteArray buffer = getEtcFileContent(fileName);
- if (buffer.isEmpty())
- return QByteArray();
-
- const char *ptr = buffer.constData();
- int eol = buffer.indexOf("\n");
- return QByteArray(ptr, eol).trimmed();
-}
-
-static bool readEtcRedHatRelease(QUnixOSVersion &v)
-{
- // /etc/redhat-release analysed should be a one line file
- // the format of its content is <Vendor_ID release Version>
- // i.e. "Red Hat Enterprise Linux Workstation release 6.5 (Santiago)"
- QByteArray line = getEtcFileFirstLine("/etc/redhat-release");
- if (line.isEmpty())
- return false;
-
- v.prettyName = QString::fromLatin1(line);
-
- const char keyword[] = "release ";
- int releaseIndex = line.indexOf(keyword);
- v.productType = QString::fromLatin1(line.mid(0, releaseIndex)).remove(QLatin1Char(' '));
- int spaceIndex = line.indexOf(' ', releaseIndex + strlen(keyword));
- v.productVersion = QString::fromLatin1(line.mid(releaseIndex + strlen(keyword),
- spaceIndex > -1 ? spaceIndex - releaseIndex - int(strlen(keyword)) : -1));
- return true;
-}
-
-static bool readEtcDebianVersion(QUnixOSVersion &v)
-{
- // /etc/debian_version analysed should be a one line file
- // the format of its content is <Release_ID/sid>
- // i.e. "jessie/sid"
- QByteArray line = getEtcFileFirstLine("/etc/debian_version");
- if (line.isEmpty())
- return false;
-
- v.productType = QStringLiteral("Debian");
- v.productVersion = QString::fromLatin1(line);
- return true;
-}
-#endif
-
-static bool findUnixOsVersion(QUnixOSVersion &v)
-{
- if (readOsRelease(v))
- return true;
- if (readEtcLsbRelease(v))
- return true;
-#if defined(Q_OS_LINUX)
- if (readEtcRedHatRelease(v))
- return true;
- if (readEtcDebianVersion(v))
- return true;
-#endif
- return false;
-}
-# endif // USE_ETC_OS_RELEASE
-#endif // Q_OS_UNIX
-
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
-static const char *osVer_helper(QOperatingSystemVersion)
-{
-/* Data:
-
-
-
-Cupcake
-Donut
-Eclair
-Eclair
-Eclair
-Froyo
-Gingerbread
-Gingerbread
-Honeycomb
-Honeycomb
-Honeycomb
-Ice Cream Sandwich
-Ice Cream Sandwich
-Jelly Bean
-Jelly Bean
-Jelly Bean
-KitKat
-KitKat
-Lollipop
-Lollipop
-Marshmallow
-Nougat
-Nougat
-Oreo
- */
- static const char versions_string[] =
- "\0"
- "Cupcake\0"
- "Donut\0"
- "Eclair\0"
- "Froyo\0"
- "Gingerbread\0"
- "Honeycomb\0"
- "Ice Cream Sandwich\0"
- "Jelly Bean\0"
- "KitKat\0"
- "Lollipop\0"
- "Marshmallow\0"
- "Nougat\0"
- "Oreo\0"
- "\0";
-
- static const int versions_indices[] = {
- 0, 0, 0, 1, 9, 15, 15, 15,
- 22, 28, 28, 40, 40, 40, 50, 50,
- 69, 69, 69, 80, 80, 87, 87, 96,
- 108, 108, 115, -1
- };
-
- static const int versions_count = (sizeof versions_indices) / (sizeof versions_indices[0]);
-
- // https://source.android.com/source/build-numbers.html
- // https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels
- const int sdk_int = QJniObject::getStaticField<jint>("android/os/Build$VERSION", "SDK_INT");
- return &versions_string[versions_indices[qBound(0, sdk_int, versions_count - 1)]];
-}
-#endif
-
-/*!
- \since 5.4
-
- Returns the architecture of the CPU that Qt was compiled for, in text
- format. Note that this may not match the actual CPU that the application is
- running on if there's an emulation layer or if the CPU supports multiple
- architectures (like x86-64 processors supporting i386 applications). To
- detect that, use currentCpuArchitecture().
-
- Values returned by this function are stable and will not change over time,
- so applications can rely on the returned value as an identifier, except
- that new CPU types may be added over time.
-
- Typical returned values are (note: list not exhaustive):
- \list
- \li "arm"
- \li "arm64"
- \li "i386"
- \li "ia64"
- \li "mips"
- \li "mips64"
- \li "power"
- \li "power64"
- \li "sparc"
- \li "sparcv9"
- \li "x86_64"
- \endlist
-
- \sa QSysInfo::buildAbi(), QSysInfo::currentCpuArchitecture()
-*/
-QString QSysInfo::buildCpuArchitecture()
-{
- return QStringLiteral(ARCH_PROCESSOR);
-}
-
-/*!
- \since 5.4
-
- Returns the architecture of the CPU that the application is running on, in
- text format. Note that this function depends on what the OS will report and
- may not detect the actual CPU architecture if the OS hides that information
- or is unable to provide it. For example, a 32-bit OS running on a 64-bit
- CPU is usually unable to determine the CPU is actually capable of running
- 64-bit programs.
-
- Values returned by this function are mostly stable: an attempt will be made
- to ensure that they stay constant over time and match the values returned
- by QSysInfo::builldCpuArchitecture(). However, due to the nature of the
- operating system functions being used, there may be discrepancies.
-
- Typical returned values are (note: list not exhaustive):
- \list
- \li "arm"
- \li "arm64"
- \li "i386"
- \li "ia64"
- \li "mips"
- \li "mips64"
- \li "power"
- \li "power64"
- \li "sparc"
- \li "sparcv9"
- \li "x86_64"
- \endlist
-
- \sa QSysInfo::buildAbi(), QSysInfo::buildCpuArchitecture()
- */
-QString QSysInfo::currentCpuArchitecture()
-{
-#if defined(Q_OS_WIN)
- // We don't need to catch all the CPU architectures in this function;
- // only those where the host CPU might be different than the build target
- // (usually, 64-bit platforms).
- SYSTEM_INFO info;
- GetNativeSystemInfo(&info);
- switch (info.wProcessorArchitecture) {
-# ifdef PROCESSOR_ARCHITECTURE_AMD64
- case PROCESSOR_ARCHITECTURE_AMD64:
- return QStringLiteral("x86_64");
-# endif
-# ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
- case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
-# endif
- case PROCESSOR_ARCHITECTURE_IA64:
- return QStringLiteral("ia64");
- }
-#elif defined(Q_OS_DARWIN) && !defined(Q_OS_MACOS)
- // iOS-based OSes do not return the architecture on uname(2)'s result.
- return buildCpuArchitecture();
-#elif defined(Q_OS_UNIX)
- long ret = -1;
- struct utsname u;
-
-# if defined(Q_OS_SOLARIS)
- // We need a special call for Solaris because uname(2) on x86 returns "i86pc" for
- // both 32- and 64-bit CPUs. Reference:
- // http://docs.oracle.com/cd/E18752_01/html/816-5167/sysinfo-2.html#REFMAN2sysinfo-2
- // http://fxr.watson.org/fxr/source/common/syscall/systeminfo.c?v=OPENSOLARIS
- // http://fxr.watson.org/fxr/source/common/conf/param.c?v=OPENSOLARIS;im=10#L530
- if (ret == -1)
- ret = sysinfo(SI_ARCHITECTURE_64, u.machine, sizeof u.machine);
-# endif
-
- if (ret == -1)
- ret = uname(&u);
-
- // we could use detectUnixVersion() above, but we only need a field no other function does
- if (ret != -1) {
- // the use of QT_BUILD_INTERNAL here is simply to ensure all branches build
- // as we don't often build on some of the less common platforms
-# if defined(Q_PROCESSOR_ARM) || defined(QT_BUILD_INTERNAL)
- if (strcmp(u.machine, "aarch64") == 0)
- return QStringLiteral("arm64");
- if (strncmp(u.machine, "armv", 4) == 0)
- return QStringLiteral("arm");
-# endif
-# if defined(Q_PROCESSOR_POWER) || defined(QT_BUILD_INTERNAL)
- // harmonize "powerpc" and "ppc" to "power"
- if (strncmp(u.machine, "ppc", 3) == 0)
- return QLatin1String("power") + QLatin1String(u.machine + 3);
- if (strncmp(u.machine, "powerpc", 7) == 0)
- return QLatin1String("power") + QLatin1String(u.machine + 7);
- if (strcmp(u.machine, "Power Macintosh") == 0)
- return QLatin1String("power");
-# endif
-# if defined(Q_PROCESSOR_SPARC) || defined(QT_BUILD_INTERNAL)
- // Solaris sysinfo(2) (above) uses "sparcv9", but uname -m says "sun4u";
- // Linux says "sparc64"
- if (strcmp(u.machine, "sun4u") == 0 || strcmp(u.machine, "sparc64") == 0)
- return QStringLiteral("sparcv9");
- if (strcmp(u.machine, "sparc32") == 0)
- return QStringLiteral("sparc");
-# endif
-# if defined(Q_PROCESSOR_X86) || defined(QT_BUILD_INTERNAL)
- // harmonize all "i?86" to "i386"
- if (strlen(u.machine) == 4 && u.machine[0] == 'i'
- && u.machine[2] == '8' && u.machine[3] == '6')
- return QStringLiteral("i386");
- if (strcmp(u.machine, "amd64") == 0) // Solaris
- return QStringLiteral("x86_64");
-# endif
- return QString::fromLatin1(u.machine);
- }
-#endif
- return buildCpuArchitecture();
-}
-
-/*!
- \since 5.4
-
- Returns the full architecture string that Qt was compiled for. This string
- is useful for identifying different, incompatible builds. For example, it
- can be used as an identifier to request an upgrade package from a server.
-
- The values returned from this function are kept stable as follows: the
- mandatory components of the result will not change in future versions of
- Qt, but optional suffixes may be added.
-
- The returned value is composed of three or more parts, separated by dashes
- ("-"). They are:
+ \section1 List of Headers Extracted from <QtGlobal>
\table
- \header \li Component \li Value
- \row \li CPU Architecture \li The same as QSysInfo::buildCpuArchitecture(), such as "arm", "i386", "mips" or "x86_64"
- \row \li Endianness \li "little_endian" or "big_endian"
- \row \li Word size \li Whether it's a 32- or 64-bit application. Possible values are:
- "llp64" (Windows 64-bit), "lp64" (Unix 64-bit), "ilp32" (32-bit)
- \row \li (Optional) ABI \li Zero or more components identifying different ABIs possible in this architecture.
- Currently, Qt has optional ABI components for ARM and MIPS processors: one
- component is the main ABI (such as "eabi", "o32", "n32", "o64"); another is
- whether the calling convention is using hardware floating point registers ("hardfloat"
- is present).
-
- Additionally, if Qt was configured with \c{-qreal float}, the ABI option tag "qreal_float"
- will be present. If Qt was configured with another type as qreal, that type is present after
- "qreal_", with all characters other than letters and digits escaped by an underscore, followed
- by two hex digits. For example, \c{-qreal long double} becomes "qreal_long_20double".
+ \header \li Header \li Summary
+ \row \li <QFlags> \li Type-safe way of combining enum values
+ \row \li \l <QForeach> \li Qt's implementation of foreach and forever loops
+ \row \li \l <QFunctionPointer> \li Typedef for a pointer-to-function type
+ \row \li <QGlobalStatic> \li Thread-safe initialization of global static objects
+ \row \li \l <QOverload> \li Helpers for resolving member function overloads
+ \row \li <QSysInfo> \li A helper class to get system information
+ \row \li \l <QTypeInfo> \li Helpers to get type information
+ \row \li \l <QtAssert> \li Q_ASSERT and other runtime checks
+ \row \li \l <QtClassHelperMacros> \li Qt class helper macros
+ \row \li \l <QtCompilerDetection> \li Compiler-specific macro definitions
+ \row \li \l <QtDeprecationMarkers> \li Deprecation helper macros
+ \row \li \l <QtEnvironmentVariables> \li Helpers for working with environment variables
+ \row \li <QtExceptionHandling> \li Helpers for exception handling
+ \row \li \l <QtLogging> \li Qt logging helpers
+ \row \li <QtMalloc> \li Memory allocation helpers
+ \row \li \l <QtMinMax> \li Helpers for comparing values
+ \row \li \l <QtNumeric> \li Various numeric functions
+ \row \li \l <QtPreprocessorSupport> \li Helper preprocessor macros
+ \row \li \l <QtProcessorDetection> \li Architecture-specific macro definitions
+ \row \li \l <QtResource> \li Helpers for initializing and cleaning resources
+ \row \li \l <QtSwap> \li Implementation of qSwap()
+ \row \li \l <QtSystemDetection> \li Platform-specific macro definitions
+ \row \li \l <QtTranslation> \li Qt translation helpers
+ \row \li \l <QtTypeTraits> \li Qt type traits
+ \row \li \l <QtTypes> \li Qt fundamental type declarations
+ \row \li \l <QtVersionChecks> \li QT_VERSION_CHECK and related checks
+ \row \li \l <QtVersion> \li QT_VERSION_STR and qVersion()
\endtable
-
- \sa QSysInfo::buildCpuArchitecture()
-*/
-QString QSysInfo::buildAbi()
-{
- // ARCH_FULL is a concatenation of strings (incl. ARCH_PROCESSOR), which breaks
- // QStringLiteral on MSVC. Since the concatenation behavior we want is specified
- // the same C++11 paper as the Unicode strings, we'll use that macro and hope
- // that Microsoft implements the new behavior when they add support for Unicode strings.
- return QStringLiteral(ARCH_FULL);
-}
-
-static QString unknownText()
-{
- return QStringLiteral("unknown");
-}
-
-/*!
- \since 5.4
-
- Returns the type of the operating system kernel Qt was compiled for. It's
- also the kernel the application is running on, unless the host operating
- system is running a form of compatibility or virtualization layer.
-
- Values returned by this function are stable and will not change over time,
- so applications can rely on the returned value as an identifier, except
- that new OS kernel types may be added over time.
-
- On Windows, this function returns the type of Windows kernel, like "winnt".
- On Unix systems, it returns the same as the output of \c{uname
- -s} (lowercased).
-
- \note This function may return surprising values: it returns "linux"
- for all operating systems running Linux (including Android), "qnx" for all
- operating systems running QNX, "freebsd" for
- Debian/kFreeBSD, and "darwin" for \macos and iOS. For information on the type
- of product the application is running on, see productType().
-
- \sa QFileSelector, kernelVersion(), productType(), productVersion(), prettyProductName()
*/
-QString QSysInfo::kernelType()
-{
-#if defined(Q_OS_WIN)
- return QStringLiteral("winnt");
-#elif defined(Q_OS_UNIX)
- struct utsname u;
- if (uname(&u) == 0)
- return QString::fromLatin1(u.sysname).toLower();
-#endif
- return unknownText();
-}
-
-/*!
- \since 5.4
-
- Returns the release version of the operating system kernel. On Windows, it
- returns the version of the NT kernel. On Unix systems, including
- Android and \macos, it returns the same as the \c{uname -r}
- command would return.
-
- If the version could not be determined, this function may return an empty
- string.
-
- \sa kernelType(), productType(), productVersion(), prettyProductName()
-*/
-QString QSysInfo::kernelVersion()
-{
-#ifdef Q_OS_WIN
- const auto osver = QOperatingSystemVersion::current();
- return QString::number(osver.majorVersion()) + QLatin1Char('.') + QString::number(osver.minorVersion())
- + QLatin1Char('.') + QString::number(osver.microVersion());
-#else
- struct utsname u;
- if (uname(&u) == 0)
- return QString::fromLatin1(u.release);
- return QString();
-#endif
-}
-
-
-/*!
- \since 5.4
-
- Returns the product name of the operating system this application is
- running in. If the application is running on some sort of emulation or
- virtualization layer (such as WINE on a Unix system), this function will
- inspect the emulation / virtualization layer.
-
- Values returned by this function are stable and will not change over time,
- so applications can rely on the returned value as an identifier, except
- that new OS types may be added over time.
-
- \b{Linux and Android note}: this function returns "android" for Linux
- systems running Android userspace, notably when using the Bionic library.
- For all other Linux systems, regardless of C library being used, it tries
- to determine the distribution name and returns that. If determining the
- distribution name failed, it returns "unknown".
-
- \b{\macos note}: this function returns "osx" for all \macos systems,
- regardless of Apple naming convention. The returned string will be updated
- for Qt 6. Note that this function erroneously returned "macos" for \macos
- 10.12 in Qt versions 5.6.2, 5.7.1, and 5.8.0.
-
- \b{Darwin, iOS, tvOS, and watchOS note}: this function returns "ios" for
- iOS systems, "tvos" for tvOS systems, "watchos" for watchOS systems, and
- "darwin" in case the system could not be determined.
-
- \b{FreeBSD note}: this function returns "debian" for Debian/kFreeBSD and
- "unknown" otherwise.
-
- \b{Windows note}: this function return "windows"
-
- For other Unix-type systems, this function usually returns "unknown".
-
- \sa QFileSelector, kernelType(), kernelVersion(), productVersion(), prettyProductName()
-*/
-QString QSysInfo::productType()
-{
- // similar, but not identical to QFileSelectorPrivate::platformSelectors
-#if defined(Q_OS_WIN)
- return QStringLiteral("windows");
-
-#elif defined(Q_OS_QNX)
- return QStringLiteral("qnx");
-
-#elif defined(Q_OS_ANDROID)
- return QStringLiteral("android");
-
-#elif defined(Q_OS_IOS)
- return QStringLiteral("ios");
-#elif defined(Q_OS_TVOS)
- return QStringLiteral("tvos");
-#elif defined(Q_OS_WATCHOS)
- return QStringLiteral("watchos");
-#elif defined(Q_OS_MACOS)
- return QStringLiteral("macos");
-#elif defined(Q_OS_DARWIN)
- return QStringLiteral("darwin");
-
-#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
- QUnixOSVersion unixOsVersion;
- findUnixOsVersion(unixOsVersion);
- if (!unixOsVersion.productType.isEmpty())
- return unixOsVersion.productType;
-#endif
- return unknownText();
-}
-
-/*!
- \since 5.4
-
- Returns the product version of the operating system in string form. If the
- version could not be determined, this function returns "unknown".
-
- It will return the Android, iOS, \macos, Windows full-product
- versions on those systems.
-
- Typical returned values are (note: list not exhaustive):
- \list
- \li "2016.09" (Amazon Linux AMI 2016.09)
- \li "7.1" (Android Nougat)
- \li "25" (Fedora 25)
- \li "10.1" (iOS 10.1)
- \li "10.12" (macOS Sierra)
- \li "10.0" (tvOS 10)
- \li "16.10" (Ubuntu 16.10)
- \li "3.1" (watchOS 3.1)
- \li "10" (Windows 10)
- \li "Server 2016" (Windows Server 2016)
- \endlist
-
- On Linux systems, it will try to determine the distribution version and will
- return that. This is also done on Debian/kFreeBSD, so this function will
- return Debian version in that case.
-
- In all other Unix-type systems, this function always returns "unknown".
-
- \note The version string returned from this function is not guaranteed to
- be orderable. On Linux, the version of
- the distribution may jump unexpectedly, please refer to the distribution's
- documentation for versioning practices.
-
- \sa kernelType(), kernelVersion(), productType(), prettyProductName()
-*/
-QString QSysInfo::productVersion()
-{
-#if defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN)
- const auto version = QOperatingSystemVersion::current();
- return QString::number(version.majorVersion()) + QLatin1Char('.') + QString::number(version.minorVersion());
-#elif defined(Q_OS_WIN)
- const char *version = osVer_helper();
- if (version) {
- const QLatin1Char spaceChar(' ');
- return QString::fromLatin1(version).remove(spaceChar).toLower() + winSp_helper().remove(spaceChar).toLower();
- }
- // fall through
-
-#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
- QUnixOSVersion unixOsVersion;
- findUnixOsVersion(unixOsVersion);
- if (!unixOsVersion.productVersion.isEmpty())
- return unixOsVersion.productVersion;
-#endif
-
- // fallback
- return unknownText();
-}
-
-/*!
- \since 5.4
-
- Returns a prettier form of productType() and productVersion(), containing
- other tokens like the operating system type, codenames and other
- information. The result of this function is suitable for displaying to the
- user, but not for long-term storage, as the string may change with updates
- to Qt.
-
- If productType() is "unknown", this function will instead use the
- kernelType() and kernelVersion() functions.
-
- \sa kernelType(), kernelVersion(), productType(), productVersion()
-*/
-QString QSysInfo::prettyProductName()
-{
-#if (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN)
- const auto version = QOperatingSystemVersion::current();
- const int majorVersion = version.majorVersion();
- const QString versionString = QString::number(majorVersion) + QLatin1Char('.')
- + QString::number(version.minorVersion());
- QString result = version.name() + QLatin1Char(' ');
- const char *name = osVer_helper(version);
- if (!name)
- return result + versionString;
- result += QLatin1String(name);
-# if !defined(Q_OS_WIN)
- return result + QLatin1String(" (") + versionString + QLatin1Char(')');
-# else
- // (resembling winver.exe): Windows 10 "Windows 10 Version 1809"
- const auto releaseId = windows10ReleaseId();
- if (!releaseId.isEmpty())
- result += QLatin1String(" Version ") + releaseId;
- return result;
-# endif // Windows
-#elif defined(Q_OS_HAIKU)
- return QLatin1String("Haiku ") + productVersion();
-#elif defined(Q_OS_UNIX)
-# ifdef USE_ETC_OS_RELEASE
- QUnixOSVersion unixOsVersion;
- findUnixOsVersion(unixOsVersion);
- if (!unixOsVersion.prettyName.isEmpty())
- return unixOsVersion.prettyName;
-# endif
- struct utsname u;
- if (uname(&u) == 0)
- return QString::fromLatin1(u.sysname) + QLatin1Char(' ') + QString::fromLatin1(u.release);
-#endif
- return unknownText();
-}
-
-#ifndef QT_BOOTSTRAPPED
-/*!
- \since 5.6
-
- Returns this machine's host name, if one is configured. Note that hostnames
- are not guaranteed to be globally unique, especially if they were
- configured automatically.
-
- This function does not guarantee the returned host name is a Fully
- Qualified Domain Name (FQDN). For that, use QHostInfo to resolve the
- returned name to an FQDN.
-
- This function returns the same as QHostInfo::localHostName().
-
- \sa QHostInfo::localDomainName, machineUniqueId()
- */
-QString QSysInfo::machineHostName()
-{
- // the hostname can change, so we can't cache it
-#if defined(Q_OS_LINUX)
- // gethostname(3) on Linux just calls uname(2), so do it ourselves
- // and avoid a memcpy
- struct utsname u;
- if (uname(&u) == 0)
- return QString::fromLocal8Bit(u.nodename);
- return QString();
-#else
-# ifdef Q_OS_WIN
- // Important: QtNetwork depends on machineHostName() initializing ws2_32.dll
- winsockInit();
-# endif
-
- char hostName[512];
- if (gethostname(hostName, sizeof(hostName)) == -1)
- return QString();
- hostName[sizeof(hostName) - 1] = '\0';
- return QString::fromLocal8Bit(hostName);
-#endif
-}
-#endif // QT_BOOTSTRAPPED
-
-enum {
- UuidStringLen = sizeof("00000000-0000-0000-0000-000000000000") - 1
-};
-
-/*!
- \since 5.11
-
- Returns a unique ID for this machine, if one can be determined. If no
- unique ID could be determined, this function returns an empty byte array.
- Unlike machineHostName(), the value returned by this function is likely
- globally unique.
-
- A unique ID is useful in network operations to identify this machine for an
- extended period of time, when the IP address could change or if this
- machine could have more than one IP address. For example, the ID could be
- used when communicating with a server or when storing device-specific data
- in shared network storage.
-
- Note that on some systems, this value will persist across reboots and on
- some it will not. Applications should not blindly depend on this fact
- without verifying the OS capabilities. In particular, on Linux systems,
- this ID is usually permanent and it matches the D-Bus machine ID, except
- for nodes without their own storage (replicated nodes).
-
- \sa machineHostName(), bootUniqueId()
-*/
-QByteArray QSysInfo::machineUniqueId()
-{
-#if defined(Q_OS_DARWIN) && __has_include(<IOKit/IOKitLib.h>)
- char uuid[UuidStringLen + 1];
- io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
- QCFString stringRef = (CFStringRef)IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
- CFStringGetCString(stringRef, uuid, sizeof(uuid), kCFStringEncodingMacRoman);
- return QByteArray(uuid);
-#elif defined(Q_OS_BSD4) && defined(KERN_HOSTUUID)
- char uuid[UuidStringLen + 1];
- size_t uuidlen = sizeof(uuid);
- int name[] = { CTL_KERN, KERN_HOSTUUID };
- if (sysctl(name, sizeof name / sizeof name[0], &uuid, &uuidlen, nullptr, 0) == 0
- && uuidlen == sizeof(uuid))
- return QByteArray(uuid, uuidlen - 1);
-#elif defined(Q_OS_UNIX)
- // The modern name on Linux is /etc/machine-id, but that path is
- // unlikely to exist on non-Linux (non-systemd) systems. The old
- // path is more than enough.
- static const char fullfilename[] = "/usr/local/var/lib/dbus/machine-id";
- const char *firstfilename = fullfilename + sizeof("/usr/local") - 1;
- int fd = qt_safe_open(firstfilename, O_RDONLY);
- if (fd == -1 && errno == ENOENT)
- fd = qt_safe_open(fullfilename, O_RDONLY);
-
- if (fd != -1) {
- char buffer[32]; // 128 bits, hex-encoded
- qint64 len = qt_safe_read(fd, buffer, sizeof(buffer));
- qt_safe_close(fd);
-
- if (len != -1)
- return QByteArray(buffer, len);
- }
-#elif defined(Q_OS_WIN)
- // Let's poke at the registry
- // ### Qt 6: Use new helpers from qwinregistry.cpp (once bootstrap builds are obsolete)
- HKEY key = NULL;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ | KEY_WOW64_64KEY, &key)
- == ERROR_SUCCESS) {
- wchar_t buffer[UuidStringLen + 1];
- DWORD size = sizeof(buffer);
- bool ok = (RegQueryValueEx(key, L"MachineGuid", NULL, NULL, (LPBYTE)buffer, &size) ==
- ERROR_SUCCESS);
- RegCloseKey(key);
- if (ok)
- return QStringView(buffer, (size - 1) / 2).toLatin1();
- }
-#endif
- return QByteArray();
-}
-
-/*!
- \since 5.11
-
- Returns a unique ID for this machine's boot, if one can be determined. If
- no unique ID could be determined, this function returns an empty byte
- array. This value is expected to change after every boot and can be
- considered globally unique.
-
- This function is currently only implemented for Linux and Apple operating
- systems.
-
- \sa machineUniqueId()
-*/
-QByteArray QSysInfo::bootUniqueId()
-{
-#ifdef Q_OS_LINUX
- // use low-level API here for simplicity
- int fd = qt_safe_open("/proc/sys/kernel/random/boot_id", O_RDONLY);
- if (fd != -1) {
- char uuid[UuidStringLen];
- qint64 len = qt_safe_read(fd, uuid, sizeof(uuid));
- qt_safe_close(fd);
- if (len == UuidStringLen)
- return QByteArray(uuid, UuidStringLen);
- }
-#elif defined(Q_OS_DARWIN)
- // "kern.bootsessionuuid" is only available by name
- char uuid[UuidStringLen + 1];
- size_t uuidlen = sizeof(uuid);
- if (sysctlbyname("kern.bootsessionuuid", uuid, &uuidlen, nullptr, 0) == 0
- && uuidlen == sizeof(uuid))
- return QByteArray(uuid, uuidlen - 1);
-#endif
- return QByteArray();
-};
-
-/*!
- \macro void Q_ASSERT(bool test)
- \relates <QtGlobal>
-
- Prints a warning message containing the source code file name and
- line number if \a test is \c false.
-
- Q_ASSERT() is useful for testing pre- and post-conditions
- during development. It does nothing if \c QT_NO_DEBUG was defined
- during compilation.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 17
-
- If \c b is zero, the Q_ASSERT statement will output the following
- message using the qFatal() function:
-
- \snippet code/src_corelib_global_qglobal.cpp 18
-
- \sa Q_ASSERT_X(), qFatal(), {Debugging Techniques}
-*/
-
-/*!
- \macro void Q_ASSERT_X(bool test, const char *where, const char *what)
- \relates <QtGlobal>
-
- Prints the message \a what together with the location \a where,
- the source file name and line number if \a test is \c false.
-
- Q_ASSERT_X is useful for testing pre- and post-conditions during
- development. It does nothing if \c QT_NO_DEBUG was defined during
- compilation.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 19
-
- If \c b is zero, the Q_ASSERT_X statement will output the following
- message using the qFatal() function:
-
- \snippet code/src_corelib_global_qglobal.cpp 20
-
- \sa Q_ASSERT(), qFatal(), {Debugging Techniques}
-*/
-
-/*!
- \macro void Q_ASSUME(bool expr)
- \relates <QtGlobal>
- \since 5.0
-
- Causes the compiler to assume that \a expr is \c true. This macro is useful
- for improving code generation, by providing the compiler with hints about
- conditions that it would not otherwise know about. However, there is no
- guarantee that the compiler will actually use those hints.
-
- This macro could be considered a "lighter" version of \l{Q_ASSERT()}. While
- Q_ASSERT will abort the program's execution if the condition is \c false,
- Q_ASSUME will tell the compiler not to generate code for those conditions.
- Therefore, it is important that the assumptions always hold, otherwise
- undefined behaviour may occur.
-
- If \a expr is a constantly \c false condition, Q_ASSUME will tell the compiler
- that the current code execution cannot be reached. That is, Q_ASSUME(false)
- is equivalent to Q_UNREACHABLE().
-
- In debug builds the condition is enforced by an assert to facilitate debugging.
-
- \note Q_LIKELY() tells the compiler that the expression is likely, but not
- the only possibility. Q_ASSUME tells the compiler that it is the only
- possibility.
-
- \sa Q_ASSERT(), Q_UNREACHABLE(), Q_LIKELY()
-*/
-
-/*!
- \macro void Q_UNREACHABLE()
- \relates <QtGlobal>
- \since 5.0
-
- Tells the compiler that the current point cannot be reached by any
- execution, so it may optimize any code paths leading here as dead code, as
- well as code continuing from here.
-
- This macro is useful to mark impossible conditions. For example, given the
- following enum:
-
- \snippet code/src_corelib_global_qglobal.cpp qunreachable-enum
-
- One can write a switch table like so:
-
- \snippet code/src_corelib_global_qglobal.cpp qunreachable-switch
-
- The advantage of inserting Q_UNREACHABLE() at that point is that the
- compiler is told not to generate code for a shape variable containing that
- value. If the macro is missing, the compiler will still generate the
- necessary comparisons for that value. If the case label were removed, some
- compilers could produce a warning that some enum values were not checked.
-
- By using this macro in impossible conditions, code coverage may be improved
- as dead code paths may be eliminated.
-
- In debug builds the condition is enforced by an assert to facilitate debugging.
-
- \sa Q_ASSERT(), Q_ASSUME(), qFatal()
-*/
-
-/*!
- \macro void Q_FALLTHROUGH()
- \relates <QtGlobal>
- \since 5.8
-
- Can be used in switch statements at the end of case block to tell the compiler
- and other developers that that the lack of a break statement is intentional.
-
- This is useful since a missing break statement is often a bug, and some
- compilers can be configured to emit warnings when one is not found.
-
- \sa Q_UNREACHABLE()
-*/
-
-/*!
- \macro void Q_CHECK_PTR(void *pointer)
- \relates <QtGlobal>
-
- If \a pointer is \nullptr, prints a message containing the source
- code's file name and line number, saying that the program ran out
- of memory and aborts program execution. It throws \c std::bad_alloc instead
- if exceptions are enabled.
-
- Q_CHECK_PTR does nothing if \c QT_NO_DEBUG and \c QT_NO_EXCEPTIONS were
- defined during compilation. Therefore you must not use Q_CHECK_PTR to check
- for successful memory allocations because the check will be disabled in
- some cases.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 21
-
- \sa qWarning(), {Debugging Techniques}
-*/
-
-/*!
- \fn template <typename T> T *q_check_ptr(T *p)
- \relates <QtGlobal>
-
- Uses Q_CHECK_PTR on \a p, then returns \a p.
-
- This can be used as an inline version of Q_CHECK_PTR.
-*/
-
-/*!
- \macro const char* Q_FUNC_INFO()
- \relates <QtGlobal>
-
- Expands to a string that describe the function the macro resides in. How this string looks
- more specifically is compiler dependent. With GNU GCC it is typically the function signature,
- while with other compilers it might be the line and column number.
-
- Q_FUNC_INFO can be conveniently used with qDebug(). For example, this function:
-
- \snippet code/src_corelib_global_qglobal.cpp 22
-
- when instantiated with the integer type, will with the GCC compiler produce:
-
- \tt{const TInputType& myMin(const TInputType&, const TInputType&) [with TInputType = int] was called with value1: 3 value2: 4}
-
- If this macro is used outside a function, the behavior is undefined.
- */
-
-/*!
- \internal
- The Q_CHECK_PTR macro calls this function if an allocation check
- fails.
-*/
-void qt_check_pointer(const char *n, int l) noexcept
-{
- // make separate printing calls so that the first one may flush;
- // the second one could want to allocate memory (fputs prints a
- // newline and stderr auto-flushes).
- fputs("Out of memory", stderr);
- fprintf(stderr, " in %s, line %d\n", n, l);
-
- std::terminate();
-}
-
-/*
- \internal
- Allows you to throw an exception without including <new>
- Called internally from Q_CHECK_PTR on certain OS combinations
-*/
-void qBadAlloc()
-{
-#ifndef QT_NO_EXCEPTIONS
- throw std::bad_alloc();
-#else
- std::terminate();
-#endif
-}
-
-/*
- \internal
- Allows you to call std::terminate() without including <exception>.
- Called internally from QT_TERMINATE_ON_EXCEPTION
-*/
-Q_NORETURN void qTerminate() noexcept
-{
- std::terminate();
-}
-
-/*
- The Q_ASSERT macro calls this function when the test fails.
-*/
-void qt_assert(const char *assertion, const char *file, int line) noexcept
-{
- QMessageLogger(file, line, nullptr).fatal("ASSERT: \"%s\" in file %s, line %d", assertion, file, line);
-}
-
-/*
- The Q_ASSERT_X macro calls this function when the test fails.
-*/
-void qt_assert_x(const char *where, const char *what, const char *file, int line) noexcept
-{
- QMessageLogger(file, line, nullptr).fatal("ASSERT failure in %s: \"%s\", file %s, line %d", where, what, file, line);
-}
-
/*
Dijkstra's bisection algorithm to find the square root of an integer.
@@ -3318,889 +118,10 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION unsigned int qt_int_sqrt(unsigned int n)
return p;
}
-// In the C runtime on all platforms access to the environment is not thread-safe. We
-// add thread-safety for the Qt wrappers.
-static QBasicMutex environmentMutex;
-
-/*
- Wraps tzset(), which accesses the environment, so should only be called while
- we hold the lock on the environment mutex.
-*/
-void qTzSet()
-{
- const auto locker = qt_scoped_lock(environmentMutex);
-#if defined(Q_OS_WIN)
- _tzset();
-#else
- tzset();
-#endif // Q_OS_WIN
-}
-
-/*
- Wrap mktime(), which is specified to behave as if it called tzset(), hence
- shares its implicit environment-dependence.
-*/
-time_t qMkTime(struct tm *when)
-{
- const auto locker = qt_scoped_lock(environmentMutex);
- return mktime(when);
-}
-
// Also specified to behave as if they call tzset():
// localtime() -- but not localtime_r(), which we use when threaded
// strftime() -- not used (except in tests)
-/*!
- \relates <QtGlobal>
- \threadsafe
-
- Returns the value of the environment variable with name \a varName as a
- QByteArray. If no variable by that name is found in the environment, this
- function returns a default-constructed QByteArray.
-
- The Qt environment manipulation functions are thread-safe, but this
- requires that the C library equivalent functions like getenv and putenv are
- not directly called.
-
- To convert the data to a QString use QString::fromLocal8Bit().
-
- \note on desktop Windows, qgetenv() may produce data loss if the
- original string contains Unicode characters not representable in the
- ANSI encoding. Use qEnvironmentVariable() instead.
- On Unix systems, this function is lossless.
-
- \sa qputenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet(),
- qEnvironmentVariableIsEmpty()
-*/
-QByteArray qgetenv(const char *varName)
-{
- const auto locker = qt_scoped_lock(environmentMutex);
-#ifdef Q_CC_MSVC
- size_t requiredSize = 0;
- QByteArray buffer;
- getenv_s(&requiredSize, 0, 0, varName);
- if (requiredSize == 0)
- return buffer;
- buffer.resize(int(requiredSize));
- getenv_s(&requiredSize, buffer.data(), requiredSize, varName);
- // requiredSize includes the terminating null, which we don't want.
- Q_ASSERT(buffer.endsWith('\0'));
- buffer.chop(1);
- return buffer;
-#else
- return QByteArray(::getenv(varName));
-#endif
-}
-
-/*!
- \fn QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
- \fn QString qEnvironmentVariable(const char *varName)
-
- \relates <QtGlobal>
- \since 5.10
-
- These functions return the value of the environment variable, \a varName, as a
- QString. If no variable \a varName is found in the environment and \a defaultValue
- is provided, \a defaultValue is returned. Otherwise QString() is returned.
-
- The Qt environment manipulation functions are thread-safe, but this
- requires that the C library equivalent functions like getenv and putenv are
- not directly called.
-
- The following table describes how to choose between qgetenv() and
- qEnvironmentVariable():
- \table
- \header \li Condition \li Recommendation
- \row
- \li Variable contains file paths or user text
- \li qEnvironmentVariable()
- \row
- \li Windows-specific code
- \li qEnvironmentVariable()
- \row
- \li Unix-specific code, destination variable is not QString and/or is
- used to interface with non-Qt APIs
- \li qgetenv()
- \row
- \li Destination variable is a QString
- \li qEnvironmentVariable()
- \row
- \li Destination variable is a QByteArray or std::string
- \li qgetenv()
- \endtable
-
- \note on Unix systems, this function may produce data loss if the original
- string contains arbitrary binary data that cannot be decoded by the locale
- codec. Use qgetenv() instead for that case. On Windows, this function is
- lossless.
-
- \note the variable name \a varName must contain only US-ASCII characters.
-
- \sa qputenv(), qgetenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty()
-*/
-QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
-{
-#if defined(Q_OS_WIN)
- const auto locker = qt_scoped_lock(environmentMutex);
- QVarLengthArray<wchar_t, 32> wname(int(strlen(varName)) + 1);
- for (int i = 0; i < wname.size(); ++i) // wname.size() is correct: will copy terminating null
- wname[i] = uchar(varName[i]);
- size_t requiredSize = 0;
- QString buffer;
- _wgetenv_s(&requiredSize, 0, 0, wname.data());
- if (requiredSize == 0)
- return defaultValue;
- buffer.resize(int(requiredSize));
- _wgetenv_s(&requiredSize, reinterpret_cast<wchar_t *>(buffer.data()), requiredSize,
- wname.data());
- // requiredSize includes the terminating null, which we don't want.
- Q_ASSERT(buffer.endsWith(QLatin1Char('\0')));
- buffer.chop(1);
- return buffer;
-#else
- QByteArray value = qgetenv(varName);
- if (value.isNull())
- return defaultValue;
-// duplicated in qfile.h (QFile::decodeName)
-#if defined(Q_OS_DARWIN)
- return QString::fromUtf8(value).normalized(QString::NormalizationForm_C);
-#else // other Unix
- return QString::fromLocal8Bit(value);
-#endif
-#endif
-}
-
-QString qEnvironmentVariable(const char *varName)
-{
- return qEnvironmentVariable(varName, QString());
-}
-
-/*!
- \relates <QtGlobal>
- \since 5.1
-
- Returns whether the environment variable \a varName is empty.
-
- Equivalent to
- \snippet code/src_corelib_global_qglobal.cpp is-empty
- except that it's potentially much faster, and can't throw exceptions.
-
- \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
-*/
-bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
-{
- const auto locker = qt_scoped_lock(environmentMutex);
-#ifdef Q_CC_MSVC
- // we provide a buffer that can only hold the empty string, so
- // when the env.var isn't empty, we'll get an ERANGE error (buffer
- // too small):
- size_t dummy;
- char buffer = '\0';
- return getenv_s(&dummy, &buffer, 1, varName) != ERANGE;
-#else
- const char * const value = ::getenv(varName);
- return !value || !*value;
-#endif
-}
-
-/*!
- \relates <QtGlobal>
- \since 5.5
-
- Returns the numerical value of the environment variable \a varName.
- If \a ok is not null, sets \c{*ok} to \c true or \c false depending
- on the success of the conversion.
-
- Equivalent to
- \snippet code/src_corelib_global_qglobal.cpp to-int
- except that it's much faster, and can't throw exceptions.
-
- \note there's a limit on the length of the value, which is sufficient for
- all valid values of int, not counting leading zeroes or spaces. Values that
- are too long will either be truncated or this function will set \a ok to \c
- false.
-
- \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
-*/
-int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
-{
- static const int NumBinaryDigitsPerOctalDigit = 3;
- static const int MaxDigitsForOctalInt =
- (std::numeric_limits<uint>::digits + NumBinaryDigitsPerOctalDigit - 1) / NumBinaryDigitsPerOctalDigit;
-
- const auto locker = qt_scoped_lock(environmentMutex);
-#ifdef Q_CC_MSVC
- // we provide a buffer that can hold any int value:
- char buffer[MaxDigitsForOctalInt + 2]; // +1 for NUL +1 for optional '-'
- size_t dummy;
- if (getenv_s(&dummy, buffer, sizeof buffer, varName) != 0) {
- if (ok)
- *ok = false;
- return 0;
- }
-#else
- const char * const buffer = ::getenv(varName);
- if (!buffer || strlen(buffer) > MaxDigitsForOctalInt + 2) {
- if (ok)
- *ok = false;
- return 0;
- }
-#endif
- bool ok_ = true;
- const char *endptr;
- const qlonglong value = qstrtoll(buffer, &endptr, 0, &ok_);
-
- // Keep the following checks in sync with QByteArray::toInt()
- if (!ok_) {
- if (ok)
- *ok = false;
- return 0;
- }
-
- if (*endptr != '\0') {
- while (ascii_isspace(*endptr))
- ++endptr;
- }
-
- if (*endptr != '\0') {
- // we stopped at a non-digit character after converting some digits
- if (ok)
- *ok = false;
- return 0;
- }
-
- if (int(value) != value) {
- if (ok)
- *ok = false;
- return 0;
- } else if (ok) {
- *ok = ok_;
- }
- return int(value);
-}
-
-/*!
- \relates <QtGlobal>
- \since 5.1
-
- Returns whether the environment variable \a varName is set.
-
- Equivalent to
- \snippet code/src_corelib_global_qglobal.cpp is-null
- except that it's potentially much faster, and can't throw exceptions.
-
- \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsEmpty()
-*/
-bool qEnvironmentVariableIsSet(const char *varName) noexcept
-{
- const auto locker = qt_scoped_lock(environmentMutex);
-#ifdef Q_CC_MSVC
- size_t requiredSize = 0;
- (void)getenv_s(&requiredSize, 0, 0, varName);
- return requiredSize != 0;
-#else
- return ::getenv(varName) != nullptr;
-#endif
-}
-
-/*!
- \relates <QtGlobal>
-
- This function sets the \a value of the environment variable named
- \a varName. It will create the variable if it does not exist. It
- returns 0 if the variable could not be set.
-
- Calling qputenv with an empty value removes the environment variable on
- Windows, and makes it set (but empty) on Unix. Prefer using qunsetenv()
- for fully portable behavior.
-
- \note qputenv() was introduced because putenv() from the standard
- C library was deprecated in VC2005 (and later versions). qputenv()
- uses the replacement function in VC, and calls the standard C
- library's implementation on all other platforms.
-
- \sa qgetenv(), qEnvironmentVariable()
-*/
-bool qputenv(const char *varName, const QByteArray &value)
-{
- const auto locker = qt_scoped_lock(environmentMutex);
-#if defined(Q_CC_MSVC)
- return _putenv_s(varName, value.constData()) == 0;
-#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_HAIKU)
- // POSIX.1-2001 has setenv
- return setenv(varName, value.constData(), true) == 0;
-#else
- QByteArray buffer(varName);
- buffer += '=';
- buffer += value;
- char *envVar = qstrdup(buffer.constData());
- int result = putenv(envVar);
- if (result != 0) // error. we have to delete the string.
- delete[] envVar;
- return result == 0;
-#endif
-}
-
-/*!
- \relates <QtGlobal>
-
- This function deletes the variable \a varName from the environment.
-
- Returns \c true on success.
-
- \since 5.1
-
- \sa qputenv(), qgetenv(), qEnvironmentVariable()
-*/
-bool qunsetenv(const char *varName)
-{
- const auto locker = qt_scoped_lock(environmentMutex);
-#if defined(Q_CC_MSVC)
- return _putenv_s(varName, "") == 0;
-#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_BSD4) || defined(Q_OS_HAIKU)
- // POSIX.1-2001, BSD and Haiku have unsetenv
- return unsetenv(varName) == 0;
-#elif defined(Q_CC_MINGW)
- // On mingw, putenv("var=") removes "var" from the environment
- QByteArray buffer(varName);
- buffer += '=';
- return putenv(buffer.constData()) == 0;
-#else
- // Fallback to putenv("var=") which will insert an empty var into the
- // environment and leak it
- QByteArray buffer(varName);
- buffer += '=';
- char *envVar = qstrdup(buffer.constData());
- return putenv(envVar) == 0;
-#endif
-}
-
-/*!
- \macro forever
- \relates <QtGlobal>
-
- This macro is provided for convenience for writing infinite
- loops.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 31
-
- It is equivalent to \c{for (;;)}.
-
- If you're worried about namespace pollution, you can disable this
- macro by adding the following line to your \c .pro file:
-
- \snippet code/src_corelib_global_qglobal.cpp 32
-
- \sa Q_FOREVER
-*/
-
-/*!
- \macro Q_FOREVER
- \relates <QtGlobal>
-
- Same as \l{forever}.
-
- This macro is available even when \c no_keywords is specified
- using the \c .pro file's \c CONFIG variable.
-
- \sa foreach()
-*/
-
-/*!
- \macro foreach(variable, container)
- \relates <QtGlobal>
-
- This macro is used to implement Qt's \c foreach loop. The \a
- variable parameter is a variable name or variable definition; the
- \a container parameter is a Qt container whose value type
- corresponds to the type of the variable. See \l{The foreach
- Keyword} for details.
-
- If you're worried about namespace pollution, you can disable this
- macro by adding the following line to your \c .pro file:
-
- \snippet code/src_corelib_global_qglobal.cpp 33
-
- \note Since Qt 5.7, the use of this macro is discouraged. It will
- be removed in a future version of Qt. Please use C++11 range-for,
- possibly with qAsConst(), as needed.
-
- \sa qAsConst()
-*/
-
-/*!
- \macro Q_FOREACH(variable, container)
- \relates <QtGlobal>
-
- Same as foreach(\a variable, \a container).
-
- This macro is available even when \c no_keywords is specified
- using the \c .pro file's \c CONFIG variable.
-
- \note Since Qt 5.7, the use of this macro is discouraged. It will
- be removed in a future version of Qt. Please use C++11 range-for,
- possibly with qAsConst(), as needed.
-
- \sa qAsConst()
-*/
-
-/*!
- \fn template <typename T> typename std::add_const<T>::type &qAsConst(T &t)
- \relates <QtGlobal>
- \since 5.7
-
- Returns \a t cast to \c{const T}.
-
- This function is a Qt implementation of C++17's std::as_const(),
- a cast function like std::move(). But while std::move() turns
- lvalues into rvalues, this function turns non-const lvalues into
- const lvalues. Like std::as_const(), it doesn't work on rvalues,
- because it cannot be efficiently implemented for rvalues without
- leaving dangling references.
-
- Its main use in Qt is to prevent implicitly-shared Qt containers
- from detaching:
- \snippet code/src_corelib_global_qglobal.cpp as-const-0
-
- Of course, in this case, you could (and probably should) have declared
- \c s as \c const in the first place:
- \snippet code/src_corelib_global_qglobal.cpp as-const-1
- but often that is not easily possible.
-
- It is important to note that qAsConst() does not copy its argument,
- it just performs a \c{const_cast<const T&>(t)}. This is also the reason
- why it is designed to fail for rvalues: The returned reference would go
- stale too soon. So while this works (but detaches the returned object):
- \snippet code/src_corelib_global_qglobal.cpp as-const-2
-
- this would not:
- \snippet code/src_corelib_global_qglobal.cpp as-const-3
-
- To prevent this construct from compiling (and failing at runtime), qAsConst() has
- a second, deleted, overload which binds to rvalues.
-*/
-
-/*!
- \fn template <typename T> void qAsConst(const T &&t)
- \relates <QtGlobal>
- \since 5.7
- \overload
-
- This overload is deleted to prevent a dangling reference in code like
- \snippet code/src_corelib_global_qglobal.cpp as-const-4
-*/
-
-/*!
- \fn template <typename T, typename U = T> T qExchange(T &obj, U &&newValue)
- \relates <QtGlobal>
- \since 5.14
-
- Replaces the value of \a obj with \a newValue and returns the old value of \a obj.
-
- This is Qt's implementation of std::exchange(). It differs from std::exchange()
- only in that it is \c constexpr already in C++14, and available on all supported
- compilers.
-
- Here is how to use qExchange() to implement move constructors:
- \code
- MyClass(MyClass &&other)
- : m_pointer{qExchange(other.m_pointer, nullptr)},
- m_int{qExchange(other.m_int, 0)},
- m_vector{std::move(other.m_vector)},
- ...
- \endcode
-
- For members of class type, we can use std::move(), as their move-constructor will
- do the right thing. But for scalar types such as raw pointers or integer type, move
- is the same as copy, which, particularly for pointers, is not what we expect. So, we
- cannot use std::move() for such types, but we can use std::exchange()/qExchange() to
- make sure the source object's member is already reset by the time we get to the
- initialization of our next data member, which might come in handy if the constructor
- exits with an exception.
-
- Here is how to use qExchange() to write a loop that consumes the collection it
- iterates over:
- \code
- for (auto &e : qExchange(collection, {})
- doSomethingWith(e);
- \endcode
-
- Which is equivalent to the following, much more verbose code:
- \code
- {
- auto tmp = std::move(collection);
- collection = {}; // or collection.clear()
- for (auto &e : tmp)
- doSomethingWith(e);
- } // destroys 'tmp'
- \endcode
-
- This is perfectly safe, as the for-loop keeps the result of qExchange() alive for as
- long as the loop runs, saving the declaration of a temporary variable. Be aware, though,
- that qExchange() returns a non-const object, so Qt containers may detach.
-*/
-
-/*!
- \fn template <typename Enum> std::underlying_type_t<Enum> qToUnderlying(Enum e)
- \relates <QtGlobal>
- \since 6.2
-
- Converts the enumerator \a e to the equivalent value expressed in its
- enumeration's underlying type.
-*/
-
-/*!
- \macro QT_TR_NOOP(sourceText)
- \relates <QtGlobal>
-
- Marks the UTF-8 encoded string literal \a sourceText for delayed
- translation in the current context (class).
-
- The macro tells lupdate to collect the string, and expands to
- \a sourceText itself.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 34
-
- The macro QT_TR_NOOP_UTF8() is identical and obsolete; this applies
- to all other _UTF8 macros as well.
-
- \sa QT_TRANSLATE_NOOP(), {Internationalization with Qt}
-*/
-
-/*!
- \macro QT_TRANSLATE_NOOP(context, sourceText)
- \relates <QtGlobal>
-
- Marks the UTF-8 encoded string literal \a sourceText for delayed
- translation in the given \a context. The \a context is typically
- a class name and also needs to be specified as a string literal.
-
- The macro tells lupdate to collect the string, and expands to
- \a sourceText itself.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 35
-
- \sa QT_TR_NOOP(), QT_TRANSLATE_NOOP3(), {Internationalization with Qt}
-*/
-
-/*!
- \macro QT_TRANSLATE_NOOP3(context, sourceText, disambiguation)
- \relates <QtGlobal>
- \since 4.4
-
- Marks the UTF-8 encoded string literal \a sourceText for delayed
- translation in the given \a context with the given \a disambiguation.
- The \a context is typically a class and also needs to be specified
- as a string literal. The string literal \a disambiguation should be
- a short semantic tag to tell apart otherwise identical strings.
-
- The macro tells lupdate to collect the string, and expands to an
- anonymous struct of the two string literals passed as \a sourceText
- and \a disambiguation.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 36
-
- \sa QT_TR_NOOP(), QT_TRANSLATE_NOOP(), {Internationalization with Qt}
-*/
-
-/*!
- \macro QT_TR_N_NOOP(sourceText)
- \relates <QtGlobal>
- \since 5.12
-
- Marks the UTF-8 encoded string literal \a sourceText for numerator
- dependent delayed translation in the current context (class).
-
- The macro tells lupdate to collect the string, and expands to
- \a sourceText itself.
-
- The macro expands to \a sourceText.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qttrnnoop
-
- \sa QT_TR_NOOP, {Internationalization with Qt}
-*/
-
-/*!
- \macro QT_TRANSLATE_N_NOOP(context, sourceText)
- \relates <QtGlobal>
- \since 5.12
-
- Marks the UTF-8 encoded string literal \a sourceText for numerator
- dependent delayed translation in the given \a context.
- The \a context is typically a class name and also needs to be
- specified as a string literal.
-
- The macro tells lupdate to collect the string, and expands to
- \a sourceText itself.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qttranslatennoop
-
- \sa QT_TRANSLATE_NOOP(), QT_TRANSLATE_N_NOOP3(),
- {Internationalization with Qt}
-*/
-
-/*!
- \macro QT_TRANSLATE_N_NOOP3(context, sourceText, comment)
- \relates <QtGlobal>
- \since 5.12
-
- Marks the UTF-8 encoded string literal \a sourceText for numerator
- dependent delayed translation in the given \a context with the given
- \a comment.
- The \a context is typically a class and also needs to be specified
- as a string literal. The string literal \a comment should be
- a short semantic tag to tell apart otherwise identical strings.
-
- The macro tells lupdate to collect the string, and expands to an
- anonymous struct of the two string literals passed as \a sourceText
- and \a comment.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qttranslatennoop3
-
- \sa QT_TR_NOOP(), QT_TRANSLATE_NOOP(), QT_TRANSLATE_NOOP3(),
- {Internationalization with Qt}
-*/
-
-/*!
- \fn QString qtTrId(const char *id, int n = -1)
- \relates <QtGlobal>
- \reentrant
- \since 4.6
-
- \brief The qtTrId function finds and returns a translated string.
-
- Returns a translated string identified by \a id.
- If no matching string is found, the id itself is returned. This
- should not happen under normal conditions.
-
- If \a n >= 0, all occurrences of \c %n in the resulting string
- are replaced with a decimal representation of \a n. In addition,
- depending on \a n's value, the translation text may vary.
-
- Meta data and comments can be passed as documented for QObject::tr().
- In addition, it is possible to supply a source string template like that:
-
- \tt{//% <C string>}
-
- or
-
- \tt{\\begincomment% <C string> \\endcomment}
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qttrid
-
- Creating QM files suitable for use with this function requires passing
- the \c -idbased option to the \c lrelease tool.
-
- \warning This method is reentrant only if all translators are
- installed \e before calling this method. Installing or removing
- translators while performing translations is not supported. Doing
- so will probably result in crashes or other undesirable behavior.
-
- \sa QObject::tr(), QCoreApplication::translate(), {Internationalization with Qt}
-*/
-
-/*!
- \macro QT_TRID_NOOP(id)
- \relates <QtGlobal>
- \since 4.6
-
- \brief The QT_TRID_NOOP macro marks an id for dynamic translation.
-
- The only purpose of this macro is to provide an anchor for attaching
- meta data like to qtTrId().
-
- The macro expands to \a id.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qttrid_noop
-
- \sa qtTrId(), {Internationalization with Qt}
-*/
-
-/*!
- \macro Q_LIKELY(expr)
- \relates <QtGlobal>
- \since 4.8
-
- \brief Hints to the compiler that the enclosed condition, \a expr, is
- likely to evaluate to \c true.
-
- Use of this macro can help the compiler to optimize the code.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qlikely
-
- \sa Q_UNLIKELY()
-*/
-
-/*!
- \macro Q_UNLIKELY(expr)
- \relates <QtGlobal>
- \since 4.8
-
- \brief Hints to the compiler that the enclosed condition, \a expr, is
- likely to evaluate to \c false.
-
- Use of this macro can help the compiler to optimize the code.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qunlikely
-
- \sa Q_LIKELY()
-*/
-
-/*!
- \macro QT_POINTER_SIZE
- \relates <QtGlobal>
-
- Expands to the size of a pointer in bytes (4 or 8). This is
- equivalent to \c sizeof(void *) but can be used in a preprocessor
- directive.
-*/
-
-/*!
- \macro const char *qPrintable(const QString &str)
- \relates <QtGlobal>
-
- Returns \a str as a \c{const char *}. This is equivalent to
- \a{str}.toLocal8Bit().constData().
-
- The char pointer will be invalid after the statement in which
- qPrintable() is used. This is because the array returned by
- QString::toLocal8Bit() will fall out of scope.
-
- \note qDebug(), qInfo(), qWarning(), qCritical(), qFatal() expect
- %s arguments to be UTF-8 encoded, while qPrintable() converts to
- local 8-bit encoding. Therefore qUtf8Printable() should be used
- for logging strings instead of qPrintable().
-
- \sa qUtf8Printable()
-*/
-
-/*!
- \macro const char *qUtf8Printable(const QString &str)
- \relates <QtGlobal>
- \since 5.4
-
- Returns \a str as a \c{const char *}. This is equivalent to
- \a{str}.toUtf8().constData().
-
- The char pointer will be invalid after the statement in which
- qUtf8Printable() is used. This is because the array returned by
- QString::toUtf8() will fall out of scope.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 37
-
- \sa qPrintable(), qDebug(), qInfo(), qWarning(), qCritical(), qFatal()
-*/
-
-/*!
- \macro const wchar_t *qUtf16Printable(const QString &str)
- \relates <QtGlobal>
- \since 5.7
-
- Returns \a str as a \c{const ushort *}, but cast to a \c{const wchar_t *}
- to avoid warnings. This is equivalent to \a{str}.utf16() plus some casting.
-
- The only useful thing you can do with the return value of this macro is to
- pass it to QString::asprintf() for use in a \c{%ls} conversion. In particular,
- the return value is \e{not} a valid \c{const wchar_t*}!
-
- In general, the pointer will be invalid after the statement in which
- qUtf16Printable() is used. This is because the pointer may have been
- obtained from a temporary expression, which will fall out of scope.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qUtf16Printable
-
- \sa qPrintable(), qDebug(), qInfo(), qWarning(), qCritical(), qFatal()
-*/
-
-/*!
- \macro Q_DECLARE_TYPEINFO(Type, Flags)
- \relates <QtGlobal>
-
- You can use this macro to specify information about a custom type
- \a Type. With accurate type information, Qt's \l{Container Classes}
- {generic containers} can choose appropriate storage methods and
- algorithms.
-
- \a Flags can be one of the following:
-
- \list
- \li \c Q_PRIMITIVE_TYPE specifies that \a Type is a POD (plain old
- data) type with no constructor or destructor, and for which memcpy()ing
- creates a valid independent copy of the object.
- \li \c Q_RELOCATABLE_TYPE specifies that \a Type has a constructor
- and/or a destructor but can be moved in memory using \c
- memcpy().
- \li \c Q_MOVABLE_TYPE is the same as \c Q_RELOCATABLE_TYPE. Prefer to use
- \c Q_RELOCATABLE_TYPE in new code. Note: despite the name, this
- has nothing to do with move constructors or C++ move semantics.
- \li \c Q_COMPLEX_TYPE (the default) specifies that \a Type has
- constructors and/or a destructor and that it may not be moved
- in memory.
- \endlist
-
- Example of a "primitive" type:
-
- \snippet code/src_corelib_global_qglobal.cpp 38
-
- An example of a non-POD "primitive" type is QUuid: Even though
- QUuid has constructors (and therefore isn't POD), every bit
- pattern still represents a valid object, and memcpy() can be used
- to create a valid independent copy of a QUuid object.
-
- Example of a relocatable type:
-
- \snippet code/src_corelib_global_qglobal.cpp 39
-
- Qt will try to detect the class of a type using
- \l {https://en.cppreference.com/w/cpp/types/is_trivial} {std::is_trivial_v<T>}
- to indentify primitive
- types and it will require both
- \l {https://en.cppreference.com/w/cpp/types/is_trivially_copyable} {std::is_trivially_copyable_v<T>}
- and
- \l {https://en.cppreference.com/w/cpp/types/is_destructible} {std::is_trivially_destructible_v<T>}
- to identify relocatable types.
- Use this macro to tune the behavior.
- For instance many types would be candidates for Q_RELOCATABLE_TYPE despite
- not being trivially-copyable.
-*/
-
-/*!
- \macro Q_UNUSED(name)
- \relates <QtGlobal>
-
- Indicates to the compiler that the parameter with the specified
- \a name is not used in the body of a function. This can be used to
- suppress compiler warnings while allowing functions to be defined
- with meaningful parameter names in their signatures.
-*/
-
struct QInternal_CallBackTable
{
QList<QList<qInternalCallback>> callbacks;
@@ -4249,57 +170,6 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
}
/*!
- \macro Q_BYTE_ORDER
- \relates <QtGlobal>
-
- This macro can be used to determine the byte order your system
- uses for storing data in memory. i.e., whether your system is
- little-endian or big-endian. It is set by Qt to one of the macros
- Q_LITTLE_ENDIAN or Q_BIG_ENDIAN. You normally won't need to worry
- about endian-ness, but you might, for example if you need to know
- which byte of an integer or UTF-16 character is stored in the
- lowest address. Endian-ness is important in networking, where
- computers with different values for Q_BYTE_ORDER must pass data
- back and forth.
-
- Use this macro as in the following examples.
-
- \snippet code/src_corelib_global_qglobal.cpp 40
-
- \sa Q_BIG_ENDIAN, Q_LITTLE_ENDIAN
-*/
-
-/*!
- \macro Q_LITTLE_ENDIAN
- \relates <QtGlobal>
-
- This macro represents a value you can compare to the macro
- Q_BYTE_ORDER to determine the endian-ness of your system. In a
- little-endian system, the least significant byte is stored at the
- lowest address. The other bytes follow in increasing order of
- significance.
-
- \snippet code/src_corelib_global_qglobal.cpp 41
-
- \sa Q_BYTE_ORDER, Q_BIG_ENDIAN
-*/
-
-/*!
- \macro Q_BIG_ENDIAN
- \relates <QtGlobal>
-
- This macro represents a value you can compare to the macro
- Q_BYTE_ORDER to determine the endian-ness of your system. In a
- big-endian system, the most significant byte is stored at the
- lowest address. The other bytes follow in decreasing order of
- significance.
-
- \snippet code/src_corelib_global_qglobal.cpp 42
-
- \sa Q_BYTE_ORDER, Q_LITTLE_ENDIAN
-*/
-
-/*!
\macro QT_NAMESPACE
\internal
@@ -4429,296 +299,6 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
*/
/*!
- \fn bool qFuzzyCompare(double p1, double p2)
- \relates <QtGlobal>
- \since 4.4
- \threadsafe
-
- Compares the floating point value \a p1 and \a p2 and
- returns \c true if they are considered equal, otherwise \c false.
-
- Note that comparing values where either \a p1 or \a p2 is 0.0 will not work,
- nor does comparing values where one of the values is NaN or infinity.
- If one of the values is always 0.0, use qFuzzyIsNull instead. If one of the
- values is likely to be 0.0, one solution is to add 1.0 to both values.
-
- \snippet code/src_corelib_global_qglobal.cpp 46
-
- The two numbers are compared in a relative way, where the
- exactness is stronger the smaller the numbers are.
- */
-
-/*!
- \fn bool qFuzzyCompare(float p1, float p2)
- \relates <QtGlobal>
- \since 4.4
- \threadsafe
-
- Compares the floating point value \a p1 and \a p2 and
- returns \c true if they are considered equal, otherwise \c false.
-
- The two numbers are compared in a relative way, where the
- exactness is stronger the smaller the numbers are.
- */
-
-/*!
- \fn bool qFuzzyIsNull(double d)
- \relates <QtGlobal>
- \since 4.4
- \threadsafe
-
- Returns true if the absolute value of \a d is within 0.000000000001 of 0.0.
-*/
-
-/*!
- \fn bool qFuzzyIsNull(float f)
- \relates <QtGlobal>
- \since 4.4
- \threadsafe
-
- Returns true if the absolute value of \a f is within 0.00001f of 0.0.
-*/
-
-/*!
- \macro QT_REQUIRE_VERSION(int argc, char **argv, const char *version)
- \relates <QtGlobal>
-
- This macro can be used to ensure that the application is run
- against a recent enough version of Qt. This is especially useful
- if your application depends on a specific bug fix introduced in a
- bug-fix release (e.g., 4.0.2).
-
- The \a argc and \a argv parameters are the \c main() function's
- \c argc and \c argv parameters. The \a version parameter is a
- string literal that specifies which version of Qt the application
- requires (e.g., "4.0.2").
-
- Example:
-
- \snippet code/src_gui_dialogs_qmessagebox.cpp 4
-*/
-
-/*!
- \macro Q_DECL_EXPORT
- \relates <QtGlobal>
-
- This macro marks a symbol for shared library export (see
- \l{sharedlibrary.html}{Creating Shared Libraries}).
-
- \sa Q_DECL_IMPORT
-*/
-
-/*!
- \macro Q_DECL_IMPORT
- \relates <QtGlobal>
-
- This macro declares a symbol to be an import from a shared library (see
- \l{sharedlibrary.html}{Creating Shared Libraries}).
-
- \sa Q_DECL_EXPORT
-*/
-
-/*!
- \macro Q_DECL_CONSTEXPR
- \relates <QtGlobal>
-
- This macro can be used to declare variable that should be constructed at compile-time,
- or an inline function that can be computed at compile-time.
-
- It expands to "constexpr" if your compiler supports that C++11 keyword, or to nothing
- otherwise.
-
- \sa Q_DECL_RELAXED_CONSTEXPR
-*/
-
-/*!
- \macro Q_DECL_RELAXED_CONSTEXPR
- \relates <QtGlobal>
-
- This macro can be used to declare an inline function that can be computed
- at compile-time according to the relaxed rules from C++14.
-
- It expands to "constexpr" if your compiler supports C++14 relaxed constant
- expressions, or to nothing otherwise.
-
- \sa Q_DECL_CONSTEXPR
-*/
-
-/*!
- \macro qDebug(const char *message, ...)
- \relates <QtGlobal>
- \threadsafe
-
- Calls the message handler with the debug message \a message. If no
- message handler has been installed, the message is printed to
- stderr. Under Windows the message is sent to the console, if it is a
- console application; otherwise, it is sent to the debugger. On QNX, the
- message is sent to slogger2. This function does nothing if \c QT_NO_DEBUG_OUTPUT
- was defined during compilation.
-
- If you pass the function a format string and a list of arguments,
- it works in similar way to the C printf() function. The format
- should be a Latin-1 string.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp 24
-
- If you include \c <QtDebug>, a more convenient syntax is also
- available:
-
- \snippet code/src_corelib_global_qglobal.cpp 25
-
- With this syntax, the function returns a QDebug object that is
- configured to use the QtDebugMsg message type. It automatically
- puts a single space between each item, and outputs a newline at
- the end. It supports many C++ and Qt types.
-
- To suppress the output at run-time, install your own message handler
- with qInstallMessageHandler().
-
- \sa qInfo(), qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
- {Debugging Techniques}
-*/
-
-/*!
- \macro qInfo(const char *message, ...)
- \relates <QtGlobal>
- \threadsafe
- \since 5.5
-
- Calls the message handler with the informational message \a message. If no
- message handler has been installed, the message is printed to
- stderr. Under Windows, the message is sent to the console, if it is a
- console application; otherwise, it is sent to the debugger. On QNX the
- message is sent to slogger2. This function does nothing if \c QT_NO_INFO_OUTPUT
- was defined during compilation.
-
- If you pass the function a format string and a list of arguments,
- it works in similar way to the C printf() function. The format
- should be a Latin-1 string.
-
- Example:
-
- \snippet code/src_corelib_global_qglobal.cpp qInfo_printf
-
- If you include \c <QtDebug>, a more convenient syntax is also
- available:
-
- \snippet code/src_corelib_global_qglobal.cpp qInfo_stream
-
- With this syntax, the function returns a QDebug object that is
- configured to use the QtInfoMsg message type. It automatically
- puts a single space between each item, and outputs a newline at
- the end. It supports many C++ and Qt types.
-
- To suppress the output at run-time, install your own message handler
- with qInstallMessageHandler().
-
- \sa qDebug(), qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
- {Debugging Techniques}
-*/
-
-/*!
- \macro qWarning(const char *message, ...)
- \relates <QtGlobal>
- \threadsafe
-
- Calls the message handler with the warning message \a message. If no
- message handler has been installed, the message is printed to
- stderr. Under Windows, the message is sent to the debugger.
- On QNX the message is sent to slogger2. This
- function does nothing if \c QT_NO_WARNING_OUTPUT was defined
- during compilation; it exits if at the nth warning corresponding to the
- counter in environment variable \c QT_FATAL_WARNINGS. That is, if the
- environment variable contains the value 1, it will exit on the 1st message;
- if it contains the value 10, it will exit on the 10th message. Any
- non-numeric value is equivalent to 1.
-
- This function takes a format string and a list of arguments,
- similar to the C printf() function. The format should be a Latin-1
- string.
-
- Example:
- \snippet code/src_corelib_global_qglobal.cpp 26
-
- If you include <QtDebug>, a more convenient syntax is
- also available:
-
- \snippet code/src_corelib_global_qglobal.cpp 27
-
- This syntax inserts a space between each item, and
- appends a newline at the end.
-
- To suppress the output at runtime, install your own message handler
- with qInstallMessageHandler().
-
- \sa qDebug(), qInfo(), qCritical(), qFatal(), qInstallMessageHandler(),
- {Debugging Techniques}
-*/
-
-/*!
- \macro qCritical(const char *message, ...)
- \relates <QtGlobal>
- \threadsafe
-
- Calls the message handler with the critical message \a message. If no
- message handler has been installed, the message is printed to
- stderr. Under Windows, the message is sent to the debugger.
- On QNX the message is sent to slogger2.
-
- It exits if the environment variable QT_FATAL_CRITICALS is not empty.
-
- This function takes a format string and a list of arguments,
- similar to the C printf() function. The format should be a Latin-1
- string.
-
- Example:
- \snippet code/src_corelib_global_qglobal.cpp 28
-
- If you include <QtDebug>, a more convenient syntax is
- also available:
-
- \snippet code/src_corelib_global_qglobal.cpp 29
-
- A space is inserted between the items, and a newline is
- appended at the end.
-
- To suppress the output at runtime, install your own message handler
- with qInstallMessageHandler().
-
- \sa qDebug(), qInfo(), qWarning(), qFatal(), qInstallMessageHandler(),
- {Debugging Techniques}
-*/
-
-/*!
- \macro qFatal(const char *message, ...)
- \relates <QtGlobal>
-
- Calls the message handler with the fatal message \a message. If no
- message handler has been installed, the message is printed to
- stderr. Under Windows, the message is sent to the debugger.
- On QNX the message is sent to slogger2.
-
- If you are using the \b{default message handler} this function will
- abort to create a core dump. On Windows, for debug builds,
- this function will report a _CRT_ERROR enabling you to connect a debugger
- to the application.
-
- This function takes a format string and a list of arguments,
- similar to the C printf() function.
-
- Example:
- \snippet code/src_corelib_global_qglobal.cpp 30
-
- To suppress the output at runtime, install your own message handler
- with qInstallMessageHandler().
-
- \sa qDebug(), qInfo(), qWarning(), qCritical(), qInstallMessageHandler(),
- {Debugging Techniques}
-*/
-
-/*!
\macro qMove(x)
\relates <QtGlobal>
\deprecated
@@ -4731,176 +311,52 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
*/
/*!
- \macro Q_DECL_NOTHROW
+ \macro QT_ENABLE_STRICT_MODE_UP_TO
\relates <QtGlobal>
- \since 5.0
+ \since 6.8
- This macro marks a function as never throwing, under no
- circumstances. If the function does nevertheless throw, the
- behaviour is undefined.
+ Defining this macro will disable a number of Qt APIs that are
+ deemed suboptimal or dangerous.
- The macro expands to either "throw()", if that has some benefit on
- the compiler, or to C++11 noexcept, if available, or to nothing
- otherwise.
+ This macro's value must be set to a Qt version, using
+ \l{QT_VERSION_CHECK}'s encoding. For instance, in order to set it
+ to Qt 6.6, define \c{QT_ENABLE_STRICT_MODE_UP_TO=0x060600}.
+ This will disable only the APIs introduced in versions up to (and
+ including) the specified Qt version.
- If you need C++11 noexcept semantics, don't use this macro, use
- Q_DECL_NOEXCEPT/Q_DECL_NOEXCEPT_EXPR instead.
+ If the \l QT_DISABLE_DEPRECATED_UP_TO macro is \e not defined,
+ then QT_ENABLE_STRICT_MODE_UP_TO will define it as well,
+ to the same value.
- \sa Q_DECL_NOEXCEPT, Q_DECL_NOEXCEPT_EXPR()
-*/
+ This macro should always be set to the minimum Qt version that
+ your project wants to support.
-/*!
- \macro QT_TERMINATE_ON_EXCEPTION(expr)
- \relates <QtGlobal>
- \internal
-
- In general, use of the Q_DECL_NOEXCEPT macro is preferred over
- Q_DECL_NOTHROW, because it exhibits well-defined behavior and
- supports the more powerful Q_DECL_NOEXCEPT_EXPR variant. However,
- use of Q_DECL_NOTHROW has the advantage that Windows builds
- benefit on a wide range or compiler versions that do not yet
- support the C++11 noexcept feature.
-
- It may therefore be beneficial to use Q_DECL_NOTHROW and emulate
- the C++11 behavior manually with an embedded try/catch.
-
- Qt provides the QT_TERMINATE_ON_EXCEPTION(expr) macro for this
- purpose. It either expands to \c expr (if Qt is compiled without
- exception support or the compiler supports C++11 noexcept
- semantics) or to
- \snippet code/src_corelib_global_qglobal.cpp qterminate
- otherwise.
-
- Since this macro expands to just \c expr if the compiler supports
- C++11 noexcept, expecting the compiler to take over responsibility
- of calling std::terminate() in that case, it should not be used
- outside Q_DECL_NOTHROW functions.
-
- \sa Q_DECL_NOEXCEPT, Q_DECL_NOTHROW, qTerminate()
-*/
-
-/*!
- \macro Q_DECL_NOEXCEPT
- \relates <QtGlobal>
- \since 5.0
-
- This macro marks a function as never throwing. If the function
- does nevertheless throw, the behaviour is defined:
- std::terminate() is called.
-
- The macro expands to C++11 noexcept, if available, or to nothing
- otherwise.
-
- If you need the operator version of C++11 noexcept, use
- Q_DECL_NOEXCEPT_EXPR(x).
-
- If you don't need C++11 noexcept semantics, e.g. because your
- function can't possibly throw, don't use this macro, use
- Q_DECL_NOTHROW instead.
-
- \sa Q_DECL_NOTHROW, Q_DECL_NOEXCEPT_EXPR()
-*/
-
-/*!
- \macro Q_DECL_NOEXCEPT_EXPR(x)
- \relates <QtGlobal>
- \since 5.0
-
- This macro marks a function as non-throwing if \a x is \c true. If
- the function does nevertheless throw, the behaviour is defined:
- std::terminate() is called.
-
- The macro expands to C++11 noexcept(x), if available, or to
- nothing otherwise.
-
- If you need the always-true version of C++11 noexcept, use
- Q_DECL_NOEXCEPT.
-
- If you don't need C++11 noexcept semantics, e.g. because your
- function can't possibly throw, don't use this macro, use
- Q_DECL_NOTHROW instead.
-
- \sa Q_DECL_NOTHROW, Q_DECL_NOEXCEPT
-*/
-
-/*!
- \macro Q_DECL_OVERRIDE
- \since 5.0
- \deprecated
- \relates <QtGlobal>
+ The APIs disabled by this macro are listed in the table below,
+ together with the minimum value to use in order to disable them.
- This macro can be used to declare an overriding virtual
- function. Use of this markup will allow the compiler to generate
- an error if the overriding virtual function does not in fact
- override anything.
-
- It expands to "override".
-
- The macro goes at the end of the function, usually after the
- \c{const}, if any:
- \snippet code/src_corelib_global_qglobal.cpp qdecloverride
-
- \sa Q_DECL_FINAL
-*/
-
-/*!
- \macro Q_DECL_FINAL
- \since 5.0
- \deprecated
- \relates <QtGlobal>
-
- This macro can be used to declare an overriding virtual or a class
- as "final", with Java semantics. Further-derived classes can then
- no longer override this virtual function, or inherit from this
- class, respectively.
-
- It expands to "final".
-
- The macro goes at the end of the function, usually after the
- \c{const}, if any:
- \snippet code/src_corelib_global_qglobal.cpp qdeclfinal-1
-
- For classes, it goes in front of the \c{:} in the class
- definition, if any:
- \snippet code/src_corelib_global_qglobal.cpp qdeclfinal-2
-
- \sa Q_DECL_OVERRIDE
-*/
-
-/*!
- \macro Q_FORWARD_DECLARE_OBJC_CLASS(classname)
- \since 5.2
- \relates <QtGlobal>
-
- Forward-declares an Objective-C \a classname in a manner such that it can be
- compiled as either Objective-C or C++.
-
- This is primarily intended for use in header files that may be included by
- both Objective-C and C++ source files.
-*/
-
-/*!
- \macro Q_FORWARD_DECLARE_CF_TYPE(type)
- \since 5.2
- \relates <QtGlobal>
-
- Forward-declares a Core Foundation \a type. This includes the actual
- type and the ref type. For example, Q_FORWARD_DECLARE_CF_TYPE(CFString)
- declares __CFString and CFStringRef.
-*/
+ \table
+ \header \li Version \li Disabled APIs
+ \row \li 6.0.0 \li \l{foreach-keyword}{foreach} (see \l{QT_NO_FOREACH})
+ \row \li 6.0.0 \li QString constructors from \c{const char *} (see \l{QT_NO_CAST_FROM_ASCII})
+ \row \li 6.0.0 \li QString conversions towards \c{const char *} / QByteArray (see \l{QT_NO_CAST_TO_ASCII})
+ \row \li 6.0.0 \li QByteArray implicit conversions towards \c{const char *} (see \l{QT_NO_CAST_FROM_BYTEARRAY})
+ \row \li 6.0.0 \li QUrl implicit conversions from QString (see \l{QT_NO_URL_CAST_FROM_STRING})
+ \row \li 6.0.0 \li Allowing narrowing conversions in signal-slot connections (see \l{QT_NO_NARROWING_CONVERSIONS_IN_CONNECT})
+ \row \li 6.0.0 \li Java-style iterators for Qt containers
+ \row \li 6.6.0 \li The qExchange() function (see \l{QT_NO_QEXCHANGE})
+ \row \li 6.7.0 \li Overloads of QObject::connect that do not take a context object (see \l{QT_NO_CONTEXTLESS_CONNECT})
+ \row \li 6.8.0 \li The qAsConst() function (see \l{QT_NO_QASCONST})
+ \endtable
-/*!
- \macro Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type)
- \since 5.2
- \relates <QtGlobal>
+ Moreover, individual APIs may also get disabled as part of the
+ setting of QT_DISABLE_DEPRECATED_UP_TO. Please refer to each class'
+ documentation for more details.
- Forward-declares a mutable Core Foundation \a type. This includes the actual
- type and the ref type. For example, Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(CFMutableString)
- declares __CFMutableString and CFMutableStringRef.
+ \sa QT_DISABLE_DEPRECATED_UP_TO, QT_NO_KEYWORDS, QT_VERSION_CHECK
*/
-namespace QNativeInterface::Private {
- Q_LOGGING_CATEGORY(lcNativeInterface, "qt.nativeinterface")
+namespace QtPrivate {
+Q_LOGGING_CATEGORY(lcNativeInterface, "qt.nativeinterface")
}
QT_END_NAMESPACE
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 8bc7181633..1009057bad 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1,46 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2019 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2019 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QGLOBAL_H
#define QGLOBAL_H
+#if 0
+#pragma qt_class(QtGlobal)
+#endif
+
#ifdef __cplusplus
# include <type_traits>
# include <cstddef>
@@ -49,1404 +17,30 @@
#endif
#ifndef __ASSEMBLER__
# include <assert.h>
+# include <stdbool.h>
# include <stddef.h>
#endif
-/*
- QT_VERSION is (major << 16) + (minor << 8) + patch.
-*/
-#define QT_VERSION QT_VERSION_CHECK(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH)
-/*
- can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
-*/
-#define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
-
-#ifdef QT_BOOTSTRAPPED
-#include <QtCore/qconfig-bootstrapped.h>
-#else
-#include <QtCore/qconfig.h>
-#include <QtCore/qtcore-config.h>
-#endif
-
-/*
- The QT_CONFIG macro implements a safe compile time check for features of Qt.
- Features can be in three states:
- 0 or undefined: This will lead to a compile error when testing for it
- -1: The feature is not available
- 1: The feature is available
-*/
-#define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1)
-#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not available.")
+#include <QtCore/qtversionchecks.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtcoreexports.h>
-/* These two macros makes it possible to turn the builtin line expander into a
- * string literal. */
-#define QT_STRINGIFY2(x) #x
-#define QT_STRINGIFY(x) QT_STRINGIFY2(x)
+#include <QtCore/qtpreprocessorsupport.h>
#include <QtCore/qsystemdetection.h>
#include <QtCore/qprocessordetection.h>
#include <QtCore/qcompilerdetection.h>
-// This could go to the very beginning of this file, but we're using compiler
-// detection, so it's here.
-#if defined(__cplusplus) && (__cplusplus < 201703L)
-# ifdef Q_CC_MSVC
-# error "Qt requires a C++17 compiler, and a suitable value for __cplusplus. On MSVC, you must pass the /Zc:__cplusplus option to the compiler."
-# else
-# error "Qt requires a C++17 compiler"
-# endif
-#endif // __cplusplus
-
-#if defined (__ELF__)
-# define Q_OF_ELF
-#endif
-#if defined (__MACH__) && defined (__APPLE__)
-# define Q_OF_MACH_O
-#endif
-
-/*
- Avoid "unused parameter" warnings
-*/
-#define Q_UNUSED(x) (void)x;
-
-#if defined(__cplusplus)
-// Don't use these in C++ mode, use static_assert directly.
-// These are here only to keep old code compiling.
-# define Q_STATIC_ASSERT(Condition) static_assert(bool(Condition), #Condition)
-# define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
-#elif defined(Q_COMPILER_STATIC_ASSERT)
-// C11 mode - using the _S version in case <assert.h> doesn't do the right thing
-# define Q_STATIC_ASSERT(Condition) _Static_assert(!!(Condition), #Condition)
-# define Q_STATIC_ASSERT_X(Condition, Message) _Static_assert(!!(Condition), Message)
-#else
-// C89 & C99 version
-# define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B)
-# define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B
-# ifdef __COUNTER__
-# define Q_STATIC_ASSERT(Condition) \
- typedef char Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __COUNTER__) [(Condition) ? 1 : -1];
-# else
-# define Q_STATIC_ASSERT(Condition) \
- typedef char Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) [(Condition) ? 1 : -1];
-# endif /* __COUNTER__ */
-# define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
-#endif
-
-#ifdef __cplusplus
-
-#include <algorithm>
-
-#if !defined(QT_NAMESPACE) || defined(Q_MOC_RUN) /* user namespace */
-
-# define QT_PREPEND_NAMESPACE(name) ::name
-# define QT_USE_NAMESPACE
-# define QT_BEGIN_NAMESPACE
-# define QT_END_NAMESPACE
-# define QT_BEGIN_INCLUDE_NAMESPACE
-# define QT_END_INCLUDE_NAMESPACE
-#ifndef QT_BEGIN_MOC_NAMESPACE
-# define QT_BEGIN_MOC_NAMESPACE
-#endif
-#ifndef QT_END_MOC_NAMESPACE
-# define QT_END_MOC_NAMESPACE
-#endif
-# define QT_FORWARD_DECLARE_CLASS(name) class name;
-# define QT_FORWARD_DECLARE_STRUCT(name) struct name;
-# define QT_MANGLE_NAMESPACE(name) name
-
-#else /* user namespace */
-
-# define QT_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
-# define QT_USE_NAMESPACE using namespace ::QT_NAMESPACE;
-# define QT_BEGIN_NAMESPACE namespace QT_NAMESPACE {
-# define QT_END_NAMESPACE }
-# define QT_BEGIN_INCLUDE_NAMESPACE }
-# define QT_END_INCLUDE_NAMESPACE namespace QT_NAMESPACE {
-#ifndef QT_BEGIN_MOC_NAMESPACE
-# define QT_BEGIN_MOC_NAMESPACE QT_USE_NAMESPACE
-#endif
-#ifndef QT_END_MOC_NAMESPACE
-# define QT_END_MOC_NAMESPACE
-#endif
-# define QT_FORWARD_DECLARE_CLASS(name) \
- QT_BEGIN_NAMESPACE class name; QT_END_NAMESPACE \
- using QT_PREPEND_NAMESPACE(name);
-
-# define QT_FORWARD_DECLARE_STRUCT(name) \
- QT_BEGIN_NAMESPACE struct name; QT_END_NAMESPACE \
- using QT_PREPEND_NAMESPACE(name);
-
-# define QT_MANGLE_NAMESPACE0(x) x
-# define QT_MANGLE_NAMESPACE1(a, b) a##_##b
-# define QT_MANGLE_NAMESPACE2(a, b) QT_MANGLE_NAMESPACE1(a,b)
-# define QT_MANGLE_NAMESPACE(name) QT_MANGLE_NAMESPACE2( \
- QT_MANGLE_NAMESPACE0(name), QT_MANGLE_NAMESPACE0(QT_NAMESPACE))
-
-namespace QT_NAMESPACE {}
-
-# ifndef QT_BOOTSTRAPPED
-# ifndef QT_NO_USING_NAMESPACE
- /*
- This expands to a "using QT_NAMESPACE" also in _header files_.
- It is the only way the feature can be used without too much
- pain, but if people _really_ do not want it they can add
- DEFINES += QT_NO_USING_NAMESPACE to their .pro files.
- */
- QT_USE_NAMESPACE
-# endif
-# endif
-
-#endif /* user namespace */
-
-#else /* __cplusplus */
-
-# define QT_BEGIN_NAMESPACE
-# define QT_END_NAMESPACE
-# define QT_USE_NAMESPACE
-# define QT_BEGIN_INCLUDE_NAMESPACE
-# define QT_END_INCLUDE_NAMESPACE
-
-#endif /* __cplusplus */
-
-#if defined(Q_OS_DARWIN) && !defined(QT_LARGEFILE_SUPPORT)
-# define QT_LARGEFILE_SUPPORT 64
-#endif
-
#ifndef __ASSEMBLER__
-QT_BEGIN_NAMESPACE
-
-/*
- Size-dependent types (architechture-dependent byte order)
-
- Make sure to update QMetaType when changing these typedefs
-*/
-
-typedef signed char qint8; /* 8 bit signed */
-typedef unsigned char quint8; /* 8 bit unsigned */
-typedef short qint16; /* 16 bit signed */
-typedef unsigned short quint16; /* 16 bit unsigned */
-typedef int qint32; /* 32 bit signed */
-typedef unsigned int quint32; /* 32 bit unsigned */
-// Unlike LL / ULL in C++, for historical reasons, we force the
-// result to be of the requested type.
-#ifdef __cplusplus
-# define Q_INT64_C(c) static_cast<long long>(c ## LL) /* signed 64 bit constant */
-# define Q_UINT64_C(c) static_cast<unsigned long long>(c ## ULL) /* unsigned 64 bit constant */
-#else
-# define Q_INT64_C(c) ((long long)(c ## LL)) /* signed 64 bit constant */
-# define Q_UINT64_C(c) ((unsigned long long)(c ## ULL)) /* unsigned 64 bit constant */
-#endif
-typedef long long qint64; /* 64 bit signed */
-typedef unsigned long long quint64; /* 64 bit unsigned */
-
-typedef qint64 qlonglong;
-typedef quint64 qulonglong;
-
-#ifndef __cplusplus
-// In C++ mode, we define below using QIntegerForSize template
-Q_STATIC_ASSERT_X(sizeof(ptrdiff_t) == sizeof(size_t), "Weird ptrdiff_t and size_t definitions");
-typedef ptrdiff_t qptrdiff;
-typedef ptrdiff_t qsizetype;
-typedef ptrdiff_t qintptr;
-typedef size_t quintptr;
-
-#define PRIdQPTRDIFF "td"
-#define PRIiQPTRDIFF "ti"
-
-#define PRIdQSIZETYPE "td"
-#define PRIiQSIZETYPE "ti"
-
-#define PRIdQINTPTR "td"
-#define PRIiQINTPTR "ti"
-
-#define PRIuQUINTPTR "zu"
-#define PRIoQUINTPTR "zo"
-#define PRIxQUINTPTR "zx"
-#define PRIXQUINTPTR "zX"
-#endif
-
-/*
- Useful type definitions for Qt
-*/
-
-QT_BEGIN_INCLUDE_NAMESPACE
-typedef unsigned char uchar;
-typedef unsigned short ushort;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-QT_END_INCLUDE_NAMESPACE
-
-#if defined(QT_COORD_TYPE)
-typedef QT_COORD_TYPE qreal;
-#else
-typedef double qreal;
-#endif
-
-#if defined(QT_NO_DEPRECATED)
-# undef QT_DEPRECATED
-# undef QT_DEPRECATED_X
-# undef QT_DEPRECATED_VARIABLE
-# undef QT_DEPRECATED_CONSTRUCTOR
-#elif !defined(QT_NO_DEPRECATED_WARNINGS)
-# undef QT_DEPRECATED
-# define QT_DEPRECATED Q_DECL_DEPRECATED
-# undef QT_DEPRECATED_X
-# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text)
-# undef QT_DEPRECATED_VARIABLE
-# define QT_DEPRECATED_VARIABLE Q_DECL_VARIABLE_DEPRECATED
-# undef QT_DEPRECATED_CONSTRUCTOR
-# define QT_DEPRECATED_CONSTRUCTOR Q_DECL_CONSTRUCTOR_DEPRECATED explicit
-#else
-# undef QT_DEPRECATED
-# define QT_DEPRECATED
-# undef QT_DEPRECATED_X
-# define QT_DEPRECATED_X(text)
-# undef QT_DEPRECATED_VARIABLE
-# define QT_DEPRECATED_VARIABLE
-# undef QT_DEPRECATED_CONSTRUCTOR
-# define QT_DEPRECATED_CONSTRUCTOR
-# undef Q_DECL_ENUMERATOR_DEPRECATED
-# define Q_DECL_ENUMERATOR_DEPRECATED
-#endif
-
-#ifndef QT_DEPRECATED_WARNINGS_SINCE
-# ifdef QT_DISABLE_DEPRECATED_BEFORE
-# define QT_DEPRECATED_WARNINGS_SINCE QT_DISABLE_DEPRECATED_BEFORE
-# else
-# define QT_DEPRECATED_WARNINGS_SINCE QT_VERSION
-# endif
-#endif
-
-#ifndef QT_DISABLE_DEPRECATED_BEFORE
-#define QT_DISABLE_DEPRECATED_BEFORE QT_VERSION_CHECK(5, 0, 0)
-#endif
-
-/*
- QT_DEPRECATED_SINCE(major, minor) evaluates as true if the Qt version is greater than
- the deprecation point specified.
-
- Use it to specify from which version of Qt a function or class has been deprecated
-
- Example:
- #if QT_DEPRECATED_SINCE(5,1)
- QT_DEPRECATED void deprecatedFunction(); //function deprecated since Qt 5.1
- #endif
-
-*/
-#ifdef QT_DEPRECATED
-#define QT_DEPRECATED_SINCE(major, minor) (QT_VERSION_CHECK(major, minor, 0) > QT_DISABLE_DEPRECATED_BEFORE)
-#else
-#define QT_DEPRECATED_SINCE(major, minor) 0
-#endif
-
-/*
- QT_DEPRECATED_VERSION(major, minor) and QT_DEPRECATED_VERSION_X(major, minor, text)
- outputs a deprecation warning if QT_DEPRECATED_WARNINGS_SINCE is equal or greater
- than the version specified as major, minor. This makes it possible to deprecate a
- function without annoying a user who needs to stick at a specified minimum version
- and therefore can't use the new function.
-*/
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(5, 12, 0)
-# define QT_DEPRECATED_VERSION_X_5_12(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_5_12 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_5_12(text)
-# define QT_DEPRECATED_VERSION_5_12
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(5, 13, 0)
-# define QT_DEPRECATED_VERSION_X_5_13(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_5_13 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_5_13(text)
-# define QT_DEPRECATED_VERSION_5_13
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(5, 14, 0)
-# define QT_DEPRECATED_VERSION_X_5_14(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_5_14 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_5_14(text)
-# define QT_DEPRECATED_VERSION_5_14
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(5, 15, 0)
-# define QT_DEPRECATED_VERSION_X_5_15(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_5_15 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_5_15(text)
-# define QT_DEPRECATED_VERSION_5_15
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(6, 0, 0)
-# define QT_DEPRECATED_VERSION_X_6_0(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_6_0 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_6_0(text)
-# define QT_DEPRECATED_VERSION_6_0
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(6, 1, 0)
-# define QT_DEPRECATED_VERSION_X_6_1(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_6_1 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_6_1(text)
-# define QT_DEPRECATED_VERSION_6_1
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(6, 2, 0)
-# define QT_DEPRECATED_VERSION_X_6_2(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_6_2 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_6_2(text)
-# define QT_DEPRECATED_VERSION_6_2
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(6, 3, 0)
-# define QT_DEPRECATED_VERSION_X_6_3(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_6_3 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_6_3(text)
-# define QT_DEPRECATED_VERSION_6_3
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(6, 4, 0)
-# define QT_DEPRECATED_VERSION_X_6_4(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_6_4 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_6_4(text)
-# define QT_DEPRECATED_VERSION_6_4
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(6, 5, 0)
-# define QT_DEPRECATED_VERSION_X_6_5(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_6_5 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_6_5(text)
-# define QT_DEPRECATED_VERSION_6_5
-#endif
-
-#if QT_DEPRECATED_WARNINGS_SINCE >= QT_VERSION_CHECK(6, 6, 0)
-# define QT_DEPRECATED_VERSION_X_6_6(text) QT_DEPRECATED_X(text)
-# define QT_DEPRECATED_VERSION_6_6 QT_DEPRECATED
-#else
-# define QT_DEPRECATED_VERSION_X_6_6(text)
-# define QT_DEPRECATED_VERSION_6_6
-#endif
-
-#define QT_DEPRECATED_VERSION_X_5(minor, text) QT_DEPRECATED_VERSION_X_5_##minor(text)
-#define QT_DEPRECATED_VERSION_X(major, minor, text) QT_DEPRECATED_VERSION_X_##major##_##minor(text)
-
-#define QT_DEPRECATED_VERSION_5(minor) QT_DEPRECATED_VERSION_5_##minor
-#define QT_DEPRECATED_VERSION(major, minor) QT_DEPRECATED_VERSION_##major##_##minor
-
-/*
- QT_REMOVED_SINCE(major, minor) evaluates as true if the Qt version is greater than
- the deprecation point specified \e and QT_BUILD_REMOVED_API is defined.
-
- Use it to remove functions from the API, but not the ABI, by moving their definitions
- into the module's \c{removed_api/} subdir and defining QT_BUILD_REMOVED_API.
-
- Example:
-
- // header
- #if QT_REMOVED_SINCE(6, 3)
- void removedFunction(); // function removed since Qt 6.3
- #endif
-
- // implementation
- // ... moved from here ...
-
- // removed_api/some.cpp
- #define QT_BUILD_REMOVED_API
- #include <qglobal.h>
-
- #include <someheader.h>
-
- #if QT_REMOVED_SINCE(6, 3)
- void removedFunction() { newFunction(); }
- #endif
-
- The function is now removed from the API, but remains in the ABI until
- the deprecation point moves past 6.3.
-*/
-#ifdef QT_BUILD_REMOVED_API
-#define QT_REMOVED_SINCE(major, minor) QT_DEPRECATED_SINCE(major, minor)
-#else
-#define QT_REMOVED_SINCE(major, minor) 0
-#endif
-
-#ifdef __cplusplus
-// A tag to help mark stuff deprecated (cf. QStringViewLiteral)
-namespace QtPrivate {
-enum class Deprecated_t {};
-constexpr inline Deprecated_t Deprecated = {};
-}
-#endif
-
-/*
- The Qt modules' export macros.
- The options are:
- - defined(QT_STATIC): Qt was built or is being built in static mode
- - defined(QT_SHARED): Qt was built or is being built in shared/dynamic mode
- If neither was defined, then QT_SHARED is implied. If Qt was compiled in static
- mode, QT_STATIC is defined in qconfig.h. In shared mode, QT_STATIC is implied
- for the bootstrapped tools.
-*/
-
-#ifdef QT_BOOTSTRAPPED
-# ifdef QT_SHARED
-# error "QT_SHARED and QT_BOOTSTRAPPED together don't make sense. Please fix the build"
-# elif !defined(QT_STATIC)
-# define QT_STATIC
-# endif
-#endif
-
-#if defined(QT_SHARED) || !defined(QT_STATIC)
-# ifdef QT_STATIC
-# error "Both QT_SHARED and QT_STATIC defined, please make up your mind"
-# endif
-# ifndef QT_SHARED
-# define QT_SHARED
-# endif
-# if defined(QT_BUILD_CORE_LIB)
-# define Q_CORE_EXPORT Q_DECL_EXPORT
-# else
-# define Q_CORE_EXPORT Q_DECL_IMPORT
-# endif
-#else
-# define Q_CORE_EXPORT
-#endif
-
-/*
- Some classes do not permit copies to be made of an object. These
- classes contains a private copy constructor and assignment
- operator to disable copying (the compiler gives an error message).
-*/
-#define Q_DISABLE_COPY(Class) \
- Class(const Class &) = delete;\
- Class &operator=(const Class &) = delete;
-
-#define Q_DISABLE_COPY_MOVE(Class) \
- Q_DISABLE_COPY(Class) \
- Class(Class &&) = delete; \
- Class &operator=(Class &&) = delete;
-
-/*
- Implementing a move assignment operator using an established
- technique (move-and-swap, pure swap) is just boilerplate.
- Here's a couple of *private* macros for convenience.
-
- To know which one to use:
-
- * if you don't have a move constructor (*) => use pure swap;
- * if you have a move constructor, then
- * if your class holds just memory (no file handles, no user-defined
- datatypes, etc.) => use pure swap;
- * use move and swap.
-
- The preference should always go for the move-and-swap one, as it
- will deterministically destroy the data previously held in *this,
- and not "dump" it in the moved-from object (which may then be alive
- for longer).
-
- The requirement for either macro is the presence of a member swap(),
- which any value class that defines its own special member functions
- should have anyhow.
-
- (*) Many value classes in Qt do not have move constructors; mostly,
- the implicitly shared classes using QSharedDataPointer and friends.
- The reason is mostly historical: those classes require either an
- out-of-line move constructor, which we could not provide before we
- made C++11 mandatory (and that we don't like anyhow), or
- an out-of-line dtor for the Q(E)DSP<Private> member (cf. QPixmap).
-
- If you can however add a move constructor to a class lacking it,
- consider doing so, then reevaluate which macro to choose.
-*/
-#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(Class) \
- Class &operator=(Class &&other) noexcept { \
- Class moved(std::move(other)); \
- swap(moved); \
- return *this; \
- }
-
-#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Class) \
- Class &operator=(Class &&other) noexcept { \
- swap(other); \
- return *this; \
- }
-
-/*
- No, this is not an evil backdoor. QT_BUILD_INTERNAL just exports more symbols
- for Qt's internal unit tests. If you want slower loading times and more
- symbols that can vanish from version to version, feel free to define QT_BUILD_INTERNAL.
-*/
-#if defined(QT_BUILD_INTERNAL) && defined(QT_BUILDING_QT) && defined(QT_SHARED)
-# define Q_AUTOTEST_EXPORT Q_DECL_EXPORT
-#elif defined(QT_BUILD_INTERNAL) && defined(QT_SHARED)
-# define Q_AUTOTEST_EXPORT Q_DECL_IMPORT
-#else
-# define Q_AUTOTEST_EXPORT
-#endif
-
-#define Q_INIT_RESOURCE(name) \
- do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \
- QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (false)
-#define Q_CLEANUP_RESOURCE(name) \
- do { extern int QT_MANGLE_NAMESPACE(qCleanupResources_ ## name) (); \
- QT_MANGLE_NAMESPACE(qCleanupResources_ ## name) (); } while (false)
-
-/*
- * If we're compiling C++ code:
- * - and this is a non-namespace build, declare qVersion as extern "C"
- * - and this is a namespace build, declare it as a regular function
- * (we're already inside QT_BEGIN_NAMESPACE / QT_END_NAMESPACE)
- * If we're compiling C code, simply declare the function. If Qt was compiled
- * in a namespace, qVersion isn't callable anyway.
- */
-#if !defined(QT_NAMESPACE) && defined(__cplusplus) && !defined(Q_QDOC)
-extern "C"
-#endif
-Q_CORE_EXPORT Q_DECL_CONST_FUNCTION const char *qVersion(void) Q_DECL_NOEXCEPT;
+# include <QtCore/qassert.h>
+# include <QtCore/qtnoop.h>
+# include <QtCore/qtypes.h>
+#endif /* !__ASSEMBLER__ */
+#include <QtCore/qtversion.h>
#if defined(__cplusplus)
-#ifndef Q_CONSTRUCTOR_FUNCTION
-# define Q_CONSTRUCTOR_FUNCTION0(AFUNC) \
- namespace { \
- static const struct AFUNC ## _ctor_class_ { \
- inline AFUNC ## _ctor_class_() { AFUNC(); } \
- } AFUNC ## _ctor_instance_; \
- }
-
-# define Q_CONSTRUCTOR_FUNCTION(AFUNC) Q_CONSTRUCTOR_FUNCTION0(AFUNC)
-#endif
-
-#ifndef Q_DESTRUCTOR_FUNCTION
-# define Q_DESTRUCTOR_FUNCTION0(AFUNC) \
- namespace { \
- static const struct AFUNC ## _dtor_class_ { \
- inline AFUNC ## _dtor_class_() { } \
- inline ~ AFUNC ## _dtor_class_() { AFUNC(); } \
- } AFUNC ## _dtor_instance_; \
- }
-# define Q_DESTRUCTOR_FUNCTION(AFUNC) Q_DESTRUCTOR_FUNCTION0(AFUNC)
-#endif
-
-/*
- quintptr and qptrdiff is guaranteed to be the same size as a pointer, i.e.
-
- sizeof(void *) == sizeof(quintptr)
- && sizeof(void *) == sizeof(qptrdiff)
-
- size_t and qsizetype are not guaranteed to be the same size as a pointer, but
- they usually are. We actually check for that in qglobal.cpp.
-*/
-template <int> struct QIntegerForSize;
-template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qint8 Signed; };
-template <> struct QIntegerForSize<2> { typedef quint16 Unsigned; typedef qint16 Signed; };
-template <> struct QIntegerForSize<4> { typedef quint32 Unsigned; typedef qint32 Signed; };
-template <> struct QIntegerForSize<8> { typedef quint64 Unsigned; typedef qint64 Signed; };
-#if defined(Q_CC_GNU) && defined(__SIZEOF_INT128__)
-template <> struct QIntegerForSize<16> { __extension__ typedef unsigned __int128 Unsigned; __extension__ typedef __int128 Signed; };
-#endif
-template <class T> struct QIntegerForSizeof: QIntegerForSize<sizeof(T)> { };
-typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Signed qregisterint;
-typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Unsigned qregisteruint;
-typedef QIntegerForSizeof<void *>::Unsigned quintptr;
-typedef QIntegerForSizeof<void *>::Signed qptrdiff;
-typedef qptrdiff qintptr;
-using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
-
-// These custom definitions are necessary as we're not defining our
-// datatypes in terms of the language ones, but in terms of integer
-// types that have the sime size. For instance, on a 32-bit platform,
-// qptrdiff is int, while ptrdiff_t may be aliased to long; therefore
-// using %td to print a qptrdiff would be wrong (and raise -Wformat
-// warnings), although both int and long have same bit size on that
-// platform.
-//
-// We know that sizeof(size_t) == sizeof(void *) == sizeof(qptrdiff).
-#if SIZE_MAX == 4294967295ULL
-#define PRIuQUINTPTR "u"
-#define PRIoQUINTPTR "o"
-#define PRIxQUINTPTR "x"
-#define PRIXQUINTPTR "X"
-
-#define PRIdQPTRDIFF "d"
-#define PRIiQPTRDIFF "i"
-
-#define PRIdQINTPTR "d"
-#define PRIiQINTPTR "i"
-
-#define PRIdQSIZETYPE "d"
-#define PRIiQSIZETYPE "i"
-#elif SIZE_MAX == 18446744073709551615ULL
-#define PRIuQUINTPTR "llu"
-#define PRIoQUINTPTR "llo"
-#define PRIxQUINTPTR "llx"
-#define PRIXQUINTPTR "llX"
-
-#define PRIdQPTRDIFF "lld"
-#define PRIiQPTRDIFF "lli"
-
-#define PRIdQINTPTR "lld"
-#define PRIiQINTPTR "lli"
-
-#define PRIdQSIZETYPE "lld"
-#define PRIiQSIZETYPE "lli"
-#else
-#error Unsupported platform (unknown value for SIZE_MAX)
-#endif
-
-/* moc compats (signals/slots) */
-#ifndef QT_MOC_COMPAT
-# define QT_MOC_COMPAT
-#else
-# undef QT_MOC_COMPAT
-# define QT_MOC_COMPAT
-#endif
-
-#ifdef QT_ASCII_CAST_WARNINGS
-# define QT_ASCII_CAST_WARN Q_DECL_DEPRECATED_X("Use fromUtf8, QStringLiteral, or QLatin1String")
-#else
-# define QT_ASCII_CAST_WARN
-#endif
-
-#ifdef Q_PROCESSOR_X86_32
-# if defined(Q_CC_GNU)
-# define QT_FASTCALL __attribute__((regparm(3)))
-# elif defined(Q_CC_MSVC)
-# define QT_FASTCALL __fastcall
-# else
-# define QT_FASTCALL
-# endif
-#else
-# define QT_FASTCALL
-#endif
-
-// enable gcc warnings for printf-style functions
-#if defined(Q_CC_GNU) && !defined(__INSURE__)
-# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
-# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B) \
- __attribute__((format(gnu_printf, (A), (B))))
-# else
-# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B) \
- __attribute__((format(printf, (A), (B))))
-# endif
-#else
-# define Q_ATTRIBUTE_FORMAT_PRINTF(A, B)
-#endif
-
-#ifdef Q_CC_MSVC
-# define Q_NEVER_INLINE __declspec(noinline)
-# define Q_ALWAYS_INLINE __forceinline
-#elif defined(Q_CC_GNU)
-# define Q_NEVER_INLINE __attribute__((noinline))
-# define Q_ALWAYS_INLINE inline __attribute__((always_inline))
-#else
-# define Q_NEVER_INLINE
-# define Q_ALWAYS_INLINE inline
-#endif
-
-//defines the type for the WNDPROC on windows
-//the alignment needs to be forced for sse2 to not crash with mingw
-#if defined(Q_OS_WIN)
-# if defined(Q_CC_MINGW) && defined(Q_PROCESSOR_X86_32)
-# define QT_ENSURE_STACK_ALIGNED_FOR_SSE __attribute__ ((force_align_arg_pointer))
-# else
-# define QT_ENSURE_STACK_ALIGNED_FOR_SSE
-# endif
-# define QT_WIN_CALLBACK CALLBACK QT_ENSURE_STACK_ALIGNED_FOR_SSE
-#endif
-
-/*
- Utility macros and inline functions
-*/
-
-template <typename T>
-constexpr inline T qAbs(const T &t) { return t >= 0 ? t : -t; }
-
-// gcc < 10 doesn't have __has_builtin
-#if defined(Q_PROCESSOR_ARM_64) && (__has_builtin(__builtin_round) || defined(Q_CC_GNU)) && !defined(Q_CC_CLANG)
-// ARM64 has a single instruction that can do C++ rounding with conversion to integer.
-// Note current clang versions have non-constexpr __builtin_round, ### allow clang this path when they fix it.
-constexpr inline int qRound(double d)
-{ return int(__builtin_round(d)); }
-constexpr inline int qRound(float f)
-{ return int(__builtin_roundf(f)); }
-constexpr inline qint64 qRound64(double d)
-{ return qint64(__builtin_round(d)); }
-constexpr inline qint64 qRound64(float f)
-{ return qint64(__builtin_roundf(f)); }
-#elif defined(__SSE2__) && (__has_builtin(__builtin_copysign) || defined(Q_CC_GNU))
-// SSE has binary operations directly on floating point making copysign fast
-constexpr inline int qRound(double d)
-{ return int(d + __builtin_copysign(0.5, d)); }
-constexpr inline int qRound(float f)
-{ return int(f + __builtin_copysignf(0.5f, f)); }
-constexpr inline qint64 qRound64(double d)
-{ return qint64(d + __builtin_copysign(0.5, d)); }
-constexpr inline qint64 qRound64(float f)
-{ return qint64(f + __builtin_copysignf(0.5f, f)); }
-#else
-constexpr inline int qRound(double d)
-{ return d >= 0.0 ? int(d + 0.5) : int(d - 0.5); }
-constexpr inline int qRound(float d)
-{ return d >= 0.0f ? int(d + 0.5f) : int(d - 0.5f); }
-
-constexpr inline qint64 qRound64(double d)
-{ return d >= 0.0 ? qint64(d + 0.5) : qint64(d - 0.5); }
-constexpr inline qint64 qRound64(float d)
-{ return d >= 0.0f ? qint64(d + 0.5f) : qint64(d - 0.5f); }
-#endif
-
-namespace QTypeTraits {
-
-namespace detail {
-template<typename T, typename U,
- typename = std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U> &&
- std::is_floating_point_v<T> == std::is_floating_point_v<U> &&
- std::is_signed_v<T> == std::is_signed_v<U> &&
- !std::is_same_v<T, bool> && !std::is_same_v<U, bool> &&
- !std::is_same_v<T, char> && !std::is_same_v<U, char>>>
-struct Promoted
-{
- using type = decltype(T() + U());
-};
-}
-
-template <typename T, typename U>
-using Promoted = typename detail::Promoted<T, U>::type;
-
-}
-
-template <typename T>
-constexpr inline const T &qMin(const T &a, const T &b) { return (a < b) ? a : b; }
-template <typename T>
-constexpr inline const T &qMax(const T &a, const T &b) { return (a < b) ? b : a; }
-template <typename T>
-constexpr inline const T &qBound(const T &min, const T &val, const T &max)
-{ return qMax(min, qMin(max, val)); }
-template <typename T, typename U>
-constexpr inline QTypeTraits::Promoted<T, U> qMin(const T &a, const U &b)
-{
- using P = QTypeTraits::Promoted<T, U>;
- P _a = a;
- P _b = b;
- return (_a < _b) ? _a : _b;
-}
-template <typename T, typename U>
-constexpr inline QTypeTraits::Promoted<T, U> qMax(const T &a, const U &b)
-{
- using P = QTypeTraits::Promoted<T, U>;
- P _a = a;
- P _b = b;
- return (_a < _b) ? _b : _a;
-}
-template <typename T, typename U>
-constexpr inline QTypeTraits::Promoted<T, U> qBound(const T &min, const U &val, const T &max)
-{ return qMax(min, qMin(max, val)); }
-template <typename T, typename U>
-constexpr inline QTypeTraits::Promoted<T, U> qBound(const T &min, const T &val, const U &max)
-{ return qMax(min, qMin(max, val)); }
-template <typename T, typename U>
-constexpr inline QTypeTraits::Promoted<T, U> qBound(const U &min, const T &val, const T &max)
-{ return qMax(min, qMin(max, val)); }
-
-#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
-# ifdef __OBJC__
-# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
-# else
-# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
-# endif
-#endif
-#ifndef Q_FORWARD_DECLARE_CF_TYPE
-# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
-#endif
-#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE
-# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
-#endif
-#ifndef Q_FORWARD_DECLARE_CG_TYPE
-#define Q_FORWARD_DECLARE_CG_TYPE(type) typedef const struct type *type ## Ref;
-#endif
-#ifndef Q_FORWARD_DECLARE_MUTABLE_CG_TYPE
-#define Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(type) typedef struct type *type ## Ref;
-#endif
-
-#ifdef Q_OS_DARWIN
-# define QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, tvos, watchos) \
- ((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && macos != __MAC_NA && __MAC_OS_X_VERSION_MAX_ALLOWED >= macos) || \
- (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios) || \
- (defined(__TV_OS_VERSION_MAX_ALLOWED) && tvos != __TVOS_NA && __TV_OS_VERSION_MAX_ALLOWED >= tvos) || \
- (defined(__WATCH_OS_VERSION_MAX_ALLOWED) && watchos != __WATCHOS_NA && __WATCH_OS_VERSION_MAX_ALLOWED >= watchos))
-
-# define QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, ios, tvos, watchos) \
- ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && macos != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < macos) || \
- (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MIN_REQUIRED < ios) || \
- (defined(__TV_OS_VERSION_MIN_REQUIRED) && tvos != __TVOS_NA && __TV_OS_VERSION_MIN_REQUIRED < tvos) || \
- (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && watchos != __WATCHOS_NA && __WATCH_OS_VERSION_MIN_REQUIRED < watchos))
-
-# define QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios) \
- QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, __TVOS_NA, __WATCHOS_NA)
-# define QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos) \
- QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, __IPHONE_NA, __TVOS_NA, __WATCHOS_NA)
-# define QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(ios) \
- QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, ios, __TVOS_NA, __WATCHOS_NA)
-# define QT_TVOS_PLATFORM_SDK_EQUAL_OR_ABOVE(tvos) \
- QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_NA, tvos, __WATCHOS_NA)
-# define QT_WATCHOS_PLATFORM_SDK_EQUAL_OR_ABOVE(watchos) \
- QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_NA, __TVOS_NA, watchos)
-
-# define QT_MACOS_IOS_DEPLOYMENT_TARGET_BELOW(macos, ios) \
- QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, ios, __TVOS_NA, __WATCHOS_NA)
-# define QT_MACOS_DEPLOYMENT_TARGET_BELOW(macos) \
- QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, __IPHONE_NA, __TVOS_NA, __WATCHOS_NA)
-# define QT_IOS_DEPLOYMENT_TARGET_BELOW(ios) \
- QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, ios, __TVOS_NA, __WATCHOS_NA)
-# define QT_TVOS_DEPLOYMENT_TARGET_BELOW(tvos) \
- QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, __IPHONE_NA, tvos, __WATCHOS_NA)
-# define QT_WATCHOS_DEPLOYMENT_TARGET_BELOW(watchos) \
- QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, __IPHONE_NA, __TVOS_NA, watchos)
-
-// Compatibility synonyms, do not use
-# define QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios)
-# define QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, ios) QT_MACOS_IOS_DEPLOYMENT_TARGET_BELOW(osx, ios)
-# define QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(osx) QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(osx)
-# define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) QT_MACOS_DEPLOYMENT_TARGET_BELOW(osx)
-
-// Implemented in qcore_mac_objc.mm
-class Q_CORE_EXPORT QMacAutoReleasePool
-{
-public:
- QMacAutoReleasePool();
- ~QMacAutoReleasePool();
-private:
- Q_DISABLE_COPY(QMacAutoReleasePool)
- void *pool;
-};
-
-#else
-
-#define QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, tvos, watchos) (0)
-#define QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios) (0)
-#define QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos) (0)
-#define QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(ios) (0)
-#define QT_TVOS_PLATFORM_SDK_EQUAL_OR_ABOVE(tvos) (0)
-#define QT_WATCHOS_PLATFORM_SDK_EQUAL_OR_ABOVE(watchos) (0)
-
-#define QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) (0)
-#define QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(osx) (0)
-
-#endif // Q_OS_DARWIN
-
-/*
- Data stream functions are provided by many classes (defined in qdatastream.h)
-*/
-
-class QDataStream;
-
-inline void qt_noop(void) {}
-
-/* These wrap try/catch so we can switch off exceptions later.
-
- Beware - do not use more than one QT_CATCH per QT_TRY, and do not use
- the exception instance in the catch block.
- If you can't live with those constraints, don't use these macros.
- Use the QT_NO_EXCEPTIONS macro to protect your code instead.
-*/
-
-#if !defined(QT_NO_EXCEPTIONS)
-# if !defined(Q_MOC_RUN)
-# if (defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !__has_feature(cxx_exceptions)) || \
- (defined(Q_CC_GNU) && !defined(__EXCEPTIONS))
-# define QT_NO_EXCEPTIONS
-# endif
-# elif defined(QT_BOOTSTRAPPED)
-# define QT_NO_EXCEPTIONS
-# endif
-#endif
-
-Q_NORETURN Q_DECL_COLD_FUNCTION Q_CORE_EXPORT void qTerminate() noexcept;
-#ifdef QT_NO_EXCEPTIONS
-# define QT_TRY if (true)
-# define QT_CATCH(A) else
-# define QT_THROW(A) qt_noop()
-# define QT_RETHROW qt_noop()
-# define QT_TERMINATE_ON_EXCEPTION(expr) do { expr; } while (false)
-#else
-# define QT_TRY try
-# define QT_CATCH(A) catch (A)
-# define QT_THROW(A) throw A
-# define QT_RETHROW throw
-# ifdef Q_COMPILER_NOEXCEPT
-# define QT_TERMINATE_ON_EXCEPTION(expr) do { expr; } while (false)
-# else
-# define QT_TERMINATE_ON_EXCEPTION(expr) do { try { expr; } catch (...) { qTerminate(); } } while (false)
-# endif
-#endif
-
-Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qSharedBuild() noexcept;
-
-#ifndef Q_OUTOFLINE_TEMPLATE
-# define Q_OUTOFLINE_TEMPLATE
-#endif
-#ifndef Q_INLINE_TEMPLATE
-# define Q_INLINE_TEMPLATE inline
-#endif
-
-/*
- Debugging and error handling
-*/
-
-#if !defined(QT_NO_DEBUG) && !defined(QT_DEBUG)
-# define QT_DEBUG
-#endif
-
-// QtPrivate::asString defined in qstring.h
-#ifndef qPrintable
-# define qPrintable(string) QtPrivate::asString(string).toLocal8Bit().constData()
-#endif
-
-#ifndef qUtf8Printable
-# define qUtf8Printable(string) QtPrivate::asString(string).toUtf8().constData()
-#endif
-
-/*
- Wrap QString::utf16() with enough casts to allow passing it
- to QString::asprintf("%ls") without warnings.
-*/
-#ifndef qUtf16Printable
-# define qUtf16Printable(string) \
- static_cast<const wchar_t*>(static_cast<const void*>(QString(string).utf16()))
-#endif
-
-class QString;
-Q_DECL_COLD_FUNCTION
-Q_CORE_EXPORT QString qt_error_string(int errorCode = -1);
-
-#ifndef Q_CC_MSVC
-Q_NORETURN
-#endif
-Q_DECL_COLD_FUNCTION
-Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line) noexcept;
-
-#if !defined(Q_ASSERT)
-# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
-# define Q_ASSERT(cond) static_cast<void>(false && (cond))
-# else
-# define Q_ASSERT(cond) ((cond) ? static_cast<void>(0) : qt_assert(#cond, __FILE__, __LINE__))
-# endif
-#endif
-
-#ifndef Q_CC_MSVC
-Q_NORETURN
-#endif
-Q_DECL_COLD_FUNCTION
-Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char *file, int line) noexcept;
-
-#if !defined(Q_ASSERT_X)
-# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
-# define Q_ASSERT_X(cond, where, what) static_cast<void>(false && (cond))
-# else
-# define Q_ASSERT_X(cond, where, what) ((cond) ? static_cast<void>(0) : qt_assert_x(where, what, __FILE__, __LINE__))
-# endif
-#endif
-
-Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) noexcept;
-Q_NORETURN Q_DECL_COLD_FUNCTION
-Q_CORE_EXPORT void qBadAlloc();
-
-#ifdef QT_NO_EXCEPTIONS
-# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
-# define Q_CHECK_PTR(p) qt_noop()
-# else
-# define Q_CHECK_PTR(p) do {if (!(p)) qt_check_pointer(__FILE__,__LINE__);} while (false)
-# endif
-#else
-# define Q_CHECK_PTR(p) do { if (!(p)) qBadAlloc(); } while (false)
-#endif
-
-template <typename T>
-inline T *q_check_ptr(T *p) { Q_CHECK_PTR(p); return p; }
-
-typedef void (*QFunctionPointer)();
-
-#if !defined(Q_UNIMPLEMENTED)
-# define Q_UNIMPLEMENTED() qWarning("Unimplemented code.")
-#endif
-
-[[nodiscard]] constexpr bool qFuzzyCompare(double p1, double p2)
-{
- return (qAbs(p1 - p2) * 1000000000000. <= qMin(qAbs(p1), qAbs(p2)));
-}
-
-[[nodiscard]] constexpr bool qFuzzyCompare(float p1, float p2)
-{
- return (qAbs(p1 - p2) * 100000.f <= qMin(qAbs(p1), qAbs(p2)));
-}
-
-[[nodiscard]] constexpr bool qFuzzyIsNull(double d)
-{
- return qAbs(d) <= 0.000000000001;
-}
-
-[[nodiscard]] constexpr bool qFuzzyIsNull(float f)
-{
- return qAbs(f) <= 0.00001f;
-}
-
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_FLOAT_COMPARE
-
-[[nodiscard]] constexpr bool qIsNull(double d) noexcept
-{
- return d == 0.0;
-}
-
-[[nodiscard]] constexpr bool qIsNull(float f) noexcept
-{
- return f == 0.0f;
-}
-
-QT_WARNING_POP
-
-/*
- Compilers which follow outdated template instantiation rules
- require a class to have a comparison operator to exist when
- a QList of this type is instantiated. It's not actually
- used in the list, though. Hence the dummy implementation.
- Just in case other code relies on it we better trigger a warning
- mandating a real implementation.
-*/
-
-#ifdef Q_FULL_TEMPLATE_INSTANTIATION
-# define Q_DUMMY_COMPARISON_OPERATOR(C) \
- bool operator==(const C&) const { \
- qWarning(#C"::operator==(const "#C"&) was called"); \
- return false; \
- }
-#else
-
-# define Q_DUMMY_COMPARISON_OPERATOR(C)
-#endif
-
-QT_WARNING_PUSH
-// warning: noexcept-expression evaluates to 'false' because of a call to 'void swap(..., ...)'
-QT_WARNING_DISABLE_GCC("-Wnoexcept")
-
-namespace QtPrivate
-{
-namespace SwapExceptionTester { // insulate users from the "using std::swap" below
- using std::swap; // import std::swap
- template <typename T>
- void checkSwap(T &t)
- noexcept(noexcept(swap(t, t)));
- // declared, but not implemented (only to be used in unevaluated contexts (noexcept operator))
-}
-} // namespace QtPrivate
-
-// Documented in ../tools/qalgorithm.qdoc
-template <typename T>
-constexpr void qSwap(T &value1, T &value2)
- noexcept(noexcept(QtPrivate::SwapExceptionTester::checkSwap(value1)))
-{
- using std::swap;
- swap(value1, value2);
-}
-
-QT_WARNING_POP
-
-Q_CORE_EXPORT void *qMallocAligned(size_t size, size_t alignment) Q_ALLOC_SIZE(1);
-Q_CORE_EXPORT void *qReallocAligned(void *ptr, size_t size, size_t oldsize, size_t alignment) Q_ALLOC_SIZE(2);
-Q_CORE_EXPORT void qFreeAligned(void *ptr);
-
-
-/*
- Avoid some particularly useless warnings from some stupid compilers.
- To get ALL C++ compiler warnings, define QT_CC_WARNINGS or comment out
- the line "#define QT_NO_WARNINGS".
-*/
-#if !defined(QT_CC_WARNINGS)
-# define QT_NO_WARNINGS
-#endif
-#if defined(QT_NO_WARNINGS)
-# if defined(Q_CC_MSVC)
-QT_WARNING_DISABLE_MSVC(4251) /* class 'type' needs to have dll-interface to be used by clients of class 'type2' */
-QT_WARNING_DISABLE_MSVC(4244) /* conversion from 'type1' to 'type2', possible loss of data */
-QT_WARNING_DISABLE_MSVC(4275) /* non - DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier' */
-QT_WARNING_DISABLE_MSVC(4514) /* unreferenced inline function has been removed */
-QT_WARNING_DISABLE_MSVC(4800) /* 'type' : forcing value to bool 'true' or 'false' (performance warning) */
-QT_WARNING_DISABLE_MSVC(4097) /* typedef-name 'identifier1' used as synonym for class-name 'identifier2' */
-QT_WARNING_DISABLE_MSVC(4706) /* assignment within conditional expression */
-QT_WARNING_DISABLE_MSVC(4355) /* 'this' : used in base member initializer list */
-QT_WARNING_DISABLE_MSVC(4710) /* function not inlined */
-QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc */
-# elif defined(Q_CC_BOR)
-# pragma option -w-inl
-# pragma option -w-aus
-# pragma warn -inl
-# pragma warn -pia
-# pragma warn -ccc
-# pragma warn -rch
-# pragma warn -sig
-# endif
-#endif
-
-// this adds const to non-const objects (like std::as_const)
-template <typename T>
-constexpr typename std::add_const<T>::type &qAsConst(T &t) noexcept { return t; }
-// prevent rvalue arguments:
-template <typename T>
-void qAsConst(const T &&) = delete;
-
-// like std::exchange
-template <typename T, typename U = T>
-constexpr T qExchange(T &t, U &&newValue)
-{
- T old = std::move(t);
- t = std::forward<U>(newValue);
- return old;
-}
-
-// like std::to_underlying
-template <typename Enum>
-constexpr std::underlying_type_t<Enum> qToUnderlying(Enum e) noexcept
-{
- return static_cast<std::underlying_type_t<Enum>>(e);
-}
-
-#ifdef __cpp_conditional_explicit
-#define Q_IMPLICIT explicit(false)
-#else
-#define Q_IMPLICIT
-#endif
-
-#ifndef QT_NO_FOREACH
-
-namespace QtPrivate {
-
-template <typename T>
-class QForeachContainer {
- Q_DISABLE_COPY(QForeachContainer)
-public:
- QForeachContainer(const T &t) : c(t), i(qAsConst(c).begin()), e(qAsConst(c).end()) {}
- QForeachContainer(T &&t) : c(std::move(t)), i(qAsConst(c).begin()), e(qAsConst(c).end()) {}
-
- QForeachContainer(QForeachContainer &&other)
- : c(std::move(other.c)),
- i(qAsConst(c).begin()),
- e(qAsConst(c).end()),
- control(std::move(other.control))
- {
- }
-
- QForeachContainer &operator=(QForeachContainer &&other)
- {
- c = std::move(other.c);
- i = qAsConst(c).begin();
- e = qAsConst(c).end();
- control = std::move(other.control);
- return *this;
- }
-
- T c;
- typename T::const_iterator i, e;
- int control = 1;
-};
-
-// Containers that have a detach function are considered shared, and are OK in a foreach loop
-template <typename T, typename = decltype(std::declval<T>().detach())>
-inline void warnIfContainerIsNotShared(int) {}
-
-#if QT_DEPRECATED_SINCE(6, 0)
-// Other containers will copy themselves if used in foreach, this use is deprecated
-template <typename T>
-QT_DEPRECATED_VERSION_X_6_0("Do not use foreach/Q_FOREACH with containers which are not implicitly shared. "
- "Prefer using a range-based for loop with these containers: `for (const auto &it : container)`, "
- "keeping in mind that range-based for doesn't copy the container as Q_FOREACH does")
-inline void warnIfContainerIsNotShared(...) {}
-#endif
-
-template<typename T>
-QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t)
-{
- warnIfContainerIsNotShared<typename std::decay<T>::type>(0);
- return QForeachContainer<typename std::decay<T>::type>(std::forward<T>(t));
-}
-
-}
-
-// Use C++17 if statement with initializer. User's code ends up in a else so
-// scoping of different ifs is not broken
-#define Q_FOREACH(variable, container) \
-for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
- _container_.i != _container_.e; ++_container_.i) \
- if (variable = *_container_.i; false) {} else
-#endif // QT_NO_FOREACH
-
-#define Q_FOREVER for(;;)
-#ifndef QT_NO_KEYWORDS
-# ifndef QT_NO_FOREACH
-# ifndef foreach
-# define foreach Q_FOREACH
-# endif
-# endif // QT_NO_FOREACH
-# ifndef forever
-# define forever Q_FOREVER
-# endif
-#endif
-
-template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
-template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get())
-{ static_assert(noexcept(ptr.get()), "Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"); return ptr.get(); }
-
-// 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
-#define Q_DECLARE_PRIVATE(Class) \
- inline Class##Private* d_func() noexcept \
- { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr));) } \
- inline const Class##Private* d_func() const noexcept \
- { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));) } \
- friend class Class##Private;
-
-#define Q_DECLARE_PRIVATE_D(Dptr, Class) \
- inline Class##Private* d_func() noexcept \
- { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr));) } \
- inline const Class##Private* d_func() const noexcept \
- { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr));) } \
- friend class Class##Private;
-
-#define Q_DECLARE_PUBLIC(Class) \
- inline Class* q_func() noexcept { return static_cast<Class *>(q_ptr); } \
- inline const Class* q_func() const noexcept { return static_cast<const Class *>(q_ptr); } \
- friend class Class;
-
-#define Q_D(Class) Class##Private * const d = d_func()
-#define Q_Q(Class) Class * const q = q_func()
-
-#define QT_TR_NOOP(x) x
-#define QT_TR_NOOP_UTF8(x) x
-#define QT_TRANSLATE_NOOP(scope, x) x
-#define QT_TRANSLATE_NOOP_UTF8(scope, x) x
-#define QT_TRANSLATE_NOOP3(scope, x, comment) {x, comment}
-#define QT_TRANSLATE_NOOP3_UTF8(scope, x, comment) {x, comment}
-
-#ifndef QT_NO_TRANSLATION
-
-#define QT_TR_N_NOOP(x) x
-#define QT_TRANSLATE_N_NOOP(scope, x) x
-#define QT_TRANSLATE_N_NOOP3(scope, x, comment) {x, comment}
-
-// Defined in qcoreapplication.cpp
-// The better name qTrId() is reserved for an upcoming function which would
-// return a much more powerful QStringFormatter instead of a QString.
-Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1);
-
-#define QT_TRID_NOOP(id) id
-
-#endif // QT_NO_TRANSLATION
-
-
-#ifdef Q_QDOC
-// Just for documentation generation
-template<typename T>
-auto qOverload(T functionPointer);
-template<typename T>
-auto qConstOverload(T memberFunctionPointer);
-template<typename T>
-auto qNonConstOverload(T memberFunctionPointer);
-#else
-template <typename... Args>
-struct QNonConstOverload
-{
- template <typename R, typename T>
- constexpr auto operator()(R (T::*ptr)(Args...)) const noexcept -> decltype(ptr)
- { return ptr; }
-
- template <typename R, typename T>
- static constexpr auto of(R (T::*ptr)(Args...)) noexcept -> decltype(ptr)
- { return ptr; }
-};
-
-template <typename... Args>
-struct QConstOverload
-{
- template <typename R, typename T>
- constexpr auto operator()(R (T::*ptr)(Args...) const) const noexcept -> decltype(ptr)
- { return ptr; }
-
- template <typename R, typename T>
- static constexpr auto of(R (T::*ptr)(Args...) const) noexcept -> decltype(ptr)
- { return ptr; }
-};
-
-template <typename... Args>
-struct QOverload : QConstOverload<Args...>, QNonConstOverload<Args...>
-{
- using QConstOverload<Args...>::of;
- using QConstOverload<Args...>::operator();
- using QNonConstOverload<Args...>::of;
- using QNonConstOverload<Args...>::operator();
-
- template <typename R>
- constexpr auto operator()(R (*ptr)(Args...)) const noexcept -> decltype(ptr)
- { return ptr; }
-
- template <typename R>
- static constexpr auto of(R (*ptr)(Args...)) noexcept -> decltype(ptr)
- { return ptr; }
-};
-
-template <typename... Args> constexpr inline QOverload<Args...> qOverload = {};
-template <typename... Args> constexpr inline QConstOverload<Args...> qConstOverload = {};
-template <typename... Args> constexpr inline QNonConstOverload<Args...> qNonConstOverload = {};
-#endif
-
-
-class QByteArray;
-Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
-// need it as two functions because QString is only forward-declared here
-Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName);
-Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName, const QString &defaultValue);
-Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value);
-Q_CORE_EXPORT bool qunsetenv(const char *varName);
-
-Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept;
-Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept;
-Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept;
-
-inline int qIntCast(double f) { return int(f); }
-inline int qIntCast(float f) { return int(f); }
-
-#define QT_MODULE(x)
-
-#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && \
- (!defined(__PIC__) || (defined(__PIE__) && defined(Q_CC_GNU) && Q_CC_GNU >= 500))
-# error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\
- "Compile your code with -fPIC (and not with -fPIE)."
-#endif
-
-#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
-#define QT_VA_ARGS_EXPAND(...) __VA_ARGS__ // Needed for MSVC
-#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_EXPAND(QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
-#define QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##_##ARGC
-#define QT_OVERLOADED_MACRO_IMP(MACRO, ARGC) QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC)
-#define QT_OVERLOADED_MACRO(MACRO, ...) QT_VA_ARGS_EXPAND(QT_OVERLOADED_MACRO_IMP(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__))
-
-// This macro can be used to calculate member offsets for types with a non standard layout.
-// It uses the fact that offsetof() is allowed to support those types since C++17 as an optional
-// feature. All our compilers do support this, but some issue a warning, so we wrap the offsetof()
-// call in a macro that disables the compiler warning.
-#define Q_OFFSETOF(Class, member) \
- []() -> size_t { \
- QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
- return offsetof(Class, member); \
- QT_WARNING_POP \
- }()
-
-QT_END_NAMESPACE
+#include <QtCore/qtclasshelpermacros.h>
// We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4.
// Be careful when changing the order of these files.
@@ -1457,11 +51,24 @@ QT_END_NAMESPACE
#include <QtCore/qflags.h>
#include <QtCore/qatomic.h>
+#include <QtCore/qconstructormacros.h>
+#include <QtCore/qdarwinhelpers.h>
+#include <QtCore/qexceptionhandling.h>
+#include <QtCore/qforeach.h>
+#include <QtCore/qfunctionpointer.h>
#include <QtCore/qglobalstatic.h>
+#include <QtCore/qmalloc.h>
+#include <QtCore/qminmax.h>
#include <QtCore/qnumeric.h>
+#include <QtCore/qoverload.h>
+#include <QtCore/qswap.h>
+#include <QtCore/qtdeprecationmarkers.h>
+#include <QtCore/qtenvironmentvariables.h>
+#include <QtCore/qtresource.h>
+#include <QtCore/qttranslation.h>
+#include <QtCore/qttypetraits.h>
#include <QtCore/qversiontagging.h>
#endif /* __cplusplus */
-#endif /* !__ASSEMBLER__ */
#endif /* QGLOBAL_H */
diff --git a/src/corelib/global/qglobal_p.h b/src/corelib/global/qglobal_p.h
index 5ab84fa8be..31f67510e3 100644
--- a/src/corelib/global/qglobal_p.h
+++ b/src/corelib/global/qglobal_p.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Copyright (C) 2015 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// Copyright (C) 2015 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QGLOBAL_P_H
#define QGLOBAL_P_H
@@ -60,17 +24,37 @@
#include <QtCore/private/qtcore-config_p.h>
#endif
-#if defined(__cplusplus)
-#ifdef Q_CC_MINGW
-# include <unistd.h> // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r()
+#if defined(Q_CC_MSVC)
+// By default, dynamic initialization uses subsection "$XCU", which is
+// equivalent to #pragma init_seg(user). Additionally, #pragma
+// init_seg(compiler) and init_seg(lib) use "$XCC" and "$XCL" respectively. So
+// place us between "compiler" and "lib".
+# define QT_SUPPORTS_INIT_PRIORITY 1
+
+// warning C4075: initializers put in unrecognized initialization area
+# define Q_DECL_INIT_PRIORITY(nn) \
+ __pragma(warning(disable: 4075)) \
+ __pragma(init_seg(".CRT$XCK" QT_STRINGIFY(nn))) Q_DECL_UNUSED
+#elif defined(Q_OS_QNX)
+// init_priority fails on QNX and we didn't bother investigating why
+# define QT_SUPPORTS_INIT_PRIORITY 0
+#elif defined(Q_OS_WIN) || defined(Q_OF_ELF)
+# define QT_SUPPORTS_INIT_PRIORITY 1
+// priorities 0 to 1000 are reserved to the runtime;
+// we use above 2000 in case someone REALLY needs to go before us
+# define Q_DECL_INIT_PRIORITY(nn) __attribute__((init_priority(2000 + nn), used))
+#elif defined(QT_SHARED)
+// it doesn't support this exactly, but we can work around it
+# define QT_SUPPORTS_INIT_PRIORITY -1
+# define Q_DECL_INIT_PRIORITY(nn) Q_DECL_UNUSED
+#else
+# define QT_SUPPORTS_INIT_PRIORITY 0
#endif
-#include <time.h>
+#if defined(__cplusplus)
QT_BEGIN_NAMESPACE
-// These behave as if they consult the environment, so need to share its locking:
-Q_CORE_EXPORT void qTzSet();
-Q_CORE_EXPORT time_t qMkTime(struct tm *when);
+Q_NORETURN Q_CORE_EXPORT void qAbort();
QT_END_NAMESPACE
@@ -146,4 +130,3 @@ QT_END_NAMESPACE
#endif // defined(__cplusplus)
#endif // QGLOBAL_P_H
-
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index 4aa496e7f6..93127adab3 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -1,49 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QGLOBALSTATIC_H
#define QGLOBALSTATIC_H
+#include <QtCore/qassert.h>
#include <QtCore/qatomic.h>
+#include <QtCore/qtclasshelpermacros.h>
+#include <atomic> // for bootstrapped (no thread) builds
#include <type_traits>
QT_BEGIN_NAMESPACE
@@ -55,84 +20,109 @@ enum GuardValues {
Uninitialized = 0,
Initializing = 1
};
-}
-#if defined(Q_OS_UNIX) && defined(Q_CC_INTEL)
-// Work around Intel issue ID 6000058488:
-// local statics inside an inline function inside an anonymous namespace are global
-// symbols (this affects the IA-64 C++ ABI, so OS X and Linux only)
-# define Q_GLOBAL_STATIC_INTERNAL_DECORATION Q_DECL_HIDDEN
-#else
-# define Q_GLOBAL_STATIC_INTERNAL_DECORATION Q_DECL_HIDDEN inline
+template <typename QGS> union Holder
+{
+ using Type = typename QGS::QGS_Type;
+ using PlainType = std::remove_cv_t<Type>;
+
+ static constexpr bool ConstructionIsNoexcept = noexcept(QGS::innerFunction(nullptr));
+ Q_CONSTINIT static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
+
+ // union's sole member
+ PlainType storage;
+
+ Holder() noexcept(ConstructionIsNoexcept)
+ {
+ QGS::innerFunction(pointer());
+ guard.storeRelaxed(QtGlobalStatic::Initialized);
+ }
+
+ ~Holder()
+ {
+ // TSAN does not support atomic_thread_fence and GCC complains:
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97868
+ // https://github.com/google/sanitizers/issues/1352
+QT_WARNING_PUSH
+#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1100
+QT_WARNING_DISABLE_GCC("-Wtsan")
#endif
+ // import changes to *pointer() by other threads before running ~PlainType():
+ std::atomic_thread_fence(std::memory_order_acquire);
+QT_WARNING_POP
+ pointer()->~PlainType();
+ guard.storeRelease(QtGlobalStatic::Destroyed);
+ }
-#define Q_GLOBAL_STATIC_INTERNAL(ARGS) \
- Q_GLOBAL_STATIC_INTERNAL_DECORATION Type *innerFunction() \
- { \
- struct HolderBase { \
- HolderBase() = default; \
- ~HolderBase() noexcept \
- { if (guard.loadRelaxed() == QtGlobalStatic::Initialized) \
- guard.storeRelaxed(QtGlobalStatic::Destroyed); } \
- Q_DISABLE_COPY_MOVE(HolderBase) \
- }; \
- static struct Holder : public HolderBase { \
- Type value; \
- Holder() \
- noexcept(noexcept(typename std::remove_cv<Type>::type ARGS)) \
- : value ARGS \
- { guard.storeRelaxed(QtGlobalStatic::Initialized); } \
- } holder; \
- return &holder.value; \
+ PlainType *pointer() noexcept
+ {
+ return &storage;
}
+ Q_DISABLE_COPY_MOVE(Holder)
+};
+}
-// this class must be POD, unless the compiler supports thread-safe statics
-template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard>
-struct QGlobalStatic
+template <typename Holder> struct QGlobalStatic
{
- typedef T Type;
+ using Type = typename Holder::Type;
- bool isDestroyed() const { return guard.loadRelaxed() <= QtGlobalStatic::Destroyed; }
- bool exists() const { return guard.loadRelaxed() == QtGlobalStatic::Initialized; }
+ bool isDestroyed() const noexcept { return guardValue() <= QtGlobalStatic::Destroyed; }
+ bool exists() const noexcept { return guardValue() == QtGlobalStatic::Initialized; }
operator Type *()
{
if (isDestroyed())
return nullptr;
- return innerFunction();
+ return instance();
}
Type *operator()()
{
if (isDestroyed())
return nullptr;
- return innerFunction();
+ return instance();
}
Type *operator->()
{
- Q_ASSERT_X(!isDestroyed(), "Q_GLOBAL_STATIC",
+ Q_ASSERT_X(!isDestroyed(), Q_FUNC_INFO,
"The global static was used after being destroyed");
- return innerFunction();
+ return instance();
}
Type &operator*()
{
- Q_ASSERT_X(!isDestroyed(), "Q_GLOBAL_STATIC",
+ Q_ASSERT_X(!isDestroyed(), Q_FUNC_INFO,
"The global static was used after being destroyed");
- return *innerFunction();
+ return *instance();
+ }
+
+protected:
+ static Type *instance() noexcept(Holder::ConstructionIsNoexcept)
+ {
+ static Holder holder;
+ return holder.pointer();
+ }
+ static QtGlobalStatic::GuardValues guardValue() noexcept
+ {
+ return QtGlobalStatic::GuardValues(Holder::guard.loadAcquire());
}
};
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
- namespace { namespace Q_QGS_ ## NAME { \
- typedef TYPE Type; \
- QBasicAtomicInt guard = Q_BASIC_ATOMIC_INITIALIZER(QtGlobalStatic::Uninitialized); \
- Q_GLOBAL_STATIC_INTERNAL(ARGS) \
- } } \
- static QGlobalStatic<TYPE, \
- Q_QGS_ ## NAME::innerFunction, \
- Q_QGS_ ## NAME::guard> NAME;
-
-#define Q_GLOBAL_STATIC(TYPE, NAME) \
- Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ())
+ QT_WARNING_PUSH \
+ QT_WARNING_DISABLE_CLANG("-Wunevaluated-expression") \
+ namespace { struct Q_QGS_ ## NAME { \
+ typedef TYPE QGS_Type; \
+ static void innerFunction(void *pointer) \
+ noexcept(noexcept(std::remove_cv_t<QGS_Type> ARGS)) \
+ { \
+ new (pointer) QGS_Type ARGS; \
+ } \
+ }; } \
+ Q_CONSTINIT static QGlobalStatic<QtGlobalStatic::Holder<Q_QGS_ ## NAME>> NAME; \
+ QT_WARNING_POP
+ /**/
+
+#define Q_GLOBAL_STATIC(TYPE, NAME, ...) \
+ Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, (__VA_ARGS__))
QT_END_NAMESPACE
#endif // QGLOBALSTATIC_H
diff --git a/src/corelib/global/qglobalstatic.qdoc b/src/corelib/global/qglobalstatic.qdoc
index e7935d5a9b..38700032b1 100644
--- a/src/corelib/global/qglobalstatic.qdoc
+++ b/src/corelib/global/qglobalstatic.qdoc
@@ -1,32 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
- \macro Q_GLOBAL_STATIC(Type, VariableName)
+ \macro Q_GLOBAL_STATIC(Type, VariableName, ...)
\since 5.1
\relates QGlobalStatic
@@ -36,6 +12,11 @@
will not increase the application or the library's load time. Additionally,
the object is initialized in a thread-safe manner on all platforms.
+ Since Qt 6.3, this macro admits variadic arguments, which are used to
+ initialize the object, thus making the need for \l
+ Q_GLOBAL_STATIC_WITH_ARGS unnecessary. Please note the arguments do not
+ require an extra set of parentheses, unlike the older macro.
+
The typical use of this macro is as follows, in a global context (that is,
outside of any function bodies):
@@ -65,10 +46,6 @@
\li the order of initialization and destruction among different
translation units is not determined, leading to possible uses before
initialization or after destruction;
-
- \li if it is found inside a function (that is, not global), it will be
- initialized on first use, but many current compilers (as of 2013) do
- not guarantee that the initialization will be thread-safe;
\endlist
The Q_GLOBAL_STATIC macro solves all of the above problems by guaranteeing
@@ -195,11 +172,11 @@
\omit
\section1 Compatibility with Qt 4 and Qt 5.0
- This macro, in its current form and behavior, was introduced in Qt 5.1.
- Prior to that version, Qt had another macro with the same name that was
- private API. This section is not meant to document how to use
- Q_GLOBAL_STATIC in those versions, but instead to serve as a porting guide
- for Qt code that used those macros.
+ This macro, in its current behavior, was introduced in Qt 5.1. Prior to
+ that version, Qt had another macro with the same name that was private API.
+ This section is not meant to document how to use Q_GLOBAL_STATIC in those
+ versions, but instead to serve as a porting guide for Qt code that used
+ those macros.
The Qt 4 Q_GLOBAL_STATIC macro differed in behavior in the following ways:
@@ -218,24 +195,38 @@
\section1 Implementation Details
- Q_GLOBAL_STATIC is implemented by creating a QBasicAtomicInt called the \c
- guard and a free, inline function called \c innerFunction. The guard
- variable is initialized to value 0 (chosen so that the guard can be placed
- in the .bss section of the binary file), which denotes that construction
- has not yet taken place (uninitialized). The inner function is implemented
- by the helper macro Q_GLOBAL_STATIC_INTERNAL.
-
- Both the guard variable and the inner function are passed as template
- parameters to QGlobalStatic, along with the type \a Type. Both should also
- have static linkage or be placed inside an anonymous namespace, so that the
- visibility of Q_GLOBAL_STATIC is that of a global static. To permit
- multiple Q_GLOBAL_STATIC per translation unit, the guard variable and the
- inner function must have unique names, which can be accomplished by
- concatenating with \a VariableName or by placing them in a namespace that
- has \a VariableName as part of the name. To simplify and improve
- readability on Q_GLOBAL_STATIC_INTERNAL, we chose the namespace solution.
- It's also required for C++98 builds, since static symbols cannot be used as
- template parameters.
+ Q_GLOBAL_STATIC is implemented by creating a type called \c Q_QGS_NAME
+ where \c NAME is the name of the variable the user passed to the macro,
+ inside an unnamed namespace, and a \c static variable of \l QGlobalStatic
+ type, named \c NAME. The use of unnamed namespaces forces the compiler to emit
+ non-exported symbols, often local to the translation unit, and this
+ propagates to the \l QGlobalStatic template instantiation that uses such
+ types. Additionally, because the type is used only for one variable,
+ there's effectively no difference between static and non-static data
+ members.
+
+ The "QGS" type is a \c struct containing a \c typedef to \a TYPE and a
+ static member function that receives a pointer to storage suitable to hold
+ an instance of \a TYPE. It will initialize the storage using a placement \c
+ new and the variadic arguments.
+
+ The majority of the work is done by the public \l QGlobalStatic class and
+ the private \c QtGlobalStatic::Holder class. The \c Holder union has a
+ single non-static member of type \a TYPE, but because this is a union, its
+ construction and destruction are explicitly controlled in the Holder's
+ constructor and destructor. The constructor calls the "QGS" type's static
+ member function with a pointer to this member so it can be initialized
+ and the destructor calls the type's destructor. The \c{Holder} type is
+ therefore neither trivially constructible nor trivially destructible. It is
+ used as a function-local \c static so its initialization is thread-safe due
+ to C++11's requirement that such variables be thread-safely initialized.
+
+ Additionally, both the constructor and destructor modify a guard variable
+ after construction and before destruction, respectively. The guard variable
+ is implemented as a \c {static inline} member instead of a non-static
+ member so the compiler and linker are free to place this variable in memory
+ far from the actual object. This way, if we wanted to, we could mark it
+ aligned-to-cacheline in the future to prevent false sharing.
The guard variable can assume the following values:
@@ -257,42 +248,15 @@
operate solely on the guard variable: the former returns \c true if the guard
is negative, whereas the latter returns \c true only if it is -2.
- The Q_GLOBAL_STATIC_INTERNAL macro implements the actual construction and
- destruction. There are two implementations of it: one for compilers that
- support thread-safe initialization of function-local statics and one for
- compilers that don't. Thread-safe initialization is required by C++11 in
- [stmt.decl], but as of the time of this writing, only compilers based on
- the IA-64 C++ ABI implemented it properly. The implementation requiring
- thread-safe initialization is also used on the Qt bootstrapped tools, which
- disable the "thread" feature.
-
- The implementation requiring thread-safe initialization from the compiler
- is the simplest: it creates the \a Type object as a function-local static
- and returns its address. The actual object is actually inside a holder
- structure so holder's destructor can set the guard variable to the value -2
- (destroyed) when the type has finished destruction. Since we need to set
- the guard \b after the destruction has finished, this code needs to be in a
- base struct's destructor. And it only sets to -2 (destroyed) if it finds
- the guard at -1 (initialized): this is done to ensure that the guard isn't
- set to -2 in the event the type's constructor threw an exception. A holder
- structure is used to avoid creating two statics, which the ABI might
- require duplicating the thread-safe control structures for.
-
- The other implementation is similar to Qt 4's Q_GLOBAL_STATIC, but unlike
- that one, it uses a \l QBasicMutex to provide locking. It is also more
- efficient memory-wise. It use a simple double-checked locking of the mutex
- and then creates the contents on the heap. After that, it creates a
- function-local structure called "Cleanup", whose destructor will be run at
- program exit and will actually destroy the contents.
-
\endomit
- \sa Q_GLOBAL_STATIC_WITH_ARGS(), QGlobalStatic
+ \sa Q_GLOBAL_STATIC_WITH_ARGS(), Q_APPLICATION_STATIC(), QGlobalStatic
*/
/*!
\macro Q_GLOBAL_STATIC_WITH_ARGS(Type, VariableName, Arguments)
\since 5.1
+ \obsolete
\relates QGlobalStatic
Creates a global and static object of type \l QGlobalStatic, of name \a
@@ -310,7 +274,12 @@
\endcode
The \a Arguments macro parameter must always include the parentheses or, if
- C++11 uniform initialization is allowed, the braces.
+ C++11 uniform initialization is allowed, the braces. The above call is
+ equivalent to
+
+ \code
+ Q_GLOBAL_STATIC(MyType, staticType, 42, "Hello", "World")
+ \endcode
Aside from the actual initialization of the contents with the supplied
arguments, this macro behaves identically to Q_GLOBAL_STATIC(). Please
@@ -356,7 +325,7 @@
*/
/*!
- \fn template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard> bool QGlobalStatic<T, innerFunction, guard>::isDestroyed() const
+ \fn template <typename Holder> bool QGlobalStatic<Holder>::isDestroyed() const
This function returns \c true if the global static object has already
completed destruction (that is, if the destructor for the type has already
@@ -386,7 +355,7 @@
*/
/*!
- \fn template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard> bool QGlobalStatic<T, innerFunction, guard>::exists() const
+ \fn template <typename Holder> bool QGlobalStatic<Holder>::exists() const
This function returns \c true if the global static object has already
completed initialization (that is, if the constructor for the type has
@@ -436,7 +405,7 @@
/*!
\keyword qglobalstatic-operator-type-ptr
- \fn template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard> QGlobalStatic<T, innerFunction, guard>::operator Type*()
+ \fn template <typename Holder> QGlobalStatic<Holder>::operator Type*()
This function returns the address of the contents of this global static. If
the contents have not yet been created, they will be created thread-safely
@@ -469,7 +438,7 @@
*/
/*!
- \fn template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard> Type *QGlobalStatic<T, innerFunction, guard>::operator()()
+ \fn template <typename Holder> Type *QGlobalStatic<Holder>::operator()()
\deprecated
This function returns the address of the contents of this global static. If
@@ -485,7 +454,7 @@
*/
/*!
- \fn template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard> Type *QGlobalStatic<T, innerFunction, guard>::operator->()
+ \fn template <typename Holder> Type *QGlobalStatic<Holder>::operator->()
This function returns the address of the contents of this global static. If
the contents have not yet been created, they will be created thread-safely
@@ -498,7 +467,7 @@
*/
/*!
- \fn template <typename T, T *(&innerFunction)(), QBasicAtomicInt &guard> Type &QGlobalStatic<T, innerFunction, guard>::operator*()
+ \fn template <typename Holder> Type &QGlobalStatic<Holder>::operator*()
This function returns a reference to the contents of this global static. If
the contents have not yet been created, they will be created thread-safely
diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp
index 491e126b7a..414b96aac3 100644
--- a/src/corelib/global/qhooks.cpp
+++ b/src/corelib/global/qhooks.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Volker Krause <volker.krause@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Volker Krause <volker.krause@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qhooks_p.h"
@@ -67,7 +31,7 @@ quintptr Q_CORE_EXPORT qtHookData[] = {
// The required sizes and offsets are tested in tests/auto/other/toolsupport.
// When this fails and the change was intentional, adjust the test and
// adjust this value here.
- 21
+ 22,
};
static_assert(QHooks::LastHookIndex == sizeof(qtHookData) / sizeof(qtHookData[0]));
diff --git a/src/corelib/global/qhooks_p.h b/src/corelib/global/qhooks_p.h
index a51a2ec86b..e266c2a7f9 100644
--- a/src/corelib/global/qhooks_p.h
+++ b/src/corelib/global/qhooks_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Volker Krause <volker.krause@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Volker Krause <volker.krause@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QHOOKS_H
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 625fab75f7..92729b06f1 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qdir.h"
#include "qstringlist.h"
@@ -51,14 +15,13 @@
#include "qcoreapplication.h"
#include "private/qglobal_p.h"
+#include "archdetect.cpp"
#include "qconfig.cpp"
#ifdef Q_OS_DARWIN
# include "private/qcore_mac_p.h"
#endif // Q_OS_DARWIN
-#include "archdetect.cpp"
-
#if QT_CONFIG(relocatable) && QT_CONFIG(dlopen) && !QT_CONFIG(framework)
# include <dlfcn.h>
#endif
@@ -69,6 +32,8 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
extern void qDumpCPUFeatures(); // in qsimd.cpp
#if QT_CONFIG(settings)
@@ -79,16 +44,16 @@ struct QLibrarySettings
{
QLibrarySettings();
void load();
+ bool havePaths();
QSettings *configuration();
QScopedPointer<QSettings> settings;
- bool havePaths;
+ bool paths;
bool reloadOnQAppAvailable;
};
Q_GLOBAL_STATIC(QLibrarySettings, qt_library_settings)
-QLibrarySettings::QLibrarySettings() : havePaths(false)
- , reloadOnQAppAvailable(false)
+QLibrarySettings::QLibrarySettings() : paths(false), reloadOnQAppAvailable(false)
{
load();
}
@@ -100,6 +65,13 @@ QSettings *QLibrarySettings::configuration()
return settings.data();
}
+bool QLibrarySettings::havePaths()
+{
+ if (reloadOnQAppAvailable && QCoreApplication::instance() != nullptr)
+ load();
+ return paths;
+}
+
void QLibrarySettings::load()
{
// If we get any settings here, those won't change when the application shows up.
@@ -110,15 +82,24 @@ void QLibrarySettings::load()
// This code needs to be in the regular library, as otherwise a qt.conf that
// works for qmake would break things for dynamically built Qt tools.
QStringList children = settings->childGroups();
- havePaths = !children.contains(QLatin1String("Platforms"))
- || children.contains(QLatin1String("Paths"));
+ paths = !children.contains("Platforms"_L1)
+ || children.contains("Paths"_L1);
}
}
+namespace {
+const QString *qtconfManualPath = nullptr;
+}
+
+void QLibraryInfoPrivate::setQtconfManualPath(const QString *path)
+{
+ qtconfManualPath = path;
+}
+
static QSettings *findConfiguration()
{
- if (!QLibraryInfoPrivate::qtconfManualPath.isEmpty())
- return new QSettings(QLibraryInfoPrivate::qtconfManualPath, QSettings::IniFormat);
+ if (qtconfManualPath)
+ return new QSettings(*qtconfManualPath, QSettings::IniFormat);
QString qtconfig = QStringLiteral(":/qt/etc/qt.conf");
if (QFile::exists(qtconfig))
@@ -127,7 +108,7 @@ static QSettings *findConfiguration()
CFBundleRef bundleRef = CFBundleGetMainBundle();
if (bundleRef) {
QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef,
- QCFString(QLatin1String("qt.conf")),
+ QCFString("qt.conf"_L1),
0,
0);
if (urlRef) {
@@ -140,18 +121,16 @@ static QSettings *findConfiguration()
#endif
if (QCoreApplication::instance()) {
QDir pwd(QCoreApplication::applicationDirPath());
- qtconfig = pwd.filePath(QLatin1String("qt" QT_STRINGIFY(QT_VERSION_MAJOR) ".conf"));
+ qtconfig = pwd.filePath(u"qt" QT_STRINGIFY(QT_VERSION_MAJOR) ".conf"_s);
if (QFile::exists(qtconfig))
return new QSettings(qtconfig, QSettings::IniFormat);
- qtconfig = pwd.filePath(QLatin1String("qt.conf"));
+ qtconfig = pwd.filePath("qt.conf"_L1);
if (QFile::exists(qtconfig))
return new QSettings(qtconfig, QSettings::IniFormat);
}
return nullptr; //no luck
}
-QString QLibraryInfoPrivate::qtconfManualPath;
-
QSettings *QLibraryInfoPrivate::configuration()
{
QLibrarySettings *ls = qt_library_settings();
@@ -166,7 +145,7 @@ void QLibraryInfoPrivate::reload()
static bool havePaths() {
QLibrarySettings *ls = qt_library_settings();
- return ls && ls->havePaths;
+ return ls && ls->havePaths();
}
#endif // settings
@@ -199,42 +178,8 @@ static bool havePaths() {
QLibraryInfo::QLibraryInfo()
{ }
-#if defined(Q_CC_INTEL) // must be before GNU, Clang and MSVC because ICC/ICL claim to be them
-# ifdef __INTEL_CLANG_COMPILER
-# define ICC_COMPAT "Clang"
-# elif defined(__INTEL_MS_COMPAT_LEVEL)
-# define ICC_COMPAT "Microsoft"
-# elif defined(__GNUC__)
-# define ICC_COMPAT "GCC"
-# else
-# define ICC_COMPAT "no"
-# endif
-# if __INTEL_COMPILER == 1300
-# define ICC_VERSION "13.0"
-# elif __INTEL_COMPILER == 1310
-# define ICC_VERSION "13.1"
-# elif __INTEL_COMPILER == 1400
-# define ICC_VERSION "14.0"
-# elif __INTEL_COMPILER == 1500
-# define ICC_VERSION "15.0"
-# else
-# define ICC_VERSION QT_STRINGIFY(__INTEL_COMPILER)
-# endif
-# ifdef __INTEL_COMPILER_UPDATE
-# define COMPILER_STRING "Intel(R) C++ " ICC_VERSION "." QT_STRINGIFY(__INTEL_COMPILER_UPDATE) \
- " build " QT_STRINGIFY(__INTEL_COMPILER_BUILD_DATE) " [" \
- ICC_COMPAT " compatibility]"
-# else
-# define COMPILER_STRING "Intel(R) C++ " ICC_VERSION \
- " build " QT_STRINGIFY(__INTEL_COMPILER_BUILD_DATE) " [" \
- ICC_COMPAT " compatibility]"
-# endif
-#elif defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
-# ifdef __apple_build_version__ // Apple clang has other version numbers
-# define COMPILER_STRING "Clang " __clang_version__ " (Apple)"
-# else
-# define COMPILER_STRING "Clang " __clang_version__
-# endif
+#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
+# define COMPILER_STRING __VERSION__ /* already includes the compiler's name */
#elif defined(Q_CC_GHS)
# define COMPILER_STRING "GHS " QT_STRINGIFY(__GHS_VERSION_NUMBER)
#elif defined(Q_CC_GNU)
@@ -244,8 +189,10 @@ QLibraryInfo::QLibraryInfo()
# define COMPILER_STRING "MSVC 2015"
# elif _MSC_VER < 1917
# define COMPILER_STRING "MSVC 2017"
-# elif _MSC_VER < 2000
+# elif _MSC_VER < 1930
# define COMPILER_STRING "MSVC 2019"
+# elif _MSC_VER < 2000
+# define COMPILER_STRING "MSVC 2022"
# else
# define COMPILER_STRING "MSVC _MSC_VER " QT_STRINGIFY(_MSC_VER)
# endif
@@ -262,7 +209,10 @@ QLibraryInfo::QLibraryInfo()
#else
# define SHARED_STRING " static"
#endif
-#define QT_BUILD_STR "Qt " QT_VERSION_STR " (" ARCH_FULL SHARED_STRING DEBUG_STRING " build; by " COMPILER_STRING ")"
+static const char *qt_build_string() noexcept
+{
+ return "Qt " QT_VERSION_STR " (" ARCH_FULL SHARED_STRING DEBUG_STRING " build; by " COMPILER_STRING ")";
+}
/*!
Returns a string describing how this version of Qt was built.
@@ -274,7 +224,7 @@ QLibraryInfo::QLibraryInfo()
const char *QLibraryInfo::build() noexcept
{
- return QT_BUILD_STR;
+ return qt_build_string();
}
/*!
@@ -283,7 +233,7 @@ const char *QLibraryInfo::build() noexcept
false if it was built in release mode.
*/
bool
-QLibraryInfo::isDebugBuild()
+QLibraryInfo::isDebugBuild() noexcept
{
#ifdef QT_DEBUG
return true;
@@ -293,6 +243,19 @@ QLibraryInfo::isDebugBuild()
}
/*!
+ \since 6.5
+ Returns \c true if this is a shared (dynamic) build of Qt.
+*/
+bool QLibraryInfo::isSharedBuild() noexcept
+{
+#ifdef QT_SHARED
+ return true;
+#else
+ return false;
+#endif
+}
+
+/*!
\since 5.8
Returns the version of the Qt library.
@@ -303,35 +266,6 @@ QVersionNumber QLibraryInfo::version() noexcept
return QVersionNumber(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH);
}
-/*
- * To add a new entry in QLibraryInfo::LibraryPath, add it to the enum
- * in qtbase/src/corelib/global/qlibraryinfo.h and:
- * - add its relative path in the qtConfEntries[] array below
- * (the key is what appears in a qt.conf file)
- */
-
-static const struct {
- char key[19], value[13];
-} qtConfEntries[] = {
- { "Prefix", "." },
- { "Documentation", "doc" }, // should be ${Data}/doc
- { "Headers", "include" },
- { "Libraries", "lib" },
-#ifdef Q_OS_WIN
- { "LibraryExecutables", "bin" },
-#else
- { "LibraryExecutables", "libexec" }, // should be ${ArchData}/libexec
-#endif
- { "Binaries", "bin" },
- { "Plugins", "plugins" }, // should be ${ArchData}/plugins
- { "Qml2Imports", "qml" }, // should be ${ArchData}/qml
- { "ArchData", "." },
- { "Data", "." },
- { "Translations", "translations" }, // should be ${Data}/translations
- { "Examples", "examples" },
- { "Tests", "tests" },
-};
-
static QString prefixFromAppDirHelper()
{
QString appDir;
@@ -344,7 +278,7 @@ static QString prefixFromAppDirHelper()
if (urlRef) {
QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
#ifdef Q_OS_MACOS
- QString bundleContentsDir = QString(path) + QLatin1String("/Contents/");
+ QString bundleContentsDir = QString(path) + "/Contents/"_L1;
if (QDir(bundleContentsDir).exists())
return QDir::cleanPath(bundleContentsDir);
#else
@@ -369,8 +303,7 @@ static QString prefixFromQtCoreLibraryHelper(const QString &qtCoreLibraryPath)
{
const QString qtCoreLibrary = QDir::fromNativeSeparators(qtCoreLibraryPath);
const QString libDir = QFileInfo(qtCoreLibrary).absolutePath();
- const QString prefixDir = libDir + QLatin1Char('/')
- + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH);
+ const QString prefixDir = libDir + "/" QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH;
return QDir::cleanPath(prefixDir);
}
#endif
@@ -386,7 +319,7 @@ static HMODULE getWindowsModuleHandle()
}
#endif // Q_OS_WIN
-static QString getRelocatablePrefix()
+static QString getRelocatablePrefix(QLibraryInfoPrivate::UsageMode usageMode)
{
QString prefixPath;
@@ -394,7 +327,14 @@ static QString getRelocatablePrefix()
// For regular builds, the prefix will be relative to the location of the QtCore shared library.
#if defined(QT_STATIC)
prefixPath = prefixFromAppDirHelper();
+ if (usageMode == QLibraryInfoPrivate::UsedFromQtBinDir) {
+ // For Qt tools in a static build, we must chop off the bin directory.
+ constexpr QByteArrayView binDir = qt_configure_strs.viewAt(QLibraryInfo::BinariesPath - 1);
+ constexpr size_t binDirLength = binDir.size() + 1;
+ prefixPath.chop(binDirLength);
+ }
#elif defined(Q_OS_DARWIN) && QT_CONFIG(framework)
+ Q_UNUSED(usageMode);
#ifndef QT_LIBINFIX
#define QT_LIBINFIX ""
#endif
@@ -429,16 +369,22 @@ static QString getRelocatablePrefix()
const QCFString libDirCFString = CFURLCopyFileSystemPath(libDirCFPath, kCFURLPOSIXPathStyle);
- const QString prefixDir = QString(libDirCFString) + QLatin1Char('/')
- + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH);
+ const QString prefixDir = QString(libDirCFString) + "/" QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH;
prefixPath = QDir::cleanPath(prefixDir);
+#elif defined(Q_OS_WASM)
+ // Emscripten expects to find shared libraries at the root of the in-memory
+ // file system when resolving dependencies for for dlopen() calls. So that's
+ // where libqt6core.so would be.
+ prefixPath = QStringLiteral("/");
#elif QT_CONFIG(dlopen)
+ Q_UNUSED(usageMode);
Dl_info info;
int result = dladdr(reinterpret_cast<void *>(&QLibraryInfo::isDebugBuild), &info);
if (result > 0 && info.dli_fname)
prefixPath = prefixFromQtCoreLibraryHelper(QString::fromLocal8Bit(info.dli_fname));
#elif defined(Q_OS_WIN)
+ Q_UNUSED(usageMode);
HMODULE hModule = getWindowsModuleHandle();
const int kBufferSize = 4096;
wchar_t buffer[kBufferSize];
@@ -452,7 +398,7 @@ static QString getRelocatablePrefix()
// executable within the QT_HOST_BIN directory. We're detecting the latter case by checking
// whether there's an import library corresponding to our QtCore DLL in PREFIX/lib.
const QString libdir = QString::fromLocal8Bit(
- qt_configure_strs + qt_configure_str_offsets[QLibraryInfo::LibrariesPath - 1]);
+ qt_configure_strs.viewAt(QLibraryInfo::LibrariesPath - 1));
const QLatin1Char slash('/');
#if defined(Q_CC_MINGW)
const QString implibPrefix = QStringLiteral("lib");
@@ -464,7 +410,7 @@ static QString getRelocatablePrefix()
const QString qtCoreImpLibFileName = implibPrefix
+ QFileInfo(qtCoreFilePath).completeBaseName() + implibSuffix;
const QString qtCoreImpLibPath = qtCoreDirPath
- + slash + QLatin1String(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH)
+ + slash + QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH
+ slash + libdir
+ slash + qtCoreImpLibFileName;
if (!QFileInfo::exists(qtCoreImpLibPath)) {
@@ -484,7 +430,7 @@ static QString getRelocatablePrefix()
// See "Hardware capabilities" in the ld.so documentation and the Qt 5.3.0
// changelog regarding SSE2 support.
const QString libdir = QString::fromLocal8Bit(
- qt_configure_strs + qt_configure_str_offsets[QLibraryInfo::LibrariesPath - 1]);
+ qt_configure_strs.viewAt(QLibraryInfo::LibrariesPath - 1));
QDir prefixDir(prefixPath);
while (!prefixDir.exists(libdir)) {
prefixDir.cdUp();
@@ -502,32 +448,63 @@ static QString getRelocatablePrefix()
}
#endif
-static QString getPrefix()
+static QString getPrefix(QLibraryInfoPrivate::UsageMode usageMode)
{
#if QT_CONFIG(relocatable)
- return getRelocatablePrefix();
+ return getRelocatablePrefix(usageMode);
#else
+ Q_UNUSED(usageMode);
return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH);
#endif
}
-void QLibraryInfoPrivate::keyAndDefault(QLibraryInfo::LibraryPath loc, QString *key,
- QString *value)
+QLibraryInfoPrivate::LocationInfo QLibraryInfoPrivate::locationInfo(QLibraryInfo::LibraryPath loc)
{
- if (unsigned(loc) < sizeof(qtConfEntries)/sizeof(qtConfEntries[0])) {
- *key = QLatin1String(qtConfEntries[loc].key);
- *value = QLatin1String(qtConfEntries[loc].value);
- }
+ /*
+ * To add a new entry in QLibraryInfo::LibraryPath, add it to the enum
+ * in qtbase/src/corelib/global/qlibraryinfo.h and:
+ * - add its relative path in the qtConfEntries[] array below
+ * (the key is what appears in a qt.conf file)
+ */
+ static constexpr auto qtConfEntries = qOffsetStringArray(
+ "Prefix", ".",
+ "Documentation", "doc", // should be ${Data}/doc
+ "Headers", "include",
+ "Libraries", "lib",
+#ifdef Q_OS_WIN
+ "LibraryExecutables", "bin",
+#else
+ "LibraryExecutables", "libexec", // should be ${ArchData}/libexec
+#endif
+ "Binaries", "bin",
+ "Plugins", "plugins", // should be ${ArchData}/plugins
+
+ "QmlImports", "qml", // should be ${ArchData}/qml
+
+ "ArchData", ".",
+ "Data", ".",
+ "Translations", "translations", // should be ${Data}/translations
+ "Examples", "examples",
+ "Tests", "tests"
+ );
+ [[maybe_unused]]
+ constexpr QByteArrayView dot{"."};
+
+ LocationInfo result;
+
+ if (int(loc) < qtConfEntries.count()) {
+ result.key = QLatin1StringView(qtConfEntries.viewAt(loc * 2));
+ result.defaultValue = QLatin1StringView(qtConfEntries.viewAt(loc * 2 + 1));
+ if (result.key == u"QmlImports")
+ result.fallbackKey = u"Qml2Imports"_s;
#ifndef Q_OS_WIN // On Windows we use the registry
- else if (loc == QLibraryInfo::SettingsPath) {
- *key = QLatin1String("Settings");
- *value = QLatin1String(".");
- }
+ } else if (loc == QLibraryInfo::SettingsPath) {
+ result.key = "Settings"_L1;
+ result.defaultValue = QLatin1StringView(dot);
#endif
- else {
- key->clear();
- value->clear();
}
+
+ return result;
}
/*! \fn QString QLibraryInfo::location(LibraryLocation loc)
@@ -542,40 +519,58 @@ void QLibraryInfoPrivate::keyAndDefault(QLibraryInfo::LibraryPath loc, QString *
*/
QString QLibraryInfo::path(LibraryPath p)
{
- const LibraryPath loc = p;
+ return QLibraryInfoPrivate::path(p);
+}
+
+
+/*
+ Returns the path specified by \a p.
+
+ The usage mode can be set to UsedFromQtBinDir to enable special handling for executables that
+ live in <install-prefix>/bin.
+ */
+QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMode)
+{
+ const QLibraryInfo::LibraryPath loc = p;
QString ret;
bool fromConf = false;
#if QT_CONFIG(settings)
if (havePaths()) {
fromConf = true;
- QString key;
- QString defaultValue;
- QLibraryInfoPrivate::keyAndDefault(loc, &key, &defaultValue);
- if (!key.isNull()) {
+ auto li = QLibraryInfoPrivate::locationInfo(loc);
+ if (!li.key.isNull()) {
QSettings *config = QLibraryInfoPrivate::configuration();
Q_ASSERT(config != nullptr);
- config->beginGroup(QLatin1String("Paths"));
+ config->beginGroup("Paths"_L1);
+
+ if (li.fallbackKey.isNull()) {
+ ret = config->value(li.key, li.defaultValue).toString();
+ } else {
+ QVariant v = config->value(li.key);
+ if (!v.isValid())
+ v = config->value(li.fallbackKey, li.defaultValue);
+ ret = v.toString();
+ }
- ret = config->value(key, defaultValue).toString();
- int startIndex = 0;
- forever {
- startIndex = ret.indexOf(QLatin1Char('$'), startIndex);
+ qsizetype startIndex = 0;
+ while (true) {
+ startIndex = ret.indexOf(u'$', startIndex);
if (startIndex < 0)
break;
- if (ret.length() < startIndex + 3)
+ if (ret.size() < startIndex + 3)
break;
- if (ret.at(startIndex + 1) != QLatin1Char('(')) {
+ if (ret.at(startIndex + 1) != u'(') {
startIndex++;
continue;
}
- int endIndex = ret.indexOf(QLatin1Char(')'), startIndex + 2);
+ qsizetype endIndex = ret.indexOf(u')', startIndex + 2);
if (endIndex < 0)
break;
auto envVarName = QStringView{ret}.mid(startIndex + 2, endIndex - startIndex - 2);
QString value = QString::fromLocal8Bit(qgetenv(envVarName.toLocal8Bit().constData()));
ret.replace(startIndex, endIndex - startIndex + 1, value);
- startIndex += value.length();
+ startIndex += value.size();
}
config->endGroup();
@@ -586,35 +581,31 @@ QString QLibraryInfo::path(LibraryPath p)
#endif // settings
if (!fromConf) {
- // "volatile" here is a hack to prevent compilers from doing a
- // compile-time strlen() on "path". The issue is that Qt installers
- // will binary-patch the Qt installation paths -- in such scenarios, Qt
- // will be built with a dummy path, thus the compile-time result of
- // strlen is meaningless.
- const char * volatile path = nullptr;
- if (loc == PrefixPath) {
- ret = getPrefix();
- } else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) {
- path = qt_configure_strs + qt_configure_str_offsets[loc - 1];
+ if (loc == QLibraryInfo::PrefixPath) {
+ ret = getPrefix(usageMode);
+ } else if (int(loc) <= qt_configure_strs.count()) {
+ ret = QString::fromLocal8Bit(qt_configure_strs.viewAt(loc - 1));
#ifndef Q_OS_WIN // On Windows we use the registry
- } else if (loc == SettingsPath) {
- path = QT_CONFIGURE_SETTINGS_PATH;
+ } else if (loc == QLibraryInfo::SettingsPath) {
+ // Use of volatile is a hack to discourage compilers from calling
+ // strlen(), in the inlined fromLocal8Bit(const char *)'s body, at
+ // compile-time, as Qt installers binary-patch the path, replacing
+ // the dummy path seen at compile-time, typically changing length.
+ const char *volatile path = QT_CONFIGURE_SETTINGS_PATH;
+ ret = QString::fromLocal8Bit(path);
#endif
}
-
- if (path)
- ret = QString::fromLocal8Bit(path);
}
if (!ret.isEmpty() && QDir::isRelativePath(ret)) {
QString baseDir;
- if (loc == PrefixPath) {
+ if (loc == QLibraryInfo::PrefixPath) {
baseDir = prefixFromAppDirHelper();
} else {
// we make any other path absolute to the prefix directory
- baseDir = path(PrefixPath);
+ baseDir = path(QLibraryInfo::PrefixPath, usageMode);
}
- ret = QDir::cleanPath(baseDir + QLatin1Char('/') + ret);
+ ret = QDir::cleanPath(baseDir + u'/' + ret);
}
return ret;
}
@@ -637,10 +628,9 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
#if QT_CONFIG(settings)
QScopedPointer<const QSettings> settings(findConfiguration());
if (!settings.isNull()) {
- const QString key = QLatin1String("Platforms")
- + QLatin1Char('/')
+ const QString key = "Platforms/"_L1
+ platformName
- + QLatin1String("Arguments");
+ + "Arguments"_L1;
return settings->value(key).toStringList();
}
#else
@@ -664,7 +654,7 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
\value BinariesPath The path to installed Qt binaries (tools and applications).
\value PluginsPath The path to installed Qt plugins.
\value QmlImportsPath The path to installed QML extensions to import.
- \value Qml2ImportsPath The path to installed QML extensions to import.
+ \value Qml2ImportsPath This value is deprecated. Use QmlImportsPath instead.
\value ArchDataPath The path to general architecture-dependent Qt data.
\value DataPath The path to general architecture-independent Qt data.
\value TranslationsPath The path to translation information for Qt strings.
@@ -680,34 +670,103 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
\deprecated Use LibraryPath with QLibraryInfo::path() instead.
*/
+/*!
+ \macro QT_VERSION_STR
+ \relates <QtVersion>
+
+ This macro expands to a string that specifies Qt's version number (for
+ example, "6.1.2"). This is the version with which the application is
+ compiled. This may be a different version than the version the application
+ will find itself using at \e runtime.
+
+ \sa qVersion(), QT_VERSION
+*/
+
+/*!
+ \relates <QtVersion>
+
+ Returns the version number of Qt at runtime as a string (for example,
+ "6.1.2"). This is the version of the Qt library in use at \e runtime,
+ which need not be the version the application was \e compiled with.
+
+ \sa QT_VERSION_STR, QLibraryInfo::version()
+*/
+
+const char *qVersion() noexcept
+{
+ return QT_VERSION_STR;
+}
+
+#if QT_DEPRECATED_SINCE(6, 9)
+
+bool qSharedBuild() noexcept
+{
+ return QLibraryInfo::isSharedBuild();
+}
+
+#endif // QT_DEPRECATED_SINCE(6, 9)
+
QT_END_NAMESPACE
#if defined(Q_CC_GNU) && defined(ELF_INTERPRETER)
+# include <elf.h>
# include <stdio.h>
# include <stdlib.h>
#include "private/qcoreapplication_p.h"
+QT_WARNING_DISABLE_GCC("-Wformat-overflow")
QT_WARNING_DISABLE_GCC("-Wattributes")
QT_WARNING_DISABLE_CLANG("-Wattributes")
QT_WARNING_DISABLE_INTEL(2621)
+# if defined(Q_OS_LINUX)
+# include "minimum-linux_p.h"
+# endif
+# ifdef QT_ELF_NOTE_OS_TYPE
+struct ElfNoteAbiTag
+{
+ static_assert(sizeof(Elf32_Nhdr) == sizeof(Elf64_Nhdr),
+ "The size of an ELF note is wrong (should be 12 bytes)");
+ struct Payload {
+ Elf32_Word ostype = QT_ELF_NOTE_OS_TYPE;
+ Elf32_Word major = QT_ELF_NOTE_OS_MAJOR;
+ Elf32_Word minor = QT_ELF_NOTE_OS_MINOR;
+# ifdef QT_ELF_NOTE_OS_PATCH
+ Elf32_Word patch = QT_ELF_NOTE_OS_PATCH;
+# endif
+ };
+
+ Elf32_Nhdr header = {
+ .n_namesz = sizeof(name),
+ .n_descsz = sizeof(Payload),
+ .n_type = NT_GNU_ABI_TAG
+ };
+ char name[sizeof ELF_NOTE_GNU] = ELF_NOTE_GNU; // yes, include the null terminator
+ Payload payload = {};
+};
+__attribute__((section(".note.ABI-tag"), aligned(4), used))
+extern constexpr ElfNoteAbiTag QT_MANGLE_NAMESPACE(qt_abi_tag) = {};
+# endif
+
extern const char qt_core_interpreter[] __attribute__((section(".interp")))
= ELF_INTERPRETER;
extern "C" void qt_core_boilerplate() __attribute__((force_align_arg_pointer));
void qt_core_boilerplate()
{
- printf("This is the QtCore library version " QT_BUILD_STR "\n"
- "Copyright (C) 2016 The Qt Company Ltd.\n"
- "Contact: http://www.qt.io/licensing/\n"
+ printf("This is the QtCore library version %s\n"
+ "%s\n"
+ "Contact: https://www.qt.io/licensing/\n"
"\n"
"Installation prefix: %s\n"
"Library path: %s\n"
"Plugin path: %s\n",
- qt_configure_prefix_path_str + 12,
- qt_configure_strs + qt_configure_str_offsets[QT_PREPEND_NAMESPACE(QLibraryInfo)::LibrariesPath - 1],
- qt_configure_strs + qt_configure_str_offsets[QT_PREPEND_NAMESPACE(QLibraryInfo)::PluginsPath - 1]);
+ QT_PREPEND_NAMESPACE(qt_build_string)(),
+ QT_COPYRIGHT,
+ QT_CONFIGURE_PREFIX_PATH,
+ qt_configure_strs[QT_PREPEND_NAMESPACE(QLibraryInfo)::LibrariesPath - 1],
+ qt_configure_strs[QT_PREPEND_NAMESPACE(QLibraryInfo)::PluginsPath - 1]);
QT_PREPEND_NAMESPACE(qDumpCPUFeatures)();
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index a7d44768c8..d4e8f8b050 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLIBRARYINFO_H
#define QLIBRARYINFO_H
@@ -51,7 +15,8 @@ class Q_CORE_EXPORT QLibraryInfo
public:
static const char *build() noexcept;
- static bool isDebugBuild();
+ [[nodiscard]] static bool isDebugBuild() noexcept Q_DECL_CONST_FUNCTION;
+ [[nodiscard]] static bool isSharedBuild() noexcept Q_DECL_CONST_FUNCTION;
#ifndef QT_BOOTSTRAPPED
static QVersionNumber version() noexcept Q_DECL_CONST_FUNCTION;
@@ -89,6 +54,13 @@ private:
QLibraryInfo();
};
+#if QT_DEPRECATED_SINCE(6, 9)
+
+QT_DEPRECATED_VERSION_X_6_9("Use QLibraryInfo::isSharedBuild() instead.")
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qSharedBuild() noexcept;
+
+#endif
+
QT_END_NAMESPACE
#endif // QLIBRARYINFO_H
diff --git a/src/corelib/global/qlibraryinfo_p.h b/src/corelib/global/qlibraryinfo_p.h
index a0900f010b..4b471b932e 100644
--- a/src/corelib/global/qlibraryinfo_p.h
+++ b/src/corelib/global/qlibraryinfo_p.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLIBRARYINFO_P_H
#define QLIBRARYINFO_P_H
@@ -53,6 +17,7 @@
//
#include "QtCore/qlibraryinfo.h"
+#include "QtCore/private/qglobal_p.h"
#if QT_CONFIG(settings)
# include "QtCore/qsettings.h"
@@ -67,10 +32,24 @@ public:
#if QT_CONFIG(settings)
static QSettings *configuration();
static void reload();
- static QString qtconfManualPath;
+ static void setQtconfManualPath(const QString *qtconfManualPath);
#endif
- static void keyAndDefault(QLibraryInfo::LibraryPath loc, QString *key,
- QString *value);
+
+ struct LocationInfo
+ {
+ QString key;
+ QString defaultValue;
+ QString fallbackKey;
+ };
+
+ static LocationInfo locationInfo(QLibraryInfo::LibraryPath loc);
+
+ enum UsageMode {
+ RegularUsage,
+ UsedFromQtBinDir
+ };
+
+ static QString path(QLibraryInfo::LibraryPath p, UsageMode usageMode = RegularUsage);
};
QT_END_NAMESPACE
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 9bb15d21be..a9daedc70f 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1,43 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qglobal_p.h"
#include "qlogging.h"
@@ -59,7 +23,6 @@
#include "qthread.h"
#include "private/qloggingregistry_p.h"
#include "private/qcoreapplication_p.h"
-#include "private/qsimd_p.h"
#include <qtcore_tracepoints_p.h>
#endif
#ifdef Q_OS_WIN
@@ -107,14 +70,14 @@ extern char *__progname;
#endif
#ifndef QT_BOOTSTRAPPED
-#if QT_CONFIG(regularexpression)
-# ifdef __UCLIBC__
-# if __UCLIBC_HAS_BACKTRACE__
-# define QLOGGING_HAVE_BACKTRACE
-# endif
-# elif (defined(__GLIBC__) && defined(__GLIBCXX__)) || (__has_include(<cxxabi.h>) && __has_include(<execinfo.h>))
-# define QLOGGING_HAVE_BACKTRACE
+#if __has_include(<cxxabi.h>) && QT_CONFIG(backtrace) && QT_CONFIG(regularexpression)
+# include <qregularexpression.h>
+# if QT_CONFIG(dladdr)
+# include <dlfcn.h>
# endif
+# include BACKTRACE_HEADER
+# include <cxxabi.h>
+# define QLOGGING_HAVE_BACKTRACE
#endif
#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || __has_include(<sys/syscall.h>))
@@ -152,12 +115,6 @@ static QT_PREPEND_NAMESPACE(qint64) qt_gettid()
return qintptr(QThread::currentThreadId());
}
#endif
-
-#ifdef QLOGGING_HAVE_BACKTRACE
-# include <qregularexpression.h>
-# include <cxxabi.h>
-# include <execinfo.h>
-#endif
#endif // !QT_BOOTSTRAPPED
#include <cstdlib>
@@ -169,12 +126,51 @@ static QT_PREPEND_NAMESPACE(qint64) qt_gettid()
QT_BEGIN_NAMESPACE
-#if !defined(Q_CC_MSVC)
+using namespace Qt::StringLiterals;
+
+#ifndef QT_BOOTSTRAPPED
+Q_TRACE_POINT(qtcore, qt_message_print, int type, const char *category, const char *function, const char *file, int line, const QString &message);
+#endif
+
+/*!
+ \headerfile <QtLogging>
+ \inmodule QtCore
+ \title Qt Logging Types
+
+ \brief The <QtLogging> header file defines Qt logging types, functions
+ and macros.
+
+ The <QtLogging> header file contains several types, functions and
+ macros for logging.
+
+ The QtMsgType enum identifies the various messages that can be generated
+ and sent to a Qt message handler; QtMessageHandler is a type definition for
+ a pointer to a function with the signature
+ \c {void myMessageHandler(QtMsgType, const QMessageLogContext &, const char *)}.
+ qInstallMessageHandler() function can be used to install the given
+ QtMessageHandler. QMessageLogContext class contains the line, file, and
+ function the message was logged at. This information is created by the
+ QMessageLogger class.
+
+ <QtLogging> also contains functions that generate messages from the
+ given string argument: qDebug(), qInfo(), qWarning(), qCritical(),
+ and qFatal(). These functions call the message handler
+ with the given message.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 4
+*/
+
+template <typename String>
+#if !defined(Q_CC_MSVC_ONLY)
Q_NORETURN
#endif
-static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const QString &message);
+static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, String &&message);
static void qt_message_print(QtMsgType, const QMessageLogContext &context, const QString &message);
-static void qt_message_print(const QString &message);
+static void preformattedMessageHandler(QtMsgType type, const QMessageLogContext &context,
+ const QString &formattedMessage);
+static QString formatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str);
static int checked_var_value(const char *varname)
{
@@ -190,6 +186,17 @@ static int checked_var_value(const char *varname)
return ok ? value : 1;
}
+static bool is_fatal_count_down(QAtomicInt &n)
+{
+ // it's fatal if the current value is exactly 1,
+ // otherwise decrement if it's non-zero
+
+ int v = n.loadRelaxed();
+ while (v != 0 && !n.testAndSetRelaxed(v, v - 1, v))
+ qYieldCpu();
+ return v == 1; // we exited the loop, so either v == 0 or CAS succeeded to set n from v to v-1
+}
+
static bool isFatal(QtMsgType msgType)
{
if (msgType == QtFatalMsg)
@@ -197,28 +204,17 @@ static bool isFatal(QtMsgType msgType)
if (msgType == QtCriticalMsg) {
static QAtomicInt fatalCriticals = checked_var_value("QT_FATAL_CRITICALS");
-
- // it's fatal if the current value is exactly 1,
- // otherwise decrement if it's non-zero
- return fatalCriticals.loadRelaxed() && fatalCriticals.fetchAndAddRelaxed(-1) == 1;
+ return is_fatal_count_down(fatalCriticals);
}
if (msgType == QtWarningMsg || msgType == QtCriticalMsg) {
static QAtomicInt fatalWarnings = checked_var_value("QT_FATAL_WARNINGS");
-
- // it's fatal if the current value is exactly 1,
- // otherwise decrement if it's non-zero
- return fatalWarnings.loadRelaxed() && fatalWarnings.fetchAndAddRelaxed(-1) == 1;
+ return is_fatal_count_down(fatalWarnings);
}
return false;
}
-static bool isDefaultCategory(const char *category)
-{
- return !category || strcmp(category, "default") == 0;
-}
-
/*!
Returns true if writing to \c stderr is supported.
@@ -348,7 +344,7 @@ using namespace QtPrivate;
\sa QMessageLogContext, qDebug(), qInfo(), qWarning(), qCritical(), qFatal()
*/
-#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
+#if defined(Q_CC_MSVC_ONLY) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
static inline void convert_to_wchar_t_elided(wchar_t *d, size_t space, const char *s) noexcept
{
size_t len = qstrlen(s);
@@ -369,14 +365,15 @@ static inline void convert_to_wchar_t_elided(wchar_t *d, size_t space, const cha
\internal
*/
Q_NEVER_INLINE
-static QString qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg, va_list ap)
+static void qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg, va_list ap)
{
QString buf = QString::vasprintf(msg, ap);
qt_message_print(msgType, context, buf);
- return buf;
+
+ if (isFatal(msgType))
+ qt_message_fatal(msgType, context, buf);
}
-#undef qDebug
/*!
Logs a debug message specified with format \a msg. Additional
parameters, specified by \a msg, may be used.
@@ -387,15 +384,10 @@ void QMessageLogger::debug(const char *msg, ...) const
{
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtDebugMsg, context, msg, ap);
+ qt_message(QtDebugMsg, context, msg, ap);
va_end(ap);
-
- if (isFatal(QtDebugMsg))
- qt_message_fatal(QtDebugMsg, context, message);
}
-
-#undef qInfo
/*!
Logs an informational message specified with format \a msg. Additional
parameters, specified by \a msg, may be used.
@@ -407,11 +399,8 @@ void QMessageLogger::info(const char *msg, ...) const
{
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtInfoMsg, context, msg, ap);
+ qt_message(QtInfoMsg, context, msg, ap);
va_end(ap);
-
- if (isFatal(QtInfoMsg))
- qt_message_fatal(QtInfoMsg, context, message);
}
/*!
@@ -422,8 +411,8 @@ void QMessageLogger::info(const char *msg, ...) const
\snippet code/qlogging/qlogging.cpp 2
- A function which this signature is generated by Q_DECLARE_LOGGING_CATEGORY,
- Q_LOGGING_CATEGORY.
+ The \c Q_DECLARE_LOGGING_CATEGORY macro generates a function declaration
+ with this signature, and \c Q_LOGGING_CATEGORY generates its definition.
\since 5.3
*/
@@ -446,11 +435,8 @@ void QMessageLogger::debug(const QLoggingCategory &cat, const char *msg, ...) co
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtDebugMsg, ctxt, msg, ap);
+ qt_message(QtDebugMsg, ctxt, msg, ap);
va_end(ap);
-
- if (isFatal(QtDebugMsg))
- qt_message_fatal(QtDebugMsg, ctxt, message);
}
/*!
@@ -473,11 +459,8 @@ void QMessageLogger::debug(QMessageLogger::CategoryFunction catFunc,
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtDebugMsg, ctxt, msg, ap);
+ qt_message(QtDebugMsg, ctxt, msg, ap);
va_end(ap);
-
- if (isFatal(QtDebugMsg))
- qt_message_fatal(QtDebugMsg, ctxt, message);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -557,11 +540,8 @@ void QMessageLogger::info(const QLoggingCategory &cat, const char *msg, ...) con
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtInfoMsg, ctxt, msg, ap);
+ qt_message(QtInfoMsg, ctxt, msg, ap);
va_end(ap);
-
- if (isFatal(QtInfoMsg))
- qt_message_fatal(QtInfoMsg, ctxt, message);
}
/*!
@@ -584,11 +564,8 @@ void QMessageLogger::info(QMessageLogger::CategoryFunction catFunc,
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtInfoMsg, ctxt, msg, ap);
+ qt_message(QtInfoMsg, ctxt, msg, ap);
va_end(ap);
-
- if (isFatal(QtInfoMsg))
- qt_message_fatal(QtInfoMsg, ctxt, message);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -639,7 +616,6 @@ QDebug QMessageLogger::info(QMessageLogger::CategoryFunction catFunc) const
#endif
-#undef qWarning
/*!
Logs a warning message specified with format \a msg. Additional
parameters, specified by \a msg, may be used.
@@ -650,11 +626,8 @@ void QMessageLogger::warning(const char *msg, ...) const
{
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtWarningMsg, context, msg, ap);
+ qt_message(QtWarningMsg, context, msg, ap);
va_end(ap);
-
- if (isFatal(QtWarningMsg))
- qt_message_fatal(QtWarningMsg, context, message);
}
/*!
@@ -675,11 +648,8 @@ void QMessageLogger::warning(const QLoggingCategory &cat, const char *msg, ...)
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtWarningMsg, ctxt, msg, ap);
+ qt_message(QtWarningMsg, ctxt, msg, ap);
va_end(ap);
-
- if (isFatal(QtWarningMsg))
- qt_message_fatal(QtWarningMsg, ctxt, message);
}
/*!
@@ -702,11 +672,8 @@ void QMessageLogger::warning(QMessageLogger::CategoryFunction catFunc,
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtWarningMsg, ctxt, msg, ap);
+ qt_message(QtWarningMsg, ctxt, msg, ap);
va_end(ap);
-
- if (isFatal(QtWarningMsg))
- qt_message_fatal(QtWarningMsg, ctxt, message);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -754,8 +721,6 @@ QDebug QMessageLogger::warning(QMessageLogger::CategoryFunction catFunc) const
#endif
-#undef qCritical
-
/*!
Logs a critical message specified with format \a msg. Additional
parameters, specified by \a msg, may be used.
@@ -766,11 +731,8 @@ void QMessageLogger::critical(const char *msg, ...) const
{
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtCriticalMsg, context, msg, ap);
+ qt_message(QtCriticalMsg, context, msg, ap);
va_end(ap);
-
- if (isFatal(QtCriticalMsg))
- qt_message_fatal(QtCriticalMsg, context, message);
}
/*!
@@ -791,11 +753,8 @@ void QMessageLogger::critical(const QLoggingCategory &cat, const char *msg, ...)
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtCriticalMsg, ctxt, msg, ap);
+ qt_message(QtCriticalMsg, ctxt, msg, ap);
va_end(ap);
-
- if (isFatal(QtCriticalMsg))
- qt_message_fatal(QtCriticalMsg, ctxt, message);
}
/*!
@@ -818,11 +777,8 @@ void QMessageLogger::critical(QMessageLogger::CategoryFunction catFunc,
va_list ap;
va_start(ap, msg); // use variable arg list
- const QString message = qt_message(QtCriticalMsg, ctxt, msg, ap);
+ qt_message(QtCriticalMsg, ctxt, msg, ap);
va_end(ap);
-
- if (isFatal(QtCriticalMsg))
- qt_message_fatal(QtCriticalMsg, ctxt, message);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -871,7 +827,55 @@ QDebug QMessageLogger::critical(QMessageLogger::CategoryFunction catFunc) const
#endif
-#undef qFatal
+/*!
+ Logs a fatal message specified with format \a msg for the context \a cat.
+ Additional parameters, specified by \a msg, may be used.
+
+ \since 6.5
+ \sa qCFatal()
+*/
+void QMessageLogger::fatal(const QLoggingCategory &cat, const char *msg, ...) const noexcept
+{
+ QMessageLogContext ctxt;
+ ctxt.copyContextFrom(context);
+ ctxt.category = cat.categoryName();
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, ctxt, msg, ap));
+ va_end(ap);
+
+#ifndef Q_CC_MSVC_ONLY
+ Q_UNREACHABLE();
+#endif
+}
+
+/*!
+ Logs a fatal message specified with format \a msg for the context returned
+ by \a catFunc. Additional parameters, specified by \a msg, may be used.
+
+ \since 6.5
+ \sa qCFatal()
+*/
+void QMessageLogger::fatal(QMessageLogger::CategoryFunction catFunc,
+ const char *msg, ...) const noexcept
+{
+ const QLoggingCategory &cat = (*catFunc)();
+
+ QMessageLogContext ctxt;
+ ctxt.copyContextFrom(context);
+ ctxt.category = cat.categoryName();
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, ctxt, msg, ap));
+ va_end(ap);
+
+#ifndef Q_CC_MSVC_ONLY
+ Q_UNREACHABLE();
+#endif
+}
+
/*!
Logs a fatal message specified with format \a msg. Additional
parameters, specified by \a msg, may be used.
@@ -880,14 +884,65 @@ QDebug QMessageLogger::critical(QMessageLogger::CategoryFunction catFunc) const
*/
void QMessageLogger::fatal(const char *msg, ...) const noexcept
{
- QString message;
-
va_list ap;
va_start(ap, msg); // use variable arg list
- QT_TERMINATE_ON_EXCEPTION(message = qt_message(QtFatalMsg, context, msg, ap));
+ QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, context, msg, ap));
va_end(ap);
- qt_message_fatal(QtFatalMsg, context, message);
+#ifndef Q_CC_MSVC_ONLY
+ Q_UNREACHABLE();
+#endif
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+/*!
+ Logs a fatal message using a QDebug stream.
+
+ \since 6.5
+
+ \sa qFatal(), QDebug
+*/
+QDebug QMessageLogger::fatal() const
+{
+ QDebug dbg = QDebug(QtFatalMsg);
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.copyContextFrom(context);
+ return dbg;
+}
+
+/*!
+ Logs a fatal message into category \a cat using a QDebug stream.
+
+ \since 6.5
+ \sa qCFatal(), QDebug
+*/
+QDebug QMessageLogger::fatal(const QLoggingCategory &cat) const
+{
+ QDebug dbg = QDebug(QtFatalMsg);
+
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.copyContextFrom(context);
+ ctxt.category = cat.categoryName();
+
+ return dbg;
+}
+
+/*!
+ Logs a fatal message into category returned by \a catFunc using a QDebug stream.
+
+ \since 6.5
+ \sa qCFatal(), QDebug
+*/
+QDebug QMessageLogger::fatal(QMessageLogger::CategoryFunction catFunc) const
+{
+ return fatal((*catFunc)());
+}
+#endif // QT_NO_DEBUG_STREAM
+
+#if !defined(QT_BOOTSTRAPPED)
+static bool isDefaultCategory(const char *category)
+{
+ return !category || strcmp(category, "default") == 0;
}
/*!
@@ -902,15 +957,20 @@ Q_AUTOTEST_EXPORT QByteArray qCleanupFuncinfo(QByteArray info)
if (info.isEmpty())
return info;
- int pos;
+ qsizetype pos;
// Skip trailing [with XXX] for templates (gcc), but make
// sure to not affect Objective-C message names.
pos = info.size() - 1;
if (info.endsWith(']') && !(info.startsWith('+') || info.startsWith('-'))) {
while (--pos) {
- if (info.at(pos) == '[')
- info.truncate(pos);
+ if (info.at(pos) == '[') {
+ info.truncate(pos);
+ break;
+ }
+ }
+ if (info.endsWith(' ')) {
+ info.chop(1);
}
}
@@ -924,14 +984,21 @@ Q_AUTOTEST_EXPORT QByteArray qCleanupFuncinfo(QByteArray info)
// canonize operator names
info.replace("operator ", "operator");
+ pos = -1;
// remove argument list
forever {
int parencount = 0;
- pos = info.lastIndexOf(')');
+ pos = info.lastIndexOf(')', pos);
if (pos == -1) {
// Don't know how to parse this function name
return info;
}
+ if (info.indexOf('>', pos) != -1
+ || info.indexOf(':', pos) != -1) {
+ // that wasn't the function argument list.
+ --pos;
+ continue;
+ }
// find the beginning of the argument list
--pos;
@@ -949,7 +1016,7 @@ Q_AUTOTEST_EXPORT QByteArray qCleanupFuncinfo(QByteArray info)
info.truncate(++pos);
if (info.at(pos - 1) == ')') {
- if (info.indexOf(operator_call) == pos - (int)strlen(operator_call))
+ if (info.indexOf(operator_call) == pos - qsizetype(strlen(operator_call)))
break;
// this function returns a pointer to a function
@@ -972,19 +1039,19 @@ Q_AUTOTEST_EXPORT QByteArray qCleanupFuncinfo(QByteArray info)
if (pos > -1) {
switch (info.at(pos)) {
case ')':
- if (info.indexOf(operator_call) == pos - (int)strlen(operator_call) + 1)
+ if (info.indexOf(operator_call) == pos - qsizetype(strlen(operator_call)) + 1)
pos -= 2;
break;
case '<':
- if (info.indexOf(operator_lessThan) == pos - (int)strlen(operator_lessThan) + 1)
+ if (info.indexOf(operator_lessThan) == pos - qsizetype(strlen(operator_lessThan)) + 1)
--pos;
break;
case '>':
- if (info.indexOf(operator_greaterThan) == pos - (int)strlen(operator_greaterThan) + 1)
+ if (info.indexOf(operator_greaterThan) == pos - qsizetype(strlen(operator_greaterThan)) + 1)
--pos;
break;
case '=': {
- int operatorLength = (int)strlen(operator_lessThanEqual);
+ auto operatorLength = qsizetype(strlen(operator_lessThanEqual));
if (info.indexOf(operator_lessThanEqual) == pos - operatorLength + 1)
pos -= 2;
else if (info.indexOf(operator_greaterThanEqual) == pos - operatorLength + 1)
@@ -1028,7 +1095,7 @@ Q_AUTOTEST_EXPORT QByteArray qCleanupFuncinfo(QByteArray info)
break;
// find the matching close
- int end = pos;
+ qsizetype end = pos;
templatecount = 1;
--pos;
while (pos && templatecount) {
@@ -1090,7 +1157,7 @@ struct QMessagePattern
QString backtraceSeparator;
int backtraceDepth;
};
- QList<BacktraceParams> backtraceArgs; // backtrace argumens in sequence of %{backtrace
+ QList<BacktraceParams> backtraceArgs; // backtrace arguments in sequence of %{backtrace
#endif
bool fromEnvironment;
@@ -1100,7 +1167,7 @@ struct QMessagePattern
Q_DECLARE_TYPEINFO(QMessagePattern::BacktraceParams, Q_RELOCATABLE_TYPE);
#endif
-QBasicMutex QMessagePattern::mutex;
+Q_CONSTINIT QBasicMutex QMessagePattern::mutex;
QMessagePattern::QMessagePattern()
{
@@ -1109,7 +1176,7 @@ QMessagePattern::QMessagePattern()
#endif
const QString envPattern = QString::fromLocal8Bit(qgetenv("QT_MESSAGE_PATTERN"));
if (envPattern.isEmpty()) {
- setPattern(QLatin1String(defaultPattern));
+ setPattern(QLatin1StringView(defaultPattern));
fromEnvironment = false;
} else {
setPattern(envPattern);
@@ -1132,10 +1199,9 @@ void QMessagePattern::setPattern(const QString &pattern)
bool inPlaceholder = false;
for (int i = 0; i < pattern.size(); ++i) {
const QChar c = pattern.at(i);
- if ((c == QLatin1Char('%'))
- && !inPlaceholder) {
+ if (c == u'%' && !inPlaceholder) {
if ((i + 1 < pattern.size())
- && pattern.at(i + 1) == QLatin1Char('{')) {
+ && pattern.at(i + 1) == u'{') {
// beginning of placeholder
if (!lexeme.isEmpty()) {
lexemes.append(lexeme);
@@ -1147,7 +1213,7 @@ void QMessagePattern::setPattern(const QString &pattern)
lexeme.append(c);
- if ((c == QLatin1Char('}') && inPlaceholder)) {
+ if (c == u'}' && inPlaceholder) {
// end of placeholder
lexemes.append(lexeme);
lexeme.clear();
@@ -1168,37 +1234,36 @@ void QMessagePattern::setPattern(const QString &pattern)
for (int i = 0; i < lexemes.size(); ++i) {
const QString lexeme = lexemes.at(i);
- if (lexeme.startsWith(QLatin1String("%{"))
- && lexeme.endsWith(QLatin1Char('}'))) {
+ if (lexeme.startsWith("%{"_L1) && lexeme.endsWith(u'}')) {
// placeholder
- if (lexeme == QLatin1String(typeTokenC)) {
+ if (lexeme == QLatin1StringView(typeTokenC)) {
tokens[i] = typeTokenC;
- } else if (lexeme == QLatin1String(categoryTokenC))
+ } else if (lexeme == QLatin1StringView(categoryTokenC))
tokens[i] = categoryTokenC;
- else if (lexeme == QLatin1String(messageTokenC))
+ else if (lexeme == QLatin1StringView(messageTokenC))
tokens[i] = messageTokenC;
- else if (lexeme == QLatin1String(fileTokenC))
+ else if (lexeme == QLatin1StringView(fileTokenC))
tokens[i] = fileTokenC;
- else if (lexeme == QLatin1String(lineTokenC))
+ else if (lexeme == QLatin1StringView(lineTokenC))
tokens[i] = lineTokenC;
- else if (lexeme == QLatin1String(functionTokenC))
+ else if (lexeme == QLatin1StringView(functionTokenC))
tokens[i] = functionTokenC;
- else if (lexeme == QLatin1String(pidTokenC))
+ else if (lexeme == QLatin1StringView(pidTokenC))
tokens[i] = pidTokenC;
- else if (lexeme == QLatin1String(appnameTokenC))
+ else if (lexeme == QLatin1StringView(appnameTokenC))
tokens[i] = appnameTokenC;
- else if (lexeme == QLatin1String(threadidTokenC))
+ else if (lexeme == QLatin1StringView(threadidTokenC))
tokens[i] = threadidTokenC;
- else if (lexeme == QLatin1String(qthreadptrTokenC))
+ else if (lexeme == QLatin1StringView(qthreadptrTokenC))
tokens[i] = qthreadptrTokenC;
- else if (lexeme.startsWith(QLatin1String(timeTokenC))) {
+ else if (lexeme.startsWith(QLatin1StringView(timeTokenC))) {
tokens[i] = timeTokenC;
- int spaceIdx = lexeme.indexOf(QChar::fromLatin1(' '));
+ qsizetype spaceIdx = lexeme.indexOf(QChar::fromLatin1(' '));
if (spaceIdx > 0)
- timeArgs.append(lexeme.mid(spaceIdx + 1, lexeme.length() - spaceIdx - 2));
+ timeArgs.append(lexeme.mid(spaceIdx + 1, lexeme.size() - spaceIdx - 2));
else
timeArgs.append(QString());
- } else if (lexeme.startsWith(QLatin1String(backtraceTokenC))) {
+ } else if (lexeme.startsWith(QLatin1StringView(backtraceTokenC))) {
#ifdef QLOGGING_HAVE_BACKTRACE
tokens[i] = backtraceTokenC;
QString backtraceSeparator = QStringLiteral("|");
@@ -1209,7 +1274,7 @@ void QMessagePattern::setPattern(const QString &pattern)
if (m.hasMatch()) {
int depth = m.capturedView(1).toInt();
if (depth <= 0)
- error += QLatin1String("QT_MESSAGE_PATTERN: %{backtrace} depth must be a number greater than 0\n");
+ error += "QT_MESSAGE_PATTERN: %{backtrace} depth must be a number greater than 0\n"_L1;
else
backtraceDepth = depth;
}
@@ -1221,13 +1286,13 @@ void QMessagePattern::setPattern(const QString &pattern)
backtraceParams.backtraceSeparator = backtraceSeparator;
backtraceArgs.append(backtraceParams);
#else
- error += QLatin1String("QT_MESSAGE_PATTERN: %{backtrace} is not supported by this Qt build\n");
+ error += "QT_MESSAGE_PATTERN: %{backtrace} is not supported by this Qt build\n"_L1;
tokens[i] = "";
#endif
}
#define IF_TOKEN(LEVEL) \
- else if (lexeme == QLatin1String(LEVEL)) { \
+ else if (lexeme == QLatin1StringView(LEVEL)) { \
if (inIf) \
nestedIfError = true; \
tokens[i] = LEVEL; \
@@ -1240,50 +1305,135 @@ void QMessagePattern::setPattern(const QString &pattern)
IF_TOKEN(ifCriticalTokenC)
IF_TOKEN(ifFatalTokenC)
#undef IF_TOKEN
- else if (lexeme == QLatin1String(endifTokenC)) {
+ else if (lexeme == QLatin1StringView(endifTokenC)) {
tokens[i] = endifTokenC;
if (!inIf && !nestedIfError)
- error += QLatin1String("QT_MESSAGE_PATTERN: %{endif} without an %{if-*}\n");
+ error += "QT_MESSAGE_PATTERN: %{endif} without an %{if-*}\n"_L1;
inIf = false;
} else {
tokens[i] = emptyTokenC;
- error += QStringLiteral("QT_MESSAGE_PATTERN: Unknown placeholder %1\n")
- .arg(lexeme);
+ error += "QT_MESSAGE_PATTERN: Unknown placeholder "_L1 + lexeme + '\n'_L1;
}
} else {
- char *literal = new char[lexeme.size() + 1];
- strncpy(literal, lexeme.toLatin1().constData(), lexeme.size());
- literal[lexeme.size()] = '\0';
- literalsVar.emplace_back(literal);
- tokens[i] = literal;
+ using UP = std::unique_ptr<char[]>;
+ tokens[i] = literalsVar.emplace_back(UP(qstrdup(lexeme.toLatin1().constData()))).get();
}
}
if (nestedIfError)
- error += QLatin1String("QT_MESSAGE_PATTERN: %{if-*} cannot be nested\n");
+ error += "QT_MESSAGE_PATTERN: %{if-*} cannot be nested\n"_L1;
else if (inIf)
- error += QLatin1String("QT_MESSAGE_PATTERN: missing %{endif}\n");
+ error += "QT_MESSAGE_PATTERN: missing %{endif}\n"_L1;
- if (!error.isEmpty())
- qt_message_print(error);
+ if (!error.isEmpty()) {
+ // remove the last '\n' because the sinks deal with that on their own
+ error.chop(1);
+
+ QMessageLogContext ctx(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE,
+ "QMessagePattern::setPattern", nullptr);
+ preformattedMessageHandler(QtWarningMsg, ctx, error);
+ }
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)
+#if defined(QLOGGING_HAVE_BACKTRACE)
// make sure the function has "Message" in the name so the function is removed
+/*
+ A typical backtrace in debug mode looks like:
+ #0 backtraceFramesForLogMessage (frameCount=0) at qlogging.cpp:1398
+ #1 formatBacktraceForLogMessage (backtraceParams=..., function=0x5555555580b0 "virtual void MyClass::myFunction(int)") at qlogging.cpp:1525
+ #2 formatLogMessage (type=QtDebugMsg, context=..., str=...) at qlogging.cpp:1642
+ #3 qDefaultMessageHandler (type=QtDebugMsg, context=..., message=...) at qlogging.cpp:1997
+ #4 qt_message_print (msgType=QtDebugMsg, context=..., message=...) at qlogging.cpp:2043
+ #5 qt_message_output (msgType=QtDebugMsg, context=..., message=...) at qlogging.cpp:2082
+ #6 QDebug::~QDebug (this=0x7fffffffd9b8, __in_chrg=<optimized out>) at qdebug.cpp:166
+*/
+static constexpr int TypicalBacktraceFrameCount = 7;
-#if ((defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || __has_attribute(optimize)) \
- && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
+# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
// force skipping the frame pointer, to save the backtrace() function some work
-__attribute__((optimize("omit-frame-pointer")))
-#endif
+# pragma GCC push_options
+# pragma GCC optimize ("omit-frame-pointer")
+# endif
+
static QStringList backtraceFramesForLogMessage(int frameCount)
{
+ struct DecodedFrame {
+ QString library;
+ QString function;
+ };
+
QStringList result;
if (frameCount == 0)
return result;
+ QVarLengthArray<void *, 32> buffer(TypicalBacktraceFrameCount + frameCount);
+ int n = backtrace(buffer.data(), buffer.size());
+ if (n <= 0)
+ return result;
+ buffer.resize(n);
+
+ auto shouldSkipFrame = [&result](const auto &library, const auto &function) {
+ if (!result.isEmpty() || !library.contains("Qt6Core"_L1))
+ return false;
+ if (function.isEmpty())
+ return true;
+ if (function.contains("6QDebug"_L1))
+ return true;
+ if (function.contains("Message"_L1) || function.contains("_message"_L1))
+ return true;
+ return false;
+ };
+
+ auto demangled = [](auto &function) -> QString {
+ if (!function.startsWith("_Z"_L1))
+ return function;
+
+ // we optimize for the case where __cxa_demangle succeeds
+ auto fn = [&]() {
+ if constexpr (sizeof(function.at(0)) == 1)
+ return function.data(); // -> const char *
+ else
+ return std::move(function).toUtf8(); // -> QByteArray
+ }();
+ QScopedPointer<char, QScopedPointerPodDeleter> demangled;
+ demangled.reset(abi::__cxa_demangle(fn, nullptr, nullptr, nullptr));
+
+ if (demangled)
+ return QString::fromUtf8(qCleanupFuncinfo(demangled.data()));
+ else
+ return QString::fromUtf8(fn); // restore
+ };
+
+# if QT_CONFIG(dladdr)
+ // use dladdr() instead of backtrace_symbols()
+ QString cachedLibrary;
+ const char *cachedFname = nullptr;
+ auto decodeFrame = [&](void *addr) -> DecodedFrame {
+ Dl_info info;
+ if (!dladdr(addr, &info))
+ return {};
+
+ // These are actually UTF-8, so we'll correct below
+ QLatin1StringView fn(info.dli_sname);
+ QLatin1StringView lib;
+ if (const char *lastSlash = strrchr(info.dli_fname, '/'))
+ lib = QLatin1StringView(lastSlash + 1);
+ else
+ lib = QLatin1StringView(info.dli_fname);
+
+ if (shouldSkipFrame(lib, fn))
+ return {};
+
+ QString function = demangled(fn);
+ if (lib.data() != cachedFname) {
+ cachedFname = lib.data();
+ cachedLibrary = QString::fromUtf8(cachedFname, lib.size());
+ }
+ return { cachedLibrary, function };
+ };
+# else
// The results of backtrace_symbols looks like this:
// /lib/libc.so.6(__libc_start_main+0xf3) [0x4a937413]
// The offset and function name are optional.
@@ -1291,46 +1441,40 @@ static QStringList backtraceFramesForLogMessage(int frameCount)
// This code is protected by QMessagePattern::mutex so it is thread safe on all compilers
static const QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"));
- QVarLengthArray<void *, 32> buffer(8 + frameCount);
- int n = backtrace(buffer.data(), buffer.size());
- if (n > 0) {
- int numberPrinted = 0;
- for (int i = 0; i < n && numberPrinted < frameCount; ++i) {
- QScopedPointer<char*, QScopedPointerPodDeleter> strings(backtrace_symbols(buffer.data() + i, 1));
- QString trace = QString::fromLatin1(strings.data()[0]);
- QRegularExpressionMatch m = rx.match(trace);
- if (m.hasMatch()) {
- QString library = m.captured(1);
- QString function = m.captured(2);
-
- // skip the trace from QtCore that are because of the qDebug itself
- if (!numberPrinted && library.contains(QLatin1String("Qt6Core"))
- && (function.isEmpty() || function.contains(QLatin1String("Message"), Qt::CaseInsensitive)
- || function.contains(QLatin1String("QDebug")))) {
- continue;
- }
+ auto decodeFrame = [&](void *&addr) -> DecodedFrame {
+ QScopedPointer<char*, QScopedPointerPodDeleter> strings(backtrace_symbols(&addr, 1));
+ QString trace = QString::fromUtf8(strings.data()[0]);
+ QRegularExpressionMatch m = rx.match(trace);
+ if (!m.hasMatch())
+ return {};
- if (function.startsWith(QLatin1String("_Z"))) {
- QScopedPointer<char, QScopedPointerPodDeleter> demangled(
- abi::__cxa_demangle(function.toUtf8(), nullptr, nullptr, nullptr));
- if (demangled)
- function = QString::fromUtf8(qCleanupFuncinfo(demangled.data()));
- }
+ QString library = m.captured(1);
+ QString function = m.captured(2);
- if (function.isEmpty()) {
- result.append(QLatin1Char('?') + library + QLatin1Char('?'));
- } else {
- result.append(function);
- }
- } else {
- if (numberPrinted == 0) {
- // innermost, unknown frames are usually the logging framework itself
- continue;
- }
+ // skip the trace from QtCore that are because of the qDebug itself
+ if (shouldSkipFrame(library, function))
+ return {};
+
+ function = demangled(function);
+ return { library, function };
+ };
+# endif
+
+ for (void *&addr : buffer) {
+ DecodedFrame frame = decodeFrame(addr);
+ if (!frame.library.isEmpty()) {
+ if (frame.function.isEmpty())
+ result.append(u'?' + frame.library + u'?');
+ else
+ result.append(frame.function);
+ } else {
+ // innermost, unknown frames are usually the logging framework itself
+ if (!result.isEmpty())
result.append(QStringLiteral("???"));
- }
- numberPrinted++;
}
+
+ if (result.size() == frameCount)
+ break;
}
return result;
}
@@ -1346,17 +1490,21 @@ static QString formatBacktraceForLogMessage(const QMessagePattern::BacktracePara
return QString();
// if the first frame is unknown, replace it with the context function
- if (function && frames.at(0).startsWith(QLatin1Char('?')))
+ if (function && frames.at(0).startsWith(u'?'))
frames[0] = QString::fromUtf8(qCleanupFuncinfo(function));
return frames.join(backtraceSeparator);
}
+
+# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+# pragma GCC pop_options
+# endif
#endif // QLOGGING_HAVE_BACKTRACE && !QT_BOOTSTRAPPED
Q_GLOBAL_STATIC(QMessagePattern, qMessagePattern)
/*!
- \relates <QtGlobal>
+ \relates <QtLogging>
\since 5.4
Generates a formatted string out of the \a type, \a context, \a str arguments.
@@ -1371,6 +1519,14 @@ Q_GLOBAL_STATIC(QMessagePattern, qMessagePattern)
*/
QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
{
+ return formatLogMessage(type, context, str);
+}
+
+// Separate function so the default message handler can bypass the public,
+// exported function above. Static functions can't get added to the dynamic
+// symbol tables, so they never show up in backtrace_symbols() or equivalent.
+static QString formatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
+{
QString message;
const auto locker = qt_scoped_lock(QMessagePattern::mutex);
@@ -1384,12 +1540,10 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
bool skip = false;
-#ifndef QT_BOOTSTRAPPED
int timeArgsIdx = 0;
#ifdef QLOGGING_HAVE_BACKTRACE
int backtraceArgsIdx = 0;
#endif
-#endif
// we do not convert file, function, line literals to local encoding due to overhead
for (int i = 0; pattern->tokens[i]; ++i) {
@@ -1399,42 +1553,39 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
} else if (skip) {
// we skip adding messages, but we have to iterate over
// timeArgsIdx and backtraceArgsIdx anyway
-#ifndef QT_BOOTSTRAPPED
if (token == timeTokenC)
timeArgsIdx++;
#ifdef QLOGGING_HAVE_BACKTRACE
else if (token == backtraceTokenC)
backtraceArgsIdx++;
#endif
-#endif
} else if (token == messageTokenC) {
message.append(str);
} else if (token == categoryTokenC) {
#ifndef Q_OS_ANDROID
// Don't add the category to the message on Android
- message.append(QLatin1String(context.category));
+ message.append(QLatin1StringView(context.category));
#endif
} else if (token == typeTokenC) {
switch (type) {
- case QtDebugMsg: message.append(QLatin1String("debug")); break;
- case QtInfoMsg: message.append(QLatin1String("info")); break;
- case QtWarningMsg: message.append(QLatin1String("warning")); break;
- case QtCriticalMsg:message.append(QLatin1String("critical")); break;
- case QtFatalMsg: message.append(QLatin1String("fatal")); break;
+ case QtDebugMsg: message.append("debug"_L1); break;
+ case QtInfoMsg: message.append("info"_L1); break;
+ case QtWarningMsg: message.append("warning"_L1); break;
+ case QtCriticalMsg:message.append("critical"_L1); break;
+ case QtFatalMsg: message.append("fatal"_L1); break;
}
} else if (token == fileTokenC) {
if (context.file)
- message.append(QLatin1String(context.file));
+ message.append(QLatin1StringView(context.file));
else
- message.append(QLatin1String("unknown"));
+ message.append("unknown"_L1);
} else if (token == lineTokenC) {
message.append(QString::number(context.line));
} else if (token == functionTokenC) {
if (context.function)
message.append(QString::fromLatin1(qCleanupFuncinfo(context.function)));
else
- message.append(QLatin1String("unknown"));
-#ifndef QT_BOOTSTRAPPED
+ message.append("unknown"_L1);
} else if (token == pidTokenC) {
message.append(QString::number(QCoreApplication::applicationPid()));
} else if (token == appnameTokenC) {
@@ -1443,7 +1594,7 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
// print the TID as decimal
message.append(QString::number(qt_gettid()));
} else if (token == qthreadptrTokenC) {
- message.append(QLatin1String("0x"));
+ message.append("0x"_L1);
message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16));
#ifdef QLOGGING_HAVE_BACKTRACE
} else if (token == backtraceTokenC) {
@@ -1454,13 +1605,13 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
} else if (token == timeTokenC) {
QString timeFormat = pattern->timeArgs.at(timeArgsIdx);
timeArgsIdx++;
- if (timeFormat == QLatin1String("process")) {
- quint64 ms = pattern->timer.elapsed();
- message.append(QString::asprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000)));
- } else if (timeFormat == QLatin1String("boot")) {
+ if (timeFormat == "process"_L1) {
+ quint64 ms = pattern->timer.elapsed();
+ message.append(QString::asprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000)));
+ } else if (timeFormat == "boot"_L1) {
// just print the milliseconds since the elapsed timer reference
// like the Linux kernel does
- uint ms = QDeadlineTimer::current().deadline();
+ qint64 ms = QDeadlineTimer::current().deadline();
message.append(QString::asprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000)));
#if QT_CONFIG(datestring)
} else if (timeFormat.isEmpty()) {
@@ -1469,7 +1620,6 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
message.append(QDateTime::currentDateTime().toString(timeFormat));
#endif // QT_CONFIG(datestring)
}
-#endif // !QT_BOOTSTRAPPED
} else if (token == ifCategoryTokenC) {
if (isDefaultCategory(context.category))
skip = true;
@@ -1483,21 +1633,29 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
HANDLE_IF_TOKEN(Fatal)
#undef HANDLE_IF_TOKEN
} else {
- message.append(QLatin1String(token));
+ message.append(QLatin1StringView(token));
}
}
return message;
}
+#else // QT_BOOTSTRAPPED
+static QString formatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(context);
+ return str;
+}
+#endif
static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &buf);
// pointer to QtMessageHandler debug handler (with context)
-static QBasicAtomicPointer<void (QtMsgType, const QMessageLogContext &, const QString &)> messageHandler = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
+Q_CONSTINIT static QBasicAtomicPointer<void (QtMsgType, const QMessageLogContext &, const QString &)> messageHandler = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
// ------------------------ Alternate logging sinks -------------------------
#if defined(QT_BOOTSTRAPPED)
- // Boostrapped tools always print to stderr, so no need for alternate sinks
+ // Bootstrapped tools always print to stderr, so no need for alternate sinks
#else
#if QT_CONFIG(slog2)
@@ -1505,13 +1663,14 @@ static QBasicAtomicPointer<void (QtMsgType, const QMessageLogContext &, const QS
#define QT_LOG_CODE 9000
#endif
-static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
+static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &,
+ const QString &message)
{
if (shouldLogToStderr())
return false; // Leave logging up to stderr handler
- QString formattedMessage = qFormatLogMessage(type, context, message);
- formattedMessage.append(QLatin1Char('\n'));
+ QString formattedMessage = message;
+ formattedMessage.append(u'\n');
if (slog2_set_default_buffer((slog2_buffer_t)-1) == 0) {
slog2_buffer_set_config_t buffer_config;
slog2_buffer_t buffer_handle;
@@ -1532,7 +1691,7 @@ static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &cont
// Set as the default buffer
slog2_set_default_buffer(buffer_handle);
}
- int severity;
+ int severity = SLOG2_INFO;
//Determines the severity level
switch (type) {
case QtDebugMsg:
@@ -1561,13 +1720,11 @@ static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &cont
#if QT_CONFIG(journald)
static bool systemd_default_message_handler(QtMsgType type,
const QMessageLogContext &context,
- const QString &message)
+ const QString &formattedMessage)
{
if (shouldLogToStderr())
return false; // Leave logging up to stderr handler
- QString formattedMessage = qFormatLogMessage(type, context, message);
-
int priority = LOG_INFO; // Informational
switch (type) {
case QtDebugMsg:
@@ -1600,13 +1757,12 @@ static bool systemd_default_message_handler(QtMsgType type,
#endif
#if QT_CONFIG(syslog)
-static bool syslog_default_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
+static bool syslog_default_message_handler(QtMsgType type, const QMessageLogContext &context,
+ const QString &formattedMessage)
{
if (shouldLogToStderr())
return false; // Leave logging up to stderr handler
- QString formattedMessage = qFormatLogMessage(type, context, message);
-
int priority = LOG_INFO; // Informational
switch (type) {
case QtDebugMsg:
@@ -1632,16 +1788,14 @@ static bool syslog_default_message_handler(QtMsgType type, const QMessageLogCont
}
#endif
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
static bool android_default_message_handler(QtMsgType type,
const QMessageLogContext &context,
- const QString &message)
+ const QString &formattedMessage)
{
if (shouldLogToStderr())
return false; // Leave logging up to stderr handler
- QString formattedMessage = qFormatLogMessage(type, context, message);
-
android_LogPriority priority = ANDROID_LOG_DEBUG;
switch (type) {
case QtDebugMsg:
@@ -1661,9 +1815,10 @@ static bool android_default_message_handler(QtMsgType type,
break;
};
+ // If application name is a tag ensure it has no spaces
// If a category is defined, use it as an Android logging tag
__android_log_print(priority, isDefaultCategory(context.category) ?
- qPrintable(QCoreApplication::applicationName()) : context.category,
+ qPrintable(QCoreApplication::applicationName().replace(u' ', u'_')) : context.category,
"%s\n", qPrintable(formattedMessage));
return true; // Prevent further output to stderr
@@ -1671,10 +1826,10 @@ static bool android_default_message_handler(QtMsgType type,
#endif //Q_OS_ANDROID
#ifdef Q_OS_WIN
-static void win_outputDebugString_helper(QStringView message)
+static void win_outputDebugString_helper(const QString &message)
{
const qsizetype maxOutputStringLength = 32766;
- static QBasicMutex m;
+ Q_CONSTINIT static QBasicMutex m;
auto locker = qt_unique_lock(m);
// fast path: Avoid string copies if one output is enough
if (message.length() <= maxOutputStringLength) {
@@ -1682,8 +1837,8 @@ static void win_outputDebugString_helper(QStringView message)
} else {
wchar_t *messagePart = new wchar_t[maxOutputStringLength + 1];
for (qsizetype i = 0; i < message.length(); i += maxOutputStringLength) {
- const qsizetype length = std::min(message.length() - i, maxOutputStringLength);
- const qsizetype len = message.mid(i, length).toWCharArray(messagePart);
+ const qsizetype length = qMin(message.length() - i, maxOutputStringLength);
+ const qsizetype len = QStringView{message}.mid(i, length).toWCharArray(messagePart);
Q_ASSERT(len == length);
messagePart[len] = 0;
OutputDebugString(messagePart);
@@ -1692,13 +1847,13 @@ static void win_outputDebugString_helper(QStringView message)
}
}
-static bool win_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
+static bool win_message_handler(QtMsgType, const QMessageLogContext &,
+ const QString &formattedMessage)
{
if (shouldLogToStderr())
return false; // Leave logging up to stderr handler
- const QString formattedMessage = qFormatLogMessage(type, context, message).append(QLatin1Char('\n'));
- win_outputDebugString_helper(formattedMessage);
+ win_outputDebugString_helper(formattedMessage + u'\n');
return true; // Prevent further output to stderr
}
@@ -1706,15 +1861,14 @@ static bool win_message_handler(QtMsgType type, const QMessageLogContext &contex
#ifdef Q_OS_WASM
static bool wasm_default_message_handler(QtMsgType type,
- const QMessageLogContext &context,
- const QString &message)
+ const QMessageLogContext &,
+ const QString &formattedMessage)
{
if (shouldLogToStderr())
return false; // Leave logging up to stderr handler
- QString formattedMessage = qFormatLogMessage(type, context, message);
- int emOutputFlags = (EM_LOG_CONSOLE | EM_LOG_DEMANGLE);
- QByteArray localMsg = message.toLocal8Bit();
+ int emOutputFlags = EM_LOG_CONSOLE;
+ QByteArray localMsg = formattedMessage.toLocal8Bit();
switch (type) {
case QtDebugMsg:
break;
@@ -1739,58 +1893,89 @@ static bool wasm_default_message_handler(QtMsgType type,
// --------------------------------------------------------------------------
-static void stderr_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
+static void stderr_message_handler(QtMsgType type, const QMessageLogContext &context,
+ const QString &formattedMessage)
{
- QString formattedMessage = qFormatLogMessage(type, context, message);
+ Q_UNUSED(type);
+ Q_UNUSED(context);
// print nothing if message pattern didn't apply / was empty.
// (still print empty lines, e.g. because message itself was empty)
if (formattedMessage.isNull())
return;
-
fprintf(stderr, "%s\n", formattedMessage.toLocal8Bit().constData());
fflush(stderr);
}
+namespace {
+struct SystemMessageSink
+{
+ using Fn = bool(QtMsgType, const QMessageLogContext &, const QString &);
+ Fn *sink;
+ bool messageIsUnformatted = false;
+};
+}
+
+static constexpr SystemMessageSink systemMessageSink = {
+#if defined(QT_BOOTSTRAPPED)
+ nullptr
+#elif defined(Q_OS_WIN)
+ win_message_handler
+#elif QT_CONFIG(slog2)
+ slog2_default_handler
+#elif QT_CONFIG(journald)
+ systemd_default_message_handler
+#elif QT_CONFIG(syslog)
+ syslog_default_message_handler
+#elif defined(Q_OS_ANDROID)
+ android_default_message_handler
+#elif defined(QT_USE_APPLE_UNIFIED_LOGGING)
+ AppleUnifiedLogger::messageHandler, true
+#elif defined Q_OS_WASM
+ wasm_default_message_handler
+#else
+ nullptr
+#endif
+};
+
+static void preformattedMessageHandler(QtMsgType type, const QMessageLogContext &context,
+ const QString &formattedMessage)
+{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Waddress") // "the address of ~~ will never be NULL
+ if (systemMessageSink.sink && systemMessageSink.sink(type, context, formattedMessage))
+ return;
+QT_WARNING_POP
+
+ stderr_message_handler(type, context, formattedMessage);
+}
+
/*!
\internal
*/
static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context,
const QString &message)
{
- bool handledStderr = false;
-
// A message sink logs the message to a structured or unstructured destination,
// optionally formatting the message if the latter, and returns true if the sink
// handled stderr output as well, which will shortcut our default stderr output.
- // In the future, if we allow multiple/dynamic sinks, this will be iterating
- // a list of sinks.
-#if !defined(QT_BOOTSTRAPPED)
-# if defined(Q_OS_WIN)
- handledStderr |= win_message_handler(type, context, message);
-# elif QT_CONFIG(slog2)
- handledStderr |= slog2_default_handler(type, context, message);
-# elif QT_CONFIG(journald)
- handledStderr |= systemd_default_message_handler(type, context, message);
-# elif QT_CONFIG(syslog)
- handledStderr |= syslog_default_message_handler(type, context, message);
-# elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- handledStderr |= android_default_message_handler(type, context, message);
-# elif defined(QT_USE_APPLE_UNIFIED_LOGGING)
- handledStderr |= AppleUnifiedLogger::messageHandler(type, context, message);
-# elif defined Q_OS_WASM
- handledStderr |= wasm_default_message_handler(type, context, message);
-# endif
-#endif
+ if (systemMessageSink.messageIsUnformatted) {
+ if (systemMessageSink.sink(type, context, message))
+ return;
+ }
- if (!handledStderr)
- stderr_message_handler(type, context, message);
+ preformattedMessageHandler(type, context, formatLogMessage(type, context, message));
}
-#if defined(Q_COMPILER_THREAD_LOCAL)
+#if defined(QT_BOOTSTRAPPED)
+// there's no message handler in bootstrapped mode; force everything to stderr
+static bool grabMessageHandler() { return false; }
+static void ungrabMessageHandler() { }
+
+#elif defined(Q_COMPILER_THREAD_LOCAL)
-static thread_local bool msgHandlerGrabbed = false;
+Q_CONSTINIT static thread_local bool msgHandlerGrabbed = false;
static bool grabMessageHandler()
{
@@ -1832,25 +2017,14 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
auto msgHandler = messageHandler.loadAcquire();
(msgHandler ? msgHandler : qDefaultMessageHandler)(msgType, context, message);
} else {
- fprintf(stderr, "%s\n", message.toLocal8Bit().constData());
- }
-}
-
-static void qt_message_print(const QString &message)
-{
-#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED)
- if (!shouldLogToStderr()) {
- win_outputDebugString_helper(message);
- return;
+ stderr_message_handler(msgType, context, message);
}
-#endif
- fprintf(stderr, "%s", message.toLocal8Bit().constData());
- fflush(stderr);
}
-static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const QString &message)
+template <typename String>
+static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, String &&message)
{
-#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
+#if defined(Q_CC_MSVC_ONLY) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
wchar_t contextFileL[256];
// we probably should let the compiler do this for us, by declaring QMessageLogContext::file to
// be const wchar_t * in the first place, but the #ifdefery above is very complex and we
@@ -1869,37 +2043,15 @@ static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const
_CrtDbgBreak();
#else
Q_UNUSED(context);
- Q_UNUSED(message);
#endif
-#ifdef Q_OS_WIN
- // std::abort() in the MSVC runtime will call _exit(3) if the abort
- // behavior is _WRITE_ABORT_MSG - see also _set_abort_behavior(). This is
- // the default for a debug-mode build of the runtime. Worse, MinGW's
- // std::abort() implementation (in msvcrt.dll) is basically a call to
- // _exit(3) too. Unfortunately, _exit() and _Exit() *do* run the static
- // destructors of objects in DLLs, a violation of the C++ standard (see
- // [support.start.term]). So we bypass std::abort() and directly
- // terminate the application.
-
-# if defined(Q_CC_MSVC) && !defined(Q_CC_INTEL)
- if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE))
- __fastfail(FAST_FAIL_FATAL_APP_EXIT);
-# else
- RaiseFailFastException(nullptr, nullptr, 0);
-# endif
-
- // Fallback
- TerminateProcess(GetCurrentProcess(), STATUS_FATAL_APP_EXIT);
-
- // Tell the compiler the application has stopped.
- Q_UNREACHABLE_IMPL();
-#else // !Q_OS_WIN
- std::abort();
-#endif
+ if constexpr (std::is_class_v<String> && !std::is_const_v<String>)
+ message.clear();
+ else
+ Q_UNUSED(message);
+ qAbort();
}
-
/*!
\internal
*/
@@ -1921,7 +2073,7 @@ void qErrnoWarning(const char *msg, ...)
QString buf = QString::vasprintf(msg, ap);
va_end(ap);
- buf += QLatin1String(" (") + error_string + QLatin1Char(')');
+ buf += " ("_L1 + error_string + u')';
QMessageLogContext context;
qt_message_output(QtCriticalMsg, context, buf);
}
@@ -1935,14 +2087,14 @@ void qErrnoWarning(int code, const char *msg, ...)
QString buf = QString::vasprintf(msg, ap);
va_end(ap);
- buf += QLatin1String(" (") + qt_error_string(code) + QLatin1Char(')');
+ buf += " ("_L1 + qt_error_string(code) + u')';
QMessageLogContext context;
qt_message_output(QtCriticalMsg, context, buf);
}
/*!
\typedef QtMessageHandler
- \relates <QtGlobal>
+ \relates <QtLogging>
\since 5.0
This is a typedef for a pointer to a function with the following
@@ -1955,41 +2107,69 @@ void qErrnoWarning(int code, const char *msg, ...)
/*!
\fn QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)
- \relates <QtGlobal>
+ \relates <QtLogging>
\since 5.0
- Installs a Qt message \a handler which has been defined
- previously. Returns a pointer to the previous message handler.
-
- The message handler is a function that prints out debug messages,
- warnings, critical and fatal error messages. The Qt library (debug
- mode) contains hundreds of warning messages that are printed
- when internal errors (usually invalid function arguments)
- occur. Qt built in release mode also contains such warnings unless
- QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during
- compilation. If you implement your own message handler, you get total
- control of these messages.
-
- The default message handler prints the message to the standard
- output under X11 or to the debugger under Windows. If it is a
- fatal message, the application aborts immediately.
-
- Only one message handler can be defined, since this is usually
- done on an application-wide basis to control debug output.
-
- To restore the message handler, call \c qInstallMessageHandler(0).
-
- Example:
+ Installs a Qt message \a handler.
+ Returns a pointer to the previously installed message handler.
+
+ A message handler is a function that prints out debug, info,
+ warning, critical, and fatal messages from Qt's logging infrastructure.
+ By default, Qt uses a standard message handler that formats and
+ prints messages to different sinks specific to the operating system
+ and Qt configuration. Installing your own message handler allows you
+ to assume full control, and for instance log messages to the
+ file system.
+
+ Note that Qt supports \l{QLoggingCategory}{logging categories} for
+ grouping related messages in semantic categories. You can use these
+ to enable or disable logging per category and \l{QtMsgType}{message type}.
+ As the filtering for logging categories is done even before a message
+ is created, messages for disabled types and categories will not reach
+ the message handler.
+
+ A message handler needs to be
+ \l{Reentrancy and Thread-Safety}{reentrant}. That is, it might be called
+ from different threads, in parallel. Therefore, writes to common sinks
+ (like a database, or a file) often need to be synchronized.
+
+ Qt allows to enrich logging messages with further meta-information
+ by calling \l qSetMessagePattern(), or setting the \c QT_MESSAGE_PATTERN
+ environment variable. To keep this formatting, a custom message handler
+ can use \l qFormatLogMessage().
+
+ Try to keep the code in the message handler itself minimal, as expensive
+ operations might block the application. Also, to avoid recursion, any
+ logging messages generated in the message handler itself will be ignored.
+
+ The message handler should always return. For
+ \l{QtFatalMsg}{fatal messages}, the application aborts immediately after
+ handling that message.
+
+ Only one message handler can be installed at a time, for the whole application.
+ If there was a previous custom message handler installed,
+ the function will return a pointer to it. This handler can then
+ be later reinstalled by another call to the method. Also, calling
+ \c qInstallMessageHandler(nullptr) will restore the default
+ message handler.
+
+ Here is an example of a message handler that logs to a local file
+ before calling the default handler:
\snippet code/src_corelib_global_qglobal.cpp 23
+ Note that the C++ standard guarantees that \c{static FILE *f} is
+ initialized in a thread-safe way. We can also expect \c{fprintf()}
+ and \c{fflush()} to be thread-safe, so no further synchronization
+ is necessary.
+
\sa QtMessageHandler, QtMsgType, qDebug(), qInfo(), qWarning(), qCritical(), qFatal(),
- {Debugging Techniques}
+ {Debugging Techniques}, qFormatLogMessage()
*/
/*!
\fn void qSetMessagePattern(const QString &pattern)
- \relates <QtGlobal>
+ \relates <QtLogging>
\since 5.0
\brief Changes the output of the default message handler.
@@ -2022,9 +2202,12 @@ void qErrnoWarning(int code, const char *msg, ...)
\row \li \c{%{backtrace [depth=N] [separator="..."]}} \li A backtrace with the number of frames
specified by the optional \c depth parameter (defaults to 5), and separated by the optional
\c separator parameter (defaults to "|").
+
This expansion is available only on some platforms (currently only platfoms using glibc).
Names are only known for exported functions. If you want to see the name of every function
- in your application, use \c{QMAKE_LFLAGS += -rdynamic}.
+ in your application, make sure your application is compiled and linked with \c{-rdynamic},
+ or an equivalent of it.
+
When reading backtraces, take into account that frames might be missing due to inlining or
tail call optimization.
\endtable
@@ -2039,19 +2222,23 @@ void qErrnoWarning(int code, const char *msg, ...)
Example:
\snippet code/src_corelib_global_qlogging.cpp 0
- The default \a pattern is "%{if-category}%{category}: %{endif}%{message}".
+ The default \a pattern is \c{%{if-category}%{category}: %{endif}%{message}}.
The \a pattern can also be changed at runtime by setting the QT_MESSAGE_PATTERN
environment variable; if both \l qSetMessagePattern() is called and QT_MESSAGE_PATTERN is
set, the environment variable takes precedence.
+ \note The information for the placeholders \c category, \c file, \c function and \c line is
+ only recorded in debug builds. Alternatively, \c QT_MESSAGELOGCONTEXT can be defined
+ explicitly. For more information refer to the QMessageLogContext documentation.
+
\note The message pattern only applies to unstructured logging, such as the default
\c stderr output. Structured logging such as systemd will record the message as is,
along with as much structured information as can be captured.
Custom message handlers can use qFormatLogMessage() to take \a pattern into account.
- \sa qInstallMessageHandler(), {Debugging Techniques}, {QLoggingCategory}
+ \sa qInstallMessageHandler(), {Debugging Techniques}, {QLoggingCategory}, QMessageLogContext
*/
QtMessageHandler qInstallMessageHandler(QtMessageHandler h)
@@ -2063,6 +2250,7 @@ QtMessageHandler qInstallMessageHandler(QtMessageHandler h)
return qDefaultMessageHandler;
}
+#ifndef QT_BOOTSTRAPPED
void qSetMessagePattern(const QString &pattern)
{
const auto locker = qt_scoped_lock(QMessagePattern::mutex);
@@ -2070,7 +2258,7 @@ void qSetMessagePattern(const QString &pattern)
if (!qMessagePattern()->fromEnvironment)
qMessagePattern()->setPattern(pattern);
}
-
+#endif
/*!
Copies context information from \a logContext into this QMessageLogContext.
@@ -2133,4 +2321,219 @@ QMessageLogContext &QMessageLogContext::copyContextFrom(const QMessageLogContext
\a lineNumber, in function \a functionName, and category \a categoryName.
*/
+/*!
+ \macro qDebug(const char *message, ...)
+ \relates <QtLogging>
+ \threadsafe
+
+ Calls the message handler with the debug message \a message. If no
+ message handler has been installed, the message is printed to
+ stderr. Under Windows the message is sent to the console, if it is a
+ console application; otherwise, it is sent to the debugger. On QNX, the
+ message is sent to slogger2. This function does nothing if \c QT_NO_DEBUG_OUTPUT
+ was defined during compilation.
+
+ If you pass the function a format string and a list of arguments,
+ it works in similar way to the C printf() function. The format
+ should be a Latin-1 string.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 24
+
+ If you include \c <QtDebug>, a more convenient syntax is also
+ available:
+
+ \snippet code/src_corelib_global_qglobal.cpp 25
+
+ With this syntax, the function returns a QDebug object that is
+ configured to use the QtDebugMsg message type. It automatically
+ puts a single space between each item, and outputs a newline at
+ the end. It supports many C++ and Qt types.
+
+ To suppress the output at runtime, install your own message handler
+ with qInstallMessageHandler().
+
+ \sa qInfo(), qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
+ {Debugging Techniques}
+*/
+
+/*!
+ \macro qInfo(const char *message, ...)
+ \relates <QtLogging>
+ \threadsafe
+ \since 5.5
+
+ Calls the message handler with the informational message \a message. If no
+ message handler has been installed, the message is printed to
+ stderr. Under Windows, the message is sent to the console, if it is a
+ console application; otherwise, it is sent to the debugger. On QNX the
+ message is sent to slogger2. This function does nothing if \c QT_NO_INFO_OUTPUT
+ was defined during compilation.
+
+ If you pass the function a format string and a list of arguments,
+ it works in similar way to the C printf() function. The format
+ should be a Latin-1 string.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qInfo_printf
+
+ If you include \c <QtDebug>, a more convenient syntax is also
+ available:
+
+ \snippet code/src_corelib_global_qglobal.cpp qInfo_stream
+
+ With this syntax, the function returns a QDebug object that is
+ configured to use the QtInfoMsg message type. It automatically
+ puts a single space between each item, and outputs a newline at
+ the end. It supports many C++ and Qt types.
+
+ To suppress the output at runtime, install your own message handler
+ using qInstallMessageHandler().
+
+ \sa qDebug(), qWarning(), qCritical(), qFatal(), qInstallMessageHandler(),
+ {Debugging Techniques}
+*/
+
+/*!
+ \macro qWarning(const char *message, ...)
+ \relates <QtLogging>
+ \threadsafe
+
+ Calls the message handler with the warning message \a message. If no
+ message handler has been installed, the message is printed to
+ stderr. Under Windows, the message is sent to the debugger.
+ On QNX the message is sent to slogger2.
+
+ This function takes a format string and a list of arguments,
+ similar to the C printf() function. The format should be a Latin-1
+ string.
+
+ Example:
+ \snippet code/src_corelib_global_qglobal.cpp 26
+
+ If you include <QtDebug>, a more convenient syntax is
+ also available:
+
+ \snippet code/src_corelib_global_qglobal.cpp 27
+
+ This syntax inserts a space between each item, and
+ appends a newline at the end.
+
+ This function does nothing if \c QT_NO_WARNING_OUTPUT was defined
+ during compilation.
+ To suppress the output at runtime, you can set
+ \l{QLoggingCategory}{logging rules} or register a custom
+ \l{QLoggingCategory::installFilter()}{filter}.
+
+ For debugging purposes, it is sometimes convenient to let the
+ program abort for warning messages. This allows you then
+ to inspect the core dump, or attach a debugger - see also \l{qFatal()}.
+ To enable this, set the environment variable \c{QT_FATAL_WARNINGS}
+ to a number \c n. The program terminates then for the n-th warning.
+ That is, if the environment variable is set to 1, it will terminate
+ on the first call; if it contains the value 10, it will exit on the 10th
+ call. Any non-numeric value in the environment variable is equivalent to 1.
+
+ \sa qDebug(), qInfo(), qCritical(), qFatal(), qInstallMessageHandler(),
+ {Debugging Techniques}
+*/
+
+/*!
+ \macro qCritical(const char *message, ...)
+ \relates <QtLogging>
+ \threadsafe
+
+ Calls the message handler with the critical message \a message. If no
+ message handler has been installed, the message is printed to
+ stderr. Under Windows, the message is sent to the debugger.
+ On QNX the message is sent to slogger2.
+
+ This function takes a format string and a list of arguments,
+ similar to the C printf() function. The format should be a Latin-1
+ string.
+
+ Example:
+ \snippet code/src_corelib_global_qglobal.cpp 28
+
+ If you include <QtDebug>, a more convenient syntax is
+ also available:
+
+ \snippet code/src_corelib_global_qglobal.cpp 29
+
+ A space is inserted between the items, and a newline is
+ appended at the end.
+
+ To suppress the output at runtime, you can define
+ \l{QLoggingCategory}{logging rules} or register a custom
+ \l{QLoggingCategory::installFilter()}{filter}.
+
+ For debugging purposes, it is sometimes convenient to let the
+ program abort for critical messages. This allows you then
+ to inspect the core dump, or attach a debugger - see also \l{qFatal()}.
+ To enable this, set the environment variable \c{QT_FATAL_CRITICALS}
+ to a number \c n. The program terminates then for the n-th critical
+ message.
+ That is, if the environment variable is set to 1, it will terminate
+ on the first call; if it contains the value 10, it will exit on the 10th
+ call. Any non-numeric value in the environment variable is equivalent to 1.
+
+ \sa qDebug(), qInfo(), qWarning(), qFatal(), qInstallMessageHandler(),
+ {Debugging Techniques}
+*/
+
+/*!
+ \macro qFatal(const char *message, ...)
+ \relates <QtLogging>
+
+ Calls the message handler with the fatal message \a message. If no
+ message handler has been installed, the message is printed to
+ stderr. Under Windows, the message is sent to the debugger.
+ On QNX the message is sent to slogger2.
+
+ If you are using the \b{default message handler} this function will
+ abort to create a core dump. On Windows, for debug builds,
+ this function will report a _CRT_ERROR enabling you to connect a debugger
+ to the application.
+
+ This function takes a format string and a list of arguments,
+ similar to the C printf() function.
+
+ Example:
+ \snippet code/src_corelib_global_qglobal.cpp 30
+
+ To suppress the output at runtime, install your own message handler
+ with qInstallMessageHandler().
+
+ \sa qDebug(), qInfo(), qWarning(), qCritical(), qInstallMessageHandler(),
+ {Debugging Techniques}
+*/
+
+/*!
+ \enum QtMsgType
+ \relates <QtLogging>
+
+ This enum describes the messages that can be sent to a message
+ handler (QtMessageHandler). You can use the enum to identify and
+ associate the various message types with the appropriate
+ actions.
+
+ \value QtDebugMsg
+ A message generated by the qDebug() function.
+ \value QtInfoMsg
+ A message generated by the qInfo() function.
+ \value QtWarningMsg
+ A message generated by the qWarning() function.
+ \value QtCriticalMsg
+ A message generated by the qCritical() function.
+ \value QtFatalMsg
+ A message generated by the qFatal() function.
+ \omitvalue QtSystemMsg
+
+ \c QtInfoMsg was added in Qt 5.5.
+
+ \sa QtMessageHandler, qInstallMessageHandler()
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index ecf60f747c..de82267218 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -1,50 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLOGGING_H
#define QLOGGING_H
+#include <QtCore/qtclasshelpermacros.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtcoreexports.h>
+#include <QtCore/qcontainerfwd.h>
+
#if 0
// header is automatically included in qglobal.h
#pragma qt_no_master_include
+#pragma qt_class(QtLogging)
#endif
QT_BEGIN_NAMESPACE
@@ -57,13 +25,16 @@ QT_BEGIN_NAMESPACE
class QDebug;
class QNoDebug;
+
enum QtMsgType {
QtDebugMsg,
QtWarningMsg,
QtCriticalMsg,
QtFatalMsg,
QtInfoMsg,
- QtSystemMsg = QtCriticalMsg
+#if QT_DEPRECATED_SINCE(6, 7)
+ QtSystemMsg Q_DECL_ENUMERATOR_DEPRECATED_X("Use QtCriticalMsg instead.") = QtCriticalMsg
+#endif
};
class QMessageLogContext
@@ -89,6 +60,12 @@ private:
class QLoggingCategory;
+#if defined(Q_CC_MSVC_ONLY)
+# define QT_MESSAGE_LOGGER_NORETURN
+#else
+# define QT_MESSAGE_LOGGER_NORETURN Q_NORETURN
+#endif
+
class Q_CORE_EXPORT QMessageLogger
{
Q_DISABLE_COPY(QMessageLogger)
@@ -107,6 +84,8 @@ public:
void warning(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
Q_DECL_COLD_FUNCTION
void critical(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+ QT_MESSAGE_LOGGER_NORETURN Q_DECL_COLD_FUNCTION
+ void fatal(const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
typedef const QLoggingCategory &(*CategoryFunction)();
@@ -122,12 +101,10 @@ public:
void critical(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
Q_DECL_COLD_FUNCTION
void critical(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
-
-#ifndef Q_CC_MSVC
- Q_NORETURN
-#endif
- Q_DECL_COLD_FUNCTION
- void fatal(const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+ QT_MESSAGE_LOGGER_NORETURN Q_DECL_COLD_FUNCTION
+ void fatal(const QLoggingCategory &cat, const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+ QT_MESSAGE_LOGGER_NORETURN Q_DECL_COLD_FUNCTION
+ void fatal(CategoryFunction catFunc, const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
#ifndef QT_NO_DEBUG_STREAM
QDebug debug() const;
@@ -136,12 +113,24 @@ public:
QDebug info() const;
QDebug info(const QLoggingCategory &cat) const;
QDebug info(CategoryFunction catFunc) const;
+ Q_DECL_COLD_FUNCTION
QDebug warning() const;
+ Q_DECL_COLD_FUNCTION
QDebug warning(const QLoggingCategory &cat) const;
+ Q_DECL_COLD_FUNCTION
QDebug warning(CategoryFunction catFunc) const;
+ Q_DECL_COLD_FUNCTION
QDebug critical() const;
+ Q_DECL_COLD_FUNCTION
QDebug critical(const QLoggingCategory &cat) const;
+ Q_DECL_COLD_FUNCTION
QDebug critical(CategoryFunction catFunc) const;
+ Q_DECL_COLD_FUNCTION
+ QDebug fatal() const;
+ Q_DECL_COLD_FUNCTION
+ QDebug fatal(const QLoggingCategory &cat) const;
+ Q_DECL_COLD_FUNCTION
+ QDebug fatal(CategoryFunction catFunc) const;
QNoDebug noDebug() const noexcept;
#endif // QT_NO_DEBUG_STREAM
@@ -150,6 +139,8 @@ private:
QMessageLogContext context;
};
+#undef QT_MESSAGE_LOGGER_NORETURN
+
#if !defined(QT_MESSAGELOGCONTEXT) && !defined(QT_NO_MESSAGELOGCONTEXT)
# if defined(QT_NO_DEBUG)
# define QT_NO_MESSAGELOGCONTEXT
@@ -202,5 +193,8 @@ Q_CORE_EXPORT void qSetMessagePattern(const QString &messagePattern);
Q_CORE_EXPORT QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context,
const QString &buf);
+Q_DECL_COLD_FUNCTION
+Q_CORE_EXPORT QString qt_error_string(int errorCode = -1);
+
QT_END_NAMESPACE
#endif // QLOGGING_H
diff --git a/src/corelib/global/qlogging_p.h b/src/corelib/global/qlogging_p.h
index 3d0c097ffe..9492f10f1f 100644
--- a/src/corelib/global/qlogging_p.h
+++ b/src/corelib/global/qlogging_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLOGGING_P_H
#define QLOGGING_P_H
@@ -51,6 +15,8 @@
// We mean it.
//
+#include <QtCore/private/qglobal_p.h>
+
QT_BEGIN_NAMESPACE
namespace QtPrivate {
diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp
index aeba9ed19b..d413a35c6b 100644
--- a/src/corelib/global/qmalloc.cpp
+++ b/src/corelib/global/qmalloc.cpp
@@ -1,42 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#include "qmalloc.h"
#include "qplatformdefs.h"
#include <stdlib.h>
@@ -80,6 +45,7 @@ void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t align
// However, we need to store the actual pointer, so we need to allocate actually size +
// alignment anyway.
+ qptrdiff oldoffset = oldptr ? static_cast<char *>(oldptr) - static_cast<char *>(actualptr) : 0;
void *real = realloc(actualptr, newsize + alignment);
if (!real)
return nullptr;
@@ -89,7 +55,6 @@ void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t align
void **faked_ptr = reinterpret_cast<void **>(faked);
if (oldptr) {
- qptrdiff oldoffset = static_cast<char *>(oldptr) - static_cast<char *>(actualptr);
qptrdiff newoffset = reinterpret_cast<char *>(faked_ptr) - static_cast<char *>(real);
if (oldoffset != newoffset)
memmove(faked_ptr, static_cast<char *>(real) + oldoffset, qMin(oldsize, newsize));
diff --git a/src/corelib/global/qmalloc.h b/src/corelib/global/qmalloc.h
new file mode 100644
index 0000000000..83dfff358b
--- /dev/null
+++ b/src/corelib/global/qmalloc.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QMALLOC_H
+#define QMALLOC_H
+
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtcoreexports.h>
+
+#include <cstddef> // size_t
+
+#if 0
+#pragma qt_class(QtMalloc)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+Q_CORE_EXPORT void *qMallocAligned(size_t size, size_t alignment) Q_ALLOC_SIZE(1);
+Q_CORE_EXPORT void *qReallocAligned(void *ptr, size_t size, size_t oldsize, size_t alignment) Q_ALLOC_SIZE(2);
+Q_CORE_EXPORT void qFreeAligned(void *ptr);
+
+QT_END_NAMESPACE
+
+#endif // QMALLOC_H
diff --git a/src/corelib/global/qminmax.h b/src/corelib/global/qminmax.h
new file mode 100644
index 0000000000..e6fb62bf9d
--- /dev/null
+++ b/src/corelib/global/qminmax.h
@@ -0,0 +1,88 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QMINMAX_H
+#define QMINMAX_H
+
+#if 0
+#pragma qt_class(QtMinMax)
+#pragma qt_sync_stop_processing
+#endif
+
+#include <QtCore/qassert.h>
+#include <QtCore/qtconfigmacros.h>
+
+#include <type_traits>
+
+QT_BEGIN_NAMESPACE
+
+namespace QTypeTraits {
+
+namespace detail {
+template<typename T, typename U,
+ typename = std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U> &&
+ std::is_floating_point_v<T> == std::is_floating_point_v<U> &&
+ std::is_signed_v<T> == std::is_signed_v<U> &&
+ !std::is_same_v<T, bool> && !std::is_same_v<U, bool> &&
+ !std::is_same_v<T, char> && !std::is_same_v<U, char>>>
+struct Promoted
+{
+ using type = decltype(T() + U());
+};
+}
+
+template <typename T, typename U>
+using Promoted = typename detail::Promoted<T, U>::type;
+
+}
+
+template <typename T>
+constexpr inline const T &qMin(const T &a, const T &b) { return (a < b) ? a : b; }
+template <typename T>
+constexpr inline const T &qMax(const T &a, const T &b) { return (a < b) ? b : a; }
+template <typename T>
+constexpr inline const T &qBound(const T &min, const T &val, const T &max)
+{
+ Q_ASSERT(!(max < min));
+ return qMax(min, qMin(max, val));
+}
+template <typename T, typename U>
+constexpr inline QTypeTraits::Promoted<T, U> qMin(const T &a, const U &b)
+{
+ using P = QTypeTraits::Promoted<T, U>;
+ P _a = a;
+ P _b = b;
+ return (_a < _b) ? _a : _b;
+}
+template <typename T, typename U>
+constexpr inline QTypeTraits::Promoted<T, U> qMax(const T &a, const U &b)
+{
+ using P = QTypeTraits::Promoted<T, U>;
+ P _a = a;
+ P _b = b;
+ return (_a < _b) ? _b : _a;
+}
+template <typename T, typename U>
+constexpr inline QTypeTraits::Promoted<T, U> qBound(const T &min, const U &val, const T &max)
+{
+ Q_ASSERT(!(max < min));
+ return qMax(min, qMin(max, val));
+}
+template <typename T, typename U>
+constexpr inline QTypeTraits::Promoted<T, U> qBound(const T &min, const T &val, const U &max)
+{
+ using P = QTypeTraits::Promoted<T, U>;
+ Q_ASSERT(!(P(max) < P(min)));
+ return qMax(min, qMin(max, val));
+}
+template <typename T, typename U>
+constexpr inline QTypeTraits::Promoted<T, U> qBound(const U &min, const T &val, const T &max)
+{
+ using P = QTypeTraits::Promoted<T, U>;
+ Q_ASSERT(!(P(max) < P(min)));
+ return qMax(min, qMin(max, val));
+}
+
+QT_END_NAMESPACE
+
+#endif // QMINMAX_H
diff --git a/src/corelib/global/qminmax.qdoc b/src/corelib/global/qminmax.qdoc
new file mode 100644
index 0000000000..36f680b4c7
--- /dev/null
+++ b/src/corelib/global/qminmax.qdoc
@@ -0,0 +1,39 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*! \fn template <typename T> const T &qMin(const T &a, const T &b)
+ \relates <QtMinMax>
+
+ Returns the minimum of \a a and \a b.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 13
+
+ \sa qMax(), qBound()
+*/
+
+/*! \fn template <typename T> const T &qMax(const T &a, const T &b)
+ \relates <QtMinMax>
+
+ Returns the maximum of \a a and \a b.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 14
+
+ \sa qMin(), qBound()
+*/
+
+/*! \fn template <typename T> const T &qBound(const T &min, const T &val, const T &max)
+ \relates <QtMinMax>
+
+ Returns \a val bounded by \a min and \a max. This is equivalent
+ to qMax(\a min, qMin(\a val, \a max)).
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 15
+
+ \sa qMin(), qMax()
+*/
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 48bbba655e..3b4daa0f8f 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1,46 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2020 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2020 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QNAMESPACE_H
#define QNAMESPACE_H
+#if 0
+#pragma qt_class(Qt)
+#endif
+
#include <QtCore/qglobal.h>
#include <QtCore/qtmetamacros.h>
@@ -78,6 +46,12 @@ namespace Qt {
transparent
};
+ enum class ColorScheme {
+ Unknown,
+ Light,
+ Dark,
+ };
+
enum MouseButton {
NoButton = 0x00000000,
LeftButton = 0x00000001,
@@ -208,6 +182,7 @@ namespace Qt {
// size of a multi-variant string.
TextLongestVariant = 0x80000
};
+ Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, AlignmentFlag, TextFlag)
enum TextElideMode {
ElideLeft,
@@ -215,6 +190,7 @@ namespace Qt {
ElideMiddle,
ElideNone
};
+ Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, TextElideMode, TextFlag)
enum WhiteSpaceMode {
WhiteSpaceNormal,
@@ -236,7 +212,7 @@ namespace Qt {
ToolTip = Popup | Sheet,
SplashScreen = ToolTip | Dialog,
Desktop = 0x00000010 | Window,
- SubWindow = 0x00000012,
+ SubWindow = 0x00000012, // Note QTBUG-115729 before using
ForeignWindow = 0x00000020 | Window,
CoverWindow = 0x00000040 | Window,
@@ -446,7 +422,7 @@ namespace Qt {
enum ApplicationAttribute
{
// AA_ImmediateWidgetCreation = 0,
- // AA_MSWindowsUseDirect3DByDefault = 1,
+ AA_QtQuickUseDefaultSizePolicy = 1 QT_TECH_PREVIEW_API,
AA_DontShowIconsInMenus = 2,
AA_NativeWindows = 3,
AA_DontCreateNativeWidgetSiblings = 4,
@@ -487,6 +463,7 @@ namespace Qt {
AA_CompressTabletEvents = 29,
// AA_DisableWindowContextHelpButton = 30,
AA_DisableSessionManager = 31,
+ AA_DontUseNativeMenuWindows = 32,
// Add new attributes before this line
AA_AttributeCount
@@ -626,7 +603,11 @@ namespace Qt {
Key_twosuperior = 0x0b2,
Key_threesuperior = 0x0b3,
Key_acute = 0x0b4,
- Key_mu = 0x0b5,
+ Key_micro = 0x0b5,
+#if QT_DEPRECATED_SINCE(6, 11)
+ Key_mu Q_DECL_ENUMERATOR_DEPRECATED_X("This key was misnamed, use Key_micro instead")
+ = Key_micro,
+#endif
Key_paragraph = 0x0b6,
Key_periodcentered = 0x0b7,
Key_cedilla = 0x0b8,
@@ -1460,6 +1441,7 @@ namespace Qt {
enum LayoutDirection {
LeftToRight,
RightToLeft,
+ // ### Qt 7: make auto the first one (with value 0)
LayoutDirectionAuto
};
@@ -1609,6 +1591,11 @@ namespace Qt {
};
inline constexpr Initialization Uninitialized = Initialization::Uninitialized;
+ struct Disambiguated_t {
+ explicit Disambiguated_t() = default;
+ };
+ inline constexpr Disambiguated_t Disambiguated{};
+
enum CoordinateSystem {
DeviceCoordinates,
LogicalCoordinates
@@ -1689,6 +1676,10 @@ namespace Qt {
VeryCoarseTimer
};
+ enum class TimerId {
+ Invalid = 0,
+ };
+
enum ScrollPhase {
NoScrollPhase = 0,
ScrollBegin,
@@ -1726,6 +1717,12 @@ namespace Qt {
PassThrough
};
+ enum class PermissionStatus {
+ Undetermined,
+ Granted,
+ Denied,
+ };
+
// QTBUG-48701
enum ReturnByValueConstant { ReturnByValue }; // ### Qt 7: Remove me
@@ -1769,6 +1766,7 @@ namespace Qt {
Q_ENUM_NS(DayOfWeek)
Q_ENUM_NS(CursorShape)
Q_ENUM_NS(GlobalColor)
+ Q_ENUM_NS(ColorScheme)
Q_ENUM_NS(AspectRatioMode)
Q_ENUM_NS(TransformationMode)
Q_FLAG_NS(ImageConversionFlags)
@@ -1816,10 +1814,11 @@ namespace Qt {
Q_ENUM_NS(TimerType)
Q_ENUM_NS(ScrollPhase)
Q_ENUM_NS(MouseEventSource)
- Q_FLAG_NS(MouseEventFlag)
+ Q_FLAG_NS(MouseEventFlags)
Q_ENUM_NS(ChecksumType)
Q_ENUM_NS(HighDpiScaleFactorRoundingPolicy)
Q_ENUM_NS(TabFocusBehavior)
+ Q_ENUM_NS(PermissionStatus)
#endif // Q_DOC
}
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 0ad279f16c..86065c5917 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1,30 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2020 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2020 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\namespace Qt
@@ -108,6 +84,19 @@
QCoreApplication::testAttribute().
+ \value [since 6.7] AA_QtQuickUseDefaultSizePolicy Qt Quick Layouts use the built-in size
+ policy of \l Item. For example, when this is set, \l Button fills the available
+ width, but has a fixed height. When this is not set, it will use the default
+ sizing behavior of the layout it's in, which is to use its implicit size as the
+ preferred size. This is explained in detail in \l {Specifying preferred size} and
+ \l {Size constraints}. When this is set, the default size policy of the item
+ with the layout can be overridden by explicitly setting
+ \l{Layout::fillWidth}{Layout.fillWidth} or
+ \l{Layout::fillHeight}{Layout.fillHeight}.
+ \b Note: This API is considered tech preview and may change or be removed in future
+ versions of Qt.
+
+
\value AA_DontShowIconsInMenus Actions with the Icon property won't be
shown in any menus unless specifically set by the
QAction::iconVisibleInMenu property.
@@ -118,9 +107,11 @@
\value AA_DontShowShortcutsInContextMenus Actions with the Shortcut property
won't be shown in any shortcut menus unless specifically set by the
QAction::shortcutVisibleInContextMenu property. This value was added
- in Qt 5.10, and defaults to the preference reported by the implementation
- of QPlatformIntegration::styleHint. To override the platform integration,
- set this attribute after QCoreApplication has been instantiated.
+ in Qt 5.10, and is by default based on the value reported by
+ QStyleHints::showShortcutsInContextMenus(). To override the default
+ behavior, set the style hint before QCoreApplication has been
+ instantiated, or set this attribute after QCoreApplication has
+ been instantiated.
\value AA_NativeWindows Ensures that widgets have native windows.
@@ -142,15 +133,15 @@
set to true won't be used as a native menubar (e.g, the menubar at
the top of the main screen on \macos).
- \value AA_MacDontSwapCtrlAndMeta Keyboard shortcuts on \macos are typically
+ \value AA_MacDontSwapCtrlAndMeta Keyboard shortcuts on Apple platforms are typically
based on the Command (or Cmd) keyboard modifier, represented by
the ⌘ symbol. For example, the 'Copy' action is Command+C (⌘+C).
To ease cross platform development Qt will by default remap Command
to the Qt::ControlModifier, to align with other platforms. This
allows creating keyboard shortcuts such as "Ctrl+J", which on
\macos will then map to Command+J, as expected by \macos users. The
- actual Control (or Ctrl) modifier on \macos, represented by ⌃, is
- mapped to Qt::MetaModifier.
+ actual Control (or Ctrl) modifier on Apple platforms, represented by ⌃,
+ is mapped to Qt::MetaModifier.
When this attribute is true Qt will not do the remapping, and pressing
the Command modifier will result in Qt::MetaModifier, while pressing
@@ -213,9 +204,9 @@
\value AA_UseStyleSheetPropagationInWidgetStyles By default, Qt Style Sheets
disable regular QWidget palette and font propagation. When this flag
- is enabled, font and palette changes propagate as though the user had
- manually called the corresponding QWidget methods. See
- \l{The Style Sheet Syntax#Inheritance}{The Style Sheet Syntax - Inheritance}
+ is enabled, font and palette changes done from a style sheet will propagate
+ a single time, when the style sheet is set.
+ See \l{The Style Sheet Syntax#Inheritance}{The Style Sheet Syntax - Inheritance}
for more details.
This value was added in Qt 5.7.
@@ -282,6 +273,12 @@
Currently supported on the Windows platform only.
This value was added in 5.15
+ \value AA_DontUseNativeMenuWindows Menu popup windows (e.g. context menus,
+ combo box menus, and non-native menubar menus) created while this
+ attribute is set to true will not be represented as native top
+ level windows, unless required by the implementation.
+ This value was added in Qt 6.8.
+
\omitvalue AA_AttributeCount
\omitvalue AA_EnableHighDpiScaling
\omitvalue AA_UseHighDpiPixmaps
@@ -639,7 +636,7 @@
connection types, using a bitwise OR. When Qt::UniqueConnection is
set, QObject::connect() will fail if the connection already exists
(i.e. if the same signal is already connected to the same slot
- for the same pair of objects). This flag was introduced in Qt 4.6.
+ for the same pair of objects).
\value SingleShotConnection
This is a flag that can be combined with any one of the above
@@ -752,15 +749,25 @@
Mean Time has zero offset from it. Neither UTC nor OffsetFromUTC
has any transitions.
+ When specifying a datetime using OffsetFromUTC, the offset from UTC must
+ also be supplied (it is measured in seconds). To specify a datetime using
+ TimeZone, a QTimeZone must be supplied. From Qt 6.5, a QTimeZone can now
+ package a timespec with, where needed, an offset as a lightweight time
+ description, so that passing a QTimeZone now provides a uniform way to use
+ datetime APIs, saving the need to call them differently for different
+ timespecs.
+
\note After a change to the system time-zone setting, the behavior
of LocalTime-based QDateTime objects created before the change is
undefined: QDateTime may have cached data that the change
- invalidates. (This is not triggered by transitions of the system
+ invalidates. (This is not triggered by \e transitions of the system
time-zone.) In long-running processes, updates to the system's
time-zone data (e.g. when politicians change the rules for a zone)
may likewise lead to conflicts between the updated time-zone
information and data cached by QDateTime objects created before
the update, using either LocalTime or TimeZone.
+
+ \sa QTimeZone, QDateTime
*/
/*!
@@ -798,14 +805,29 @@
/*!
\enum Qt::DockWidgetArea
- \value LeftDockWidgetArea
- \value RightDockWidgetArea
- \value TopDockWidgetArea
- \value BottomDockWidgetArea
- \value AllDockWidgetAreas
- \value NoDockWidgetArea
+ Represents the areas a QDockWidget can be plugged to.
+ \note A floating dock widget with tabs can be docked anywhere.
+
+ \value LeftDockWidgetArea The left dock area of a QMainWindow.
+ \value RightDockWidgetArea The right dock area of a QMainWindow.
+ \value TopDockWidgetArea The top dock area of a QMainWindow.
+ \value BottomDockWidgetArea The bottom dock area of a QMainWindow.
+ \value AllDockWidgetAreas All dock widget areas (default).
+ \value NoDockWidgetArea No dock widget areas.
\omitvalue DockWidgetArea_Mask
+ \sa QDockWidget::setAllowedAreas, QDockWidget::isAreaAllowed
+*/
+
+/*!
+ \enum Qt::ColorScheme
+
+ Represents the appearance of an application's theme,
+ defined by QGuiApplication::palette().
+
+ \value Unknown The appearance is unknown.
+ \value Light The background colors are lighter than the text color, i.e. the theme is light.
+ \value Dark The background colors are darker than the text color, i.e. the theme is dark.
*/
/*!
@@ -977,8 +999,7 @@
\value WA_Hover Forces Qt to generate paint events when the mouse
enters or leaves the widget. This feature is typically used when
- implementing custom styles; see the \l{widgets/styles}{Styles}
- example for details.
+ implementing custom styles.
\value WA_InputMethodEnabled Enables input methods for Asian languages.
Must be set when creating custom text editing widgets.
@@ -1126,10 +1147,10 @@
e.g., when a hidden widget was resized. This flag is set or cleared by the
Qt kernel.
- \value WA_QuitOnClose Makes Qt quit the application when the last widget
- with the attribute set has accepted closeEvent(). This behavior can be
- modified with the QApplication::quitOnLastWindowClosed property. By default
- this attribute is set for all widgets of type Qt::Window.
+ \value WA_QuitOnClose Indicates that the widget should be taken into account
+ when deciding whether to quit the application when the last window is closed.
+ This behavior can be modified with the QGuiApplication::quitOnLastWindowClosed
+ property. By default this attribute is set for all widgets of type Qt::Window.
\value WA_Resized Indicates that the widget has an explicit size. This flag
is set or cleared by QWidget::resize() and QWidget::setGeometry().
@@ -1303,7 +1324,7 @@
to this top level window. This attribute has no effect on non-X11
platforms.
- \value WA_AlwaysStackOnTop Since Qt 5.4, this value forces QOpenGLWidget and
+ \value [since 5.4] WA_AlwaysStackOnTop Forces QOpenGLWidget and
QQuickWidget to be drawn last, on top of other widgets. Ignored for other
type of widgets. Setting this attribute breaks the stacking order, but
allows having a semi-transparent OpenGL widget with other widgets visible
@@ -1439,6 +1460,7 @@
\value Key_Help
\value Key_Direction_L
\value Key_Direction_R
+
\value Key_Space
\value Key_Any
\value Key_Exclam
@@ -1530,7 +1552,8 @@
\value Key_twosuperior
\value Key_threesuperior
\value Key_acute
- \value Key_mu
+ \value [since 6.7] Key_micro
+ \value Key_mu Deprecated alias for Key_micro
\value Key_paragraph
\value Key_periodcentered
\value Key_cedilla
@@ -1575,6 +1598,7 @@
\value Key_ssharp
\value Key_division
\value Key_ydiaeresis
+
\value Key_Multi_key
\value Key_Codeinput
\value Key_SingleCandidate
@@ -2222,11 +2246,17 @@
you call QWidget::activateWindow() manually).
\value FramelessWindowHint Produces a borderless window.
- The user cannot move or resize a borderless window via the window
- system. On X11, the result of the flag is dependent on the window manager and its
+
+ On X11, the result of the flag is dependent on the window manager and its
ability to understand Motif and/or NETWM hints. Most existing
modern window managers can handle this.
+ \note If the window manager relies on the frame to interactively manipulate
+ the window, the user can no longer move or resize the window via the window
+ system, but this side effect should not be relied on. To produce a fixed
+ size window that can not be resized, please set QWindow::setMinimumSize()
+ and QWindow::setMaximumSize() to the same size.
+
\value NoDropShadowWindowHint Disables window drop shadow on supporting platforms.
The \c CustomizeWindowHint flag is used to enable customization of
@@ -2659,7 +2689,8 @@
\value ImCursorRectangle The rectangle covering the area of the input cursor in widget coordinates.
\value ImFont The currently used font for text input.
\value ImCursorPosition The logical position of the cursor within the text surrounding the input area
- (see \c ImSurroundingText).
+ (see \c ImSurroundingText). The position does not incorporate the offset of
+ the cursor within the preedit area, as controlled by QInputMethodEvent::Cursor.
\value ImSurroundingText The plain text around the input area, for example the current paragraph.
\value ImCurrentSelection The currently selected text.
\value ImMaximumTextLength The maximum number of characters that the widget can hold. If there is no limit,
@@ -2670,7 +2701,9 @@
\value ImHints The hints for input method on expected input. (See Qt::InputMethodHints)
\value ImPreferredLanguage The preferred input language.
\value ImPlatformData Platform specific data for input method.
- \value ImAbsolutePosition The logical position of the cursor within the entire document.
+ \value ImAbsolutePosition The logical position of the cursor within the entire document. The position does
+ not incorporate the offset of the cursor within the preedit area, as controlled
+ by QInputMethodEvent::Cursor.
\value ImTextBeforeCursor The plain text before the cursor. The widget can decide how much text to return,
but \b{must} not return an empty string unless the cursor is at the start of the document.
\value ImTextAfterCursor The plain text after the cursor. The widget can decide how much text to return,
@@ -2758,8 +2791,7 @@
\value CheckStateRole This role is used to obtain the checked state of
an item. (Qt::CheckState)
\value InitialSortOrderRole This role is used to obtain the initial sort order
- of a header view section. (Qt::SortOrder). This
- role was introduced in Qt 4.8.
+ of a header view section. (Qt::SortOrder).
Accessibility roles (with associated types):
@@ -2862,7 +2894,10 @@
\value ElideLeft The ellipsis should appear at the beginning of the text.
\value ElideRight The ellipsis should appear at the end of the text.
\value ElideMiddle The ellipsis should appear in the middle of the text.
- \value ElideNone Ellipsis should NOT appear in the text.
+ \value ElideNone Ellipsis should NOT appear in the text. When passed to functions such as
+ QFontMetrics::elidedText(), this will cause the full string to return unless
+ the text contains multi-length variants. Elision in this case must be done
+ by clipping to the component width.
Qt::ElideMiddle is normally the most appropriate choice for URLs (e.g.,
"\l{http://bugreports.qt.io/browse/QTWEBSITE-13}{http://bugreports.qt.../QTWEBSITE-13/}"),
@@ -3027,6 +3062,11 @@
*/
/*!
+ \enum Qt::Disambiguated_t
+ \internal
+*/
+
+/*!
\enum Qt::CoordinateSystem
\since 4.6
@@ -3107,8 +3147,8 @@
the Qt::GestureStarted state and ending with a gesture in the
Qt::GestureFinished or Qt::GestureCanceled states.
- \value IgnoredGesturesPropagateToParent Since Qt 4.7, this flag allows you
- to fine-tune gesture event propagation. By setting the flag when
+ \value [since 4.7] IgnoredGesturesPropagateToParent Allows fine-tuning of
+ gesture event propagation. By setting the flag when
\l{QGraphicsObject::grabGesture()}{grabbing} a gesture all ignored partial
gestures will propagate to their parent items.
@@ -3196,6 +3236,26 @@
*/
/*!
+ \enum Qt::TimerId
+ \since 6.8
+ \relates QObject
+ \relates QTimer
+ \relates QChronoTimer
+
+ This is used to represent timer IDs (for example, QTimer and QChronoTimer).
+ The underlying type is \c int. You can use \l qToUnderlying() to convert
+ Qt::TimerId to \c int.
+
+ \value Invalid Represents a no-op timer ID; it's usage depends on the
+ context, for example, this is the value returned by QObject::startTimer()
+ to indicate it failed to start a timer; whereas QChronoTimer::id() returns
+ this value when the timer is inactive, that is, \c timer.isActive()
+ returns \c false.
+
+ \sa QTimer::id(), QChronoTimer::id(), QObject::startTimer()
+*/
+
+/*!
\enum Qt::ScrollPhase
\since 5.2
@@ -3291,6 +3351,38 @@
*/
/*!
+ \enum Qt::PermissionStatus
+
+ This enum describes the possible statuses of a permissions.
+
+ \value Undetermined
+ The permission status is not yet known. Permission should be requested
+ via QCoreApplication::requestPermission() to determine the actual status.
+ This status will never be the result of requesting a permission.
+
+ \value Granted
+ The user has explicitly granted the application the permission,
+ or the permission is known to not require user authorization on
+ the given platform.
+
+ \value Denied
+ The user has explicitly denied the application the requested permission,
+ or the permission is known to not be accessible or applicable to applications
+ on the given platform.
+
+ \note On Android, there is no \c Undetermined status by the platform's APIs.
+ Thus, if a permission is denied for an app,
+ \l QCoreApplication::checkPermission() returns \c Undetermined
+ by default until \l QCoreApplication::requestPermission() is called.
+ After that \l QCoreApplication::checkPermission() reports a non \c Undetermined
+ status.
+
+ \since 6.5
+ \sa QCoreApplication::requestPermission(), QCoreApplication::checkPermission(),
+ {Application Permissions}
+*/
+
+/*!
\enum Qt::ReturnByValueConstant
\since 5.15
diff --git a/src/corelib/global/qnativeinterface.h b/src/corelib/global/qnativeinterface.h
index 5e5c78beec..89f33651c5 100644
--- a/src/corelib/global/qnativeinterface.h
+++ b/src/corelib/global/qnativeinterface.h
@@ -1,47 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QNATIVEINTERFACE_H
#define QNATIVEINTERFACE_H
#include <QtCore/qglobal.h>
-#include <QtCore/qloggingcategory.h>
QT_BEGIN_NAMESPACE
@@ -69,6 +32,8 @@ QT_BEGIN_NAMESPACE
template <typename> \
friend struct QNativeInterface::Private::TypeInfo; \
public: \
+ NativeInterface() = default; \
+ Q_DISABLE_COPY_MOVE(NativeInterface)
// Revisioned interfaces only make sense when exposed through a base
// type via QT_DECLARE_NATIVE_INTERFACE_ACCESSOR, as the revision
@@ -157,12 +122,14 @@ namespace QNativeInterface::Private {
// of incompatible interface types read better.
template <typename I>
struct NativeInterface : TypeInfo<I> {};
-
- Q_CORE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcNativeInterface)
-
} // QNativeInterface::Private
// Declares an accessor for the native interface
+#ifdef Q_QDOC
+#define QT_DECLARE_NATIVE_INTERFACE_ACCESSOR(T) \
+ template <typename QNativeInterface> \
+ QNativeInterface *nativeInterface() const;
+#else
#define QT_DECLARE_NATIVE_INTERFACE_ACCESSOR(T) \
template <typename NativeInterface, typename TypeInfo = QNativeInterface::Private::NativeInterface<NativeInterface>, \
typename BaseType = T, std::enable_if_t<TypeInfo::template isCompatibleWith<T>, bool> = true> \
@@ -174,35 +141,7 @@ namespace QNativeInterface::Private {
protected: \
void *resolveInterface(const char *name, int revision) const; \
public:
-
-// Provides a definition for the interface destructor
-#define QT_DEFINE_NATIVE_INTERFACE_2(Namespace, InterfaceClass) \
- QT_PREPEND_NAMESPACE(Namespace)::InterfaceClass::~InterfaceClass() = default
-
-#define QT_DEFINE_NATIVE_INTERFACE(...) QT_OVERLOADED_MACRO(QT_DEFINE_NATIVE_INTERFACE, QNativeInterface, __VA_ARGS__)
-#define QT_DEFINE_PRIVATE_NATIVE_INTERFACE(...) QT_OVERLOADED_MACRO(QT_DEFINE_NATIVE_INTERFACE, QNativeInterface::Private, __VA_ARGS__)
-
-#define QT_NATIVE_INTERFACE_RETURN_IF(NativeInterface, baseType) \
- { \
- using QNativeInterface::Private::lcNativeInterface; \
- using QNativeInterface::Private::TypeInfo; \
- qCDebug(lcNativeInterface, "Comparing requested interface name %s with available %s", \
- name, TypeInfo<NativeInterface>::name()); \
- if (qstrcmp(name, TypeInfo<NativeInterface>::name()) == 0) { \
- qCDebug(lcNativeInterface, "Match for interface %s. Comparing revisions (requested %d / available %d)", \
- name, revision, TypeInfo<NativeInterface>::revision()); \
- if (revision == TypeInfo<NativeInterface>::revision()) { \
- qCDebug(lcNativeInterface) << "Full match. Returning dynamic cast of" << baseType; \
- return dynamic_cast<NativeInterface*>(baseType); \
- } else { \
- qCWarning(lcNativeInterface, "Native interface revision mismatch (requested %d / available %d) for interface %s", \
- revision, TypeInfo<NativeInterface>::revision(), name); \
- return nullptr; \
- } \
- } else { \
- qCDebug(lcNativeInterface, "No match for requested interface name %s", name); \
- } \
- }
+#endif
QT_END_NAMESPACE
diff --git a/src/corelib/global/qnativeinterface_p.h b/src/corelib/global/qnativeinterface_p.h
new file mode 100644
index 0000000000..aa7705e153
--- /dev/null
+++ b/src/corelib/global/qnativeinterface_p.h
@@ -0,0 +1,63 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QNATIVEINTERFACE_P_H
+#define QNATIVEINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qglobal_p.h>
+#include <QtCore/qloggingcategory.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtPrivate {
+Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcNativeInterface, Q_CORE_EXPORT)
+}
+
+// Provides a definition for the interface destructor
+#define QT_DEFINE_NATIVE_INTERFACE_2(Namespace, InterfaceClass) \
+ QT_PREPEND_NAMESPACE(Namespace)::InterfaceClass::~InterfaceClass() = default
+
+#define QT_DEFINE_NATIVE_INTERFACE(...) \
+ QT_OVERLOADED_MACRO(QT_DEFINE_NATIVE_INTERFACE, QNativeInterface, __VA_ARGS__)
+#define QT_DEFINE_PRIVATE_NATIVE_INTERFACE(...) \
+ QT_OVERLOADED_MACRO(QT_DEFINE_NATIVE_INTERFACE, QNativeInterface::Private, __VA_ARGS__)
+
+#define QT_NATIVE_INTERFACE_RETURN_IF(NativeInterface, baseType) \
+ { \
+ using QtPrivate::lcNativeInterface; \
+ using QNativeInterface::Private::TypeInfo; \
+ qCDebug(lcNativeInterface, "Comparing requested interface name %s with available %s", \
+ name, TypeInfo<NativeInterface>::name()); \
+ if (qstrcmp(name, TypeInfo<NativeInterface>::name()) == 0) { \
+ qCDebug(lcNativeInterface, \
+ "Match for interface %s. Comparing revisions (requested %d / available %d)", \
+ name, revision, TypeInfo<NativeInterface>::revision()); \
+ if (revision == TypeInfo<NativeInterface>::revision()) { \
+ qCDebug(lcNativeInterface) << "Full match. Returning dynamic cast of" << baseType; \
+ return dynamic_cast<NativeInterface *>(baseType); \
+ } else { \
+ qCWarning(lcNativeInterface, \
+ "Native interface revision mismatch (requested %d / available %d) for " \
+ "interface %s", \
+ revision, TypeInfo<NativeInterface>::revision(), name); \
+ return nullptr; \
+ } \
+ } else { \
+ qCDebug(lcNativeInterface, "No match for requested interface name %s", name); \
+ } \
+ }
+
+QT_END_NAMESPACE
+
+#endif // QNATIVEINTERFACE_P_H
diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp
index 63055a0b61..a46039c5da 100644
--- a/src/corelib/global/qnumeric.cpp
+++ b/src/corelib/global/qnumeric.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qnumeric.h"
#include "qnumeric_p.h"
@@ -44,61 +8,72 @@
QT_BEGIN_NAMESPACE
/*!
+ \headerfile <QtNumeric>
+ \inmodule QtCore
+ \title Qt Numeric Functions
+
+ \brief The <QtNumeric> header file provides common numeric functions.
+
+ The <QtNumeric> header file contains various numeric functions
+ for comparing and adjusting a numeric value.
+*/
+
+/*!
Returns \c true if the double \a {d} is equivalent to infinity.
- \relates <QtGlobal>
+ \relates <QtNumeric>
\sa qInf()
*/
Q_CORE_EXPORT bool qIsInf(double d) { return qt_is_inf(d); }
/*!
Returns \c true if the double \a {d} is not a number (NaN).
- \relates <QtGlobal>
+ \relates <QtNumeric>
*/
Q_CORE_EXPORT bool qIsNaN(double d) { return qt_is_nan(d); }
/*!
Returns \c true if the double \a {d} is a finite number.
- \relates <QtGlobal>
+ \relates <QtNumeric>
*/
Q_CORE_EXPORT bool qIsFinite(double d) { return qt_is_finite(d); }
/*!
Returns \c true if the float \a {f} is equivalent to infinity.
- \relates <QtGlobal>
+ \relates <QtNumeric>
\sa qInf()
*/
Q_CORE_EXPORT bool qIsInf(float f) { return qt_is_inf(f); }
/*!
Returns \c true if the float \a {f} is not a number (NaN).
- \relates <QtGlobal>
+ \relates <QtNumeric>
*/
Q_CORE_EXPORT bool qIsNaN(float f) { return qt_is_nan(f); }
/*!
Returns \c true if the float \a {f} is a finite number.
- \relates <QtGlobal>
+ \relates <QtNumeric>
*/
Q_CORE_EXPORT bool qIsFinite(float f) { return qt_is_finite(f); }
#if QT_CONFIG(signaling_nan)
/*!
Returns the bit pattern of a signalling NaN as a double.
- \relates <QtGlobal>
+ \relates <QtNumeric>
*/
Q_CORE_EXPORT double qSNaN() { return qt_snan(); }
#endif
/*!
Returns the bit pattern of a quiet NaN as a double.
- \relates <QtGlobal>
+ \relates <QtNumeric>
\sa qIsNaN()
*/
Q_CORE_EXPORT double qQNaN() { return qt_qnan(); }
/*!
Returns the bit pattern for an infinite number as a double.
- \relates <QtGlobal>
+ \relates <QtNumeric>
\sa qIsInf()
*/
Q_CORE_EXPORT double qInf() { return qt_inf(); }
@@ -107,7 +82,7 @@ Q_CORE_EXPORT double qInf() { return qt_inf(); }
\fn int qFpClassify(double val)
\fn int qFpClassify(float val)
- \relates <QtGlobal>
+ \relates <QtNumeric>
Classifies a floating-point value.
The return values are defined in \c{<cmath>}: returns one of the following,
@@ -159,7 +134,7 @@ static inline quint32 f2i(float f)
\sa qFuzzyCompare()
\since 5.2
- \relates <QtGlobal>
+ \relates <QtNumeric>
*/
Q_CORE_EXPORT quint32 qFloatDistance(float a, float b)
{
@@ -217,7 +192,7 @@ static inline quint64 d2i(double d)
\sa qFuzzyCompare()
\since 5.2
- \relates <QtGlobal>
+ \relates <QtNumeric>
*/
Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
{
@@ -256,6 +231,7 @@ Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
/*!
\fn template<typename T> bool qAddOverflow(T v1, T v2, T *result)
+ \relates <QtNumeric>
\since 6.1
Adds two values \a v1 and \a v2, of a numeric type \c T and records the
@@ -287,6 +263,7 @@ Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
/*!
\fn template<typename T> bool qSubOverflow(T v1, T v2, T *result)
+ \relates <QtNumeric>
\since 6.1
Subtracts \a v2 from \a v1 and records the resulting value in \a result. If
@@ -318,6 +295,7 @@ Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
/*!
\fn template<typename T> bool qMulOverflow(T v1, T v2, T *result)
+ \relates <QtNumeric>
\since 6.1
Multiplies \a v1 and \a v2, and records the resulting value in \a result. If
@@ -349,4 +327,170 @@ Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
This can be faster than calling the version with only variable arguments.
*/
+/*! \fn template <typename T> T qAbs(const T &t)
+ \relates <QtNumeric>
+
+ Compares \a t to the 0 of type T and returns the absolute
+ value. Thus if T is \e {double}, then \a t is compared to
+ \e{(double) 0}.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 10
+*/
+
+/*! \fn int qRound(double d)
+ \relates <QtNumeric>
+
+ Rounds \a d to the nearest integer.
+
+ Rounds half away from zero (e.g. 0.5 -> 1, -0.5 -> -1).
+
+ \note This function does not guarantee correctness for high precisions.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 11A
+
+ \note If the value \a d is outside the range of \c int,
+ the behavior is undefined.
+*/
+
+/*! \fn int qRound(float d)
+ \relates <QtNumeric>
+
+ Rounds \a d to the nearest integer.
+
+ Rounds half away from zero (e.g. 0.5f -> 1, -0.5f -> -1).
+
+ \note This function does not guarantee correctness for high precisions.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 11B
+
+ \note If the value \a d is outside the range of \c int,
+ the behavior is undefined.
+*/
+
+/*! \fn qint64 qRound64(double d)
+ \relates <QtNumeric>
+
+ Rounds \a d to the nearest 64-bit integer.
+
+ Rounds half away from zero (e.g. 0.5 -> 1, -0.5 -> -1).
+
+ \note This function does not guarantee correctness for high precisions.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 12A
+
+ \note If the value \a d is outside the range of \c qint64,
+ the behavior is undefined.
+*/
+
+/*! \fn qint64 qRound64(float d)
+ \relates <QtNumeric>
+
+ Rounds \a d to the nearest 64-bit integer.
+
+ Rounds half away from zero (e.g. 0.5f -> 1, -0.5f -> -1).
+
+ \note This function does not guarantee correctness for high precisions.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 12B
+
+ \note If the value \a d is outside the range of \c qint64,
+ the behavior is undefined.
+*/
+
+/*!
+ \fn bool qFuzzyCompare(double p1, double p2)
+ \relates <QtNumeric>
+ \since 4.4
+ \threadsafe
+
+ Compares the floating point value \a p1 and \a p2 and
+ returns \c true if they are considered equal, otherwise \c false.
+
+ Note that comparing values where either \a p1 or \a p2 is 0.0 will not work,
+ nor does comparing values where one of the values is NaN or infinity.
+ If one of the values is always 0.0, use qFuzzyIsNull instead. If one of the
+ values is likely to be 0.0, one solution is to add 1.0 to both values.
+
+ \snippet code/src_corelib_global_qglobal.cpp 46
+
+ The two numbers are compared in a relative way, where the
+ exactness is stronger the smaller the numbers are.
+*/
+
+/*!
+ \fn bool qFuzzyCompare(float p1, float p2)
+ \relates <QtNumeric>
+ \since 4.4
+ \threadsafe
+
+ Compares the floating point value \a p1 and \a p2 and
+ returns \c true if they are considered equal, otherwise \c false.
+
+ The two numbers are compared in a relative way, where the
+ exactness is stronger the smaller the numbers are.
+*/
+
+/*!
+ \fn bool qFuzzyIsNull(double d)
+ \relates <QtNumeric>
+ \since 4.4
+ \threadsafe
+
+ Returns true if the absolute value of \a d is within 0.000000000001 of 0.0.
+*/
+
+/*!
+ \fn bool qFuzzyIsNull(float f)
+ \relates <QtNumeric>
+ \since 4.4
+ \threadsafe
+
+ Returns true if the absolute value of \a f is within 0.00001f of 0.0.
+*/
+
+namespace QtNumericTests {
+
+template <typename T> static constexpr T max = std::numeric_limits<T>::max();
+template <typename T> static constexpr T min = std::numeric_limits<T>::min();
+
+static_assert(qt_saturate<short>(max<unsigned>) == max<short>);
+static_assert(qt_saturate<int>(max<unsigned>) == max<int>);
+static_assert(qt_saturate<qint64>(max<unsigned>) == qint64(max<unsigned>));
+
+static_assert(qt_saturate<short>(max<int>) == max<short>);
+static_assert(qt_saturate<unsigned>(max<int>) == unsigned(max<int>));
+static_assert(qt_saturate<qint64>(max<int>) == qint64(max<int>));
+
+static_assert(qt_saturate<short>(max<qint64>) == max<short>);
+static_assert(qt_saturate<int>(max<qint64>) == max<int>);
+static_assert(qt_saturate<unsigned>(max<qint64>) == max<unsigned>);
+static_assert(qt_saturate<quint64>(max<qint64>) == quint64(max<qint64>));
+
+static_assert(qt_saturate<short>(max<quint64>) == max<short>);
+static_assert(qt_saturate<int>(max<quint64>) == max<int>);
+static_assert(qt_saturate<unsigned>(max<quint64>) == max<unsigned>);
+static_assert(qt_saturate<qint64>(max<quint64>) == max<qint64>);
+
+static_assert(qt_saturate<short>(min<int>) == min<short>);
+static_assert(qt_saturate<qint64>(min<int>) == qint64(min<int>));
+static_assert(qt_saturate<unsigned>(min<int>) == 0);
+static_assert(qt_saturate<quint64>(min<int>) == 0);
+
+static_assert(qt_saturate<short>(min<qint64>) == min<short>);
+static_assert(qt_saturate<int>(min<qint64>) == min<int>);
+static_assert(qt_saturate<unsigned>(min<qint64>) == 0);
+static_assert(qt_saturate<quint64>(min<qint64>) == 0);
+
+} // namespace QtNumericTests
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h
index 49d795902c..2238c13da0 100644
--- a/src/corelib/global/qnumeric.h
+++ b/src/corelib/global/qnumeric.h
@@ -1,46 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QNUMERIC_H
#define QNUMERIC_H
-#include <QtCore/qglobal.h>
+#if 0
+#pragma qt_class(QtNumeric)
+#endif
+
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtcoreexports.h>
+#include <QtCore/qtypes.h>
+
#include <cmath>
#include <limits>
#include <type_traits>
@@ -114,11 +85,9 @@ Q_CORE_EXPORT quint64 qFloatDistance(double a, double b);
// size_t. Implementations for 8- and 16-bit types will work but may not be as
// efficient. Implementations for 64-bit may be missing on 32-bit platforms.
-#if (((defined(Q_CC_INTEL) ? (Q_CC_INTEL >= 1800 && !defined(Q_OS_WIN)) : defined(Q_CC_GNU)) \
- && Q_CC_GNU >= 500) \
- || __has_builtin(__builtin_add_overflow)) \
+#if (Q_CC_GNU >= 500 || __has_builtin(__builtin_add_overflow)) \
&& !(QT_POINTER_SIZE == 4 && defined(Q_CC_CLANG))
-// GCC 5, ICC 18, and Clang 3.8 have builtins to detect overflows
+// GCC 5 and Clang 3.8 have builtins to detect overflows
// 32 bit Clang has the builtins but tries to link a library which hasn't
#define Q_INTRINSIC_MUL_OVERFLOW64
@@ -219,7 +188,7 @@ qMulOverflow(T v1, T v2, T *r)
typename LargerInt::Signed, typename LargerInt::Unsigned>;
Larger lr = Larger(v1) * Larger(v2);
*r = T(lr);
- return lr > std::numeric_limits<T>::max() || lr < std::numeric_limits<T>::min();
+ return lr > (std::numeric_limits<T>::max)() || lr < (std::numeric_limits<T>::min)();
}
# if defined(Q_INTRINSIC_MUL_OVERFLOW64)
@@ -324,15 +293,15 @@ template <typename T, T V2> bool qMulOverflow(T v1, std::integral_constant<T, V2
} else if constexpr (V2 == -1) {
// multiplication by -1 is valid *except* for signed minimum values
// (necessary to avoid diving min() by -1, which is an overflow)
- if (v1 < 0 && v1 == std::numeric_limits<T>::min())
+ if (v1 < 0 && v1 == (std::numeric_limits<T>::min)())
return true;
*r = -v1;
return false;
} else {
// For 64-bit multiplications on 32-bit platforms, let's instead compare v1
// against the bounds that would overflow.
- constexpr T Highest = std::numeric_limits<T>::max() / V2;
- constexpr T Lowest = std::numeric_limits<T>::min() / V2;
+ constexpr T Highest = (std::numeric_limits<T>::max)() / V2;
+ constexpr T Lowest = (std::numeric_limits<T>::min)() / V2;
if constexpr (Highest > Lowest) {
if (v1 > Highest || v1 < Lowest)
return true;
@@ -350,9 +319,91 @@ template <typename T, T V2> bool qMulOverflow(T v1, std::integral_constant<T, V2
template <auto V2, typename T> bool qMulOverflow(T v1, T *r)
{
+ if constexpr (V2 == 2)
+ return qAddOverflow(v1, v1, r);
return qMulOverflow(v1, std::integral_constant<T, V2>{}, r);
}
+template <typename T>
+constexpr inline T qAbs(const T &t) { return t >= 0 ? t : -t; }
+
+// gcc < 10 doesn't have __has_builtin
+#if defined(Q_PROCESSOR_ARM_64) && (__has_builtin(__builtin_round) || defined(Q_CC_GNU)) && !defined(Q_CC_CLANG)
+// ARM64 has a single instruction that can do C++ rounding with conversion to integer.
+// Note current clang versions have non-constexpr __builtin_round, ### allow clang this path when they fix it.
+constexpr inline int qRound(double d)
+{ return int(__builtin_round(d)); }
+constexpr inline int qRound(float f)
+{ return int(__builtin_roundf(f)); }
+constexpr inline qint64 qRound64(double d)
+{ return qint64(__builtin_round(d)); }
+constexpr inline qint64 qRound64(float f)
+{ return qint64(__builtin_roundf(f)); }
+#elif defined(__SSE2__) && (__has_builtin(__builtin_copysign) || defined(Q_CC_GNU))
+// SSE has binary operations directly on floating point making copysign fast
+constexpr inline int qRound(double d)
+{ return int(d + __builtin_copysign(0.5, d)); }
+constexpr inline int qRound(float f)
+{ return int(f + __builtin_copysignf(0.5f, f)); }
+constexpr inline qint64 qRound64(double d)
+{ return qint64(d + __builtin_copysign(0.5, d)); }
+constexpr inline qint64 qRound64(float f)
+{ return qint64(f + __builtin_copysignf(0.5f, f)); }
+#else
+constexpr inline int qRound(double d)
+{ return d >= 0.0 ? int(d + 0.5) : int(d - 0.5); }
+constexpr inline int qRound(float d)
+{ return d >= 0.0f ? int(d + 0.5f) : int(d - 0.5f); }
+
+constexpr inline qint64 qRound64(double d)
+{ return d >= 0.0 ? qint64(d + 0.5) : qint64(d - 0.5); }
+constexpr inline qint64 qRound64(float d)
+{ return d >= 0.0f ? qint64(d + 0.5f) : qint64(d - 0.5f); }
+#endif
+
+namespace QtPrivate {
+template <typename T>
+constexpr inline const T &min(const T &a, const T &b) { return (a < b) ? a : b; }
+}
+
+[[nodiscard]] constexpr bool qFuzzyCompare(double p1, double p2)
+{
+ return (qAbs(p1 - p2) * 1000000000000. <= QtPrivate::min(qAbs(p1), qAbs(p2)));
+}
+
+[[nodiscard]] constexpr bool qFuzzyCompare(float p1, float p2)
+{
+ return (qAbs(p1 - p2) * 100000.f <= QtPrivate::min(qAbs(p1), qAbs(p2)));
+}
+
+[[nodiscard]] constexpr bool qFuzzyIsNull(double d)
+{
+ return qAbs(d) <= 0.000000000001;
+}
+
+[[nodiscard]] constexpr bool qFuzzyIsNull(float f)
+{
+ return qAbs(f) <= 0.00001f;
+}
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_FLOAT_COMPARE
+
+[[nodiscard]] constexpr bool qIsNull(double d) noexcept
+{
+ return d == 0.0;
+}
+
+[[nodiscard]] constexpr bool qIsNull(float f) noexcept
+{
+ return f == 0.0f;
+}
+
+QT_WARNING_POP
+
+inline int qIntCast(double f) { return int(f); }
+inline int qIntCast(float f) { return int(f); }
+
QT_END_NAMESPACE
#endif // QNUMERIC_H
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index 823a1812de..d40e6b964b 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2020 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2021 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QNUMERIC_P_H
#define QNUMERIC_P_H
@@ -54,11 +18,16 @@
#include "QtCore/private/qglobal_p.h"
#include "QtCore/qnumeric.h"
+#include "QtCore/qsimd.h"
#include <cmath>
#include <limits>
#include <type_traits>
-#if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || defined(Q_CC_INTEL))
+#ifndef __has_extension
+# define __has_extension(X) 0
+#endif
+
+#if !defined(Q_CC_MSVC) && defined(Q_OS_QNX)
# include <math.h>
# ifdef isnan
# define QT_MATH_H_DEFINES_MACROS
@@ -86,6 +55,8 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
+class qfloat16;
+
namespace qnumeric_std_wrapper {
#if defined(QT_MATH_H_DEFINES_MACROS)
# undef QT_MATH_H_DEFINES_MACROS
@@ -173,22 +144,38 @@ Q_DECL_CONST_FUNCTION static inline int qt_fpclassify(float f)
return qnumeric_std_wrapper::fpclassify(f);
}
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
namespace {
/*!
Returns true if the double \a v can be converted to type \c T, false if
it's out of range. If the conversion is successful, the converted value is
stored in \a value; if it was not successful, \a value will contain the
minimum or maximum of T, depending on the sign of \a d. If \c T is
- unsigned, then \a value contains the absolute value of \a v.
+ unsigned, then \a value contains the absolute value of \a v. If \c T is \c
+ float, an underflow is also signalled by returning false and setting \a
+ value to zero.
This function works for v containing infinities, but not NaN. It's the
caller's responsibility to exclude that possibility before calling it.
*/
-template<typename T>
-static inline bool convertDoubleTo(double v, T *value, bool allow_precision_upgrade = true)
+template <typename T> static inline std::enable_if_t<std::is_integral_v<T>, bool>
+convertDoubleTo(double v, T *value, bool allow_precision_upgrade = true)
{
- static_assert(std::numeric_limits<T>::is_integer);
+ static_assert(std::is_integral_v<T>);
+ constexpr bool TypeIsLarger = std::numeric_limits<T>::digits > std::numeric_limits<double>::digits;
+
+ if constexpr (TypeIsLarger) {
+ using S = std::make_signed_t<T>;
+ constexpr S max_mantissa = S(1) << std::numeric_limits<double>::digits;
+ // T has more bits than double's mantissa, so don't allow "upgrading"
+ // to T (makes it look like the number had more precision than really
+ // was transmitted)
+ if (!allow_precision_upgrade && !(v <= double(max_mantissa) && v >= double(-max_mantissa - 1)))
+ return false;
+ }
+
+ constexpr T Tmin = (std::numeric_limits<T>::min)();
+ constexpr T Tmax = (std::numeric_limits<T>::max)();
// The [conv.fpint] (7.10 Floating-integral conversions) section of the C++
// standard says only exact conversions are guaranteed. Converting
@@ -200,23 +187,90 @@ static inline bool convertDoubleTo(double v, T *value, bool allow_precision_upgr
// correct, but Clang, ICC and MSVC don't realize that it's a constant and
// the math call stays in the compiled code.
+#if defined(Q_PROCESSOR_X86_64) && defined(__SSE2__)
+ // Of course, UB doesn't apply if we use intrinsics, in which case we are
+ // allowed to dpeend on exactly the processor's behavior. This
+ // implementation uses the truncating conversions from Scalar Double to
+ // integral types (CVTTSD2SI and VCVTTSD2USI), which is documented to
+ // return the "indefinite integer value" if the range of the target type is
+ // exceeded. (only implemented for x86-64 to avoid having to deal with the
+ // non-existence of the 64-bit intrinsics on i386)
+
+ if (std::numeric_limits<T>::is_signed) {
+ __m128d mv = _mm_set_sd(v);
+# ifdef __AVX512F__
+ // use explicit round control and suppress exceptions
+ if (sizeof(T) > 4)
+ *value = T(_mm_cvtt_roundsd_i64(mv, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
+ else
+ *value = _mm_cvtt_roundsd_i32(mv, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+# else
+ *value = sizeof(T) > 4 ? T(_mm_cvttsd_si64(mv)) : _mm_cvttsd_si32(mv);
+# endif
+
+ // if *value is the "indefinite integer value", check if the original
+ // variable \a v is the same value (Tmin is an exact representation)
+ if (*value == Tmin && !_mm_ucomieq_sd(mv, _mm_set_sd(Tmin))) {
+ // v != Tmin, so it was out of range
+ if (v > 0)
+ *value = Tmax;
+ return false;
+ }
+
+ // convert the integer back to double and compare for equality with v,
+ // to determine if we've lost any precision
+ __m128d mi = _mm_setzero_pd();
+ mi = sizeof(T) > 4 ? _mm_cvtsi64_sd(mv, *value) : _mm_cvtsi32_sd(mv, *value);
+ return _mm_ucomieq_sd(mv, mi);
+ }
+
+# ifdef __AVX512F__
+ if (!std::numeric_limits<T>::is_signed) {
+ // Same thing as above, but this function operates on absolute values
+ // and the "indefinite integer value" for the 64-bit unsigned
+ // conversion (Tmax) is not representable in double, so it can never be
+ // the result of an in-range conversion. This is implemented for AVX512
+ // and later because of the unsigned conversion instruction. Converting
+ // to unsigned without losing an extra bit of precision prior to AVX512
+ // is left to the compiler below.
+
+ v = fabs(v);
+ __m128d mv = _mm_set_sd(v);
+
+ // use explicit round control and suppress exceptions
+ if (sizeof(T) > 4)
+ *value = T(_mm_cvtt_roundsd_u64(mv, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
+ else
+ *value = _mm_cvtt_roundsd_u32(mv, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+
+ if (*value == Tmax) {
+ // no double can have an exact value of quint64(-1), but they can
+ // quint32(-1), so we need to compare for that
+ if (TypeIsLarger || _mm_ucomieq_sd(mv, _mm_set_sd(Tmax)))
+ return false;
+ }
+
+ // return true if it was an exact conversion
+ __m128d mi = _mm_setzero_pd();
+ mi = sizeof(T) > 4 ? _mm_cvtu64_sd(mv, *value) : _mm_cvtu32_sd(mv, *value);
+ return _mm_ucomieq_sd(mv, mi);
+ }
+# endif
+#endif
+
double supremum;
if (std::numeric_limits<T>::is_signed) {
- supremum = -1.0 * std::numeric_limits<T>::min(); // -1 * (-2^63) = 2^63, exact (for T = qint64)
- *value = std::numeric_limits<T>::min();
- if (v < std::numeric_limits<T>::min())
+ supremum = -1.0 * Tmin; // -1 * (-2^63) = 2^63, exact (for T = qint64)
+ *value = Tmin;
+ if (v < Tmin)
return false;
} else {
using ST = typename std::make_signed<T>::type;
- supremum = -2.0 * std::numeric_limits<ST>::min(); // -2 * (-2^63) = 2^64, exact (for T = quint64)
+ supremum = -2.0 * (std::numeric_limits<ST>::min)(); // -2 * (-2^63) = 2^64, exact (for T = quint64)
v = fabs(v);
}
- if (std::is_integral<T>::value && sizeof(T) > 4 && !allow_precision_upgrade) {
- if (v > double(Q_INT64_C(1)<<53) || v < double(-((Q_INT64_C(1)<<53) + 1)))
- return false;
- }
- *value = std::numeric_limits<T>::max();
+ *value = Tmax;
if (v >= supremum)
return false;
@@ -231,6 +285,116 @@ QT_WARNING_DISABLE_FLOAT_COMPARE
QT_WARNING_POP
}
+template <typename T> static
+std::enable_if_t<std::is_floating_point_v<T> || std::is_same_v<T, qfloat16>, bool>
+convertDoubleTo(double v, T *value, bool allow_precision_upgrade = true)
+{
+ Q_UNUSED(allow_precision_upgrade);
+ constexpr T Huge = std::numeric_limits<T>::infinity();
+
+ if constexpr (std::numeric_limits<double>::max_exponent <=
+ std::numeric_limits<T>::max_exponent) {
+ // no UB can happen
+ *value = T(v);
+ return true;
+ }
+
+#if defined(__SSE2__) && (defined(Q_CC_GNU) || __has_extension(gnu_asm))
+ // The x86 CVTSD2SH instruction from SSE2 does what we want:
+ // - converts out-of-range doubles to ±infinity and sets #O
+ // - converts underflows to zero and sets #U
+ // We need to clear any previously-stored exceptions from it before the
+ // operation (3-cycle cost) and obtain the new state afterwards (1 cycle).
+
+ unsigned csr = _MM_MASK_MASK; // clear stored exception indicators
+ auto sse_check_result = [&](auto result) {
+ if ((csr & (_MM_EXCEPT_UNDERFLOW | _MM_EXCEPT_OVERFLOW)) == 0)
+ return true;
+ if (csr & _MM_EXCEPT_OVERFLOW)
+ return false;
+
+ // According to IEEE 754[1], #U is also set when the result is tiny and
+ // inexact, but still non-zero, so detect that (this won't generate
+ // good code for types without hardware support).
+ // [1] https://en.wikipedia.org/wiki/Floating-point_arithmetic#Exception_handling
+ return result != 0;
+ };
+
+ // Written directly in assembly because both Clang and GCC have been
+ // observed to reorder the STMXCSR instruction above the conversion
+ // operation. MSVC generates horrid code when using the intrinsics anyway,
+ // so it's not a loss.
+ // See https://github.com/llvm/llvm-project/issues/83661.
+ if constexpr (std::is_same_v<T, float>) {
+# ifdef __AVX__
+ asm ("vldmxcsr %[csr]\n\t"
+ "vcvtsd2ss %[in], %[in], %[out]\n\t"
+ "vstmxcsr %[csr]"
+ : [csr] "+m" (csr), [out] "=v" (*value) : [in] "v" (v));
+# else
+ asm ("ldmxcsr %[csr]\n\t"
+ "cvtsd2ss %[in], %[out]\n\t"
+ "stmxcsr %[csr]"
+ : [csr] "+m" (csr), [out] "=v" (*value) : [in] "v" (v));
+# endif
+ return sse_check_result(*value);
+ }
+
+# if defined(__F16C__) || defined(__AVX512FP16__)
+ if constexpr (sizeof(T) == 2 && std::numeric_limits<T>::max_exponent == 16) {
+ // qfloat16 or std::float16_t, but not std::bfloat16_t or std::bfloat8_t
+ auto doConvert = [&](auto *out) {
+ asm ("vldmxcsr %[csr]\n\t"
+# ifdef __AVX512FP16__
+ // AVX512FP16 & AVX10 have an instruction for this
+ "vcvtsd2sh %[in], %[in], %[out]\n\t"
+# else
+ "vcvtsd2ss %[in], %[in], %[out]\n\t" // sets DEST[MAXVL-1:128] := 0
+ "vcvtps2ph %[rc], %[out], %[out]\n\t"
+# endif
+ "vstmxcsr %[csr]"
+ : [csr] "+m" (csr), [out] "=v" (*out)
+ : [in] "v" (v), [rc] "i" (_MM_FROUND_CUR_DIRECTION)
+ );
+ return sse_check_result(out);
+ };
+
+ if constexpr (std::is_same_v<T, qfloat16> && !std::is_void_v<typename T::NativeType>) {
+ typename T::NativeType tmp;
+ bool b = doConvert(&tmp);
+ *value = tmp;
+ return b;
+ } else {
+# ifndef Q_CC_CLANG
+ // Clang can only implement this if it has a native FP16 type
+ return doConvert(value);
+# endif
+ }
+ }
+# endif
+#endif // __SSE2__ && inline assembly
+
+ if (!qt_is_finite(v) && std::numeric_limits<T>::has_infinity) {
+ // infinity (or NaN)
+ *value = T(v);
+ return true;
+ }
+
+ // Check for in-range value to ensure the conversion is not UB (see the
+ // comment above for Standard language).
+ if (std::fabs(v) > (std::numeric_limits<T>::max)()) {
+ *value = v < 0 ? -Huge : Huge;
+ return false;
+ }
+
+ *value = T(v);
+ if (v != 0 && *value == 0) {
+ // Underflow through loss of precision
+ return false;
+ }
+ return true;
+}
+
template <typename T> inline bool add_overflow(T v1, T v2, T *r) { return qAddOverflow(v1, v2, r); }
template <typename T> inline bool sub_overflow(T v1, T v2, T *r) { return qSubOverflow(v1, v2, r); }
template <typename T> inline bool mul_overflow(T v1, T v2, T *r) { return qMulOverflow(v1, v2, r); }
@@ -265,7 +429,42 @@ template <auto V2, typename T> bool mul_overflow(T v1, T *r)
return qMulOverflow<V2, T>(v1, r);
}
}
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
+
+/*
+ Safely narrows \a x to \c{To}. Let \c L be
+ \c{std::numeric_limit<To>::min()} and \c H be \c{std::numeric_limit<To>::max()}.
+
+ If \a x is less than L, returns L. If \a x is greater than H,
+ returns H. Otherwise, returns \c{To(x)}.
+*/
+template <typename To, typename From>
+static constexpr auto qt_saturate(From x)
+{
+ static_assert(std::is_integral_v<To>);
+ static_assert(std::is_integral_v<From>);
+
+ [[maybe_unused]]
+ constexpr auto Lo = (std::numeric_limits<To>::min)();
+ constexpr auto Hi = (std::numeric_limits<To>::max)();
+
+ if constexpr (std::is_signed_v<From> == std::is_signed_v<To>) {
+ // same signedness, we can accept regular integer conversion rules
+ return x < Lo ? Lo :
+ x > Hi ? Hi :
+ /*else*/ To(x);
+ } else {
+ if constexpr (std::is_signed_v<From>) { // ie. !is_signed_v<To>
+ if (x < From{0})
+ return To{0};
+ }
+
+ // from here on, x >= 0
+ using FromU = std::make_unsigned_t<From>;
+ using ToU = std::make_unsigned_t<To>;
+ return FromU(x) > ToU(Hi) ? Hi : To(x); // assumes Hi >= 0
+ }
+}
QT_END_NAMESPACE
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
index 3603852c82..d25a626b8d 100644
--- a/src/corelib/global/qoperatingsystemversion.cpp
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -1,43 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qoperatingsystemversion.h"
+
#if !defined(Q_OS_DARWIN) && !defined(Q_OS_WIN)
#include "qoperatingsystemversion_p.h"
#endif
@@ -49,7 +14,8 @@
#include <qversionnumber.h>
#include <qdebug.h>
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
+#include <QtCore/private/qjnihelpers_p.h>
#include <QJniObject>
#endif
@@ -93,7 +59,8 @@ QT_BEGIN_NAMESPACE
\row
\li Windows
\li dwMajorVersion, dwMinorVersion, and dwBuildNumber from
- \l{https://msdn.microsoft.com/en-us/library/mt723418.aspx}{RtlGetVersion} -
+ \l{https://docs.microsoft.com/en-us/windows/win32/devnotes/rtlgetversion}
+ {RtlGetVersion} -
note that this function ALWAYS return the version number of the
underlying operating system, as opposed to the shim underneath
GetVersionEx that hides the real version number if the
@@ -144,18 +111,23 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QOperatingSystemVersion QOperatingSystemVersion::current()
-
+ \fn QOperatingSystemVersion::current()
Returns a QOperatingSystemVersion indicating the current OS and its version number.
\sa currentType()
*/
+QOperatingSystemVersionBase QOperatingSystemVersionBase::current()
+{
+ static const QOperatingSystemVersionBase v = current_impl();
+ return v;
+}
+
#if !defined(Q_OS_DARWIN) && !defined(Q_OS_WIN)
-QOperatingSystemVersion QOperatingSystemVersion::current()
+QOperatingSystemVersionBase QOperatingSystemVersionBase::current_impl()
{
- QOperatingSystemVersion version;
+ QOperatingSystemVersionBase version;
version.m_os = currentType();
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#ifdef Q_OS_ANDROID
#ifndef QT_BOOTSTRAPPED
const QVersionNumber v = QVersionNumber::fromString(QJniObject::getStaticObjectField(
"android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString());
@@ -204,11 +176,13 @@ QOperatingSystemVersion QOperatingSystemVersion::current()
{ 9, 0 }, // API level 28
{ 10, 0 }, // API level 29
{ 11, 0 }, // API level 30
+ { 12, 0 }, // API level 31
+ { 12, 0 }, // API level 32
+ { 13, 0 }, // API level 33
};
// This will give us at least the first 2 version components
- const size_t versionIdx = size_t(QJniObject::getStaticField<jint>(
- "android/os/Build$VERSION", "SDK_INT")) - 1;
+ const size_t versionIdx = QtAndroidPrivate::androidSdkVersion() - 1;
if (versionIdx < sizeof(versions) / sizeof(versions[0])) {
version.m_major = versions[versionIdx].major;
version.m_minor = versions[versionIdx].minor;
@@ -225,13 +199,13 @@ QOperatingSystemVersion QOperatingSystemVersion::current()
}
#endif
-static inline int compareVersionComponents(int lhs, int rhs)
+static inline int compareVersionComponents(int lhs, int rhs) noexcept
{
return lhs >= 0 && rhs >= 0 ? lhs - rhs : 0;
}
-int QOperatingSystemVersion::compare(const QOperatingSystemVersion &v1,
- const QOperatingSystemVersion &v2)
+int QOperatingSystemVersionBase::compare(QOperatingSystemVersionBase v1,
+ QOperatingSystemVersionBase v2) noexcept
{
if (v1.m_major == v2.m_major) {
if (v1.m_minor == v2.m_minor) {
@@ -328,32 +302,32 @@ int QOperatingSystemVersion::compare(const QOperatingSystemVersion &v1,
\sa type()
*/
-QString QOperatingSystemVersion::name() const
+QString QOperatingSystemVersionBase::name(QOperatingSystemVersionBase osversion)
{
- switch (type()) {
- case QOperatingSystemVersion::Windows:
+ switch (osversion.type()) {
+ case QOperatingSystemVersionBase::Windows:
return QStringLiteral("Windows");
- case QOperatingSystemVersion::MacOS: {
- if (majorVersion() < 10)
+ case QOperatingSystemVersionBase::MacOS: {
+ if (osversion.majorVersion() < 10)
return QStringLiteral("Mac OS");
- if (majorVersion() == 10 && minorVersion() < 8)
+ if (osversion.majorVersion() == 10 && osversion.minorVersion() < 8)
return QStringLiteral("Mac OS X");
- if (majorVersion() == 10 && minorVersion() < 12)
+ if (osversion.majorVersion() == 10 && osversion.minorVersion() < 12)
return QStringLiteral("OS X");
return QStringLiteral("macOS");
}
- case QOperatingSystemVersion::IOS: {
- if (majorVersion() < 4)
+ case QOperatingSystemVersionBase::IOS: {
+ if (osversion.majorVersion() < 4)
return QStringLiteral("iPhone OS");
return QStringLiteral("iOS");
}
- case QOperatingSystemVersion::TvOS:
+ case QOperatingSystemVersionBase::TvOS:
return QStringLiteral("tvOS");
- case QOperatingSystemVersion::WatchOS:
+ case QOperatingSystemVersionBase::WatchOS:
return QStringLiteral("watchOS");
- case QOperatingSystemVersion::Android:
+ case QOperatingSystemVersionBase::Android:
return QStringLiteral("Android");
- case QOperatingSystemVersion::Unknown:
+ case QOperatingSystemVersionBase::Unknown:
default:
return QString();
}
@@ -367,13 +341,17 @@ QString QOperatingSystemVersion::name() const
*/
bool QOperatingSystemVersion::isAnyOfType(std::initializer_list<OSType> types) const
{
- for (const auto &t : qAsConst(types)) {
- if (type() == t)
- return true;
- }
- return false;
+ // ### Qt7: Remove this function
+ return std::find(types.begin(), types.end(), type()) != types.end();
}
+bool QOperatingSystemVersionBase::isAnyOfType(std::initializer_list<OSType> types, OSType type)
+{
+ return std::find(types.begin(), types.end(), type) != types.end();
+}
+
+#ifndef QT_BOOTSTRAPPED
+
/*!
\variable QOperatingSystemVersion::Windows7
\brief a version corresponding to Windows 7 (version 6.1).
@@ -400,13 +378,105 @@ const QOperatingSystemVersion QOperatingSystemVersion::Windows8_1 =
/*!
\variable QOperatingSystemVersion::Windows10
- \brief a version corresponding to Windows 10 (version 10.0).
+ \brief a version corresponding to general Windows 10 (version 10.0).
\since 5.9
*/
const QOperatingSystemVersion QOperatingSystemVersion::Windows10 =
QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10);
/*!
+ \variable QOperatingSystemVersion::Windows10_1809
+ \brief a version corresponding to Windows 10 October 2018 Update
+ Version 1809 (version 10.0.17763).
+ \since 6.3
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows10_1809;
+
+/*!
+ \variable QOperatingSystemVersion::Windows10_1903
+ \brief a version corresponding to Windows 10 May 2019 Update
+ Version 1903 (version 10.0.18362).
+ \since 6.3
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows10_1903;
+
+/*!
+ \variable QOperatingSystemVersion::Windows10_1909
+ \brief a version corresponding to Windows 10 November 2019 Update
+ Version 1909 (version 10.0.18363).
+ \since 6.3
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows10_1909;
+
+/*!
+ \variable QOperatingSystemVersion::Windows10_2004
+ \brief a version corresponding to Windows 10 May 2020 Update
+ Version 2004 (version 10.0.19041).
+ \since 6.3
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows10_2004;
+
+/*!
+ \variable QOperatingSystemVersion::Windows10_20H2
+ \brief a version corresponding to Windows 10 October 2020 Update
+ Version 20H2 (version 10.0.19042).
+ \since 6.3
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows10_20H2;
+
+/*!
+ \variable QOperatingSystemVersion::Windows10_21H1
+ \brief a version corresponding to Windows 10 May 2021 Update
+ Version 21H1 (version 10.0.19043).
+ \since 6.3
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows10_21H1;
+
+/*!
+ \variable QOperatingSystemVersion::Windows10_21H2
+ \brief a version corresponding to Windows 10 November 2021 Update
+ Version 21H2 (version 10.0.19044).
+ \since 6.3
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows10_21H2;
+
+/*!
+ \variable QOperatingSystemVersion::Windows10_22H2
+ \brief a version corresponding to Windows 10 October 2022 Update
+ Version 22H2 (version 10.0.19045).
+ \since 6.5
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows10_22H2;
+
+/*!
+ \variable QOperatingSystemVersion::Windows11
+ \brief a version corresponding to the initial release of Windows 11
+ (version 10.0.22000).
+ \since 6.3
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows11;
+
+/*!
+ \variable QOperatingSystemVersion::Windows11_21H2
+ \brief a version corresponding to Windows 11 Version 21H2 (version 10.0.22000).
+ \since 6.4
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows11_21H2;
+
+/*!
+ \variable QOperatingSystemVersion::Windows11_22H2
+ \brief a version corresponding to Windows 11 Version 22H2 (version 10.0.22621).
+ \since 6.4
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Windows11_22H2;
+
+/*!
+ \variable QOperatingSystemVersion::Windows11_23H2
+ \brief a version corresponding to Windows 11 Version 23H2 (version 10.0.22631).
+ \since 6.6
+ */
+
+/*!
\variable QOperatingSystemVersion::OSXMavericks
\brief a version corresponding to OS X Mavericks (version 10.9).
\since 5.9
@@ -464,24 +534,32 @@ const QOperatingSystemVersion QOperatingSystemVersion::MacOSCatalina =
/*!
\variable QOperatingSystemVersion::MacOSBigSur
- \brief a version corresponding to macOS Big Sur
-
- The actual version number depends on whether the application was built
- using the Xcode 12 SDK. If it was, the version number corresponds
- to macOS 11.0. If not it will correspond to macOS 10.16.
-
- By comparing QOperatingSystemVersion::current() to this constant
- you will always end up comparing to the right version number.
+ \brief a version corresponding to macOS Big Sur (version 11).
\since 6.0
*/
-const QOperatingSystemVersion QOperatingSystemVersion::MacOSBigSur = [] {
-#if defined(Q_OS_DARWIN)
- if (QMacVersion::buildSDK(QMacVersion::ApplicationBinary) >= QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 16))
- return QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 11, 0);
- else
-#endif
- return QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 16);
-}();
+const QOperatingSystemVersion QOperatingSystemVersion::MacOSBigSur =
+ QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 11, 0);
+
+/*!
+ \variable QOperatingSystemVersion::MacOSMonterey
+ \brief a version corresponding to macOS Monterey (version 12).
+ \since 6.3
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::MacOSMonterey =
+ QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 12, 0);
+
+/*!
+ \variable QOperatingSystemVersion::MacOSVentura
+ \brief a version corresponding to macOS Ventura (version 13).
+ \since 6.4
+*/
+const QOperatingSystemVersionBase QOperatingSystemVersion::MacOSVentura;
+
+/*!
+ \variable QOperatingSystemVersion::MacOSSonoma
+ \brief a version corresponding to macOS Sonoma (version 14).
+ \since 6.5
+*/
/*!
\variable QOperatingSystemVersion::AndroidJellyBean
@@ -599,6 +677,35 @@ const QOperatingSystemVersion QOperatingSystemVersion::Android10 =
const QOperatingSystemVersion QOperatingSystemVersion::Android11 =
QOperatingSystemVersion(QOperatingSystemVersion::Android, 11, 0);
+/*!
+ \variable QOperatingSystemVersion::Android12
+ \brief a version corresponding to Android 12 (version 12.0, API level 31).
+ \since 6.5
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Android12;
+
+/*!
+ \variable QOperatingSystemVersion::Android12L
+ \brief a version corresponding to Android 12L (version 12.0, API level 32).
+ \since 6.5
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Android12L;
+
+/*!
+ \variable QOperatingSystemVersion::Android13
+ \brief a version corresponding to Android 13 (version 13.0, API level 33).
+ \since 6.5
+ */
+const QOperatingSystemVersionBase QOperatingSystemVersion::Android13;
+
+/*!
+ \variable QOperatingSystemVersion::Android14
+ \brief a version corresponding to Android 14 (version 14.0, API level 34).
+ \since 6.7
+ */
+
+#endif // !QT_BOOTSTRAPPED
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QOperatingSystemVersion &ov)
{
diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h
index c884e0e3e8..6aecdef341 100644
--- a/src/corelib/global/qoperatingsystemversion.h
+++ b/src/corelib/global/qoperatingsystemversion.h
@@ -1,43 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qglobal.h>
+#include <QtCore/qcompare.h>
#include <QtCore/qversionnumber.h>
#ifndef QOPERATINGSYSTEMVERSION_H
@@ -45,11 +10,147 @@
QT_BEGIN_NAMESPACE
+#if 0
+# pragma qt_class(QOperatingSystemVersionBase)
+# pragma qt_class(QOperatingSystemVersion)
+# pragma qt_sync_stop_processing // we have some ifdef'ery fooling syncqt
+#endif
+
class QString;
-class Q_CORE_EXPORT QOperatingSystemVersion
+class QOperatingSystemVersionBase
+{
+public:
+ // ### Qt 7: Keep synchronized with the copy in QOperatingSystemVersion until Qt7,
+ // then remove this comment :)
+ enum OSType {
+ Unknown = 0,
+ Windows,
+ MacOS,
+ IOS,
+ TvOS,
+ WatchOS,
+ Android
+ };
+
+ constexpr QOperatingSystemVersionBase(OSType osType,
+ int vmajor, int vminor = -1, int vmicro = -1)
+ : m_os(osType),
+ m_major(vmajor),
+ m_minor(vminor),
+ m_micro(vmicro)
+ { }
+
+ static Q_CORE_EXPORT QOperatingSystemVersionBase current();
+ static Q_CORE_EXPORT QString name(QOperatingSystemVersionBase osversion);
+ static Q_CORE_EXPORT bool isAnyOfType(std::initializer_list<OSType> types, OSType type);
+
+ static constexpr OSType currentType()
+ {
+#if defined(Q_OS_WIN)
+ return Windows;
+#elif defined(Q_OS_MACOS)
+ return MacOS;
+#elif defined(Q_OS_IOS)
+ return IOS;
+#elif defined(Q_OS_TVOS)
+ return TvOS;
+#elif defined(Q_OS_WATCHOS)
+ return WatchOS;
+#elif defined(Q_OS_ANDROID)
+ return Android;
+#else
+ return Unknown;
+#endif
+ }
+
+ inline QVersionNumber version() const { return QVersionNumber(m_major, m_minor, m_micro); }
+
+ constexpr int majorVersion() const { return m_major; }
+ constexpr int minorVersion() const { return m_minor; }
+ constexpr int microVersion() const { return m_micro; }
+
+ constexpr int segmentCount() const
+ { return m_micro >= 0 ? 3 : m_minor >= 0 ? 2 : m_major >= 0 ? 1 : 0; }
+
+ inline bool isAnyOfType(std::initializer_list<OSType> types) const
+ {
+ return QOperatingSystemVersionBase::isAnyOfType(types, type());
+ }
+ constexpr OSType type() const { return m_os; }
+ inline QString name() const { return name(*this); }
+
+protected:
+ static Q_CORE_EXPORT int compare(QOperatingSystemVersionBase v1,
+ QOperatingSystemVersionBase v2) noexcept;
+
+ friend Qt::partial_ordering compareThreeWay(const QOperatingSystemVersionBase &lhs,
+ const QOperatingSystemVersionBase &rhs) noexcept
+ {
+ if (lhs.type() != rhs.type())
+ return Qt::partial_ordering::unordered;
+ const int res = QOperatingSystemVersionBase::compare(lhs, rhs);
+ return Qt::compareThreeWay(res, 0);
+ }
+#ifdef __cpp_lib_three_way_comparison
+ friend std::partial_ordering
+ operator<=>(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
+ { return compareThreeWay(lhs, rhs); }
+#else
+ friend bool
+ operator>(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
+ { return is_gt(compareThreeWay(lhs, rhs)); }
+
+ friend bool
+ operator>=(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
+ { return is_gteq(compareThreeWay(lhs, rhs)); }
+
+ friend bool
+ operator<(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
+ { return is_lt(compareThreeWay(lhs, rhs)); }
+
+ friend bool
+ operator<=(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
+ { return is_lteq(compareThreeWay(lhs, rhs)); }
+#endif
+
+ QOperatingSystemVersionBase() = default;
+private:
+ static QOperatingSystemVersionBase current_impl();
+
+ OSType m_os;
+ int m_major;
+ int m_minor;
+ int m_micro;
+};
+
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) && !defined(Q_QDOC)
+class QOperatingSystemVersionUnexported : public QOperatingSystemVersionBase
+{
+public:
+ using QOperatingSystemVersionBase::QOperatingSystemVersionBase;
+ constexpr QOperatingSystemVersionUnexported(QOperatingSystemVersionBase other) noexcept
+ : QOperatingSystemVersionBase(other) {}
+#else
+class QOperatingSystemVersion : public QOperatingSystemVersionBase
+{
+ using QOperatingSystemVersionUnexported = QOperatingSystemVersionBase;
+#endif
+
+ // ### Qt7: Regroup with the rest below
+ static constexpr QOperatingSystemVersionBase MacOSSonoma { QOperatingSystemVersionBase::MacOS, 14, 0 };
+ static constexpr QOperatingSystemVersionBase Android14 { QOperatingSystemVersionBase::Android, 14, 0 };
+ static constexpr QOperatingSystemVersionBase Windows11_23H2 { QOperatingSystemVersionBase::Windows, 10, 0, 22631 };
+
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) && !defined(Q_QDOC)
+};
+
+class Q_CORE_EXPORT QOperatingSystemVersion : public QOperatingSystemVersionUnexported
{
+#endif
public:
+ // ### Qt7: Remove. Keep synchronized with QOperatingSystemVersionBase::OSType until then!
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
enum OSType {
Unknown = 0,
Windows,
@@ -59,7 +160,12 @@ public:
WatchOS,
Android
};
+#endif
+ // ### Qt7: remove the branch with static const variables. Then group and
+ // sort the inline ones. Until then, new entries should be added to
+ // QOperatingSystemVersionUnexported.
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
static const QOperatingSystemVersion Windows7;
static const QOperatingSystemVersion Windows8;
static const QOperatingSystemVersion Windows8_1;
@@ -73,6 +179,7 @@ public:
static const QOperatingSystemVersion MacOSMojave;
static const QOperatingSystemVersion MacOSCatalina;
static const QOperatingSystemVersion MacOSBigSur;
+ static const QOperatingSystemVersion MacOSMonterey;
static const QOperatingSystemVersion AndroidJellyBean;
static const QOperatingSystemVersion AndroidJellyBean_MR1;
@@ -88,69 +195,99 @@ public:
static const QOperatingSystemVersion AndroidPie;
static const QOperatingSystemVersion Android10;
static const QOperatingSystemVersion Android11;
+#else
+ static constexpr QOperatingSystemVersionBase Windows7 { QOperatingSystemVersionBase::Windows, 6, 1 };
+ static constexpr QOperatingSystemVersionBase Windows8 { QOperatingSystemVersionBase::Windows, 6, 2 };
+ static constexpr QOperatingSystemVersionBase Windows8_1 { QOperatingSystemVersionBase::Windows, 6, 3 };
+ static constexpr QOperatingSystemVersionBase Windows10 { QOperatingSystemVersionBase::Windows, 10 };
- constexpr QOperatingSystemVersion(OSType osType,
- int vmajor, int vminor = -1, int vmicro = -1)
- : m_os(osType),
- m_major(qMax(-1, vmajor)),
- m_minor(vmajor < 0 ? -1 : qMax(-1, vminor)),
- m_micro(vmajor < 0 || vminor < 0 ? -1 : qMax(-1, vmicro))
- { }
+ static constexpr QOperatingSystemVersionBase OSXMavericks { QOperatingSystemVersionBase::MacOS, 10, 9 };
+ static constexpr QOperatingSystemVersionBase OSXYosemite { QOperatingSystemVersionBase::MacOS, 10, 10 };
+ static constexpr QOperatingSystemVersionBase OSXElCapitan { QOperatingSystemVersionBase::MacOS, 10, 11 };
+ static constexpr QOperatingSystemVersionBase MacOSSierra { QOperatingSystemVersionBase::MacOS, 10, 12 };
+ static constexpr QOperatingSystemVersionBase MacOSHighSierra { QOperatingSystemVersionBase::MacOS, 10, 13 };
+ static constexpr QOperatingSystemVersionBase MacOSMojave { QOperatingSystemVersionBase::MacOS, 10, 14 };
+ static constexpr QOperatingSystemVersionBase MacOSCatalina { QOperatingSystemVersionBase::MacOS, 10, 15 };
+ static constexpr QOperatingSystemVersionBase MacOSBigSur = { QOperatingSystemVersionBase::MacOS, 11, 0 };
+ static constexpr QOperatingSystemVersionBase MacOSMonterey = { QOperatingSystemVersionBase::MacOS, 12, 0 };
+
+ static constexpr QOperatingSystemVersionBase AndroidJellyBean { QOperatingSystemVersionBase::Android, 4, 1 };
+ static constexpr QOperatingSystemVersionBase AndroidJellyBean_MR1 { QOperatingSystemVersionBase::Android, 4, 2 };
+ static constexpr QOperatingSystemVersionBase AndroidJellyBean_MR2 { QOperatingSystemVersionBase::Android, 4, 3 };
+ static constexpr QOperatingSystemVersionBase AndroidKitKat { QOperatingSystemVersionBase::Android, 4, 4 };
+ static constexpr QOperatingSystemVersionBase AndroidLollipop { QOperatingSystemVersionBase::Android, 5, 0 };
+ static constexpr QOperatingSystemVersionBase AndroidLollipop_MR1 { QOperatingSystemVersionBase::Android, 5, 1 };
+ static constexpr QOperatingSystemVersionBase AndroidMarshmallow { QOperatingSystemVersionBase::Android, 6, 0 };
+ static constexpr QOperatingSystemVersionBase AndroidNougat { QOperatingSystemVersionBase::Android, 7, 0 };
+ static constexpr QOperatingSystemVersionBase AndroidNougat_MR1 { QOperatingSystemVersionBase::Android, 7, 1 };
+ static constexpr QOperatingSystemVersionBase AndroidOreo { QOperatingSystemVersionBase::Android, 8, 0 };
+ static constexpr QOperatingSystemVersionBase AndroidOreo_MR1 { QOperatingSystemVersionBase::Android, 8, 1 };
+ static constexpr QOperatingSystemVersionBase AndroidPie { QOperatingSystemVersionBase::Android, 9, 0 };
+ static constexpr QOperatingSystemVersionBase Android10 { QOperatingSystemVersionBase::Android, 10, 0 };
+ static constexpr QOperatingSystemVersionBase Android11 { QOperatingSystemVersionBase::Android, 11, 0 };
+#endif
+
+ static constexpr QOperatingSystemVersionBase Windows10_1809 { QOperatingSystemVersionBase::Windows, 10, 0, 17763 }; // RS5
+ static constexpr QOperatingSystemVersionBase Windows10_1903 { QOperatingSystemVersionBase::Windows, 10, 0, 18362 }; // 19H1
+ static constexpr QOperatingSystemVersionBase Windows10_1909 { QOperatingSystemVersionBase::Windows, 10, 0, 18363 }; // 19H2
+ static constexpr QOperatingSystemVersionBase Windows10_2004 { QOperatingSystemVersionBase::Windows, 10, 0, 19041 }; // 20H1
+ static constexpr QOperatingSystemVersionBase Windows10_20H2 { QOperatingSystemVersionBase::Windows, 10, 0, 19042 };
+ static constexpr QOperatingSystemVersionBase Windows10_21H1 { QOperatingSystemVersionBase::Windows, 10, 0, 19043 };
+ static constexpr QOperatingSystemVersionBase Windows10_21H2 { QOperatingSystemVersionBase::Windows, 10, 0, 19044 };
+ static constexpr QOperatingSystemVersionBase Windows10_22H2 { QOperatingSystemVersionBase::Windows, 10, 0, 19045 };
+ static constexpr QOperatingSystemVersionBase Windows11 { QOperatingSystemVersionBase::Windows, 10, 0, 22000 };
+ static constexpr QOperatingSystemVersionBase Windows11_21H2 = Windows11;
+ static constexpr QOperatingSystemVersionBase Windows11_22H2 { QOperatingSystemVersionBase::Windows, 10, 0, 22621 };
+
+ static constexpr QOperatingSystemVersionBase Android12 { QOperatingSystemVersionBase::Android, 12, 0 };
+ static constexpr QOperatingSystemVersionBase Android12L { QOperatingSystemVersionBase::Android, 12, 0 };
+ static constexpr QOperatingSystemVersionBase Android13 { QOperatingSystemVersionBase::Android, 13, 0 };
+ static constexpr QOperatingSystemVersionBase MacOSVentura { QOperatingSystemVersionBase::MacOS, 13, 0 };
+
+ constexpr QOperatingSystemVersion(const QOperatingSystemVersionBase &osversion)
+ : QOperatingSystemVersionUnexported(osversion) {}
+
+ constexpr QOperatingSystemVersion(OSType osType, int vmajor, int vminor = -1, int vmicro = -1)
+ : QOperatingSystemVersionUnexported(QOperatingSystemVersionBase::OSType(osType), vmajor, vminor,
+ vmicro)
+ {
+ }
+
+#if QT_CORE_REMOVED_SINCE(6, 3) || defined(Q_QDOC)
static QOperatingSystemVersion current();
+#endif
static constexpr OSType currentType()
{
-#if defined(Q_OS_WIN)
- return Windows;
-#elif defined(Q_OS_MACOS)
- return MacOS;
-#elif defined(Q_OS_IOS)
- return IOS;
-#elif defined(Q_OS_TVOS)
- return TvOS;
-#elif defined(Q_OS_WATCHOS)
- return WatchOS;
-#elif defined(Q_OS_ANDROID)
- return Android;
-#else
- return Unknown;
-#endif
+ return OSType(QOperatingSystemVersionBase::currentType());
}
- QVersionNumber version() const { return QVersionNumber(m_major, m_minor, m_micro); }
+#if QT_CORE_REMOVED_SINCE(6, 3) || defined(Q_QDOC)
+ QVersionNumber version() const { return QOperatingSystemVersionBase::version(); }
- constexpr int majorVersion() const { return m_major; }
- constexpr int minorVersion() const { return m_minor; }
- constexpr int microVersion() const { return m_micro; }
+ constexpr int majorVersion() const { return QOperatingSystemVersionBase::majorVersion(); }
+ constexpr int minorVersion() const { return QOperatingSystemVersionBase::minorVersion(); }
+ constexpr int microVersion() const { return QOperatingSystemVersionBase::microVersion(); }
constexpr int segmentCount() const
- { return m_micro >= 0 ? 3 : m_minor >= 0 ? 2 : m_major >= 0 ? 1 : 0; }
+ { return QOperatingSystemVersionBase::segmentCount(); }
+#endif // QT_CORE_REMOVED_SINCE(6, 3)
- bool isAnyOfType(std::initializer_list<OSType> types) const;
- constexpr OSType type() const { return m_os; }
+ constexpr OSType type() const { return OSType(QOperatingSystemVersionBase::type()); }
+ QT7_ONLY(Q_CORE_EXPORT) bool isAnyOfType(std::initializer_list<OSType> types) const;
+#if QT_CORE_REMOVED_SINCE(6, 3) || defined(Q_QDOC)
QString name() const;
-
- friend bool operator>(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
- { return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) > 0; }
-
- friend bool operator>=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
- { return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) >= 0; }
-
- friend bool operator<(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
- { return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) < 0; }
-
- friend bool operator<=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
- { return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) <= 0; }
+#endif
private:
QOperatingSystemVersion() = default;
- OSType m_os;
- int m_major;
- int m_minor;
- int m_micro;
- static int compare(const QOperatingSystemVersion &v1, const QOperatingSystemVersion &v2);
+#if QT_CORE_REMOVED_SINCE(6, 3)
+ // ### Qt 7: Remove. It's only here for backwards compat with previous inline calls.
+ [[maybe_unused]] static int compare(const QOperatingSystemVersion &v1,
+ const QOperatingSystemVersion &v2);
+#endif
};
Q_DECLARE_TYPEINFO(QOperatingSystemVersion, Q_PRIMITIVE_TYPE);
diff --git a/src/corelib/global/qoperatingsystemversion_darwin.mm b/src/corelib/global/qoperatingsystemversion_darwin.mm
index d8b927ff5d..f8d9fbd027 100644
--- a/src/corelib/global/qoperatingsystemversion_darwin.mm
+++ b/src/corelib/global/qoperatingsystemversion_darwin.mm
@@ -1,56 +1,57 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qoperatingsystemversion_p.h"
+
#import <Foundation/Foundation.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qversionnumber.h>
+
+#if !defined(QT_BOOTSTRAPPED)
+#include <QtCore/qprocess.h>
+#endif
+
QT_BEGIN_NAMESPACE
-QOperatingSystemVersion QOperatingSystemVersion::current()
+using namespace Qt::StringLiterals;
+
+QOperatingSystemVersionBase QOperatingSystemVersionBase::current_impl()
{
NSOperatingSystemVersion osv = NSProcessInfo.processInfo.operatingSystemVersion;
- QOperatingSystemVersion v;
- v.m_os = currentType();
- v.m_major = osv.majorVersion;
- v.m_minor = osv.minorVersion;
- v.m_micro = osv.patchVersion;
- return v;
+ QVersionNumber versionNumber(osv.majorVersion, osv.minorVersion, osv.patchVersion);
+
+ if (versionNumber.majorVersion() == 10 && versionNumber.minorVersion() >= 16) {
+ // The process is running in system version compatibility mode,
+ // due to the executable being built against a pre-macOS 11 SDK.
+ // This might happen even if we require a more recent SDK for
+ // building Qt applications, as the Qt 'app' might be a plugin
+ // hosted inside a host that used an earlier SDK. But, since we
+ // require a recent SDK for the Qt app itself, the application
+ // should be prepared for versions numbers beyond 10, and we can
+ // resolve the real version number here.
+#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(process)
+ QProcess sysctl;
+ QProcessEnvironment nonCompatEnvironment;
+ nonCompatEnvironment.insert("SYSTEM_VERSION_COMPAT"_L1, "0"_L1);
+ sysctl.setProcessEnvironment(nonCompatEnvironment);
+ sysctl.start("/usr/sbin/sysctl"_L1, QStringList() << "-b"_L1 << "kern.osproductversion"_L1);
+ if (sysctl.waitForFinished()) {
+ auto versionString = QString::fromLatin1(sysctl.readAll());
+ auto nonCompatSystemVersion = QVersionNumber::fromString(versionString);
+ if (!nonCompatSystemVersion.isNull())
+ versionNumber = nonCompatSystemVersion;
+ }
+#endif
+ }
+
+ QOperatingSystemVersionBase operatingSystemVersion;
+ operatingSystemVersion.m_os = currentType();
+ operatingSystemVersion.m_major = versionNumber.majorVersion();
+ operatingSystemVersion.m_minor = versionNumber.minorVersion();
+ operatingSystemVersion.m_micro = versionNumber.microVersion();
+
+ return operatingSystemVersion;
}
QT_END_NAMESPACE
diff --git a/src/corelib/global/qoperatingsystemversion_p.h b/src/corelib/global/qoperatingsystemversion_p.h
index 6922f4ad54..5d1480d524 100644
--- a/src/corelib/global/qoperatingsystemversion_p.h
+++ b/src/corelib/global/qoperatingsystemversion_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QOPERATINGSYSTEMVERSION_P_H
#define QOPERATINGSYSTEMVERSION_P_H
@@ -52,6 +16,7 @@
//
#include "qoperatingsystemversion.h"
+#include "private/qglobal_p.h"
#ifdef Q_OS_WIN
#include <qt_windows.h>
diff --git a/src/corelib/global/qoperatingsystemversion_win.cpp b/src/corelib/global/qoperatingsystemversion_win.cpp
index eb58b60788..a209fb17b6 100644
--- a/src/corelib/global/qoperatingsystemversion_win.cpp
+++ b/src/corelib/global/qoperatingsystemversion_win.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qoperatingsystemversion_win_p.h"
@@ -50,10 +14,7 @@ static inline OSVERSIONINFOEX determineWinOsVersion()
{
OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0};
-#define GetProcAddressA GetProcAddress
-#define pGetModuleHandle GetModuleHandleW
-
- HMODULE ntdll = pGetModuleHandle(L"ntdll.dll");
+ HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
if (Q_UNLIKELY(!ntdll))
return result;
@@ -63,7 +24,7 @@ static inline OSVERSIONINFOEX determineWinOsVersion()
// because linking to it at load time will not pass the Windows App Certification Kit
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910.aspx
RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(
- reinterpret_cast<QFunctionPointer>(GetProcAddressA(ntdll, "RtlGetVersion")));
+ reinterpret_cast<QFunctionPointer>(GetProcAddress(ntdll, "RtlGetVersion")));
if (Q_UNLIKELY(!pRtlGetVersion))
return result;
@@ -90,25 +51,18 @@ OSVERSIONINFOEX qWindowsVersionInfo()
result.wServicePackMinor = 0;
const QByteArray winVerOverride = qgetenv("QT_WINVER_OVERRIDE");
- if (winVerOverride == "WINDOWS7" || winVerOverride == "2008_R2") {
- result.dwMajorVersion = 6;
- result.dwMinorVersion = 1;
- } else if (winVerOverride == "WINDOWS8" || winVerOverride == "2012") {
- result.dwMajorVersion = 6;
- result.dwMinorVersion = 2;
- } else if (winVerOverride == "WINDOWS8_1" || winVerOverride == "2012_R2") {
- result.dwMajorVersion = 6;
- result.dwMinorVersion = 3;
- } else if (winVerOverride == "WINDOWS10" || winVerOverride == "2016") {
+ if (winVerOverride == "WINDOWS10" || winVerOverride == "2016"
+ || winVerOverride == "2019" || winVerOverride == "2022") {
+ result.dwMajorVersion = 10;
+ } else if (winVerOverride == "WINDOWS11") {
result.dwMajorVersion = 10;
+ result.dwBuildNumber = 22000;
} else {
return realResult;
}
- if (winVerOverride == "2008_R2"
- || winVerOverride == "2012"
- || winVerOverride == "2012_R2"
- || winVerOverride == "2016") {
+ if (winVerOverride == "2016" || winVerOverride == "2019"
+ || winVerOverride == "2022") {
// If the current host OS is a domain controller and the override OS
// is also a server type OS, preserve that information
if (result.wProductType == VER_NT_WORKSTATION)
@@ -123,9 +77,9 @@ OSVERSIONINFOEX qWindowsVersionInfo()
return realResult;
}
-QOperatingSystemVersion QOperatingSystemVersion::current()
+QOperatingSystemVersionBase QOperatingSystemVersionBase::current_impl()
{
- QOperatingSystemVersion v;
+ QOperatingSystemVersionBase v;
v.m_os = currentType();
const OSVERSIONINFOEX osv = qWindowsVersionInfo();
v.m_major = osv.dwMajorVersion;
diff --git a/src/corelib/global/qoperatingsystemversion_win_p.h b/src/corelib/global/qoperatingsystemversion_win_p.h
index 446bd286fc..92fc0e12f3 100644
--- a/src/corelib/global/qoperatingsystemversion_win_p.h
+++ b/src/corelib/global/qoperatingsystemversion_win_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QOPERATINGSYSTEMVERSION_WIN_P_H
#define QOPERATINGSYSTEMVERSION_WIN_P_H
@@ -51,7 +15,7 @@
// We mean it.
//
-#include <QtCore/qglobal.h>
+#include <QtCore/private/qglobal_p.h>
#include <qt_windows.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/global/qoverload.h b/src/corelib/global/qoverload.h
new file mode 100644
index 0000000000..9376e1e246
--- /dev/null
+++ b/src/corelib/global/qoverload.h
@@ -0,0 +1,80 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QOVERLOAD_H
+#define QOVERLOAD_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#if 0
+#pragma qt_class(QOverload)
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_QDOC
+// Just for documentation generation
+template<typename T>
+auto qOverload(T functionPointer);
+template<typename T>
+auto qConstOverload(T memberFunctionPointer);
+template<typename T>
+auto qNonConstOverload(T memberFunctionPointer);
+#else
+template <typename... Args>
+struct QNonConstOverload
+{
+ template <typename R, typename T>
+ constexpr auto operator()(R (T::*ptr)(Args...)) const noexcept -> decltype(ptr)
+ { return ptr; }
+
+ template <typename R, typename T>
+ static constexpr auto of(R (T::*ptr)(Args...)) noexcept -> decltype(ptr)
+ { return ptr; }
+};
+
+template <typename... Args>
+struct QConstOverload
+{
+ template <typename R, typename T>
+ constexpr auto operator()(R (T::*ptr)(Args...) const) const noexcept -> decltype(ptr)
+ { return ptr; }
+
+ template <typename R, typename T>
+ static constexpr auto of(R (T::*ptr)(Args...) const) noexcept -> decltype(ptr)
+ { return ptr; }
+};
+
+template <typename... Args>
+struct QOverload : QConstOverload<Args...>, QNonConstOverload<Args...>
+{
+ using QConstOverload<Args...>::of;
+ using QConstOverload<Args...>::operator();
+ using QNonConstOverload<Args...>::of;
+ using QNonConstOverload<Args...>::operator();
+
+ template <typename R>
+ constexpr auto operator()(R (*ptr)(Args...)) const noexcept -> decltype(ptr)
+ { return ptr; }
+
+ template <typename R>
+ static constexpr auto of(R (*ptr)(Args...)) noexcept -> decltype(ptr)
+ { return ptr; }
+};
+
+template <typename... Args> constexpr inline QOverload<Args...> qOverload = {};
+template <typename... Args> constexpr inline QConstOverload<Args...> qConstOverload = {};
+template <typename... Args> constexpr inline QNonConstOverload<Args...> qNonConstOverload = {};
+
+#endif // Q_QDOC
+
+#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
+#define QT_VA_ARGS_EXPAND(...) __VA_ARGS__ // Needed for MSVC
+#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_EXPAND(QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
+#define QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##_##ARGC
+#define QT_OVERLOADED_MACRO_IMP(MACRO, ARGC) QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC)
+#define QT_OVERLOADED_MACRO(MACRO, ...) QT_VA_ARGS_EXPAND(QT_OVERLOADED_MACRO_IMP(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__))
+
+QT_END_NAMESPACE
+
+#endif /* QOVERLOAD_H */
diff --git a/src/corelib/global/qoverload.qdoc b/src/corelib/global/qoverload.qdoc
new file mode 100644
index 0000000000..f11e266483
--- /dev/null
+++ b/src/corelib/global/qoverload.qdoc
@@ -0,0 +1,43 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*! \fn template <typename T> auto qOverload(T functionPointer)
+ \relates <QOverload>
+ \since 5.7
+
+ Returns a pointer to an overloaded function. The template
+ parameter is the list of the argument types of the function.
+ \a functionPointer is the pointer to the (member) function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 52
+
+ If a member function is also const-overloaded \l qConstOverload and
+ \l qNonConstOverload need to be used.
+
+ \sa qConstOverload(), qNonConstOverload(), {Differences between String-Based
+ and Functor-Based Connections}
+*/
+
+/*! \fn template <typename T> auto qConstOverload(T memberFunctionPointer)
+ \relates <QOverload>
+ \since 5.7
+
+ Returns the \a memberFunctionPointer pointer to a constant member function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 54
+
+ \sa qOverload, qNonConstOverload, {Differences between String-Based
+ and Functor-Based Connections}
+*/
+
+/*! \fn template <typename T> auto qNonConstOverload(T memberFunctionPointer)
+ \relates <QOverload>
+ \since 5.7
+
+ Returns the \a memberFunctionPointer pointer to a non-constant member function:
+
+ \snippet code/src_corelib_global_qglobal.cpp 54
+
+ \sa qOverload, qNonConstOverload, {Differences between String-Based
+ and Functor-Based Connections}
+*/
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index f7bca43345..f7298bbb86 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -1,45 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLOBAL_H
-# include <QtCore/qglobal.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+
+#if 0
+#pragma qt_class(QtProcessorDetection)
+#pragma qt_sync_skip_header_check
+#pragma qt_sync_stop_processing
#endif
#ifndef QPROCESSORDETECTION_H
@@ -84,8 +51,8 @@
Alpha is bi-endian, use endianness auto-detection implemented below.
*/
-// #elif defined(__alpha__) || defined(_M_ALPHA)
-// # define Q_PROCESSOR_ALPHA
+#if defined(__alpha__) || defined(_M_ALPHA)
+# define Q_PROCESSOR_ALPHA
// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
@@ -94,7 +61,7 @@
ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to
auto-detection implemented below.
*/
-#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
+#elif defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
# if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
# define Q_PROCESSOR_ARM_64
# define Q_PROCESSOR_WORDSIZE 8
@@ -176,6 +143,15 @@
// # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
/*
+ PA-RISC family, no revisions or variants
+
+ PA-RISC is big-endian.
+*/
+#elif defined(__hppa__)
+# define Q_PROCESSOR_HPPA
+# define Q_BYTE_ORDER Q_BIG_ENDIAN
+
+/*
X86 family, known variants: 32- and 64-bit
X86 is little-endian.
@@ -224,6 +200,29 @@
// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
+ LoongArch family, known variants: 32- and 64-bit
+
+ LoongArch is little-endian.
+*/
+#elif defined(__loongarch__)
+# define Q_PROCESSOR_LOONGARCH
+# if __loongarch_grlen == 64
+# define Q_PROCESSOR_LOONGARCH_64
+# else
+# define Q_PROCESSOR_LOONGARCH_32
+# endif
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+
+/*
+ Motorola 68000 family, no revisions or variants
+
+ M68K is big-endian.
+*/
+#elif defined(__m68k__)
+# define Q_PROCESSOR_M68K
+# define Q_BYTE_ORDER Q_BIG_ENDIAN
+
+/*
MIPS family, known revisions: I, II, III, IV, 32, 64
MIPS is bi-endian, use endianness auto-detection implemented below.
@@ -327,7 +326,7 @@
*/
#elif defined(__sparc__)
# define Q_PROCESSOR_SPARC
-# if defined(__sparc_v9__)
+# if defined(__sparc_v9__) || defined(__sparcv9)
# define Q_PROCESSOR_SPARC_V9
# endif
# if defined(__sparc64__)
@@ -340,6 +339,12 @@
# define Q_PROCESSOR_WASM
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
# define Q_PROCESSOR_WORDSIZE 8
+#ifdef QT_COMPILER_SUPPORTS_SSE2
+# define Q_PROCESSOR_X86 6 // enables SIMD support
+# define Q_PROCESSOR_X86_64 // wasm64
+# define Q_PROCESSOR_WASM_64
+#endif
+
#endif
/*
diff --git a/src/corelib/global/qprocessordetection.qdoc b/src/corelib/global/qprocessordetection.qdoc
new file mode 100644
index 0000000000..e6605fb9b9
--- /dev/null
+++ b/src/corelib/global/qprocessordetection.qdoc
@@ -0,0 +1,448 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \headerfile <QtProcessorDetection>
+ \inmodule QtCore
+ \title Architecture-specific Macro Definitions
+ \ingroup funclists
+
+ \brief The <QtProcessorDetection> header file includes various
+ architecture-specific macros.
+
+ The <QtProcessorDetection> header file declares a range of macros
+ (Q_PROCESSOR_*) that are defined if the application is compiled for
+ specified processor architectures. For example, the Q_PROCESSOR_X86 macro is
+ defined if the application is compiled for x86 processors.
+
+ The purpose of these macros is to enable programmers to add
+ architecture-specific code to their application.
+*/
+
+/*!
+ \macro Q_PROCESSOR_ALPHA
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for Alpha processors.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_ARM
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for ARM processors. Qt currently
+ supports three optional ARM revisions: \l Q_PROCESSOR_ARM_V5, \l
+ Q_PROCESSOR_ARM_V6, and \l Q_PROCESSOR_ARM_V7.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_ARM_V5
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for ARMv5 processors. The \l
+ Q_PROCESSOR_ARM macro is also defined when Q_PROCESSOR_ARM_V5 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_ARM_V6
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for ARMv6 processors. The \l
+ Q_PROCESSOR_ARM and \l Q_PROCESSOR_ARM_V5 macros are also defined when
+ Q_PROCESSOR_ARM_V6 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_ARM_V7
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for ARMv7 processors. The \l
+ Q_PROCESSOR_ARM, \l Q_PROCESSOR_ARM_V5, and \l Q_PROCESSOR_ARM_V6 macros
+ are also defined when Q_PROCESSOR_ARM_V7 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_AVR32
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for AVR32 processors.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_BLACKFIN
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for Blackfin processors.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_HPPA
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for PA-RISC processors.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_IA64
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for IA-64 processors. This includes
+ all Itanium and Itanium 2 processors.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_LOONGARCH
+ \relates <QtProcessorDetection>
+ \since 6.5
+
+ Defined if the application is compiled for LoongArch processors.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_LOONGARCH_32
+ \relates <QtProcessorDetection>
+ \since 6.5
+
+ Defined if the application is compiled for 32-bit LoongArch processors.
+ The \l Q_PROCESSOR_LOONGARCH macro is also defined when
+ Q_PROCESSOR_LOONGARCH_32 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_LOONGARCH_64
+ \relates <QtProcessorDetection>
+ \since 6.5
+
+ Defined if the application is compiled for 64-bit LoongArch processors.
+ The \l Q_PROCESSOR_LOONGARCH macro is also defined when
+ Q_PROCESSOR_LOONGARCH_64 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_M68K
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for Motorola 68000 processors.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_MIPS
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for MIPS processors. Qt currently
+ supports seven MIPS revisions: \l Q_PROCESSOR_MIPS_I, \l
+ Q_PROCESSOR_MIPS_II, \l Q_PROCESSOR_MIPS_III, \l Q_PROCESSOR_MIPS_IV, \l
+ Q_PROCESSOR_MIPS_V, \l Q_PROCESSOR_MIPS_32, and \l Q_PROCESSOR_MIPS_64.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_MIPS_I
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for MIPS-I processors. The \l
+ Q_PROCESSOR_MIPS macro is also defined when Q_PROCESSOR_MIPS_I is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_MIPS_II
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for MIPS-II processors. The \l
+ Q_PROCESSOR_MIPS and \l Q_PROCESSOR_MIPS_I macros are also defined when
+ Q_PROCESSOR_MIPS_II is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_MIPS_32
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for MIPS32 processors. The \l
+ Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, and \l Q_PROCESSOR_MIPS_II macros
+ are also defined when Q_PROCESSOR_MIPS_32 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_MIPS_III
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for MIPS-III processors. The \l
+ Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, and \l Q_PROCESSOR_MIPS_II macros
+ are also defined when Q_PROCESSOR_MIPS_III is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_MIPS_IV
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for MIPS-IV processors. The \l
+ Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, and \l
+ Q_PROCESSOR_MIPS_III macros are also defined when Q_PROCESSOR_MIPS_IV is
+ defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_MIPS_V
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for MIPS-V processors. The \l
+ Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, \l
+ Q_PROCESSOR_MIPS_III, and \l Q_PROCESSOR_MIPS_IV macros are also defined
+ when Q_PROCESSOR_MIPS_V is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_MIPS_64
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for MIPS64 processors. The \l
+ Q_PROCESSOR_MIPS, \l Q_PROCESSOR_MIPS_I, \l Q_PROCESSOR_MIPS_II, \l
+ Q_PROCESSOR_MIPS_III, \l Q_PROCESSOR_MIPS_IV, and \l Q_PROCESSOR_MIPS_V
+ macros are also defined when Q_PROCESSOR_MIPS_64 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_POWER
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for POWER processors. Qt currently
+ supports two Power variants: \l Q_PROCESSOR_POWER_32 and \l
+ Q_PROCESSOR_POWER_64.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_POWER_32
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for 32-bit Power processors. The \l
+ Q_PROCESSOR_POWER macro is also defined when Q_PROCESSOR_POWER_32 is
+ defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_POWER_64
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for 64-bit Power processors. The \l
+ Q_PROCESSOR_POWER macro is also defined when Q_PROCESSOR_POWER_64 is
+ defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_RISCV
+ \relates <QtProcessorDetection>
+ \since 5.13
+
+ Defined if the application is compiled for RISC-V processors. Qt currently
+ supports two RISC-V variants: \l Q_PROCESSOR_RISCV_32 and \l
+ Q_PROCESSOR_RISCV_64.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_RISCV_32
+ \relates <QtProcessorDetection>
+ \since 5.13
+
+ Defined if the application is compiled for 32-bit RISC-V processors. The \l
+ Q_PROCESSOR_RISCV macro is also defined when Q_PROCESSOR_RISCV_32 is
+ defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_RISCV_64
+ \relates <QtProcessorDetection>
+ \since 5.13
+
+ Defined if the application is compiled for 64-bit RISC-V processors. The \l
+ Q_PROCESSOR_RISCV macro is also defined when Q_PROCESSOR_RISCV_64 is
+ defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_S390
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for S/390 processors. Qt supports
+ one optional variant of S/390: Q_PROCESSOR_S390_X.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_S390_X
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for S/390x processors. The \l
+ Q_PROCESSOR_S390 macro is also defined when Q_PROCESSOR_S390_X is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_SH
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for SuperH processors. Qt currently
+ supports one SuperH revision: \l Q_PROCESSOR_SH_4A.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_SH_4A
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for SuperH 4A processors. The \l
+ Q_PROCESSOR_SH macro is also defined when Q_PROCESSOR_SH_4A is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_SPARC
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for SPARC processors. Qt currently
+ supports one optional SPARC revision: \l Q_PROCESSOR_SPARC_V9.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_SPARC_V9
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for SPARC V9 processors. The \l
+ Q_PROCESSOR_SPARC macro is also defined when Q_PROCESSOR_SPARC_V9 is
+ defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_PROCESSOR_X86
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for x86 processors. Qt currently
+ supports two x86 variants: \l Q_PROCESSOR_X86_32 and \l Q_PROCESSOR_X86_64.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_X86_32
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for 32-bit x86 processors. This
+ includes all i386, i486, i586, and i686 processors. The \l Q_PROCESSOR_X86
+ macro is also defined when Q_PROCESSOR_X86_32 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+/*!
+ \macro Q_PROCESSOR_X86_64
+ \relates <QtProcessorDetection>
+
+ Defined if the application is compiled for 64-bit x86 processors. This
+ includes all AMD64, Intel 64, and other x86_64/x64 processors. The \l
+ Q_PROCESSOR_X86 macro is also defined when Q_PROCESSOR_X86_64 is defined.
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+
+/*!
+ \macro Q_BYTE_ORDER
+ \relates <QtProcessorDetection>
+
+ This macro can be used to determine the byte order your system
+ uses for storing data in memory. i.e., whether your system is
+ little-endian or big-endian. It is set by Qt to one of the macros
+ Q_LITTLE_ENDIAN or Q_BIG_ENDIAN. You normally won't need to worry
+ about endian-ness, but you might, for example if you need to know
+ which byte of an integer or UTF-16 character is stored in the
+ lowest address. Endian-ness is important in networking, where
+ computers with different values for Q_BYTE_ORDER must pass data
+ back and forth.
+
+ Use this macro as in the following examples.
+
+ \snippet code/src_corelib_global_qglobal.cpp 40
+
+ \sa Q_BIG_ENDIAN, Q_LITTLE_ENDIAN
+*/
+
+/*!
+ \macro Q_LITTLE_ENDIAN
+ \relates <QtProcessorDetection>
+
+ This macro represents a value you can compare to the macro
+ Q_BYTE_ORDER to determine the endian-ness of your system. In a
+ little-endian system, the least significant byte is stored at the
+ lowest address. The other bytes follow in increasing order of
+ significance.
+
+ \snippet code/src_corelib_global_qglobal.cpp 41
+
+ \sa Q_BYTE_ORDER, Q_BIG_ENDIAN
+*/
+
+/*!
+ \macro Q_BIG_ENDIAN
+ \relates <QtProcessorDetection>
+
+ This macro represents a value you can compare to the macro
+ Q_BYTE_ORDER to determine the endian-ness of your system. In a
+ big-endian system, the most significant byte is stored at the
+ lowest address. The other bytes follow in decreasing order of
+ significance.
+
+ \snippet code/src_corelib_global_qglobal.cpp 42
+
+ \sa Q_BYTE_ORDER, Q_LITTLE_ENDIAN
+*/
+
+/*!
+ \macro QT_POINTER_SIZE
+ \relates <QtProcessorDetection>
+
+ Expands to the size of a pointer in bytes (4 or 8). This is
+ equivalent to \c sizeof(void *) but can be used in a preprocessor
+ directive.
+*/
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index b699dcbece..21448b8c14 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 Intel Corporation.
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 Intel Corporation.
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// for rand_s
#define _CRT_RAND_S
@@ -46,7 +10,6 @@
#include <qendian.h>
#include <qmutex.h>
#include <qobjectdefs.h>
-#include <qthreadstorage.h>
#include <errno.h>
@@ -54,7 +17,9 @@
# include <sys/auxv.h>
#endif
-#if !QT_CONFIG(getentropy) && (!defined(Q_OS_BSD4) || defined(__GLIBC__)) && !defined(Q_OS_WIN)
+#if QT_CONFIG(getentropy) && __has_include(<sys/random.h>)
+# include <sys/random.h>
+#elif !QT_CONFIG(getentropy) && (!defined(Q_OS_BSD4) || defined(__GLIBC__)) && !defined(Q_OS_WIN)
# include "qdeadlinetimer.h"
# include "qhashfunctions.h"
#endif // !QT_CONFIG(getentropy)
@@ -228,10 +193,10 @@ static void fallback_fill(quint32 *ptr, qsizetype left) noexcept
arc4random_buf(ptr, left * sizeof(*ptr));
}
#else
-static QBasicAtomicInteger<unsigned> seed = Q_BASIC_ATOMIC_INITIALIZER(0U);
+Q_CONSTINIT static QBasicAtomicInteger<unsigned> seed = Q_BASIC_ATOMIC_INITIALIZER(0U);
static void fallback_update_seed(unsigned value)
{
- // Update the seed to be used for the fallback mechansim, if we need to.
+ // Update the seed to be used for the fallback mechanism, if we need to.
// We can't use QtPrivate::QHashCombine here because that is not an atomic
// operation. A simple XOR will have to do then.
seed.fetchAndXorRelaxed(value);
@@ -352,16 +317,17 @@ struct QRandomGenerator::SystemAndGlobalGenerators
// the state in case another thread tries to lock the mutex. It's not
// a common scenario, but since sizeof(QRandomGenerator) >= 2560, the
// overhead is actually acceptable.
- // 2) We use both alignas and std::aligned_storage<..., 64> because
- // some implementations of std::aligned_storage can't align to more
- // than a primitive type's alignment.
+ // 2) We use both alignas(T) and alignas(64) because some implementations
+ // can't align to more than a primitive type's alignment.
// 3) We don't store the entire system QRandomGenerator, only the space
// used by the QRandomGenerator::type member. This is fine because we
// (ab)use the common initial sequence exclusion to aliasing rules.
QBasicMutex globalPRNGMutex;
struct ShortenedSystem { uint type; } system_;
SystemGenerator sys;
- alignas(64) std::aligned_storage<sizeof(QRandomGenerator64), 64>::type global_;
+ alignas(64) struct {
+ alignas(QRandomGenerator64) uchar data[sizeof(QRandomGenerator64)];
+ } global_;
constexpr SystemAndGlobalGenerators()
: globalPRNGMutex{}, system_{0}, sys{}, global_{}
@@ -378,7 +344,7 @@ struct QRandomGenerator::SystemAndGlobalGenerators
static SystemAndGlobalGenerators *self()
{
- static SystemAndGlobalGenerators g;
+ Q_CONSTINIT static SystemAndGlobalGenerators g;
static_assert(sizeof(g) > sizeof(QRandomGenerator64));
return &g;
}
@@ -671,7 +637,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
position in the deterministic sequence as the \a other object was. Both
objects will generate the same sequence from this point on.
- For that reason, it is not adviseable to create a copy of
+ For that reason, it is not advisable to create a copy of
QRandomGenerator::global(). If one needs an exclusive deterministic
generator, consider instead using securelySeeded() to obtain a new object
that shares no relationship with the QRandomGenerator::global().
@@ -681,7 +647,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\fn bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
\relates QRandomGenerator
- Returns true if the two the two engines \a rng1 and \a rng2 are at the same
+ Returns true if the two engines \a rng1 and \a rng2 are at the same
state or if they are both reading from the operating system facilities,
false otherwise.
*/
@@ -689,7 +655,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
/*!
\fn bool QRandomGenerator::operator!=(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
- Returns \c true if the two the two engines \a rng1 and \a rng2 are at
+ Returns \c true if the two engines \a rng1 and \a rng2 are at
different states or if one of them is reading from the operating system
facilities and the other is not, \c false otherwise.
*/
@@ -799,7 +765,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
- \fn template <typename UInt> void QRandomGenerator::fillRange(UInt *buffer, qsizetype count)
+ \fn template <typename UInt, QRandomGenerator::IfValidUInt<UInt> = true> void QRandomGenerator::fillRange(UInt *buffer, qsizetype count)
Generates \a count 32- or 64-bit quantities (depending on the type \c UInt)
and stores them in the buffer pointed by \a buffer. This is the most
@@ -815,7 +781,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
- \fn template <typename UInt, size_t N> void QRandomGenerator::fillRange(UInt (&buffer)[N])
+ \fn template <typename UInt, size_t N, QRandomGenerator::IfValidUInt<UInt> = true> void QRandomGenerator::fillRange(UInt (&buffer)[N])
Generates \c N 32- or 64-bit quantities (depending on the type \c UInt) and
stores them in the \a buffer array. This is the most efficient way to
diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h
index 7639937da4..f8e53f4009 100644
--- a/src/corelib/global/qrandom.h
+++ b/src/corelib/global/qrandom.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QRANDOM_H
#define QRANDOM_H
@@ -203,8 +167,8 @@ public:
void seed(quint32 s = 1) { *this = { s }; }
void seed(std::seed_seq &sseq) noexcept { *this = { sseq }; }
Q_CORE_EXPORT void discard(unsigned long long z);
- static constexpr result_type min() { return std::numeric_limits<result_type>::min(); }
- static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
+ static constexpr result_type min() { return (std::numeric_limits<result_type>::min)(); }
+ static constexpr result_type max() { return (std::numeric_limits<result_type>::max)(); }
static inline Q_DECL_CONST_FUNCTION QRandomGenerator *system();
static inline Q_DECL_CONST_FUNCTION QRandomGenerator *global();
@@ -229,15 +193,9 @@ private:
union Storage {
uint dummy;
-#ifdef Q_COMPILER_UNRESTRICTED_UNIONS
RandomEngine twister;
RandomEngine &engine() { return twister; }
const RandomEngine &engine() const { return twister; }
-#else
- std::aligned_storage<sizeof(RandomEngine), alignof(RandomEngine)>::type buffer;
- RandomEngine &engine() { return reinterpret_cast<RandomEngine &>(buffer); }
- const RandomEngine &engine() const { return reinterpret_cast<const RandomEngine &>(buffer); }
-#endif
static_assert(std::is_trivially_destructible<RandomEngine>::value,
"std::mersenne_twister not trivially destructible as expected");
@@ -283,8 +241,8 @@ public:
QRandomGenerator::discard(z * 2);
}
- static constexpr result_type min() { return std::numeric_limits<result_type>::min(); }
- static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
+ static constexpr result_type min() { return (std::numeric_limits<result_type>::min)(); }
+ static constexpr result_type max() { return (std::numeric_limits<result_type>::max)(); }
static Q_DECL_CONST_FUNCTION Q_CORE_EXPORT QRandomGenerator64 *system();
static Q_DECL_CONST_FUNCTION Q_CORE_EXPORT QRandomGenerator64 *global();
static Q_CORE_EXPORT QRandomGenerator64 securelySeeded();
diff --git a/src/corelib/global/qrandom_p.h b/src/corelib/global/qrandom_p.h
index b8968c703e..c0209f97d2 100644
--- a/src/corelib/global/qrandom_p.h
+++ b/src/corelib/global/qrandom_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QRANDOM_P_H
#define QRANDOM_P_H
diff --git a/src/corelib/global/qsimd.cpp b/src/corelib/global/qsimd.cpp
index 025c50b6e8..8bc5381591 100644
--- a/src/corelib/global/qsimd.cpp
+++ b/src/corelib/global/qsimd.cpp
@@ -1,60 +1,34 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2019 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// we need ICC to define the prototype for _rdseed64_step
#define __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
+#undef _FORTIFY_SOURCE // otherwise, the always_inline from stdio.h fail to inline
#include "qsimd_p.h"
#include "qalgorithms.h"
-#include <QByteArray>
+
#include <stdio.h>
+#include <string.h>
+
+#if defined(QT_NO_DEBUG) && !defined(NDEBUG)
+# define NDEBUG
+#endif
+#include <assert.h>
#ifdef Q_OS_LINUX
# include "../testlib/3rdparty/valgrind_p.h"
#endif
+#define QT_FUNCTION_TARGET_BASELINE
+
#if defined(Q_OS_WIN)
# if !defined(Q_CC_GNU)
# include <intrin.h>
# endif
-# if defined(Q_PROCESSOR_ARM64)
+# if defined(Q_PROCESSOR_ARM_64)
+# include <qt_windows.h>
# include <processthreadsapi.h>
# endif
#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_MIPS_32)
@@ -88,6 +62,14 @@
QT_BEGIN_NAMESPACE
+template <typename T, uint N> QT_FUNCTION_TARGET_BASELINE
+uint arraysize(T (&)[N])
+{
+ // Same as std::size, but with QT_FUNCTION_TARGET_BASELIE,
+ // otherwise some versions of GCC fail to compile.
+ return N;
+}
+
#if defined(Q_PROCESSOR_ARM)
/* Data:
neon
@@ -117,16 +99,11 @@ static const int features_indices[] = {
# include "qsimd_x86.cpp" // generated by util/x86simdgen
#else
static const char features_string[] = "";
-static const int features_indices[] = { };
+static const int features_indices[] = { 0 };
#endif
// end generated
-#if defined (Q_OS_NACL)
-static inline uint detectProcessorFeatures()
-{
- return 0;
-}
-#elif defined(Q_PROCESSOR_ARM)
+#if defined(Q_PROCESSOR_ARM)
static inline quint64 detectProcessorFeatures()
{
quint64 features = 0;
@@ -166,7 +143,7 @@ static inline quint64 detectProcessorFeatures()
features |= CpuFeatureAES;
#endif
return features;
-#elif defined(Q_OS_WIN) && defined(Q_PROCESSOR_ARM64)
+#elif defined(Q_OS_WIN) && defined(Q_PROCESSOR_ARM_64)
features |= CpuFeatureNEON;
if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) != 0)
features |= CpuFeatureCRC32;
@@ -194,9 +171,23 @@ static inline quint64 detectProcessorFeatures()
#else
# define PICreg "%%rbx"
#endif
+#ifdef __SSE2_MATH__
+# define X86_BASELINE "no-sse3"
+#else
+# define X86_BASELINE "no-sse"
+#endif
+
+#if defined(Q_CC_GNU)
+// lower the target for functions in this file
+# undef QT_FUNCTION_TARGET_BASELINE
+# define QT_FUNCTION_TARGET_BASELINE __attribute__((target(X86_BASELINE)))
+# define QT_FUNCTION_TARGET_STRING_BASELINE_RDRND \
+ X86_BASELINE "," QT_FUNCTION_TARGET_STRING_RDRND
+#endif
static bool checkRdrndWorks() noexcept;
+QT_FUNCTION_TARGET_BASELINE
static int maxBasicCpuidSupported()
{
#if defined(Q_CC_EMSCRIPTEN)
@@ -244,6 +235,7 @@ static int maxBasicCpuidSupported()
#endif
}
+QT_FUNCTION_TARGET_BASELINE
static void cpuidFeatures01(uint &ecx, uint &edx)
{
#if defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)
@@ -273,6 +265,7 @@ static void cpuidFeatures01(uint &ecx, uint &edx)
inline void __cpuidex(int info[4], int, __int64) { memset(info, 0, 4*sizeof(int));}
#endif
+QT_FUNCTION_TARGET_BASELINE
static void cpuidFeatures07_00(uint &ebx, uint &ecx, uint &edx)
{
#if defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)
@@ -306,6 +299,7 @@ static void cpuidFeatures07_00(uint &ebx, uint &ecx, uint &edx)
#endif
}
+QT_FUNCTION_TARGET_BASELINE
#if defined(Q_OS_WIN) && !(defined(Q_CC_GNU) || defined(Q_CC_GHS))
// fallback overload in case this intrinsic does not exist: unsigned __int64 _xgetbv(unsigned int);
inline quint64 _xgetbv(__int64) { return 0; }
@@ -327,22 +321,7 @@ static void xgetbv(uint in, uint &eax, uint &edx)
#endif
}
-// Flags from the XCR0 state register
-enum XCR0Flags {
- X87 = 1 << 0,
- XMM0_15 = 1 << 1,
- YMM0_15Hi128 = 1 << 2,
- BNDRegs = 1 << 3,
- BNDCSR = 1 << 4,
- OpMask = 1 << 5,
- ZMM0_15Hi256 = 1 << 6,
- ZMM16_31 = 1 << 7,
-
- SSEState = XMM0_15,
- AVXState = XMM0_15 | YMM0_15Hi128,
- AVX512State = AVXState | OpMask | ZMM0_15Hi256 | ZMM16_31
-};
-
+QT_FUNCTION_TARGET_BASELINE
static quint64 adjustedXcr0(quint64 xcr0)
{
/*
@@ -362,59 +341,54 @@ static quint64 adjustedXcr0(quint64 xcr0)
constexpr quintptr cpu_capabilities64 = commpage + 0x10;
quint64 capab = *reinterpret_cast<quint64 *>(cpu_capabilities64);
if (capab & kHasAVX512F)
- xcr0 |= AVX512State;
+ xcr0 |= XSave_Avx512State;
#endif
return xcr0;
}
+QT_FUNCTION_TARGET_BASELINE
static quint64 detectProcessorFeatures()
{
- static const quint64 AllAVX2 = CpuFeatureAVX2 | AllAVX512;
- static const quint64 AllAVX = CpuFeatureAVX | AllAVX2;
-
quint64 features = 0;
int cpuidLevel = maxBasicCpuidSupported();
#if Q_PROCESSOR_X86 < 5
if (cpuidLevel < 1)
return 0;
#else
- Q_ASSERT(cpuidLevel >= 1);
+ assert(cpuidLevel >= 1);
#endif
uint results[X86CpuidMaxLeaf] = {};
- cpuidFeatures01(results[Leaf1ECX], results[Leaf1EDX]);
+ cpuidFeatures01(results[Leaf01ECX], results[Leaf01EDX]);
if (cpuidLevel >= 7)
- cpuidFeatures07_00(results[Leaf7_0EBX], results[Leaf7_0ECX], results[Leaf7_0EDX]);
+ cpuidFeatures07_00(results[Leaf07_00EBX], results[Leaf07_00ECX], results[Leaf07_00EDX]);
// populate our feature list
- for (uint i = 0; i < sizeof(x86_locators) / sizeof(x86_locators[0]); ++i) {
+ for (uint i = 0; i < arraysize(x86_locators); ++i) {
uint word = x86_locators[i] / 32;
uint bit = 1U << (x86_locators[i] % 32);
- quint64 feature = Q_UINT64_C(1) << (i + 1);
+ quint64 feature = Q_UINT64_C(1) << i;
if (results[word] & bit)
features |= feature;
}
// now check the AVX state
quint64 xcr0 = 0;
- if (results[Leaf1ECX] & (1u << 27)) {
+ if (results[Leaf01ECX] & (1u << 27)) {
// XGETBV enabled
uint xgetbvA = 0, xgetbvD = 0;
xgetbv(0, xgetbvA, xgetbvD);
xcr0 = xgetbvA;
- if (sizeof(XCR0Flags) > sizeof(xgetbvA))
+ if (sizeof(XSaveBits) > sizeof(xgetbvA))
xcr0 |= quint64(xgetbvD) << 32;
xcr0 = adjustedXcr0(xcr0);
}
- if ((xcr0 & AVXState) != AVXState) {
- // support for YMM registers is disabled, disable all AVX
- features &= ~AllAVX;
- } else if ((xcr0 & AVX512State) != AVX512State) {
- // support for ZMM registers or mask registers is disabled, disable all AVX512
- features &= ~AllAVX512;
+ for (auto req : xsave_requirements) {
+ if ((xcr0 & req.xsave_state) != req.xsave_state)
+ features &= ~req.cpu_features;
}
if (features & CpuFeatureRDRND && !checkRdrndWorks())
@@ -577,32 +551,38 @@ static inline uint detectProcessorFeatures()
}
#endif
-static const int features_count = (sizeof features_indices) / (sizeof features_indices[0]);
-
// record what CPU features were enabled by default in this Qt build
static const quint64 minFeature = qCompilerCpuFeatures;
-#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
-Q_CORE_EXPORT QBasicAtomicInteger<quint64> qt_cpu_features[1] = { Q_BASIC_ATOMIC_INITIALIZER(0) };
-#else
-Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2] = { Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) };
-#endif
+static constexpr auto SimdInitialized = QCpuFeatureType(1) << (sizeof(QCpuFeatureType) * 8 - 1);
+Q_ATOMIC(QCpuFeatureType) QT_MANGLE_NAMESPACE(qt_cpu_features)[1] = { 0 };
-quint64 qDetectCpuFeatures()
+QT_FUNCTION_TARGET_BASELINE
+uint64_t QT_MANGLE_NAMESPACE(qDetectCpuFeatures)()
{
auto minFeatureTest = minFeature;
-#if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_64)
- // Yocto hard-codes CRC32+AES on. Since they are unlikely to be used
- // automatically by compilers, we can just add runtime check.
- minFeatureTest &= ~(CpuFeatureAES|CpuFeatureCRC32);
+#if defined(Q_PROCESSOR_X86_64) && defined(cpu_feature_shstk)
+ // Controlflow Enforcement Technology (CET) is an OS-assisted
+ // hardware-feature, meaning the CPUID bit may be disabled if the OS
+ // doesn't support it, but that's ok.
+ minFeatureTest &= ~CpuFeatureSHSTK;
#endif
- quint64 f = detectProcessorFeatures();
- QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
- if (!disable.isEmpty()) {
- disable.prepend(' ');
- for (int i = 0; i < features_count; ++i) {
- if (disable.contains(features_string + features_indices[i]))
- f &= ~(Q_UINT64_C(1) << i);
+ QCpuFeatureType f = detectProcessorFeatures();
+
+ // Intentionally NOT qgetenv (this code runs too early)
+ if (char *disable = getenv("QT_NO_CPU_FEATURE"); disable && *disable) {
+#if _POSIX_C_SOURCE >= 200112L
+ char *saveptr = nullptr;
+ auto strtok = [&saveptr](char *str, const char *delim) {
+ return ::strtok_r(str, delim, &saveptr);
+ };
+#endif
+ while (char *token = strtok(disable, " ")) {
+ disable = nullptr;
+ for (uint i = 0; i < arraysize(features_indices); ++i) {
+ if (strcmp(token, features_string + features_indices[i]) == 0)
+ f &= ~(Q_UINT64_C(1) << i);
+ }
}
}
@@ -612,37 +592,36 @@ quint64 qDetectCpuFeatures()
bool runningOnValgrind = false;
#endif
if (Q_UNLIKELY(!runningOnValgrind && minFeatureTest != 0 && (f & minFeatureTest) != minFeatureTest)) {
- quint64 missing = minFeatureTest & ~f;
+ quint64 missing = minFeatureTest & ~quint64(f);
fprintf(stderr, "Incompatible processor. This Qt build requires the following features:\n ");
- for (int i = 0; i < features_count; ++i) {
+ for (uint i = 0; i < arraysize(features_indices); ++i) {
if (missing & (Q_UINT64_C(1) << i))
fprintf(stderr, "%s", features_string + features_indices[i]);
}
fprintf(stderr, "\n");
fflush(stderr);
- qFatal("Aborted. Incompatible processor: missing feature 0x%llx -%s.", missing,
- features_string + features_indices[qCountTrailingZeroBits(missing)]);
+ qAbort();
}
- qt_cpu_features[0].storeRelaxed(f | quint32(QSimdInitialized));
-#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
- qt_cpu_features[1].storeRelaxed(f >> 32);
-#endif
+ assert((f & SimdInitialized) == 0);
+ f |= SimdInitialized;
+ std::atomic_store_explicit(QT_MANGLE_NAMESPACE(qt_cpu_features), f, std::memory_order_relaxed);
return f;
}
+QT_FUNCTION_TARGET_BASELINE
void qDumpCPUFeatures()
{
- quint64 features = qCpuFeatures() & ~quint64(QSimdInitialized);
+ quint64 features = detectProcessorFeatures() & ~SimdInitialized;
printf("Processor features: ");
- for (int i = 0; i < features_count; ++i) {
+ for (uint i = 0; i < arraysize(features_indices); ++i) {
if (features & (Q_UINT64_C(1) << i))
printf("%s%s", features_string + features_indices[i],
minFeature & (Q_UINT64_C(1) << i) ? "[required]" : "");
}
if ((features = (qCompilerCpuFeatures & ~features))) {
printf("\n!!!!!!!!!!!!!!!!!!!!\n!!! Missing required features:");
- for (int i = 0; i < features_count; ++i) {
+ for (uint i = 0; i < arraysize(features_indices); ++i) {
if (features & (Q_UINT64_C(1) << i))
printf("%s", features_string + features_indices[i]);
}
@@ -723,7 +702,8 @@ out:
return ptr;
}
-static QT_FUNCTION_TARGET(RDRND) Q_DECL_COLD_FUNCTION bool checkRdrndWorks() noexcept
+QT_FUNCTION_TARGET(BASELINE_RDRND) Q_DECL_COLD_FUNCTION
+static bool checkRdrndWorks() noexcept
{
/*
* Some AMD CPUs (e.g. AMD A4-6250J and AMD Ryzen 3000-series) have a
@@ -776,8 +756,20 @@ QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) no
ptr = qt_random_rdrnd(ptr, end);
return ptr - reinterpret_cast<unsigned *>(buffer);
}
-#elif defined(Q_PROCESSOR_X86) && !defined(Q_OS_NACL) && !defined(Q_PROCESSOR_ARM)
+#elif defined(Q_PROCESSOR_X86) && !defined(Q_PROCESSOR_ARM)
static bool checkRdrndWorks() noexcept { return false; }
#endif // Q_PROCESSOR_X86 && RDRND
+#if QT_SUPPORTS_INIT_PRIORITY
+namespace {
+struct QSimdInitializer
+{
+ inline QSimdInitializer() { QT_MANGLE_NAMESPACE(qDetectCpuFeatures)(); }
+};
+}
+
+// This is intentionally a dynamic initialization of the variable
+Q_DECL_INIT_PRIORITY(01) static QSimdInitializer initializer;
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qsimd.h b/src/corelib/global/qsimd.h
index 5fd34d0092..4ef925ca33 100644
--- a/src/corelib/global/qsimd.h
+++ b/src/corelib/global/qsimd.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSIMD_H
#define QSIMD_H
@@ -89,20 +53,20 @@
# define QT_COMPILER_USES_mips_dspr2 -1
#endif
-#if defined(Q_PROCESSOR_X86)
-#if defined(Q_CC_MSVC)
+#if defined(Q_PROCESSOR_X86) && defined(Q_CC_MSVC)
// MSVC doesn't define __SSE2__, so do it ourselves
-# if (defined(_M_X64) || _M_IX86_FP >= 2)
+# if (defined(_M_X64) || _M_IX86_FP >= 2) && defined(QT_COMPILER_SUPPORTS_SSE2)
# define __SSE__ 1
# define __SSE2__ 1
# endif
-#if (defined(_M_AVX) || defined(__AVX__))
+# if (defined(_M_AVX) || defined(__AVX__))
// Visual Studio defines __AVX__ when /arch:AVX is passed, but not the earlier macros
// See: https://msdn.microsoft.com/en-us/library/b0084kay.aspx
# define __SSE3__ 1
# define __SSSE3__ 1
# define __SSE4_1__ 1
# define __SSE4_2__ 1
+# define __POPCNT__ 1
# ifndef __AVX__
# define __AVX__ 1
# endif
@@ -110,7 +74,17 @@
# ifdef __SSE2__
# define QT_VECTORCALL __vectorcall
# endif
-#endif
+# ifdef __AVX2__
+// MSVC defines __AVX2__ with /arch:AVX2
+# define __F16C__ 1
+# define __RDRND__ 1
+# define __FMA__ 1
+# define __BMI__ 1
+# define __BMI2__ 1
+# define __MOVBE__ 1
+# define __LZCNT__ 1
+# endif
+// Starting with /arch:AVX512, MSVC defines all the macros
#endif
#if defined(Q_PROCESSOR_X86) && defined(__SSE2__)
diff --git a/src/corelib/global/qsimd_p.h b/src/corelib/global/qsimd_p.h
index 35979176fa..012eb6cf4f 100644
--- a/src/corelib/global/qsimd_p.h
+++ b/src/corelib/global/qsimd_p.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSIMD_P_H
#define QSIMD_P_H
@@ -55,34 +19,21 @@
#include <QtCore/private/qglobal_p.h>
#include <QtCore/qsimd.h>
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wundef")
+QT_WARNING_DISABLE_GCC("-Wundef")
+QT_WARNING_DISABLE_INTEL(103)
+
+#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \
+ for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i)
+
+#define ALIGNMENT_PROLOGUE_32BYTES(ptr, i, length) \
+ for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((8 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x7)) & 0x7))); ++i)
+
+#define SIMD_EPILOGUE(i, length, max) \
+ for (int _i = 0; _i < max && i < length; ++i, ++_i)
+
/*
- * qt_module_config.prf defines the QT_COMPILER_SUPPORTS_XXX macros.
- * They mean the compiler supports the necessary flags and the headers
- * for the x86 and ARM intrinsics:
- * - GCC: the -mXXX or march=YYY flag is necessary before #include
- * up to 4.8; GCC >= 4.9 can include unconditionally
- * - Intel CC: #include can happen unconditionally
- * - MSVC: #include can happen unconditionally
- * - RVCT: ???
- *
- * We will try to include all headers possible under this configuration.
- *
- * MSVC does not define __SSE2__ & family, so we will define them. MSVC 2013 &
- * up do define __AVX__ if the -arch:AVX option is passed on the command-line.
- *
- * Supported XXX are:
- * Flag | Arch | GCC | Intel CC | MSVC |
- * ARM_NEON | ARM | I & C | None | ? |
- * SSE2 | x86 | I & C | I & C | I & C |
- * SSE3 | x86 | I & C | I & C | I only |
- * SSSE3 | x86 | I & C | I & C | I only |
- * SSE4_1 | x86 | I & C | I & C | I only |
- * SSE4_2 | x86 | I & C | I & C | I only |
- * AVX | x86 | I & C | I & C | I & C |
- * AVX2 | x86 | I & C | I & C | I only |
- * AVX512xx | x86 | I & C | I & C | I only |
- * I = intrinsics; C = code generation
- *
* Code can use the following constructs to determine compiler support & status:
* - #ifdef __XXX__ (e.g: #ifdef __AVX__ or #ifdef __ARM_NEON__)
* If this test passes, then the compiler is already generating code for that
@@ -103,6 +54,9 @@
* sub-arch. Only inside such functions is the use of the intrisics
* guaranteed to work. This is useful with runtime detection (see below).
*
+ * The distinction between QT_COMPILER_SUPPORTS and QT_COMPILER_SUPPORTS_HERE is
+ * historical: GCC 4.8 needed the distinction.
+ *
* Runtime detection of a CPU sub-architecture can be done with the
* qCpuHasFeature(XXX) function. There are two strategies for generating
* optimized code like that:
@@ -145,7 +99,7 @@
#define QT_COMPILER_SUPPORTS(x) (QT_COMPILER_SUPPORTS_ ## x - 0)
-#if defined(Q_PROCESSOR_ARM) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)
+#if defined(Q_PROCESSOR_ARM)
# define QT_COMPILER_SUPPORTS_HERE(x) ((__ARM_FEATURE_ ## x) || (__ ## x ## __) || QT_COMPILER_SUPPORTS(x))
# if defined(Q_CC_GNU)
/* GCC requires attributes for a function */
@@ -162,104 +116,143 @@
# if !defined(__MIPS_DSPR2__) && defined(__mips_dspr2) && defined(Q_PROCESSOR_MIPS_32)
# define __MIPS_DSPR2__
# endif
-#elif defined(Q_PROCESSOR_X86) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)
+#elif defined(Q_PROCESSOR_X86)
# if defined(Q_CC_CLANG) && defined(Q_CC_MSVC)
# define QT_COMPILER_SUPPORTS_HERE(x) (__ ## x ## __)
# else
# define QT_COMPILER_SUPPORTS_HERE(x) ((__ ## x ## __) || QT_COMPILER_SUPPORTS(x))
# endif
-# if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
+# if defined(Q_CC_GNU)
/* GCC requires attributes for a function */
# define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x)))
# else
# define QT_FUNCTION_TARGET(x)
# endif
-#elif defined(Q_PROCESSOR_ARM)
-# define QT_COMPILER_SUPPORTS_HERE(x) ((__ARM_FEATURE_ ## x) || (__ ## x ## __))
-# define QT_FUNCTION_TARGET(x)
#else
# define QT_COMPILER_SUPPORTS_HERE(x) (__ ## x ## __)
# define QT_FUNCTION_TARGET(x)
#endif
+#if defined(__SSE2__) && !defined(QT_COMPILER_SUPPORTS_SSE2) && !defined(QT_BOOTSTRAPPED)
+// Intrinsic support appears to be missing, so pretend these features don't exist
+# undef __SSE__
+# undef __SSE2__
+# undef __SSE3__
+# undef __SSSE3__
+# undef __SSE4_1__
+# undef __SSE4_2__
+# undef __AES__
+# undef __POPCNT__
+# undef __AVX__
+# undef __F16C__
+# undef __RDRND__
+# undef __AVX2__
+# undef __BMI__
+# undef __BMI2__
+# undef __FMA__
+# undef __MOVBE__
+# undef __RDSEED__
+# undef __AVX512F__
+# undef __AVX512ER__
+# undef __AVX512CD__
+# undef __AVX512PF__
+# undef __AVX512DQ__
+# undef __AVX512BW__
+# undef __AVX512VL__
+# undef __AVX512IFMA__
+# undef __AVX512VBMI__
+# undef __SHA__
+# undef __AVX512VBMI2__
+# undef __AVX512BITALG__
+# undef __AVX512VNNI__
+# undef __AVX512VPOPCNTDQ__
+# undef __GFNI__
+# undef __VAES__
+#endif
+
#ifdef Q_PROCESSOR_X86
/* -- x86 intrinsic support -- */
+# if defined(QT_COMPILER_SUPPORTS_RDSEED) && defined(Q_OS_QNX)
+// The compiler for QNX is missing the intrinsic
+# undef QT_COMPILER_SUPPORTS_RDSEED
+# endif
# if defined(Q_CC_MSVC) && (defined(_M_X64) || _M_IX86_FP >= 2)
// MSVC doesn't define __SSE2__, so do it ourselves
# define __SSE__ 1
# endif
-# if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
-// GCC 4.4 and Clang 2.8 added a few more intrinsics there
-# include <x86intrin.h>
-# endif
-
-# if defined(__SSE4_2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC))
-// POPCNT instructions:
-// All processors that support SSE4.2 support POPCNT
-// (but neither MSVC nor the Intel compiler define this macro)
-# define __POPCNT__ 1
+# if defined(Q_OS_WIN) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
+// 64-bit GCC on Windows does not support AVX, so we hack around it by forcing
+// it to emit unaligned loads & stores
+// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49001
+asm(
+ ".macro vmovapd args:vararg\n"
+ " vmovupd \\args\n"
+ ".endm\n"
+ ".macro vmovaps args:vararg\n"
+ " vmovups \\args\n"
+ ".endm\n"
+ ".macro vmovdqa args:vararg\n"
+ " vmovdqu \\args\n"
+ ".endm\n"
+ ".macro vmovdqa32 args:vararg\n"
+ " vmovdqu32 \\args\n"
+ ".endm\n"
+ ".macro vmovdqa64 args:vararg\n"
+ " vmovdqu64 \\args\n"
+ ".endm\n"
+);
# endif
-// AVX intrinsics
-# if defined(__AVX__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC))
-// PCLMULQDQ instructions:
-// All processors that support AVX support PCLMULQDQ
-// (but neither MSVC nor the Intel compiler define this macro)
-# define __PCLMUL__ 1
-# endif
-
-# if defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC))
-// F16C instructions:
-// All processors that support AVX2 support F16C:
-// (but neither MSVC nor the Intel compiler define this macro)
-# define __F16C__ 1
-# endif
-
-# if defined(__BMI__) && !defined(__BMI2__) && defined(Q_CC_INTEL)
-// BMI2 instructions:
-// All processors that support BMI support BMI2 (and AVX2)
-// (but neither MSVC nor the Intel compiler define this macro)
-# define __BMI2__ 1
+# if defined(Q_CC_GNU) && !defined(Q_OS_WASM)
+// GCC 4.4 and Clang 2.8 added a few more intrinsics there
+# include <x86intrin.h>
# endif
+#ifdef Q_OS_WASM
+# include <immintrin.h>
+# endif
-# include "qsimd_x86_p.h"
+# include <QtCore/private/qsimd_x86_p.h>
-// Haswell sub-architecture
+// x86-64 sub-architecture version 3
//
// The Intel Core 4th generation was codenamed "Haswell" and introduced AVX2,
-// BMI1, BMI2, FMA, LZCNT, MOVBE, which makes it a good divider for a
-// sub-target for us. The first AMD processor with AVX2 support (Zen) has the
-// same features.
-//
-// macOS's fat binaries support the "x86_64h" sub-architecture and the GNU libc
-// ELF loader also supports a "haswell/" subdir (e.g., /usr/lib/haswell).
-# define QT_FUNCTION_TARGET_STRING_ARCH_HASWELL "arch=haswell"
-# if defined(__AVX2__) && defined(__BMI__) && defined(__BMI2__) && defined(__F16C__) && \
- defined(__FMA__) && defined(__LZCNT__) && defined(__RDRND__)
+// BMI1, BMI2, FMA, LZCNT, MOVBE. This feature set was chosen as the version 3
+// of the x86-64 ISA (x86-64-v3) and is supported by GCC and Clang. On systems
+// with the GNU libc, libraries with this feature can be installed on a
+// "glibc-hwcaps/x86-64-v3" subdir. macOS's fat binaries support the "x86_64h"
+// sub-architecture too.
+
+# if defined(__AVX2__)
+// List of features present with -march=x86-64-v3 and not architecturally
+// implied by __AVX2__
+# define ARCH_HASWELL_MACROS \
+ (__AVX2__ + __BMI__ + __BMI2__ + __F16C__ + __FMA__ + __LZCNT__ + __POPCNT__)
+# if ARCH_HASWELL_MACROS != 7
+# error "Please enable all x86-64-v3 extensions; you probably want to use -march=haswell or -march=x86-64-v3 instead of -mavx2"
+# endif
+static_assert(ARCH_HASWELL_MACROS, "Undeclared identifiers indicate which features are missing.");
# define __haswell__ 1
+# undef ARCH_HASWELL_MACROS
# endif
-// This constant does not include all CPU features found in a Haswell, only
-// those that we'd have optimized code for.
-// Note: must use Q_CONSTEXPR here, as this file may be compiled in C mode.
-QT_BEGIN_NAMESPACE
-static const quint64 CpuFeatureArchHaswell = 0
- | CpuFeatureSSE2
- | CpuFeatureSSE3
- | CpuFeatureSSSE3
- | CpuFeatureSSE4_1
- | CpuFeatureSSE4_2
- | CpuFeatureFMA
- | CpuFeaturePOPCNT
- | CpuFeatureAVX
- | CpuFeatureF16C
- | CpuFeatureAVX2
- | CpuFeatureBMI
- | CpuFeatureBMI2;
-QT_END_NAMESPACE
-
+// x86-64 sub-architecture version 4
+//
+// Similar to the above, x86-64-v4 matches the AVX512 variant of the Intel Core
+// 6th generation (codename "Skylake"). AMD Zen4 is the their first processor
+// with AVX512 support and it includes all of these too. The GNU libc subdir for
+// this is "glibc-hwcaps/x86-64-v4".
+//
+# define ARCH_SKX_MACROS (__AVX512F__ + __AVX512BW__ + __AVX512CD__ + __AVX512DQ__ + __AVX512VL__)
+# if ARCH_SKX_MACROS != 0
+# if ARCH_SKX_MACROS != 5
+# error "Please enable all x86-64-v4 extensions; you probably want to use -march=skylake-avx512 or -march=x86-64-v4 instead of -mavx512f"
+# endif
+static_assert(ARCH_SKX_MACROS, "Undeclared identifiers indicate which features are missing.");
+# define __skylake_avx512__ 1
+# endif
+# undef ARCH_SKX_MACROS
#endif /* Q_PROCESSOR_X86 */
// NEON intrinsics
@@ -314,12 +307,6 @@ inline uint8_t vaddv_u8(uint8x8_t v8)
#endif
#endif
-
-#ifdef __cplusplus
-#include <qatomic.h>
-
-QT_BEGIN_NAMESPACE
-
#ifndef Q_PROCESSOR_X86
enum CPUFeatures {
#if defined(Q_PROCESSOR_ARM)
@@ -332,21 +319,25 @@ enum CPUFeatures {
CpuFeatureDSP = 2,
CpuFeatureDSPR2 = 4,
#endif
-
- // used only to indicate that the CPU detection was initialised
- QSimdInitialized = 1
};
-static const quint64 qCompilerCpuFeatures = 0
+static const uint64_t qCompilerCpuFeatures = 0
#if defined __ARM_NEON__
| CpuFeatureNEON
#endif
+#if !(defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_64))
+ // Yocto Project recipes enable Crypto extension for all ARMv8 configs,
+ // even for targets without the Crypto extension. That's wrong, but as
+ // the compiler never generates the code for them on their own, most
+ // code never notices the problem. But we would. By not setting the
+ // bits here, we force a runtime detection.
#if defined __ARM_FEATURE_CRC32
| CpuFeatureCRC32
#endif
#if defined __ARM_FEATURE_CRYPTO
| CpuFeatureAES
#endif
+#endif // Q_OS_LINUX && Q_PROCESSOR_ARM64
#if defined __mips_dsp
| CpuFeatureDSP
#endif
@@ -356,58 +347,71 @@ static const quint64 qCompilerCpuFeatures = 0
;
#endif
-#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
-extern Q_CORE_EXPORT QBasicAtomicInteger<quint64> qt_cpu_features[1];
+#ifdef __cplusplus
+# include <atomic>
+# define Q_ATOMIC(T) std::atomic<T>
+QT_BEGIN_NAMESPACE
+using std::atomic_load_explicit;
+static constexpr auto memory_order_relaxed = std::memory_order_relaxed;
+extern "C" {
#else
-extern Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2];
+# include <stdatomic.h>
+# define Q_ATOMIC(T) _Atomic(T)
#endif
-Q_CORE_EXPORT quint64 qDetectCpuFeatures();
-#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) && !defined(QT_BOOTSTRAPPED)
-Q_CORE_EXPORT qsizetype qRandomCpu(void *, qsizetype) noexcept;
+#ifdef Q_PROCESSOR_X86
+typedef uint64_t QCpuFeatureType;
+static const QCpuFeatureType qCompilerCpuFeatures = _compilerCpuFeatures;
+static const QCpuFeatureType CpuFeatureArchHaswell = cpu_haswell;
+static const QCpuFeatureType CpuFeatureArchSkylakeAvx512 = cpu_skylake_avx512;
#else
-static inline qsizetype qRandomCpu(void *, qsizetype) noexcept
-{
- return 0;
-}
+typedef unsigned QCpuFeatureType;
#endif
+extern Q_CORE_EXPORT Q_ATOMIC(QCpuFeatureType) QT_MANGLE_NAMESPACE(qt_cpu_features)[1];
+Q_CORE_EXPORT uint64_t QT_MANGLE_NAMESPACE(qDetectCpuFeatures)();
-static inline quint64 qCpuFeatures()
+static inline uint64_t qCpuFeatures()
{
- quint64 features = qt_cpu_features[0].loadRelaxed();
-#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
- features |= quint64(qt_cpu_features[1].loadRelaxed()) << 32;
-#endif
- if (Q_UNLIKELY(features == 0)) {
- features = qDetectCpuFeatures();
- Q_ASSUME(features != 0);
+#ifdef QT_BOOTSTRAPPED
+ return qCompilerCpuFeatures; // no detection
+#else
+ quint64 features = atomic_load_explicit(QT_MANGLE_NAMESPACE(qt_cpu_features), memory_order_relaxed);
+ if (!QT_SUPPORTS_INIT_PRIORITY) {
+ if (Q_UNLIKELY(features == 0))
+ features = QT_MANGLE_NAMESPACE(qDetectCpuFeatures)();
}
return features;
+#endif
}
#define qCpuHasFeature(feature) (((qCompilerCpuFeatures & CpuFeature ## feature) == CpuFeature ## feature) \
|| ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature))
-inline bool qHasHwrng()
+#ifdef __cplusplus
+} // extern "C"
+
+# if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) && !defined(QT_BOOTSTRAPPED)
+Q_CORE_EXPORT qsizetype qRandomCpu(void *, qsizetype) noexcept;
+
+static inline bool qHasHwrng()
{
-#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
return qCpuHasFeature(RDRND);
-#else
+}
+# else
+static inline qsizetype qRandomCpu(void *, qsizetype) noexcept
+{
+ return 0;
+}
+static inline bool qHasHwrng()
+{
return false;
-#endif
}
-
-#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \
- for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i)
-
-#define ALIGNMENT_PROLOGUE_32BYTES(ptr, i, length) \
- for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((8 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x7)) & 0x7))); ++i)
+# endif
QT_END_NAMESPACE
#endif // __cplusplus
-#define SIMD_EPILOGUE(i, length, max) \
- for (int _i = 0; _i < max && i < length; ++i, ++_i)
+QT_WARNING_POP
#endif // QSIMD_P_H
diff --git a/src/corelib/global/qsimd_x86.cpp b/src/corelib/global/qsimd_x86.cpp
index be17f44c09..9a3bd80b39 100644
--- a/src/corelib/global/qsimd_x86.cpp
+++ b/src/corelib/global/qsimd_x86.cpp
@@ -1,45 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// This is a generated file. DO NOT EDIT.
-// Please see util/x86simdgen/generate.pl
-#include "qsimd_p.h"
+// Please see util/x86simdgen/README.md
+
+#include "qsimd_x86_p.h"
static const char features_string[] =
" sse2\0"
@@ -55,101 +19,202 @@ static const char features_string[] =
" f16c\0"
" rdrnd\0"
" bmi\0"
- " hle\0"
" avx2\0"
" bmi2\0"
- " rtm\0"
" avx512f\0"
" avx512dq\0"
" rdseed\0"
" avx512ifma\0"
- " avx512pf\0"
- " avx512er\0"
" avx512cd\0"
" sha\0"
" avx512bw\0"
" avx512vl\0"
" avx512vbmi\0"
+ " waitpkg\0"
" avx512vbmi2\0"
+ " shstk\0"
" gfni\0"
" vaes\0"
- " avx512vnni\0"
" avx512bitalg\0"
" avx512vpopcntdq\0"
- " avx5124nniw\0"
- " avx5124fmaps\0"
+ " hybrid\0"
+ " ibt\0"
+ " avx512fp16\0"
+ " raoint\0"
+ " cmpccxadd\0"
+ " avxifma\0"
+ " lam\0"
"\0";
-static const quint16 features_indices[] = {
- 306, 0, 6, 12, 19, 24, 32, 40,
- 47, 55, 60, 65, 71, 78, 83, 88,
- 94, 100, 105, 114, 124, 132, 144, 154,
- 164, 174, 179, 189, 199, 211, 224, 230,
- 236, 248, 262, 279, 292
+static const uint16_t features_indices[] = {
+ 0, 6, 12, 19, 24, 32, 40, 47,
+ 55, 60, 65, 71, 78, 83, 89, 95,
+ 104, 114, 122, 134, 144, 149, 159, 169,
+ 181, 190, 203, 210, 216, 222, 236, 253,
+ 261, 266, 278, 286, 297, 306,
};
enum X86CpuidLeaves {
- Leaf1ECX,
- Leaf1EDX,
- Leaf7_0EBX,
- Leaf7_0ECX,
- Leaf7_0EDX,
+ Leaf01EDX,
+ Leaf01ECX,
+ Leaf07_00EBX,
+ Leaf07_00ECX,
+ Leaf07_00EDX,
+ Leaf07_01EAX,
+ Leaf07_01EDX,
+ Leaf13_01EAX,
+ Leaf80000001hECX,
+ Leaf80000008hEBX,
X86CpuidMaxLeaf
};
-static const quint8 x86_locators[] = {
- Leaf1EDX*32 + 26, // sse2
- Leaf1ECX*32 + 0, // sse3
- Leaf1ECX*32 + 9, // ssse3
- Leaf1ECX*32 + 12, // fma
- Leaf1ECX*32 + 19, // sse4.1
- Leaf1ECX*32 + 20, // sse4.2
- Leaf1ECX*32 + 22, // movbe
- Leaf1ECX*32 + 23, // popcnt
- Leaf1ECX*32 + 25, // aes
- Leaf1ECX*32 + 28, // avx
- Leaf1ECX*32 + 29, // f16c
- Leaf1ECX*32 + 30, // rdrnd
- Leaf7_0EBX*32 + 3, // bmi
- Leaf7_0EBX*32 + 4, // hle
- Leaf7_0EBX*32 + 5, // avx2
- Leaf7_0EBX*32 + 8, // bmi2
- Leaf7_0EBX*32 + 11, // rtm
- Leaf7_0EBX*32 + 16, // avx512f
- Leaf7_0EBX*32 + 17, // avx512dq
- Leaf7_0EBX*32 + 18, // rdseed
- Leaf7_0EBX*32 + 21, // avx512ifma
- Leaf7_0EBX*32 + 26, // avx512pf
- Leaf7_0EBX*32 + 27, // avx512er
- Leaf7_0EBX*32 + 28, // avx512cd
- Leaf7_0EBX*32 + 29, // sha
- Leaf7_0EBX*32 + 30, // avx512bw
- Leaf7_0EBX*32 + 31, // avx512vl
- Leaf7_0ECX*32 + 1, // avx512vbmi
- Leaf7_0ECX*32 + 6, // avx512vbmi2
- Leaf7_0ECX*32 + 8, // gfni
- Leaf7_0ECX*32 + 9, // vaes
- Leaf7_0ECX*32 + 11, // avx512vnni
- Leaf7_0ECX*32 + 12, // avx512bitalg
- Leaf7_0ECX*32 + 14, // avx512vpopcntdq
- Leaf7_0EDX*32 + 2, // avx5124nniw
- Leaf7_0EDX*32 + 3 // avx5124fmaps
+static const uint16_t x86_locators[] = {
+ Leaf01EDX*32 + 26, // sse2
+ Leaf01ECX*32 + 0, // sse3
+ Leaf01ECX*32 + 9, // ssse3
+ Leaf01ECX*32 + 12, // fma
+ Leaf01ECX*32 + 19, // sse4.1
+ Leaf01ECX*32 + 20, // sse4.2
+ Leaf01ECX*32 + 22, // movbe
+ Leaf01ECX*32 + 23, // popcnt
+ Leaf01ECX*32 + 25, // aes
+ Leaf01ECX*32 + 28, // avx
+ Leaf01ECX*32 + 29, // f16c
+ Leaf01ECX*32 + 30, // rdrnd
+ Leaf07_00EBX*32 + 3, // bmi
+ Leaf07_00EBX*32 + 5, // avx2
+ Leaf07_00EBX*32 + 8, // bmi2
+ Leaf07_00EBX*32 + 16, // avx512f
+ Leaf07_00EBX*32 + 17, // avx512dq
+ Leaf07_00EBX*32 + 18, // rdseed
+ Leaf07_00EBX*32 + 21, // avx512ifma
+ Leaf07_00EBX*32 + 28, // avx512cd
+ Leaf07_00EBX*32 + 29, // sha
+ Leaf07_00EBX*32 + 30, // avx512bw
+ Leaf07_00EBX*32 + 31, // avx512vl
+ Leaf07_00ECX*32 + 1, // avx512vbmi
+ Leaf07_00ECX*32 + 5, // waitpkg
+ Leaf07_00ECX*32 + 6, // avx512vbmi2
+ Leaf07_00ECX*32 + 7, // shstk
+ Leaf07_00ECX*32 + 8, // gfni
+ Leaf07_00ECX*32 + 9, // vaes
+ Leaf07_00ECX*32 + 12, // avx512bitalg
+ Leaf07_00ECX*32 + 14, // avx512vpopcntdq
+ Leaf07_00EDX*32 + 15, // hybrid
+ Leaf07_00EDX*32 + 20, // ibt
+ Leaf07_00EDX*32 + 23, // avx512fp16
+ Leaf07_01EAX*32 + 3, // raoint
+ Leaf07_01EAX*32 + 6, // cmpccxadd
+ Leaf07_01EAX*32 + 23, // avxifma
+ Leaf07_01EAX*32 + 26, // lam
+};
+
+struct X86Architecture
+{
+ uint64_t features;
+ char name[17 + 1];
+};
+
+static const struct X86Architecture x86_architectures[] = {
+ { cpu_core2, "Core2" },
+ { cpu_westmere, "Westmere" },
+ { cpu_sandybridge, "Sandy Bridge" },
+ { cpu_silvermont, "Silvermont" },
+ { cpu_ivybridge, "Ivy Bridge" },
+ { cpu_goldmont, "Goldmont" },
+ { cpu_haswell, "Haswell" },
+ { cpu_broadwell, "Broadwell" },
+ { cpu_tremont, "Tremont" },
+ { cpu_skylake, "Skylake" },
+ { cpu_skylake_avx512, "Skylake (Avx512)" },
+ { cpu_cascadelake, "Cascade Lake" },
+ { cpu_cooperlake, "Cooper Lake" },
+ { cpu_cannonlake, "Cannon Lake" },
+ { cpu_gracemont, "Gracemont" },
+ { cpu_icelake_client, "Ice Lake (Client)" },
+ { cpu_icelake_server, "Ice Lake (Server)" },
+ { cpu_crestmont, "Crestmont" },
+ { cpu_tigerlake, "Tiger Lake" },
+ { cpu_clearwaterforest, "Clearwater Forest" },
+ { cpu_grandridge, "Grand Ridge" },
+ { cpu_raptorcove, "Raptor Cove" },
+ { cpu_redwoodcove, "Redwood Cove" },
+ { cpu_emeraldrapids, "Emerald Rapids" },
+ { cpu_graniterapids, "Granite Rapids" },
+};
+
+enum XSaveBits {
+ XSave_X87 = 0x0001, // X87 and MMX state
+ XSave_SseState = 0x0002, // SSE: 128 bits of XMM registers
+ XSave_Ymm_Hi128 = 0x0004, // AVX: high 128 bits in YMM registers
+ XSave_Bndregs = 0x0008, // Memory Protection Extensions
+ XSave_Bndcsr = 0x0010, // Memory Protection Extensions
+ XSave_OpMask = 0x0020, // AVX512: k0 through k7
+ XSave_Zmm_Hi256 = 0x0040, // AVX512: high 256 bits of ZMM0-15
+ XSave_Hi16_Zmm = 0x0080, // AVX512: all 512 bits of ZMM16-31
+ XSave_PTState = 0x0100, // Processor Trace
+ XSave_PKRUState = 0x0200, // Protection Key
+ XSave_CetUState = 0x0800, // CET: user mode
+ XSave_CetSState = 0x1000, // CET: supervisor mode
+ XSave_HdcState = 0x2000, // Hardware Duty Cycle
+ XSave_UintrState = 0x4000, // User Interrupts
+ XSave_HwpState = 0x10000, // Hardware P-State
+ XSave_Xtilecfg = 0x20000, // AMX: XTILECFG register
+ XSave_Xtiledata = 0x40000, // AMX: data in the tiles
+ XSave_AvxState = XSave_SseState | XSave_Ymm_Hi128,
+ XSave_MPXState = XSave_Bndregs | XSave_Bndcsr,
+ XSave_Avx512State = XSave_AvxState | XSave_OpMask | XSave_Zmm_Hi256 | XSave_Hi16_Zmm,
+ XSave_CetState = XSave_CetUState | XSave_CetSState,
+ XSave_AmxState = XSave_Xtilecfg | XSave_Xtiledata,
+};
+
+// List of features requiring XSave_AvxState
+static const uint64_t XSaveReq_AvxState = 0
+ | cpu_feature_fma
+ | cpu_feature_avx
+ | cpu_feature_f16c
+ | cpu_feature_avx2
+ | cpu_feature_avx512f
+ | cpu_feature_avx512dq
+ | cpu_feature_avx512ifma
+ | cpu_feature_avx512cd
+ | cpu_feature_avx512bw
+ | cpu_feature_avx512vl
+ | cpu_feature_avx512vbmi
+ | cpu_feature_avx512vbmi2
+ | cpu_feature_vaes
+ | cpu_feature_avx512bitalg
+ | cpu_feature_avx512vpopcntdq
+ | cpu_feature_avx512fp16
+ | cpu_feature_avxifma;
+
+// List of features requiring XSave_Avx512State
+static const uint64_t XSaveReq_Avx512State = 0
+ | cpu_feature_avx512f
+ | cpu_feature_avx512dq
+ | cpu_feature_avx512ifma
+ | cpu_feature_avx512cd
+ | cpu_feature_avx512bw
+ | cpu_feature_avx512vl
+ | cpu_feature_avx512vbmi
+ | cpu_feature_avx512vbmi2
+ | cpu_feature_avx512bitalg
+ | cpu_feature_avx512vpopcntdq
+ | cpu_feature_avx512fp16;
+
+// List of features requiring XSave_CetState
+static const uint64_t XSaveReq_CetState = 0
+ | cpu_feature_shstk;
+
+struct XSaveRequirementMapping
+{
+ uint64_t cpu_features;
+ uint64_t xsave_state;
+};
+
+static const struct XSaveRequirementMapping xsave_requirements[] = {
+ { XSaveReq_AvxState, XSave_AvxState },
+ { XSaveReq_Avx512State, XSave_Avx512State },
+ { XSaveReq_CetState, XSave_CetState },
};
-// List of AVX512 features (see detectProcessorFeatures())
-static const quint64 AllAVX512 = 0
- | CpuFeatureAVX512F
- | CpuFeatureAVX512DQ
- | CpuFeatureAVX512IFMA
- | CpuFeatureAVX512PF
- | CpuFeatureAVX512ER
- | CpuFeatureAVX512CD
- | CpuFeatureAVX512BW
- | CpuFeatureAVX512VL
- | CpuFeatureAVX512VBMI
- | CpuFeatureAVX512VBMI2
- | CpuFeatureAVX512VNNI
- | CpuFeatureAVX512BITALG
- | CpuFeatureAVX512VPOPCNTDQ
- | CpuFeatureAVX5124NNIW
- | CpuFeatureAVX5124FMAPS;
diff --git a/src/corelib/global/qsimd_x86_p.h b/src/corelib/global/qsimd_x86_p.h
index 82e3008a24..1ec89d0c6c 100644
--- a/src/corelib/global/qsimd_x86_p.h
+++ b/src/corelib/global/qsimd_x86_p.h
@@ -1,51 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// This is a generated file. DO NOT EDIT.
-// Please see util/x86simdgen/generate.pl
-#ifndef QSIMD_P_H
-# error "Please include <private/qsimd_p.h> instead"
-#endif
-#ifndef QSIMD_X86_P_H
-#define QSIMD_X86_P_H
-
-#include "qsimd_p.h"
+// Please see util/x86simdgen/README.md
//
// W A R N I N G
@@ -58,204 +14,536 @@
// We mean it.
//
-QT_BEGIN_NAMESPACE
+// This is a generated file. DO NOT EDIT.
+// Please see util/x86simdgen/README.md
+#ifndef QSIMD_X86_P_H
+#define QSIMD_X86_P_H
-// used only to indicate that the CPU detection was initialized
-#define QSimdInitialized (Q_UINT64_C(1) << 0)
+#include <stdint.h>
// in CPUID Leaf 1, EDX:
-#define CpuFeatureSSE2 (Q_UINT64_C(1) << 1)
-#define QT_FUNCTION_TARGET_STRING_SSE2 "sse2"
+#define cpu_feature_sse2 (UINT64_C(1) << 0)
// in CPUID Leaf 1, ECX:
-#define CpuFeatureSSE3 (Q_UINT64_C(1) << 2)
+#define cpu_feature_sse3 (UINT64_C(1) << 1)
+#define cpu_feature_ssse3 (UINT64_C(1) << 2)
+#define cpu_feature_fma (UINT64_C(1) << 3)
+#define cpu_feature_sse4_1 (UINT64_C(1) << 4)
+#define cpu_feature_sse4_2 (UINT64_C(1) << 5)
+#define cpu_feature_movbe (UINT64_C(1) << 6)
+#define cpu_feature_popcnt (UINT64_C(1) << 7)
+#define cpu_feature_aes (UINT64_C(1) << 8)
+#define cpu_feature_avx (UINT64_C(1) << 9)
+#define cpu_feature_f16c (UINT64_C(1) << 10)
+#define cpu_feature_rdrnd (UINT64_C(1) << 11)
+
+// in CPUID Leaf 7, Sub-leaf 0, EBX:
+#define cpu_feature_bmi (UINT64_C(1) << 12)
+#define cpu_feature_avx2 (UINT64_C(1) << 13)
+#define cpu_feature_bmi2 (UINT64_C(1) << 14)
+#define cpu_feature_avx512f (UINT64_C(1) << 15)
+#define cpu_feature_avx512dq (UINT64_C(1) << 16)
+#define cpu_feature_rdseed (UINT64_C(1) << 17)
+#define cpu_feature_avx512ifma (UINT64_C(1) << 18)
+#define cpu_feature_avx512cd (UINT64_C(1) << 19)
+#define cpu_feature_sha (UINT64_C(1) << 20)
+#define cpu_feature_avx512bw (UINT64_C(1) << 21)
+#define cpu_feature_avx512vl (UINT64_C(1) << 22)
+
+// in CPUID Leaf 7, Sub-leaf 0, ECX:
+#define cpu_feature_avx512vbmi (UINT64_C(1) << 23)
+#define cpu_feature_waitpkg (UINT64_C(1) << 24)
+#define cpu_feature_avx512vbmi2 (UINT64_C(1) << 25)
+#define cpu_feature_shstk (UINT64_C(1) << 26)
+#define cpu_feature_gfni (UINT64_C(1) << 27)
+#define cpu_feature_vaes (UINT64_C(1) << 28)
+#define cpu_feature_avx512bitalg (UINT64_C(1) << 29)
+#define cpu_feature_avx512vpopcntdq (UINT64_C(1) << 30)
+
+// in CPUID Leaf 7, Sub-leaf 0, EDX:
+#define cpu_feature_hybrid (UINT64_C(1) << 31)
+#define cpu_feature_ibt (UINT64_C(1) << 32)
+#define cpu_feature_avx512fp16 (UINT64_C(1) << 33)
+
+// in CPUID Leaf 7, Sub-leaf 1, EAX:
+#define cpu_feature_raoint (UINT64_C(1) << 34)
+#define cpu_feature_cmpccxadd (UINT64_C(1) << 35)
+#define cpu_feature_avxifma (UINT64_C(1) << 36)
+#define cpu_feature_lam (UINT64_C(1) << 37)
+
+// CPU architectures
+#define cpu_x86_64 (0 \
+ | cpu_feature_sse2)
+#define cpu_core2 (cpu_x86_64 \
+ | cpu_feature_sse3 \
+ | cpu_feature_ssse3)
+#define cpu_nhm (cpu_core2 \
+ | cpu_feature_sse4_1 \
+ | cpu_feature_sse4_2 \
+ | cpu_feature_popcnt)
+#define cpu_wsm (cpu_nhm)
+#define cpu_snb (cpu_wsm \
+ | cpu_feature_avx)
+#define cpu_ivb (cpu_snb \
+ | cpu_feature_f16c \
+ | cpu_feature_rdrnd)
+#define cpu_hsw (cpu_ivb \
+ | cpu_feature_avx2 \
+ | cpu_feature_fma \
+ | cpu_feature_bmi \
+ | cpu_feature_bmi2 \
+ | cpu_feature_movbe)
+#define cpu_bdw (cpu_hsw \
+ | cpu_feature_rdseed)
+#define cpu_bdx (cpu_bdw)
+#define cpu_skl (cpu_bdw)
+#define cpu_skx (cpu_skl \
+ | cpu_feature_avx512f \
+ | cpu_feature_avx512dq \
+ | cpu_feature_avx512cd \
+ | cpu_feature_avx512bw \
+ | cpu_feature_avx512vl)
+#define cpu_clx (cpu_skx)
+#define cpu_cpx (cpu_clx)
+#define cpu_plc (cpu_skx \
+ | cpu_feature_avx512ifma \
+ | cpu_feature_avx512vbmi)
+#define cpu_snc (cpu_plc \
+ | cpu_feature_avx512vbmi2 \
+ | cpu_feature_gfni \
+ | cpu_feature_vaes \
+ | cpu_feature_avx512bitalg \
+ | cpu_feature_avx512vpopcntdq)
+#define cpu_wlc (cpu_snc \
+ | cpu_feature_shstk \
+ | cpu_feature_ibt)
+#define cpu_glc (cpu_wlc \
+ | cpu_feature_waitpkg)
+#define cpu_rpc (cpu_glc)
+#define cpu_rwc (cpu_rpc)
+#define cpu_slm (cpu_wsm \
+ | cpu_feature_rdrnd \
+ | cpu_feature_movbe)
+#define cpu_glm (cpu_slm \
+ | cpu_feature_rdseed)
+#define cpu_tnt (cpu_glm \
+ | cpu_feature_gfni \
+ | cpu_feature_waitpkg)
+#define cpu_grt (cpu_skl \
+ | cpu_feature_gfni \
+ | cpu_feature_vaes \
+ | cpu_feature_shstk \
+ | cpu_feature_ibt \
+ | cpu_feature_waitpkg)
+#define cpu_cmt (cpu_grt \
+ | cpu_feature_cmpccxadd \
+ | cpu_feature_avxifma)
+#define cpu_cnl (cpu_plc)
+#define cpu_icl (cpu_snc)
+#define cpu_tgl (cpu_wlc)
+#define cpu_adl (cpu_grt)
+#define cpu_rpl (cpu_grt)
+#define cpu_mtl (cpu_cmt)
+#define cpu_arl (cpu_cmt)
+#define cpu_lnl (cpu_cmt)
+#define cpu_icx (cpu_snc)
+#define cpu_spr (cpu_glc)
+#define cpu_emr (cpu_spr)
+#define cpu_gnr (cpu_glc)
+#define cpu_srf (cpu_cmt \
+ | cpu_feature_cmpccxadd \
+ | cpu_feature_avxifma)
+#define cpu_grr (cpu_srf \
+ | cpu_feature_raoint)
+#define cpu_cwf (cpu_srf)
+#define cpu_nehalem (cpu_nhm)
+#define cpu_westmere (cpu_wsm)
+#define cpu_sandybridge (cpu_snb)
+#define cpu_ivybridge (cpu_ivb)
+#define cpu_haswell (cpu_hsw)
+#define cpu_broadwell (cpu_bdw)
+#define cpu_skylake (cpu_skl)
+#define cpu_skylake_avx512 (cpu_skx)
+#define cpu_cascadelake (cpu_clx)
+#define cpu_cooperlake (cpu_cpx)
+#define cpu_palmcove (cpu_plc)
+#define cpu_cannonlake (cpu_cnl)
+#define cpu_sunnycove (cpu_snc)
+#define cpu_icelake_client (cpu_icl)
+#define cpu_icelake_server (cpu_icx)
+#define cpu_willowcove (cpu_wlc)
+#define cpu_tigerlake (cpu_tgl)
+#define cpu_goldencove (cpu_glc)
+#define cpu_alderlake (cpu_adl)
+#define cpu_raptorcove (cpu_rpc)
+#define cpu_raptorlake (cpu_rpl)
+#define cpu_redwoodcove (cpu_rwc)
+#define cpu_meteorlake (cpu_mtl)
+#define cpu_arrowlake (cpu_arl)
+#define cpu_lunarlake (cpu_lnl)
+#define cpu_sapphirerapids (cpu_spr)
+#define cpu_emeraldrapids (cpu_emr)
+#define cpu_graniterapids (cpu_gnr)
+#define cpu_silvermont (cpu_slm)
+#define cpu_goldmont (cpu_glm)
+#define cpu_tremont (cpu_tnt)
+#define cpu_gracemont (cpu_grt)
+#define cpu_crestmont (cpu_cmt)
+#define cpu_grandridge (cpu_grr)
+#define cpu_sierraforest (cpu_srf)
+#define cpu_clearwaterforest (cpu_cwf)
+
+// __attribute__ target strings for GCC and Clang
+#define QT_FUNCTION_TARGET_STRING_SSE2 "sse2"
#define QT_FUNCTION_TARGET_STRING_SSE3 "sse3"
-#define CpuFeatureSSSE3 (Q_UINT64_C(1) << 3)
#define QT_FUNCTION_TARGET_STRING_SSSE3 "ssse3"
-#define CpuFeatureFMA (Q_UINT64_C(1) << 4)
#define QT_FUNCTION_TARGET_STRING_FMA "fma"
-#define CpuFeatureSSE4_1 (Q_UINT64_C(1) << 5)
#define QT_FUNCTION_TARGET_STRING_SSE4_1 "sse4.1"
-#define CpuFeatureSSE4_2 (Q_UINT64_C(1) << 6)
#define QT_FUNCTION_TARGET_STRING_SSE4_2 "sse4.2"
-#define CpuFeatureMOVBE (Q_UINT64_C(1) << 7)
#define QT_FUNCTION_TARGET_STRING_MOVBE "movbe"
-#define CpuFeaturePOPCNT (Q_UINT64_C(1) << 8)
#define QT_FUNCTION_TARGET_STRING_POPCNT "popcnt"
-#define CpuFeatureAES (Q_UINT64_C(1) << 9)
#define QT_FUNCTION_TARGET_STRING_AES "aes,sse4.2"
-#define CpuFeatureAVX (Q_UINT64_C(1) << 10)
#define QT_FUNCTION_TARGET_STRING_AVX "avx"
-#define CpuFeatureF16C (Q_UINT64_C(1) << 11)
-#define QT_FUNCTION_TARGET_STRING_F16C "f16c"
-#define CpuFeatureRDRND (Q_UINT64_C(1) << 12)
+#define QT_FUNCTION_TARGET_STRING_F16C "f16c,avx"
#define QT_FUNCTION_TARGET_STRING_RDRND "rdrnd"
-
-// in CPUID Leaf 7, Sub-leaf 0, EBX:
-#define CpuFeatureBMI (Q_UINT64_C(1) << 13)
#define QT_FUNCTION_TARGET_STRING_BMI "bmi"
-#define CpuFeatureHLE (Q_UINT64_C(1) << 14)
-#define QT_FUNCTION_TARGET_STRING_HLE "hle"
-#define CpuFeatureAVX2 (Q_UINT64_C(1) << 15)
-#define QT_FUNCTION_TARGET_STRING_AVX2 "avx2"
-#define CpuFeatureBMI2 (Q_UINT64_C(1) << 16)
+#define QT_FUNCTION_TARGET_STRING_AVX2 "avx2,avx"
#define QT_FUNCTION_TARGET_STRING_BMI2 "bmi2"
-#define CpuFeatureRTM (Q_UINT64_C(1) << 17)
-#define QT_FUNCTION_TARGET_STRING_RTM "rtm"
-#define CpuFeatureAVX512F (Q_UINT64_C(1) << 18)
-#define QT_FUNCTION_TARGET_STRING_AVX512F "avx512f"
-#define CpuFeatureAVX512DQ (Q_UINT64_C(1) << 19)
-#define QT_FUNCTION_TARGET_STRING_AVX512DQ "avx512dq"
-#define CpuFeatureRDSEED (Q_UINT64_C(1) << 20)
+#define QT_FUNCTION_TARGET_STRING_AVX512F "avx512f,avx"
+#define QT_FUNCTION_TARGET_STRING_AVX512DQ "avx512dq,avx512f"
#define QT_FUNCTION_TARGET_STRING_RDSEED "rdseed"
-#define CpuFeatureAVX512IFMA (Q_UINT64_C(1) << 21)
-#define QT_FUNCTION_TARGET_STRING_AVX512IFMA "avx512ifma"
-#define CpuFeatureAVX512PF (Q_UINT64_C(1) << 22)
-#define QT_FUNCTION_TARGET_STRING_AVX512PF "avx512pf"
-#define CpuFeatureAVX512ER (Q_UINT64_C(1) << 23)
-#define QT_FUNCTION_TARGET_STRING_AVX512ER "avx512er"
-#define CpuFeatureAVX512CD (Q_UINT64_C(1) << 24)
-#define QT_FUNCTION_TARGET_STRING_AVX512CD "avx512cd"
-#define CpuFeatureSHA (Q_UINT64_C(1) << 25)
+#define QT_FUNCTION_TARGET_STRING_AVX512IFMA "avx512ifma,avx512f"
+#define QT_FUNCTION_TARGET_STRING_AVX512CD "avx512cd,avx512f"
#define QT_FUNCTION_TARGET_STRING_SHA "sha"
-#define CpuFeatureAVX512BW (Q_UINT64_C(1) << 26)
-#define QT_FUNCTION_TARGET_STRING_AVX512BW "avx512bw"
-#define CpuFeatureAVX512VL (Q_UINT64_C(1) << 27)
-#define QT_FUNCTION_TARGET_STRING_AVX512VL "avx512vl"
-
-// in CPUID Leaf 7, Sub-leaf 0, ECX:
-#define CpuFeatureAVX512VBMI (Q_UINT64_C(1) << 28)
-#define QT_FUNCTION_TARGET_STRING_AVX512VBMI "avx512vbmi"
-#define CpuFeatureAVX512VBMI2 (Q_UINT64_C(1) << 29)
-#define QT_FUNCTION_TARGET_STRING_AVX512VBMI2 "avx512vbmi2"
-#define CpuFeatureGFNI (Q_UINT64_C(1) << 30)
+#define QT_FUNCTION_TARGET_STRING_AVX512BW "avx512bw,avx512f"
+#define QT_FUNCTION_TARGET_STRING_AVX512VL "avx512vl,avx512f"
+#define QT_FUNCTION_TARGET_STRING_AVX512VBMI "avx512vbmi,avx512f"
+#define QT_FUNCTION_TARGET_STRING_WAITPKG "waitpkg"
+#define QT_FUNCTION_TARGET_STRING_AVX512VBMI2 "avx512vbmi2,avx512f"
+#define QT_FUNCTION_TARGET_STRING_SHSTK "shstk"
#define QT_FUNCTION_TARGET_STRING_GFNI "gfni"
-#define CpuFeatureVAES (Q_UINT64_C(1) << 31)
-#define QT_FUNCTION_TARGET_STRING_VAES "vaes"
-#define CpuFeatureAVX512VNNI (Q_UINT64_C(1) << 32)
-#define QT_FUNCTION_TARGET_STRING_AVX512VNNI "avx512vnni"
-#define CpuFeatureAVX512BITALG (Q_UINT64_C(1) << 33)
-#define QT_FUNCTION_TARGET_STRING_AVX512BITALG "avx512bitalg"
-#define CpuFeatureAVX512VPOPCNTDQ (Q_UINT64_C(1) << 34)
-#define QT_FUNCTION_TARGET_STRING_AVX512VPOPCNTDQ "avx512vpopcntdq"
-
-// in CPUID Leaf 7, Sub-leaf 0, EDX:
-#define CpuFeatureAVX5124NNIW (Q_UINT64_C(1) << 35)
-#define QT_FUNCTION_TARGET_STRING_AVX5124NNIW "avx5124nniw"
-#define CpuFeatureAVX5124FMAPS (Q_UINT64_C(1) << 36)
-#define QT_FUNCTION_TARGET_STRING_AVX5124FMAPS "avx5124fmaps"
+#define QT_FUNCTION_TARGET_STRING_VAES "vaes,avx2,avx,aes"
+#define QT_FUNCTION_TARGET_STRING_AVX512BITALG "avx512bitalg,avx512f"
+#define QT_FUNCTION_TARGET_STRING_AVX512VPOPCNTDQ "avx512vpopcntdq,avx512f"
+#define QT_FUNCTION_TARGET_STRING_HYBRID "hybrid"
+#define QT_FUNCTION_TARGET_STRING_IBT "ibt"
+#define QT_FUNCTION_TARGET_STRING_AVX512FP16 "avx512fp16,avx512f,f16c"
+#define QT_FUNCTION_TARGET_STRING_RAOINT "raoint"
+#define QT_FUNCTION_TARGET_STRING_CMPCCXADD "cmpccxadd"
+#define QT_FUNCTION_TARGET_STRING_AVXIFMA "avxifma,avx"
+#define QT_FUNCTION_TARGET_STRING_LAM "lam"
+#define QT_FUNCTION_TARGET_STRING_ARCH_X86_64 "sse2"
+#define QT_FUNCTION_TARGET_STRING_ARCH_CORE2 QT_FUNCTION_TARGET_STRING_ARCH_X86_64 ",sse3,ssse3,cx16"
+#define QT_FUNCTION_TARGET_STRING_ARCH_NHM QT_FUNCTION_TARGET_STRING_ARCH_CORE2 ",sse4.1,sse4.2,popcnt"
+#define QT_FUNCTION_TARGET_STRING_ARCH_WSM QT_FUNCTION_TARGET_STRING_ARCH_NHM
+#define QT_FUNCTION_TARGET_STRING_ARCH_SNB QT_FUNCTION_TARGET_STRING_ARCH_WSM ",avx"
+#define QT_FUNCTION_TARGET_STRING_ARCH_IVB QT_FUNCTION_TARGET_STRING_ARCH_SNB ",f16c,rdrnd,fsgsbase"
+#define QT_FUNCTION_TARGET_STRING_ARCH_HSW QT_FUNCTION_TARGET_STRING_ARCH_IVB ",avx2,fma,bmi,bmi2,lzcnt,movbe"
+#define QT_FUNCTION_TARGET_STRING_ARCH_BDW QT_FUNCTION_TARGET_STRING_ARCH_HSW ",adx,rdseed"
+#define QT_FUNCTION_TARGET_STRING_ARCH_BDX QT_FUNCTION_TARGET_STRING_ARCH_BDW
+#define QT_FUNCTION_TARGET_STRING_ARCH_SKL QT_FUNCTION_TARGET_STRING_ARCH_BDW ",xsavec,xsaves"
+#define QT_FUNCTION_TARGET_STRING_ARCH_SKX QT_FUNCTION_TARGET_STRING_ARCH_SKL ",avx512f,avx512dq,avx512cd,avx512bw,avx512vl"
+#define QT_FUNCTION_TARGET_STRING_ARCH_CLX QT_FUNCTION_TARGET_STRING_ARCH_SKX ",avx512vnni"
+#define QT_FUNCTION_TARGET_STRING_ARCH_CPX QT_FUNCTION_TARGET_STRING_ARCH_CLX ",avx512bf16"
+#define QT_FUNCTION_TARGET_STRING_ARCH_PLC QT_FUNCTION_TARGET_STRING_ARCH_SKX ",avx512ifma,avx512vbmi"
+#define QT_FUNCTION_TARGET_STRING_ARCH_SNC QT_FUNCTION_TARGET_STRING_ARCH_PLC ",avx512vbmi2,gfni,vaes,vpclmulqdq,avx512vnni,avx512bitalg,avx512vpopcntdq"
+#define QT_FUNCTION_TARGET_STRING_ARCH_WLC QT_FUNCTION_TARGET_STRING_ARCH_SNC ",shstk,movdiri,movdir64b,ibt,keylocker"
+#define QT_FUNCTION_TARGET_STRING_ARCH_GLC QT_FUNCTION_TARGET_STRING_ARCH_WLC ",avx512bf16,avxvnni,cldemote,waitpkg,serialize,uintr"
+#define QT_FUNCTION_TARGET_STRING_ARCH_RPC QT_FUNCTION_TARGET_STRING_ARCH_GLC
+#define QT_FUNCTION_TARGET_STRING_ARCH_RWC QT_FUNCTION_TARGET_STRING_ARCH_RPC ",prefetchiti"
+#define QT_FUNCTION_TARGET_STRING_ARCH_SLM QT_FUNCTION_TARGET_STRING_ARCH_WSM ",rdrnd,movbe"
+#define QT_FUNCTION_TARGET_STRING_ARCH_GLM QT_FUNCTION_TARGET_STRING_ARCH_SLM ",fsgsbase,rdseed,lzcnt,xsavec,xsaves"
+#define QT_FUNCTION_TARGET_STRING_ARCH_TNT QT_FUNCTION_TARGET_STRING_ARCH_GLM ",clwb,gfni,cldemote,waitpkg,movdiri,movdir64b"
+#define QT_FUNCTION_TARGET_STRING_ARCH_GRT QT_FUNCTION_TARGET_STRING_ARCH_SKL ",avxvnni,gfni,vaes,vpclmulqdq,serialize,shstk,cldemote,movdiri,movdir64b,ibt,waitpkg,keylocker"
+#define QT_FUNCTION_TARGET_STRING_ARCH_CMT QT_FUNCTION_TARGET_STRING_ARCH_GRT ",cmpccxadd,avxifma,avxneconvert,avxvnniint8"
+#define QT_FUNCTION_TARGET_STRING_ARCH_CNL QT_FUNCTION_TARGET_STRING_ARCH_PLC
+#define QT_FUNCTION_TARGET_STRING_ARCH_ICL QT_FUNCTION_TARGET_STRING_ARCH_SNC
+#define QT_FUNCTION_TARGET_STRING_ARCH_TGL QT_FUNCTION_TARGET_STRING_ARCH_WLC
+#define QT_FUNCTION_TARGET_STRING_ARCH_ADL QT_FUNCTION_TARGET_STRING_ARCH_GRT
+#define QT_FUNCTION_TARGET_STRING_ARCH_RPL QT_FUNCTION_TARGET_STRING_ARCH_GRT
+#define QT_FUNCTION_TARGET_STRING_ARCH_MTL QT_FUNCTION_TARGET_STRING_ARCH_CMT
+#define QT_FUNCTION_TARGET_STRING_ARCH_ARL QT_FUNCTION_TARGET_STRING_ARCH_CMT
+#define QT_FUNCTION_TARGET_STRING_ARCH_LNL QT_FUNCTION_TARGET_STRING_ARCH_CMT
+#define QT_FUNCTION_TARGET_STRING_ARCH_ICX QT_FUNCTION_TARGET_STRING_ARCH_SNC ",pconfig"
+#define QT_FUNCTION_TARGET_STRING_ARCH_SPR QT_FUNCTION_TARGET_STRING_ARCH_GLC ",pconfig,amx-tile,amx-bf16,amx-int8"
+#define QT_FUNCTION_TARGET_STRING_ARCH_EMR QT_FUNCTION_TARGET_STRING_ARCH_SPR
+#define QT_FUNCTION_TARGET_STRING_ARCH_GNR QT_FUNCTION_TARGET_STRING_ARCH_GLC ",pconfig,amx-tile,amx-bf16,amx-int8,amx-fp16,amx-complex"
+#define QT_FUNCTION_TARGET_STRING_ARCH_SRF QT_FUNCTION_TARGET_STRING_ARCH_CMT ",cmpccxadd,avxifma,avxneconvert,avxvnniint8"
+#define QT_FUNCTION_TARGET_STRING_ARCH_GRR QT_FUNCTION_TARGET_STRING_ARCH_SRF ",raoint"
+#define QT_FUNCTION_TARGET_STRING_ARCH_CWF QT_FUNCTION_TARGET_STRING_ARCH_SRF
+#define QT_FUNCTION_TARGET_STRING_ARCH_NEHALEM QT_FUNCTION_TARGET_STRING_ARCH_NHM
+#define QT_FUNCTION_TARGET_STRING_ARCH_WESTMERE QT_FUNCTION_TARGET_STRING_ARCH_WSM
+#define QT_FUNCTION_TARGET_STRING_ARCH_SANDYBRIDGE QT_FUNCTION_TARGET_STRING_ARCH_SNB
+#define QT_FUNCTION_TARGET_STRING_ARCH_IVYBRIDGE QT_FUNCTION_TARGET_STRING_ARCH_IVB
+#define QT_FUNCTION_TARGET_STRING_ARCH_HASWELL QT_FUNCTION_TARGET_STRING_ARCH_HSW
+#define QT_FUNCTION_TARGET_STRING_ARCH_BROADWELL QT_FUNCTION_TARGET_STRING_ARCH_BDW
+#define QT_FUNCTION_TARGET_STRING_ARCH_SKYLAKE QT_FUNCTION_TARGET_STRING_ARCH_SKL
+#define QT_FUNCTION_TARGET_STRING_ARCH_SKYLAKE_AVX512 QT_FUNCTION_TARGET_STRING_ARCH_SKX
+#define QT_FUNCTION_TARGET_STRING_ARCH_CASCADELAKE QT_FUNCTION_TARGET_STRING_ARCH_CLX
+#define QT_FUNCTION_TARGET_STRING_ARCH_COOPERLAKE QT_FUNCTION_TARGET_STRING_ARCH_CPX
+#define QT_FUNCTION_TARGET_STRING_ARCH_PALMCOVE QT_FUNCTION_TARGET_STRING_ARCH_PLC
+#define QT_FUNCTION_TARGET_STRING_ARCH_CANNONLAKE QT_FUNCTION_TARGET_STRING_ARCH_CNL
+#define QT_FUNCTION_TARGET_STRING_ARCH_SUNNYCOVE QT_FUNCTION_TARGET_STRING_ARCH_SNC
+#define QT_FUNCTION_TARGET_STRING_ARCH_ICELAKE_CLIENT QT_FUNCTION_TARGET_STRING_ARCH_ICL
+#define QT_FUNCTION_TARGET_STRING_ARCH_ICELAKE_SERVER QT_FUNCTION_TARGET_STRING_ARCH_ICX
+#define QT_FUNCTION_TARGET_STRING_ARCH_WILLOWCOVE QT_FUNCTION_TARGET_STRING_ARCH_WLC
+#define QT_FUNCTION_TARGET_STRING_ARCH_TIGERLAKE QT_FUNCTION_TARGET_STRING_ARCH_TGL
+#define QT_FUNCTION_TARGET_STRING_ARCH_GOLDENCOVE QT_FUNCTION_TARGET_STRING_ARCH_GLC
+#define QT_FUNCTION_TARGET_STRING_ARCH_ALDERLAKE QT_FUNCTION_TARGET_STRING_ARCH_ADL
+#define QT_FUNCTION_TARGET_STRING_ARCH_RAPTORCOVE QT_FUNCTION_TARGET_STRING_ARCH_RPC
+#define QT_FUNCTION_TARGET_STRING_ARCH_RAPTORLAKE QT_FUNCTION_TARGET_STRING_ARCH_RPL
+#define QT_FUNCTION_TARGET_STRING_ARCH_REDWOODCOVE QT_FUNCTION_TARGET_STRING_ARCH_RWC
+#define QT_FUNCTION_TARGET_STRING_ARCH_METEORLAKE QT_FUNCTION_TARGET_STRING_ARCH_MTL
+#define QT_FUNCTION_TARGET_STRING_ARCH_ARROWLAKE QT_FUNCTION_TARGET_STRING_ARCH_ARL
+#define QT_FUNCTION_TARGET_STRING_ARCH_LUNARLAKE QT_FUNCTION_TARGET_STRING_ARCH_LNL
+#define QT_FUNCTION_TARGET_STRING_ARCH_SAPPHIRERAPIDS QT_FUNCTION_TARGET_STRING_ARCH_SPR
+#define QT_FUNCTION_TARGET_STRING_ARCH_EMERALDRAPIDS QT_FUNCTION_TARGET_STRING_ARCH_EMR
+#define QT_FUNCTION_TARGET_STRING_ARCH_GRANITERAPIDS QT_FUNCTION_TARGET_STRING_ARCH_GNR
+#define QT_FUNCTION_TARGET_STRING_ARCH_SILVERMONT QT_FUNCTION_TARGET_STRING_ARCH_SLM
+#define QT_FUNCTION_TARGET_STRING_ARCH_GOLDMONT QT_FUNCTION_TARGET_STRING_ARCH_GLM
+#define QT_FUNCTION_TARGET_STRING_ARCH_TREMONT QT_FUNCTION_TARGET_STRING_ARCH_TNT
+#define QT_FUNCTION_TARGET_STRING_ARCH_GRACEMONT QT_FUNCTION_TARGET_STRING_ARCH_GRT
+#define QT_FUNCTION_TARGET_STRING_ARCH_CRESTMONT QT_FUNCTION_TARGET_STRING_ARCH_CMT
+#define QT_FUNCTION_TARGET_STRING_ARCH_GRANDRIDGE QT_FUNCTION_TARGET_STRING_ARCH_GRR
+#define QT_FUNCTION_TARGET_STRING_ARCH_SIERRAFOREST QT_FUNCTION_TARGET_STRING_ARCH_SRF
+#define QT_FUNCTION_TARGET_STRING_ARCH_CLEARWATERFOREST QT_FUNCTION_TARGET_STRING_ARCH_CWF
-static const quint64 qCompilerCpuFeatures = 0
+static const uint64_t _compilerCpuFeatures = 0
#ifdef __SSE2__
- | CpuFeatureSSE2
+ | cpu_feature_sse2
#endif
#ifdef __SSE3__
- | CpuFeatureSSE3
+ | cpu_feature_sse3
#endif
#ifdef __SSSE3__
- | CpuFeatureSSSE3
+ | cpu_feature_ssse3
#endif
#ifdef __FMA__
- | CpuFeatureFMA
+ | cpu_feature_fma
#endif
#ifdef __SSE4_1__
- | CpuFeatureSSE4_1
+ | cpu_feature_sse4_1
#endif
#ifdef __SSE4_2__
- | CpuFeatureSSE4_2
+ | cpu_feature_sse4_2
#endif
#ifdef __MOVBE__
- | CpuFeatureMOVBE
+ | cpu_feature_movbe
#endif
#ifdef __POPCNT__
- | CpuFeaturePOPCNT
+ | cpu_feature_popcnt
#endif
#ifdef __AES__
- | CpuFeatureAES
+ | cpu_feature_aes
#endif
#ifdef __AVX__
- | CpuFeatureAVX
+ | cpu_feature_avx
#endif
#ifdef __F16C__
- | CpuFeatureF16C
+ | cpu_feature_f16c
#endif
#ifdef __RDRND__
- | CpuFeatureRDRND
+ | cpu_feature_rdrnd
#endif
#ifdef __BMI__
- | CpuFeatureBMI
-#endif
-#ifdef __HLE__
- | CpuFeatureHLE
+ | cpu_feature_bmi
#endif
#ifdef __AVX2__
- | CpuFeatureAVX2
+ | cpu_feature_avx2
#endif
#ifdef __BMI2__
- | CpuFeatureBMI2
-#endif
-#ifdef __RTM__
- | CpuFeatureRTM
+ | cpu_feature_bmi2
#endif
#ifdef __AVX512F__
- | CpuFeatureAVX512F
+ | cpu_feature_avx512f
#endif
#ifdef __AVX512DQ__
- | CpuFeatureAVX512DQ
+ | cpu_feature_avx512dq
#endif
#ifdef __RDSEED__
- | CpuFeatureRDSEED
+ | cpu_feature_rdseed
#endif
#ifdef __AVX512IFMA__
- | CpuFeatureAVX512IFMA
-#endif
-#ifdef __AVX512PF__
- | CpuFeatureAVX512PF
-#endif
-#ifdef __AVX512ER__
- | CpuFeatureAVX512ER
+ | cpu_feature_avx512ifma
#endif
#ifdef __AVX512CD__
- | CpuFeatureAVX512CD
+ | cpu_feature_avx512cd
#endif
#ifdef __SHA__
- | CpuFeatureSHA
+ | cpu_feature_sha
#endif
#ifdef __AVX512BW__
- | CpuFeatureAVX512BW
+ | cpu_feature_avx512bw
#endif
#ifdef __AVX512VL__
- | CpuFeatureAVX512VL
+ | cpu_feature_avx512vl
#endif
#ifdef __AVX512VBMI__
- | CpuFeatureAVX512VBMI
+ | cpu_feature_avx512vbmi
+#endif
+#ifdef __WAITPKG__
+ | cpu_feature_waitpkg
#endif
#ifdef __AVX512VBMI2__
- | CpuFeatureAVX512VBMI2
+ | cpu_feature_avx512vbmi2
+#endif
+#ifdef __SHSTK__
+ | cpu_feature_shstk
#endif
#ifdef __GFNI__
- | CpuFeatureGFNI
+ | cpu_feature_gfni
#endif
#ifdef __VAES__
- | CpuFeatureVAES
-#endif
-#ifdef __AVX512VNNI__
- | CpuFeatureAVX512VNNI
+ | cpu_feature_vaes
#endif
#ifdef __AVX512BITALG__
- | CpuFeatureAVX512BITALG
+ | cpu_feature_avx512bitalg
#endif
#ifdef __AVX512VPOPCNTDQ__
- | CpuFeatureAVX512VPOPCNTDQ
+ | cpu_feature_avx512vpopcntdq
+#endif
+#ifdef __HYBRID__
+ | cpu_feature_hybrid
+#endif
+#ifdef __IBT__
+ | cpu_feature_ibt
#endif
-#ifdef __AVX5124NNIW__
- | CpuFeatureAVX5124NNIW
+#ifdef __AVX512FP16__
+ | cpu_feature_avx512fp16
#endif
-#ifdef __AVX5124FMAPS__
- | CpuFeatureAVX5124FMAPS
+#ifdef __RAOINT__
+ | cpu_feature_raoint
+#endif
+#ifdef __CMPCCXADD__
+ | cpu_feature_cmpccxadd
+#endif
+#ifdef __AVXIFMA__
+ | cpu_feature_avxifma
+#endif
+#ifdef __LAM__
+ | cpu_feature_lam
#endif
;
-QT_END_NAMESPACE
+#if (defined __cplusplus) && __cplusplus >= 201103L
+enum X86CpuFeatures : uint64_t {
+ CpuFeatureSSE2 = cpu_feature_sse2, ///< Streaming SIMD Extensions 2
+ CpuFeatureSSE3 = cpu_feature_sse3, ///< Streaming SIMD Extensions 3
+ CpuFeatureSSSE3 = cpu_feature_ssse3, ///< Supplemental Streaming SIMD Extensions 3
+ CpuFeatureFMA = cpu_feature_fma, ///< Fused Multiply-Add
+ CpuFeatureSSE4_1 = cpu_feature_sse4_1, ///< Streaming SIMD Extensions 4.1
+ CpuFeatureSSE4_2 = cpu_feature_sse4_2, ///< Streaming SIMD Extensions 4.2
+ CpuFeatureMOVBE = cpu_feature_movbe, ///< MOV Big Endian
+ CpuFeaturePOPCNT = cpu_feature_popcnt, ///< Population count
+ CpuFeatureAES = cpu_feature_aes, ///< Advenced Encryption Standard
+ CpuFeatureAVX = cpu_feature_avx, ///< Advanced Vector Extensions
+ CpuFeatureF16C = cpu_feature_f16c, ///< 16-bit Float Conversion
+ CpuFeatureRDRND = cpu_feature_rdrnd, ///< Random number generator
+ CpuFeatureBMI = cpu_feature_bmi, ///< Bit Manipulation Instructions
+ CpuFeatureAVX2 = cpu_feature_avx2, ///< Advanced Vector Extensions 2
+ CpuFeatureBMI2 = cpu_feature_bmi2, ///< Bit Manipulation Instructions 2
+ CpuFeatureAVX512F = cpu_feature_avx512f, ///< AVX512 Foundation
+ CpuFeatureAVX512DQ = cpu_feature_avx512dq, ///< AVX512 Double & Quadword
+ CpuFeatureRDSEED = cpu_feature_rdseed, ///< Random number generator for seeding
+ CpuFeatureAVX512IFMA = cpu_feature_avx512ifma, ///< AVX512 Integer Fused Multiply-Add
+ CpuFeatureAVX512CD = cpu_feature_avx512cd, ///< AVX512 Conflict Detection
+ CpuFeatureSHA = cpu_feature_sha, ///< SHA-1 and SHA-256 instructions
+ CpuFeatureAVX512BW = cpu_feature_avx512bw, ///< AVX512 Byte & Word
+ CpuFeatureAVX512VL = cpu_feature_avx512vl, ///< AVX512 Vector Length
+ CpuFeatureAVX512VBMI = cpu_feature_avx512vbmi, ///< AVX512 Vector Byte Manipulation Instructions
+ CpuFeatureWAITPKG = cpu_feature_waitpkg, ///< User-Level Monitor / Wait
+ CpuFeatureAVX512VBMI2 = cpu_feature_avx512vbmi2, ///< AVX512 Vector Byte Manipulation Instructions 2
+ CpuFeatureSHSTK = cpu_feature_shstk, ///< Control Flow Enforcement Technology Shadow Stack
+ CpuFeatureGFNI = cpu_feature_gfni, ///< Galois Field new instructions
+ CpuFeatureVAES = cpu_feature_vaes, ///< 256- and 512-bit AES
+ CpuFeatureAVX512BITALG = cpu_feature_avx512bitalg, ///< AVX512 Bit Algorithms
+ CpuFeatureAVX512VPOPCNTDQ = cpu_feature_avx512vpopcntdq, ///< AVX512 Population Count
+ CpuFeatureHYBRID = cpu_feature_hybrid, ///< Hybrid processor
+ CpuFeatureIBT = cpu_feature_ibt, ///< Control Flow Enforcement Technology Indirect Branch Tracking
+ CpuFeatureAVX512FP16 = cpu_feature_avx512fp16, ///< AVX512 16-bit Floating Point
+ CpuFeatureRAOINT = cpu_feature_raoint, ///< Remote Atomic Operations, Integer
+ CpuFeatureCMPCCXADD = cpu_feature_cmpccxadd, ///< CMPccXADD instructions
+ CpuFeatureAVXIFMA = cpu_feature_avxifma, ///< AVX-IFMA instructions
+ CpuFeatureLAM = cpu_feature_lam, ///< Linear Address Masking
+}; // enum X86CpuFeatures
+
+enum X86CpuArchitectures : uint64_t {
+ CpuArchx8664 = cpu_x86_64,
+ CpuArchCore2 = cpu_core2,
+ CpuArchNHM = cpu_nhm,
+ CpuArchWSM = cpu_wsm,
+ CpuArchSNB = cpu_snb,
+ CpuArchIVB = cpu_ivb,
+ CpuArchHSW = cpu_hsw, ///< hle,rtm
+ CpuArchBDW = cpu_bdw,
+ CpuArchBDX = cpu_bdx,
+ CpuArchSKL = cpu_skl,
+ CpuArchSKX = cpu_skx, ///< clwb
+ CpuArchCLX = cpu_clx,
+ CpuArchCPX = cpu_cpx,
+ CpuArchPLC = cpu_plc, ///< sha
+ CpuArchSNC = cpu_snc, ///< fsrm,rdpid
+ CpuArchWLC = cpu_wlc, ///< avx512vp2intersect
+ CpuArchGLC = cpu_glc, ///< tsxldtrk
+ CpuArchRPC = cpu_rpc,
+ CpuArchRWC = cpu_rwc,
+ CpuArchSLM = cpu_slm,
+ CpuArchGLM = cpu_glm,
+ CpuArchTNT = cpu_tnt,
+ CpuArchGRT = cpu_grt, ///< rdpid
+ CpuArchCMT = cpu_cmt,
+ CpuArchCNL = cpu_cnl,
+ CpuArchICL = cpu_icl,
+ CpuArchTGL = cpu_tgl,
+ CpuArchADL = cpu_adl,
+ CpuArchRPL = cpu_rpl,
+ CpuArchMTL = cpu_mtl,
+ CpuArchARL = cpu_arl,
+ CpuArchLNL = cpu_lnl,
+ CpuArchICX = cpu_icx,
+ CpuArchSPR = cpu_spr,
+ CpuArchEMR = cpu_emr,
+ CpuArchGNR = cpu_gnr,
+ CpuArchSRF = cpu_srf,
+ CpuArchGRR = cpu_grr,
+ CpuArchCWF = cpu_cwf,
+ CpuArchNehalem = cpu_nehalem, ///< Intel Core i3/i5/i7
+ CpuArchWestmere = cpu_westmere, ///< Intel Core i3/i5/i7
+ CpuArchSandyBridge = cpu_sandybridge, ///< Second Generation Intel Core i3/i5/i7
+ CpuArchIvyBridge = cpu_ivybridge, ///< Third Generation Intel Core i3/i5/i7
+ CpuArchHaswell = cpu_haswell, ///< Fourth Generation Intel Core i3/i5/i7
+ CpuArchBroadwell = cpu_broadwell, ///< Fifth Generation Intel Core i3/i5/i7
+ CpuArchSkylake = cpu_skylake, ///< Sixth Generation Intel Core i3/i5/i7
+ CpuArchSkylakeAvx512 = cpu_skylake_avx512, ///< Intel Xeon Scalable
+ CpuArchCascadeLake = cpu_cascadelake, ///< Second Generation Intel Xeon Scalable
+ CpuArchCooperLake = cpu_cooperlake, ///< Third Generation Intel Xeon Scalable
+ CpuArchPalmCove = cpu_palmcove,
+ CpuArchCannonLake = cpu_cannonlake, ///< Intel Core i3-8121U
+ CpuArchSunnyCove = cpu_sunnycove,
+ CpuArchIceLakeClient = cpu_icelake_client, ///< Tenth Generation Intel Core i3/i5/i7
+ CpuArchIceLakeServer = cpu_icelake_server, ///< Third Generation Intel Xeon Scalable
+ CpuArchWillowCove = cpu_willowcove,
+ CpuArchTigerLake = cpu_tigerlake, ///< Eleventh Generation Intel Core i3/i5/i7
+ CpuArchGoldenCove = cpu_goldencove,
+ CpuArchAlderLake = cpu_alderlake, ///< Twelfth Generation Intel Core
+ CpuArchRaptorCove = cpu_raptorcove,
+ CpuArchRaptorLake = cpu_raptorlake, ///< Thirteenth Generation Intel Core
+ CpuArchRedwoodCove = cpu_redwoodcove,
+ CpuArchMeteorLake = cpu_meteorlake,
+ CpuArchArrowLake = cpu_arrowlake,
+ CpuArchLunarLake = cpu_lunarlake,
+ CpuArchSapphireRapids = cpu_sapphirerapids, ///< Fourth Generation Intel Xeon Scalable
+ CpuArchEmeraldRapids = cpu_emeraldrapids, ///< Fifth Generation Intel Xeon Scalable
+ CpuArchGraniteRapids = cpu_graniterapids,
+ CpuArchSilvermont = cpu_silvermont,
+ CpuArchGoldmont = cpu_goldmont,
+ CpuArchTremont = cpu_tremont,
+ CpuArchGracemont = cpu_gracemont,
+ CpuArchCrestmont = cpu_crestmont,
+ CpuArchGrandRidge = cpu_grandridge,
+ CpuArchSierraForest = cpu_sierraforest,
+ CpuArchClearwaterForest = cpu_clearwaterforest,
+}; // enum X86cpuArchitectures
+#endif /* C++11 */
-#endif // QSIMD_X86_P_H
+#endif /* QSIMD_X86_P_H */
diff --git a/src/corelib/global/qswap.h b/src/corelib/global/qswap.h
new file mode 100644
index 0000000000..3d533c8a95
--- /dev/null
+++ b/src/corelib/global/qswap.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTCORE_QSWAP_H
+#define QTCORE_QSWAP_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#include <type_traits>
+#include <utility>
+
+#if 0
+#pragma qt_class(QtSwap)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+template <typename T>
+constexpr void qSwap(T &value1, T &value2)
+ noexcept(std::is_nothrow_swappable_v<T>)
+{
+ using std::swap;
+ swap(value1, value2);
+}
+
+// pure compile-time micro-optimization for our own headers, so not documented:
+template <typename T>
+constexpr inline void qt_ptr_swap(T* &lhs, T* &rhs) noexcept
+{
+ T *tmp = lhs;
+ lhs = rhs;
+ rhs = tmp;
+}
+
+QT_END_NAMESPACE
+
+#endif // QTCORE_QSWAP_H
diff --git a/src/corelib/global/qswap.qdoc b/src/corelib/global/qswap.qdoc
new file mode 100644
index 0000000000..bffad903f9
--- /dev/null
+++ b/src/corelib/global/qswap.qdoc
@@ -0,0 +1,38 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \fn template <typename T> void qSwap(T &lhs, T &rhs)
+ \relates <QtSwap>
+
+ Exchanges the values of variables \a lhs and \a rhs,
+ taking type-specific \c{swap()} overloads into account.
+
+ This function is Qt's version of
+ \l{https://www.boost.org/doc/libs/release/libs/core/doc/html/core/swap.html}{\c{boost::swap()}},
+ and is equivalent to
+ \code
+ using std::swap; // bring std::swap into scope (for built-in types)
+ swap(lhs, rhs); // unqualified call (picks up type-specific overloads
+ // via Argument-Dependent Lookup, or falls back to std::swap)
+ \endcode
+
+ Use this function primarily in generic code, where you would traditionally
+ have written the above two lines, because you don't know anything about \c{T}.
+
+ If you already know what \c{T} is, then use one of the following options, in
+ order of preference:
+
+ \list
+ \li \c{lhs.swap(rhs);} if such a member-swap exists
+ \li \c{std::swap(lhs, rhs);} if no type-specific \c{swap()} exists
+ \endlist
+
+ See
+ \l{https://www.boost.org/doc/libs/release/libs/core/doc/html/core/swap.html}{\c{boost::swap()} on boost.org}
+ for more details.
+
+ See also
+ \l{https://en.cppreference.com/w/cpp/algorithm/swap}{\c{std::swap} on cppreference.com},
+ \l{https://en.cppreference.com/w/cpp/named_req/Swappable}{\c{Swappable} on cppreference.com}.
+*/
diff --git a/src/corelib/global/qsysinfo.cpp b/src/corelib/global/qsysinfo.cpp
new file mode 100644
index 0000000000..803d447d2c
--- /dev/null
+++ b/src/corelib/global/qsysinfo.cpp
@@ -0,0 +1,1070 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qsysinfo.h"
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qoperatingsystemversion.h>
+#include <QtCore/qstring.h>
+
+#include <private/qoperatingsystemversion_p.h>
+
+#ifdef Q_OS_UNIX
+# include <sys/utsname.h>
+# include <private/qcore_unix_p.h>
+#endif
+
+#ifdef Q_OS_ANDROID
+#include <QtCore/private/qjnihelpers_p.h>
+#include <qjniobject.h>
+#endif
+
+#if defined(Q_OS_SOLARIS)
+# include <sys/systeminfo.h>
+#endif
+
+#if defined(Q_OS_DARWIN)
+# include "qnamespace.h"
+# include <private/qcore_mac_p.h>
+# if __has_include(<IOKit/IOKitLib.h>)
+# include <IOKit/IOKitLib.h>
+# endif
+#endif
+
+#ifdef Q_OS_BSD4
+# include <sys/sysctl.h>
+#endif
+
+#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
+# include "qoperatingsystemversion_win_p.h"
+# include "private/qwinregistry_p.h"
+# include "qt_windows.h"
+#endif // Q_OS_WIN || Q_OS_CYGWIN
+
+#include "archdetect.cpp"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt::StringLiterals;
+
+/*!
+ \class QSysInfo
+ \inmodule QtCore
+ \brief The QSysInfo class provides information about the system.
+
+ \list
+ \li \l WordSize specifies the size of a pointer for the platform
+ on which the application is compiled.
+ \li \l ByteOrder specifies whether the platform is big-endian or
+ little-endian.
+ \endlist
+
+ Some constants are defined only on certain platforms. You can use
+ the preprocessor symbols Q_OS_WIN and Q_OS_MACOS to test that
+ the application is compiled under Windows or \macos.
+
+ \sa QLibraryInfo
+*/
+
+/*!
+ \enum QSysInfo::Sizes
+
+ This enum provides platform-specific information about the sizes of data
+ structures used by the underlying architecture.
+
+ \value WordSize The size in bits of a pointer for the platform on which
+ the application is compiled (32 or 64).
+*/
+
+/*!
+ \enum QSysInfo::Endian
+
+ \value BigEndian Big-endian byte order (also called Network byte order)
+ \value LittleEndian Little-endian byte order
+ \value ByteOrder Equals BigEndian or LittleEndian, depending on
+ the platform's byte order.
+*/
+
+#if defined(Q_OS_DARWIN)
+
+static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current())
+{
+#ifdef Q_OS_MACOS
+ if (version.majorVersion() == 13)
+ return "Ventura";
+ if (version.majorVersion() == 12)
+ return "Monterey";
+ // Compare against predefined constant to handle 10.16/11.0
+ if (QOperatingSystemVersion::MacOSBigSur.version().isPrefixOf(version.version()))
+ return "Big Sur";
+ if (version.majorVersion() == 10) {
+ switch (version.minorVersion()) {
+ case 9:
+ return "Mavericks";
+ case 10:
+ return "Yosemite";
+ case 11:
+ return "El Capitan";
+ case 12:
+ return "Sierra";
+ case 13:
+ return "High Sierra";
+ case 14:
+ return "Mojave";
+ case 15:
+ return "Catalina";
+ }
+ }
+ // unknown, future version
+#else
+ Q_UNUSED(version);
+#endif
+ return nullptr;
+}
+
+#elif defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
+
+# ifndef QT_BOOTSTRAPPED
+class QWindowsSockInit
+{
+public:
+ QWindowsSockInit();
+ ~QWindowsSockInit();
+ int version;
+};
+
+QWindowsSockInit::QWindowsSockInit()
+: version(0)
+{
+ //### should we try for 2.2 on all platforms ??
+ WSAData wsadata;
+
+ // IPv6 requires Winsock v2.0 or better.
+ if (WSAStartup(MAKEWORD(2, 0), &wsadata) != 0) {
+ qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed.");
+ } else {
+ version = 0x20;
+ }
+}
+
+QWindowsSockInit::~QWindowsSockInit()
+{
+ WSACleanup();
+}
+Q_GLOBAL_STATIC(QWindowsSockInit, winsockInit)
+# endif // QT_BOOTSTRAPPED
+
+static QString readVersionRegistryString(const wchar_t *subKey)
+{
+ return QWinRegistryKey(HKEY_LOCAL_MACHINE, LR"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)")
+ .stringValue(subKey);
+}
+
+static inline QString windowsDisplayVersion()
+{
+ // https://tickets.puppetlabs.com/browse/FACT-3058
+ // The "ReleaseId" key stopped updating since Windows 10 20H2.
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10_20H2)
+ return readVersionRegistryString(L"DisplayVersion");
+ else
+ return readVersionRegistryString(L"ReleaseId");
+}
+
+static QString winSp_helper()
+{
+ const auto osv = qWindowsVersionInfo();
+ const qint16 major = osv.wServicePackMajor;
+ if (major) {
+ QString sp = QStringLiteral("SP ") + QString::number(major);
+ const qint16 minor = osv.wServicePackMinor;
+ if (minor)
+ sp += u'.' + QString::number(minor);
+
+ return sp;
+ }
+ return QString();
+}
+
+static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current())
+{
+ Q_UNUSED(version);
+ const OSVERSIONINFOEX osver = qWindowsVersionInfo();
+ const bool workstation = osver.wProductType == VER_NT_WORKSTATION;
+
+#define Q_WINVER(major, minor) (major << 8 | minor)
+ switch (Q_WINVER(osver.dwMajorVersion, osver.dwMinorVersion)) {
+ case Q_WINVER(10, 0):
+ if (workstation) {
+ if (osver.dwBuildNumber >= 22000)
+ return "11";
+ return "10";
+ }
+ // else: Server
+ if (osver.dwBuildNumber >= 20348)
+ return "Server 2022";
+ if (osver.dwBuildNumber >= 17763)
+ return "Server 2019";
+ return "Server 2016";
+ }
+#undef Q_WINVER
+ // unknown, future version
+ return nullptr;
+}
+
+#endif
+#if defined(Q_OS_UNIX)
+# if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD)
+# define USE_ETC_OS_RELEASE
+struct QUnixOSVersion
+{
+ // from /etc/os-release older /etc/lsb-release // redhat /etc/redhat-release // debian /etc/debian_version
+ QString productType; // $ID $DISTRIB_ID // single line file containing: // Debian
+ QString productVersion; // $VERSION_ID $DISTRIB_RELEASE // <Vendor_ID release Version_ID> // single line file <Release_ID/sid>
+ QString prettyName; // $PRETTY_NAME $DISTRIB_DESCRIPTION
+};
+
+static QString unquote(QByteArrayView str)
+{
+ // man os-release says:
+ // Variable assignment values must be enclosed in double
+ // or single quotes if they include spaces, semicolons or
+ // other special characters outside of A–Z, a–z, 0–9. Shell
+ // special characters ("$", quotes, backslash, backtick)
+ // must be escaped with backslashes, following shell style.
+ // All strings should be in UTF-8 format, and non-printable
+ // characters should not be used. It is not supported to
+ // concatenate multiple individually quoted strings.
+ if (str.size() >= 2 && str.front() == '"' && str.back() == '"')
+ str = str.sliced(1).chopped(1);
+ return QString::fromUtf8(str);
+}
+
+static QByteArray getEtcFileContent(const char *filename)
+{
+ // we're avoiding QFile here
+ int fd = qt_safe_open(filename, O_RDONLY);
+ if (fd == -1)
+ return QByteArray();
+
+ QT_STATBUF sbuf;
+ if (QT_FSTAT(fd, &sbuf) == -1) {
+ qt_safe_close(fd);
+ return QByteArray();
+ }
+
+ QByteArray buffer(sbuf.st_size, Qt::Uninitialized);
+ buffer.resize(qt_safe_read(fd, buffer.data(), sbuf.st_size));
+ qt_safe_close(fd);
+ return buffer;
+}
+
+static bool readEtcFile(QUnixOSVersion &v, const char *filename,
+ const QByteArray &idKey, const QByteArray &versionKey, const QByteArray &prettyNameKey)
+{
+
+ QByteArray buffer = getEtcFileContent(filename);
+ if (buffer.isEmpty())
+ return false;
+
+ const char *ptr = buffer.constData();
+ const char *end = buffer.constEnd();
+ const char *eol;
+ QByteArray line;
+ for (; ptr != end; ptr = eol + 1) {
+ // find the end of the line after ptr
+ eol = static_cast<const char *>(memchr(ptr, '\n', end - ptr));
+ if (!eol)
+ eol = end - 1;
+ line.setRawData(ptr, eol - ptr);
+
+ if (line.startsWith(idKey)) {
+ ptr += idKey.size();
+ v.productType = unquote({ptr, eol});
+ continue;
+ }
+
+ if (line.startsWith(prettyNameKey)) {
+ ptr += prettyNameKey.size();
+ v.prettyName = unquote({ptr, eol});
+ continue;
+ }
+
+ if (line.startsWith(versionKey)) {
+ ptr += versionKey.size();
+ v.productVersion = unquote({ptr, eol});
+ continue;
+ }
+ }
+
+ return true;
+}
+
+static bool readOsRelease(QUnixOSVersion &v)
+{
+ QByteArray id = QByteArrayLiteral("ID=");
+ QByteArray versionId = QByteArrayLiteral("VERSION_ID=");
+ QByteArray prettyName = QByteArrayLiteral("PRETTY_NAME=");
+
+ // man os-release(5) says:
+ // The file /etc/os-release takes precedence over /usr/lib/os-release.
+ // Applications should check for the former, and exclusively use its data
+ // if it exists, and only fall back to /usr/lib/os-release if it is
+ // missing.
+ return readEtcFile(v, "/etc/os-release", id, versionId, prettyName) ||
+ readEtcFile(v, "/usr/lib/os-release", id, versionId, prettyName);
+}
+
+static bool readEtcLsbRelease(QUnixOSVersion &v)
+{
+ bool ok = readEtcFile(v, "/etc/lsb-release", QByteArrayLiteral("DISTRIB_ID="),
+ QByteArrayLiteral("DISTRIB_RELEASE="), QByteArrayLiteral("DISTRIB_DESCRIPTION="));
+ if (ok && (v.prettyName.isEmpty() || v.prettyName == v.productType)) {
+ // some distributions have redundant information for the pretty name,
+ // so try /etc/<lowercasename>-release
+
+ // we're still avoiding QFile here
+ QByteArray distrorelease = "/etc/" + v.productType.toLatin1().toLower() + "-release";
+ int fd = qt_safe_open(distrorelease, O_RDONLY);
+ if (fd != -1) {
+ QT_STATBUF sbuf;
+ if (QT_FSTAT(fd, &sbuf) != -1 && sbuf.st_size > v.prettyName.size()) {
+ // file apparently contains interesting information
+ QByteArray buffer(sbuf.st_size, Qt::Uninitialized);
+ buffer.resize(qt_safe_read(fd, buffer.data(), sbuf.st_size));
+ v.prettyName = QString::fromLatin1(buffer.trimmed());
+ }
+ qt_safe_close(fd);
+ }
+ }
+
+ // some distributions have a /etc/lsb-release file that does not provide the values
+ // we are looking for, i.e. DISTRIB_ID, DISTRIB_RELEASE and DISTRIB_DESCRIPTION.
+ // Assuming that neither DISTRIB_ID nor DISTRIB_RELEASE were found, or contained valid values,
+ // returning false for readEtcLsbRelease will allow further /etc/<lowercasename>-release parsing.
+ return ok && !(v.productType.isEmpty() && v.productVersion.isEmpty());
+}
+
+#if defined(Q_OS_LINUX)
+static QByteArray getEtcFileFirstLine(const char *fileName)
+{
+ QByteArray buffer = getEtcFileContent(fileName);
+ if (buffer.isEmpty())
+ return QByteArray();
+
+ const char *ptr = buffer.constData();
+ return QByteArray(ptr, buffer.indexOf("\n")).trimmed();
+}
+
+static bool readEtcRedHatRelease(QUnixOSVersion &v)
+{
+ // /etc/redhat-release analysed should be a one line file
+ // the format of its content is <Vendor_ID release Version>
+ // i.e. "Red Hat Enterprise Linux Workstation release 6.5 (Santiago)"
+ QByteArray line = getEtcFileFirstLine("/etc/redhat-release");
+ if (line.isEmpty())
+ return false;
+
+ v.prettyName = QString::fromLatin1(line);
+
+ const char keyword[] = "release ";
+ const qsizetype releaseIndex = line.indexOf(keyword);
+ v.productType = QString::fromLatin1(line.mid(0, releaseIndex)).remove(u' ');
+ const qsizetype spaceIndex = line.indexOf(' ', releaseIndex + strlen(keyword));
+ v.productVersion = QString::fromLatin1(line.mid(releaseIndex + strlen(keyword),
+ spaceIndex > -1 ? spaceIndex - releaseIndex - int(strlen(keyword)) : -1));
+ return true;
+}
+
+static bool readEtcDebianVersion(QUnixOSVersion &v)
+{
+ // /etc/debian_version analysed should be a one line file
+ // the format of its content is <Release_ID/sid>
+ // i.e. "jessie/sid"
+ QByteArray line = getEtcFileFirstLine("/etc/debian_version");
+ if (line.isEmpty())
+ return false;
+
+ v.productType = QStringLiteral("Debian");
+ v.productVersion = QString::fromLatin1(line);
+ return true;
+}
+#endif
+
+static bool findUnixOsVersion(QUnixOSVersion &v)
+{
+ if (readOsRelease(v))
+ return true;
+ if (readEtcLsbRelease(v))
+ return true;
+#if defined(Q_OS_LINUX)
+ if (readEtcRedHatRelease(v))
+ return true;
+ if (readEtcDebianVersion(v))
+ return true;
+#endif
+ return false;
+}
+# endif // USE_ETC_OS_RELEASE
+#endif // Q_OS_UNIX
+
+#ifdef Q_OS_ANDROID
+static const char *osVer_helper(QOperatingSystemVersion)
+{
+ // https://source.android.com/source/build-numbers.html
+ // https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels
+ const int sdk_int = QtAndroidPrivate::androidSdkVersion();
+ switch (sdk_int) {
+ case 3:
+ return "Cupcake";
+ case 4:
+ return "Donut";
+ case 5:
+ case 6:
+ case 7:
+ return "Eclair";
+ case 8:
+ return "Froyo";
+ case 9:
+ case 10:
+ return "Gingerbread";
+ case 11:
+ case 12:
+ case 13:
+ return "Honeycomb";
+ case 14:
+ case 15:
+ return "Ice Cream Sandwich";
+ case 16:
+ case 17:
+ case 18:
+ return "Jelly Bean";
+ case 19:
+ case 20:
+ return "KitKat";
+ case 21:
+ case 22:
+ return "Lollipop";
+ case 23:
+ return "Marshmallow";
+ case 24:
+ case 25:
+ return "Nougat";
+ case 26:
+ case 27:
+ return "Oreo";
+ case 28:
+ return "Pie";
+ case 29:
+ return "10";
+ case 30:
+ return "11";
+ case 31:
+ return "12";
+ case 32:
+ return "12L";
+ case 33:
+ return "13";
+ default:
+ break;
+ }
+
+ return "";
+}
+#endif
+
+/*!
+ \since 5.4
+
+ Returns the architecture of the CPU that Qt was compiled for, in text
+ format. Note that this may not match the actual CPU that the application is
+ running on if there's an emulation layer or if the CPU supports multiple
+ architectures (like x86-64 processors supporting i386 applications). To
+ detect that, use currentCpuArchitecture().
+
+ Values returned by this function are stable and will not change over time,
+ so applications can rely on the returned value as an identifier, except
+ that new CPU types may be added over time.
+
+ Typical returned values are (note: list not exhaustive):
+ \list
+ \li "arm"
+ \li "arm64"
+ \li "i386"
+ \li "ia64"
+ \li "mips"
+ \li "mips64"
+ \li "power"
+ \li "power64"
+ \li "sparc"
+ \li "sparcv9"
+ \li "x86_64"
+ \endlist
+
+ \sa QSysInfo::buildAbi(), QSysInfo::currentCpuArchitecture()
+*/
+QString QSysInfo::buildCpuArchitecture()
+{
+ return QStringLiteral(ARCH_PROCESSOR);
+}
+
+/*!
+ \since 5.4
+
+ Returns the architecture of the CPU that the application is running on, in
+ text format. Note that this function depends on what the OS will report and
+ may not detect the actual CPU architecture if the OS hides that information
+ or is unable to provide it. For example, a 32-bit OS running on a 64-bit
+ CPU is usually unable to determine the CPU is actually capable of running
+ 64-bit programs.
+
+ Values returned by this function are mostly stable: an attempt will be made
+ to ensure that they stay constant over time and match the values returned
+ by QSysInfo::builldCpuArchitecture(). However, due to the nature of the
+ operating system functions being used, there may be discrepancies.
+
+ Typical returned values are (note: list not exhaustive):
+ \list
+ \li "arm"
+ \li "arm64"
+ \li "i386"
+ \li "ia64"
+ \li "mips"
+ \li "mips64"
+ \li "power"
+ \li "power64"
+ \li "sparc"
+ \li "sparcv9"
+ \li "x86_64"
+ \endlist
+
+ \sa QSysInfo::buildAbi(), QSysInfo::buildCpuArchitecture()
+*/
+QString QSysInfo::currentCpuArchitecture()
+{
+#if defined(Q_OS_WIN)
+ // We don't need to catch all the CPU architectures in this function;
+ // only those where the host CPU might be different than the build target
+ // (usually, 64-bit platforms).
+ SYSTEM_INFO info;
+ GetNativeSystemInfo(&info);
+ switch (info.wProcessorArchitecture) {
+# ifdef PROCESSOR_ARCHITECTURE_AMD64
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ return QStringLiteral("x86_64");
+# endif
+# ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
+ case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+# endif
+ case PROCESSOR_ARCHITECTURE_IA64:
+ return QStringLiteral("ia64");
+ }
+#elif defined(Q_OS_DARWIN) && !defined(Q_OS_MACOS)
+ // iOS-based OSes do not return the architecture on uname(2)'s result.
+ return buildCpuArchitecture();
+#elif defined(Q_OS_UNIX)
+ long ret = -1;
+ struct utsname u;
+
+# if defined(Q_OS_SOLARIS)
+ // We need a special call for Solaris because uname(2) on x86 returns "i86pc" for
+ // both 32- and 64-bit CPUs. Reference:
+ // http://docs.oracle.com/cd/E18752_01/html/816-5167/sysinfo-2.html#REFMAN2sysinfo-2
+ // http://fxr.watson.org/fxr/source/common/syscall/systeminfo.c?v=OPENSOLARIS
+ // http://fxr.watson.org/fxr/source/common/conf/param.c?v=OPENSOLARIS;im=10#L530
+ if (ret == -1)
+ ret = sysinfo(SI_ARCHITECTURE_64, u.machine, sizeof u.machine);
+# endif
+
+ if (ret == -1)
+ ret = uname(&u);
+
+ // we could use detectUnixVersion() above, but we only need a field no other function does
+ if (ret != -1) {
+ // the use of QT_BUILD_INTERNAL here is simply to ensure all branches build
+ // as we don't often build on some of the less common platforms
+# if defined(Q_PROCESSOR_ARM) || defined(QT_BUILD_INTERNAL)
+ if (strcmp(u.machine, "aarch64") == 0)
+ return QStringLiteral("arm64");
+ if (strncmp(u.machine, "armv", 4) == 0)
+ return QStringLiteral("arm");
+# endif
+# if defined(Q_PROCESSOR_POWER) || defined(QT_BUILD_INTERNAL)
+ // harmonize "powerpc" and "ppc" to "power"
+ if (strncmp(u.machine, "ppc", 3) == 0)
+ return "power"_L1 + QLatin1StringView(u.machine + 3);
+ if (strncmp(u.machine, "powerpc", 7) == 0)
+ return "power"_L1 + QLatin1StringView(u.machine + 7);
+ if (strcmp(u.machine, "Power Macintosh") == 0)
+ return "power"_L1;
+# endif
+# if defined(Q_PROCESSOR_SPARC) || defined(QT_BUILD_INTERNAL)
+ // Solaris sysinfo(2) (above) uses "sparcv9", but uname -m says "sun4u";
+ // Linux says "sparc64"
+ if (strcmp(u.machine, "sun4u") == 0 || strcmp(u.machine, "sparc64") == 0)
+ return QStringLiteral("sparcv9");
+ if (strcmp(u.machine, "sparc32") == 0)
+ return QStringLiteral("sparc");
+# endif
+# if defined(Q_PROCESSOR_X86) || defined(QT_BUILD_INTERNAL)
+ // harmonize all "i?86" to "i386"
+ if (strlen(u.machine) == 4 && u.machine[0] == 'i'
+ && u.machine[2] == '8' && u.machine[3] == '6')
+ return QStringLiteral("i386");
+ if (strcmp(u.machine, "amd64") == 0) // Solaris
+ return QStringLiteral("x86_64");
+# endif
+ return QString::fromLatin1(u.machine);
+ }
+#endif
+ return buildCpuArchitecture();
+}
+
+/*!
+ \since 5.4
+
+ Returns the full architecture string that Qt was compiled for. This string
+ is useful for identifying different, incompatible builds. For example, it
+ can be used as an identifier to request an upgrade package from a server.
+
+ The values returned from this function are kept stable as follows: the
+ mandatory components of the result will not change in future versions of
+ Qt, but optional suffixes may be added.
+
+ The returned value is composed of three or more parts, separated by dashes
+ ("-"). They are:
+
+ \table
+ \header \li Component \li Value
+ \row \li CPU Architecture \li The same as QSysInfo::buildCpuArchitecture(), such as "arm", "i386", "mips" or "x86_64"
+ \row \li Endianness \li "little_endian" or "big_endian"
+ \row \li Word size \li Whether it's a 32- or 64-bit application. Possible values are:
+ "llp64" (Windows 64-bit), "lp64" (Unix 64-bit), "ilp32" (32-bit)
+ \row \li (Optional) ABI \li Zero or more components identifying different ABIs possible in this architecture.
+ Currently, Qt has optional ABI components for ARM and MIPS processors: one
+ component is the main ABI (such as "eabi", "o32", "n32", "o64"); another is
+ whether the calling convention is using hardware floating point registers ("hardfloat"
+ is present).
+
+ Additionally, if Qt was configured with \c{-qreal float}, the ABI option tag "qreal_float"
+ will be present. If Qt was configured with another type as qreal, that type is present after
+ "qreal_", with all characters other than letters and digits escaped by an underscore, followed
+ by two hex digits. For example, \c{-qreal long double} becomes "qreal_long_20double".
+ \endtable
+
+ \sa QSysInfo::buildCpuArchitecture()
+*/
+QString QSysInfo::buildAbi()
+{
+ // ARCH_FULL is a concatenation of strings (incl. ARCH_PROCESSOR), which breaks
+ // QStringLiteral on MSVC. Since the concatenation behavior we want is specified
+ // the same C++11 paper as the Unicode strings, we'll use that macro and hope
+ // that Microsoft implements the new behavior when they add support for Unicode strings.
+ return QStringLiteral(ARCH_FULL);
+}
+
+static QString unknownText()
+{
+ return QStringLiteral("unknown");
+}
+
+/*!
+ \since 5.4
+
+ Returns the type of the operating system kernel Qt was compiled for. It's
+ also the kernel the application is running on, unless the host operating
+ system is running a form of compatibility or virtualization layer.
+
+ Values returned by this function are stable and will not change over time,
+ so applications can rely on the returned value as an identifier, except
+ that new OS kernel types may be added over time.
+
+ On Windows, this function returns the type of Windows kernel, like "winnt".
+ On Unix systems, it returns the same as the output of \c{uname
+ -s} (lowercased).
+
+ \note This function may return surprising values: it returns "linux"
+ for all operating systems running Linux (including Android), "qnx" for all
+ operating systems running QNX, "freebsd" for
+ Debian/kFreeBSD, and "darwin" for \macos and iOS. For information on the type
+ of product the application is running on, see productType().
+
+ \sa QFileSelector, kernelVersion(), productType(), productVersion(), prettyProductName()
+*/
+QString QSysInfo::kernelType()
+{
+#if defined(Q_OS_WIN)
+ return QStringLiteral("winnt");
+#elif defined(Q_OS_UNIX)
+ struct utsname u;
+ if (uname(&u) == 0)
+ return QString::fromLatin1(u.sysname).toLower();
+#endif
+ return unknownText();
+}
+
+/*!
+ \since 5.4
+
+ Returns the release version of the operating system kernel. On Windows, it
+ returns the version of the NT kernel. On Unix systems, including
+ Android and \macos, it returns the same as the \c{uname -r}
+ command would return.
+
+ If the version could not be determined, this function may return an empty
+ string.
+
+ \sa kernelType(), productType(), productVersion(), prettyProductName()
+*/
+QString QSysInfo::kernelVersion()
+{
+#ifdef Q_OS_WIN
+ const auto osver = QOperatingSystemVersion::current();
+ return QString::asprintf("%d.%d.%d",
+ osver.majorVersion(), osver.minorVersion(), osver.microVersion());
+#else
+ struct utsname u;
+ if (uname(&u) == 0)
+ return QString::fromLatin1(u.release);
+ return QString();
+#endif
+}
+
+
+/*!
+ \since 5.4
+
+ Returns the product name of the operating system this application is
+ running in. If the application is running on some sort of emulation or
+ virtualization layer (such as WINE on a Unix system), this function will
+ inspect the emulation / virtualization layer.
+
+ Values returned by this function are stable and will not change over time,
+ so applications can rely on the returned value as an identifier, except
+ that new OS types may be added over time.
+
+ \b{Linux and Android note}: this function returns "android" for Linux
+ systems running Android userspace, notably when using the Bionic library.
+ For all other Linux systems, regardless of C library being used, it tries
+ to determine the distribution name and returns that. If determining the
+ distribution name failed, it returns "unknown".
+
+ \b{\macos note}: this function returns "macos" for all \macos systems,
+ regardless of Apple naming convention. Previously, in Qt 5, it returned
+ "osx", again regardless of Apple naming conventions.
+
+ \b{Darwin, iOS, tvOS, and watchOS note}: this function returns "ios" for
+ iOS systems, "tvos" for tvOS systems, "watchos" for watchOS systems, and
+ "darwin" in case the system could not be determined.
+
+ \b{FreeBSD note}: this function returns "debian" for Debian/kFreeBSD and
+ "unknown" otherwise.
+
+ \b{Windows note}: this function return "windows"
+
+ For other Unix-type systems, this function usually returns "unknown".
+
+ \sa QFileSelector, kernelType(), kernelVersion(), productVersion(), prettyProductName()
+*/
+QString QSysInfo::productType()
+{
+ // similar, but not identical to QFileSelectorPrivate::platformSelectors
+#if defined(Q_OS_WIN)
+ return QStringLiteral("windows");
+
+#elif defined(Q_OS_QNX)
+ return QStringLiteral("qnx");
+
+#elif defined(Q_OS_ANDROID)
+ return QStringLiteral("android");
+
+#elif defined(Q_OS_IOS)
+ return QStringLiteral("ios");
+#elif defined(Q_OS_TVOS)
+ return QStringLiteral("tvos");
+#elif defined(Q_OS_WATCHOS)
+ return QStringLiteral("watchos");
+#elif defined(Q_OS_MACOS)
+ return QStringLiteral("macos");
+#elif defined(Q_OS_DARWIN)
+ return QStringLiteral("darwin");
+#elif defined(Q_OS_WASM)
+ return QStringLiteral("wasm");
+
+#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
+ QUnixOSVersion unixOsVersion;
+ findUnixOsVersion(unixOsVersion);
+ if (!unixOsVersion.productType.isEmpty())
+ return unixOsVersion.productType;
+#endif
+ return unknownText();
+}
+
+/*!
+ \since 5.4
+
+ Returns the product version of the operating system in string form. If the
+ version could not be determined, this function returns "unknown".
+
+ It will return the Android, iOS, \macos, Windows full-product
+ versions on those systems.
+
+ Typical returned values are (note: list not exhaustive):
+ \list
+ \li "12" (Android 12)
+ \li "36" (Fedora 36)
+ \li "15.5" (iOS 15.5)
+ \li "12.4" (macOS Monterey)
+ \li "22.04" (Ubuntu 22.04)
+ \li "8.6" (watchOS 8.6)
+ \li "11" (Windows 11)
+ \li "Server 2022" (Windows Server 2022)
+ \endlist
+
+ On Linux systems, it will try to determine the distribution version and will
+ return that. This is also done on Debian/kFreeBSD, so this function will
+ return Debian version in that case.
+
+ In all other Unix-type systems, this function always returns "unknown".
+
+ \note The version string returned from this function is not guaranteed to
+ be orderable. On Linux, the version of
+ the distribution may jump unexpectedly, please refer to the distribution's
+ documentation for versioning practices.
+
+ \sa kernelType(), kernelVersion(), productType(), prettyProductName()
+*/
+QString QSysInfo::productVersion()
+{
+#if defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN)
+ const auto version = QOperatingSystemVersion::current();
+ return QString::asprintf("%d.%d", version.majorVersion(), version.minorVersion());
+#elif defined(Q_OS_WIN)
+ const char *version = osVer_helper();
+ if (version) {
+ const QLatin1Char spaceChar(' ');
+ return QString::fromLatin1(version).remove(spaceChar).toLower() + winSp_helper().remove(spaceChar).toLower();
+ }
+ // fall through
+
+#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
+ QUnixOSVersion unixOsVersion;
+ findUnixOsVersion(unixOsVersion);
+ if (!unixOsVersion.productVersion.isEmpty())
+ return unixOsVersion.productVersion;
+#endif
+
+ // fallback
+ return unknownText();
+}
+
+/*!
+ \since 5.4
+
+ Returns a prettier form of productType() and productVersion(), containing
+ other tokens like the operating system type, codenames and other
+ information. The result of this function is suitable for displaying to the
+ user, but not for long-term storage, as the string may change with updates
+ to Qt.
+
+ If productType() is "unknown", this function will instead use the
+ kernelType() and kernelVersion() functions.
+
+ \sa kernelType(), kernelVersion(), productType(), productVersion()
+*/
+QString QSysInfo::prettyProductName()
+{
+#if defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN)
+ const auto version = QOperatingSystemVersion::current();
+ const int majorVersion = version.majorVersion();
+ const QString versionString = QString::asprintf("%d.%d", majorVersion, version.minorVersion());
+ QString result = version.name() + u' ';
+ const char *name = osVer_helper(version);
+ if (!name)
+ return result + versionString;
+ result += QLatin1StringView(name);
+# if !defined(Q_OS_WIN)
+ return result + " ("_L1 + versionString + u')';
+# else
+ // (resembling winver.exe): Windows 10 "Windows 10 Version 1809"
+ const auto displayVersion = windowsDisplayVersion();
+ if (!displayVersion.isEmpty())
+ result += " Version "_L1 + displayVersion;
+ return result;
+# endif // Windows
+#elif defined(Q_OS_HAIKU)
+ return "Haiku "_L1 + productVersion();
+#elif defined(Q_OS_UNIX)
+# ifdef USE_ETC_OS_RELEASE
+ QUnixOSVersion unixOsVersion;
+ findUnixOsVersion(unixOsVersion);
+ if (!unixOsVersion.prettyName.isEmpty())
+ return unixOsVersion.prettyName;
+# endif
+ struct utsname u;
+ if (uname(&u) == 0)
+ return QString::fromLatin1(u.sysname) + u' ' + QString::fromLatin1(u.release);
+#endif
+ return unknownText();
+}
+
+#ifndef QT_BOOTSTRAPPED
+/*!
+ \since 5.6
+
+ Returns this machine's host name, if one is configured. Note that hostnames
+ are not guaranteed to be globally unique, especially if they were
+ configured automatically.
+
+ This function does not guarantee the returned host name is a Fully
+ Qualified Domain Name (FQDN). For that, use QHostInfo to resolve the
+ returned name to an FQDN.
+
+ This function returns the same as QHostInfo::localHostName().
+
+ \sa QHostInfo::localDomainName, machineUniqueId()
+*/
+QString QSysInfo::machineHostName()
+{
+ // the hostname can change, so we can't cache it
+#if defined(Q_OS_LINUX)
+ // gethostname(3) on Linux just calls uname(2), so do it ourselves
+ // and avoid a memcpy
+ struct utsname u;
+ if (uname(&u) == 0)
+ return QString::fromLocal8Bit(u.nodename);
+ return QString();
+#else
+# ifdef Q_OS_WIN
+ // Important: QtNetwork depends on machineHostName() initializing ws2_32.dll
+ winsockInit();
+ QString hostName;
+ hostName.resize(512);
+ unsigned long len = hostName.size();
+ BOOL res = GetComputerNameEx(ComputerNameDnsHostname,
+ reinterpret_cast<wchar_t *>(const_cast<quint16 *>(hostName.utf16())), &len);
+ if (!res && len > 512) {
+ hostName.resize(len - 1);
+ GetComputerNameEx(ComputerNameDnsHostname,
+ reinterpret_cast<wchar_t *>(const_cast<quint16 *>(hostName.utf16())), &len);
+ }
+ hostName.truncate(len);
+ return hostName;
+# else // !Q_OS_WIN
+
+ char hostName[512];
+ if (gethostname(hostName, sizeof(hostName)) == -1)
+ return QString();
+ hostName[sizeof(hostName) - 1] = '\0';
+ return QString::fromLocal8Bit(hostName);
+# endif
+#endif
+}
+#endif // QT_BOOTSTRAPPED
+
+enum {
+ UuidStringLen = sizeof("00000000-0000-0000-0000-000000000000") - 1
+};
+
+/*!
+ \since 5.11
+
+ Returns a unique ID for this machine, if one can be determined. If no
+ unique ID could be determined, this function returns an empty byte array.
+ Unlike machineHostName(), the value returned by this function is likely
+ globally unique.
+
+ A unique ID is useful in network operations to identify this machine for an
+ extended period of time, when the IP address could change or if this
+ machine could have more than one IP address. For example, the ID could be
+ used when communicating with a server or when storing device-specific data
+ in shared network storage.
+
+ Note that on some systems, this value will persist across reboots and on
+ some it will not. Applications should not blindly depend on this fact
+ without verifying the OS capabilities. In particular, on Linux systems,
+ this ID is usually permanent and it matches the D-Bus machine ID, except
+ for nodes without their own storage (replicated nodes).
+
+ \sa machineHostName(), bootUniqueId()
+*/
+QByteArray QSysInfo::machineUniqueId()
+{
+#if defined(Q_OS_DARWIN) && __has_include(<IOKit/IOKitLib.h>)
+ char uuid[UuidStringLen + 1];
+ io_service_t service = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
+ QCFString stringRef = (CFStringRef)IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
+ CFStringGetCString(stringRef, uuid, sizeof(uuid), kCFStringEncodingMacRoman);
+ return QByteArray(uuid);
+#elif defined(Q_OS_BSD4) && defined(KERN_HOSTUUID)
+ char uuid[UuidStringLen + 1];
+ size_t uuidlen = sizeof(uuid);
+ int name[] = { CTL_KERN, KERN_HOSTUUID };
+ if (sysctl(name, sizeof name / sizeof name[0], &uuid, &uuidlen, nullptr, 0) == 0
+ && uuidlen == sizeof(uuid))
+ return QByteArray(uuid, uuidlen - 1);
+#elif defined(Q_OS_UNIX)
+ // The modern name on Linux is /etc/machine-id, but that path is
+ // unlikely to exist on non-Linux (non-systemd) systems. The old
+ // path is more than enough.
+ static const char fullfilename[] = "/usr/local/var/lib/dbus/machine-id";
+ const char *firstfilename = fullfilename + sizeof("/usr/local") - 1;
+ int fd = qt_safe_open(firstfilename, O_RDONLY);
+ if (fd == -1 && errno == ENOENT)
+ fd = qt_safe_open(fullfilename, O_RDONLY);
+
+ if (fd != -1) {
+ char buffer[32]; // 128 bits, hex-encoded
+ qint64 len = qt_safe_read(fd, buffer, sizeof(buffer));
+ qt_safe_close(fd);
+
+ if (len != -1)
+ return QByteArray(buffer, len);
+ }
+#elif defined(Q_OS_WIN)
+ // Let's poke at the registry
+ const QString machineGuid = QWinRegistryKey(HKEY_LOCAL_MACHINE, LR"(SOFTWARE\Microsoft\Cryptography)")
+ .stringValue(u"MachineGuid"_s);
+ if (!machineGuid.isEmpty())
+ return machineGuid.toLatin1();
+#endif
+ return QByteArray();
+}
+
+/*!
+ \since 5.11
+
+ Returns a unique ID for this machine's boot, if one can be determined. If
+ no unique ID could be determined, this function returns an empty byte
+ array. This value is expected to change after every boot and can be
+ considered globally unique.
+
+ This function is currently only implemented for Linux and Apple operating
+ systems.
+
+ \sa machineUniqueId()
+*/
+QByteArray QSysInfo::bootUniqueId()
+{
+#ifdef Q_OS_LINUX
+ // use low-level API here for simplicity
+ int fd = qt_safe_open("/proc/sys/kernel/random/boot_id", O_RDONLY);
+ if (fd != -1) {
+ char uuid[UuidStringLen];
+ qint64 len = qt_safe_read(fd, uuid, sizeof(uuid));
+ qt_safe_close(fd);
+ if (len == UuidStringLen)
+ return QByteArray(uuid, UuidStringLen);
+ }
+#elif defined(Q_OS_DARWIN)
+ // "kern.bootsessionuuid" is only available by name
+ char uuid[UuidStringLen + 1];
+ size_t uuidlen = sizeof(uuid);
+ if (sysctlbyname("kern.bootsessionuuid", uuid, &uuidlen, nullptr, 0) == 0
+ && uuidlen == sizeof(uuid))
+ return QByteArray(uuid, uuidlen - 1);
+#endif
+ return QByteArray();
+};
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h
index 04379ecd7e..01f6313299 100644
--- a/src/corelib/global/qsysinfo.h
+++ b/src/corelib/global/qsysinfo.h
@@ -1,48 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSYSINFO_H
#define QSYSINFO_H
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qprocessordetection.h>
+#include <QtCore/qtcoreexports.h>
+
QT_BEGIN_NAMESPACE
/*
@@ -50,6 +16,8 @@ QT_BEGIN_NAMESPACE
*/
class QString;
+class QByteArray;
+
class Q_CORE_EXPORT QSysInfo
{
public:
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index c8f98042c9..d797a19600 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -1,45 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Copyright (C) 2019 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// Copyright (C) 2019 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#ifndef QGLOBAL_H
-# include <QtCore/qglobal.h>
+#if 0
+#pragma qt_class(QtSystemDetection)
+#pragma qt_sync_skip_header_check
+#pragma qt_sync_stop_processing
#endif
#ifndef QSYSTEMDETECTION_H
@@ -72,6 +38,7 @@
ANDROID - Android platform
HAIKU - Haiku
WEBOS - LG WebOS
+ WASM - WebAssembly
The following operating systems have variants:
LINUX - both Q_OS_LINUX and Q_OS_ANDROID are defined when building for Android
@@ -84,14 +51,10 @@
#if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))
# include <TargetConditionals.h>
+# define Q_OS_APPLE
# if defined(TARGET_OS_MAC) && TARGET_OS_MAC
# define Q_OS_DARWIN
# define Q_OS_BSD4
-# ifdef __LP64__
-# define Q_OS_DARWIN64
-# else
-# define Q_OS_DARWIN32
-# endif
# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
# define QT_PLATFORM_UIKIT
# if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH
@@ -128,8 +91,6 @@
# define Q_OS_SOLARIS
#elif defined(hpux) || defined(__hpux)
# define Q_OS_HPUX
-#elif defined(__native_client__)
-# define Q_OS_NACL
#elif defined(__EMSCRIPTEN__)
# define Q_OS_WASM
#elif defined(__linux__) || defined(__linux)
@@ -161,7 +122,7 @@
# define Q_OS_INTEGRITY
#elif defined(__rtems__)
# define Q_OS_RTEMS
-#elif defined(VXWORKS) /* there is no "real" VxWorks define - this has to be set in the mkspec! */
+#elif defined(__vxworks)
# define Q_OS_VXWORKS
#elif defined(__HAIKU__)
# define Q_OS_HAIKU
@@ -187,93 +148,77 @@
// Compatibility synonyms
#ifdef Q_OS_DARWIN
-#define Q_OS_MAC
-#endif
-#ifdef Q_OS_DARWIN32
-#define Q_OS_MAC32
-#endif
-#ifdef Q_OS_DARWIN64
-#define Q_OS_MAC64
-#endif
-#ifdef Q_OS_MACOS
-#define Q_OS_MACX
-#define Q_OS_OSX
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunknown-pragmas"
+# define Q_OS_MAC // FIXME: Deprecate
+# ifdef __LP64__
+# define Q_OS_DARWIN64
+# pragma clang deprecated(Q_OS_DARWIN64, "use Q_OS_DARWIN and QT_POINTER_SIZE/Q_PROCESSOR_* instead")
+# define Q_OS_MAC64
+# pragma clang deprecated(Q_OS_MAC64, "use Q_OS_DARWIN and QT_POINTER_SIZE/Q_PROCESSOR_* instead")
+# else
+# define Q_OS_DARWIN32
+# pragma clang deprecated(Q_OS_DARWIN32, "use Q_OS_DARWIN and QT_POINTER_SIZE/Q_PROCESSOR_* instead")
+# define Q_OS_MAC32
+# pragma clang deprecated(Q_OS_MAC32, "use Q_OS_DARWIN and QT_POINTER_SIZE/Q_PROCESSOR_* instead")
+# endif
+# ifdef Q_OS_MACOS
+# define Q_OS_MACX
+# pragma clang deprecated(Q_OS_MACX, "use Q_OS_MACOS instead")
+# define Q_OS_OSX
+# pragma clang deprecated(Q_OS_OSX, "use Q_OS_MACOS instead")
+# endif
+# pragma clang diagnostic pop
#endif
#ifdef Q_OS_DARWIN
# include <Availability.h>
# include <AvailabilityMacros.h>
-#
-# ifdef Q_OS_MACOS
-# if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6
-# undef __MAC_OS_X_VERSION_MIN_REQUIRED
-# define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_10_6
-# endif
-# if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
-# undef MAC_OS_X_VERSION_MIN_REQUIRED
-# define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
-# endif
-# endif
-#
-# // Numerical checks are preferred to named checks, but to be safe
-# // we define the missing version names in case Qt uses them.
-#
-# if !defined(__MAC_10_11)
-# define __MAC_10_11 101100
-# endif
-# if !defined(__MAC_10_12)
-# define __MAC_10_12 101200
-# endif
-# if !defined(__MAC_10_13)
-# define __MAC_10_13 101300
-# endif
-# if !defined(__MAC_10_14)
-# define __MAC_10_14 101400
-# endif
-# if !defined(__MAC_10_15)
-# define __MAC_10_15 101500
-# endif
-# if !defined(__MAC_10_16)
-# define __MAC_10_16 101600
-# endif
-# if !defined(MAC_OS_X_VERSION_10_11)
-# define MAC_OS_X_VERSION_10_11 __MAC_10_11
-# endif
-# if !defined(MAC_OS_X_VERSION_10_12)
-# define MAC_OS_X_VERSION_10_12 __MAC_10_12
-# endif
-# if !defined(MAC_OS_X_VERSION_10_13)
-# define MAC_OS_X_VERSION_10_13 __MAC_10_13
-# endif
-# if !defined(MAC_OS_X_VERSION_10_14)
-# define MAC_OS_X_VERSION_10_14 __MAC_10_14
-# endif
-# if !defined(MAC_OS_X_VERSION_10_15)
-# define MAC_OS_X_VERSION_10_15 __MAC_10_15
-# endif
-# if !defined(MAC_OS_X_VERSION_10_16)
-# define MAC_OS_X_VERSION_10_16 __MAC_10_16
-# endif
-#
-# if !defined(__IPHONE_10_0)
-# define __IPHONE_10_0 100000
-# endif
-# if !defined(__IPHONE_10_1)
-# define __IPHONE_10_1 100100
-# endif
-# if !defined(__IPHONE_10_2)
-# define __IPHONE_10_2 100200
-# endif
-# if !defined(__IPHONE_10_3)
-# define __IPHONE_10_3 100300
-# endif
-# if !defined(__IPHONE_11_0)
-# define __IPHONE_11_0 110000
-# endif
-# if !defined(__IPHONE_12_0)
-# define __IPHONE_12_0 120000
-# endif
-#endif
+
+# define QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, tvos, watchos) \
+ ((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && macos != __MAC_NA && __MAC_OS_X_VERSION_MAX_ALLOWED >= macos) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios) || \
+ (defined(__TV_OS_VERSION_MAX_ALLOWED) && tvos != __TVOS_NA && __TV_OS_VERSION_MAX_ALLOWED >= tvos) || \
+ (defined(__WATCH_OS_VERSION_MAX_ALLOWED) && watchos != __WATCHOS_NA && __WATCH_OS_VERSION_MAX_ALLOWED >= watchos))
+
+# define QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, ios, tvos, watchos) \
+ ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && macos != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < macos) || \
+ (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MIN_REQUIRED < ios) || \
+ (defined(__TV_OS_VERSION_MIN_REQUIRED) && tvos != __TVOS_NA && __TV_OS_VERSION_MIN_REQUIRED < tvos) || \
+ (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && watchos != __WATCHOS_NA && __WATCH_OS_VERSION_MIN_REQUIRED < watchos))
+
+# define QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios) \
+ QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, __TVOS_NA, __WATCHOS_NA)
+# define QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos) \
+ QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, __IPHONE_NA, __TVOS_NA, __WATCHOS_NA)
+# define QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(ios) \
+ QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, ios, __TVOS_NA, __WATCHOS_NA)
+# define QT_TVOS_PLATFORM_SDK_EQUAL_OR_ABOVE(tvos) \
+ QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_NA, tvos, __WATCHOS_NA)
+# define QT_WATCHOS_PLATFORM_SDK_EQUAL_OR_ABOVE(watchos) \
+ QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_NA, __TVOS_NA, watchos)
+
+# define QT_MACOS_IOS_DEPLOYMENT_TARGET_BELOW(macos, ios) \
+ QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, ios, __TVOS_NA, __WATCHOS_NA)
+# define QT_MACOS_DEPLOYMENT_TARGET_BELOW(macos) \
+ QT_DARWIN_DEPLOYMENT_TARGET_BELOW(macos, __IPHONE_NA, __TVOS_NA, __WATCHOS_NA)
+# define QT_IOS_DEPLOYMENT_TARGET_BELOW(ios) \
+ QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, ios, __TVOS_NA, __WATCHOS_NA)
+# define QT_TVOS_DEPLOYMENT_TARGET_BELOW(tvos) \
+ QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, __IPHONE_NA, tvos, __WATCHOS_NA)
+# define QT_WATCHOS_DEPLOYMENT_TARGET_BELOW(watchos) \
+ QT_DARWIN_DEPLOYMENT_TARGET_BELOW(__MAC_NA, __IPHONE_NA, __TVOS_NA, watchos)
+
+#else // !Q_OS_DARWIN
+
+#define QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, tvos, watchos) (0)
+#define QT_MACOS_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios) (0)
+#define QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(macos) (0)
+#define QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(ios) (0)
+#define QT_TVOS_PLATFORM_SDK_EQUAL_OR_ABOVE(tvos) (0)
+#define QT_WATCHOS_PLATFORM_SDK_EQUAL_OR_ABOVE(watchos) (0)
+
+#endif // Q_OS_DARWIN
#ifdef __LSB_VERSION__
# if __LSB_VERSION__ < 40
@@ -284,4 +229,11 @@
#endif
#endif
+#if defined (__ELF__)
+# define Q_OF_ELF
+#endif
+#if defined (__MACH__) && defined (__APPLE__)
+# define Q_OF_MACH_O
+#endif
+
#endif // QSYSTEMDETECTION_H
diff --git a/src/corelib/global/qsystemdetection.qdoc b/src/corelib/global/qsystemdetection.qdoc
new file mode 100644
index 0000000000..11750e8cf7
--- /dev/null
+++ b/src/corelib/global/qsystemdetection.qdoc
@@ -0,0 +1,212 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \headerfile <QtSystemDetection>
+ \inmodule QtCore
+ \title Platform-specific Macro Definitions
+ \ingroup funclists
+
+ \brief The <QtSystemDetection> header file includes various
+ platfrom-specific macros.
+
+ The <QtSystemDetection> header file declares a range of macros (Q_OS_*)
+ that are defined for the specified platforms. For example, Q_OS_UNIX which
+ is defined for Unix-based systems.
+
+ The purpose of these macros is to enable programmers to add
+ platform-specific code to their application.
+*/
+
+/*!
+ \macro Q_OS_DARWIN
+ \relates <QtSystemDetection>
+
+ Defined on Darwin-based operating systems such as \macos, iOS, watchOS, and tvOS.
+
+ \note Unless you are dealing with code specific to the Darwin kernel,
+ prefer Q_OS_APPLE to refer to the family of Apple operating systems.
+*/
+
+/*!
+ \macro Q_OS_APPLE
+ \relates <QtSystemDetection>
+
+ Defined on Apple operating systems such as \macos, iOS, watchOS, and tvOS.
+*/
+
+/*!
+ \macro Q_OS_MAC
+ \relates <QtSystemDetection>
+
+ Deprecated synonym for \c Q_OS_DARWIN. Do not use.
+*/
+
+/*!
+ \macro Q_OS_OSX
+ \relates <QtSystemDetection>
+
+ Deprecated synonym for \c Q_OS_MACOS. Do not use.
+*/
+
+/*!
+ \macro Q_OS_MACOS
+ \relates <QtSystemDetection>
+
+ Defined on \macos.
+*/
+
+/*!
+ \macro Q_OS_IOS
+ \relates <QtSystemDetection>
+
+ Defined on iOS.
+*/
+
+/*!
+ \macro Q_OS_WATCHOS
+ \relates <QtSystemDetection>
+
+ Defined on watchOS.
+*/
+
+/*!
+ \macro Q_OS_TVOS
+ \relates <QtSystemDetection>
+
+ Defined on tvOS.
+*/
+
+/*!
+ \macro Q_OS_WIN
+ \relates <QtSystemDetection>
+
+ Defined on all supported versions of Windows. That is, if
+ \l Q_OS_WIN32 or \l Q_OS_WIN64 is defined.
+*/
+
+/*!
+ \macro Q_OS_WINDOWS
+ \relates <QtSystemDetection>
+
+ This is a synonym for Q_OS_WIN.
+*/
+
+/*!
+ \macro Q_OS_WIN32
+ \relates <QtSystemDetection>
+
+ Defined on 32-bit and 64-bit versions of Windows.
+*/
+
+/*!
+ \macro Q_OS_WIN64
+ \relates <QtSystemDetection>
+
+ Defined on 64-bit versions of Windows.
+*/
+
+/*!
+ \macro Q_OS_CYGWIN
+ \relates <QtSystemDetection>
+
+ Defined on Cygwin.
+*/
+
+/*!
+ \macro Q_OS_SOLARIS
+ \relates <QtSystemDetection>
+
+ Defined on Sun Solaris.
+*/
+
+/*!
+ \macro Q_OS_HPUX
+ \relates <QtSystemDetection>
+
+ Defined on HP-UX.
+*/
+
+/*!
+ \macro Q_OS_LINUX
+ \relates <QtSystemDetection>
+
+ Defined on Linux.
+*/
+
+/*!
+ \macro Q_OS_ANDROID
+ \relates <QtSystemDetection>
+
+ Defined on Android.
+*/
+
+/*!
+ \macro Q_OS_FREEBSD
+ \relates <QtSystemDetection>
+
+ Defined on FreeBSD.
+*/
+
+/*!
+ \macro Q_OS_NETBSD
+ \relates <QtSystemDetection>
+
+ Defined on NetBSD.
+*/
+
+/*!
+ \macro Q_OS_OPENBSD
+ \relates <QtSystemDetection>
+
+ Defined on OpenBSD.
+*/
+
+/*!
+ \macro Q_OS_AIX
+ \relates <QtSystemDetection>
+
+ Defined on AIX.
+*/
+
+/*!
+ \macro Q_OS_HURD
+ \relates <QtSystemDetection>
+
+ Defined on GNU Hurd.
+*/
+
+/*!
+ \macro Q_OS_QNX
+ \relates <QtSystemDetection>
+
+ Defined on QNX Neutrino.
+*/
+
+/*!
+ \macro Q_OS_LYNX
+ \relates <QtSystemDetection>
+
+ Defined on LynxOS.
+*/
+
+/*!
+ \macro Q_OS_BSD4
+ \relates <QtSystemDetection>
+
+ Defined on any BSD 4.4 system.
+*/
+
+/*!
+ \macro Q_OS_UNIX
+ \relates <QtSystemDetection>
+
+ Defined on any UNIX BSD/SYSV system.
+*/
+
+/*!
+ \macro Q_OS_WASM
+ \relates <QtSystemDetection>
+
+ Defined on Web Assembly.
+*/
diff --git a/src/corelib/global/qt_pch.h b/src/corelib/global/qt_pch.h
index 6108b075f0..3f224cda85 100644
--- a/src/corelib/global/qt_pch.h
+++ b/src/corelib/global/qt_pch.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
/*
* This is a precompiled header file for use in Xcode / Mac GCC /
@@ -50,36 +14,31 @@
// for rand_s, _CRT_RAND_S must be #defined before #including stdlib.h.
// put it at the beginning so some indirect inclusion doesn't break it
#ifndef _CRT_RAND_S
-#define _CRT_RAND_S
+# define _CRT_RAND_S
#endif
#include <stdlib.h>
#include <qglobal.h>
#ifdef Q_OS_WIN
-# ifdef Q_CC_MINGW
+# ifdef Q_CC_MINGW
// <unistd.h> must be included before any other header pulls in <time.h>.
-# include <unistd.h> // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r()
-# endif
-# define _POSIX_
-# include <limits.h>
-# undef _POSIX_
-# if defined(Q_CC_CLANG) && defined(Q_CC_MSVC)
-// See https://bugs.llvm.org/show_bug.cgi?id=41226
-# include <wchar.h>
-__declspec(selectany) auto *__wmemchr_symbol_loader_value = wmemchr(L"", L'0', 0);
-# endif
-# endif
-# include <qcoreapplication.h>
-# include <qcoreevent.h>
-# include <qiodevice.h>
-# include <qlist.h>
-# include <qvariant.h> /* All moc genereated code has this include */
-# include <qobject.h>
-# if QT_CONFIG(regularexpression)
-# include <qregularexpression.h>
-# endif
-# include <qscopedpointer.h>
-# include <qshareddata.h>
-# include <qstring.h>
-# include <qstringlist.h>
-# include <qtimer.h>
+# include <unistd.h> // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r()
+# endif // Q_CC_MINGW
+# define _POSIX_
+# include <limits.h>
+# undef _POSIX_
+#endif // Q_OS_WIN
+#include <qcoreapplication.h>
+#include <qcoreevent.h>
+#include <qiodevice.h>
+#include <qlist.h>
+#include <qvariant.h> /* All moc generated code has this include */
+#include <qobject.h>
+#if QT_CONFIG(regularexpression)
+# include <qregularexpression.h>
+#endif
+#include <qscopedpointer.h>
+#include <qshareddata.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qtimer.h>
#endif
diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h
index 7ffe313f00..5586d0b927 100644
--- a/src/corelib/global/qt_windows.h
+++ b/src/corelib/global/qt_windows.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QT_WINDOWS_H
#define QT_WINDOWS_H
@@ -45,17 +9,17 @@
#pragma qt_sync_stop_processing
#endif
-#if defined(Q_CC_MINGW)
-// mingw's windows.h does not set _WIN32_WINNT, resulting breaking compilation
-# ifndef WINVER
-# define WINVER 0x601
-# endif
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x601
-# endif
-# ifndef NTDDI_VERSION
-# define NTDDI_VERSION 0x06010000
-# endif
+#ifndef WINVER
+# define WINVER 0x0A00 // _WIN32_WINNT_WIN10
+#endif
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0A00
+#endif
+#ifndef _WIN32_IE
+# define _WIN32_IE 0x0A00
+#endif
+#ifndef NTDDI_VERSION
+# define NTDDI_VERSION 0x0A00000C // NTDDI_WIN10_NI
#endif
#ifndef NOMINMAX
@@ -63,13 +27,6 @@
#endif
#include <windows.h>
-#if defined(_WIN32_IE) && _WIN32_IE < 0x0501
-# undef _WIN32_IE
-#endif
-#if !defined(_WIN32_IE)
-# define _WIN32_IE 0x0501
-#endif
-
// already defined when compiled with WINVER >= 0x0500
#ifndef SPI_SETMENUANIMATION
#define SPI_SETMENUANIMATION 0x1003
diff --git a/src/corelib/global/qtclasshelpermacros.h b/src/corelib/global/qtclasshelpermacros.h
new file mode 100644
index 0000000000..8839e80fb9
--- /dev/null
+++ b/src/corelib/global/qtclasshelpermacros.h
@@ -0,0 +1,132 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTCLASSHELPERMACROS_H
+#define QTCLASSHELPERMACROS_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#if 0
+#pragma qt_class(QtClassHelperMacros)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if defined(__cplusplus)
+
+/*
+ Some classes do not permit copies to be made of an object. These
+ classes contains a private copy constructor and assignment
+ operator to disable copying (the compiler gives an error message).
+*/
+#define Q_DISABLE_COPY(Class) \
+ Class(const Class &) = delete;\
+ Class &operator=(const Class &) = delete;
+
+#define Q_DISABLE_COPY_MOVE(Class) \
+ Q_DISABLE_COPY(Class) \
+ Class(Class &&) = delete; \
+ Class &operator=(Class &&) = delete;
+
+/*
+ Implementing a move assignment operator using an established
+ technique (move-and-swap, pure swap) is just boilerplate.
+ Here's a couple of *private* macros for convenience.
+
+ To know which one to use:
+
+ * if you don't have a move constructor (*) => use pure swap;
+ * if you have a move constructor, then
+ * if your class holds just memory (no file handles, no user-defined
+ datatypes, etc.) => use pure swap;
+ * use move and swap.
+
+ The preference should always go for the move-and-swap one, as it
+ will deterministically destroy the data previously held in *this,
+ and not "dump" it in the moved-from object (which may then be alive
+ for longer).
+
+ The requirement for either macro is the presence of a member swap(),
+ which any value class that defines its own special member functions
+ should have anyhow.
+
+ (*) Many value classes in Qt do not have move constructors; mostly,
+ the implicitly shared classes using QSharedDataPointer and friends.
+ The reason is mostly historical: those classes require either an
+ out-of-line move constructor, which we could not provide before we
+ made C++11 mandatory (and that we don't like anyhow), or
+ an out-of-line dtor for the Q(E)DSP<Private> member (cf. QPixmap).
+
+ If you can however add a move constructor to a class lacking it,
+ consider doing so, then reevaluate which macro to choose.
+*/
+#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(Class) \
+ Class &operator=(Class &&other) noexcept { \
+ Class moved(std::move(other)); \
+ swap(moved); \
+ return *this; \
+ }
+
+#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Class) \
+ Class &operator=(Class &&other) noexcept { \
+ swap(other); \
+ return *this; \
+ }
+
+template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
+template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get())
+{ static_assert(noexcept(ptr.get()), "Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"); return ptr.get(); }
+
+class QObject;
+class QObjectPrivate;
+namespace QtPrivate {
+ template <typename ObjPrivate> void assertObjectType(QObjectPrivate *d);
+ inline const QObject *getQObject(const QObjectPrivate *d);
+}
+
+#define Q_DECLARE_PRIVATE(Class) \
+ inline Class##Private* d_func() noexcept \
+ { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr));) } \
+ inline const Class##Private* d_func() const noexcept \
+ { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));) } \
+ friend class Class##Private;
+
+#define Q_DECLARE_PRIVATE_D(Dptr, Class) \
+ inline Class##Private* d_func() noexcept \
+ { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr));) } \
+ inline const Class##Private* d_func() const noexcept \
+ { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr));) } \
+ friend class Class##Private;
+
+#define Q_DECLARE_PUBLIC(Class) \
+ inline Class* q_func() noexcept { return static_cast<Class *>(q_ptr); } \
+ inline const Class* q_func() const noexcept { return static_cast<const Class *>(q_ptr); } \
+ friend class Class; \
+ friend const QObject *QtPrivate::getQObject(const QObjectPrivate *d); \
+ template <typename ObjPrivate> friend void QtPrivate::assertObjectType(QObjectPrivate *d);
+
+#define Q_D(Class) Class##Private * const d = d_func()
+#define Q_Q(Class) Class * const q = q_func()
+
+/*
+ Specialize a shared type with:
+
+ Q_DECLARE_SHARED(type)
+
+ where 'type' is the name of the type to specialize. NOTE: shared
+ types must define a member-swap, and be defined in the same
+ namespace as Qt for this to work.
+*/
+
+#define Q_DECLARE_SHARED(TYPE) \
+Q_DECLARE_TYPEINFO(TYPE, Q_RELOCATABLE_TYPE); \
+inline void swap(TYPE &value1, TYPE &value2) \
+ noexcept(noexcept(value1.swap(value2))) \
+{ value1.swap(value2); }
+
+#endif // __cplusplus
+
+QT_END_NAMESPACE
+
+#endif // QTCLASSHELPERMACROS_H
diff --git a/src/corelib/global/qtclasshelpermacros.qdoc b/src/corelib/global/qtclasshelpermacros.qdoc
new file mode 100644
index 0000000000..8eaee7e5d2
--- /dev/null
+++ b/src/corelib/global/qtclasshelpermacros.qdoc
@@ -0,0 +1,59 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \macro Q_DISABLE_COPY(Class)
+ \relates <QtClassHelperMacros>
+
+ Disables the use of copy constructors and assignment operators
+ for the given \a Class.
+
+ Instances of subclasses of QObject should not be thought of as
+ values that can be copied or assigned, but as unique identities.
+ This means that when you create your own subclass of QObject
+ (director or indirect), you should \e not give it a copy constructor
+ or an assignment operator. However, it may not enough to simply
+ omit them from your class, because, if you mistakenly write some code
+ that requires a copy constructor or an assignment operator (it's easy
+ to do), your compiler will thoughtfully create it for you. You must
+ do more.
+
+ The curious user will have seen that the Qt classes derived
+ from QObject typically include this macro in a private section:
+
+ \snippet code/src_corelib_global_qglobal.cpp 43
+
+ It declares a copy constructor and an assignment operator in the
+ private section, so that if you use them by mistake, the compiler
+ will report an error.
+
+ \snippet code/src_corelib_global_qglobal.cpp 44
+
+ But even this might not catch absolutely every case. You might be
+ tempted to do something like this:
+
+ \snippet code/src_corelib_global_qglobal.cpp 45
+
+ First of all, don't do that. Most compilers will generate code that
+ uses the copy constructor, so the privacy violation error will be
+ reported, but your C++ compiler is not required to generate code for
+ this statement in a specific way. It could generate code using
+ \e{neither} the copy constructor \e{nor} the assignment operator we
+ made private. In that case, no error would be reported, but your
+ application would probably crash when you called a member function
+ of \c{w}.
+
+ \sa Q_DISABLE_COPY_MOVE
+*/
+
+/*!
+ \macro Q_DISABLE_COPY_MOVE(Class)
+ \relates <QtClassHelperMacros>
+
+ A convenience macro that disables the use of copy constructors, assignment
+ operators, move constructors and move assignment operators for the given
+ \a Class.
+
+ \sa Q_DISABLE_COPY
+ \since 5.13
+*/
diff --git a/src/corelib/global/qtconfiginclude.h b/src/corelib/global/qtconfiginclude.h
new file mode 100644
index 0000000000..8b22a47ac7
--- /dev/null
+++ b/src/corelib/global/qtconfiginclude.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2022 Intel Corporation
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTCONFIGINCLUDE_H
+#define QTCONFIGINCLUDE_H
+
+#if 0
+# pragma qt_sync_stop_processing
+#endif
+
+#include <QtCore/qconfig.h>
+
+#ifdef QT_BOOTSTRAPPED
+// qconfig-bootstrapped.h is not supposed to be a part of the synced header files. So we find it by
+// the include path specified for Bootstrap library in the source tree instead of the build tree as
+// it's done for regular header files.
+#include "qconfig-bootstrapped.h"
+#else
+#include <QtCore/qtcore-config.h>
+#endif
+
+#endif // QTCONFIGINCLUDE_H
diff --git a/src/corelib/global/qtconfigmacros.h b/src/corelib/global/qtconfigmacros.h
new file mode 100644
index 0000000000..6080562ab4
--- /dev/null
+++ b/src/corelib/global/qtconfigmacros.h
@@ -0,0 +1,189 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTCONFIGMACROS_H
+#define QTCONFIGMACROS_H
+
+#if 0
+# pragma qt_sync_stop_processing
+#endif
+
+#include <QtCore/qtconfiginclude.h>
+
+#include <assert.h>
+
+/*
+ The Qt modules' export macros.
+ The options are:
+ - defined(QT_STATIC): Qt was built or is being built in static mode
+ - defined(QT_SHARED): Qt was built or is being built in shared/dynamic mode
+ If neither was defined, then QT_SHARED is implied. If Qt was compiled in static
+ mode, QT_STATIC is defined in qconfig.h. In shared mode, QT_STATIC is implied
+ for the bootstrapped tools.
+*/
+
+#ifdef QT_BOOTSTRAPPED
+# ifdef QT_SHARED
+# error "QT_SHARED and QT_BOOTSTRAPPED together don't make sense. Please fix the build"
+# elif !defined(QT_STATIC)
+# define QT_STATIC
+# endif
+#endif
+
+#if defined(QT_SHARED) || !defined(QT_STATIC)
+# ifdef QT_STATIC
+# error "Both QT_SHARED and QT_STATIC defined, please make up your mind"
+# endif
+# ifndef QT_SHARED
+# define QT_SHARED
+# endif
+#endif
+
+/*
+ No, this is not an evil backdoor. QT_BUILD_INTERNAL just exports more symbols
+ for Qt's internal unit tests. If you want slower loading times and more
+ symbols that can vanish from version to version, feel free to define QT_BUILD_INTERNAL.
+
+ \note After adding Q_AUTOTEST_EXPORT to a method, you'll need to wrap any unittests
+ that will use that method in "#ifdef QT_BUILD_INTERNAL".
+*/
+#if defined(QT_BUILD_INTERNAL) && defined(QT_BUILDING_QT) && defined(QT_SHARED)
+# define Q_AUTOTEST_EXPORT Q_DECL_EXPORT
+#elif defined(QT_BUILD_INTERNAL) && defined(QT_SHARED)
+# define Q_AUTOTEST_EXPORT Q_DECL_IMPORT
+#else
+# define Q_AUTOTEST_EXPORT
+#endif
+
+/*
+ The QT_CONFIG macro implements a safe compile time check for features of Qt.
+ Features can be in three states:
+ 0 or undefined: This will lead to a compile error when testing for it
+ -1: The feature is not available
+ 1: The feature is available
+*/
+#define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1)
+#define QT_REQUIRE_CONFIG(feature) static_assert(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not available.")
+
+/* moc compats (signals/slots) */
+#ifndef QT_MOC_COMPAT
+# define QT_MOC_COMPAT
+#else
+# undef QT_MOC_COMPAT
+# define QT_MOC_COMPAT
+#endif
+
+/*
+ Debugging and error handling
+*/
+
+#if !defined(QT_NO_DEBUG) && !defined(QT_DEBUG)
+# define QT_DEBUG
+#endif
+
+// valid for both C and C++
+#define QT_MANGLE_NAMESPACE0(x) x
+#define QT_MANGLE_NAMESPACE1(a, b) a##_##b
+#define QT_MANGLE_NAMESPACE2(a, b) QT_MANGLE_NAMESPACE1(a,b)
+#if !defined(QT_NAMESPACE) || defined(Q_MOC_RUN) /* user namespace */
+# define QT_MANGLE_NAMESPACE(name) name
+#else
+# define QT_MANGLE_NAMESPACE(name) QT_MANGLE_NAMESPACE2( \
+ QT_MANGLE_NAMESPACE0(name), QT_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#endif
+
+#ifdef __cplusplus
+
+#if !defined(QT_NAMESPACE) || defined(Q_MOC_RUN) /* user namespace */
+
+# define QT_PREPEND_NAMESPACE(name) ::name
+# define QT_USE_NAMESPACE
+# define QT_BEGIN_NAMESPACE
+# define QT_END_NAMESPACE
+# define QT_BEGIN_INCLUDE_NAMESPACE
+# define QT_END_INCLUDE_NAMESPACE
+# define QT_FORWARD_DECLARE_CLASS(name) class name;
+# define QT_FORWARD_DECLARE_STRUCT(name) struct name;
+
+#else /* user namespace */
+
+# define QT_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
+# define QT_USE_NAMESPACE using namespace ::QT_NAMESPACE;
+# define QT_BEGIN_NAMESPACE namespace QT_NAMESPACE {
+# define QT_END_NAMESPACE }
+# define QT_BEGIN_INCLUDE_NAMESPACE }
+# define QT_END_INCLUDE_NAMESPACE namespace QT_NAMESPACE {
+# define QT_FORWARD_DECLARE_CLASS(name) \
+ QT_BEGIN_NAMESPACE class name; QT_END_NAMESPACE \
+ using QT_PREPEND_NAMESPACE(name);
+
+# define QT_FORWARD_DECLARE_STRUCT(name) \
+ QT_BEGIN_NAMESPACE struct name; QT_END_NAMESPACE \
+ using QT_PREPEND_NAMESPACE(name);
+
+namespace QT_NAMESPACE {}
+
+# ifndef QT_BOOTSTRAPPED
+# ifndef QT_NO_USING_NAMESPACE
+ /*
+ This expands to a "using QT_NAMESPACE" also in _header files_.
+ It is the only way the feature can be used without too much
+ pain, but if people _really_ do not want it they can add
+ QT_NO_USING_NAMESPACE to their build configuration.
+ */
+ QT_USE_NAMESPACE
+# endif
+# endif
+
+#endif /* user namespace */
+
+#else /* __cplusplus */
+
+# define QT_BEGIN_NAMESPACE
+# define QT_END_NAMESPACE
+# define QT_USE_NAMESPACE
+# define QT_BEGIN_INCLUDE_NAMESPACE
+# define QT_END_INCLUDE_NAMESPACE
+
+#endif /* __cplusplus */
+
+/* ### Qt 6.9 (or later): remove *_MOC_* macros (moc does not need them since 6.5) */
+#ifndef QT_BEGIN_MOC_NAMESPACE
+# define QT_BEGIN_MOC_NAMESPACE QT_USE_NAMESPACE
+#endif
+#ifndef QT_END_MOC_NAMESPACE
+# define QT_END_MOC_NAMESPACE
+#endif
+
+/*
+ Strict mode
+*/
+#ifdef QT_ENABLE_STRICT_MODE_UP_TO
+#ifndef QT_DISABLE_DEPRECATED_UP_TO
+# define QT_DISABLE_DEPRECATED_UP_TO QT_ENABLE_STRICT_MODE_UP_TO
+#endif
+
+#if QT_ENABLE_STRICT_MODE_UP_TO >= QT_VERSION_CHECK(6, 0, 0)
+# define QT_NO_FOREACH
+# define QT_NO_CAST_FROM_ASCII
+# define QT_NO_CAST_TO_ASCII
+# define QT_NO_CAST_FROM_BYTEARRAY
+# define QT_NO_URL_CAST_FROM_STRING
+# define QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
+# define QT_NO_JAVA_STYLE_ITERATORS
+#endif // 6.0.0
+
+#if QT_ENABLE_STRICT_MODE_UP_TO >= QT_VERSION_CHECK(6, 6, 0)
+# define QT_NO_QEXCHANGE
+#endif // 6.6.0
+
+#if QT_ENABLE_STRICT_MODE_UP_TO >= QT_VERSION_CHECK(6, 7, 0)
+# define QT_NO_CONTEXTLESS_CONNECT
+#endif // 6.7.0
+
+#if QT_ENABLE_STRICT_MODE_UP_TO >= QT_VERSION_CHECK(6, 8, 0)
+# define QT_NO_QASCONST
+#endif // 6.8.0
+#endif // QT_ENABLE_STRICT_MODE_UP_TO
+
+#endif /* QTCONFIGMACROS_H */
diff --git a/src/corelib/global/qtdeprecationmarkers.h b/src/corelib/global/qtdeprecationmarkers.h
new file mode 100644
index 0000000000..6df5ebce6d
--- /dev/null
+++ b/src/corelib/global/qtdeprecationmarkers.h
@@ -0,0 +1,347 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTDEPRECATIONMARKERS_H
+#define QTDEPRECATIONMARKERS_H
+
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtversionchecks.h>
+#include <QtCore/qcompilerdetection.h> // for Q_DECL_DEPRECATED
+
+#if 0
+#pragma qt_class(QtDeprecationMarkers)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_NO_DEPRECATED)
+# undef QT_DEPRECATED
+# undef QT_DEPRECATED_X
+# undef QT_DEPRECATED_VARIABLE
+# undef QT_DEPRECATED_CONSTRUCTOR
+#elif !defined(QT_NO_DEPRECATED_WARNINGS)
+# undef QT_DEPRECATED
+# define QT_DEPRECATED Q_DECL_DEPRECATED
+# undef QT_DEPRECATED_X
+# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text)
+# undef QT_DEPRECATED_VARIABLE
+# define QT_DEPRECATED_VARIABLE Q_DECL_VARIABLE_DEPRECATED
+# undef QT_DEPRECATED_CONSTRUCTOR
+# define QT_DEPRECATED_CONSTRUCTOR Q_DECL_CONSTRUCTOR_DEPRECATED explicit
+#else
+# undef QT_DEPRECATED
+# define QT_DEPRECATED
+# undef QT_DEPRECATED_X
+# define QT_DEPRECATED_X(text)
+# undef QT_DEPRECATED_VARIABLE
+# define QT_DEPRECATED_VARIABLE
+# undef QT_DEPRECATED_CONSTRUCTOR
+# define QT_DEPRECATED_CONSTRUCTOR
+# undef Q_DECL_ENUMERATOR_DEPRECATED
+# define Q_DECL_ENUMERATOR_DEPRECATED
+# undef Q_DECL_ENUMERATOR_DEPRECATED_X
+# define Q_DECL_ENUMERATOR_DEPRECATED_X(ignored)
+#endif
+
+// If the deprecated macro is defined, use its value
+#if !defined(QT_DISABLE_DEPRECATED_UP_TO) && defined(QT_DISABLE_DEPRECATED_BEFORE)
+# define QT_DISABLE_DEPRECATED_UP_TO QT_DISABLE_DEPRECATED_BEFORE
+#endif
+
+// If the deprecated macro is defined, use its value
+#if !defined(QT_WARN_DEPRECATED_UP_TO) && defined(QT_DEPRECATED_WARNINGS_SINCE)
+# define QT_WARN_DEPRECATED_UP_TO QT_DEPRECATED_WARNINGS_SINCE
+#endif
+
+#ifndef QT_WARN_DEPRECATED_UP_TO
+# ifdef QT_DISABLE_DEPRECATED_UP_TO
+# define QT_WARN_DEPRECATED_UP_TO QT_DISABLE_DEPRECATED_UP_TO
+# else
+# define QT_WARN_DEPRECATED_UP_TO QT_VERSION
+# endif
+#endif
+
+#ifndef QT_DISABLE_DEPRECATED_UP_TO
+#define QT_DISABLE_DEPRECATED_UP_TO QT_VERSION_CHECK(5, 0, 0)
+#endif
+
+/*
+ QT_DEPRECATED_SINCE(major, minor) evaluates as true if the Qt version is greater than
+ the deprecation point specified.
+
+ Use it to specify from which version of Qt a function or class has been deprecated
+
+ Example:
+ #if QT_DEPRECATED_SINCE(5,1)
+ QT_DEPRECATED void deprecatedFunction(); //function deprecated since Qt 5.1
+ #endif
+
+*/
+#ifdef QT_DEPRECATED
+#define QT_DEPRECATED_SINCE(major, minor) (QT_VERSION_CHECK(major, minor, 0) > QT_DISABLE_DEPRECATED_UP_TO)
+#else
+#define QT_DEPRECATED_SINCE(major, minor) 0
+#endif
+
+/*
+ QT_DEPRECATED_VERSION(major, minor) and QT_DEPRECATED_VERSION_X(major, minor, text)
+ outputs a deprecation warning if QT_WARN_DEPRECATED_UP_TO is equal to or greater
+ than the version specified as major, minor. This makes it possible to deprecate a
+ function without annoying a user who needs to stay compatible with a specified minimum
+ version and therefore can't use the new function.
+*/
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(5, 12, 0)
+# define QT_DEPRECATED_VERSION_X_5_12(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_5_12 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_5_12(text)
+# define QT_DEPRECATED_VERSION_5_12
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(5, 13, 0)
+# define QT_DEPRECATED_VERSION_X_5_13(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_5_13 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_5_13(text)
+# define QT_DEPRECATED_VERSION_5_13
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(5, 14, 0)
+# define QT_DEPRECATED_VERSION_X_5_14(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_5_14 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_5_14(text)
+# define QT_DEPRECATED_VERSION_5_14
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(5, 15, 0)
+# define QT_DEPRECATED_VERSION_X_5_15(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_5_15 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_5_15(text)
+# define QT_DEPRECATED_VERSION_5_15
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 0, 0)
+# define QT_DEPRECATED_VERSION_X_6_0(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_0 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_0(text)
+# define QT_DEPRECATED_VERSION_6_0
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 1, 0)
+# define QT_DEPRECATED_VERSION_X_6_1(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_1 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_1(text)
+# define QT_DEPRECATED_VERSION_6_1
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 2, 0)
+# define QT_DEPRECATED_VERSION_X_6_2(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_2 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_2(text)
+# define QT_DEPRECATED_VERSION_6_2
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 3, 0)
+# define QT_DEPRECATED_VERSION_X_6_3(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_3 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_3(text)
+# define QT_DEPRECATED_VERSION_6_3
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 4, 0)
+# define QT_DEPRECATED_VERSION_X_6_4(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_4 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_4(text)
+# define QT_DEPRECATED_VERSION_6_4
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 5, 0)
+# define QT_DEPRECATED_VERSION_X_6_5(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_5 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_5(text)
+# define QT_DEPRECATED_VERSION_6_5
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 6, 0)
+# define QT_DEPRECATED_VERSION_X_6_6(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_6 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_6(text)
+# define QT_DEPRECATED_VERSION_6_6
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 7, 0)
+# define QT_DEPRECATED_VERSION_X_6_7(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_7 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_7(text)
+# define QT_DEPRECATED_VERSION_6_7
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 8, 0)
+# define QT_DEPRECATED_VERSION_X_6_8(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_8 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_8(text)
+# define QT_DEPRECATED_VERSION_6_8
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 9, 0)
+# define QT_DEPRECATED_VERSION_X_6_9(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_9 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_9(text)
+# define QT_DEPRECATED_VERSION_6_9
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 10, 0)
+# define QT_DEPRECATED_VERSION_X_6_10(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_10 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_10(text)
+# define QT_DEPRECATED_VERSION_6_10
+#endif
+
+#if QT_WARN_DEPRECATED_UP_TO >= QT_VERSION_CHECK(6, 11, 0)
+# define QT_DEPRECATED_VERSION_X_6_11(text) QT_DEPRECATED_X(text)
+# define QT_DEPRECATED_VERSION_6_11 QT_DEPRECATED
+#else
+# define QT_DEPRECATED_VERSION_X_6_11(text)
+# define QT_DEPRECATED_VERSION_6_11
+#endif
+
+#define QT_DEPRECATED_VERSION_X_5(minor, text) QT_DEPRECATED_VERSION_X_5_##minor(text)
+#define QT_DEPRECATED_VERSION_X(major, minor, text) QT_DEPRECATED_VERSION_X_##major##_##minor(text)
+
+#define QT_DEPRECATED_VERSION_5(minor) QT_DEPRECATED_VERSION_5_##minor
+#define QT_DEPRECATED_VERSION(major, minor) QT_DEPRECATED_VERSION_##major##_##minor
+
+/*
+ QT_IF_DEPRECATED_SINCE(major, minor, whenTrue, whenFalse) expands to
+ \a whenTrue if the specified (\a major, \a minor) version is less than or
+ equal to the deprecation version defined by QT_DISABLE_DEPRECATED_UP_TO,
+ and to \a whenFalse otherwise.
+
+ Currently used for QT_INLINE_SINCE(maj, min), but can also be helpful for
+ other macros of that kind.
+
+ The implementation uses QT_DEPRECATED_SINCE(maj, min) to define a bunch of
+ helper QT_IF_DEPRECATED_SINCE_X_Y macros, which expand to \a whenTrue or
+ \a whenFalse depending on the value of QT_DEPRECATED_SINCE.
+
+ If you need to use QT_IF_DEPRECATED_SINCE() for a (major, minor) version,
+ that is not yet covered by the list below, you need to copy the definition
+ and change the major and minor versions accordingly. For example, for
+ version (X, Y), you will need to add
+
+ \code
+ #if QT_DEPRECATED_SINCE(X, Y)
+ # define QT_IF_DEPRECATED_SINCE_X_Y(whenTrue, whenFalse) whenFalse
+ #else
+ # define QT_IF_DEPRECATED_SINCE_X_Y(whenTrue, whenFalse) whenTrue
+ #endif
+ \endcode
+*/
+
+#define QT_IF_DEPRECATED_SINCE(major, minor, whenTrue, whenFalse) \
+ QT_IF_DEPRECATED_SINCE_ ## major ## _ ## minor(whenTrue, whenFalse)
+
+#if QT_DEPRECATED_SINCE(6, 0)
+# define QT_IF_DEPRECATED_SINCE_6_0(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_0(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 1)
+# define QT_IF_DEPRECATED_SINCE_6_1(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_1(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 2)
+# define QT_IF_DEPRECATED_SINCE_6_2(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_2(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 3)
+# define QT_IF_DEPRECATED_SINCE_6_3(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_3(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 4)
+# define QT_IF_DEPRECATED_SINCE_6_4(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_4(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 5)
+# define QT_IF_DEPRECATED_SINCE_6_5(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_5(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 6)
+# define QT_IF_DEPRECATED_SINCE_6_6(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_6(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 7)
+# define QT_IF_DEPRECATED_SINCE_6_7(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_7(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 8)
+# define QT_IF_DEPRECATED_SINCE_6_8(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_8(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 9)
+# define QT_IF_DEPRECATED_SINCE_6_9(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_9(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 10)
+# define QT_IF_DEPRECATED_SINCE_6_10(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_10(whenTrue, whenFalse) whenTrue
+#endif
+
+#if QT_DEPRECATED_SINCE(6, 11)
+# define QT_IF_DEPRECATED_SINCE_6_11(whenTrue, whenFalse) whenFalse
+#else
+# define QT_IF_DEPRECATED_SINCE_6_11(whenTrue, whenFalse) whenTrue
+#endif
+
+#ifdef __cplusplus
+// A tag to help mark stuff deprecated (cf. QStringViewLiteral)
+namespace QtPrivate {
+enum class Deprecated_t {};
+constexpr inline Deprecated_t Deprecated = {};
+}
+#endif
+
+#ifdef QT_ASCII_CAST_WARNINGS
+# define QT_ASCII_CAST_WARN \
+ Q_DECL_DEPRECATED_X("Use fromUtf8, QStringLiteral, or QLatin1StringView")
+#else
+# define QT_ASCII_CAST_WARN
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QTDEPRECATIONMARKERS_H
diff --git a/src/corelib/global/qtdeprecationmarkers.qdoc b/src/corelib/global/qtdeprecationmarkers.qdoc
new file mode 100644
index 0000000000..2dd572533e
--- /dev/null
+++ b/src/corelib/global/qtdeprecationmarkers.qdoc
@@ -0,0 +1,64 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \headerfile <QtDeprecationMarkers>
+ \inmodule QtCore
+ \title Qt Deprecation Macros
+
+ \brief The <QtDeprecationMarkers> header file contains deprecation helper macros.
+
+ The header file declares several macros for disabling deprecated Qt APIs
+ and enabling/disabling compiler warnings when they are used.
+*/
+
+/*!
+ \macro QT_DISABLE_DEPRECATED_BEFORE
+ \relates <QtDeprecationMarkers>
+ \deprecated [6.5] Use QT_DISABLE_DEPRECATED_UP_TO instead
+
+ \sa QT_DISABLE_DEPRECATED_UP_TO
+*/
+
+/*!
+ \macro QT_DISABLE_DEPRECATED_UP_TO
+ \relates <QtDeprecationMarkers>
+
+ This macro can be defined in the project file to disable functions
+ deprecated in a specified version of Qt or any earlier version. The default
+ version number is 5.0, meaning that functions deprecated in or before
+ Qt 5.0 will not be included.
+
+ For instance, when preparing to upgrade to Qt 6.3, after eliminating all
+ deprecation warnings, you can set \c{QT_DISABLE_DEPRECATED_UP_TO=0x060300}
+ to exclude from your builds the Qt APIs you no longer use. In your own
+ project's build configuration, this will ensure that anyone adding new calls
+ to the deprecated APIs will know about it right away. If you also build Qt
+ for yourself, including this define in your build configuration for Qt will
+ make your binaries smaller by leaving out even the implementation of the
+ deprecated APIs.
+
+ \sa QT_DEPRECATED_WARNINGS, QT_DISABLE_DEPRECATED_UP_TO
+*/
+
+/*!
+ \macro QT_DEPRECATED_WARNINGS
+ \relates <QtDeprecationMarkers>
+
+ Since Qt 5.13, this macro has no effect. In Qt 5.12 and before, if this macro
+ is defined, the compiler will generate warnings if any API declared as
+ deprecated by Qt is used.
+
+ \sa QT_DISABLE_DEPRECATED_UP_TO, QT_NO_DEPRECATED_WARNINGS
+*/
+
+/*!
+ \macro QT_NO_DEPRECATED_WARNINGS
+ \relates <QtDeprecationMarkers>
+ \since 5.13
+
+ This macro can be used to suppress deprecation warnings that would otherwise
+ be generated when using deprecated APIs.
+
+ \sa QT_DISABLE_DEPRECATED_UP_TO
+*/
diff --git a/src/corelib/global/qtenvironmentvariables.cpp b/src/corelib/global/qtenvironmentvariables.cpp
new file mode 100644
index 0000000000..cf5955902a
--- /dev/null
+++ b/src/corelib/global/qtenvironmentvariables.cpp
@@ -0,0 +1,429 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qtenvironmentvariables.h"
+#include "qtenvironmentvariables_p.h"
+
+#include <qplatformdefs.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qvarlengtharray.h>
+
+#include <QtCore/private/qlocking_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// In the C runtime on all platforms access to the environment is not thread-safe. We
+// add thread-safety for the Qt wrappers.
+Q_CONSTINIT static QBasicMutex environmentMutex;
+
+/*!
+ \relates <QtEnvironmentVariables>
+ \threadsafe
+
+ Returns the value of the environment variable with name \a varName as a
+ QByteArray. If no variable by that name is found in the environment, this
+ function returns a default-constructed QByteArray.
+
+ The Qt environment manipulation functions are thread-safe, but this
+ requires that the C library equivalent functions like getenv and putenv are
+ not directly called.
+
+ To convert the data to a QString use QString::fromLocal8Bit().
+
+ \note on desktop Windows, qgetenv() may produce data loss if the
+ original string contains Unicode characters not representable in the
+ ANSI encoding. Use qEnvironmentVariable() instead.
+ On Unix systems, this function is lossless.
+
+ \sa qputenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet(),
+ qEnvironmentVariableIsEmpty()
+*/
+QByteArray qgetenv(const char *varName)
+{
+ const auto locker = qt_scoped_lock(environmentMutex);
+#ifdef Q_CC_MSVC
+ size_t requiredSize = 0;
+ QByteArray buffer;
+ getenv_s(&requiredSize, 0, 0, varName);
+ if (requiredSize == 0)
+ return buffer;
+ buffer.resize(qsizetype(requiredSize));
+ getenv_s(&requiredSize, buffer.data(), requiredSize, varName);
+ // requiredSize includes the terminating null, which we don't want.
+ Q_ASSERT(buffer.endsWith('\0'));
+ buffer.chop(1);
+ return buffer;
+#else
+ return QByteArray(::getenv(varName));
+#endif
+}
+
+/*!
+ \fn QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
+ \fn QString qEnvironmentVariable(const char *varName)
+
+ \relates <QtEnvironmentVariables>
+ \since 5.10
+
+ These functions return the value of the environment variable, \a varName, as a
+ QString. If no variable \a varName is found in the environment and \a defaultValue
+ is provided, \a defaultValue is returned. Otherwise QString() is returned.
+
+ The Qt environment manipulation functions are thread-safe, but this
+ requires that the C library equivalent functions like getenv and putenv are
+ not directly called.
+
+ The following table describes how to choose between qgetenv() and
+ qEnvironmentVariable():
+ \table
+ \header \li Condition \li Recommendation
+ \row
+ \li Variable contains file paths or user text
+ \li qEnvironmentVariable()
+ \row
+ \li Windows-specific code
+ \li qEnvironmentVariable()
+ \row
+ \li Unix-specific code, destination variable is not QString and/or is
+ used to interface with non-Qt APIs
+ \li qgetenv()
+ \row
+ \li Destination variable is a QString
+ \li qEnvironmentVariable()
+ \row
+ \li Destination variable is a QByteArray or std::string
+ \li qgetenv()
+ \endtable
+
+ \note on Unix systems, this function may produce data loss if the original
+ string contains arbitrary binary data that cannot be decoded by the locale
+ codec. Use qgetenv() instead for that case. On Windows, this function is
+ lossless.
+
+ \note the variable name \a varName must contain only US-ASCII characters.
+
+ \sa qputenv(), qgetenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty()
+*/
+QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
+{
+#if defined(Q_OS_WIN)
+ QVarLengthArray<wchar_t, 32> wname(qsizetype(strlen(varName)) + 1);
+ for (qsizetype i = 0; i < wname.size(); ++i) // wname.size() is correct: will copy terminating null
+ wname[i] = uchar(varName[i]);
+ size_t requiredSize = 0;
+ auto locker = qt_unique_lock(environmentMutex);
+ _wgetenv_s(&requiredSize, 0, 0, wname.data());
+ if (requiredSize == 0)
+ return defaultValue;
+ QString buffer(qsizetype(requiredSize), Qt::Uninitialized);
+ _wgetenv_s(&requiredSize, reinterpret_cast<wchar_t *>(buffer.data()), requiredSize,
+ wname.data());
+ locker.unlock();
+ // requiredSize includes the terminating null, which we don't want.
+ Q_ASSERT(buffer.endsWith(QChar(u'\0')));
+ buffer.chop(1);
+ return buffer;
+#else
+ QByteArray value = qgetenv(varName);
+ if (value.isNull())
+ return defaultValue;
+// duplicated in qfile.h (QFile::decodeName)
+#if defined(Q_OS_DARWIN)
+ return QString::fromUtf8(value).normalized(QString::NormalizationForm_C);
+#else // other Unix
+ return QString::fromLocal8Bit(value);
+#endif
+#endif
+}
+
+QString qEnvironmentVariable(const char *varName)
+{
+ return qEnvironmentVariable(varName, QString());
+}
+
+/*!
+ \relates <QtEnvironmentVariables>
+ \since 5.1
+
+ Returns whether the environment variable \a varName is empty.
+
+ Equivalent to
+ \snippet code/src_corelib_global_qglobal.cpp is-empty
+ except that it's potentially much faster, and can't throw exceptions.
+
+ \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
+*/
+bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
+{
+ const auto locker = qt_scoped_lock(environmentMutex);
+#ifdef Q_CC_MSVC
+ // we provide a buffer that can only hold the empty string, so
+ // when the env.var isn't empty, we'll get an ERANGE error (buffer
+ // too small):
+ size_t dummy;
+ char buffer = '\0';
+ return getenv_s(&dummy, &buffer, 1, varName) != ERANGE;
+#else
+ const char * const value = ::getenv(varName);
+ return !value || !*value;
+#endif
+}
+
+/*!
+ \relates <QtEnvironmentVariables>
+ \since 5.5
+
+ Returns the numerical value of the environment variable \a varName.
+ If \a ok is not null, sets \c{*ok} to \c true or \c false depending
+ on the success of the conversion.
+
+ Equivalent to
+ \snippet code/src_corelib_global_qglobal.cpp to-int
+ except that it's much faster, and can't throw exceptions.
+
+ \note there's a limit on the length of the value, which is sufficient for
+ all valid values of int, not counting leading zeroes or spaces. Values that
+ are too long will either be truncated or this function will set \a ok to \c
+ false.
+
+ \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet()
+*/
+int qEnvironmentVariableIntValue(const char *varName, bool *ok) noexcept
+{
+ static const int NumBinaryDigitsPerOctalDigit = 3;
+ static const int MaxDigitsForOctalInt =
+ (std::numeric_limits<uint>::digits + NumBinaryDigitsPerOctalDigit - 1) / NumBinaryDigitsPerOctalDigit;
+
+ const auto locker = qt_scoped_lock(environmentMutex);
+ size_t size;
+#ifdef Q_CC_MSVC
+ // we provide a buffer that can hold any int value:
+ char buffer[MaxDigitsForOctalInt + 2]; // +1 for NUL +1 for optional '-'
+ size_t dummy;
+ if (getenv_s(&dummy, buffer, sizeof buffer, varName) != 0) {
+ if (ok)
+ *ok = false;
+ return 0;
+ }
+ size = strlen(buffer);
+#else
+ const char * const buffer = ::getenv(varName);
+ if (!buffer || (size = strlen(buffer)) > MaxDigitsForOctalInt + 2) {
+ if (ok)
+ *ok = false;
+ return 0;
+ }
+#endif
+ return QByteArrayView(buffer, size).toInt(ok, 0);
+}
+
+/*!
+ \relates <QtEnvironmentVariables>
+ \since 5.1
+
+ Returns whether the environment variable \a varName is set.
+
+ Equivalent to
+ \snippet code/src_corelib_global_qglobal.cpp is-null
+ except that it's potentially much faster, and can't throw exceptions.
+
+ \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsEmpty()
+*/
+bool qEnvironmentVariableIsSet(const char *varName) noexcept
+{
+ const auto locker = qt_scoped_lock(environmentMutex);
+#ifdef Q_CC_MSVC
+ size_t requiredSize = 0;
+ (void)getenv_s(&requiredSize, 0, 0, varName);
+ return requiredSize != 0;
+#else
+ return ::getenv(varName) != nullptr;
+#endif
+}
+
+/*!
+ \fn bool qputenv(const char *varName, QByteArrayView value)
+ \relates <QtEnvironmentVariables>
+
+ This function sets the \a value of the environment variable named
+ \a varName. It will create the variable if it does not exist. It
+ returns 0 if the variable could not be set.
+
+ Calling qputenv with an empty value removes the environment variable on
+ Windows, and makes it set (but empty) on Unix. Prefer using qunsetenv()
+ for fully portable behavior.
+
+ \note qputenv() was introduced because putenv() from the standard
+ C library was deprecated in VC2005 (and later versions). qputenv()
+ uses the replacement function in VC, and calls the standard C
+ library's implementation on all other platforms.
+
+ \note In Qt versions prior to 6.5, the \a value argument was QByteArray,
+ not QByteArrayView.
+
+ \sa qgetenv(), qEnvironmentVariable()
+*/
+bool qputenv(const char *varName, QByteArrayView raw)
+{
+ auto protect = [](const char *str) { return str ? str : ""; };
+
+ std::string value{protect(raw.data()), size_t(raw.size())}; // NUL-terminates w/SSO
+
+#if defined(Q_CC_MSVC)
+ const auto locker = qt_scoped_lock(environmentMutex);
+ return _putenv_s(varName, value.data()) == 0;
+#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_HAIKU)
+ // POSIX.1-2001 has setenv
+ const auto locker = qt_scoped_lock(environmentMutex);
+ return setenv(varName, value.data(), true) == 0;
+#else
+ std::string buffer;
+ buffer += protect(varName);
+ buffer += '=';
+ buffer += value;
+ char *envVar = qstrdup(buffer.data());
+ int result = [&] {
+ const auto locker = qt_scoped_lock(environmentMutex);
+ return putenv(envVar);
+ }();
+ if (result != 0) // error. we have to delete the string.
+ delete[] envVar;
+ return result == 0;
+#endif
+}
+
+/*!
+ \relates <QtEnvironmentVariables>
+
+ This function deletes the variable \a varName from the environment.
+
+ Returns \c true on success.
+
+ \since 5.1
+
+ \sa qputenv(), qgetenv(), qEnvironmentVariable()
+*/
+bool qunsetenv(const char *varName)
+{
+#if defined(Q_CC_MSVC)
+ const auto locker = qt_scoped_lock(environmentMutex);
+ return _putenv_s(varName, "") == 0;
+#elif (defined(_POSIX_VERSION) && (_POSIX_VERSION-0) >= 200112L) || defined(Q_OS_BSD4) || defined(Q_OS_HAIKU)
+ // POSIX.1-2001, BSD and Haiku have unsetenv
+ const auto locker = qt_scoped_lock(environmentMutex);
+ return unsetenv(varName) == 0;
+#elif defined(Q_CC_MINGW)
+ // On mingw, putenv("var=") removes "var" from the environment
+ QByteArray buffer(varName);
+ buffer += '=';
+ const auto locker = qt_scoped_lock(environmentMutex);
+ return putenv(buffer.constData()) == 0;
+#else
+ // Fallback to putenv("var=") which will insert an empty var into the
+ // environment and leak it
+ QByteArray buffer(varName);
+ buffer += '=';
+ char *envVar = qstrdup(buffer.constData());
+ const auto locker = qt_scoped_lock(environmentMutex);
+ return putenv(envVar) == 0;
+#endif
+}
+
+/* Various time-related APIs that need to consult system settings also need
+ protection with the same lock as the environment, since those system settings
+ include part of the environment (principally TZ).
+
+ First, tzset(), which POSIX explicitly says accesses the environment.
+*/
+void qTzSet()
+{
+ const auto locker = qt_scoped_lock(environmentMutex);
+#if defined(Q_OS_WIN)
+ _tzset();
+#else
+ tzset();
+#endif // Q_OS_WIN
+}
+
+/* Wrap mktime(), which is specified to behave as if it called tzset(), hence
+ shares its implicit environment-dependence.
+*/
+time_t qMkTime(struct tm *when)
+{
+ const auto locker = qt_scoped_lock(environmentMutex);
+#if defined(Q_OS_WIN)
+ // QTBUG-83881 MS's mktime() seems to need _tzset() called first.
+ _tzset();
+#endif
+ return mktime(when);
+}
+
+/* For localtime(), POSIX mandates that it behave as if it called tzset().
+ For the alternatives to it, we need (if only for compatibility) to do the
+ same explicitly, which should ensure a re-parse of timezone info.
+*/
+bool qLocalTime(time_t utc, struct tm *local)
+{
+ const auto locker = qt_scoped_lock(environmentMutex);
+#if defined(Q_OS_WIN)
+ // The doc of localtime_s() says that it corrects for the same things
+ // _tzset() sets the globals for, but QTBUG-109974 reveals a need for an
+ // explicit call, all the same.
+ _tzset();
+ return !localtime_s(local, &utc);
+#elif QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // Use the reentrant version of localtime() where available, as it is
+ // thread-safe and doesn't use a shared static data area.
+ // As localtime_r() is not specified to work as if it called tzset(),
+ // make an explicit call.
+ tzset();
+ if (tm *res = localtime_r(&utc, local)) {
+ Q_ASSERT(res == local);
+ Q_UNUSED(res);
+ return true;
+ }
+ return false;
+#else
+ // POSIX mandates that localtime() behaves as if it called tzset().
+ // Returns shared static data which may be overwritten at any time (albeit
+ // our lock probably keeps it safe). So copy the result promptly:
+ if (tm *res = localtime(&utc)) {
+ *local = *res;
+ return true;
+ }
+ return false;
+#endif
+}
+
+/* Access to the tzname[] global in one thread is UB if any other is calling
+ tzset() or anything that behaves as if it called tzset(). So also lock this
+ access to prevent such collisions.
+
+ Parameter dstIndex must be 1 for DST or 0 for standard time.
+ Returns the relevant form of the name of local-time's zone.
+*/
+QString qTzName(int dstIndex)
+{
+ char name[512];
+ bool ok;
+#if defined(_UCRT) // i.e., MSVC and MinGW-UCRT
+ size_t s = 0;
+ {
+ const auto locker = qt_scoped_lock(environmentMutex);
+ ok = _get_tzname(&s, name, 512, dstIndex) != 0;
+ }
+#else
+ {
+ const auto locker = qt_scoped_lock(environmentMutex);
+ const char *const src = tzname[dstIndex];
+ ok = src != nullptr;
+ if (ok)
+ memcpy(name, src, std::min(sizeof(name), strlen(src) + 1));
+ }
+#endif // Q_OS_WIN
+ return ok ? QString::fromLocal8Bit(name) : QString();
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qtenvironmentvariables.h b/src/corelib/global/qtenvironmentvariables.h
new file mode 100644
index 0000000000..e7be182677
--- /dev/null
+++ b/src/corelib/global/qtenvironmentvariables.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTENVIRONMENTVARIABLES_H
+#define QTENVIRONMENTVARIABLES_H
+
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtcoreexports.h>
+#include <QtCore/qtdeprecationmarkers.h>
+
+#if 0
+#pragma qt_class(QtEnvironmentVariables)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QByteArray;
+class QByteArrayView;
+class QString;
+
+Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
+// need it as two functions because QString is only forward-declared here
+Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName);
+Q_CORE_EXPORT QString qEnvironmentVariable(const char *varName, const QString &defaultValue);
+#if QT_CORE_REMOVED_SINCE(6, 5)
+Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray &value);
+#endif
+Q_CORE_EXPORT bool qputenv(const char *varName, QByteArrayView value);
+Q_CORE_EXPORT bool qunsetenv(const char *varName);
+
+Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept;
+Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept;
+Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept;
+
+QT_END_NAMESPACE
+
+#endif /* QTENVIRONMENTVARIABLES_H */
diff --git a/src/corelib/global/qtenvironmentvariables_p.h b/src/corelib/global/qtenvironmentvariables_p.h
new file mode 100644
index 0000000000..0c81d36db6
--- /dev/null
+++ b/src/corelib/global/qtenvironmentvariables_p.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// Copyright (C) 2015 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTENVIRONMENTVARIABLES_P_H
+#define QTENVIRONMENTVARIABLES_P_H
+// Nothing but (tests and) ../time/qlocaltime.cpp should access this.
+#if defined(__cplusplus)
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an implementation
+// detail. This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+
+#include "qglobal_p.h"
+
+#ifdef Q_CC_MINGW
+# include <unistd.h> // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r()
+#endif
+#include <time.h>
+
+QT_BEGIN_NAMESPACE
+
+// These (behave as if they) consult the environment, so need to share its locking:
+Q_CORE_EXPORT void qTzSet();
+Q_CORE_EXPORT time_t qMkTime(struct tm *when);
+Q_CORE_EXPORT bool qLocalTime(time_t utc, struct tm *local);
+Q_CORE_EXPORT QString qTzName(int dstIndex);
+
+QT_END_NAMESPACE
+
+#endif // defined(__cplusplus)
+#endif // QTENVIRONMENTVARIABLES_P_H
diff --git a/src/corelib/global/qtnoop.h b/src/corelib/global/qtnoop.h
new file mode 100644
index 0000000000..c84e6c8a99
--- /dev/null
+++ b/src/corelib/global/qtnoop.h
@@ -0,0 +1,20 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTNOOP_H
+#define QTNOOP_H
+
+#if 0
+#pragma qt_sync_stop_processing
+#endif
+
+#ifdef __cplusplus
+constexpr
+#endif
+inline void qt_noop(void)
+#ifdef __cplusplus
+ noexcept
+#endif
+{}
+
+#endif // QTNOOP_H
diff --git a/src/corelib/global/qtpreprocessorsupport.h b/src/corelib/global/qtpreprocessorsupport.h
new file mode 100644
index 0000000000..73bbeb68b6
--- /dev/null
+++ b/src/corelib/global/qtpreprocessorsupport.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTPREPROCESSORSUPPORT_H
+#define QTPREPROCESSORSUPPORT_H
+
+#if 0
+#pragma qt_class(QtPreprocessorSupport)
+#pragma qt_sync_stop_processing
+#endif
+
+/* These two macros makes it possible to turn the builtin line expander into a
+ * string literal. */
+#define QT_STRINGIFY2(x) #x
+#define QT_STRINGIFY(x) QT_STRINGIFY2(x)
+
+/*
+ Avoid "unused parameter" warnings
+*/
+#define Q_UNUSED(x) (void)x;
+
+#if !defined(Q_UNIMPLEMENTED)
+# define Q_UNIMPLEMENTED() qWarning("Unimplemented code.")
+#endif
+
+#endif // QTPREPROCESSORSUPPORT_H
diff --git a/src/corelib/global/qtpreprocessorsupport.qdoc b/src/corelib/global/qtpreprocessorsupport.qdoc
new file mode 100644
index 0000000000..c9fedf4ec1
--- /dev/null
+++ b/src/corelib/global/qtpreprocessorsupport.qdoc
@@ -0,0 +1,20 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \macro Q_UNUSED(name)
+ \relates <QtPreprocessorSupport>
+
+ Indicates to the compiler that the parameter with the specified
+ \a name is not used in the body of a function. This can be used to
+ suppress compiler warnings while allowing functions to be defined
+ with meaningful parameter names in their signatures.
+*/
+
+/*!
+ \macro QT_STRINGIFY(arg)
+ \relates <QtPreprocessorSupport>
+
+ The macro can be used to turn the builtin line expander \a arg into a string
+ literal.
+*/
diff --git a/src/corelib/global/qtrace_p.h b/src/corelib/global/qtrace_p.h
index d9011c6066..f4e39ffe2b 100644
--- a/src/corelib/global/qtrace_p.h
+++ b/src/corelib/global/qtrace_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTRACE_P_H
#define QTRACE_P_H
@@ -93,7 +57,7 @@
* qcoreapplication_qrect(const QRect &rect)
*
* The provider file is then parsed by src/tools/tracegen, which can be
- * switched to output either ETW or LTTNG tracepoint definitions. The provider
+ * switched to output either ETW, CTF or LTTNG tracepoint definitions. The provider
* name is deduced to be basename(provider_file).
*
* To use the above (inside qtcore), you need to include
@@ -111,12 +75,56 @@
* - QByteArray
* - QUrl
* - QRect
+ * - QRectF
+ * - QSize
+ * - QSizeF
*
* Dynamic arrays are supported using the syntax illustrated by
* qcoreapplication_baz above.
+ *
+ * One can also add prefix for the generated providername_tracepoints_p.h file
+ * by specifying it inside brackets '{ }' in the tracepoints file. One can
+ * for example add forward declaration for a type:
+ *
+ * {
+ * QT_BEGIN_NAMESPACE
+ * class QEvent;
+ * QT_END_NAMESPACE
+ * }
+ *
+ * Metadata
+ *
+ * Metadata is used to add textual information for different types such
+ * as enums and flags. How this data is handled depends on the used backend.
+ * For ETW, the values are converted to text, for CTF and LTTNG they are used to add
+ * CTF enumerations, which are converted to text after tracing.
+ *
+ * Enumererations are specified using ENUM:
+ *
+ * ENUM {
+ * Enum0 = 0,
+ * Enum1 = 1,
+ * Enum2,
+ * RANGE(RangeEnum, 3 ... 10),
+ * } Name;
+ *
+ * Name must match to one of the enumerations used in the tracepoints. Range of values
+ * can be provided using RANGE(name, first ... last). All values must be unique.
+ *
+ * Flags are specified using FLAGS:
+ *
+ * FLAGS {
+ * Default = 0,
+ * Flag0 = 1,
+ * Flag1 = 2,
+ * Flag2 = 4,
+ * } Name;
+ *
+ * Name must match to one of the flags used in the tracepoints. Each value must be
+ * power of two and unique.
*/
-#include <QtCore/qglobal.h>
+#include <QtCore/private/qglobal_p.h>
#include <QtCore/qscopeguard.h>
QT_BEGIN_NAMESPACE
@@ -140,6 +148,91 @@ QT_BEGIN_NAMESPACE
# define Q_TRACE_ENABLED(x) false
#endif // defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
+
+/*
+ * The Qt tracepoints can also be defined directly in the source files using
+ * the following macros. If using these macros, the tracepoints file is automatically
+ * generated using the tracepointgen tool. The tool scans the input files for
+ * these macros. These macros are ignored during compile time. Both automatic
+ * generation and manually specifying tracepoints in a file can't be done at the same
+ * time for the same provider.
+ *
+ * - Q_TRACE_INSTRUMENT(provider)
+ * Generate entry/exit tracepoints for a function. For example, member function
+ *
+ * void SomeClass::method(int param1, float param2)
+ * {
+ * ...
+ * }
+ *
+ * converted to use tracepoints:
+ *
+ * void Q_TRACE_INSTRUMENT(provider) SomeClass::method(int param1, float param2)
+ * {
+ * Q_TRACE_SCOPE(SomeClass_method, param1, param2);
+ * ...
+ * }
+ *
+ * generates following tracepoints in provider.tracepoints file:
+ *
+ * SomeClass_method_entry(int param1, float param2)
+ * SomeClass_method_exit()
+ *
+ * - Q_TRACE_PARAM_REPLACE(in, out)
+ * Can be used with Q_TRACE_INSTRUMENT to replace parameter type in with type out.
+ * If a parameter type is not supported by the tracegen tool, one can use this to
+ * change it to another supported type.
+ *
+ * void Q_TRACE_INSTRUMENT(provider) SomeClass::method(int param1, UserType param2)
+ * {
+ * Q_TRACE_PARAM_REPLACE(UserType, QString);
+ * Q_TRACE_SCOPE(SomeClass_method, param1, param2.toQString());
+ * }
+ *
+ * - Q_TRACE_POINT(provider, tracepoint, ...)
+ * Manually specify tracepoint for the provider. 'tracepoint' is the full name
+ * of the tracepoint and ... can be zero or more parameters.
+ *
+ * Q_TRACE_POINT(provider, SomeClass_function_entry, int param1, int param2);
+ *
+ * generates following tracepoint:
+ *
+ * SomeClass_function_entry(int param1, int param2)
+ *
+ * - Q_TRACE_PREFIX(provider, prefix)
+ * Provide prefix for the tracepoint. Multiple prefixes can be specified for the same
+ * provider in different files, they are all concatenated into one in the
+ * provider.tracepoints file.
+ *
+ * Q_TRACE_PREFIX(provider,
+ * "QT_BEGIN_NAMESPACE" \
+ * "class QEvent;" \
+ * "QT_END_NAMESPACE")
+ *
+ * - Q_TRACE_METADATA(provider, metadata)
+ * Provides metadata for the tracepoint provider.
+ *
+ * Q_TRACE_METADATA(qtgui,
+ * "ENUM {" \
+ * "Format_Invalid," \
+ * "Format_Mono," \
+ * "Format_MonoLSB," \
+ * "Format_Indexed8," \
+ * ...
+ * "} QImage::Format;" \
+ * );
+ *
+ * If the content of enum is empty or contains keyword AUTO, then the tracepointgen tool
+ * tries to find the enumeration from header files.
+ *
+ * Q_TRACE_METADATA(qtcore, "ENUM { AUTO, RANGE User ... MaxUser } QEvent::Type;");
+ */
+#define Q_TRACE_INSTRUMENT(provider)
+#define Q_TRACE_PARAM_REPLACE(in, out)
+#define Q_TRACE_POINT(provider, tracepoint, ...)
+#define Q_TRACE_PREFIX(provider, prefix)
+#define Q_TRACE_METADATA(provider, metadata)
+
QT_END_NAMESPACE
#endif // QTRACE_P_H
diff --git a/src/corelib/global/qtresource.h b/src/corelib/global/qtresource.h
new file mode 100644
index 0000000000..535903aac0
--- /dev/null
+++ b/src/corelib/global/qtresource.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTRESOURCE_H
+#define QTRESOURCE_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#if 0
+#pragma qt_class(QtResource)
+#pragma qt_sync_stop_processing
+#endif
+
+#define Q_INIT_RESOURCE(name) \
+ do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \
+ QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (false)
+#define Q_CLEANUP_RESOURCE(name) \
+ do { extern int QT_MANGLE_NAMESPACE(qCleanupResources_ ## name) (); \
+ QT_MANGLE_NAMESPACE(qCleanupResources_ ## name) (); } while (false)
+
+#endif // QTRESOURCE_H
diff --git a/src/corelib/global/qtresource.qdoc b/src/corelib/global/qtresource.qdoc
new file mode 100644
index 0000000000..abc5265987
--- /dev/null
+++ b/src/corelib/global/qtresource.qdoc
@@ -0,0 +1,54 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \macro void Q_INIT_RESOURCE(name)
+ \relates <QtResource>
+
+ Initializes the resources specified by the \c .qrc file with the
+ specified base \a name. Normally, when resources are built as part
+ of the application, the resources are loaded automatically at
+ startup. The Q_INIT_RESOURCE() macro is necessary on some platforms
+ for resources stored in a static library.
+
+ For example, if your application's resources are listed in a file
+ called \c myapp.qrc, you can ensure that the resources are
+ initialized at startup by adding this line to your \c main()
+ function:
+
+ \snippet code/src_corelib_io_qdir.cpp 13
+
+ If the file name contains characters that cannot be part of a valid C++ function name
+ (such as '-'), they have to be replaced by the underscore character ('_').
+
+ \note This macro cannot be used in a namespace. It should be called from
+ main(). If that is not possible, the following workaround can be used
+ to init the resource \c myapp from the function \c{MyNamespace::myFunction}:
+
+ \snippet code/src_corelib_io_qdir.cpp 14
+
+ \sa Q_CLEANUP_RESOURCE(), {The Qt Resource System}
+*/
+
+/*!
+ \since 4.1
+ \macro void Q_CLEANUP_RESOURCE(name)
+ \relates <QtResource>
+
+ Unloads the resources specified by the \c .qrc file with the base
+ name \a name.
+
+ Normally, Qt resources are unloaded automatically when the
+ application terminates, but if the resources are located in a
+ plugin that is being unloaded, call Q_CLEANUP_RESOURCE() to force
+ removal of your resources.
+
+ \note This macro cannot be used in a namespace. Please see the
+ Q_INIT_RESOURCE documentation for a workaround.
+
+ Example:
+
+ \snippet code/src_corelib_io_qdir.cpp 15
+
+ \sa Q_INIT_RESOURCE(), {The Qt Resource System}
+*/
diff --git a/src/corelib/global/qtsymbolmacros.h b/src/corelib/global/qtsymbolmacros.h
new file mode 100644
index 0000000000..18cdc85f72
--- /dev/null
+++ b/src/corelib/global/qtsymbolmacros.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTSYMBOLMACROS_H
+#define QTSYMBOLMACROS_H
+
+#if 0
+# pragma qt_sync_stop_processing
+#endif
+
+// For GHS symbol keeping.
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qtpreprocessorsupport.h>
+
+// For handling namespaced resources.
+#ifdef QT_NAMESPACE
+# define QT_RCC_MANGLE_NAMESPACE0(x) x
+# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
+# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
+# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
+ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#else
+# define QT_RCC_MANGLE_NAMESPACE(name) name
+#endif
+
+// GHS needs special handling to keep a symbol around.
+#if defined(Q_CC_GHS)
+# define Q_GHS_KEEP_REFERENCE(S) QT_DO_PRAGMA(ghs reference S ##__Fv)
+#else
+# define Q_GHS_KEEP_REFERENCE(S)
+#endif
+
+// Macros to ensure a symbol is not dropped by the linker even if it's not used.
+#define QT_DECLARE_EXTERN_SYMBOL(NAME, RETURN_TYPE) \
+ extern RETURN_TYPE NAME(); \
+ Q_GHS_KEEP_REFERENCE(NAME)
+
+#define QT_DECLARE_EXTERN_SYMBOL_INT(NAME) \
+ QT_DECLARE_EXTERN_SYMBOL(NAME, int)
+
+#define QT_DECLARE_EXTERN_SYMBOL_VOID(NAME) \
+ QT_DECLARE_EXTERN_SYMBOL(NAME, void)
+
+#define QT_KEEP_SYMBOL_VAR_NAME(NAME) NAME ## _keep
+
+#define QT_KEEP_SYMBOL_HELPER(NAME, VAR_NAME) \
+ volatile auto VAR_NAME = &NAME; \
+ Q_UNUSED(VAR_NAME)
+
+#define QT_KEEP_SYMBOL(NAME) \
+ QT_KEEP_SYMBOL_HELPER(NAME, QT_KEEP_SYMBOL_VAR_NAME(NAME))
+
+
+// Similar to the ones above, but for rcc resource symbols specifically.
+#define QT_GET_RESOURCE_INIT_SYMBOL(NAME) \
+ QT_RCC_MANGLE_NAMESPACE(qInitResources_ ## NAME)
+
+#define QT_DECLARE_EXTERN_RESOURCE(NAME) \
+ QT_DECLARE_EXTERN_SYMBOL_INT(QT_GET_RESOURCE_INIT_SYMBOL(NAME))
+
+#define QT_KEEP_RESOURCE(NAME) \
+ QT_KEEP_SYMBOL(QT_GET_RESOURCE_INIT_SYMBOL(NAME))
+
+#endif // QTSYMBOLMACROS_H
+
diff --git a/src/corelib/global/qttranslation.h b/src/corelib/global/qttranslation.h
new file mode 100644
index 0000000000..fb0a2244cc
--- /dev/null
+++ b/src/corelib/global/qttranslation.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTTRANSLATION_H
+#define QTTRANSLATION_H
+
+#include <QtCore/qtconfigmacros.h> // QT_NO_TRANSLATION should be defined here as well
+#include <QtCore/qtcoreexports.h>
+
+#if 0
+#pragma qt_class(QtTranslation)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+#define QT_TR_NOOP(x) x
+#define QT_TR_NOOP_UTF8(x) x
+#define QT_TRANSLATE_NOOP(scope, x) x
+#define QT_TRANSLATE_NOOP_UTF8(scope, x) x
+#define QT_TRANSLATE_NOOP3(scope, x, comment) {x, comment}
+#define QT_TRANSLATE_NOOP3_UTF8(scope, x, comment) {x, comment}
+
+#ifndef QT_NO_TRANSLATION
+
+#define QT_TR_N_NOOP(x) x
+#define QT_TRANSLATE_N_NOOP(scope, x) x
+#define QT_TRANSLATE_N_NOOP3(scope, x, comment) {x, comment}
+
+// Defined in qcoreapplication.cpp
+// The better name qTrId() is reserved for an upcoming function which would
+// return a much more powerful QStringFormatter instead of a QString.
+Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1);
+
+#define QT_TRID_NOOP(id) id
+#define QT_TRID_N_NOOP(id) id
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TRANSLATION
+
+#endif /* QTTRANSLATION_H */
diff --git a/src/corelib/global/qttranslation.qdoc b/src/corelib/global/qttranslation.qdoc
new file mode 100644
index 0000000000..b2b0b1f3c3
--- /dev/null
+++ b/src/corelib/global/qttranslation.qdoc
@@ -0,0 +1,206 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \macro QT_TR_NOOP(sourceText)
+ \relates <QtTranslation>
+
+ Marks the UTF-8 encoded string literal \a sourceText for delayed
+ translation in the current context (class).
+
+ The macro tells lupdate to collect the string, and expands to
+ \a sourceText itself.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 34
+
+ The macro QT_TR_NOOP_UTF8() is identical and obsolete; this applies
+ to all other _UTF8 macros as well.
+
+ \sa QT_TRANSLATE_NOOP(), {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TRANSLATE_NOOP(context, sourceText)
+ \relates <QtTranslation>
+
+ Marks the UTF-8 encoded string literal \a sourceText for delayed
+ translation in the given \a context. The \a context is typically
+ a class name and also needs to be specified as a string literal.
+
+ The macro tells lupdate to collect the string, and expands to
+ \a sourceText itself.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 35
+
+ \sa QT_TR_NOOP(), QT_TRANSLATE_NOOP3(), {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TRANSLATE_NOOP3(context, sourceText, disambiguation)
+ \relates <QtTranslation>
+ \since 4.4
+
+ Marks the UTF-8 encoded string literal \a sourceText for delayed
+ translation in the given \a context with the given \a disambiguation.
+ The \a context is typically a class and also needs to be specified
+ as a string literal. The string literal \a disambiguation should be
+ a short semantic tag to tell apart otherwise identical strings.
+
+ The macro tells lupdate to collect the string, and expands to an
+ anonymous struct of the two string literals passed as \a sourceText
+ and \a disambiguation.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 36
+
+ \sa QT_TR_NOOP(), QT_TRANSLATE_NOOP(), {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TR_N_NOOP(sourceText)
+ \relates <QtTranslation>
+ \since 5.12
+
+ Marks the UTF-8 encoded string literal \a sourceText for numerator
+ dependent delayed translation in the current context (class).
+
+ The macro tells lupdate to collect the string, and expands to
+ \a sourceText itself.
+
+ The macro expands to \a sourceText.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttrnnoop
+
+ \sa QT_TR_NOOP, {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TRANSLATE_N_NOOP(context, sourceText)
+ \relates <QtTranslation>
+ \since 5.12
+
+ Marks the UTF-8 encoded string literal \a sourceText for numerator
+ dependent delayed translation in the given \a context.
+ The \a context is typically a class name and also needs to be
+ specified as a string literal.
+
+ The macro tells lupdate to collect the string, and expands to
+ \a sourceText itself.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttranslatennoop
+
+ \sa QT_TRANSLATE_NOOP(), QT_TRANSLATE_N_NOOP3(),
+ {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TRANSLATE_N_NOOP3(context, sourceText, comment)
+ \relates <QtTranslation>
+ \since 5.12
+
+ Marks the UTF-8 encoded string literal \a sourceText for numerator
+ dependent delayed translation in the given \a context with the given
+ \a comment.
+ The \a context is typically a class and also needs to be specified
+ as a string literal. The string literal \a comment should be
+ a short semantic tag to tell apart otherwise identical strings.
+
+ The macro tells lupdate to collect the string, and expands to an
+ anonymous struct of the two string literals passed as \a sourceText
+ and \a comment.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttranslatennoop3
+
+ \sa QT_TR_NOOP(), QT_TRANSLATE_NOOP(), QT_TRANSLATE_NOOP3(),
+ {Internationalization with Qt}
+*/
+
+/*!
+ \fn QString qtTrId(const char *id, int n = -1)
+ \relates <QtTranslation>
+ \reentrant
+ \since 4.6
+
+ \brief The qtTrId function finds and returns a translated string.
+
+ Returns a translated string identified by \a id.
+ If no matching string is found, the id itself is returned. This
+ should not happen under normal conditions.
+
+ If \a n >= 0, all occurrences of \c %n in the resulting string
+ are replaced with a decimal representation of \a n. In addition,
+ depending on \a n's value, the translation text may vary.
+
+ Meta data and comments can be passed as documented for QObject::tr().
+ In addition, it is possible to supply a source string template like that:
+
+ \tt{//% <C string>}
+
+ or
+
+ \tt{\\begincomment% <C string> \\endcomment}
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttrid
+
+ Creating QM files suitable for use with this function requires passing
+ the \c -idbased option to the \c lrelease tool.
+
+ \warning This method is reentrant only if all translators are
+ installed \e before calling this method. Installing or removing
+ translators while performing translations is not supported. Doing
+ so will probably result in crashes or other undesirable behavior.
+
+ \sa QObject::tr(), QCoreApplication::translate(), {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TRID_NOOP(id)
+ \relates <QtTranslation>
+ \since 4.6
+
+ \brief The QT_TRID_NOOP macro marks an id for dynamic translation.
+
+ The only purpose of this macro is to provide an anchor for attaching
+ meta data like to qtTrId().
+
+ The macro expands to \a id.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttrid_noop
+
+ \sa qtTrId(), {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TRID_N_NOOP(id)
+ \relates <QtTranslation>
+ \since 6.3
+
+ \brief The QT_TRID_N_NOOP macro marks an id for numerator
+ dependent dynamic translation.
+
+ The only purpose of this macro is to provide an anchor for attaching
+ meta data like to qtTrId().
+
+ The macro expands to \a id.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttrid_n_noop
+
+ \sa qtTrId(), {Internationalization with Qt}
+*/
diff --git a/src/corelib/global/qttypetraits.h b/src/corelib/global/qttypetraits.h
new file mode 100644
index 0000000000..1efb24bf70
--- /dev/null
+++ b/src/corelib/global/qttypetraits.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTTYPETRAITS_H
+#define QTTYPETRAITS_H
+
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtdeprecationmarkers.h>
+
+#include <type_traits>
+#include <utility>
+
+#if 0
+#pragma qt_class(QtTypeTraits)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// like std::to_underlying
+template <typename Enum>
+constexpr std::underlying_type_t<Enum> qToUnderlying(Enum e) noexcept
+{
+ return static_cast<std::underlying_type_t<Enum>>(e);
+}
+
+#ifndef QT_NO_QASCONST
+#if QT_DEPRECATED_SINCE(6, 6)
+
+// this adds const to non-const objects (like std::as_const)
+template <typename T>
+QT_DEPRECATED_VERSION_X_6_6("Use std::as_const() instead.")
+constexpr typename std::add_const<T>::type &qAsConst(T &t) noexcept { return t; }
+// prevent rvalue arguments:
+template <typename T>
+void qAsConst(const T &&) = delete;
+
+#endif // QT_DEPRECATED_SINCE(6, 6)
+#endif // QT_NO_QASCONST
+
+#ifndef QT_NO_QEXCHANGE
+
+// like std::exchange
+template <typename T, typename U = T>
+constexpr T qExchange(T &t, U &&newValue)
+noexcept(std::conjunction_v<std::is_nothrow_move_constructible<T>,
+ std::is_nothrow_assignable<T &, U>>)
+{
+ T old = std::move(t);
+ t = std::forward<U>(newValue);
+ return old;
+}
+
+#endif // QT_NO_QEXCHANGE
+
+namespace QtPrivate {
+// helper to be used to trigger a "dependent static_assert(false)"
+// (for instance, in a final `else` branch of a `if constexpr`.)
+template <typename T> struct type_dependent_false : std::false_type {};
+template <auto T> struct value_dependent_false : std::false_type {};
+}
+
+QT_END_NAMESPACE
+
+#endif // QTTYPETRAITS_H
diff --git a/src/corelib/global/qttypetraits.qdoc b/src/corelib/global/qttypetraits.qdoc
new file mode 100644
index 0000000000..ed814d6f43
--- /dev/null
+++ b/src/corelib/global/qttypetraits.qdoc
@@ -0,0 +1,146 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \headerfile <QtTypeTraits>
+ \inmodule QtCore
+ \since 6.5
+ \title Qt Type Traits
+ \brief Functionality for type traits and transformations.
+*/
+
+/*!
+ \fn template <typename Enum> std::underlying_type_t<Enum> qToUnderlying(Enum e)
+ \relates <QtTypeTraits>
+ \since 6.2
+
+ Converts the enumerator \a e to the equivalent value expressed in its
+ enumeration's underlying type.
+*/
+
+/*!
+ \fn template <typename T> typename std::add_const<T>::type &qAsConst(T &t)
+ \relates <QtTypeTraits>
+ \since 5.7
+
+ \deprecated [6.6] Use std::as_const() instead.
+
+ Returns \a t cast to \c{const T}.
+
+ This function is a Qt implementation of C++17's std::as_const(),
+ a cast function like std::move(). But while std::move() turns
+ lvalues into rvalues, this function turns non-const lvalues into
+ const lvalues. Like std::as_const(), it doesn't work on rvalues,
+ because it cannot be efficiently implemented for rvalues without
+ leaving dangling references.
+
+ Its main use in Qt is to prevent implicitly-shared Qt containers
+ from detaching:
+ \snippet code/src_corelib_global_qglobal.cpp as-const-0
+
+ Of course, in this case, you could (and probably should) have declared
+ \c s as \c const in the first place:
+ \snippet code/src_corelib_global_qglobal.cpp as-const-1
+ but often that is not easily possible.
+
+ It is important to note that qAsConst() does not copy its argument,
+ it just performs a \c{const_cast<const T&>(t)}. This is also the reason
+ why it is designed to fail for rvalues: The returned reference would go
+ stale too soon. So while this works (but detaches the returned object):
+ \snippet code/src_corelib_global_qglobal.cpp as-const-2
+
+ this would not:
+ \snippet code/src_corelib_global_qglobal.cpp as-const-3
+
+ To prevent this construct from compiling (and failing at runtime), qAsConst() has
+ a second, deleted, overload which binds to rvalues.
+
+ \note You can make the qAsConst() function unavailable by defining
+ the \l{QT_NO_QASCONST} macro.
+*/
+
+/*!
+ \macro QT_NO_QASCONST
+ \since 6.8
+ \relates <QtTypeTraits>
+
+ Defining this macro removes the availability of the qAsConst()
+ function.
+
+ \sa qAsConst
+*/
+
+/*!
+ \fn template <typename T> void qAsConst(const T &&t)
+ \relates <QtTypeTraits>
+ \since 5.7
+ \overload
+
+ \deprecated [6.6]
+
+ This overload is deleted to prevent a dangling reference in code like
+ \snippet code/src_corelib_global_qglobal.cpp as-const-4
+*/
+
+/*!
+ \fn template <typename T, typename U = T> T qExchange(T &obj, U &&newValue)
+ \relates <QtTypeTraits>
+ \since 5.14
+
+ Replaces the value of \a obj with \a newValue and returns the old value of \a obj.
+
+ This is Qt's implementation of std::exchange(). It differs from std::exchange()
+ only in that it is \c constexpr already before C++20 and noexcept already before C++23.
+
+ We strongly advise to use std::exchange() when you don't need the C++20 or C++23 variants.
+ You can make qExchange() unavailable by defining the \l{QT_NO_QEXCHANGE} macro.
+
+ Here is how to use qExchange() to implement move constructors:
+ \code
+ MyClass(MyClass &&other)
+ : m_pointer{qExchange(other.m_pointer, nullptr)},
+ m_int{qExchange(other.m_int, 0)},
+ m_vector{std::move(other.m_vector)},
+ ...
+ \endcode
+
+ For members of class type, we can use std::move(), as their move-constructor will
+ do the right thing. But for scalar types such as raw pointers or integer type, move
+ is the same as copy, which, particularly for pointers, is not what we expect. So, we
+ cannot use std::move() for such types, but we can use std::exchange()/qExchange() to
+ make sure the source object's member is already reset by the time we get to the
+ initialization of our next data member, which might come in handy if the constructor
+ exits with an exception.
+
+ Here is how to use qExchange() to write a loop that consumes the collection it
+ iterates over:
+ \code
+ for (auto &e : qExchange(collection, {})
+ doSomethingWith(e);
+ \endcode
+
+ Which is equivalent to the following, much more verbose code:
+ \code
+ {
+ auto tmp = std::move(collection);
+ collection = {}; // or collection.clear()
+ for (auto &e : tmp)
+ doSomethingWith(e);
+ } // destroys 'tmp'
+ \endcode
+
+ This is perfectly safe, as the for-loop keeps the result of qExchange() alive for as
+ long as the loop runs, saving the declaration of a temporary variable. Be aware, though,
+ that qExchange() returns a non-const object, so Qt containers may detach.
+*/
+
+/*!
+ \macro QT_NO_QEXCHANGE
+ \since 6.6
+ \relates <QtTypeTraits>
+
+ Defining this macro removes the availability of the qExchange()
+ function.
+
+ \sa qExchange
+*/
diff --git a/src/corelib/global/qtversion.h b/src/corelib/global/qtversion.h
new file mode 100644
index 0000000000..775f2479a9
--- /dev/null
+++ b/src/corelib/global/qtversion.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTVERSION_H
+#define QTVERSION_H
+
+#if 0
+#pragma qt_class(QtVersion)
+#pragma qt_sync_stop_processing
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtcoreexports.h>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * If we're compiling C++ code:
+ * - and this is a non-namespace build, declare qVersion as extern "C"
+ * - and this is a namespace build, declare it as a regular function
+ * (we're already inside QT_BEGIN_NAMESPACE / QT_END_NAMESPACE)
+ * If we're compiling C code, simply declare the function. If Qt was compiled
+ * in a namespace, qVersion isn't callable anyway.
+ */
+#if !defined(QT_NAMESPACE) && defined(__cplusplus) && !defined(Q_QDOC)
+extern "C"
+#endif
+/* defined in qlibraryinfo.cpp */
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION const char *qVersion(void) Q_DECL_NOEXCEPT;
+
+QT_END_NAMESPACE
+
+#endif // __ASSEMBLER__
+
+#endif // QTVERSION_H
diff --git a/src/corelib/global/qtversionchecks.cpp b/src/corelib/global/qtversionchecks.cpp
new file mode 100644
index 0000000000..3e3f4547f1
--- /dev/null
+++ b/src/corelib/global/qtversionchecks.cpp
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*!
+ \macro QT_VERSION_CHECK(major, minor, patch)
+ \relates <QtVersionChecks>
+
+ Turns the \a major, \a minor and \a patch numbers of a version into an
+ integer that encodes all three. When expressed in hexadecimal, this integer
+ is of form \c 0xMMNNPP wherein \c{0xMM ==} \a major, \c{0xNN ==} \a minor,
+ and \c{0xPP ==} \a patch. This can be compared with another similarly
+ processed version ID.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qt-version-check
+
+ \note the parameters are read as integers in the normal way, so should
+ normally be written in decimal (so a \c 0x prefix must be used if writing
+ them in hexadecimal). Thus \c{QT_VERSION_CHECK(5, 15, 0)} is equal to \c
+ 0x050f00, which could equally be written \c{QT_VERSION_CHECK(5, 0xf, 0)}.
+
+ \sa QT_VERSION
+*/
+
+/*!
+ \macro QT_VERSION
+ \relates <QtVersionChecks>
+
+ This macro expands to a numeric value of the same form as \l
+ QT_VERSION_CHECK() constructs, that specifies the version of Qt with which
+ code using it is compiled. For example, if you compile your application with
+ Qt 6.1.2, the QT_VERSION macro will expand to \c 0x060102, the same as
+ \c{QT_VERSION_CHECK(6, 1, 2)}. Note that this need not agree with the
+ version the application will find itself using at \e runtime.
+
+ You can use QT_VERSION to select the latest Qt features where available
+ while falling back to older implementations otherwise. Using
+ QT_VERSION_CHECK() for the value to compare with is recommended.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 16
+
+ \sa QT_VERSION_STR, QT_VERSION_CHECK(), qVersion()
+*/
diff --git a/src/corelib/global/qtversionchecks.h b/src/corelib/global/qtversionchecks.h
new file mode 100644
index 0000000000..14df2780d8
--- /dev/null
+++ b/src/corelib/global/qtversionchecks.h
@@ -0,0 +1,114 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTVERSIONCHECKS_H
+#define QTVERSIONCHECKS_H
+
+#if 0
+#pragma qt_class(QtVersionChecks)
+#pragma qt_sync_stop_processing
+#endif
+
+#include <QtCore/qtconfiginclude.h>
+
+/*
+ QT_VERSION is (major << 16) | (minor << 8) | patch.
+*/
+#define QT_VERSION QT_VERSION_CHECK(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH)
+/*
+ can be used like #if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
+*/
+#define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
+
+/*
+ Helper macros to make some simple code active in Qt 6 or Qt 7 only,
+ like:
+ struct QT6_ONLY(Q_CORE_EXPORT) QTrivialClass
+ {
+ void QT7_ONLY(Q_CORE_EXPORT) void operate();
+ }
+*/
+#if QT_VERSION_MAJOR == 7 || defined(QT_BOOTSTRAPPED)
+# define QT7_ONLY(...) __VA_ARGS__
+# define QT6_ONLY(...)
+#elif QT_VERSION_MAJOR == 6
+# define QT7_ONLY(...)
+# define QT6_ONLY(...) __VA_ARGS__
+#else
+# error Qt major version not 6 or 7
+#endif
+
+/* Macro and tag type to help overload resolution on functions
+ that are, e.g., QT_REMOVED_SINCE'ed. Example use:
+
+ #if QT_CORE_REMOVED_SINCE(6, 4)
+ int size() const;
+ #endif
+ qsizetype size(QT6_DECL_NEW_OVERLOAD) const;
+
+ in the normal cpp file:
+
+ qsizetype size(QT6_IMPL_NEW_OVERLOAD) const {
+ ~~~
+ }
+
+ in removed_api.cpp:
+
+ int size() const { return int(size(QT6_CALL_NEW_OVERLOAD)); }
+*/
+#ifdef Q_QDOC
+# define QT6_DECL_NEW_OVERLOAD
+# define QT6_DECL_NEW_OVERLOAD_TAIL
+# define QT6_IMPL_NEW_OVERLOAD
+# define QT6_IMPL_NEW_OVERLOAD_TAIL
+# define QT6_CALL_NEW_OVERLOAD
+# define QT6_CALL_NEW_OVERLOAD_TAIL
+#else
+# define QT6_DECL_NEW_OVERLOAD QT6_ONLY(Qt::Disambiguated_t = Qt::Disambiguated)
+# define QT6_DECL_NEW_OVERLOAD_TAIL QT6_ONLY(, QT6_DECL_NEW_OVERLOAD)
+# define QT6_IMPL_NEW_OVERLOAD QT6_ONLY(Qt::Disambiguated_t)
+# define QT6_IMPL_NEW_OVERLOAD_TAIL QT6_ONLY(, QT6_IMPL_NEW_OVERLOAD)
+# define QT6_CALL_NEW_OVERLOAD QT6_ONLY(Qt::Disambiguated)
+# define QT6_CALL_NEW_OVERLOAD_TAIL QT6_ONLY(, QT6_CALL_NEW_OVERLOAD)
+#endif
+
+/*
+ Macro to tag Tech Preview APIs.
+ It expands to nothing, because we want to use it in places where
+ nothing is generally allowed (not even an attribute); for instance:
+ to tag other macros, Q_PROPERTY declarations, and so on.
+
+ Still: use it as if it were an C++ attribute.
+
+ To mark a class as TP:
+ class QT_TECH_PREVIEW_API Q_CORE_EXPORT QClass { ... };
+
+ To mark a function:
+ QT_TECH_PREVIEW_API void qFunction();
+
+ To mark an enumeration or enumerator:
+ enum class QT_TECH_PREVIEW_API QEnum {
+ Enum1,
+ Enum2 QT_TECH_PREVIEW_API,
+ };
+
+ To mark parts of a class:
+ class QClass : public QObject
+ {
+ Q_OBJECT
+
+ QT_TECH_PREVIEW_API
+ Q_PROPERTY(int countNG ...) // this is TP
+
+ Q_PROPERTY(int count ...) // this is stable API
+
+ public:
+ QT_TECH_PREVIEW_API
+ void f(); // TP
+
+ void g(); // stable
+ };
+*/
+#define QT_TECH_PREVIEW_API
+
+#endif /* QTVERSIONCHECKS_H */
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 58f20b7be4..9b2119da1d 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -1,52 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTYPEINFO_H
+#define QTYPEINFO_H
+
+#include <QtCore/qcompilerdetection.h>
#include <QtCore/qcontainerfwd.h>
+
#include <variant>
#include <optional>
#include <tuple>
-#ifndef QTYPEINFO_H
-#define QTYPEINFO_H
-
QT_BEGIN_NAMESPACE
class QDebug;
@@ -55,9 +20,23 @@ class QDebug;
QTypeInfo - type trait functionality
*/
+namespace QtPrivate {
+
template <typename T>
inline constexpr bool qIsRelocatable = std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T>;
+// Denotes types that are trivially default constructible, and for which
+// value-initialization can be achieved by filling their storage with 0 bits.
+// There is no type trait we can use for this, so we hardcode a list of
+// possibilities that we know are OK on the architectures that we support.
+// The most notable exception are pointers to data members, which for instance
+// on the Itanium ABI are initialized to -1.
+template <typename T>
+inline constexpr bool qIsValueInitializationBitwiseZero =
+ std::is_scalar_v<T> && !std::is_member_object_pointer_v<T>;
+
+}
+
/*
The catch-all template.
*/
@@ -67,10 +46,11 @@ class QTypeInfo
{
public:
enum {
- isPointer = std::is_pointer_v<T>,
- isIntegral = std::is_integral_v<T>,
+ isPointer [[deprecated("Use std::is_pointer instead")]] = std::is_pointer_v<T>,
+ isIntegral [[deprecated("Use std::is_integral instead")]] = std::is_integral_v<T>,
isComplex = !std::is_trivial_v<T>,
- isRelocatable = qIsRelocatable<T>,
+ isRelocatable = QtPrivate::qIsRelocatable<T>,
+ isValueInitializationBitwiseZero = QtPrivate::qIsValueInitializationBitwiseZero<T>,
};
};
@@ -79,10 +59,11 @@ class QTypeInfo<void>
{
public:
enum {
- isPointer = false,
- isIntegral = false,
+ isPointer [[deprecated("Use std::is_pointer instead")]] = false,
+ isIntegral [[deprecated("Use std::is_integral instead")]] = false,
isComplex = false,
isRelocatable = false,
+ isValueInitializationBitwiseZero = false,
};
};
@@ -113,20 +94,33 @@ class QTypeInfoMerger
public:
static constexpr bool isComplex = ((QTypeInfo<Ts>::isComplex) || ...);
static constexpr bool isRelocatable = ((QTypeInfo<Ts>::isRelocatable) && ...);
- static constexpr bool isPointer = false;
- static constexpr bool isIntegral = false;
+ [[deprecated("Use std::is_pointer instead")]] static constexpr bool isPointer = false;
+ [[deprecated("Use std::is_integral instead")]] static constexpr bool isIntegral = false;
+ static constexpr bool isValueInitializationBitwiseZero = false;
+ static_assert(!isRelocatable ||
+ std::is_copy_constructible_v<T> ||
+ std::is_move_constructible_v<T>,
+ "All Ts... are Q_RELOCATABLE_TYPE, but T is neither copy- nor move-constructible, "
+ "so cannot be Q_RELOCATABLE_TYPE. Please mark T as Q_COMPLEX_TYPE manually.");
};
+// QTypeInfo for std::pair:
+// std::pair is spec'ed to be struct { T1 first; T2 second; }, so, unlike tuple<>,
+// we _can_ specialize QTypeInfo for pair<>:
+template <class T1, class T2>
+class QTypeInfo<std::pair<T1, T2>> : public QTypeInfoMerger<std::pair<T1, T2>, T1, T2> {};
+
#define Q_DECLARE_MOVABLE_CONTAINER(CONTAINER) \
template <typename ...T> \
class QTypeInfo<CONTAINER<T...>> \
{ \
public: \
enum { \
- isPointer = false, \
- isIntegral = false, \
+ isPointer [[deprecated("Use std::is_pointer instead")]] = false, \
+ isIntegral [[deprecated("Use std::is_integral instead")]] = false, \
isComplex = true, \
isRelocatable = true, \
+ isValueInitializationBitwiseZero = false, \
}; \
}
@@ -164,10 +158,15 @@ class QTypeInfo<TYPE > \
public: \
enum { \
isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !std::is_trivial_v<TYPE>, \
- isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || qIsRelocatable<TYPE>, \
- isPointer = false, \
- isIntegral = std::is_integral< TYPE >::value, \
+ isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || QtPrivate::qIsRelocatable<TYPE>, \
+ isPointer [[deprecated("Use std::is_pointer instead")]] = std::is_pointer_v< TYPE >, \
+ isIntegral [[deprecated("Use std::is_integral instead")]] = std::is_integral< TYPE >::value, \
+ isValueInitializationBitwiseZero = QtPrivate::qIsValueInitializationBitwiseZero<TYPE>, \
}; \
+ static_assert(!isRelocatable || \
+ std::is_copy_constructible_v<TYPE > || \
+ std::is_move_constructible_v<TYPE >, \
+ #TYPE " is neither copy- nor move-constructible, so cannot be Q_RELOCATABLE_TYPE"); \
}
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
@@ -179,31 +178,6 @@ template<typename T> class QFlags;
template<typename T>
Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);
-/*
- Specialize a shared type with:
-
- Q_DECLARE_SHARED(type)
-
- where 'type' is the name of the type to specialize. NOTE: shared
- types must define a member-swap, and be defined in the same
- namespace as Qt for this to work.
-
- If the type was already released without Q_DECLARE_SHARED applied,
- _and_ without an explicit Q_DECLARE_TYPEINFO(type, Q_RELOCATABLE_TYPE),
- then use Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(type) to mark the
- type shared (incl. swap()), without marking it movable (which
- would change the memory layout of QList, a BiC change.
-*/
-
-#define Q_DECLARE_SHARED_IMPL(TYPE, FLAGS) \
-Q_DECLARE_TYPEINFO(TYPE, FLAGS); \
-inline void swap(TYPE &value1, TYPE &value2) \
- noexcept(noexcept(value1.swap(value2))) \
-{ value1.swap(value2); }
-#define Q_DECLARE_SHARED(TYPE) Q_DECLARE_SHARED_IMPL(TYPE, Q_RELOCATABLE_TYPE)
-#define Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(TYPE) \
- Q_DECLARE_SHARED_IMPL(TYPE, Q_RELOCATABLE_TYPE)
-
namespace QTypeTraits
{
@@ -272,7 +246,7 @@ using expand_operator_equal_recursive = std::conjunction<expand_operator_equal<T
template<typename T>
struct expand_operator_equal_tuple : has_operator_equal<T> {};
template<typename T>
-struct expand_operator_equal_tuple<std::optional<T>> : has_operator_equal<T> {};
+struct expand_operator_equal_tuple<std::optional<T>> : expand_operator_equal_recursive<T> {};
template<typename T1, typename T2>
struct expand_operator_equal_tuple<std::pair<T1, T2>> : expand_operator_equal_recursive<T1, T2> {};
template<typename ...T>
@@ -311,6 +285,8 @@ using expand_operator_less_than_recursive = std::conjunction<expand_operator_les
template<typename T>
struct expand_operator_less_than_tuple : has_operator_less_than<T> {};
+template<typename T>
+struct expand_operator_less_than_tuple<std::optional<T>> : expand_operator_less_than_recursive<T> {};
template<typename T1, typename T2>
struct expand_operator_less_than_tuple<std::pair<T1, T2>> : expand_operator_less_than_recursive<T1, T2> {};
template<typename ...T>
@@ -335,17 +311,29 @@ struct has_operator_equal : detail::expand_operator_equal<T> {};
template<typename T>
inline constexpr bool has_operator_equal_v = has_operator_equal<T>::value;
+template <typename Container, typename T>
+using has_operator_equal_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_equal<T>>;
+
template<typename T>
struct has_operator_less_than : detail::expand_operator_less_than<T> {};
template<typename T>
inline constexpr bool has_operator_less_than_v = has_operator_less_than<T>::value;
+template <typename Container, typename T>
+using has_operator_less_than_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_less_than<T>>;
+
template <typename ...T>
using compare_eq_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal<T>...>, bool>;
+template <typename Container, typename ...T>
+using compare_eq_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal_container<Container, T>...>, bool>;
+
template <typename ...T>
using compare_lt_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than<T>...>, bool>;
+template <typename Container, typename ...T>
+using compare_lt_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than_container<Container, T>...>, bool>;
+
namespace detail {
template<typename T>
@@ -363,6 +351,9 @@ struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<St
template <typename Stream, typename T>
inline constexpr bool has_ostream_operator_v = has_ostream_operator<Stream, T>::value;
+template <typename Stream, typename Container, typename T>
+using has_ostream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_ostream_operator<Stream, T>>;
+
template <typename Stream, typename, typename = void>
struct has_istream_operator : std::false_type {};
template <typename Stream, typename T>
@@ -370,6 +361,8 @@ struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<St
: std::true_type {};
template <typename Stream, typename T>
inline constexpr bool has_istream_operator_v = has_istream_operator<Stream, T>::value;
+template <typename Stream, typename Container, typename T>
+using has_istream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_istream_operator<Stream, T>>;
template <typename Stream, typename T>
inline constexpr bool has_stream_operator_v = has_ostream_operator_v<Stream, T> && has_istream_operator_v<Stream, T>;
diff --git a/src/corelib/global/qtypeinfo.qdoc b/src/corelib/global/qtypeinfo.qdoc
new file mode 100644
index 0000000000..78d9d423cd
--- /dev/null
+++ b/src/corelib/global/qtypeinfo.qdoc
@@ -0,0 +1,55 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \macro Q_DECLARE_TYPEINFO(Type, Flags)
+ \relates <QTypeInfo>
+
+ You can use this macro to specify information about a custom type
+ \a Type. With accurate type information, Qt's \l{Container Classes}
+ {generic containers} can choose appropriate storage methods and
+ algorithms.
+
+ \a Flags can be one of the following:
+
+ \list
+ \li \c Q_PRIMITIVE_TYPE specifies that \a Type can be created by
+ zero-initializing its storage, requires no operation to be properly
+ destroyed, and for which memcpy()ing creates a valid independent
+ copy of the object.
+ \li \c Q_RELOCATABLE_TYPE specifies that \a Type has a constructor
+ and/or a destructor but can be moved in memory using \c
+ memcpy().
+ \li \c Q_MOVABLE_TYPE is the same as \c Q_RELOCATABLE_TYPE. Prefer to use
+ \c Q_RELOCATABLE_TYPE in new code. Note: despite the name, this
+ has nothing to do with move constructors or C++ move semantics.
+ \li \c Q_COMPLEX_TYPE (the default) specifies that \a Type has
+ constructors and/or a destructor and that it may not be moved
+ in memory.
+ \endlist
+
+ Example of a "primitive" type:
+
+ \snippet code/src_corelib_global_qglobal.cpp 38
+
+ An example of a non-POD "primitive" type is QUuid: Even though
+ QUuid has constructors (and therefore isn't POD), every bit
+ pattern still represents a valid object, and memcpy() can be used
+ to create a valid independent copy of a QUuid object.
+
+ Example of a relocatable type:
+
+ \snippet code/src_corelib_global_qglobal.cpp 39
+
+ Qt will try to detect the class of a type using
+ \l {https://en.cppreference.com/w/cpp/types/is_trivial} {std::is_trivial_v<T>}
+ to identify primitive
+ types and it will require both
+ \l {https://en.cppreference.com/w/cpp/types/is_trivially_copyable} {std::is_trivially_copyable_v<T>}
+ and
+ \l {https://en.cppreference.com/w/cpp/types/is_destructible} {std::is_trivially_destructible_v<T>}
+ to identify relocatable types.
+ Use this macro to tune the behavior.
+ For instance many types would be candidates for Q_RELOCATABLE_TYPE despite
+ not being trivially-copyable.
+*/
diff --git a/src/corelib/global/qtypes.cpp b/src/corelib/global/qtypes.cpp
new file mode 100644
index 0000000000..9de3960e2f
--- /dev/null
+++ b/src/corelib/global/qtypes.cpp
@@ -0,0 +1,528 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qtypes.h"
+
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qsystemdetection.h>
+#include <QtCore/qprocessordetection.h>
+
+#include <climits>
+#include <limits>
+#include <type_traits>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \headerfile <QtTypes>
+ \inmodule QtCore
+ \title Qt Type Declarations
+
+ \brief The <QtTypes> header file includes Qt fundamental type declarations.
+
+ The header file declares several type definitions that guarantee a
+ specified bit-size on all platforms supported by Qt for various
+ basic types, for example \l qint8 which is a signed char
+ guaranteed to be 8-bit on all platforms supported by Qt. The
+ header file also declares the \l qlonglong type definition for
+ \c {long long int}.
+
+ Several convenience type definitions are declared: \l qreal for \c
+ double or \c float, \l uchar for \c {unsigned char}, \l uint for
+ \c {unsigned int}, \l ulong for \c {unsigned long} and \l ushort
+ for \c {unsigned short}.
+
+ The header also provides series of macros that make it possible to print
+ some Qt type aliases (qsizetype, qintptr, etc.) via a formatted output
+ facility such as printf() or qDebug() without raising formatting warnings
+ and without the need of a type cast.
+*/
+
+/*!
+ \typedef qreal
+ \relates <QtTypes>
+
+ Typedef for \c double unless Qt is configured with the
+ \c{-qreal float} option.
+*/
+
+/*! \typedef uchar
+ \relates <QtTypes>
+
+ Convenience typedef for \c{unsigned char}.
+*/
+
+/*! \typedef ushort
+ \relates <QtTypes>
+
+ Convenience typedef for \c{unsigned short}.
+*/
+
+/*! \typedef uint
+ \relates <QtTypes>
+
+ Convenience typedef for \c{unsigned int}.
+*/
+
+/*! \typedef ulong
+ \relates <QtTypes>
+
+ Convenience typedef for \c{unsigned long}.
+*/
+
+/*! \typedef qint8
+ \relates <QtTypes>
+
+ Typedef for \c{signed char}. This type is guaranteed to be 8-bit
+ on all platforms supported by Qt.
+*/
+
+/*!
+ \typedef quint8
+ \relates <QtTypes>
+
+ Typedef for \c{unsigned char}. This type is guaranteed to
+ be 8-bit on all platforms supported by Qt.
+*/
+
+/*! \typedef qint16
+ \relates <QtTypes>
+
+ Typedef for \c{signed short}. This type is guaranteed to be
+ 16-bit on all platforms supported by Qt.
+*/
+
+/*!
+ \typedef quint16
+ \relates <QtTypes>
+
+ Typedef for \c{unsigned short}. This type is guaranteed to
+ be 16-bit on all platforms supported by Qt.
+*/
+
+/*! \typedef qint32
+ \relates <QtTypes>
+
+ Typedef for \c{signed int}. This type is guaranteed to be 32-bit
+ on all platforms supported by Qt.
+*/
+
+/*!
+ \typedef quint32
+ \relates <QtTypes>
+
+ Typedef for \c{unsigned int}. This type is guaranteed to
+ be 32-bit on all platforms supported by Qt.
+*/
+
+/*! \typedef qint64
+ \relates <QtTypes>
+
+ Typedef for \c{long long int}. This type is guaranteed to be 64-bit
+ on all platforms supported by Qt.
+
+ Literals of this type can be created using the Q_INT64_C() macro:
+
+ \snippet code/src_corelib_global_qglobal.cpp 5
+
+ \sa Q_INT64_C(), quint64, qlonglong
+*/
+
+/*!
+ \typedef quint64
+ \relates <QtTypes>
+
+ Typedef for \c{unsigned long long int}. This type is guaranteed to
+ be 64-bit on all platforms supported by Qt.
+
+ Literals of this type can be created using the Q_UINT64_C()
+ macro:
+
+ \snippet code/src_corelib_global_qglobal.cpp 6
+
+ \sa Q_UINT64_C(), qint64, qulonglong
+*/
+
+/*!
+ \typedef qint128
+ \relates <QtTypes>
+ \since 6.6
+
+ Typedef for \c{__int128} on platforms that support it (Qt defines the macro
+ \l QT_SUPPORTS_INT128 if this is the case).
+
+ Literals of this type can be created using the Q_INT128_C() macro.
+
+ \sa Q_INT128_C(), Q_INT128_MIN, Q_INT128_MAX, quint128, QT_SUPPORTS_INT128
+*/
+
+/*!
+ \typedef quint128
+ \relates <QtTypes>
+ \since 6.6
+
+ Typedef for \c{unsigned __int128} on platforms that support it (Qt defines
+ the macro \l QT_SUPPORTS_INT128 if this is the case).
+
+ Literals of this type can be created using the Q_UINT128_C() macro.
+
+ \sa Q_UINT128_C(), Q_UINT128_MAX, qint128, QT_SUPPORTS_INT128
+*/
+
+/*!
+ \macro QT_SUPPORTS_INT128
+ \relates <QtTypes>
+ \since 6.6
+
+ Qt defines this macro as well as the \l qint128 and \l quint128 types if
+ the platform has support for 128-bit integer types.
+
+ \sa qint128, quint128, Q_INT128_C(), Q_UINT128_C(), Q_INT128_MIN, Q_INT128_MAX, Q_UINT128_MAX
+*/
+
+/*!
+ \typedef qintptr
+ \relates <QtTypes>
+
+ Integral type for representing pointers in a signed integer (useful for
+ hashing, etc.).
+
+ Typedef for either qint32 or qint64. This type is guaranteed to
+ be the same size as a pointer on all platforms supported by Qt. On
+ a system with 32-bit pointers, qintptr is a typedef for qint32;
+ on a system with 64-bit pointers, qintptr is a typedef for
+ qint64.
+
+ Note that qintptr is signed. Use quintptr for unsigned values.
+
+ In order to print values of this type by using formatted-output
+ facilities such as \c{printf()}, qDebug(), QString::asprintf() and
+ so on, you can use the \c{PRIdQINTPTR} and \c{PRIiQINTPTR}
+ macros as format specifiers. They will both print the value as a
+ base 10 number.
+
+ \code
+ qintptr p = 123;
+ printf("The pointer is %" PRIdQINTPTR "\n", p);
+ \endcode
+
+ \sa qptrdiff, qint32, qint64
+*/
+
+/*! \typedef qlonglong
+ \relates <QtTypes>
+
+ Typedef for \c{long long int} (\c __int64 on Windows). This is
+ the same as \l qint64.
+
+ \sa qulonglong, qint64
+*/
+
+/*!
+ \typedef qulonglong
+ \relates <QtTypes>
+
+ Typedef for \c{unsigned long long int} (\c{unsigned __int64} on
+ Windows). This is the same as \l quint64.
+
+ \sa quint64, qlonglong
+*/
+
+/*!
+ \macro PRIdQINTPTR
+ \macro PRIiQINTPTR
+ \since 6.2
+ \relates <QtTypes>
+
+ See \l qintptr.
+*/
+
+/*!
+ \typedef quintptr
+ \relates <QtTypes>
+
+ Integral type for representing pointers in an unsigned integer (useful for
+ hashing, etc.).
+
+ Typedef for either quint32 or quint64. This type is guaranteed to
+ be the same size as a pointer on all platforms supported by Qt. On
+ a system with 32-bit pointers, quintptr is a typedef for quint32;
+ on a system with 64-bit pointers, quintptr is a typedef for
+ quint64.
+
+ Note that quintptr is unsigned. Use qptrdiff for signed values.
+
+ In order to print values of this type by using formatted-output
+ facilities such as \c{printf()}, qDebug(), QString::asprintf() and
+ so on, you can use the following macros as format specifiers:
+
+ \list
+ \li \c{PRIuQUINTPTR}: prints the value as a base 10 number.
+ \li \c{PRIoQUINTPTR}: prints the value as a base 8 number.
+ \li \c{PRIxQUINTPTR}: prints the value as a base 16 number, using lowercase \c{a-f} letters.
+ \li \c{PRIXQUINTPTR}: prints the value as a base 16 number, using uppercase \c{A-F} letters.
+ \endlist
+
+ \code
+ quintptr p = 123u;
+ printf("The pointer value is 0x%" PRIXQUINTPTR "\n", p);
+ \endcode
+
+ \sa qptrdiff, quint32, quint64
+*/
+
+/*!
+ \macro PRIoQUINTPTR
+ \macro PRIuQUINTPTR
+ \macro PRIxQUINTPTR
+ \macro PRIXQUINTPTR
+ \since 6.2
+ \relates <QtTypes>
+
+ See quintptr.
+*/
+
+/*!
+ \typedef qptrdiff
+ \relates <QtTypes>
+
+ Integral type for representing pointer differences.
+
+ Typedef for either qint32 or qint64. This type is guaranteed to be
+ the same size as a pointer on all platforms supported by Qt. On a
+ system with 32-bit pointers, quintptr is a typedef for quint32; on
+ a system with 64-bit pointers, quintptr is a typedef for quint64.
+
+ Note that qptrdiff is signed. Use quintptr for unsigned values.
+
+ In order to print values of this type by using formatted-output
+ facilities such as \c{printf()}, qDebug(), QString::asprintf() and
+ so on, you can use the \c{PRIdQPTRDIFF} and \c{PRIiQPTRDIFF}
+ macros as format specifiers. They will both print the value as a
+ base 10 number.
+
+ \code
+ qptrdiff d = 123;
+ printf("The difference is %" PRIdQPTRDIFF "\n", d);
+ \endcode
+
+ \sa quintptr, qint32, qint64
+*/
+
+/*!
+ \macro PRIdQPTRDIFF
+ \macro PRIiQPTRDIFF
+ \since 6.2
+ \relates <QtTypes>
+
+ See qptrdiff.
+*/
+
+/*!
+ \typedef qsizetype
+ \relates <QtTypes>
+ \since 5.10
+
+ Integral type providing Posix' \c ssize_t for all platforms.
+
+ This type is guaranteed to be the same size as a \c size_t on all
+ platforms supported by Qt.
+
+ Note that qsizetype is signed. Use \c size_t for unsigned values.
+
+ In order to print values of this type by using formatted-output
+ facilities such as \c{printf()}, qDebug(), QString::asprintf() and
+ so on, you can use the \c{PRIdQSIZETYPE} and \c{PRIiQSIZETYPE}
+ macros as format specifiers. They will both print the value as a
+ base 10 number.
+
+ \code
+ qsizetype s = 123;
+ printf("The size is %" PRIdQSIZETYPE "\n", s);
+ \endcode
+
+ \sa qptrdiff
+*/
+
+/*!
+ \macro PRIdQSIZETYPE
+ \macro PRIiQSIZETYPE
+ \since 6.2
+ \relates <QtTypes>
+
+ See qsizetype.
+*/
+
+/*! \macro qint64 Q_INT64_C(literal)
+ \relates <QtTypes>
+
+ Wraps the signed 64-bit integer \a literal in a
+ platform-independent way.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 8
+
+ \sa qint64, Q_UINT64_C(), Q_INT128_C()
+*/
+
+/*! \macro quint64 Q_UINT64_C(literal)
+ \relates <QtTypes>
+
+ Wraps the unsigned 64-bit integer \a literal in a
+ platform-independent way.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp 9
+
+ \sa quint64, Q_INT64_C(), Q_UINT128_C()
+*/
+
+/*!
+ \macro qint128 Q_INT128_C(literal)
+ \relates <QtTypes>
+ \since 6.6
+
+ Wraps the signed 128-bit integer \a literal in a
+ platform-independent way.
+
+ \note Unlike Q_INT64_C(), this macro is only available in C++, not in C.
+ This is because compilers do not provide these literals as built-ins and C
+ does not have support for user-defined literals.
+
+ \sa qint128, Q_UINT128_C(), Q_INT128_MIN, Q_INT128_MAX, Q_INT64_C(), QT_SUPPORTS_INT128
+*/
+
+/*!
+ \macro quint128 Q_UINT128_C(literal)
+ \relates <QtTypes>
+ \since 6.6
+
+ Wraps the unsigned 128-bit integer \a literal in a
+ platform-independent way.
+
+ \note Unlike Q_UINT64_C(), this macro is only available in C++, not in C.
+ This is because compilers do not provide these literals as built-ins and C
+ does not have support for user-defined literals.
+
+ \sa quint128, Q_INT128_C(), Q_UINT128_MAX, Q_UINT64_C(), QT_SUPPORTS_INT128
+*/
+
+/*!
+ \macro Q_UINT128_MAX
+ \relates <QtTypes>
+ \since 6.6
+
+ This macro expands to a compile-time constant representing the
+ maximum value representable in a \l quint128.
+
+ This macro is available in both C++ and C modes.
+
+ The minimum of \l quint128 is 0 (zero), so a \c{Q_UINT128_MIN} is neither
+ needed nor provided.
+
+ \sa Q_INT128_MAX, quint128, Q_UINT128_C, QT_SUPPORTS_INT128
+*/
+
+/*!
+ \macro Q_INT128_MIN
+ \relates <QtTypes>
+ \since 6.6
+
+ This macro expands to a compile-time constant representing the
+ minimum value representable in a \l qint128.
+
+ This macro is available in both C++ and C modes.
+
+ \sa Q_INT128_MAX, qint128, Q_INT128_C, QT_SUPPORTS_INT128
+*/
+
+/*!
+ \macro Q_INT128_MAX
+ \relates <QtTypes>
+ \since 6.6
+
+ This macro expands to a compile-time constant representing the
+ maximum value representable in a \l qint128.
+
+ This macro is available in both C++ and C modes.
+
+ \sa Q_INT128_MIN, Q_UINT128_MAX, qint128, Q_INT128_C, QT_SUPPORTS_INT128
+*/
+
+// Statically check assumptions about the environment we're running
+// in. The idea here is to error or warn if otherwise implicit Qt
+// assumptions are not fulfilled on new hardware or compilers
+// (if this list becomes too long, consider factoring into a separate file)
+static_assert(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
+static_assert(sizeof(int) == 4, "Qt assumes that int is 32 bits");
+static_assert(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined incorrectly");
+static_assert(sizeof(float) == 4, "Qt assumes that float is 32 bits");
+static_assert(sizeof(char16_t) == 2, "Qt assumes that char16_t is 16 bits");
+static_assert(sizeof(char32_t) == 4, "Qt assumes that char32_t is 32 bits");
+#if defined(Q_OS_WIN)
+static_assert(sizeof(wchar_t) == sizeof(char16_t));
+#endif
+static_assert(std::numeric_limits<int>::radix == 2,
+ "Qt assumes binary integers");
+static_assert((std::numeric_limits<int>::max() + std::numeric_limits<int>::lowest()) == -1,
+ "Qt assumes two's complement integers");
+static_assert(sizeof(wchar_t) == sizeof(char32_t) || sizeof(wchar_t) == sizeof(char16_t),
+ "Qt assumes wchar_t is compatible with either char32_t or char16_t");
+
+// While we'd like to check for __STDC_IEC_559__, as per ISO/IEC 9899:2011
+// Annex F (C11, normative for C++11), there are a few corner cases regarding
+// denormals where GHS compiler is relying hardware behavior that is not IEC
+// 559 compliant. So split the check in several subchecks.
+
+// On GHS the compiler reports std::numeric_limits<float>::is_iec559 as false.
+// This is all right according to our needs.
+#if !defined(Q_CC_GHS)
+static_assert(std::numeric_limits<float>::is_iec559,
+ "Qt assumes IEEE 754 floating point");
+#endif
+
+// Technically, presence of NaN and infinities are implied from the above check,
+// but double checking our environment doesn't hurt...
+static_assert(std::numeric_limits<float>::has_infinity &&
+ std::numeric_limits<float>::has_quiet_NaN,
+ "Qt assumes IEEE 754 floating point");
+
+// is_iec559 checks for ISO/IEC/IEEE 60559:2011 (aka IEEE 754-2008) compliance,
+// but that allows for a non-binary radix. We need to recheck that.
+// Note how __STDC_IEC_559__ would instead check for IEC 60559:1989, aka
+// ANSI/IEEE 754−1985, which specifically implies binary floating point numbers.
+static_assert(std::numeric_limits<float>::radix == 2,
+ "Qt assumes binary IEEE 754 floating point");
+
+// not required by the definition of size_t, but we depend on this
+static_assert(sizeof(size_t) == sizeof(void *), "size_t and a pointer don't have the same size");
+static_assert(sizeof(size_t) == sizeof(qsizetype)); // implied by the definition
+static_assert((std::is_same<qsizetype, qptrdiff>::value));
+static_assert(std::is_same_v<std::size_t, size_t>);
+
+// Check that our own typedefs are not broken.
+static_assert(sizeof(qint8) == 1, "Internal error, qint8 is misdefined");
+static_assert(sizeof(qint16)== 2, "Internal error, qint16 is misdefined");
+static_assert(sizeof(qint32) == 4, "Internal error, qint32 is misdefined");
+static_assert(sizeof(qint64) == 8, "Internal error, qint64 is misdefined");
+#ifdef QT_SUPPORTS_INT128
+static_assert(sizeof(qint128) == 16, "Internal error, qint128 is misdefined");
+#endif
+
+#ifdef QT_SUPPORTS_INT128
+// Standard Library supports for 128-bit integers:
+// Implementation | Version | Note
+// ---------------------|---------|------
+// GNU libstdc++ | 11.1.0 |
+// LLVM libc++ | 3.5 | May change if compiler has __is_integral()
+// MS STL | none |
+
+# if defined(_LIBCPP_VERSION) || (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 11)
+static_assert(std::numeric_limits<quint128>::max() == Q_UINT128_MAX);
+# endif
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qtypes.h b/src/corelib/global/qtypes.h
new file mode 100644
index 0000000000..db9ba38e4c
--- /dev/null
+++ b/src/corelib/global/qtypes.h
@@ -0,0 +1,283 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTYPES_H
+#define QTYPES_H
+
+#include <QtCore/qprocessordetection.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qassert.h>
+
+#ifdef __cplusplus
+# include <cstddef>
+# include <cstdint>
+# if defined(__STDCPP_FLOAT16_T__) && __has_include(<stdfloat>)
+// P1467 implementation - https://wg21.link/p1467
+# include <stdfloat>
+# endif // defined(__STDCPP_FLOAT16_T__) && __has_include(<stdfloat>)
+#else
+# include <assert.h>
+#endif
+
+#if 0
+#pragma qt_class(QtTypes)
+#pragma qt_class(QIntegerForSize)
+#pragma qt_sync_stop_processing
+#endif
+
+/*
+ Useful type definitions for Qt
+*/
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+QT_BEGIN_NAMESPACE
+
+/*
+ Size-dependent types (architecture-dependent byte order)
+
+ Make sure to update QMetaType when changing these typedefs
+*/
+
+typedef signed char qint8; /* 8 bit signed */
+typedef unsigned char quint8; /* 8 bit unsigned */
+typedef short qint16; /* 16 bit signed */
+typedef unsigned short quint16; /* 16 bit unsigned */
+typedef int qint32; /* 32 bit signed */
+typedef unsigned int quint32; /* 32 bit unsigned */
+// Unlike LL / ULL in C++, for historical reasons, we force the
+// result to be of the requested type.
+#ifdef __cplusplus
+# define Q_INT64_C(c) static_cast<long long>(c ## LL) /* signed 64 bit constant */
+# define Q_UINT64_C(c) static_cast<unsigned long long>(c ## ULL) /* unsigned 64 bit constant */
+#else
+# define Q_INT64_C(c) ((long long)(c ## LL)) /* signed 64 bit constant */
+# define Q_UINT64_C(c) ((unsigned long long)(c ## ULL)) /* unsigned 64 bit constant */
+#endif
+typedef long long qint64; /* 64 bit signed */
+typedef unsigned long long quint64; /* 64 bit unsigned */
+
+typedef qint64 qlonglong;
+typedef quint64 qulonglong;
+
+#if defined(__SIZEOF_INT128__) && !defined(QT_NO_INT128)
+# define QT_SUPPORTS_INT128 __SIZEOF_INT128__
+#else
+# undef QT_SUPPORTS_INT128
+#endif
+
+#if defined(QT_SUPPORTS_INT128)
+__extension__ typedef __int128_t qint128;
+__extension__ typedef __uint128_t quint128;
+
+// limits:
+# ifdef __cplusplus /* need to avoid c-style-casts in C++ mode */
+# define QT_C_STYLE_CAST(type, x) static_cast<type>(x)
+# else /* but C doesn't have constructor-style casts */
+# define QT_C_STYLE_CAST(type, x) ((type)(x))
+# endif
+# ifndef Q_UINT128_MAX /* allow qcompilerdetection.h/user override */
+# define Q_UINT128_MAX QT_C_STYLE_CAST(quint128, -1)
+# endif
+# define Q_INT128_MAX QT_C_STYLE_CAST(qint128, Q_UINT128_MAX / 2)
+# define Q_INT128_MIN (-Q_INT128_MAX - 1)
+
+# ifdef __cplusplus
+ namespace QtPrivate::NumberLiterals {
+ namespace detail {
+ template <quint128 accu, int base>
+ constexpr quint128 construct() { return accu; }
+
+ template <quint128 accu, int base, char C, char...Cs>
+ constexpr quint128 construct()
+ {
+ if constexpr (C != '\'') { // ignore digit separators
+ const int digitValue = '0' <= C && C <= '9' ? C - '0' :
+ 'a' <= C && C <= 'z' ? C - 'a' + 10 :
+ 'A' <= C && C <= 'Z' ? C - 'A' + 10 :
+ /* else */ -1 ;
+ static_assert(digitValue >= 0 && digitValue < base,
+ "Invalid character");
+ // accu * base + digitValue <= MAX, but without overflow:
+ static_assert(accu <= (Q_UINT128_MAX - digitValue) / base,
+ "Overflow occurred");
+ return construct<accu * base + digitValue, base, Cs...>();
+ } else {
+ return construct<accu, base, Cs...>();
+ }
+ }
+
+ template <char C, char...Cs>
+ constexpr quint128 parse0xb()
+ {
+ constexpr quint128 accu = 0;
+ if constexpr (C == 'x' || C == 'X')
+ return construct<accu, 16, Cs...>(); // base 16, skip 'x'
+ else if constexpr (C == 'b' || C == 'B')
+ return construct<accu, 2, Cs...>(); // base 2, skip 'b'
+ else
+ return construct<accu, 8, C, Cs...>(); // base 8, include C
+ }
+
+ template <char...Cs>
+ constexpr quint128 parse0()
+ {
+ if constexpr (sizeof...(Cs) == 0) // this was just a literal 0
+ return 0;
+ else
+ return parse0xb<Cs...>();
+ }
+
+ template <char C, char...Cs>
+ constexpr quint128 parse()
+ {
+ if constexpr (C == '0')
+ return parse0<Cs...>(); // base 2, 8, or 16 (or just a literal 0), skip '0'
+ else
+ return construct<0, 10, C, Cs...>(); // initial accu 0, base 10, include C
+ }
+ } // namespace detail
+ template <char...Cs>
+ constexpr quint128 operator""_quint128() noexcept
+ { return QtPrivate::NumberLiterals::detail::parse<Cs...>(); }
+ template <char...Cs>
+ constexpr qint128 operator""_qint128() noexcept
+ { return qint128(QtPrivate::NumberLiterals::detail::parse<Cs...>()); }
+
+ #ifndef Q_UINT128_C // allow qcompilerdetection.h/user override
+ # define Q_UINT128_C(c) ([]{ using namespace QtPrivate::NumberLiterals; return c ## _quint128; }())
+ #endif
+ #ifndef Q_INT128_C // allow qcompilerdetection.h/user override
+ # define Q_INT128_C(c) ([]{ using namespace QtPrivate::NumberLiterals; return c ## _qint128; }())
+ #endif
+
+ } // namespace QtPrivate::NumberLiterals
+# endif // __cplusplus
+#endif // QT_SUPPORTS_INT128
+
+#ifndef __cplusplus
+// In C++ mode, we define below using QIntegerForSize template
+static_assert(sizeof(ptrdiff_t) == sizeof(size_t), "Weird ptrdiff_t and size_t definitions");
+typedef ptrdiff_t qptrdiff;
+typedef ptrdiff_t qsizetype;
+typedef ptrdiff_t qintptr;
+typedef size_t quintptr;
+
+#define PRIdQPTRDIFF "td"
+#define PRIiQPTRDIFF "ti"
+
+#define PRIdQSIZETYPE "td"
+#define PRIiQSIZETYPE "ti"
+
+#define PRIdQINTPTR "td"
+#define PRIiQINTPTR "ti"
+
+#define PRIuQUINTPTR "zu"
+#define PRIoQUINTPTR "zo"
+#define PRIxQUINTPTR "zx"
+#define PRIXQUINTPTR "zX"
+#endif
+
+#if defined(QT_COORD_TYPE)
+typedef QT_COORD_TYPE qreal;
+#else
+typedef double qreal;
+#endif
+
+#if defined(__cplusplus)
+/*
+ quintptr are qptrdiff is guaranteed to be the same size as a pointer, i.e.
+
+ sizeof(void *) == sizeof(quintptr)
+ && sizeof(void *) == sizeof(qptrdiff)
+
+ While size_t and qsizetype are not guaranteed to be the same size as a pointer,
+ they usually are and we do check for that in qtypes.cpp, just to be sure.
+*/
+template <int> struct QIntegerForSize;
+template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qint8 Signed; };
+template <> struct QIntegerForSize<2> { typedef quint16 Unsigned; typedef qint16 Signed; };
+template <> struct QIntegerForSize<4> { typedef quint32 Unsigned; typedef qint32 Signed; };
+template <> struct QIntegerForSize<8> { typedef quint64 Unsigned; typedef qint64 Signed; };
+#if defined(QT_SUPPORTS_INT128)
+template <> struct QIntegerForSize<16> { typedef quint128 Unsigned; typedef qint128 Signed; };
+#endif
+template <class T> struct QIntegerForSizeof: QIntegerForSize<sizeof(T)> { };
+typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Signed qregisterint;
+typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Unsigned qregisteruint;
+typedef QIntegerForSizeof<void *>::Unsigned quintptr;
+typedef QIntegerForSizeof<void *>::Signed qptrdiff;
+typedef qptrdiff qintptr;
+using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
+
+// These custom definitions are necessary as we're not defining our
+// datatypes in terms of the language ones, but in terms of integer
+// types that have the sime size. For instance, on a 32-bit platform,
+// qptrdiff is int, while ptrdiff_t may be aliased to long; therefore
+// using %td to print a qptrdiff would be wrong (and raise -Wformat
+// warnings), although both int and long have same bit size on that
+// platform.
+//
+// We know that sizeof(size_t) == sizeof(void *) == sizeof(qptrdiff).
+#if SIZE_MAX == 0xffffffffULL
+#define PRIuQUINTPTR "u"
+#define PRIoQUINTPTR "o"
+#define PRIxQUINTPTR "x"
+#define PRIXQUINTPTR "X"
+
+#define PRIdQPTRDIFF "d"
+#define PRIiQPTRDIFF "i"
+
+#define PRIdQINTPTR "d"
+#define PRIiQINTPTR "i"
+
+#define PRIdQSIZETYPE "d"
+#define PRIiQSIZETYPE "i"
+#elif SIZE_MAX == 0xffffffffffffffffULL
+#define PRIuQUINTPTR "llu"
+#define PRIoQUINTPTR "llo"
+#define PRIxQUINTPTR "llx"
+#define PRIXQUINTPTR "llX"
+
+#define PRIdQPTRDIFF "lld"
+#define PRIiQPTRDIFF "lli"
+
+#define PRIdQINTPTR "lld"
+#define PRIiQINTPTR "lli"
+
+#define PRIdQSIZETYPE "lld"
+#define PRIiQSIZETYPE "lli"
+#else
+#error Unsupported platform (unknown value for SIZE_MAX)
+#endif
+
+// Define a native float16 type
+namespace QtPrivate {
+#if defined(__STDCPP_FLOAT16_T__)
+# define QFLOAT16_IS_NATIVE 1
+using NativeFloat16Type = std::float16_t;
+#elif defined(Q_CC_CLANG) && defined(__FLT16_MAX__) && 0
+// disabled due to https://github.com/llvm/llvm-project/issues/56963
+# define QFLOAT16_IS_NATIVE 1
+using NativeFloat16Type = decltype(__FLT16_MAX__);
+#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__)
+# define QFLOAT16_IS_NATIVE 1
+# ifdef __ARM_FP16_FORMAT_IEEE
+using NativeFloat16Type = __fp16;
+# else
+using NativeFloat16Type = _Float16;
+# endif
+#else
+# define QFLOAT16_IS_NATIVE 0
+using NativeFloat16Type = void;
+#endif
+} // QtPrivate
+
+#endif // __cplusplus
+
+QT_END_NAMESPACE
+
+#endif // QTYPES_H
diff --git a/src/corelib/global/qversiontagging.cpp b/src/corelib/global/qversiontagging.cpp
index b5e524bf4c..a8191869cc 100644
--- a/src/corelib/global/qversiontagging.cpp
+++ b/src/corelib/global/qversiontagging.cpp
@@ -1,58 +1,43 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qglobal.h"
+#include "qversiontagging.h"
+extern "C" {
#define SYM QT_MANGLE_NAMESPACE(qt_version_tag)
-//#define SSYM QT_STRINGIFY(SYM)
+#define SSYM QT_STRINGIFY(SYM)
+
+// With compilers that have the "alias" attribute, the macro creates a global
+// variable "qt_version_tag_M_m" (M: major, m: minor) as an alias to either
+// qt_version_tag or _qt_version_tag. Everywhere else, we simply create a new
+// global variable qt_version_tag_M_m without aliasing to a single variable.
+//
+// Additionally, on systems using ELF binaries (Linux, FreeBSD, etc.), we
+// create ELF versions by way of the .symver assembly directive[1].
+//
+// Unfortunately, Clang on Darwin systems says it supports the "alias"
+// attribute, but fails when used. That's a Clang bug (as of XCode 12).
+//
+// [1] https://sourceware.org/binutils/docs/as/Symver.html
-#if defined(Q_CC_GNU) && defined(Q_OF_ELF) && !defined(Q_OS_ANDROID)
+#if defined(Q_CC_GNU) && defined(Q_OF_ELF)
# define make_versioned_symbol2(sym, m, n, separator) \
- Q_CORE_EXPORT extern const char sym ## _ ## m ## _ ## n = 0; \
+ Q_CORE_EXPORT extern __attribute__((alias("_" SSYM))) const char sym ## _ ## m ## _ ## n; \
asm(".symver " QT_STRINGIFY(sym) "_" QT_STRINGIFY(m) "_" QT_STRINGIFY(n) ", " \
QT_STRINGIFY(sym) separator "Qt_" QT_STRINGIFY(m) "." QT_STRINGIFY(n))
+
+extern const char QT_MANGLE_NAMESPACE(_qt_version_tag) = 0;
+#elif __has_attribute(alias) && !defined(Q_OS_DARWIN)
+# define make_versioned_symbol2(sym, m, n, separator) \
+ Q_CORE_EXPORT extern __attribute__((alias(SSYM))) const char sym ## _ ## m ## _ ## n
+extern const char SYM = 0;
#else
-# define make_versioned_symbol2(sym, m, n, separator)
+# define make_versioned_symbol2(sym, m, n, separator) \
+ Q_CORE_EXPORT extern const char sym ## _ ## m ## _ ## n = 0;
#endif
#define make_versioned_symbol(sym, m, n, separator) make_versioned_symbol2(sym, m, n, separator)
-extern "C" {
#if QT_VERSION_MINOR > 0
make_versioned_symbol(SYM, QT_VERSION_MAJOR, 0, "@");
#endif
@@ -102,10 +87,15 @@ make_versioned_symbol(SYM, QT_VERSION_MAJOR, 14, "@");
make_versioned_symbol(SYM, QT_VERSION_MAJOR, 15, "@");
#endif
#if QT_VERSION_MINOR > 16
-// We don't expect there will be a Qt 5.17
# error "Please update this file with more Qt versions."
#endif
// the default version:
make_versioned_symbol(SYM, QT_VERSION_MAJOR, QT_VERSION_MINOR, "@@");
}
+
+QT_BEGIN_NAMESPACE
+
+static_assert(std::is_trivially_destructible_v<QtPrivate::QVersionTag>);
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h
index 75c2e9df7e..73faf5b6eb 100644
--- a/src/corelib/global/qversiontagging.h
+++ b/src/corelib/global/qversiontagging.h
@@ -1,88 +1,134 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// qglobal.h includes this header, so keep it outside of our include guards
-#include <QtCore/qglobal.h>
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#if !defined(QVERSIONTAGGING_H)
#define QVERSIONTAGGING_H
+#include <QtCore/qcompilerdetection.h>
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtversionchecks.h>
+#include <QtCore/qtypes.h>
+
QT_BEGIN_NAMESPACE
/*
- * Ugly hack warning and explanation:
+ * Explanation
+ *
+ * This file causes all libraries, plugins, and applications that #include this
+ * file to automatically pull in a symbol found in QtCore that encodes the
+ * current Qt version number at the time of compilation. The relocation is
+ * designed so that it's impossible for the dynamic linker to perform lazy
+ * binding. Instead, it must resolve at load time or fail. That way, attempting
+ * to load such a library or plugin while an older QtCore is loaded will fail.
+ * Similarly, if an older QtCore is found when launching an application, the
+ * application will fail to launch.
*
- * This file causes all ELF modules, be they libraries or applications, to use the
- * qt_version_tag symbol that is present in QtCore. Such symbol is versioned,
- * so the linker will automatically pull the current Qt version and add it to
- * the ELF header of the library/application. The assembly produces one section
- * called ".qtversion" containing two 32-bit values. The first is a
- * relocation to the qt_version_tag symbol (which is what causes the ELF
- * version to get used). The second value is the current Qt version at the time
- * of compilation.
+ * It's also possible to inspect which version is required by decoding the
+ * .qtversion section. The second pointer-sized variable is the required
+ * version, for example, for Qt 6.4.1:
+ *
+ * Hex dump of section [18] '.qtversion', 16 bytes at offset 0x1ee48:
+ * 0x00000000 b0ffffff ffffffff 01040600 00000000 ................
+ * ^^^^^^^^ ^^^^^^^^
*
* There will only be one copy of the section in the output library or application.
+ *
+ * This functionality can be disabled by defining QT_NO_VERSION_TAGGING. It's
+ * disabled if Qt was built statically.
+ *
+ * Windows notes:
+ *
+ * On Windows, the address of a __declspec(dllimport) variable is not a
+ * constant expression, unlike Unix systems. So we instead use the address of
+ * the import variable, which is created by prefixing the external name with
+ * "__imp_". Using that variable causes an import of the corresponding symbol
+ * from QtCore DLL.
+ *
+ * With MinGW (GCC and Clang), we use a C++17 inline variable, so the compiler
+ * and linker automatically merge the variables. The "used" __attribute__
+ * tells the compiler to always emit that variable, whether it's used or not.
+ *
+ * MSVC has no equivalent to that attribute, so instead we create an extern
+ * const variable and tell the linker to merge them all via
+ * __declspec(selectany).
+ *
+ * Unix notes:
+ *
+ * On Unix, we use the same C++17 inline variable solution as MinGW, but we
+ * don't need the "__imp_" trick.
+ *
+ * Additionally, on ELF systems like Linux and FreeBSD, the symbol in question
+ * is simply "qt_version_tag" in both QtCore and in this ELF module, but it
+ * has an ELF version attached to it (see qversiontagging.cpp and
+ * QtFlagHandlingHelpers.cmake). That way, the error message from the dynamic
+ * linker will say it can't find version "Qt_6.x".
*/
-#if defined(QT_BUILD_CORE_LIB) || defined(QT_BOOTSTRAPPED) || defined(QT_NO_VERSION_TAGGING) || defined(QT_STATIC)
+namespace QtPrivate {
+struct QVersionTag
+{
+ const void *symbol;
+ quintptr version;
+ constexpr QVersionTag(const void *sym, int currentVersion = QT_VERSION)
+ : symbol(sym), version(currentVersion)
+ {}
+};
+}
+
+#if !defined(QT_NO_VERSION_TAGGING) && (defined(QT_BUILD_CORE_LIB) || defined(QT_BOOTSTRAPPED) || defined(QT_STATIC))
// don't make tags in QtCore, bootstrapped systems or if the user asked not to
-#elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID)
-# if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL))
-# if defined(Q_PROCESSOR_X86_64) && QT_POINTER_SIZE == 8 // x86-64 64-bit
-# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
-# else // x86 or x86-64 32-bit (x32)
-# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
-# endif
-# define QT_VERSION_TAG(sym) \
- asm ( \
- ".section .qtversion, \"aG\", @progbits, " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) ", comdat\n" \
- ".align 8\n" \
- QT_VERSION_TAG_RELOC(sym) \
- ".long " QT_STRINGIFY(QT_VERSION) "\n" \
- ".align 8\n" \
- ".previous" \
- )
+# define QT_NO_VERSION_TAGGING
+#endif
+
+#if defined(Q_OS_WIN)
+# ifdef Q_PROCESSOR_X86_32
+// 32-bit x86 convention does prepend a _
+# define QT_MANGLE_IMPORT_PREFIX _imp__
+# else
+// Calling convention on other architectures does not prepend a _
+# define QT_MANGLE_IMPORT_PREFIX __imp_
+# endif
+# if defined(Q_CC_MSVC_ONLY)
+# pragma section(".qtversion",read,shared)
+# define QT_VERSION_TAG_SECTION __declspec(allocate(".qtversion"))
+# define QT_VERSION_TAG_ATTRIBUTE __declspec(selectany) extern const
+# else
+# define QT_VERSION_TAG_ATTRIBUTE __attribute__((used)) constexpr inline
+# endif
+# define QT_VERSION_TAG2(sym, imp) \
+ extern "C" const char * const imp; \
+ QT_VERSION_TAG_ATTRIBUTE QT_VERSION_TAG_SECTION QtPrivate::QVersionTag sym ## _used(&imp)
+# define QT_VERSION_TAG(sym, imp) QT_VERSION_TAG2(sym, imp)
+#elif defined(Q_CC_GNU) && __has_attribute(used)
+# ifdef Q_OS_DARWIN
+# define QT_VERSION_TAG_SECTION __attribute__((section("__DATA,.qtversion")))
# endif
+# define QT_VERSION_TAG_ATTRIBUTE __attribute__((visibility("hidden"), used))
+# define QT_VERSION_TAG2(sym, imp) \
+ extern "C" Q_DECL_IMPORT const char sym; \
+ QT_VERSION_TAG_ATTRIBUTE QT_VERSION_TAG_SECTION constexpr inline QtPrivate::QVersionTag sym ## _use(&sym)
+# define QT_VERSION_TAG(sym, imp) QT_VERSION_TAG2(sym, imp)
#endif
-#if defined(QT_VERSION_TAG)
-QT_VERSION_TAG(qt_version_tag);
+#ifdef Q_OF_ELF
+# define QT_VERSION_TAG_SYMBOL(prefix, sym, m, n) sym
+#else
+# define QT_VERSION_TAG_SYMBOL2(prefix, sym, m, n) prefix ## sym ## _ ## m ## _ ## n
+# define QT_VERSION_TAG_SYMBOL(prefix, sym, m, n) QT_VERSION_TAG_SYMBOL2(prefix, sym, m, n)
+#endif
+
+#if defined(QT_VERSION_TAG) && !defined(QT_NO_VERSION_TAGGING)
+# ifndef QT_VERSION_TAG_SECTION
+# define QT_VERSION_TAG_SECTION __attribute__((section(".qtversion")))
+# endif
+# define QT_MANGLED_VERSION_TAG_IMPORT QT_VERSION_TAG_SYMBOL(QT_MANGLE_IMPORT_PREFIX, QT_MANGLE_NAMESPACE(qt_version_tag), QT_VERSION_MAJOR, QT_VERSION_MINOR)
+# define QT_MANGLED_VERSION_TAG QT_VERSION_TAG_SYMBOL(, QT_MANGLE_NAMESPACE(qt_version_tag), QT_VERSION_MAJOR, QT_VERSION_MINOR)
+
+QT_VERSION_TAG(QT_MANGLED_VERSION_TAG, QT_MANGLED_VERSION_TAG_IMPORT);
+
+# undef QT_MANGLED_VERSION_TAG
+# undef QT_MANGLED_VERSION_TAG_IMPORT
+# undef QT_VERSION_TAG_SECTION
#endif
QT_END_NAMESPACE
diff --git a/src/corelib/global/qvolatile_p.h b/src/corelib/global/qvolatile_p.h
index 211cb3d90c..36787ecd87 100644
--- a/src/corelib/global/qvolatile_p.h
+++ b/src/corelib/global/qvolatile_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QVOLATILE_P_H
#define QVOLATILE_P_H
@@ -51,7 +15,7 @@
// We mean it.
//
-#include <QtCore/qglobal.h>
+#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/global/qxpfunctional.h b/src/corelib/global/qxpfunctional.h
new file mode 100644
index 0000000000..cbeef8b293
--- /dev/null
+++ b/src/corelib/global/qxpfunctional.h
@@ -0,0 +1,195 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef QXPFUNCTIONAL_H
+#define QXPFUNCTIONAL_H
+
+#include <QtCore/qglobal.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+#include <QtCore/q23functional.h>
+#include <QtCore/q20type_traits.h>
+#include <utility>
+
+QT_BEGIN_NAMESPACE
+
+namespace qxp {
+// like P0792r9's function_ref:
+
+// [func.wrap.ref], non-owning wrapper
+template<class... S> class function_ref; // not defined
+
+// template<class R, class... ArgTypes>
+// class function_ref<R(ArgTypes...) cv noexcept(noex)>; // see below
+//
+// [func.wrap.ref.general]
+// The header provides partial specializations of function_ref for each combination
+// of the possible replacements of the placeholders cv and noex where:
+// - cv is either const or empty.
+// - noex is either true or false.
+
+namespace detail {
+
+template <typename T>
+using if_function = std::enable_if_t<std::is_function_v<T>, bool>;
+template <typename T>
+using if_non_function = std::enable_if_t<!std::is_function_v<T>, bool>;
+
+template <typename From, typename To>
+using copy_const_t = std::conditional_t<
+ std::is_const_v<From>,
+ std::add_const_t<To>,
+ To
+ >;
+
+template <class Const>
+union BoundEntityType {
+ template <typename F, if_function<F> = true>
+ explicit constexpr BoundEntityType(F *f)
+ : fun(reinterpret_cast<QFunctionPointer>(f)) {}
+ template <typename T, if_non_function<T> = true>
+ explicit constexpr BoundEntityType(T *t)
+ : obj(static_cast<Const*>(t)) {}
+ Const *obj;
+ QFunctionPointer fun;
+};
+
+template <bool noex, class Const, class R, class... ArgTypes>
+class function_ref_base
+{
+protected:
+ ~function_ref_base() = default;
+
+ using BoundEntityType = detail::BoundEntityType<Const>;
+
+ template <typename... Ts>
+ using is_invocable_using = std::conditional_t<
+ noex,
+ std::is_nothrow_invocable_r<R, Ts..., ArgTypes...>,
+ std::is_invocable_r<R, Ts..., ArgTypes...>
+ >;
+
+ using ThunkPtr = R(*)(BoundEntityType, ArgTypes&&...) noexcept(noex);
+
+ BoundEntityType m_bound_entity;
+ ThunkPtr m_thunk_ptr;
+
+public:
+ template<
+ class F,
+ std::enable_if_t<std::conjunction_v<
+ std::is_function<F>,
+ is_invocable_using<F>
+ >, bool> = true
+ >
+ Q_IMPLICIT function_ref_base(F* f) noexcept
+ : m_bound_entity(f),
+ m_thunk_ptr([](BoundEntityType ctx, ArgTypes&&... args) noexcept(noex) -> R {
+ return q23::invoke_r<R>(reinterpret_cast<F*>(ctx.fun),
+ std::forward<ArgTypes>(args)...);
+ })
+ {}
+
+ template<
+ class F,
+ std::enable_if_t<std::conjunction_v<
+ std::negation<std::is_same<q20::remove_cvref_t<F>, function_ref_base>>,
+#ifdef Q_OS_VXWORKS
+ // The VxWorks compiler is trying to match this ctor against
+ // qxp::function_ref in lieu of using the copy-constructor, so ban
+ // matching against the equivalent qxp::function_ref here.
+ // This doesn't change anything on other platforms, so to save
+ // on compile-speed, enable it only for VxWorks:
+ std::negation<
+ std::is_same<
+ q20::remove_cvref_t<F>,
+ std::conditional_t<
+ std::is_const_v<Const>,
+ qxp::function_ref<R(ArgTypes...) const noexcept(noex)>,
+ qxp::function_ref<R(ArgTypes...) noexcept(noex)>
+ >
+ >
+ >,
+#endif // Q_OS_VXWORKS
+ std::negation<std::is_member_pointer<std::remove_reference_t<F>>>,
+ is_invocable_using<copy_const_t<Const, std::remove_reference_t<F>>&>
+ >, bool> = true
+ >
+ Q_IMPLICIT constexpr function_ref_base(F&& f) noexcept
+ : m_bound_entity(std::addressof(f)),
+ m_thunk_ptr([](BoundEntityType ctx, ArgTypes&&... args) noexcept(noex) -> R {
+ using That = copy_const_t<Const, std::remove_reference_t<F>>;
+ return q23::invoke_r<R>(*static_cast<That*>(ctx.obj),
+ std::forward<ArgTypes>(args)...);
+ })
+ {}
+
+protected:
+ template <
+ class T,
+ std::enable_if_t<std::negation_v<
+ std::disjunction<
+ std::is_same<T, function_ref_base>,
+ std::is_pointer<T>
+ >
+ >, bool> = true
+ >
+ function_ref_base& operator=(T) = delete;
+
+ // Invocation [func.wrap.ref.inv]
+ R operator()(ArgTypes... args) const noexcept(noex)
+ {
+ return m_thunk_ptr(m_bound_entity, std::forward<ArgTypes>(args)...);
+ }
+
+};
+
+} // namespace detail
+
+#define QT_SPECIALIZE_FUNCTION_REF(cv, noex) \
+ template<class R, class... ArgTypes> \
+ class function_ref<R(ArgTypes...) cv noexcept( noex )> \
+ : private detail::function_ref_base< noex , cv void, R, ArgTypes...> \
+ { \
+ using base = detail::function_ref_base< noex , cv void, R, ArgTypes...>; \
+ \
+ public: \
+ using base::base; \
+ using base::operator(); \
+ } \
+ /* end */
+
+QT_SPECIALIZE_FUNCTION_REF( , false);
+QT_SPECIALIZE_FUNCTION_REF(const, false);
+QT_SPECIALIZE_FUNCTION_REF( , true );
+QT_SPECIALIZE_FUNCTION_REF(const, true );
+
+#undef QT_SPECIALIZE_FUNCTION_REF
+
+// deduction guides [func.wrap.ref.deduct]
+
+template <
+ class F,
+ detail::if_function<F> = true
+>
+function_ref(F*) -> function_ref<F>;
+
+} // namespace qxp
+
+QT_END_NAMESPACE
+
+#endif /* QXPFUNCTIONAL_H */
diff --git a/src/corelib/global/qxptype_traits.h b/src/corelib/global/qxptype_traits.h
new file mode 100644
index 0000000000..d1641e1d0d
--- /dev/null
+++ b/src/corelib/global/qxptype_traits.h
@@ -0,0 +1,121 @@
+// Copyright (C) 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>, Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QXPTYPE_TRAITS_H
+#define QXPTYPE_TRAITS_H
+
+#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qcompilerdetection.h>
+
+#include <type_traits>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. Types and functions defined in this
+// file can reliably be replaced by their std counterparts, once available.
+// You may use these definitions in your own code, but be aware that we
+// will remove them once Qt depends on the C++ version that supports
+// them in namespace std. There will be NO deprecation warning, the
+// definitions will JUST go away.
+//
+// If you can't agree to these terms, don't use these definitions!
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+// like std::experimental::{nonesuch,is_detected/_v}(LFTSv2)
+namespace qxp {
+
+struct nonesuch {
+ ~nonesuch() = delete;
+ nonesuch(const nonesuch&) = delete;
+ void operator=(const nonesuch&) = delete;
+};
+
+namespace _detail {
+ template <typename T, typename Void, template <typename...> class Op, typename...Args>
+ struct detector {
+ using value_t = std::false_type;
+ using type = T;
+ };
+ template <typename T, template <typename...> class Op, typename...Args>
+ struct detector<T, std::void_t<Op<Args...>>, Op, Args...> {
+ using value_t = std::true_type;
+ using type = Op<Args...>;
+ };
+} // namespace _detail
+
+template <template <typename...> class Op, typename...Args>
+using is_detected = typename _detail::detector<qxp::nonesuch, void, Op, Args...>::value_t;
+
+template <template <typename...> class Op, typename...Args>
+constexpr inline bool is_detected_v = is_detected<Op, Args...>::value;
+
+
+// qxp::is_virtual_base_of_v<B, D> is true if and only if B is a virtual base class of D.
+// Just like is_base_of:
+// * only works on complete types;
+// * B and D must be class types;
+// * ignores cv-qualifications;
+// * B may be inaccessibile.
+
+namespace _detail {
+ // Check that From* can be converted to To*, ignoring accessibility.
+ // This can be done using a C cast (see [expr.cast]/4).
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wold-style-cast")
+QT_WARNING_DISABLE_CLANG("-Wold-style-cast")
+ template <typename From, typename To>
+ using is_virtual_base_conversion_test = decltype(
+ (To *)std::declval<From *>()
+ );
+QT_WARNING_POP
+
+ template <typename Base, typename Derived, typename = void>
+ struct is_virtual_base_of : std::false_type {};
+
+ template <typename Base, typename Derived>
+ struct is_virtual_base_of<
+ Base, Derived,
+ std::enable_if_t<
+ std::conjunction_v<
+ // Base is a base class of Derived.
+ std::is_base_of<Base, Derived>,
+
+ // Check that Derived* can be converted to Base*, ignoring
+ // accessibility. If this is possible, then Base is
+ // an unambiguous base of Derived (=> virtual bases are always
+ // unambiguous).
+ qxp::is_detected<is_virtual_base_conversion_test, Derived, Base>,
+
+ // Check that Base* can _not_ be converted to Derived*,
+ // again ignoring accessibility. This seals the deal:
+ // if this conversion cannot happen, it means that Base is an
+ // ambiguous base and/or it is a virtual base.
+ // But we have already established that Base is an unambiguous
+ // base, hence: Base is a virtual base.
+ std::negation<
+ qxp::is_detected<is_virtual_base_conversion_test, Base, Derived>
+ >
+ >
+ >
+ > : std::true_type {};
+}
+
+template <typename Base, typename Derived>
+using is_virtual_base_of = _detail::is_virtual_base_of<std::remove_cv_t<Base>, std::remove_cv_t<Derived>>;
+
+template <typename Base, typename Derived>
+constexpr inline bool is_virtual_base_of_v = is_virtual_base_of<Base, Derived>::value;
+
+} // namespace qxp
+
+QT_END_NAMESPACE
+
+#endif // QXPTYPE_TRAITS_H
+