diff options
Diffstat (limited to 'src/corelib/tools')
84 files changed, 2144 insertions, 3988 deletions
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index 11e4d9da39..f72cd669cb 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.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 QALGORITHMS_H #define QALGORITHMS_H @@ -78,7 +42,7 @@ namespace QAlgorithmsPrivate { # if (defined __apple_build_version__ && __clang_major__ >= 7) || (Q_CC_CLANG >= 307) # define QT_HAS_CONSTEXPR_BUILTINS # endif -#elif defined(Q_CC_MSVC) && !defined(Q_CC_INTEL) && !defined(Q_PROCESSOR_ARM) +#elif defined(Q_CC_MSVC) && !defined(Q_PROCESSOR_ARM) # define QT_HAS_CONSTEXPR_BUILTINS #elif defined(Q_CC_GNU) # define QT_HAS_CONSTEXPR_BUILTINS @@ -333,7 +297,7 @@ constexpr inline uint qConstexprCountTrailingZeroBits(quint64 v) noexcept constexpr inline uint qConstexprCountTrailingZeroBits(quint8 v) noexcept { unsigned int c = 8; // c will be the number of zero bits on the right - v &= -signed(v); + v &= quint8(-signed(v)); if (v) c--; if (v & 0x0000000F) c -= 4; if (v & 0x00000033) c -= 2; @@ -344,7 +308,7 @@ constexpr inline uint qConstexprCountTrailingZeroBits(quint8 v) noexcept constexpr inline uint qConstexprCountTrailingZeroBits(quint16 v) noexcept { unsigned int c = 16; // c will be the number of zero bits on the right - v &= -signed(v); + v &= quint16(-signed(v)); if (v) c--; if (v & 0x000000FF) c -= 8; if (v & 0x00000F0F) c -= 4; diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc index 4249cad72e..4a9c03a43c 100644 --- a/src/corelib/tools/qalgorithms.qdoc +++ b/src/corelib/tools/qalgorithms.qdoc @@ -1,32 +1,9 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \headerfile <QtAlgorithms> + \inmodule QtCore \title Generic Algorithms \ingroup funclists \keyword generic algorithms diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index 9a52898716..b1634d61b5 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -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 #include <QtCore/qarraydata.h> #include <QtCore/private/qnumeric_p.h> diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index e4250cce47..766596fe18 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** 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 QARRAYDATA_H #define QARRAYDATA_H diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 9570ab28b8..afd1a264bd 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -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) 2020 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 QARRAYDATAOPS_H #define QARRAYDATAOPS_H @@ -44,7 +8,7 @@ #include <QtCore/qarraydata.h> #include <QtCore/qcontainertools_impl.h> -#include <algorithm> +#include <memory> #include <new> #include <string.h> #include <utility> @@ -911,17 +875,13 @@ public: Q_ASSERT(distance >= 0 && distance <= this->allocatedCapacity() - this->size); Q_UNUSED(distance); -#if __cplusplus >= 202002L - constexpr bool canUseCopyAppend = std::conjunction_v< - std::is_convertible< - typename std::iterator_traits<It>::iterator_category, - std::contiguous_iterator_tag - >, - std::is_same< +#if __cplusplus >= 202002L && defined(__cpp_concepts) && defined(__cpp_lib_concepts) + constexpr bool canUseCopyAppend = + std::contiguous_iterator<It> && + std::is_same_v< std::remove_cv_t<typename std::iterator_traits<It>::value_type>, T - > - >; + >; if constexpr (canUseCopyAppend) { this->copyAppend(std::to_address(b), std::to_address(e)); } else diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index 4d83b890cc..3e1c2c11e4 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.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 QARRAYDATAPOINTER_H #define QARRAYDATAPOINTER_H @@ -149,9 +113,9 @@ public: void swap(QArrayDataPointer &other) noexcept { - qSwap(d, other.d); - qSwap(ptr, other.ptr); - qSwap(size, other.size); + qt_ptr_swap(d, other.d); + qt_ptr_swap(ptr, other.ptr); + std::swap(size, other.size); } void clear() noexcept(std::is_nothrow_destructible<T>::value) @@ -168,6 +132,28 @@ public: /*! \internal + Reinterprets the data of this QArrayDataPointer to type X. It's the + caller's responsibility to ensure that the data contents are valid and + properly aligned, particularly if T and X are not trivial types (i.e, + don't do that). The current size is kept and the allocated capacity is + updated to account for the difference in the element type's size. + + This is used in QString::fromLatin1 to perform in-place conversion of + QString to QByteArray. + */ + template <typename X> QArrayDataPointer<X> reinterpreted() && + { + if (sizeof(T) != sizeof(X)) { + Q_ASSERT(!d->isShared()); + d->alloc = d->alloc * sizeof(T) / sizeof(X); + } + auto od = reinterpret_cast<QTypedArrayData<X> *>(std::exchange(d, nullptr)); + auto optr = reinterpret_cast<X *>(std::exchange(ptr, nullptr)); + return { od, optr, std::exchange(size, 0) }; + } + + /*! \internal + Detaches this (optionally) and grows to accommodate the free space for \a n elements at the required side. The side is determined from \a pos. @@ -393,7 +379,7 @@ public: }; template <class T> -inline void qSwap(QArrayDataPointer<T> &p1, QArrayDataPointer<T> &p2) noexcept +inline void swap(QArrayDataPointer<T> &p1, QArrayDataPointer<T> &p2) noexcept { p1.swap(p2); } diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index 18ce7035d9..ecd12d095c 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** 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 #include "qbitarray.h" #include <qalgorithms.h> diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h index 75d680dc84..8e19725339 100644 --- a/src/corelib/tools/qbitarray.h +++ b/src/corelib/tools/qbitarray.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 QBITARRAY_H #define QBITARRAY_H @@ -62,7 +26,7 @@ public: inline QBitArray(QBitArray &&other) noexcept : d(std::move(other.d)) {} QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QBitArray) - inline void swap(QBitArray &other) noexcept { qSwap(d, other.d); } + void swap(QBitArray &other) noexcept { d.swap(other.d); } inline qsizetype size() const { return (d.size() << 3) - *d.constData(); } inline qsizetype count() const { return (d.size() << 3) - *d.constData(); } diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h index 8a341c8555..952b88bafb 100644 --- a/src/corelib/tools/qcache.h +++ b/src/corelib/tools/qcache.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 QCACHE_H #define QCACHE_H @@ -64,8 +28,8 @@ class QCache } Value &operator=(Value &&other) noexcept { - qSwap(t, other.t); - qSwap(cost, other.cost); + qt_ptr_swap(t, other.t); + std::swap(cost, other.cost); return *this; } ~Value() { delete t; } @@ -109,23 +73,6 @@ class QCache { value = Value(o, cost); } - static Node create(const Key &k, Value &&t) noexcept(std::is_nothrow_move_assignable_v<Key> && std::is_nothrow_move_assignable_v<T>) - { - return Node(k, std::move(t)); - } - void replace(const Value &t) noexcept(std::is_nothrow_assignable_v<T, T>) - { - value = t; - } - void replace(Value &&t) noexcept(std::is_nothrow_move_assignable_v<T>) - { - value = std::move(t); - } - Value takeValue() noexcept(std::is_nothrow_move_constructible_v<T>) - { - return std::move(value); - } - bool valuesEqual(const Node *other) const { return value == other->value; } Node(Node &&other) : Chain(other), @@ -155,11 +102,13 @@ class QCache n->prev->next = n->next; n->next->prev = n->prev; total -= n->value.cost; - auto it = d.find(n->key); + auto it = d.findBucket(n->key); d.erase(it); } T *relink(const Key &key) const noexcept { + if (isEmpty()) + return nullptr; Node *n = d.findNode(key); if (!n) return nullptr; @@ -179,11 +128,9 @@ class QCache void trim(qsizetype m) noexcept(std::is_nothrow_destructible_v<Node>) { - Chain *n = chain.prev; - while (n != &chain && total > m) { - Node *u = static_cast<Node *>(n); - n = n->prev; - unlink(u); + while (chain.prev != &chain && total > m) { + Node *n = static_cast<Node *>(chain.prev); + unlink(n); } } @@ -269,11 +216,13 @@ public: } inline bool contains(const Key &key) const noexcept { - return d.findNode(key) != nullptr; + return !isEmpty() && d.findNode(key) != nullptr; } bool remove(const Key &key) noexcept(std::is_nothrow_destructible_v<Node>) { + if (isEmpty()) + return false; Node *n = d.findNode(key); if (!n) { return false; @@ -285,6 +234,8 @@ public: T *take(const Key &key) noexcept(std::is_nothrow_destructible_v<Key>) { + if (isEmpty()) + return nullptr; Node *n = d.findNode(key); if (!n) return nullptr; diff --git a/src/corelib/tools/qcache.qdoc b/src/corelib/tools/qcache.qdoc index f9b1ffa8f4..9a4b86aa67 100644 --- a/src/corelib/tools/qcache.qdoc +++ b/src/corelib/tools/qcache.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \class QCache diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp index bfb6f68f08..f1816753e6 100644 --- a/src/corelib/tools/qcommandlineoption.cpp +++ b/src/corelib/tools/qcommandlineoption.cpp @@ -1,43 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org> -** Copyright (C) 2013 David Faure <faure@kde.org> -** 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) 2013 Laszlo Papp <lpapp@kde.org> +// Copyright (C) 2013 David Faure <faure@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qcommandlineoption.h" @@ -261,11 +225,11 @@ namespace { return warn("be empty"); const QChar c = name.at(0); - if (Q_UNLIKELY(c == QLatin1Char('-'))) + if (Q_UNLIKELY(c == u'-')) return warn("start with a '-'"); - if (Q_UNLIKELY(c == QLatin1Char('/'))) + if (Q_UNLIKELY(c == u'/')) return warn("start with a '/'"); - if (Q_UNLIKELY(name.contains(QLatin1Char('=')))) + if (Q_UNLIKELY(name.contains(u'='))) return warn("contain a '='"); return false; diff --git a/src/corelib/tools/qcommandlineoption.h b/src/corelib/tools/qcommandlineoption.h index 2e7d8fd9da..63c90a4005 100644 --- a/src/corelib/tools/qcommandlineoption.h +++ b/src/corelib/tools/qcommandlineoption.h @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org> -** 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) 2013 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QCOMMANDLINEOPTION_H #define QCOMMANDLINEOPTION_H @@ -75,7 +39,7 @@ public: QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QCommandLineOption) void swap(QCommandLineOption &other) noexcept - { qSwap(d, other.d); } + { d.swap(other.d); } QStringList names() const; diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index f294449b5f..e771877265 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -1,48 +1,13 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org> -** Copyright (C) 2013 David Faure <faure@kde.org> -** 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) 2013 Laszlo Papp <lpapp@kde.org> +// Copyright (C) 2013 David Faure <faure@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qcommandlineparser.h" #include <qcoreapplication.h> #include <private/qcoreapplication_p.h> #include <qhash.h> +#include <qvarlengtharray.h> #include <qlist.h> #include <qdebug.h> #if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) @@ -53,6 +18,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + extern void Q_CORE_EXPORT qt_call_post_routines(); typedef QHash<QString, int> NameHash_t; @@ -592,7 +559,7 @@ static void showParserMessage(const QString &message, MessageType type) void QCommandLineParser::process(const QStringList &arguments) { if (!d->parse(arguments)) { - showParserMessage(QCoreApplication::applicationName() + QLatin1String(": ") + errorText() + QLatin1Char('\n'), ErrorMessage); + showParserMessage(QCoreApplication::applicationName() + ": "_L1 + errorText() + u'\n', ErrorMessage); qt_call_post_routines(); ::exit(EXIT_FAILURE); } @@ -1017,8 +984,8 @@ QStringList QCommandLineParser::unknownOptionNames() const */ Q_NORETURN void QCommandLineParser::showVersion() { - showParserMessage(QCoreApplication::applicationName() + QLatin1Char(' ') - + QCoreApplication::applicationVersion() + QLatin1Char('\n'), + showParserMessage(QCoreApplication::applicationName() + u' ' + + QCoreApplication::applicationVersion() + u'\n', UsageMessage); qt_call_post_routines(); ::exit(EXIT_SUCCESS); @@ -1059,8 +1026,8 @@ QString QCommandLineParser::helpText() const static QString wrapText(const QString &names, int optionNameMaxWidth, const QString &description) { - const QLatin1Char nl('\n'); - const QLatin1String indentation(" "); + const auto nl = u'\n'; + const auto indentation = " "_L1; // In case the list of option names is very long, wrap it as well int nameIndex = 0; @@ -1102,7 +1069,7 @@ static QString wrapText(const QString &names, int optionNameMaxWidth, const QStr if (breakAt != -1) { const int numChars = breakAt - lineStart; //qDebug() << "breakAt=" << description.at(breakAt) << "breakAtSpace=" << breakAtSpace << lineStart << "to" << breakAt << description.mid(lineStart, numChars); - text += indentation + nextNameSection().leftJustified(optionNameMaxWidth) + QLatin1Char(' '); + text += indentation + nextNameSection().leftJustified(optionNameMaxWidth) + u' '; text += QStringView{description}.mid(lineStart, numChars) + nl; x = 0; lastBreakable = -1; @@ -1131,9 +1098,9 @@ QString QCommandLineParserPrivate::helpText(bool includeQtOptions) const if (includeQtOptions && qApp) qApp->d_func()->addQtOptions(&options); if (!options.isEmpty()) - usage += QLatin1Char(' ') + QCommandLineParser::tr("[options]"); + usage += u' ' + QCommandLineParser::tr("[options]"); for (const PositionalArgumentDefinition &arg : positionalArgumentDefinitions) - usage += QLatin1Char(' ') + arg.syntax; + usage += u' ' + arg.syntax; text += QCommandLineParser::tr("Usage: %1").arg(usage) + nl; if (!description.isEmpty()) text += description + nl; @@ -1150,13 +1117,13 @@ QString QCommandLineParserPrivate::helpText(bool includeQtOptions) const QString optionNamesString; for (const QString &optionName : optionNames) { const int numDashes = optionName.length() == 1 ? 1 : 2; - optionNamesString += QLatin1String("--", numDashes) + optionName + QLatin1String(", "); + optionNamesString += QLatin1StringView("--", numDashes) + optionName + ", "_L1; } if (!optionNames.isEmpty()) optionNamesString.chop(2); // remove trailing ", " const auto valueName = option.valueName(); if (!valueName.isEmpty()) - optionNamesString += QLatin1String(" <") + valueName + QLatin1Char('>'); + optionNamesString += " <"_L1 + valueName + u'>'; optionNameList.append(optionNamesString); longestOptionNameString = qMax(longestOptionNameString, optionNamesString.length()); } diff --git a/src/corelib/tools/qcommandlineparser.h b/src/corelib/tools/qcommandlineparser.h index 4584c384cc..332a2f9568 100644 --- a/src/corelib/tools/qcommandlineparser.h +++ b/src/corelib/tools/qcommandlineparser.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org> -** 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) 2013 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QCOMMANDLINEPARSER_H #define QCOMMANDLINEPARSER_H diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h index 673e3c3de2..c5e1ba2b62 100644 --- a/src/corelib/tools/qcontainerfwd.h +++ b/src/corelib/tools/qcontainerfwd.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 #include <QtCore/qglobal.h> diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h index 2053de6408..4a5f9f184f 100644 --- a/src/corelib/tools/qcontainertools_impl.h +++ b/src/corelib/tools/qcontainertools_impl.h @@ -1,43 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> -** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> -** 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) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +// 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 #if 0 #pragma qt_sync_skip_header_check @@ -74,6 +38,15 @@ static constexpr bool q_points_into_range(const T *p, const T *b, const T *e, } template <typename T, typename N> +void q_uninitialized_move_if_noexcept_n(T* first, N n, T* out) +{ + if constexpr (std::is_nothrow_move_constructible_v<T> || !std::is_copy_constructible_v<T>) + std::uninitialized_move_n(first, n, out); + else + std::uninitialized_copy_n(first, n, out); +} + +template <typename T, typename N> void q_uninitialized_relocate_n(T* first, N n, T* out) { if constexpr (QTypeInfo<T>::isRelocatable) { @@ -83,7 +56,7 @@ void q_uninitialized_relocate_n(T* first, N n, T* out) n * sizeof(T)); } } else { - std::uninitialized_move_n(first, n, out); + q_uninitialized_move_if_noexcept_n(first, n, out); if constexpr (QTypeInfo<T>::isComplex) std::destroy_n(first, n); } @@ -275,25 +248,52 @@ using IfIsNotSame = template<typename T, typename U> using IfIsNotConvertible = typename std::enable_if<!std::is_convertible<T, U>::value, bool>::type; -template <typename Container, typename T> -auto sequential_erase(Container &c, const T &t) +template <typename Container, typename Predicate> +auto sequential_erase_if(Container &c, Predicate &pred) { - // avoid a detach in case there is nothing to remove + // This is remove_if() modified to perform the find_if step on + // const_iterators to avoid shared container detaches if nothing needs to + // be removed. We cannot run remove_if after find_if: doing so would apply + // the predicate to the first matching element twice! + const auto cbegin = c.cbegin(); const auto cend = c.cend(); - const auto t_it = std::find(cbegin, cend, t); + const auto t_it = std::find_if(cbegin, cend, pred); auto result = std::distance(cbegin, t_it); if (result == c.size()) return result - result; // `0` of the right type + // now detach: const auto e = c.end(); - const auto it = std::remove(std::next(c.begin(), result), e, t); - result = std::distance(it, e); - c.erase(it, e); + + auto it = std::next(c.begin(), result); + auto dest = it; + + // Loop Invariants: + // - it != e + // - [next(it), e[ still to be checked + // - [c.begin(), dest[ are result + while (++it != e) { + if (!pred(*it)) { + *dest = std::move(*it); + ++dest; + } + } + + result = std::distance(dest, e); + c.erase(dest, e); return result; } template <typename Container, typename T> +auto sequential_erase(Container &c, const T &t) +{ + // use the equivalence relation from http://eel.is/c++draft/list.erasure#1 + auto cmp = [&](auto &e) { return e == t; }; + return sequential_erase_if(c, cmp); // can't pass rvalues! +} + +template <typename Container, typename T> auto sequential_erase_with_copy(Container &c, const T &t) { using CopyProxy = std::conditional_t<std::is_copy_constructible_v<T>, T, const T &>; @@ -312,24 +312,6 @@ auto sequential_erase_one(Container &c, const T &t) return true; } -template <typename Container, typename Predicate> -auto sequential_erase_if(Container &c, Predicate &pred) -{ - // avoid a detach in case there is nothing to remove - const auto cbegin = c.cbegin(); - const auto cend = c.cend(); - const auto t_it = std::find_if(cbegin, cend, pred); - auto result = std::distance(cbegin, t_it); - if (result == c.size()) - return result - result; // `0` of the right type - - const auto e = c.end(); - const auto it = std::remove_if(std::next(c.begin(), result), e, pred); - result = std::distance(it, e); - c.erase(it, e); - return result; -} - template <typename T, typename Predicate> qsizetype qset_erase_if(QSet<T> &set, Predicate &pred) { diff --git a/src/corelib/tools/qcontiguouscache.cpp b/src/corelib/tools/qcontiguouscache.cpp index 95537961f9..73cfed97f2 100644 --- a/src/corelib/tools/qcontiguouscache.cpp +++ b/src/corelib/tools/qcontiguouscache.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 "qcontiguouscache.h" #ifdef QT_QCONTIGUOUSCACHE_DEBUG diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 62ebfa0658..70703fe0ab 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.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 QCONTIGUOUSCACHE_H #define QCONTIGUOUSCACHE_H @@ -97,7 +61,7 @@ public: QContiguousCache<T> &operator=(const QContiguousCache<T> &other); QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QContiguousCache) - inline void swap(QContiguousCache<T> &other) noexcept { qSwap(d, other.d); } + void swap(QContiguousCache &other) noexcept { qt_ptr_swap(d, other.d); } #ifndef Q_CLANG_QDOC template <typename U = T> diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index e1f15d2b93..8d60be175e 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2013 Richard J. Moore <rich@kde.org>. -** 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) 2013 Richard J. Moore <rich@kde.org>. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include <qcryptographichash.h> #include <qiodevice.h> @@ -79,17 +43,17 @@ typedef HashReturn (SHA3Final)(hashState *state, BitSequence *hashval); #include "../../3rdparty/sha3/KeccakF-1600-opt64.c" -static SHA3Init * const sha3Init = Init; -static SHA3Update * const sha3Update = Update; -static SHA3Final * const sha3Final = Final; +Q_CONSTINIT static SHA3Init * const sha3Init = Init; +Q_CONSTINIT static SHA3Update * const sha3Update = Update; +Q_CONSTINIT static SHA3Final * const sha3Final = Final; #else // 32 bit optimised fallback #include "../../3rdparty/sha3/KeccakF-1600-opt32.c" -static SHA3Init * const sha3Init = Init; -static SHA3Update * const sha3Update = Update; -static SHA3Final * const sha3Final = Final; +Q_CONSTINIT static SHA3Init * const sha3Init = Init; +Q_CONSTINIT static SHA3Update * const sha3Update = Update; +Q_CONSTINIT static SHA3Final * const sha3Final = Final; #endif @@ -236,7 +200,7 @@ public: qsizetype size() const noexcept { return qsizetype{m_size}; } bool isEmpty() const noexcept { return size() == 0; } void clear() noexcept { m_size = 0; } - void resize(qsizetype s) { + void resizeForOverwrite(qsizetype s) { Q_ASSERT(s >= 0); Q_ASSERT(s <= MaxHashLength); m_size = std::uint8_t(s); @@ -272,7 +236,7 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant */ static const unsigned char sha3FinalSuffix = 0x80; - result.resize(bitCount / 8); + result.resizeForOverwrite(bitCount / 8); SHA3Context copy = sha3Context; @@ -587,7 +551,7 @@ void QCryptographicHashPrivate::finalize() noexcept switch (method) { case QCryptographicHash::Sha1: { Sha1State copy = sha1Context; - result.resize(20); + result.resizeForOverwrite(20); sha1FinalizeState(©); sha1ToHash(©, (unsigned char *)result.data()); break; @@ -600,37 +564,37 @@ void QCryptographicHashPrivate::finalize() noexcept #else case QCryptographicHash::Md4: { md4_context copy = md4Context; - result.resize(MD4_RESULTLEN); + result.resizeForOverwrite(MD4_RESULTLEN); md4_final(©, (unsigned char *)result.data()); break; } case QCryptographicHash::Md5: { MD5Context copy = md5Context; - result.resize(16); + result.resizeForOverwrite(16); MD5Final(©, (unsigned char *)result.data()); break; } case QCryptographicHash::Sha224: { SHA224Context copy = sha224Context; - result.resize(SHA224HashSize); + result.resizeForOverwrite(SHA224HashSize); SHA224Result(©, reinterpret_cast<unsigned char *>(result.data())); break; } case QCryptographicHash::Sha256: { SHA256Context copy = sha256Context; - result.resize(SHA256HashSize); + result.resizeForOverwrite(SHA256HashSize); SHA256Result(©, reinterpret_cast<unsigned char *>(result.data())); break; } case QCryptographicHash::Sha384: { SHA384Context copy = sha384Context; - result.resize(SHA384HashSize); + result.resizeForOverwrite(SHA384HashSize); SHA384Result(©, reinterpret_cast<unsigned char *>(result.data())); break; } case QCryptographicHash::Sha512: { SHA512Context copy = sha512Context; - result.resize(SHA512HashSize); + result.resizeForOverwrite(SHA512HashSize); SHA512Result(©, reinterpret_cast<unsigned char *>(result.data())); break; } @@ -654,7 +618,7 @@ void QCryptographicHashPrivate::finalize() noexcept case QCryptographicHash::Blake2b_512: { const auto length = hashLengthInternal(method); blake2b_state copy = blake2bContext; - result.resize(length); + result.resizeForOverwrite(length); blake2b_final(©, reinterpret_cast<uint8_t *>(result.data()), length); break; } @@ -664,7 +628,7 @@ void QCryptographicHashPrivate::finalize() noexcept case QCryptographicHash::Blake2s_256: { const auto length = hashLengthInternal(method); blake2s_state copy = blake2sContext; - result.resize(length); + result.resizeForOverwrite(length); blake2s_final(©, reinterpret_cast<uint8_t *>(result.data()), length); break; } diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h index 83aed7c64c..f5710015cf 100644 --- a/src/corelib/tools/qcryptographichash.h +++ b/src/corelib/tools/qcryptographichash.h @@ -1,43 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2013 Richard J. Moore <rich@kde.org>. -** 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 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2013 Richard J. Moore <rich@kde.org>. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QCRYPTOGRAPHICHASH_H #define QCRYPTOGRAPHICHASH_H @@ -108,7 +72,7 @@ public: QT_DEPRECATED_VERSION_X_6_4("Use the QByteArrayView overload instead") void addData(const char *data, qsizetype length); #endif -#if QT_REMOVED_SINCE(6, 3) +#if QT_CORE_REMOVED_SINCE(6, 3) void addData(const QByteArray &data); #endif void addData(QByteArrayView data) noexcept; @@ -117,7 +81,7 @@ public: QByteArray result() const; QByteArrayView resultView() const noexcept; -#if QT_REMOVED_SINCE(6, 3) +#if QT_CORE_REMOVED_SINCE(6, 3) static QByteArray hash(const QByteArray &data, Algorithm method); #endif static QByteArray hash(QByteArrayView data, Algorithm method); diff --git a/src/corelib/tools/qduplicatetracker_p.h b/src/corelib/tools/qduplicatetracker_p.h index eab63bab9b..4d0e6e4777 100644 --- a/src/corelib/tools/qduplicatetracker_p.h +++ b/src/corelib/tools/qduplicatetracker_p.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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) 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 QDUPLICATETRACKER_P_H #define QDUPLICATETRACKER_P_H @@ -50,7 +14,7 @@ // We mean it. // -#include <qglobal.h> +#include <private/qglobal_p.h> #if __has_include(<memory_resource>) # include <unordered_set> diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 4839fc839e..9242a617ba 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.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 /* diff --git a/src/corelib/tools/qeasingcurve.h b/src/corelib/tools/qeasingcurve.h index 7e50743bf1..5b112d7d7d 100644 --- a/src/corelib/tools/qeasingcurve.h +++ b/src/corelib/tools/qeasingcurve.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 QEASINGCURVE_H #define QEASINGCURVE_H @@ -81,7 +45,7 @@ public: QEasingCurve(QEasingCurve &&other) noexcept : d_ptr(other.d_ptr) { other.d_ptr = nullptr; } QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QEasingCurve) - void swap(QEasingCurve &other) noexcept { qSwap(d_ptr, other.d_ptr); } + void swap(QEasingCurve &other) noexcept { qt_ptr_swap(d_ptr, other.d_ptr); } bool operator==(const QEasingCurve &other) const; inline bool operator!=(const QEasingCurve &other) const diff --git a/src/corelib/tools/qflatmap_p.h b/src/corelib/tools/qflatmap_p.h index 1b3eaea01c..28bb72c864 100644 --- a/src/corelib/tools/qflatmap_p.h +++ b/src/corelib/tools/qflatmap_p.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) 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 QFLATMAP_P_H #define QFLATMAP_P_H @@ -52,6 +16,7 @@ // #include "qlist.h" +#include "private/qglobal_p.h" #include <algorithm> #include <functional> @@ -77,6 +42,19 @@ QT_BEGIN_NAMESPACE QFlatMap<float, int, std::less<float>, std::vector<float>, std::vector<int>> */ +// Qt 6.4: +// - removed QFlatMap API which was incompatible with STL semantics +// - will be released with said API disabled, to catch any out-of-tree users +// - also allows opting in to the new API using QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT +// Qt 6.5 +// - will make QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT the default: + +#ifndef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT +# if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) +# define QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT +# endif +#endif + namespace Qt { struct OrderedUniqueRange_t {}; @@ -111,8 +89,6 @@ class QFlatMap : private QFlatMapValueCompare<Key, T, Compare> { static_assert(std::is_nothrow_destructible_v<T>, "Types with throwing destructors are not supported in Qt containers."); - using full_map_t = QFlatMap<Key, T, Compare, KeyContainer, MappedContainer>; - template <class U> class mock_pointer { @@ -161,12 +137,12 @@ public: { } - reference operator*() + reference operator*() const { return { c->keys[i], c->values[i] }; } - pointer operator->() + pointer operator->() const { return { operator*() }; } @@ -191,7 +167,7 @@ public: { iterator r = *this; - i++; + ++*this; return r; } @@ -204,7 +180,7 @@ public: iterator operator--(int) { iterator r = *this; - i--; + --*this; return r; } @@ -242,7 +218,7 @@ public: return b.i - a.i; } - reference operator[](size_type n) + reference operator[](size_type n) const { size_type k = i + n; return { c->keys[k], c->values[k] }; @@ -269,12 +245,12 @@ public: } const Key &key() const { return c->keys[i]; } - T &value() { return c->values[i]; } + T &value() const { return c->values[i]; } private: containers *c = nullptr; size_type i = 0; - friend full_map_t; + friend QFlatMap; }; class const_iterator @@ -298,12 +274,12 @@ public: { } - reference operator*() + reference operator*() const { return { c->keys[i], c->values[i] }; } - pointer operator->() + pointer operator->() const { return { operator*() }; } @@ -328,7 +304,7 @@ public: { const_iterator r = *this; - i++; + ++*this; return r; } @@ -341,7 +317,7 @@ public: const_iterator operator--(int) { const_iterator r = *this; - i--; + --*this; return r; } @@ -379,7 +355,7 @@ public: return b.i - a.i; } - reference operator[](size_type n) + reference operator[](size_type n) const { size_type k = i + n; return { c->keys[k], c->values[k] }; @@ -406,12 +382,12 @@ public: } const Key &key() const { return c->keys[i]; } - const T &value() { return c->values[i]; } + const T &value() const { return c->values[i]; } private: const containers *c = nullptr; size_type i = 0; - friend full_map_t; + friend QFlatMap; }; private: @@ -419,7 +395,7 @@ private: struct is_marked_transparent_type : std::false_type { }; template <class X> - struct is_marked_transparent_type<X, typename X::is_transparent> : std::true_type { }; + struct is_marked_transparent_type<X, std::void_t<typename X::is_transparent>> : std::true_type { }; template <class X> using is_marked_transparent = typename std::enable_if< @@ -432,6 +408,7 @@ private: public: QFlatMap() = default; +#ifdef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT explicit QFlatMap(const key_container_type &keys, const mapped_container_type &values) : c{keys, values} { @@ -439,23 +416,20 @@ public: } explicit QFlatMap(key_container_type &&keys, const mapped_container_type &values) + : c{std::move(keys), values} { - c.keys = std::move(keys); - c.values = values; ensureOrderedUnique(); } explicit QFlatMap(const key_container_type &keys, mapped_container_type &&values) + : c{keys, std::move(values)} { - c.keys = keys; - c.values = std::move(values); ensureOrderedUnique(); } explicit QFlatMap(key_container_type &&keys, mapped_container_type &&values) + : c{std::move(keys), std::move(values)} { - c.keys = std::move(keys); - c.values = std::move(values); ensureOrderedUnique(); } @@ -470,37 +444,34 @@ public: initWithRange(first, last); ensureOrderedUnique(); } +#endif explicit QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, const mapped_container_type &values) + : c{keys, values} { - c.keys = keys; - c.values = values; } explicit QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, const mapped_container_type &values) + : c{std::move(keys), values} { - c.keys = std::move(keys); - c.values = values; } explicit QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, mapped_container_type &&values) + : c{keys, std::move(values)} { - c.keys = keys; - c.values = std::move(values); } explicit QFlatMap(Qt::OrderedUniqueRange_t, key_container_type &&keys, mapped_container_type &&values) + : c{std::move(keys), std::move(values)} { - c.keys = std::move(keys); - c.values = std::move(values); } explicit QFlatMap(Qt::OrderedUniqueRange_t, std::initializer_list<value_type> lst) - : QFlatMap(lst.begin(), lst.end()) + : QFlatMap(Qt::OrderedUniqueRange, lst.begin(), lst.end()) { } @@ -515,6 +486,7 @@ public: { } +#ifdef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT explicit QFlatMap(const key_container_type &keys, const mapped_container_type &values, const Compare &compare) : value_compare(compare), c{keys, values} @@ -555,6 +527,7 @@ public: initWithRange(first, last); ensureOrderedUnique(); } +#endif explicit QFlatMap(Qt::OrderedUniqueRange_t, const key_container_type &keys, const mapped_container_type &values, const Compare &compare) @@ -616,13 +589,13 @@ public: bool remove(const Key &key) { - auto it = binary_find(key); - if (it != end()) { - c.keys.erase(toKeysIterator(it)); - c.values.erase(toValuesIterator(it)); - return true; - } - return false; + return do_remove(find(key)); + } + + template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr> + bool remove(const X &key) + { + return do_remove(find(key)); } iterator erase(iterator it) @@ -633,50 +606,60 @@ public: T take(const Key &key) { - auto it = binary_find(key); - if (it != end()) { - T result = std::move(it.value()); - erase(it); - return result; - } - return {}; + return do_take(find(key)); + } + + template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr> + T take(const X &key) + { + return do_take(find(key)); } bool contains(const Key &key) const { - return binary_find(key) != end(); + return find(key) != end(); + } + + template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr> + bool contains(const X &key) const + { + return find(key) != end(); } T value(const Key &key, const T &defaultValue) const { - auto it = binary_find(key); + auto it = find(key); + return it == end() ? defaultValue : it.value(); + } + + template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr> + T value(const X &key, const T &defaultValue) const + { + auto it = find(key); return it == end() ? defaultValue : it.value(); } T value(const Key &key) const { - auto it = binary_find(key); + auto it = find(key); + return it == end() ? T() : it.value(); + } + + template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr> + T value(const X &key) const + { + auto it = find(key); return it == end() ? T() : it.value(); } T &operator[](const Key &key) { - auto it = lower_bound(key); - if (it == end() || key_compare::operator()(key, it.key())) { - c.keys.insert(toKeysIterator(it), key); - return *c.values.insert(toValuesIterator(it), T()); - } - return it.value(); + return try_emplace(key).first.value(); } T &operator[](Key &&key) { - auto it = lower_bound(key); - if (it == end() || key_compare::operator()(key, it.key())) { - c.keys.insert(toKeysIterator(it), key); - return *c.values.insert(toValuesIterator(it), T()); - } - return it.value(); + return try_emplace(std::move(key)).first.value(); } T operator[](const Key &key) const @@ -684,55 +667,71 @@ public: return value(key); } +#ifdef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT std::pair<iterator, bool> insert(const Key &key, const T &value) { - auto it = lower_bound(key); - if (it == end() || key_compare::operator()(key, it.key())) { - c.values.insert(toValuesIterator(it), value); - auto k = c.keys.insert(toKeysIterator(it), key); - return { fromKeysIterator(k), true }; - } else { - it.value() = value; - return {it, false}; - } + return try_emplace(key, value); } std::pair<iterator, bool> insert(Key &&key, const T &value) { - auto it = lower_bound(key); - if (it == end() || key_compare::operator()(key, it.key())) { - c.values.insert(toValuesIterator(it), value); - return { c.keys.insert(it, std::move(key)), true }; - } else { - *toValuesIterator(it) = value; - return {it, false}; - } + return try_emplace(std::move(key), value); } std::pair<iterator, bool> insert(const Key &key, T &&value) { + return try_emplace(key, std::move(value)); + } + + std::pair<iterator, bool> insert(Key &&key, T &&value) + { + return try_emplace(std::move(key), std::move(value)); + } +#endif + + template <typename...Args> + std::pair<iterator, bool> try_emplace(const Key &key, Args&&...args) + { auto it = lower_bound(key); if (it == end() || key_compare::operator()(key, it.key())) { - c.values.insert(toValuesIterator(it), std::move(value)); - return { c.keys.insert(it, key), true }; + c.values.emplace(toValuesIterator(it), std::forward<Args>(args)...); + return { fromKeysIterator(c.keys.insert(toKeysIterator(it), key)), true }; } else { - *toValuesIterator(it) = std::move(value); return {it, false}; } } - std::pair<iterator, bool> insert(Key &&key, T &&value) + template <typename...Args> + std::pair<iterator, bool> try_emplace(Key &&key, Args&&...args) { auto it = lower_bound(key); if (it == end() || key_compare::operator()(key, it.key())) { - c.values.insert(toValuesIterator(it), std::move(value)); + c.values.emplace(toValuesIterator(it), std::forward<Args>(args)...); return { fromKeysIterator(c.keys.insert(toKeysIterator(it), std::move(key))), true }; } else { - *toValuesIterator(it) = std::move(value); return {it, false}; } } + template <typename M> + std::pair<iterator, bool> insert_or_assign(const Key &key, M &&obj) + { + auto r = try_emplace(key, std::forward<M>(obj)); + if (!r.second) + *toValuesIterator(r.first) = std::forward<M>(obj); + return r; + } + + template <typename M> + std::pair<iterator, bool> insert_or_assign(Key &&key, M &&obj) + { + auto r = try_emplace(std::move(key), std::forward<M>(obj)); + if (!r.second) + *toValuesIterator(r.first) = std::forward<M>(obj); + return r; + } + +#ifdef QFLATMAP_ENABLE_STL_COMPATIBLE_INSERT template <class InputIt, is_compatible_iterator<InputIt> = nullptr> void insert(InputIt first, InputIt last) { @@ -758,6 +757,7 @@ public: { insertOrderedUniqueRange(first, last); } +#endif iterator begin() { return { &c, 0 }; } const_iterator begin() const { return { &c, 0 }; } @@ -784,14 +784,14 @@ public: iterator lower_bound(const Key &key) { - auto cit = const_cast<const full_map_t *>(this)->lower_bound(key); + auto cit = std::as_const(*this).lower_bound(key); return { &c, cit.i }; } template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr> iterator lower_bound(const X &key) { - auto cit = const_cast<const full_map_t *>(this)->lower_bound(key); + auto cit = std::as_const(*this).lower_bound(key); return { &c, cit.i }; } @@ -806,14 +806,113 @@ public: return fromKeysIterator(std::lower_bound(c.keys.begin(), c.keys.end(), key, key_comp())); } - iterator find(const key_type &k) + iterator find(const Key &key) + { + return { &c, std::as_const(*this).find(key).i }; + } + + template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr> + iterator find(const X &key) + { + return { &c, std::as_const(*this).find(key).i }; + } + + const_iterator find(const Key &key) const { - return binary_find(k); + auto it = lower_bound(key); + if (it != end()) { + if (!key_compare::operator()(key, it.key())) + return it; + it = end(); + } + return it; } - const_iterator find(const key_type &k) const + template <class X, class Y = Compare, is_marked_transparent<Y> = nullptr> + const_iterator find(const X &key) const { - return binary_find(k); + auto it = lower_bound(key); + if (it != end()) { + if (!key_compare::operator()(key, it.key())) + return it; + it = end(); + } + return it; + } + + template <typename Predicate> + size_type remove_if(Predicate pred) + { + const auto indirect_call_to_pred = [pred = std::move(pred)](iterator it) { + [[maybe_unused]] auto dependent_false = [](auto &&...) { return false; }; + using Pair = decltype(*it); + using K = decltype(it.key()); + using V = decltype(it.value()); + using P = Predicate; + if constexpr (std::is_invocable_v<P, K, V>) { + return pred(it.key(), it.value()); + } else if constexpr (std::is_invocable_v<P, Pair> && !std::is_invocable_v<P, K>) { + return pred(*it); + } else if constexpr (std::is_invocable_v<P, K> && !std::is_invocable_v<P, Pair>) { + return pred(it.key()); + } else { + static_assert(dependent_false(pred), + "Don't know how to call the predicate.\n" + "Options:\n" + "- pred(*it)\n" + "- pred(it.key(), it.value())\n" + "- pred(it.key())"); + } + }; + + auto first = begin(); + const auto last = end(); + + // find_if prefix loop + while (first != last && !indirect_call_to_pred(first)) + ++first; + + if (first == last) + return 0; // nothing to do + + // we know that we need to remove *first + + auto kdest = toKeysIterator(first); + auto vdest = toValuesIterator(first); + + ++first; + + auto k = std::next(kdest); + auto v = std::next(vdest); + + // Main Loop + // - first is used only for indirect_call_to_pred + // - operations are done on k, v + // Loop invariants: + // - first, k, v are pointing to the same element + // - [begin(), first[, [c.keys.begin(), k[, [c.values.begin(), v[: already processed + // - [first, end()[, [k, c.keys.end()[, [v, c.values.end()[: still to be processed + // - [c.keys.begin(), kdest[ and [c.values.begin(), vdest[ are keepers + // - [kdest, k[, [vdest, v[ are considered removed + // - kdest is not c.keys.end() + // - vdest is not v.values.end() + while (first != last) { + if (!indirect_call_to_pred(first)) { + // keep *first, aka {*k, *v} + *kdest = std::move(*k); + *vdest = std::move(*v); + ++kdest; + ++vdest; + } + ++k; + ++v; + ++first; + } + + const size_type r = std::distance(kdest, c.keys.end()); + c.keys.erase(kdest, c.keys.end()); + c.values.erase(vdest, c.values.end()); + return r; } key_compare key_comp() const noexcept @@ -827,6 +926,25 @@ public: } private: + bool do_remove(iterator it) + { + if (it != end()) { + erase(it); + return true; + } + return false; + } + + T do_take(iterator it) + { + if (it != end()) { + T result = std::move(it.value()); + erase(it); + return result; + } + return {}; + } + template <class InputIt, is_compatible_iterator<InputIt> = nullptr> void initWithRange(InputIt first, InputIt last) { @@ -874,7 +992,7 @@ private: class IndexedKeyComparator { public: - IndexedKeyComparator(const full_map_t *am) + IndexedKeyComparator(const QFlatMap *am) : m(am) { } @@ -885,7 +1003,7 @@ private: } private: - const full_map_t *m; + const QFlatMap *m; }; template <class InputIt> @@ -906,22 +1024,6 @@ private: makeUnique(); } - iterator binary_find(const Key &key) - { - return { &c, const_cast<const full_map_t *>(this)->binary_find(key).i }; - } - - const_iterator binary_find(const Key &key) const - { - auto it = lower_bound(key); - if (it != end()) { - if (!key_compare::operator()(key, it.key())) - return it; - it = end(); - } - return it; - } - void ensureOrderedUnique() { std::vector<size_type> p(size_t(c.keys.size())); @@ -953,31 +1055,47 @@ private: void makeUnique() { - if (c.keys.size() < 2) + // std::unique, but over two ranges + auto equivalent = [this](const auto &lhs, const auto &rhs) { + return !key_compare::operator()(lhs, rhs) && !key_compare::operator()(rhs, lhs); + }; + const auto kb = c.keys.begin(); + const auto ke = c.keys.end(); + auto k = std::adjacent_find(kb, ke, equivalent); + if (k == ke) return; - auto k = std::end(c.keys) - 1; - auto i = k - 1; - for (;;) { - if (key_compare::operator()(*i, *k) || key_compare::operator()(*k, *i)) { - if (i == std::begin(c.keys)) - break; - --i; - --k; - } else { - c.values.erase(std::begin(c.values) + std::distance(std::begin(c.keys), i)); - i = c.keys.erase(i); - if (i == std::begin(c.keys)) - break; - k = i + 1; + + // equivalent keys found, we need to do actual work: + auto v = std::next(c.values.begin(), std::distance(kb, k)); + + auto kdest = k; + auto vdest = v; + + ++k; + ++v; + + // Loop Invariants: + // + // - [keys.begin(), kdest] and [values.begin(), vdest] are unique + // - k is not keys.end(), v is not values.end() + // - [next(k), keys.end()[ and [next(v), values.end()[ still need to be checked + while ((++v, ++k) != ke) { + if (!equivalent(*kdest, *k)) { + *++kdest = std::move(*k); + *++vdest = std::move(*v); } } - c.keys.shrink_to_fit(); - c.values.shrink_to_fit(); + + c.keys.erase(std::next(kdest), ke); + c.values.erase(std::next(vdest), c.values.end()); } containers c; }; +template<class Key, class T, qsizetype N = 256, class Compare = std::less<Key>> +using QVarLengthFlatMap = QFlatMap<Key, T, Compare, QVarLengthArray<Key, N>, QVarLengthArray<T, N>>; + QT_END_NAMESPACE #endif // QFLATMAP_P_H diff --git a/src/corelib/tools/qfreelist.cpp b/src/corelib/tools/qfreelist.cpp index 38ad13a1ee..45bd3ba8ae 100644 --- a/src/corelib/tools/qfreelist.cpp +++ b/src/corelib/tools/qfreelist.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 "qfreelist_p.h" @@ -54,7 +18,7 @@ enum { Size3 = QFreeListDefaultConstants::MaxIndex - Offset3 }; -const int QFreeListDefaultConstants::Sizes[QFreeListDefaultConstants::BlockCount] = { +Q_CONSTINIT const int QFreeListDefaultConstants::Sizes[QFreeListDefaultConstants::BlockCount] = { Size0, Size1, Size2, diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index f54e5aad65..c06c569d23 100644 --- a/src/corelib/tools/qfreelist_p.h +++ b/src/corelib/tools/qfreelist_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 QFREELIST_P_H #define QFREELIST_P_H @@ -160,7 +124,7 @@ class QFreeList return i; x -= size; } - Q_ASSERT(false); + Q_UNREACHABLE(); return -1; } diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index bc8c9490d9..c973eaeabe 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -1,43 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2021 Intel Corporation. -** Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.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) 2021 Intel Corporation. +// Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // 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 @@ -66,11 +30,17 @@ #ifndef QT_BOOTSTRAPPED #include <qcoreapplication.h> #include <qrandom.h> +#include <private/qlocale_tools_p.h> #endif // QT_BOOTSTRAPPED #include <array> #include <limits.h> +#if defined(QT_NO_DEBUG) && !defined(NDEBUG) +# define NDEBUG +#endif +#include <assert.h> + #ifdef Q_CC_GNU # define Q_DECL_HOT_FUNCTION __attribute__((hot)) #else @@ -89,7 +59,11 @@ struct HashSeedStorage static constexpr int SeedCount = 2; QBasicAtomicInteger<quintptr> seeds[SeedCount] = { Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) }; +#if !QT_SUPPORTS_INIT_PRIORITY || defined(QT_BOOTSTRAPPED) constexpr HashSeedStorage() = default; +#else + HashSeedStorage() { initialize(0); } +#endif enum State { OverriddenByEnvironment = -1, @@ -126,19 +100,24 @@ struct HashSeedStorage private: Q_DECL_COLD_FUNCTION Q_NEVER_INLINE StateResult initialize(int which) noexcept; - [[maybe_unused]] static void ensureConstexprConstructibility() - { - static_assert(std::is_trivially_destructible_v<HashSeedStorage>); - static constexpr HashSeedStorage dummy {}; - Q_UNUSED(dummy); - } }; [[maybe_unused]] HashSeedStorage::StateResult HashSeedStorage::initialize(int which) noexcept { StateResult result = { 0, OverriddenByEnvironment }; - bool ok; - int seed = qEnvironmentVariableIntValue("QT_HASH_SEED", &ok); +#ifdef QT_BOOTSTRAPPED + Q_UNUSED(which); + Q_UNREACHABLE(); +#else + // can't use qEnvironmentVariableIntValue (reentrancy) + const char *seedstr = getenv("QT_HASH_SEED"); + const char *endptr = nullptr; + bool ok = false; + int seed = 0; + if (seedstr) + seed = qstrntoll(seedstr, strlen(seedstr), &endptr, 10, &ok); + if (ok && endptr != seedstr + strlen(seedstr)) + ok = false; if (ok) { if (seed) { // can't use qWarning here (reentrancy) @@ -158,6 +137,7 @@ private: result.requestedSeed = x.data[i]; } result.state = JustInitialized; +#endif return result; } @@ -166,14 +146,15 @@ inline HashSeedStorage::StateResult HashSeedStorage::state(int which) constexpr quintptr BadSeed = quintptr(Q_UINT64_C(0x5555'5555'5555'5555)); StateResult result = { BadSeed, AlreadyInitialized }; -#ifndef QT_BOOTSTRAPPED +#if defined(QT_BOOTSTRAPPED) + result = { 0, OverriddenByEnvironment }; +#elif !QT_SUPPORTS_INIT_PRIORITY + // dynamic initialization static auto once = [&]() { result = initialize(which); return true; }(); Q_UNUSED(once); -#else - result = { 0, OverriddenByEnvironment }; #endif if (result.state == AlreadyInitialized && which >= 0) @@ -185,6 +166,11 @@ inline HashSeedStorage::StateResult HashSeedStorage::state(int which) /* The QHash seed itself. */ +#ifdef Q_DECL_INIT_PRIORITY +Q_DECL_INIT_PRIORITY(05) +#else +Q_CONSTINIT +#endif static HashSeedStorage qt_qhash_seed; /* @@ -192,7 +178,7 @@ static HashSeedStorage qt_qhash_seed; * Austin Appleby. See http://murmurhash.googlepages.com/ */ #if QT_POINTER_SIZE == 4 - +Q_NEVER_INLINE Q_DECL_HOT_FUNCTION static inline uint murmurhash(const void *key, uint len, uint seed) noexcept { // 'm' and 'r' are mixing constants generated offline. @@ -250,7 +236,7 @@ static inline uint murmurhash(const void *key, uint len, uint seed) noexcept } #else - +Q_NEVER_INLINE Q_DECL_HOT_FUNCTION static inline uint64_t murmurhash(const void *key, uint64_t len, uint64_t seed) noexcept { const uint64_t m = 0xc6a4a7935bd1e995ULL; @@ -329,7 +315,7 @@ static inline uint64_t murmurhash(const void *key, uint64_t len, uint64_t seed) v2 = ROTL(v2, 32); \ } while (0) - +Q_NEVER_INLINE Q_DECL_HOT_FUNCTION static uint64_t siphash(const uint8_t *in, uint64_t inlen, uint64_t seed, uint64_t seed2) { /* "somepseudorandomlygeneratedbytes" */ @@ -360,7 +346,7 @@ static uint64_t siphash(const uint8_t *in, uint64_t inlen, uint64_t seed, uint64 } -#if defined(Q_CC_GNU) && Q_CC_GNU >= 700 +#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 700 QT_WARNING_DISABLE_GCC("-Wimplicit-fallthrough") #endif switch (left) { @@ -434,7 +420,7 @@ static uint64_t siphash(const uint8_t *in, uint64_t inlen, uint64_t seed, uint64 v2 = ROTL(v2, 16); \ } while (0) - +Q_NEVER_INLINE Q_DECL_HOT_FUNCTION static uint siphash(const uint8_t *in, uint inlen, uint seed, uint seed2) { /* "somepseudorandomlygeneratedbytes" */ @@ -464,7 +450,7 @@ static uint siphash(const uint8_t *in, uint inlen, uint seed, uint seed2) v0 ^= m; } -#if defined(Q_CC_GNU) && Q_CC_GNU >= 700 +#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 700 QT_WARNING_DISABLE_GCC("-Wimplicit-fallthrough") #endif switch (left) { @@ -510,27 +496,30 @@ static uint siphash(const uint8_t *in, uint inlen, uint seed, uint seed2) #if QT_COMPILER_SUPPORTS_HERE(AES) && QT_COMPILER_SUPPORTS_HERE(SSE4_2) && \ !defined(QHASH_AES_SANITIZER_BUILD) # define AESHASH +# define QT_FUNCTION_TARGET_STRING_AES_AVX2 "avx2,aes" +# define QT_FUNCTION_TARGET_STRING_AES_AVX512 \ + QT_FUNCTION_TARGET_STRING_ARCH_SKYLAKE_AVX512 "," \ + QT_FUNCTION_TARGET_STRING_AES +# define QT_FUNCTION_TARGET_STRING_VAES_AVX512 \ + QT_FUNCTION_TARGET_STRING_ARCH_SKYLAKE_AVX512 "," \ + QT_FUNCTION_TARGET_STRING_VAES +# undef QHASH_AES_SANITIZER_BUILD +# if QT_POINTER_SIZE == 8 +# define mm_set1_epz _mm_set1_epi64x +# define mm_cvtsz_si128 _mm_cvtsi64_si128 +# define mm_cvtsi128_sz _mm_cvtsi128_si64 +# define mm256_set1_epz _mm256_set1_epi64x +# else +# define mm_set1_epz _mm_set1_epi32 +# define mm_cvtsz_si128 _mm_cvtsi32_si128 +# define mm_cvtsi128_sz _mm_cvtsi128_si32 +# define mm256_set1_epz _mm256_set1_epi32 +# endif -#undef QHASH_AES_SANITIZER_BUILD - -QT_FUNCTION_TARGET(AES) -static size_t aeshash(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept -{ - __m128i key; - if (sizeof(size_t) == 8) { -#ifdef Q_PROCESSOR_X86_64 - __m128i mseed = _mm_cvtsi64_si128(seed); - key = _mm_insert_epi64(mseed, seed2, 1); -#endif - } else { - __m128i mseed = _mm_cvtsi32_si128(int(seed)); - key = _mm_insert_epi32(mseed, int(seed2), 1); - key = _mm_unpacklo_epi64(key, key); - } - +namespace { // This is inspired by the algorithm in the Go language. See: - // https://github.com/golang/go/blob/894abb5f680c040777f17f9f8ee5a5ab3a03cb94/src/runtime/asm_386.s#L902 - // https://github.com/golang/go/blob/894abb5f680c040777f17f9f8ee5a5ab3a03cb94/src/runtime/asm_amd64.s#L903 + // https://github.com/golang/go/blob/01b6cf09fc9f272d9db3d30b4c93982f4911d120/src/runtime/asm_amd64.s#L1105 + // https://github.com/golang/go/blob/01b6cf09fc9f272d9db3d30b4c93982f4911d120/src/runtime/asm_386.s#L908 // // Even though we're using the AESENC instruction from the CPU, this code // is not encryption and this routine makes no claim to be @@ -541,98 +530,268 @@ static size_t aeshash(const uchar *p, size_t len, size_t seed, size_t seed2) noe // [1] https://en.wikipedia.org/wiki/Advanced_Encryption_Standard#High-level_description_of_the_algorithm // hash 16 bytes, running 3 scramble rounds of AES on itself (like label "final1") - const auto hash16bytes = [](__m128i &state0, __m128i data) QT_FUNCTION_TARGET(AES) { + static void QT_FUNCTION_TARGET(AES) QT_VECTORCALL + hash16bytes(__m128i &state0, __m128i data) + { state0 = _mm_xor_si128(state0, data); state0 = _mm_aesenc_si128(state0, state0); state0 = _mm_aesenc_si128(state0, state0); state0 = _mm_aesenc_si128(state0, state0); + } + + // hash twice 16 bytes, running 2 scramble rounds of AES on itself + static void QT_FUNCTION_TARGET(AES) QT_VECTORCALL + hash2x16bytes(__m128i &state0, __m128i &state1, const __m128i *src0, const __m128i *src1) + { + __m128i data0 = _mm_loadu_si128(src0); + __m128i data1 = _mm_loadu_si128(src1); + state0 = _mm_xor_si128(data0, state0); + state1 = _mm_xor_si128(data1, state1); + state0 = _mm_aesenc_si128(state0, state0); + state1 = _mm_aesenc_si128(state1, state1); + state0 = _mm_aesenc_si128(state0, state0); + state1 = _mm_aesenc_si128(state1, state1); + } + + struct AESHashSeed + { + __m128i state0; + __m128i mseed2; + AESHashSeed(size_t seed, size_t seed2) QT_FUNCTION_TARGET(AES); + __m128i state1() const QT_FUNCTION_TARGET(AES); + __m256i state0_256() const QT_FUNCTION_TARGET(AES_AVX2) + { return _mm256_set_m128i(state1(), state0); } }; +} // unnamed namespace - __m128i state0 = key; - auto src = reinterpret_cast<const __m128i *>(p); +Q_ALWAYS_INLINE AESHashSeed::AESHashSeed(size_t seed, size_t seed2) +{ + __m128i mseed = mm_cvtsz_si128(seed); + mseed2 = mm_set1_epz(seed2); - if (len < 16) - goto lt16; - if (len < 32) - goto lt32; + // mseed (epi16) = [ seed, seed >> 16, seed >> 32, seed >> 48, len, 0, 0, 0 ] + mseed = _mm_insert_epi16(mseed, short(seed), 4); + // mseed (epi16) = [ seed, seed >> 16, seed >> 32, seed >> 48, len, len, len, len ] + mseed = _mm_shufflehi_epi16(mseed, 0); - // rounds of 32 bytes + // merge with the process-global seed + __m128i key = _mm_xor_si128(mseed, mseed2); + + // scramble the key + __m128i state0 = _mm_aesenc_si128(key, key); + this->state0 = state0; +} + +Q_ALWAYS_INLINE __m128i AESHashSeed::state1() const +{ { - // Make state1 = ~state0: - __m128i one = _mm_cmpeq_epi64(key, key); - __m128i state1 = _mm_xor_si128(state0, one); + // unlike the Go code, we don't have more per-process seed + __m128i state1 = _mm_aesenc_si128(state0, mseed2); + return state1; + } +} - // do simplified rounds of 32 bytes: unlike the Go code, we only - // scramble twice and we keep 256 bits of state - const auto srcend = src + (len / 32); - while (src < srcend) { - __m128i data0 = _mm_loadu_si128(src); - __m128i data1 = _mm_loadu_si128(src + 1); - state0 = _mm_xor_si128(data0, state0); - state1 = _mm_xor_si128(data1, state1); - state0 = _mm_aesenc_si128(state0, state0); - state1 = _mm_aesenc_si128(state1, state1); - state0 = _mm_aesenc_si128(state0, state0); - state1 = _mm_aesenc_si128(state1, state1); - src += 2; +static size_t QT_FUNCTION_TARGET(AES) QT_VECTORCALL +aeshash128_16to32(__m128i state0, __m128i state1, const __m128i *src, const __m128i *srcend) +{ + { + if (src + 1 < srcend) { + // epilogue: between 16 and 31 bytes + hash2x16bytes(state0, state1, src, srcend - 1); + } else if (src != srcend) { + // epilogue: between 1 and 16 bytes, overlap with the end + __m128i data = _mm_loadu_si128(srcend - 1); + hash16bytes(state0, data); } + + // combine results: state0 = _mm_xor_si128(state0, state1); } - len &= 0x1f; - // do we still have 16 or more bytes? - if (len & 0x10) { -lt32: - __m128i data = _mm_loadu_si128(src); - hash16bytes(state0, data); - ++src; - } - len &= 0xf; + return mm_cvtsi128_sz(state0); +} -lt16: +static size_t QT_FUNCTION_TARGET(AES) QT_VECTORCALL +aeshash128_lt16(__m128i state0, const uchar *p, size_t len) +{ if (len) { - // load the last chunk of data // We're going to load 16 bytes and mask zero the part we don't care // (the hash of a short string is different from the hash of a longer // including NULLs at the end because the length is in the key) // WARNING: this may produce valgrind warnings, but it's safe + constexpr quintptr PageSize = 4096; __m128i data; - if (Q_LIKELY(quintptr(src + 1) & 0xff0)) { - // same page, we definitely can't fault: + if ((quintptr(p) & (PageSize / 2)) == 0) { + // lower half of the page: // load all 16 bytes and mask off the bytes past the end of the source static const qint8 maskarray[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; + }; __m128i mask = _mm_loadu_si128(reinterpret_cast<const __m128i *>(maskarray + 15 - len)); - data = _mm_loadu_si128(src); + data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p)); data = _mm_and_si128(data, mask); } else { - // too close to the end of the page, it could fault: + // upper half of the page: // load 16 bytes ending at the data end, then shuffle them to the beginning static const qint8 shufflecontrol[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; __m128i control = _mm_loadu_si128(reinterpret_cast<const __m128i *>(shufflecontrol + 15 - len)); - p = reinterpret_cast<const uchar *>(src - 1); - data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p + len)); + data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p + len) - 1); data = _mm_shuffle_epi8(data, control); } hash16bytes(state0, data); } + return mm_cvtsi128_sz(state0); +} - // extract state0 -# if QT_POINTER_SIZE == 8 - return _mm_cvtsi128_si64(state0); -# else - return _mm_cvtsi128_si32(state0); +static size_t QT_FUNCTION_TARGET(AES) QT_VECTORCALL +aeshash128_ge32(__m128i state0, __m128i state1, const __m128i *src, const __m128i *srcend) +{ + // main loop: scramble two 16-byte blocks + for ( ; src + 2 < srcend; src += 2) + hash2x16bytes(state0, state1, src, src + 1); + + return aeshash128_16to32(state0, state1, src, srcend); +} + +# if QT_COMPILER_SUPPORTS_HERE(VAES) +static size_t QT_FUNCTION_TARGET(ARCH_ICL) QT_VECTORCALL +aeshash256_lt32_avx256(__m256i state0, const uchar *p, size_t len) +{ + __m128i state0_128 = _mm256_castsi256_si128(state0); + if (len) { + __mmask32 mask = _bzhi_u32(-1, unsigned(len)); + __m256i data = _mm256_maskz_loadu_epi8(mask, p); + __m128i data0 = _mm256_castsi256_si128(data); + if (len >= sizeof(__m128i)) { + state0 = _mm256_xor_si256(state0, data); + state0 = _mm256_aesenc_epi128(state0, state0); + state0 = _mm256_aesenc_epi128(state0, state0); + // we're XOR'ing the two halves so we skip the third AESENC + // state0 = _mm256_aesenc_epi128(state0, state0); + + // XOR the two halves and extract + __m128i low = _mm256_extracti128_si256(state0, 0); + __m128i high = _mm256_extracti128_si256(state0, 1); + state0_128 = _mm_xor_si128(low, high); + } else { + hash16bytes(state0_128, data0); + } + } + return mm_cvtsi128_sz(state0_128); +} + +static size_t QT_FUNCTION_TARGET(VAES) QT_VECTORCALL +aeshash256_ge32(__m256i state0, const uchar *p, size_t len) +{ + static const auto hash32bytes = [](__m256i &state0, __m256i data) QT_FUNCTION_TARGET(VAES) { + state0 = _mm256_xor_si256(state0, data); + state0 = _mm256_aesenc_epi128(state0, state0); + state0 = _mm256_aesenc_epi128(state0, state0); + state0 = _mm256_aesenc_epi128(state0, state0); + }; + + // hash twice 32 bytes, running 2 scramble rounds of AES on itself + const auto hash2x32bytes = [](__m256i &state0, __m256i &state1, const __m256i *src0, + const __m256i *src1) QT_FUNCTION_TARGET(VAES) { + __m256i data0 = _mm256_loadu_si256(src0); + __m256i data1 = _mm256_loadu_si256(src1); + state0 = _mm256_xor_si256(data0, state0); + state1 = _mm256_xor_si256(data1, state1); + state0 = _mm256_aesenc_epi128(state0, state0); + state1 = _mm256_aesenc_epi128(state1, state1); + state0 = _mm256_aesenc_epi128(state0, state0); + state1 = _mm256_aesenc_epi128(state1, state1); + }; + + const __m256i *src = reinterpret_cast<const __m256i *>(p); + const __m256i *srcend = reinterpret_cast<const __m256i *>(p + len); + + __m256i state1 = _mm256_aesenc_epi128(state0, mm256_set1_epz(len)); + + // main loop: scramble two 32-byte blocks + for ( ; src + 2 < srcend; src += 2) + hash2x32bytes(state0, state1, src, src + 1); + + if (src + 1 < srcend) { + // epilogue: between 32 and 31 bytes + hash2x32bytes(state0, state1, src, srcend - 1); + } else if (src != srcend) { + // epilogue: between 1 and 32 bytes, overlap with the end + __m256i data = _mm256_loadu_si256(srcend - 1); + hash32bytes(state0, data); + } + + // combine results: + state0 = _mm256_xor_si256(state0, state1); + + // XOR the two halves and extract + __m128i low = _mm256_extracti128_si256(state0, 0); + __m128i high = _mm256_extracti128_si256(state0, 1); + return mm_cvtsi128_sz(_mm_xor_si128(low, high)); +} + +static size_t QT_FUNCTION_TARGET(VAES) +aeshash256(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept +{ + AESHashSeed state(seed, seed2); + auto src = reinterpret_cast<const __m128i *>(p); + const auto srcend = reinterpret_cast<const __m128i *>(p + len); + + if (len < sizeof(__m128i)) + return aeshash128_lt16(state.state0, p, len); + + if (len <= sizeof(__m256i)) + return aeshash128_16to32(state.state0, state.state1(), src, srcend); + + return aeshash256_ge32(state.state0_256(), p, len); +} + +static size_t QT_FUNCTION_TARGET(VAES_AVX512) +aeshash256_avx256(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept +{ + AESHashSeed state(seed, seed2); + if (len <= sizeof(__m256i)) + return aeshash256_lt32_avx256(state.state0_256(), p, len); + + return aeshash256_ge32(state.state0_256(), p, len); +} +# endif // VAES + +static size_t QT_FUNCTION_TARGET(AES) +aeshash128(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept +{ + AESHashSeed state(seed, seed2); + auto src = reinterpret_cast<const __m128i *>(p); + const auto srcend = reinterpret_cast<const __m128i *>(p + len); + + if (len < sizeof(__m128i)) + return aeshash128_lt16(state.state0, p, len); + + if (len <= sizeof(__m256i)) + return aeshash128_16to32(state.state0, state.state1(), src, srcend); + + return aeshash128_ge32(state.state0, state.state1(), src, srcend); +} + +static size_t aeshash(const uchar *p, size_t len, size_t seed, size_t seed2) noexcept +{ +# if QT_COMPILER_SUPPORTS_HERE(VAES) + if (qCpuHasFeature(VAES)) { + if (qCpuHasFeature(AVX512VL)) + return aeshash256_avx256(p, len, seed, seed2); + return aeshash256(p, len, seed, seed2); + } # endif + return aeshash128(p, len, seed, seed2); } -#endif +#endif // x86 AESNI #if defined(Q_PROCESSOR_ARM) && QT_COMPILER_SUPPORTS_HERE(AES) && !defined(QHASH_AES_SANITIZER_BUILD) && !defined(QT_BOOTSTRAPPED) QT_FUNCTION_TARGET(AES) @@ -791,6 +950,7 @@ size_t qHashBits(const void *p, size_t size, size_t seed) noexcept # endif return aeshash(reinterpret_cast<const uchar *>(p), size, seed, seed2); #endif + if (size <= QT_POINTER_SIZE) return murmurhash(p, size, seed); @@ -825,13 +985,14 @@ size_t qHash(const QBitArray &bitArray, size_t seed) noexcept return result; } -size_t qHash(QLatin1String key, size_t seed) noexcept +size_t qHash(QLatin1StringView key, size_t seed) noexcept { return qHashBits(reinterpret_cast<const uchar *>(key.data()), size_t(key.size()), seed); } /*! \class QHashSeed + \inmodule QtCore \since 6.2 The QHashSeed class is used to convey the QHash seed. This is used @@ -1346,7 +1507,7 @@ size_t qHash(long double key, size_t seed) noexcept Returns the hash value for the \a key, using \a seed to seed the calculation. */ -/*! \fn size_t qHash(QLatin1String key, size_t seed = 0) +/*! \fn size_t qHash(QLatin1StringView key, size_t seed = 0) \relates QHash \since 5.0 @@ -2095,6 +2256,25 @@ size_t qHash(long double key, size_t seed) noexcept \sa constKeyValueBegin() */ +/*! \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() & + \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() const & + \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() && + \fn template <class Key, class T> auto QHash<Key, T>::asKeyValueRange() const && + \since 6.4 + + Returns a range object that allows iteration over this hash as + key/value pairs. For instance, this range object can be used in a + range-based for loop, in combination with a structured binding declaration: + + \snippet code/src_corelib_tools_qhash.cpp 34 + + Note that both the key and the value obtained this way are + references to the ones in the hash. Specifically, mutating the value + will modify the hash itself. + + \sa QKeyValueIterator +*/ + /*! \fn template <class Key, class T> QHash<Key, T>::iterator QHash<Key, T>::erase(const_iterator pos) \since 5.7 @@ -2175,9 +2355,6 @@ size_t qHash(long double key, size_t seed) noexcept If a key is common to both hashes, its value will be replaced with the value stored in \a other. - - \note If \a other contains multiple entries with the same key then the - final value of the key is undefined. */ /*! \fn template <class Key, class T> bool QHash<Key, T>::empty() const @@ -3239,6 +3416,24 @@ size_t qHash(long double key, size_t seed) noexcept \sa constKeyValueBegin() */ +/*! \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() & + \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() const & + \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() && + \fn template <class Key, class T> auto QMultiHash<Key, T>::asKeyValueRange() const && + \since 6.4 + + Returns a range object that allows iteration over this hash as + key/value pairs. For instance, this range object can be used in a + range-based for loop, in combination with a structured binding declaration: + + \snippet code/src_corelib_tools_qhash.cpp 35 + + Note that both the key and the value obtained this way are + references to the ones in the hash. Specifically, mutating the value + will modify the hash itself. + + \sa QKeyValueIterator +*/ /*! \class QMultiHash::iterator \inmodule QtCore diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 24fd24e603..5075459531 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2020 Klarälvdalens 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 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 QHASH_H #define QHASH_H @@ -254,6 +218,15 @@ constexpr bool isRelocatable() return QTypeInfo<typename Node::KeyType>::isRelocatable && QTypeInfo<typename Node::ValueType>::isRelocatable; } +struct SpanConstants { + static constexpr size_t SpanShift = 7; + static constexpr size_t NEntries = (1 << SpanShift); + static constexpr size_t LocalBucketMask = (NEntries - 1); + static constexpr size_t UnusedEntry = 0xff; + + static_assert ((NEntries & LocalBucketMask) == 0, "NEntries must be a power of two."); +}; + // Regular hash tables consist of a list of buckets that can store Nodes. But simply allocating one large array of buckets // would waste a lot of memory. To avoid this, we split the vector of buckets up into a vector of Spans. Each Span represents // NEntries buckets. To quickly find the correct Span that holds a bucket, NEntries must be a power of two. @@ -264,13 +237,6 @@ constexpr bool isRelocatable() // table have a very small memory overhead compared to many other implementations. template<typename Node> struct Span { - enum { - NEntries = 128, - LocalBucketMask = (NEntries - 1), - UnusedEntry = 0xff - }; - static_assert ((NEntries & LocalBucketMask) == 0, "EntriesPerSpan must be a power of two."); - // Entry is a slot available for storing a Node. The Span holds a pointer to // an array of Entries. Upon construction of the array, those entries are // unused, and nextFree() is being used to set up a singly linked list @@ -278,19 +244,19 @@ struct Span { // When a node gets inserted, the first free entry is being picked, removed // from the singly linked list and the Node gets constructed in place. struct Entry { - typename std::aligned_storage<sizeof(Node), alignof(Node)>::type storage; + struct { alignas(Node) unsigned char data[sizeof(Node)]; } storage; unsigned char &nextFree() { return *reinterpret_cast<unsigned char *>(&storage); } Node &node() { return *reinterpret_cast<Node *>(&storage); } }; - unsigned char offsets[NEntries]; + unsigned char offsets[SpanConstants::NEntries]; Entry *entries = nullptr; unsigned char allocated = 0; unsigned char nextFree = 0; Span() noexcept { - memset(offsets, UnusedEntry, sizeof(offsets)); + memset(offsets, SpanConstants::UnusedEntry, sizeof(offsets)); } ~Span() { @@ -301,7 +267,7 @@ struct Span { if (entries) { if constexpr (!std::is_trivially_destructible<Node>::value) { for (auto o : offsets) { - if (o != UnusedEntry) + if (o != SpanConstants::UnusedEntry) entries[o].node().~Node(); } } @@ -311,8 +277,8 @@ struct Span { } Node *insert(size_t i) { - Q_ASSERT(i <= NEntries); - Q_ASSERT(offsets[i] == UnusedEntry); + Q_ASSERT(i < SpanConstants::NEntries); + Q_ASSERT(offsets[i] == SpanConstants::UnusedEntry); if (nextFree == allocated) addStorage(); unsigned char entry = nextFree; @@ -323,11 +289,11 @@ struct Span { } void erase(size_t bucket) noexcept(std::is_nothrow_destructible<Node>::value) { - Q_ASSERT(bucket <= NEntries); - Q_ASSERT(offsets[bucket] != UnusedEntry); + Q_ASSERT(bucket < SpanConstants::NEntries); + Q_ASSERT(offsets[bucket] != SpanConstants::UnusedEntry); unsigned char entry = offsets[bucket]; - offsets[bucket] = UnusedEntry; + offsets[bucket] = SpanConstants::UnusedEntry; entries[entry].node().~Node(); entries[entry].nextFree() = nextFree; @@ -339,19 +305,19 @@ struct Span { } bool hasNode(size_t i) const noexcept { - return (offsets[i] != UnusedEntry); + return (offsets[i] != SpanConstants::UnusedEntry); } Node &at(size_t i) noexcept { - Q_ASSERT(i <= NEntries); - Q_ASSERT(offsets[i] != UnusedEntry); + Q_ASSERT(i < SpanConstants::NEntries); + Q_ASSERT(offsets[i] != SpanConstants::UnusedEntry); return entries[offsets[i]].node(); } const Node &at(size_t i) const noexcept { - Q_ASSERT(i <= NEntries); - Q_ASSERT(offsets[i] != UnusedEntry); + Q_ASSERT(i < SpanConstants::NEntries); + Q_ASSERT(offsets[i] != SpanConstants::UnusedEntry); return entries[offsets[i]].node(); } @@ -369,17 +335,17 @@ struct Span { } void moveLocal(size_t from, size_t to) noexcept { - Q_ASSERT(offsets[from] != UnusedEntry); - Q_ASSERT(offsets[to] == UnusedEntry); + Q_ASSERT(offsets[from] != SpanConstants::UnusedEntry); + Q_ASSERT(offsets[to] == SpanConstants::UnusedEntry); offsets[to] = offsets[from]; - offsets[from] = UnusedEntry; + offsets[from] = SpanConstants::UnusedEntry; } void moveFromSpan(Span &fromSpan, size_t fromIndex, size_t to) noexcept(std::is_nothrow_move_constructible_v<Node>) { - Q_ASSERT(to <= NEntries); - Q_ASSERT(offsets[to] == UnusedEntry); - Q_ASSERT(fromIndex <= NEntries); - Q_ASSERT(fromSpan.offsets[fromIndex] != UnusedEntry); + Q_ASSERT(to < SpanConstants::NEntries); + Q_ASSERT(offsets[to] == SpanConstants::UnusedEntry); + Q_ASSERT(fromIndex < SpanConstants::NEntries); + Q_ASSERT(fromSpan.offsets[fromIndex] != SpanConstants::UnusedEntry); if (nextFree == allocated) addStorage(); Q_ASSERT(nextFree < allocated); @@ -388,7 +354,7 @@ struct Span { nextFree = toEntry.nextFree(); size_t fromOffset = fromSpan.offsets[fromIndex]; - fromSpan.offsets[fromIndex] = UnusedEntry; + fromSpan.offsets[fromIndex] = SpanConstants::UnusedEntry; Entry &fromEntry = fromSpan.entries[fromOffset]; if constexpr (isRelocatable<Node>()) { @@ -403,15 +369,28 @@ struct Span { void addStorage() { - Q_ASSERT(allocated < NEntries); + Q_ASSERT(allocated < SpanConstants::NEntries); Q_ASSERT(nextFree == allocated); // the hash table should always be between 25 and 50% full // this implies that we on average have between 32 and 64 entries - // in here. The likelihood of having below 16 entries is very small, - // so start with that and increment by 16 each time we need to add - // some more space - const size_t increment = NEntries / 8; - size_t alloc = allocated + increment; + // in here. More exactly, we have a binominal distribution of the amount of + // occupied entries. + // For a 25% filled table, the average is 32 entries, with a 95% chance that we have between + // 23 and 41 entries. + // For a 50% filled table, the average is 64 entries, with a 95% chance that we have between + // 53 and 75 entries. + // Since we only resize the table once it's 50% filled and we want to avoid copies of + // data where possible, we initially allocate 48 entries, then resize to 80 entries, after that + // resize by increments of 16. That way, we usually only get one resize of the table + // while filling it. + size_t alloc; + static_assert(SpanConstants::NEntries % 8 == 0); + if (!allocated) + alloc = SpanConstants::NEntries / 8 * 3; + else if (allocated == SpanConstants::NEntries / 8 * 3) + alloc = SpanConstants::NEntries / 8 * 5; + else + alloc = allocated + SpanConstants::NEntries/8; Entry *newEntries = new Entry[alloc]; // we only add storage if the previous storage was fully filled, so // simply copy the old data over @@ -424,7 +403,7 @@ struct Span { entries[i].node().~Node(); } } - for (size_t i = allocated; i < allocated + increment; ++i) { + for (size_t i = allocated; i < alloc; ++i) { newEntries[i].nextFree() = uchar(i + 1); } delete[] entries; @@ -443,17 +422,17 @@ inline constexpr size_t maxNumBuckets() noexcept using Node3 = Node<qsizetype, QHashDummyValue>; static_assert(sizeof(Span<Node1>) == sizeof(Span<Node2>)); static_assert(sizeof(Span<Node1>) == sizeof(Span<Node3>)); - static_assert(int(Span<Node1>::NEntries) == int(Span<Node2>::NEntries)); - static_assert(int(Span<Node1>::NEntries) == int(Span<Node3>::NEntries)); // Maximum is 2^31-1 or 2^63-1 bytes (limited by qsizetype and ptrdiff_t) size_t max = (std::numeric_limits<ptrdiff_t>::max)(); - return max / sizeof(Span<Node1>) * Span<Node1>::NEntries; + return max / sizeof(Span<Node1>) * SpanConstants::NEntries; } inline constexpr size_t bucketsForCapacity(size_t requestedCapacity) noexcept { - if (requestedCapacity <= 8) - return 16; + // We want to use at minimum a full span (128 entries), so we hardcode it for any requested + // capacity <= 64. Any capacity above that gets rounded to a later power of two. + if (requestedCapacity <= 64) + return SpanConstants::NEntries; if (requestedCapacity >= maxNumBuckets()) return maxNumBuckets(); return qNextPowerOfTwo(QIntegerForSize<sizeof(size_t)>::Unsigned(2 * requestedCapacity - 1)); @@ -479,44 +458,126 @@ struct Data size_t size = 0; size_t numBuckets = 0; size_t seed = 0; + Span *spans = nullptr; + struct Bucket { + Span *span; + size_t index; + + Bucket(Span *s, size_t i) noexcept + : span(s), index(i) + {} + Bucket(const Data *d, size_t bucket) noexcept + : span(d->spans + (bucket >> SpanConstants::SpanShift)), + index(bucket & SpanConstants::LocalBucketMask) + {} + Bucket(iterator it) noexcept + : Bucket(it.d, it.bucket) + {} + + size_t toBucketIndex(const Data *d) const noexcept + { + return ((span - d->spans) << SpanConstants::SpanShift) | index; + } + iterator toIterator(const Data *d) const noexcept { return iterator{d, toBucketIndex(d)}; } + void advanceWrapped(const Data *d) noexcept + { + advance_impl(d, d->spans); + } + void advance(const Data *d) noexcept + { + advance_impl(d, nullptr); + } + bool isUnused() const noexcept + { + return !span->hasNode(index); + } + size_t offset() const noexcept + { + return span->offset(index); + } + Node &nodeAtOffset(size_t offset) + { + return span->atOffset(offset); + } + Node *node() + { + return &span->at(index); + } + Node *insert() const + { + return span->insert(index); + } - Span *spans = nullptr; + private: + friend bool operator==(Bucket lhs, Bucket rhs) noexcept + { + return lhs.span == rhs.span && lhs.index == rhs.index; + } + friend bool operator!=(Bucket lhs, Bucket rhs) noexcept { return !(lhs == rhs); } + + void advance_impl(const Data *d, Span *whenAtEnd) noexcept + { + Q_ASSERT(span); + ++index; + if (Q_UNLIKELY(index == SpanConstants::NEntries)) { + index = 0; + ++span; + if (span - d->spans == ptrdiff_t(d->numBuckets >> SpanConstants::SpanShift)) + span = whenAtEnd; + } + } + }; Data(size_t reserve = 0) { numBuckets = GrowthPolicy::bucketsForCapacity(reserve); - size_t nSpans = (numBuckets + Span::LocalBucketMask) / Span::NEntries; + size_t nSpans = numBuckets >> SpanConstants::SpanShift; spans = new Span[nSpans]; seed = QHashSeed::globalSeed(); } - Data(const Data &other, size_t reserved = 0) - : size(other.size), - numBuckets(other.numBuckets), - seed(other.seed) - { - if (reserved) - numBuckets = GrowthPolicy::bucketsForCapacity(qMax(size, reserved)); - bool resized = numBuckets != other.numBuckets; - size_t nSpans = (numBuckets + Span::LocalBucketMask) / Span::NEntries; - spans = new Span[nSpans]; - size_t otherNSpans = (other.numBuckets + Span::LocalBucketMask) / Span::NEntries; - for (size_t s = 0; s < otherNSpans; ++s) { + void reallocationHelper(const Data &other, size_t nSpans, bool resized) + { + for (size_t s = 0; s < nSpans; ++s) { const Span &span = other.spans[s]; - for (size_t index = 0; index < Span::NEntries; ++index) { + for (size_t index = 0; index < SpanConstants::NEntries; ++index) { if (!span.hasNode(index)) continue; const Node &n = span.at(index); - iterator it = resized ? find(n.key) : iterator{ this, s*Span::NEntries + index }; + auto it = resized ? findBucket(n.key) : Bucket { spans + s, index }; Q_ASSERT(it.isUnused()); - Node *newNode = spans[it.span()].insert(it.index()); + Node *newNode = it.insert(); new (newNode) Node(n); } } } - static Data *detached(Data *d, size_t size = 0) + Data(const Data &other) : size(other.size), numBuckets(other.numBuckets), seed(other.seed) + { + size_t nSpans = numBuckets >> SpanConstants::SpanShift; + spans = new Span[nSpans]; + reallocationHelper(other, nSpans, false); + } + Data(const Data &other, size_t reserved) : size(other.size), seed(other.seed) + { + numBuckets = GrowthPolicy::bucketsForCapacity(qMax(size, reserved)); + size_t nSpans = numBuckets >> SpanConstants::SpanShift; + spans = new Span[nSpans]; + size_t otherNSpans = other.numBuckets >> SpanConstants::SpanShift; + reallocationHelper(other, otherNSpans, true); + } + + static Data *detached(Data *d) + { + if (!d) + return new Data; + Data *dd = new Data(*d); + if (!d->ref.deref()) + delete d; + return dd; + } + static Data *detached(Data *d, size_t size) { if (!d) return new Data(size); @@ -560,20 +621,20 @@ struct Data Span *oldSpans = spans; size_t oldBucketCount = numBuckets; - size_t nSpans = (newBucketCount + Span::LocalBucketMask) / Span::NEntries; + size_t nSpans = newBucketCount >> SpanConstants::SpanShift; spans = new Span[nSpans]; numBuckets = newBucketCount; - size_t oldNSpans = (oldBucketCount + Span::LocalBucketMask) / Span::NEntries; + size_t oldNSpans = oldBucketCount >> SpanConstants::SpanShift; for (size_t s = 0; s < oldNSpans; ++s) { Span &span = oldSpans[s]; - for (size_t index = 0; index < Span::NEntries; ++index) { + for (size_t index = 0; index < SpanConstants::NEntries; ++index) { if (!span.hasNode(index)) continue; Node &n = span.at(index); - iterator it = find(n.key); + auto it = findBucket(n.key); Q_ASSERT(it.isUnused()); - Node *newNode = spans[it.span()].insert(it.index()); + Node *newNode = it.insert(); new (newNode) Node(std::move(n)); } span.freeData(); @@ -598,39 +659,44 @@ struct Data return size >= (numBuckets >> 1); } - iterator find(const Key &key) const noexcept + Bucket findBucket(const Key &key) const noexcept { Q_ASSERT(numBuckets > 0); size_t hash = QHashPrivate::calculateHash(key, seed); - size_t bucket = GrowthPolicy::bucketForHash(numBuckets, hash); + Bucket bucket(this, GrowthPolicy::bucketForHash(numBuckets, hash)); // loop over the buckets until we find the entry we search for // or an empty slot, in which case we know the entry doesn't exist while (true) { - // Split the bucket into the indexex of span array, and the local - // offset inside the span - size_t span = bucket / Span::NEntries; - size_t index = bucket & Span::LocalBucketMask; - Span &s = spans[span]; - size_t offset = s.offset(index); - if (offset == Span::UnusedEntry) { - return iterator{ this, bucket }; + size_t offset = bucket.offset(); + if (offset == SpanConstants::UnusedEntry) { + return bucket; } else { - Node &n = s.atOffset(offset); + Node &n = bucket.nodeAtOffset(offset); if (qHashEquals(n.key, key)) - return iterator{ this, bucket }; + return bucket; } - bucket = nextBucket(bucket); + bucket.advanceWrapped(this); } } Node *findNode(const Key &key) const noexcept { - if (!size) - return nullptr; - iterator it = find(key); - if (it.isUnused()) - return nullptr; - return it.node(); + Q_ASSERT(numBuckets > 0); + size_t hash = QHashPrivate::calculateHash(key, seed); + Bucket bucket(this, GrowthPolicy::bucketForHash(numBuckets, hash)); + // loop over the buckets until we find the entry we search for + // or an empty slot, in which case we know the entry doesn't exist + while (true) { + size_t offset = bucket.offset(); + if (offset == SpanConstants::UnusedEntry) { + return nullptr; + } else { + Node &n = bucket.nodeAtOffset(offset); + if (qHashEquals(n.key, key)) + return &n; + } + bucket.advanceWrapped(this); + } } struct InsertionResult @@ -641,62 +707,56 @@ struct Data InsertionResult findOrInsert(const Key &key) noexcept { - if (shouldGrow()) + Bucket it(static_cast<Span *>(nullptr), 0); + if (numBuckets > 0) { + it = findBucket(key); + if (!it.isUnused()) + return { it.toIterator(this), true }; + } + if (shouldGrow()) { rehash(size + 1); - iterator it = find(key); - if (it.isUnused()) { - spans[it.span()].insert(it.index()); - ++size; - return { it, false }; + it = findBucket(key); // need to get a new iterator after rehashing } - return { it, true }; + Q_ASSERT(it.span != nullptr); + Q_ASSERT(it.isUnused()); + it.insert(); + ++size; + return { it.toIterator(this), false }; } - iterator erase(iterator it) noexcept(std::is_nothrow_destructible<Node>::value) + void erase(Bucket bucket) noexcept(std::is_nothrow_destructible<Node>::value) { - size_t bucket = it.bucket; - size_t span = bucket / Span::NEntries; - size_t index = bucket & Span::LocalBucketMask; - Q_ASSERT(spans[span].hasNode(index)); - spans[span].erase(index); + Q_ASSERT(bucket.span->hasNode(bucket.index)); + bucket.span->erase(bucket.index); --size; // re-insert the following entries to avoid holes - size_t hole = bucket; - size_t next = bucket; + Bucket next = bucket; while (true) { - next = nextBucket(next); - size_t nextSpan = next / Span::NEntries; - size_t nextIndex = next & Span::LocalBucketMask; - if (!spans[nextSpan].hasNode(nextIndex)) - break; - size_t hash = QHashPrivate::calculateHash(spans[nextSpan].at(nextIndex).key, seed); - size_t newBucket = GrowthPolicy::bucketForHash(numBuckets, hash); + next.advanceWrapped(this); + size_t offset = next.offset(); + if (offset == SpanConstants::UnusedEntry) + return; + size_t hash = QHashPrivate::calculateHash(next.nodeAtOffset(offset).key, seed); + Bucket newBucket(this, GrowthPolicy::bucketForHash(numBuckets, hash)); while (true) { if (newBucket == next) { // nothing to do, item is at the right plae break; - } else if (newBucket == hole) { - // move into hole - size_t holeSpan = hole / Span::NEntries; - size_t holeIndex = hole & Span::LocalBucketMask; - if (nextSpan == holeSpan) { - spans[holeSpan].moveLocal(nextIndex, holeIndex); + } else if (newBucket == bucket) { + // move into the hole we created earlier + if (next.span == bucket.span) { + bucket.span->moveLocal(next.index, bucket.index); } else { // move between spans, more expensive - spans[holeSpan].moveFromSpan(spans[nextSpan], nextIndex, holeIndex); + bucket.span->moveFromSpan(*next.span, next.index, bucket.index); } - hole = next; + bucket = next; break; } - newBucket = nextBucket(newBucket); + newBucket.advanceWrapped(this); } } - - // return correct position of the next element - if (bucket == numBuckets - 1 || !spans[span].hasNode(index)) - ++it; - return it; } ~Data() @@ -712,8 +772,8 @@ struct iterator { const Data<Node> *d = nullptr; size_t bucket = 0; - size_t span() const noexcept { return bucket / Span::NEntries; } - size_t index() const noexcept { return bucket & Span::LocalBucketMask; } + size_t span() const noexcept { return bucket >> SpanConstants::SpanShift; } + size_t index() const noexcept { return bucket & SpanConstants::LocalBucketMask; } inline bool isUnused() const noexcept { return !d->spans[span()].hasNode(index()); } inline Node *node() const noexcept @@ -829,7 +889,7 @@ public: insert(f->first, f->second); } #endif - void swap(QHash &other) noexcept { qSwap(d, other.d); } + void swap(QHash &other) noexcept { qt_ptr_swap(d, other.d); } #ifndef Q_CLANG_QDOC template <typename AKey = Key, typename AT = T> @@ -862,6 +922,9 @@ public: inline qsizetype capacity() const noexcept { return d ? qsizetype(d->numBuckets >> 1) : 0; } void reserve(qsizetype size) { + // reserve(0) is used in squeeze() + if (size && (this->capacity() >= size)) + return; if (isDetached()) d->rehash(size); else @@ -888,9 +951,10 @@ public: { if (isEmpty()) // prevents detaching shared null return false; - auto it = d->find(key); + auto it = d->findBucket(key); + size_t bucket = it.toBucketIndex(d); detach(); - it = d->detachedIterator(it); + it = typename Data::Bucket(d, bucket); // reattach in case of detach if (it.isUnused()) return false; @@ -906,9 +970,10 @@ public: { if (isEmpty()) // prevents detaching shared null return T(); - auto it = d->find(key); + auto it = d->findBucket(key); + size_t bucket = it.toBucketIndex(d); detach(); - it = d->detachedIterator(it); + it = typename Data::Bucket(d, bucket); // reattach in case of detach if (it.isUnused()) return T(); @@ -1144,6 +1209,10 @@ public: inline const_key_value_iterator constKeyValueBegin() const noexcept { return const_key_value_iterator(begin()); } inline const_key_value_iterator keyValueEnd() const noexcept { return const_key_value_iterator(end()); } inline const_key_value_iterator constKeyValueEnd() const noexcept { return const_key_value_iterator(end()); } + auto asKeyValueRange() & { return QtPrivate::QKeyValueRange(*this); } + auto asKeyValueRange() const & { return QtPrivate::QKeyValueRange(*this); } + auto asKeyValueRange() && { return QtPrivate::QKeyValueRange(std::move(*this)); } + auto asKeyValueRange() const && { return QtPrivate::QKeyValueRange(std::move(*this)); } iterator erase(const_iterator it) { @@ -1151,8 +1220,11 @@ public: detach(); // ensure a valid iterator across the detach: iterator i = iterator{d->detachedIterator(it.i)}; + typename Data::Bucket bucket(i.i); - i.i = d->erase(i.i); + d->erase(bucket); + if (bucket.toBucketIndex(d) == d->numBuckets - 1 || bucket.isUnused()) + ++i; return i; } @@ -1181,21 +1253,22 @@ public: { if (isEmpty()) // prevents detaching shared null return end(); - auto it = d->find(key); + auto it = d->findBucket(key); + size_t bucket = it.toBucketIndex(d); detach(); - it = d->detachedIterator(it); + it = typename Data::Bucket(d, bucket); // reattach in case of detach if (it.isUnused()) - it = d->end(); - return iterator(it); + return end(); + return iterator(it.toIterator(d)); } const_iterator find(const Key &key) const noexcept { if (isEmpty()) return end(); - auto it = d->find(key); + auto it = d->findBucket(key); if (it.isUnused()) - it = d->end(); - return const_iterator(it); + return end(); + return const_iterator({d, it.toBucketIndex(d)}); } const_iterator constFind(const Key &key) const noexcept { @@ -1358,7 +1431,12 @@ public: { unite(std::move(other)); } - void swap(QMultiHash &other) noexcept { qSwap(d, other.d); qSwap(m_size, other.m_size); } + + void swap(QMultiHash &other) noexcept + { + qt_ptr_swap(d, other.d); + std::swap(m_size, other.m_size); + } #ifndef Q_CLANG_QDOC template <typename AKey = Key, typename AT = T> @@ -1410,6 +1488,9 @@ public: inline qsizetype capacity() const noexcept { return d ? qsizetype(d->numBuckets >> 1) : 0; } void reserve(qsizetype size) { + // reserve(0) is used in squeeze() + if (size && (this->capacity() >= size)) + return; if (isDetached()) d->rehash(size); else @@ -1433,9 +1514,10 @@ public: { if (isEmpty()) // prevents detaching shared null return 0; - auto it = d->find(key); + auto it = d->findBucket(key); + size_t bucket = it.toBucketIndex(d); detach(); - it = d->detachedIterator(it); + it = typename Data::Bucket(d, bucket); // reattach in case of detach if (it.isUnused()) return 0; @@ -1454,9 +1536,10 @@ public: { if (isEmpty()) // prevents detaching shared null return T(); - auto it = d->find(key); + auto it = d->findBucket(key); + size_t bucket = it.toBucketIndex(d); detach(); - it = d->detachedIterator(it); + it = typename Data::Bucket(d, bucket); // reattach in case of detach if (it.isUnused()) return T(); @@ -1748,6 +1831,10 @@ public: inline const_key_value_iterator constKeyValueBegin() const noexcept { return const_key_value_iterator(begin()); } inline const_key_value_iterator keyValueEnd() const noexcept { return const_key_value_iterator(end()); } inline const_key_value_iterator constKeyValueEnd() const noexcept { return const_key_value_iterator(end()); } + auto asKeyValueRange() & { return QtPrivate::QKeyValueRange(*this); } + auto asKeyValueRange() const & { return QtPrivate::QKeyValueRange(*this); } + auto asKeyValueRange() && { return QtPrivate::QKeyValueRange(std::move(*this)); } + auto asKeyValueRange() const && { return QtPrivate::QKeyValueRange(std::move(*this)); } iterator detach(const_iterator it) { @@ -1778,7 +1865,8 @@ public: iterator erase(const_iterator it) { Q_ASSERT(d); - iterator i = detach(it); + iterator iter = detach(it); + iterator i = iter; Chain *e = *i.e; Chain *next = e->next; *i.e = next; @@ -1786,9 +1874,14 @@ public: if (!next) { if (i.e == &i.i.node()->value) { // last remaining entry, erase - i = iterator(d->erase(i.i)); + typename Data::Bucket bucket(i.i); + d->erase(bucket); + if (bucket.toBucketIndex(d) == d->numBuckets - 1 || bucket.isUnused()) + i = iterator(++iter.i); + else // 'i' currently has a nullptr chain. So, we must recreate it + i = iterator(bucket.toIterator(d)); } else { - i = iterator(++it.i); + i = iterator(++iter.i); } } --m_size; @@ -1804,13 +1897,14 @@ public: { if (isEmpty()) return end(); - auto it = d->find(key); + auto it = d->findBucket(key); + size_t bucket = it.toBucketIndex(d); detach(); - it = d->detachedIterator(it); + it = typename Data::Bucket(d, bucket); // reattach in case of detach if (it.isUnused()) - it = d->end(); - return iterator(it); + return end(); + return iterator(it.toIterator(d)); } const_iterator find(const Key &key) const noexcept { @@ -1820,10 +1914,10 @@ public: { if (isEmpty()) return end(); - auto it = d->find(key); + auto it = d->findBucket(key); if (it.isUnused()) - it = d->end(); - return const_iterator(it); + return constEnd(); + return const_iterator(it.toIterator(d)); } iterator insert(const Key &key, const T &value) { @@ -1902,9 +1996,10 @@ public: { if (isEmpty()) // prevents detaching shared null return 0; - auto it = d->find(key); + auto it = d->findBucket(key); + size_t bucket = it.toBucketIndex(d); detach(); - it = d->detachedIterator(it); + it = typename Data::Bucket(d, bucket); // reattach in case of detach if (it.isUnused()) return 0; @@ -1931,7 +2026,7 @@ public: { if (!d) return 0; - auto it = d->find(key); + auto it = d->findBucket(key); if (it.isUnused()) return 0; qsizetype n = 0; @@ -1948,7 +2043,7 @@ public: { if (!d) return 0; - auto it = d->find(key); + auto it = d->findBucket(key); if (it.isUnused()) return 0; qsizetype n = 0; @@ -2035,9 +2130,10 @@ public: if (!d) return qMakePair(end(), end()); - auto it = d->find(key); - if (it.isUnused()) + auto bucket = d->findBucket(key); + if (bucket.isUnused()) return qMakePair(end(), end()); + auto it = bucket.toIterator(d); auto end = it; ++end; return qMakePair(const_iterator(it), const_iterator(end)); diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h index 4f8e4066ee..04d165983d 100644 --- a/src/corelib/tools/qhashfunctions.h +++ b/src/corelib/tools/qhashfunctions.h @@ -1,47 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> -** Contact: 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) 2015 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 QHASHFUNCTIONS_H #define QHASHFUNCTIONS_H #include <QtCore/qstring.h> +#include <QtCore/qstringfwd.h> #include <QtCore/qpair.h> #include <numeric> // for std::accumulate @@ -60,9 +25,6 @@ QT_BEGIN_NAMESPACE class QBitArray; -class QByteArray; -class QString; -class QLatin1String; #if QT_DEPRECATED_SINCE(6,6) QT_DEPRECATED_VERSION_X_6_6("Use QHashSeed instead") @@ -76,7 +38,7 @@ struct QHashSeed constexpr QHashSeed(size_t d = 0) : data(d) {} constexpr operator size_t() const noexcept { return data; } - static Q_CORE_EXPORT QHashSeed globalSeed() noexcept Q_DECL_PURE_FUNCTION; + static Q_CORE_EXPORT QHashSeed globalSeed() noexcept; static Q_CORE_EXPORT void setDeterministicGlobalSeed(); static Q_CORE_EXPORT void resetRandomGlobalSeed(); private: @@ -190,7 +152,7 @@ inline Q_DECL_PURE_FUNCTION size_t qHash(const QString &key, size_t seed = 0) no { return qHash(QStringView{key}, seed); } #endif Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QBitArray &key, size_t seed = 0) noexcept; -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(QLatin1String key, size_t seed = 0) noexcept; +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(QLatin1StringView key, size_t seed = 0) noexcept; Q_DECL_CONST_FUNCTION constexpr inline size_t qHash(QKeyCombination key, size_t seed = 0) noexcept { return qHash(key.toCombined(), seed); } Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(QStringView key, uint chained = 0) noexcept; @@ -251,6 +213,9 @@ struct QNothrowHashable : std::false_type {}; template <typename T> struct QNothrowHashable<T, std::enable_if_t<QNothrowHashableHelper_v<T>>> : std::true_type {}; +template <typename T> +constexpr inline bool QNothrowHashable_v = QNothrowHashable<T>::value; + } // namespace QtPrivate template <typename... T> @@ -317,15 +282,15 @@ template <typename T1, typename T2> inline size_t qHash(const std::pair<T1, T2> using argument_type = QT_PREPEND_NAMESPACE(Class); \ using result_type = size_t; \ size_t operator()(Arguments s) const \ - noexcept(noexcept(QT_PREPEND_NAMESPACE(qHash)(s))) \ + noexcept(QT_PREPEND_NAMESPACE( \ + QtPrivate::QNothrowHashable_v)<argument_type>) \ { \ /* this seeds qHash with the result of */ \ /* std::hash applied to an int, to reap */ \ /* any protection against predictable hash */ \ /* values the std implementation may provide */ \ - return QT_PREPEND_NAMESPACE(qHash)(s, \ - QT_PREPEND_NAMESPACE(qHash)( \ - std::hash<int>{}(0))); \ + using QT_PREPEND_NAMESPACE(qHash); \ + return qHash(s, qHash(std::hash<int>{}(0))); \ } \ }; \ } \ @@ -339,7 +304,8 @@ template <typename T1, typename T2> inline size_t qHash(const std::pair<T1, T2> QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QString) QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_VALUE(QStringView) -QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_VALUE(QLatin1String) +QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_VALUE(QLatin1StringView) +QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_VALUE(QByteArrayView) QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QByteArray) QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QBitArray) diff --git a/src/corelib/tools/qiterator.h b/src/corelib/tools/qiterator.h index 8922f34758..cff535d030 100644 --- a/src/corelib/tools/qiterator.h +++ b/src/corelib/tools/qiterator.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 QITERATOR_H #define QITERATOR_H @@ -301,6 +265,47 @@ private: Iterator i; }; +namespace QtPrivate { + +template <typename Map> +class QKeyValueRangeStorage +{ +protected: + Map m_map; +public: + explicit QKeyValueRangeStorage(const Map &map) : m_map(map) {} + explicit QKeyValueRangeStorage(Map &&map) : m_map(std::move(map)) {} +}; + +template <typename Map> +class QKeyValueRangeStorage<Map &> +{ +protected: + Map &m_map; +public: + explicit QKeyValueRangeStorage(Map &map) : m_map(map) {} +}; + +template <typename Map> +class QKeyValueRange : public QKeyValueRangeStorage<Map> +{ +public: + using QKeyValueRangeStorage<Map>::QKeyValueRangeStorage; + auto begin() { return this->m_map.keyValueBegin(); } + auto begin() const { return this->m_map.keyValueBegin(); } + auto end() { return this->m_map.keyValueEnd(); } + auto end() const { return this->m_map.keyValueEnd(); } +}; + +template <typename Map> +QKeyValueRange(Map &) -> QKeyValueRange<Map &>; + +template <typename Map, std::enable_if_t<!std::is_reference_v<Map>, bool> = false> +QKeyValueRange(Map &&) -> QKeyValueRange<std::remove_const_t<Map>>; + +} // namespace QtPrivate + + QT_END_NAMESPACE #endif // QITERATOR_H diff --git a/src/corelib/tools/qiterator.qdoc b/src/corelib/tools/qiterator.qdoc index 1ba5b66318..f4286c99ea 100644 --- a/src/corelib/tools/qiterator.qdoc +++ b/src/corelib/tools/qiterator.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \class QKeyValueIterator \inmodule QtCore diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index bbedfa948e..9216b8875b 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -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) 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 "qline.h" @@ -263,6 +227,15 @@ QT_BEGIN_NAMESPACE \sa setP1(), setP2(), p1(), p2() */ +/*! + \fn QLine::toLineF() const + \since 6.4 + + Returns this line as a line with floating point accuracy. + + \sa QLineF::toLine() +*/ + #ifndef QT_NO_DEBUG_STREAM @@ -423,7 +396,7 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) Construct a QLineF object from the given integer-based \a line. - \sa toLine() + \sa toLine(), QLine::toLineF() */ /*! @@ -463,7 +436,7 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) Note that the returned line's start and end points are rounded to the nearest integer. - \sa QLineF() + \sa QLineF(), QLine::toLineF() */ /*! \fn qreal QLineF::x1() const diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h index 426d69cd6d..5961d5a57e 100644 --- a/src/corelib/tools/qline.h +++ b/src/corelib/tools/qline.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) 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 QLINE_H #define QLINE_H @@ -44,6 +8,7 @@ QT_BEGIN_NAMESPACE +class QLineF; /******************************************************************************* * class QLine @@ -86,6 +51,8 @@ public: constexpr inline bool operator==(const QLine &d) const noexcept; constexpr inline bool operator!=(const QLine &d) const noexcept { return !(*this == d); } + [[nodiscard]] constexpr inline QLineF toLineF() const noexcept; + private: QPoint pt1, pt2; }; @@ -386,6 +353,8 @@ constexpr inline QPointF QLineF::pointAt(qreal t) const return QPointF(pt1.x() + (pt2.x() - pt1.x()) * t, pt1.y() + (pt2.y() - pt1.y()) * t); } +constexpr inline QLineF QLine::toLineF() const noexcept { return *this; } + constexpr inline QLine QLineF::toLine() const { return QLine(pt1.toPoint(), pt2.toPoint()); diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 9b2a56a66a..0cc62e5f6e 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** 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 QLIST_H #define QLIST_H @@ -147,12 +111,10 @@ public: using value_type = T; // libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346 #if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11) - using iterator_category = std::contiguous_iterator_tag; + using iterator_concept = std::contiguous_iterator_tag; using element_type = value_type; -#else - using iterator_category = std::random_access_iterator_tag; #endif - + using iterator_category = std::random_access_iterator_tag; using pointer = T *; using reference = T &; @@ -220,11 +182,10 @@ public: using value_type = T; // libstdc++ shipped with gcc < 11 does not have a fix for defect LWG 3346 #if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11) - using iterator_category = std::contiguous_iterator_tag; + using iterator_concept = std::contiguous_iterator_tag; using element_type = const value_type; -#else - using iterator_category = std::random_access_iterator_tag; #endif + using iterator_category = std::random_access_iterator_tag; using pointer = const T *; using reference = const T &; @@ -329,7 +290,7 @@ public: template <typename InputIterator, QtPrivate::IfIsInputIterator<InputIterator> = true> QList(InputIterator i1, InputIterator i2) { - if constexpr (!std::is_convertible_v<typename std::iterator_traits<Iterator>::iterator_category, std::forward_iterator_tag>) { + if constexpr (!std::is_convertible_v<typename std::iterator_traits<InputIterator>::iterator_category, std::forward_iterator_tag>) { std::copy(i1, i2, std::back_inserter(*this)); } else { const auto distance = std::distance(i1, i2); @@ -354,7 +315,7 @@ public: // compiler-generated special member functions are fine! - void swap(QList<T> &other) noexcept { qSwap(d, other.d); } + void swap(QList &other) noexcept { d.swap(other.d); } #ifndef Q_CLANG_QDOC template <typename U = T> @@ -585,7 +546,7 @@ public: template <typename AT = T> qsizetype count(const AT &t) const noexcept { - return qsizetype(std::count(&*cbegin(), &*cend(), t)); + return qsizetype(std::count(data(), data() + size(), t)); } void removeAt(qsizetype i) { remove(i); } diff --git a/src/corelib/tools/qlist.qdoc b/src/corelib/tools/qlist.qdoc index 4e92e2c047..e8e5a73596 100644 --- a/src/corelib/tools/qlist.qdoc +++ b/src/corelib/tools/qlist.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \class QVector diff --git a/src/corelib/tools/qmakearray_p.h b/src/corelib/tools/qmakearray_p.h index 4ed8c16234..17014c23b9 100644 --- a/src/corelib/tools/qmakearray_p.h +++ b/src/corelib/tools/qmakearray_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) 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 QMAKEARRAY_P_H #define QMAKEARRAY_P_H @@ -51,7 +15,7 @@ // We mean it. // -#include "QtCore/qglobal.h" +#include "QtCore/private/qglobal_p.h" #include <array> #include <type_traits> diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index f2f1bc96f4..9ba01bee2c 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> -** 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) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +// 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 QMAP_H #define QMAP_H @@ -238,7 +202,7 @@ public: void swap(QMap<Key, T> &other) noexcept { - qSwap(d, other.d); + d.swap(other.d); } QMap(std::initializer_list<std::pair<Key, T>> list) @@ -646,6 +610,10 @@ public: const_key_value_iterator constKeyValueBegin() const { return const_key_value_iterator(begin()); } const_key_value_iterator keyValueEnd() const { return const_key_value_iterator(end()); } const_key_value_iterator constKeyValueEnd() const { return const_key_value_iterator(end()); } + auto asKeyValueRange() & { return QtPrivate::QKeyValueRange(*this); } + auto asKeyValueRange() const & { return QtPrivate::QKeyValueRange(*this); } + auto asKeyValueRange() && { return QtPrivate::QKeyValueRange(std::move(*this)); } + auto asKeyValueRange() const && { return QtPrivate::QKeyValueRange(std::move(*this)); } iterator erase(const_iterator it) { @@ -849,7 +817,7 @@ public: void swap(QMultiMap<Key, T> &other) noexcept { - qSwap(d, other.d); + d.swap(other.d); } explicit QMultiMap(const QMap<Key, T> &other) @@ -1341,6 +1309,10 @@ public: const_key_value_iterator constKeyValueBegin() const { return const_key_value_iterator(begin()); } const_key_value_iterator keyValueEnd() const { return const_key_value_iterator(end()); } const_key_value_iterator constKeyValueEnd() const { return const_key_value_iterator(end()); } + auto asKeyValueRange() & { return QtPrivate::QKeyValueRange(*this); } + auto asKeyValueRange() const & { return QtPrivate::QKeyValueRange(*this); } + auto asKeyValueRange() && { return QtPrivate::QKeyValueRange(std::move(*this)); } + auto asKeyValueRange() const && { return QtPrivate::QKeyValueRange(std::move(*this)); } iterator erase(const_iterator it) { diff --git a/src/corelib/tools/qmap.qdoc b/src/corelib/tools/qmap.qdoc index 55c2bcb5d9..5d0825708b 100644 --- a/src/corelib/tools/qmap.qdoc +++ b/src/corelib/tools/qmap.qdoc @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> -** 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 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +// 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 /*! \class QMap @@ -243,7 +207,7 @@ \sa toStdMap() */ -/*! \fn template <class Key, class T> std::map<Key, T> QMap<Key, T>::toStdMap() const +/*! \fn template <class Key, class T> std::map<Key, T> QMap<Key, T>::toStdMap() const & Returns an STL map equivalent to this QMap. */ @@ -663,6 +627,25 @@ \sa constKeyValueBegin() */ +/*! \fn template <class Key, class T> auto QMap<Key, T>::asKeyValueRange() & + \fn template <class Key, class T> auto QMap<Key, T>::asKeyValueRange() const & + \fn template <class Key, class T> auto QMap<Key, T>::asKeyValueRange() && + \fn template <class Key, class T> auto QMap<Key, T>::asKeyValueRange() const && + \since 6.4 + + Returns a range object that allows iteration over this map as + key/value pairs. For instance, this range object can be used in a + range-based for loop, in combination with a structured binding declaration: + + \snippet code/src_corelib_tools_qmap.cpp 28 + + Note that both the key and the value obtained this way are + references to the ones in the map. Specifically, mutating the value + will modify the map itself. + + \sa QKeyValueIterator +*/ + /*! \fn template <class Key, class T> QMap<Key, T>::iterator QMap<Key, T>::erase(const_iterator pos) Removes the (key, value) pair pointed to by the iterator \a pos diff --git a/src/corelib/tools/qmargins.cpp b/src/corelib/tools/qmargins.cpp index 8f18528ce2..3cc17b1824 100644 --- a/src/corelib/tools/qmargins.cpp +++ b/src/corelib/tools/qmargins.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) 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 "qmargins.h" #include "qdatastream.h" @@ -406,6 +370,15 @@ QT_BEGIN_NAMESPACE \since 5.1 */ +/*! + \fn QMargins::toMarginsF() const + \since 6.4 + + Returns these margins as margins with floating point accuracy. + + \sa QMarginsF::toMargins() +*/ + /***************************************************************************** QMargins stream functions *****************************************************************************/ @@ -500,7 +473,9 @@ QDebug operator<<(QDebug dbg, const QMargins &m) /*! \fn QMarginsF::QMarginsF(const QMargins &margins) - Constructs margins copied from the given \a margins + Constructs margins copied from the given \a margins. + + \sa QMargins::toMarginsF() */ /*! @@ -768,7 +743,7 @@ QDebug operator<<(QDebug dbg, const QMargins &m) Note that the components in the returned margins will be rounded to the nearest integer. - \sa QMarginsF() + \sa QMarginsF(), QMargins::toMarginsF() */ /***************************************************************************** diff --git a/src/corelib/tools/qmargins.h b/src/corelib/tools/qmargins.h index cf40b89ee0..2d494f4417 100644 --- a/src/corelib/tools/qmargins.h +++ b/src/corelib/tools/qmargins.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) 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 QMARGINS_H #define QMARGINS_H @@ -44,6 +8,8 @@ QT_BEGIN_NAMESPACE +class QMarginsF; + /***************************************************************************** QMargins class *****************************************************************************/ @@ -75,6 +41,8 @@ public: constexpr QMargins &operator*=(qreal) noexcept; constexpr QMargins &operator/=(qreal); + [[nodiscard]] constexpr inline QMarginsF toMarginsF() const noexcept; + private: int m_left; int m_top; @@ -516,6 +484,8 @@ constexpr inline QMarginsF operator-(const QMarginsF &margins) noexcept return QMarginsF(-margins.left(), -margins.top(), -margins.right(), -margins.bottom()); } +constexpr QMarginsF QMargins::toMarginsF() const noexcept { return *this; } + constexpr inline QMargins QMarginsF::toMargins() const noexcept { return QMargins(qRound(m_left), qRound(m_top), qRound(m_right), qRound(m_bottom)); diff --git a/src/corelib/tools/qmessageauthenticationcode.cpp b/src/corelib/tools/qmessageauthenticationcode.cpp index 767a7a14d4..4ff48fc822 100644 --- a/src/corelib/tools/qmessageauthenticationcode.cpp +++ b/src/corelib/tools/qmessageauthenticationcode.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Ruslan Nigmatullin <euroelessar@yandex.ru> -** 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) 2013 Ruslan Nigmatullin <euroelessar@yandex.ru> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qmessageauthenticationcode.h" #include "qvarlengtharray.h" diff --git a/src/corelib/tools/qmessageauthenticationcode.h b/src/corelib/tools/qmessageauthenticationcode.h index 343bf9d617..c1e50b5668 100644 --- a/src/corelib/tools/qmessageauthenticationcode.h +++ b/src/corelib/tools/qmessageauthenticationcode.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Ruslan Nigmatullin <euroelessar@yandex.ru> -** 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) 2013 Ruslan Nigmatullin <euroelessar@yandex.ru> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QMESSAGEAUTHENTICATIONCODE_H #define QMESSAGEAUTHENTICATIONCODE_H diff --git a/src/corelib/tools/qmultimap.qdoc b/src/corelib/tools/qmultimap.qdoc index 6bfc1515e6..f4751fdc45 100644 --- a/src/corelib/tools/qmultimap.qdoc +++ b/src/corelib/tools/qmultimap.qdoc @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> -** 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 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +// 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 /*! \class QMultiMap @@ -246,7 +210,7 @@ Returns an STL multi map equivalent to this QMultiMap. */ -/*! \fn template <class Key, class T> std::multimap<Key, T> QMultiMap<Key, T>::toStdMultiMap() const +/*! \fn template <class Key, class T> std::multimap<Key, T> QMultiMap<Key, T>::toStdMultiMap() const & Returns an STL multi map equivalent to this QMultiMap. */ @@ -693,6 +657,25 @@ \sa constKeyValueBegin() */ +/*! \fn template <class Key, class T> auto QMultiMap<Key, T>::asKeyValueRange() & + \fn template <class Key, class T> auto QMultiMap<Key, T>::asKeyValueRange() const & + \fn template <class Key, class T> auto QMultiMap<Key, T>::asKeyValueRange() && + \fn template <class Key, class T> auto QMultiMap<Key, T>::asKeyValueRange() const && + \since 6.4 + + Returns a range object that allows iteration over this multi map as + key/value pairs. For instance, this range object can be used in a + range-based for loop, in combination with a structured binding declaration: + + \snippet code/src_corelib_tools_qmultimap.cpp 26 + + Note that both the key and the value obtained this way are + references to the ones in the multi map. Specifically, mutating the value + will modify the map itself. + + \sa QKeyValueIterator +*/ + /*! \fn template <class Key, class T> QMultiMap<Key, T>::iterator QMultiMap<Key, T>::erase(const_iterator pos) Removes the (key, value) pair pointed to by the iterator \a pos diff --git a/src/corelib/tools/qoffsetstringarray_p.h b/src/corelib/tools/qoffsetstringarray_p.h index b7c7495c70..a3b56badc6 100644 --- a/src/corelib/tools/qoffsetstringarray_p.h +++ b/src/corelib/tools/qoffsetstringarray_p.h @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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) 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 QOFFSETSTRINGARRAY_P_H #define QOFFSETSTRINGARRAY_P_H @@ -66,7 +30,7 @@ class tst_QOffsetStringArray; QT_BEGIN_NAMESPACE QT_WARNING_PUSH -#if defined(Q_CC_GNU) && Q_CC_GNU >= 900 +#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1100 // we usually don't overread, but GCC has a false positive QT_WARNING_DISABLE_GCC("-Wstringop-overread") #endif @@ -117,9 +81,9 @@ static constexpr OO copyData(II input, qsizetype n, OO output) template <size_t Highest> constexpr auto minifyValue() { - if constexpr (Highest <= std::numeric_limits<quint8>::max()) { + if constexpr (Highest <= (std::numeric_limits<quint8>::max)()) { return quint8(Highest); - } else if constexpr (Highest <= std::numeric_limits<quint16>::max()) { + } else if constexpr (Highest <= (std::numeric_limits<quint16>::max)()) { return quint16(Highest); } else { // int is probably enough for everyone diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h index 6cb7fc5079..75efaed3cf 100644 --- a/src/corelib/tools/qpair.h +++ b/src/corelib/tools/qpair.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 QPAIR_H #define QPAIR_H diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc index 3cd1beec18..3aaee157d4 100644 --- a/src/corelib/tools/qpair.qdoc +++ b/src/corelib/tools/qpair.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \typealias QPair diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp index 80599a4caa..d1f3b12a68 100644 --- a/src/corelib/tools/qpoint.cpp +++ b/src/corelib/tools/qpoint.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) 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 "qpoint.h" #include "qdatastream.h" @@ -381,6 +345,15 @@ QT_BEGIN_NAMESPACE \sa QPoint::operator/=() */ +/*! + \fn QPoint::toPointF() const + \since 6.4 + + Returns this point as a point with floating point accuracy. + + \sa QPointF::toPoint() +*/ + /***************************************************************************** QPoint stream functions *****************************************************************************/ @@ -532,7 +505,7 @@ size_t qHash(QPoint key, size_t seed) noexcept Constructs a copy of the given \a point. - \sa toPoint() + \sa toPoint(), QPoint::toPointF() */ /*! @@ -744,7 +717,7 @@ size_t qHash(QPoint key, size_t seed) noexcept Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rounded coordinates. - \sa QPointF() + \sa QPointF(), QPoint::toPointF() */ /*! diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h index f2c562393a..48c5e91f62 100644 --- a/src/corelib/tools/qpoint.h +++ b/src/corelib/tools/qpoint.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) 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 QPOINT_H #define QPOINT_H @@ -48,6 +12,8 @@ struct CGPoint; QT_BEGIN_NAMESPACE +class QPointF; + class QPoint { public: @@ -110,6 +76,7 @@ public: #if defined(Q_OS_DARWIN) || defined(Q_QDOC) [[nodiscard]] Q_CORE_EXPORT CGPoint toCGPoint() const noexcept; #endif + [[nodiscard]] constexpr inline QPointF toPointF() const noexcept; private: friend class QTransform; @@ -417,6 +384,8 @@ constexpr inline QPointF &QPointF::operator/=(qreal divisor) return *this; } +constexpr QPointF QPoint::toPointF() const noexcept { return *this; } + constexpr inline QPoint QPointF::toPoint() const { return QPoint(qRound(xp), qRound(yp)); diff --git a/src/corelib/tools/qqueue.cpp b/src/corelib/tools/qqueue.cpp index ffc48d6714..82095faa3d 100644 --- a/src/corelib/tools/qqueue.cpp +++ b/src/corelib/tools/qqueue.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 /*! \class QQueue diff --git a/src/corelib/tools/qqueue.h b/src/corelib/tools/qqueue.h index 862aa2ae2c..4863499f2a 100644 --- a/src/corelib/tools/qqueue.h +++ b/src/corelib/tools/qqueue.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 QQUEUE_H #define QQUEUE_H diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp index 64ccdb20ff..6d345ce543 100644 --- a/src/corelib/tools/qrect.cpp +++ b/src/corelib/tools/qrect.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) 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 "qrect.h" #include "qdatastream.h" @@ -1232,6 +1196,18 @@ bool QRect::intersects(const QRect &r) const noexcept \since 6.0 */ +/*! + \fn QRect::toRectF() const + \since 6.4 + + Returns this rectangle as a rectangle with floating point accuracy. + + \note This function, like the QRectF(QRect) constructor, preserves the + size() of the rectangle, not its bottomRight() corner. + + \sa QRectF::toRect() +*/ + /***************************************************************************** QRect stream functions *****************************************************************************/ @@ -1480,7 +1456,10 @@ QDebug operator<<(QDebug dbg, const QRect &r) Constructs a QRectF rectangle from the given QRect \a rectangle. - \sa toRect() + \note This function, like QRect::toRectF(), preserves the size() of + \a rectangle, not its bottomRight() corner. + + \sa toRect(), QRect::toRectF() */ /*! @@ -2334,7 +2313,7 @@ bool QRectF::intersects(const QRectF &r) const noexcept Returns a QRect based on the values of this rectangle. Note that the coordinates in the returned rectangle are rounded to the nearest integer. - \sa QRectF(), toAlignedRect() + \sa QRectF(), toAlignedRect(), QRect::toRectF() */ /*! diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h index 9e64f4d6e8..d114fa7ae0 100644 --- a/src/corelib/tools/qrect.h +++ b/src/corelib/tools/qrect.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) 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 QRECT_H #define QRECT_H @@ -55,6 +19,8 @@ struct CGRect; QT_BEGIN_NAMESPACE +class QRectF; + class Q_CORE_EXPORT QRect { public: @@ -157,6 +123,7 @@ public: #if defined(Q_OS_DARWIN) || defined(Q_QDOC) [[nodiscard]] CGRect toCGRect() const noexcept; #endif + [[nodiscard]] constexpr inline QRectF toRectF() const noexcept; private: int x1; @@ -863,6 +830,8 @@ inline QRectF QRectF::united(const QRectF &r) const noexcept return *this | r; } +constexpr QRectF QRect::toRectF() const noexcept { return *this; } + constexpr inline QRect QRectF::toRect() const noexcept { // This rounding is designed to minimize the maximum possible difference diff --git a/src/corelib/tools/qrefcount.cpp b/src/corelib/tools/qrefcount.cpp index 1986cce9ca..c33b34594b 100644 --- a/src/corelib/tools/qrefcount.cpp +++ b/src/corelib/tools/qrefcount.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 /*! \class QtPrivate::RefCount diff --git a/src/corelib/tools/qrefcount.h b/src/corelib/tools/qrefcount.h index 982a9c2bbf..9472716a72 100644 --- a/src/corelib/tools/qrefcount.h +++ b/src/corelib/tools/qrefcount.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 QREFCOUNT_H #define QREFCOUNT_H diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp index 09b0336145..ea4224eefe 100644 --- a/src/corelib/tools/qringbuffer.cpp +++ b/src/corelib/tools/qringbuffer.cpp @@ -1,49 +1,20 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2015 Alex Trotsenko <alex1973tr@gmail.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) 2021 The Qt Company Ltd. +// Copyright (C) 2015 Alex Trotsenko <alex1973tr@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "private/qringbuffer_p.h" #include "private/qbytearray_p.h" + +#include <type_traits> + #include <string.h> QT_BEGIN_NAMESPACE +static_assert(std::is_nothrow_default_constructible_v<QRingChunk>); +static_assert(std::is_nothrow_move_constructible_v<QRingChunk>); +static_assert(std::is_nothrow_move_assignable_v<QRingChunk>); + void QRingChunk::allocate(qsizetype alloc) { Q_ASSERT(alloc > 0 && size() == 0); @@ -57,31 +28,23 @@ void QRingChunk::detach() Q_ASSERT(isShared()); const qsizetype chunkSize = size(); - QByteArray x(chunkSize, Qt::Uninitialized); - ::memcpy(x.data(), chunk.constData() + headOffset, chunkSize); - chunk = std::move(x); + chunk = QByteArray(std::as_const(*this).data(), chunkSize); headOffset = 0; tailOffset = chunkSize; } -QByteArray QRingChunk::toByteArray() +QByteArray QRingChunk::toByteArray() && { + // ### Replace with std::move(chunk).sliced(head(), size()) once sliced()&& is available if (headOffset != 0 || tailOffset != chunk.size()) { if (isShared()) - return chunk.mid(headOffset, size()); - - if (headOffset != 0) { - char *ptr = chunk.data(); - ::memmove(ptr, ptr + headOffset, size()); - tailOffset -= headOffset; - headOffset = 0; - } + return chunk.sliced(head(), size()); - chunk.reserve(0); // avoid that resizing needlessly reallocates chunk.resize(tailOffset); + chunk.remove(0, headOffset); } - return chunk; + return std::move(chunk); } /*! @@ -363,6 +326,21 @@ void QRingBuffer::append(const QByteArray &qba) bufferSize += qba.size(); } +/*! + \internal + + Append a new buffer to the end +*/ +void QRingBuffer::append(QByteArray &&qba) +{ + const auto qbaSize = qba.size(); + if (bufferSize != 0 || buffers.isEmpty()) + buffers.emplace_back(std::move(qba)); + else + buffers.last().assign(std::move(qba)); + bufferSize += qbaSize; +} + qint64 QRingBuffer::readLine(char *data, qint64 maxLength) { Q_ASSERT(data != nullptr && maxLength > 1); diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index bbab8df3e2..25113213c9 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_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) 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 QRINGBUFFER_P_H #define QRINGBUFFER_P_H @@ -65,36 +29,19 @@ class QRingChunk { public: // initialization and cleanup - inline QRingChunk() noexcept : - headOffset(0), tailOffset(0) - { - } - inline QRingChunk(const QRingChunk &other) noexcept : - chunk(other.chunk), headOffset(other.headOffset), tailOffset(other.tailOffset) - { - } + QRingChunk() noexcept = default; explicit inline QRingChunk(qsizetype alloc) : - chunk(alloc, Qt::Uninitialized), headOffset(0), tailOffset(0) + chunk(alloc, Qt::Uninitialized), tailOffset(0) { } explicit inline QRingChunk(const QByteArray &qba) noexcept : - chunk(qba), headOffset(0), tailOffset(qba.size()) + chunk(qba), tailOffset(qba.size()) { } - - inline QRingChunk &operator=(const QRingChunk &other) noexcept + explicit QRingChunk(QByteArray &&qba) noexcept : + chunk(std::move(qba)), tailOffset(chunk.size()) { - chunk = other.chunk; - headOffset = other.headOffset; - tailOffset = other.tailOffset; - return *this; } - inline QRingChunk(QRingChunk &&other) noexcept : - chunk(other.chunk), headOffset(other.headOffset), tailOffset(other.tailOffset) - { - other.headOffset = other.tailOffset = 0; - } - QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QRingChunk) inline void swap(QRingChunk &other) noexcept { @@ -110,7 +57,7 @@ public: return !chunk.isDetached(); } Q_CORE_EXPORT void detach(); - QByteArray toByteArray(); + QByteArray toByteArray() &&; // getters inline qsizetype head() const @@ -161,28 +108,38 @@ public: headOffset = 0; tailOffset = qba.size(); } + void assign(QByteArray &&qba) + { + chunk = std::move(qba); + headOffset = 0; + tailOffset = chunk.size(); + } inline void reset() { headOffset = tailOffset = 0; } inline void clear() { - assign(QByteArray()); + *this = {}; } private: QByteArray chunk; - qsizetype headOffset; - qsizetype tailOffset; + qsizetype headOffset = 0; + qsizetype tailOffset = 0; }; Q_DECLARE_SHARED(QRingChunk) class QRingBuffer { + Q_DISABLE_COPY(QRingBuffer) public: explicit inline QRingBuffer(int growth = QRINGBUFFER_CHUNKSIZE) : bufferSize(0), basicBlockSize(growth) { } + QRingBuffer(QRingBuffer &&) noexcept = default; + QRingBuffer &operator=(QRingBuffer &&) noexcept = default; + inline void setChunkSize(int size) { basicBlockSize = size; } @@ -248,6 +205,7 @@ public: Q_CORE_EXPORT qint64 peek(char *data, qint64 maxLength, qint64 pos = 0) const; Q_CORE_EXPORT void append(const char *data, qint64 size); Q_CORE_EXPORT void append(const QByteArray &qba); + Q_CORE_EXPORT void append(QByteArray &&qba); inline qint64 skip(qint64 length) { qint64 bytesToSkip = qMin(length, bufferSize); diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 1844013d46..e569267c65 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.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 "qscopedpointer.h" diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h index c9afb248a1..508816a7e7 100644 --- a/src/corelib/tools/qscopedpointer.h +++ b/src/corelib/tools/qscopedpointer.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 QSCOPEDPOINTER_H #define QSCOPEDPOINTER_H @@ -173,7 +137,7 @@ public: QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedPointer.") void swap(QScopedPointer<T, Cleanup> &other) noexcept { - qSwap(d, other.d); + qt_ptr_swap(d, other.d); } #endif diff --git a/src/corelib/tools/qscopedvaluerollback.cpp b/src/corelib/tools/qscopedvaluerollback.cpp index 0c1c43ac49..ce3c845cc3 100644 --- a/src/corelib/tools/qscopedvaluerollback.cpp +++ b/src/corelib/tools/qscopedvaluerollback.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 "qscopedvaluerollback.h" diff --git a/src/corelib/tools/qscopedvaluerollback.h b/src/corelib/tools/qscopedvaluerollback.h index 9b14308ec2..a4a451b0c7 100644 --- a/src/corelib/tools/qscopedvaluerollback.h +++ b/src/corelib/tools/qscopedvaluerollback.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 QSCOPEDVALUEROLLBACK_H #define QSCOPEDVALUEROLLBACK_H @@ -75,7 +39,7 @@ private: T &varRef; T oldValue; - Q_DISABLE_COPY(QScopedValueRollback) + Q_DISABLE_COPY_MOVE(QScopedValueRollback) }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qscopeguard.h b/src/corelib/tools/qscopeguard.h index cc9e8db209..2639b41222 100644 --- a/src/corelib/tools/qscopeguard.h +++ b/src/corelib/tools/qscopeguard.h @@ -1,42 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com> -** 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) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com> +// 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 #ifndef QSCOPEGUARD_H #define QSCOPEGUARD_H diff --git a/src/corelib/tools/qscopeguard.qdoc b/src/corelib/tools/qscopeguard.qdoc index b36299d296..6d9874842a 100644 --- a/src/corelib/tools/qscopeguard.qdoc +++ b/src/corelib/tools/qscopeguard.qdoc @@ -1,30 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com> -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com> +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only #include "qscopeguard.h" diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 299851bf8d..2a945a31e8 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.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 QSET_H #define QSET_H diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc index 137aa61502..47153e1349 100644 --- a/src/corelib/tools/qset.qdoc +++ b/src/corelib/tools/qset.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \class QSet diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp index 16c10a58ac..8ef174ebfc 100644 --- a/src/corelib/tools/qshareddata.cpp +++ b/src/corelib/tools/qshareddata.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 <qshareddata.h> diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index de11257db3..be848e2ef8 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.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 QSHAREDDATA_H #define QSHAREDDATA_H @@ -125,7 +89,7 @@ public: bool operator!() const noexcept { return d == nullptr; } void swap(QSharedDataPointer &other) noexcept - { qSwap(d, other.d); } + { qt_ptr_swap(d, other.d); } #define DECLARE_COMPARE_SET(T1, A1, T2, A2) \ friend bool operator<(T1, T2) noexcept \ @@ -222,7 +186,7 @@ public: bool operator!() const noexcept { return d == nullptr; } void swap(QExplicitlySharedDataPointer &other) noexcept - { qSwap(d, other.d); } + { qt_ptr_swap(d, other.d); } DECLARE_COMPARE_SET(const QExplicitlySharedDataPointer &p1, p1.d, const QExplicitlySharedDataPointer &p2, p2.d) DECLARE_COMPARE_SET(const QExplicitlySharedDataPointer &p1, p1.d, const T *ptr, ptr) diff --git a/src/corelib/tools/qshareddata_impl.h b/src/corelib/tools/qshareddata_impl.h index cf1c534cdf..61a9d1d105 100644 --- a/src/corelib/tools/qshareddata_impl.h +++ b/src/corelib/tools/qshareddata_impl.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Klarälvdalens 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 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 #if 0 #pragma qt_sync_skip_header_check @@ -138,7 +102,7 @@ public: constexpr void swap(QExplicitlySharedDataPointerV2 &other) noexcept { - qSwap(d, other.d); + qt_ptr_swap(d, other.d); } // important change from QExplicitlySharedDataPointer: deep const diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index bd4d6c906b..65c1c144f1 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -1,43 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Copyright (C) 2020 Intel Corporation. -** Copyright (C) 2019 Klarälvdalens Datakonsult AB. -** 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 Intel Corporation. +// Copyright (C) 2019 Klarälvdalens Datakonsult AB. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qsharedpointer.h" diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h index a7365aecf1..a18304cae6 100644 --- a/src/corelib/tools/qsharedpointer.h +++ b/src/corelib/tools/qsharedpointer.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 QSHAREDPOINTER_H #define QSHAREDPOINTER_H diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 61aeee4952..dd6bd22fca 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -1,43 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Copyright (C) 2020 Intel Corporation. -** Copyright (C) 2019 Klarälvdalens Datakonsult AB. -** 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. +// Copyright (C) 2019 Klarälvdalens Datakonsult AB. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef Q_QDOC @@ -62,13 +26,17 @@ QT_END_NAMESPACE #include <new> #include <QtCore/qatomic.h> -#include <QtCore/qobject.h> // for qobject_cast #include <QtCore/qhashfunctions.h> +#include <QtCore/qmetatype.h> // for IsPointerToTypeDerivedFromQObject #include <memory> QT_BEGIN_NAMESPACE +class QObject; +template <class T> +T qobject_cast(const QObject *object); + // // forward declarations // @@ -508,8 +476,8 @@ private: void internalSwap(QSharedPointer &other) noexcept { - qSwap(d, other.d); - qSwap(this->value, other.value); + qt_ptr_swap(d, other.d); + qt_ptr_swap(this->value, other.value); } template <class X> friend class QSharedPointer; @@ -538,8 +506,8 @@ private: } } - qSwap(d, o); - qSwap(this->value, actual); + qt_ptr_swap(d, o); + qt_ptr_swap(this->value, actual); if (!d || d->strongref.loadRelaxed() == 0) this->value = nullptr; @@ -571,7 +539,7 @@ public: explicit operator bool() const noexcept { return !isNull(); } bool operator !() const noexcept { return isNull(); } - inline QWeakPointer() noexcept : d(nullptr), value(nullptr) { } + constexpr QWeakPointer() noexcept : d(nullptr), value(nullptr) { } inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; } QWeakPointer(const QWeakPointer &other) noexcept : d(other.d), value(other.value) @@ -609,8 +577,8 @@ public: void swap(QWeakPointer &other) noexcept { - qSwap(this->d, other.d); - qSwap(this->value, other.value); + qt_ptr_swap(this->d, other.d); + qt_ptr_swap(this->value, other.value); } inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.data()) @@ -686,6 +654,7 @@ public: private: friend struct QtPrivate::EnableInternalData; template <class X> friend class QSharedPointer; + template <class X> friend class QWeakPointer; template <class X> friend class QPointer; template <class X> diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp index 2779948aae..d5e8e4c71b 100644 --- a/src/corelib/tools/qsize.cpp +++ b/src/corelib/tools/qsize.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) 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 "qsize.h" #include "qdatastream.h" @@ -403,6 +367,15 @@ QSize QSize::scaled(const QSize &s, Qt::AspectRatioMode mode) const noexcept \sa grownBy() */ +/*! + \fn QSize::toSizeF() const + \since 6.4 + + Returns this size as a size with floating point accuracy. + + \sa QSizeF::toSize() +*/ + /***************************************************************************** QSize stream functions *****************************************************************************/ @@ -520,7 +493,7 @@ QDebug operator<<(QDebug dbg, const QSize &s) Constructs a size with floating point accuracy from the given \a size. - \sa toSize() + \sa toSize(), QSize::toSizeF() */ /*! @@ -596,7 +569,7 @@ QDebug operator<<(QDebug dbg, const QSize &s) Note that the coordinates in the returned size will be rounded to the nearest integer. - \sa QSizeF() + \sa QSizeF(), QSize::toSizeF() */ /*! diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h index bab193031c..71066c35c0 100644 --- a/src/corelib/tools/qsize.h +++ b/src/corelib/tools/qsize.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) 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 QSIZE_H #define QSIZE_H @@ -50,6 +14,7 @@ struct CGSize; QT_BEGIN_NAMESPACE +class QSizeF; class Q_CORE_EXPORT QSize { @@ -109,6 +74,8 @@ public: [[nodiscard]] CGSize toCGSize() const noexcept; #endif + [[nodiscard]] inline constexpr QSizeF toSizeF() const noexcept; + private: int wd; int ht; @@ -420,6 +387,8 @@ constexpr inline QSize QSizeF::toSize() const noexcept return QSize(qRound(wd), qRound(ht)); } +constexpr QSizeF QSize::toSizeF() const noexcept { return *this; } + #ifndef QT_NO_DEBUG_STREAM Q_CORE_EXPORT QDebug operator<<(QDebug, const QSizeF &); #endif diff --git a/src/corelib/tools/qstack.cpp b/src/corelib/tools/qstack.cpp index 849a474d2c..5255e0e100 100644 --- a/src/corelib/tools/qstack.cpp +++ b/src/corelib/tools/qstack.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 /*! \class QStack diff --git a/src/corelib/tools/qstack.h b/src/corelib/tools/qstack.h index c43c63cdd2..11ffb13328 100644 --- a/src/corelib/tools/qstack.h +++ b/src/corelib/tools/qstack.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 QSTACK_H #define QSTACK_H diff --git a/src/corelib/tools/qtaggedpointer.h b/src/corelib/tools/qtaggedpointer.h index f6ce85eebc..504645993a 100644 --- a/src/corelib/tools/qtaggedpointer.h +++ b/src/corelib/tools/qtaggedpointer.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 QTAGGEDPOINTER_H #define QTAGGEDPOINTER_H @@ -48,7 +12,7 @@ QT_BEGIN_NAMESPACE namespace QtPrivate { - constexpr quint8 nextByteSize(quint8 bits) { return (bits + 7) / 8; } + constexpr quint8 nextByteSize(quint8 bits) { return quint8((bits + 7) / 8); } template <typename T> struct TagInfo @@ -144,7 +108,7 @@ public: void swap(QTaggedPointer &other) noexcept { - qSwap(d, other.d); + std::swap(d, other.d); } friend inline bool operator==(QTaggedPointer lhs, QTaggedPointer rhs) noexcept diff --git a/src/corelib/tools/qtaggedpointer.qdoc b/src/corelib/tools/qtaggedpointer.qdoc index 36e20ecff0..acabf7047f 100644 --- a/src/corelib/tools/qtaggedpointer.qdoc +++ b/src/corelib/tools/qtaggedpointer.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \class QTaggedPointer diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index 8a01dbe685..337f09cbb8 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -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 #include "qtimeline.h" diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h index 464c4a8836..4bdcceaebd 100644 --- a/src/corelib/tools/qtimeline.h +++ b/src/corelib/tools/qtimeline.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 QTIMELINE_H #define QTIMELINE_H diff --git a/src/corelib/tools/qtools_p.h b/src/corelib/tools/qtools_p.h index 8854ae8c48..338f89d633 100644 --- a/src/corelib/tools/qtools_p.h +++ b/src/corelib/tools/qtools_p.h @@ -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 #ifndef QTOOLS_P_H #define QTOOLS_P_H @@ -84,6 +48,20 @@ constexpr inline int fromOct(uint c) noexcept { return ((c >= '0') && (c <= '7')) ? int(c - '0') : -1; } + +constexpr inline char toAsciiLower(char ch) noexcept +{ + return (ch >= 'A' && ch <= 'Z') ? ch - 'A' + 'a' : ch; +} + +constexpr inline int caseCompareAscii(char lhs, char rhs) noexcept +{ + const char lhsLower = QtMiscUtils::toAsciiLower(lhs); + const char rhsLower = QtMiscUtils::toAsciiLower(rhs); + return int(uchar(lhsLower)) - int(uchar(rhsLower)); +} + + } // We typically need an extra bit for qNextPowerOfTwo when determining the next allocation size. diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 4bff61b9b6..54603bcec1 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -1,45 +1,14 @@ -/**************************************************************************** -** -** 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 #ifndef QVARLENGTHARRAY_H #define QVARLENGTHARRAY_H +#if 0 +#pragma qt_class(QVarLengthArray) +#pragma qt_sync_stop_processing +#endif + #include <QtCore/qcontainerfwd.h> #include <QtCore/qglobal.h> #include <QtCore/qalgorithms.h> @@ -49,40 +18,266 @@ #include <algorithm> #include <initializer_list> #include <iterator> +#include <memory> #include <new> + #include <string.h> #include <stdlib.h> QT_BEGIN_NAMESPACE +template <size_t Size, size_t Align, qsizetype Prealloc> +class QVLAStorage +{ + template <size_t> class print; +protected: + ~QVLAStorage() = default; + + alignas(Align) char array[Prealloc * (Align > Size ? Align : Size)]; + QT_WARNING_PUSH + QT_WARNING_DISABLE_DEPRECATED + // ensure we maintain BC: std::aligned_storage_t was only specified by a + // minimum size, but for BC we need the substitution to be exact in size: + static_assert(std::is_same_v<print<sizeof(std::aligned_storage_t<Size, Align>[Prealloc])>, + print<sizeof(array)>>); + QT_WARNING_POP +}; + +class QVLABaseBase +{ +protected: + ~QVLABaseBase() = default; + + qsizetype a; // capacity + qsizetype s; // size + void *ptr; // data + + Q_ALWAYS_INLINE constexpr void verify(qsizetype pos = 0, qsizetype n = 1) const + { + Q_ASSERT(pos >= 0); + Q_ASSERT(pos <= size()); + Q_ASSERT(n >= 0); + Q_ASSERT(n <= size() - pos); + } + + struct free_deleter { + void operator()(void *p) const noexcept { free(p); } + }; + using malloced_ptr = std::unique_ptr<void, free_deleter>; + +public: + using size_type = qsizetype; + + constexpr size_type capacity() const noexcept { return a; } + constexpr size_type size() const noexcept { return s; } + constexpr bool empty() const noexcept { return size() == 0; } +}; + +template<class T> +class QVLABase : public QVLABaseBase +{ +protected: + ~QVLABase() = default; + +public: + T *data() noexcept { return static_cast<T *>(ptr); } + const T *data() const noexcept { return static_cast<T *>(ptr); } + + using iterator = T*; + using const_iterator = const T*; + + iterator begin() noexcept { return data(); } + const_iterator begin() const noexcept { return data(); } + const_iterator cbegin() const noexcept { return begin(); } + iterator end() noexcept { return data() + size(); } + const_iterator end() const noexcept { return data() + size(); } + const_iterator cend() const noexcept { return end(); } + + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + + reverse_iterator rbegin() noexcept { return reverse_iterator{end()}; } + const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator{end()}; } + const_reverse_iterator crbegin() const noexcept { return rbegin(); } + reverse_iterator rend() noexcept { return reverse_iterator{begin()}; } + const_reverse_iterator rend() const noexcept { return const_reverse_iterator{begin()}; } + const_reverse_iterator crend() const noexcept { return rend(); } + + using value_type = T; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + using difference_type = qptrdiff; + + reference front() + { + verify(); + return *begin(); + } + + const_reference front() const + { + verify(); + return *begin(); + } + + reference back() + { + verify(); + return *rbegin(); + } + + const_reference back() const + { + verify(); + return *rbegin(); + } + + void pop_back() + { + verify(); + if constexpr (QTypeInfo<T>::isComplex) + data()[size() - 1].~T(); + --s; + } + + template <typename AT = T> + qsizetype indexOf(const AT &t, qsizetype from = 0) const; + template <typename AT = T> + qsizetype lastIndexOf(const AT &t, qsizetype from = -1) const; + template <typename AT = T> + bool contains(const AT &t) const; + + reference operator[](qsizetype idx) + { + verify(idx); + return data()[idx]; + } + const_reference operator[](qsizetype idx) const + { + verify(idx); + return data()[idx]; + } + + value_type value(qsizetype i) const; + value_type value(qsizetype i, const T& defaultValue) const; + + void replace(qsizetype i, const T &t); + void remove(qsizetype i, qsizetype n = 1); + template <typename AT = T> + qsizetype removeAll(const AT &t); + template <typename AT = T> + bool removeOne(const AT &t); + template <typename Predicate> + qsizetype removeIf(Predicate pred); + + iterator erase(const_iterator begin, const_iterator end); + iterator erase(const_iterator pos) { return erase(pos, pos + 1); } + + size_t hash(size_t seed) const noexcept(QtPrivate::QNothrowHashable_v<T>) + { + return qHashRange(begin(), end(), seed); + } +protected: + template <typename...Args> + reference emplace_back_impl(qsizetype prealloc, void *array, Args&&...args) + { + if (size() == capacity()) // ie. size() != 0 + reallocate_impl(prealloc, array, size(), size() << 1); + reference r = *new (end()) T(std::forward<Args>(args)...); + ++s; + return r; + } + template <typename...Args> + iterator emplace_impl(qsizetype prealloc, void *array, const_iterator pos, Args&&...arg); + + iterator insert_impl(qsizetype prealloc, void *array, const_iterator pos, qsizetype n, const T &t); + + template <typename S> + bool equal(const QVLABase<S> &other) const + { + return std::equal(begin(), end(), other.begin(), other.end()); + } + template <typename S> + bool less_than(const QVLABase<S> &other) const + { + return std::lexicographical_compare(begin(), end(), other.begin(), other.end()); + } + + void append_impl(qsizetype prealloc, void *array, const T *buf, qsizetype n); + void reallocate_impl(qsizetype prealloc, void *array, qsizetype size, qsizetype alloc, const T *v = nullptr); + void resize_impl(qsizetype prealloc, void *array, qsizetype sz, const T *v = nullptr) + { reallocate_impl(prealloc, array, sz, qMax(sz, capacity()), v); } + + bool isValidIterator(const const_iterator &i) const + { + const std::less<const T *> less = {}; + return !less(cend(), i) && !less(i, cbegin()); + } +}; // Prealloc = 256 by default, specified in qcontainerfwd.h template<class T, qsizetype Prealloc> class QVarLengthArray + : public QVLABase<T>, // ### Qt 7: swap base class order + public QVLAStorage<sizeof(T), alignof(T), Prealloc> { + template <class S, qsizetype Prealloc2> + friend class QVarLengthArray; + using Base = QVLABase<T>; + using Storage = QVLAStorage<sizeof(T), alignof(T), Prealloc>; static_assert(std::is_nothrow_destructible_v<T>, "Types with throwing destructors are not supported in Qt containers."); + using Base::verify; + template <typename U> + using if_copyable = std::enable_if_t<std::is_copy_constructible_v<U>, bool>; public: - QVarLengthArray() : QVarLengthArray(0) {} + using size_type = typename Base::size_type; + using value_type = typename Base::value_type; + using pointer = typename Base::pointer; + using const_pointer = typename Base::const_pointer; + using reference = typename Base::reference; + using const_reference = typename Base::const_reference; + using difference_type = typename Base::difference_type; + + using iterator = typename Base::iterator; + using const_iterator = typename Base::const_iterator; + using reverse_iterator = typename Base::reverse_iterator; + using const_reverse_iterator = typename Base::const_reverse_iterator; + + QVarLengthArray() noexcept + { + this->a = Prealloc; + this->s = 0; + this->ptr = this->array; + } inline explicit QVarLengthArray(qsizetype size); - inline QVarLengthArray(const QVarLengthArray<T, Prealloc> &other) - : a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array)) +#ifndef Q_QDOC + template <typename U = T, if_copyable<U> = true> +#endif + explicit QVarLengthArray(qsizetype sz, const T &v) + : QVarLengthArray{} + { + resize(sz, v); + } + + QVarLengthArray(const QVarLengthArray &other) + : QVarLengthArray{} { append(other.constData(), other.size()); } QVarLengthArray(QVarLengthArray &&other) noexcept(std::is_nothrow_move_constructible_v<T>) - : a{other.a}, - s{other.s}, - ptr{other.ptr} + : Base(other) { const auto otherInlineStorage = reinterpret_cast<T*>(other.array); if (data() == otherInlineStorage) { // inline buffer - move into our inline buffer: - ptr = reinterpret_cast<T*>(array); + this->ptr = this->array; QtPrivate::q_uninitialized_relocate_n(otherInlineStorage, size(), data()); } else { // heap buffer - we just stole the memory @@ -110,7 +305,7 @@ public: { if constexpr (QTypeInfo<T>::isComplex) std::destroy_n(data(), size()); - if (data() != reinterpret_cast<T *>(array)) + if (data() != reinterpret_cast<T *>(this->array)) free(data()); } inline QVarLengthArray<T, Prealloc> &operator=(const QVarLengthArray<T, Prealloc> &other) @@ -130,16 +325,16 @@ public: // the moved-from state is the empty state, so we're good with the clear() here: clear(); Q_ASSERT(capacity() >= Prealloc); - const auto otherInlineStorage = reinterpret_cast<T *>(other.array); + const auto otherInlineStorage = other.array; if (other.ptr != otherInlineStorage) { // heap storage: steal the external buffer, reset other to otherInlineStorage - a = std::exchange(other.a, Prealloc); - ptr = std::exchange(other.ptr, otherInlineStorage); + this->a = std::exchange(other.a, Prealloc); + this->ptr = std::exchange(other.ptr, otherInlineStorage); } else { // inline storage: move into our storage (doesn't matter whether inline or external) - QtPrivate::q_uninitialized_relocate_n(other.ptr, other.s, data()); + QtPrivate::q_uninitialized_relocate_n(other.data(), other.size(), data()); } - s = std::exchange(other.s, 0); + this->s = std::exchange(other.s, 0); return *this; } @@ -147,92 +342,100 @@ public: { resize(qsizetype(list.size())); std::copy(list.begin(), list.end(), - QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size())); + QT_MAKE_CHECKED_ARRAY_ITERATOR(begin(), size())); return *this; } inline void removeLast() { - Q_ASSERT(size() > 0); - if constexpr (QTypeInfo<T>::isComplex) - data()[size() - 1].~T(); - --s; + Base::pop_back(); } - inline qsizetype size() const { return s; } +#ifdef Q_QDOC + inline qsizetype size() const { return this->s; } +#endif + using Base::size; inline qsizetype count() const { return size(); } inline qsizetype length() const { return size(); } inline T &first() { - Q_ASSERT(!isEmpty()); - return *begin(); + return front(); } inline const T &first() const { - Q_ASSERT(!isEmpty()); - return *begin(); + return front(); } T &last() { - Q_ASSERT(!isEmpty()); - return *(end() - 1); + return back(); } const T &last() const { - Q_ASSERT(!isEmpty()); - return *(end() - 1); + return back(); } - inline bool isEmpty() const { return size() == 0; } - inline void resize(qsizetype size); + bool isEmpty() const { return empty(); } + void resize(qsizetype sz) { Base::resize_impl(Prealloc, this->array, sz); } +#ifndef Q_QDOC + template <typename U = T, if_copyable<U> = true> +#endif + void resize(qsizetype sz, const T &v) + { Base::resize_impl(Prealloc, this->array, sz, &v); } inline void clear() { resize(0); } - inline void squeeze(); + void squeeze() { reallocate(size(), size()); } - inline qsizetype capacity() const { return a; } - inline void reserve(qsizetype size); + using Base::capacity; +#ifdef Q_QDOC + qsizetype capacity() const { return this->a; } +#endif + void reserve(qsizetype sz) { if (sz > capacity()) reallocate(size(), sz); } +#ifdef Q_QDOC template <typename AT = T> inline qsizetype indexOf(const AT &t, qsizetype from = 0) const; template <typename AT = T> inline qsizetype lastIndexOf(const AT &t, qsizetype from = -1) const; template <typename AT = T> inline bool contains(const AT &t) const; +#endif + using Base::indexOf; + using Base::lastIndexOf; + using Base::contains; +#ifdef Q_QDOC inline T &operator[](qsizetype idx) { - Q_ASSERT(idx >= 0 && idx < size()); + verify(idx); return data()[idx]; } inline const T &operator[](qsizetype idx) const { - Q_ASSERT(idx >= 0 && idx < size()); + verify(idx); return data()[idx]; } +#endif + using Base::operator[]; inline const T &at(qsizetype idx) const { return operator[](idx); } +#ifdef Q_QDOC T value(qsizetype i) const; T value(qsizetype i, const T &defaultValue) const; +#endif + using Base::value; inline void append(const T &t) { - if (size() == capacity()) { // i.e. size() != 0 - T copy(t); - reallocate(size(), size() << 1); - const qsizetype idx = s++; - new (data() + idx) T(std::move(copy)); - } else { - const qsizetype idx = s++; - new (data() + idx) T(t); - } + if (size() == capacity()) + emplace_back(T(t)); + else + emplace_back(t); } void append(T &&t) { - if (size() == capacity()) - reallocate(size(), size() << 1); - const qsizetype idx = s++; - new (data() + idx) T(std::move(t)); + emplace_back(std::move(t)); } - void append(const T *buf, qsizetype size); + void append(const T *buf, qsizetype sz) + { Base::append_impl(Prealloc, this->array, buf, sz); } inline QVarLengthArray<T, Prealloc> &operator<<(const T &t) { append(t); return *this; } inline QVarLengthArray<T, Prealloc> &operator<<(T &&t) @@ -242,37 +445,38 @@ public: inline QVarLengthArray<T, Prealloc> &operator+=(T &&t) { append(std::move(t)); return *this; } +#if QT_DEPRECATED_SINCE(6, 3) + QT_DEPRECATED_VERSION_X_6_3("This is slow. If you must, use insert(cbegin(), ~~~) instead.") void prepend(T &&t); + QT_DEPRECATED_VERSION_X_6_3("This is slow. If you must, use insert(cbegin(), ~~~) instead.") void prepend(const T &t); +#endif void insert(qsizetype i, T &&t); void insert(qsizetype i, const T &t); void insert(qsizetype i, qsizetype n, const T &t); +#ifdef Q_QDOC void replace(qsizetype i, const T &t); - void remove(qsizetype i); - void remove(qsizetype i, qsizetype n); + void remove(qsizetype i, qsizetype n = 1); template <typename AT = T> qsizetype removeAll(const AT &t); template <typename AT = T> bool removeOne(const AT &t); template <typename Predicate> qsizetype removeIf(Predicate pred); +#endif + using Base::replace; + using Base::remove; + using Base::removeAll; + using Base::removeOne; + using Base::removeIf; - inline T *data() { return ptr; } - inline const T *data() const { return ptr; } +#ifdef Q_QDOC + inline T *data() { return this->ptr; } + inline const T *data() const { return this->ptr; } +#endif + using Base::data; inline const T *constData() const { return data(); } - typedef qsizetype size_type; - typedef T value_type; - typedef value_type *pointer; - typedef const value_type *const_pointer; - typedef value_type &reference; - typedef const value_type &const_reference; - typedef qptrdiff difference_type; - - typedef T *iterator; - typedef const T *const_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - +#ifdef Q_QDOC inline iterator begin() { return data(); } inline const_iterator begin() const { return data(); } inline const_iterator cbegin() const { return begin(); } @@ -280,33 +484,61 @@ public: inline iterator end() { return data() + size(); } inline const_iterator end() const { return data() + size(); } inline const_iterator cend() const { return end(); } +#endif + + using Base::begin; + using Base::cbegin; + auto constBegin() const -> const_iterator { return begin(); } + using Base::end; + using Base::cend; inline const_iterator constEnd() const { return end(); } +#ifdef Q_QDOC reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } - iterator insert(const_iterator before, qsizetype n, const T &x); +#endif + using Base::rbegin; + using Base::crbegin; + using Base::rend; + using Base::crend; + + iterator insert(const_iterator before, qsizetype n, const T &x) + { return Base::insert_impl(Prealloc, this->array, before, n, x); } iterator insert(const_iterator before, T &&x) { return emplace(before, std::move(x)); } inline iterator insert(const_iterator before, const T &x) { return insert(before, 1, x); } +#ifdef Q_QDOC iterator erase(const_iterator begin, const_iterator end); inline iterator erase(const_iterator pos) { return erase(pos, pos + 1); } +#endif + using Base::erase; // STL compatibility: +#ifdef Q_QDOC inline bool empty() const { return isEmpty(); } +#endif + using Base::empty; inline void push_back(const T &t) { append(t); } void push_back(T &&t) { append(std::move(t)); } +#ifdef Q_QDOC inline void pop_back() { removeLast(); } inline T &front() { return first(); } inline const T &front() const { return first(); } inline T &back() { return last(); } inline const T &back() const { return last(); } +#endif + using Base::pop_back; + using Base::front; + using Base::back; void shrink_to_fit() { squeeze(); } template <typename...Args> - iterator emplace(const_iterator pos, Args &&...args); + iterator emplace(const_iterator pos, Args &&...args) + { return Base::emplace_impl(Prealloc, this->array, pos, std::forward<Args>(args)...); } template <typename...Args> - T &emplace_back(Args &&...args) { return *emplace(cend(), std::forward<Args>(args)...); } + T &emplace_back(Args &&...args) + { return Base::emplace_back_impl(Prealloc, this->array, std::forward<Args>(args)...); } #ifdef Q_QDOC @@ -326,12 +558,7 @@ public: template <typename U = T, qsizetype Prealloc2 = Prealloc> friend QTypeTraits::compare_eq_result<U> operator==(const QVarLengthArray<T, Prealloc> &l, const QVarLengthArray<T, Prealloc2> &r) { - if (l.size() != r.size()) - return false; - const T *rb = r.begin(); - const T *b = l.begin(); - const T *e = l.end(); - return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(rb, r.size())); + return l.equal(r); } template <typename U = T, qsizetype Prealloc2 = Prealloc> friend @@ -345,8 +572,7 @@ public: noexcept(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()))) { - return std::lexicographical_compare(lhs.begin(), lhs.end(), - rhs.begin(), rhs.end()); + return lhs.less_than(rhs); } template <typename U = T, qsizetype Prealloc2 = Prealloc> friend @@ -372,18 +598,17 @@ public: #endif private: - void reallocate(qsizetype size, qsizetype alloc); + template <typename U, qsizetype Prealloc2> + bool equal(const QVarLengthArray<U, Prealloc2> &other) const + { return Base::equal(other); } + template <typename U, qsizetype Prealloc2> + bool less_than(const QVarLengthArray<U, Prealloc2> &other) const + { return Base::less_than(other); } - qsizetype a; // capacity - qsizetype s; // size - T *ptr; // data - std::aligned_storage_t<sizeof(T), alignof(T)> array[Prealloc]; + void reallocate(qsizetype sz, qsizetype alloc) + { Base::reallocate_impl(Prealloc, this->array, sz, alloc); } - bool isValidIterator(const const_iterator &i) const - { - const std::less<const T *> less = {}; - return !less(cend(), i) && !less(i, cbegin()); - } + using Base::isValidIterator; }; template <typename InputIterator, @@ -393,35 +618,28 @@ QVarLengthArray(InputIterator, InputIterator) -> QVarLengthArray<ValueType>; template <class T, qsizetype Prealloc> Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(qsizetype asize) - : s(asize) { +{ + this->s = asize; static_assert(Prealloc > 0, "QVarLengthArray Prealloc must be greater than 0."); Q_ASSERT_X(size() >= 0, "QVarLengthArray::QVarLengthArray()", "Size must be greater than or equal to 0."); if (size() > Prealloc) { - ptr = reinterpret_cast<T *>(malloc(s * sizeof(T))); + this->ptr = malloc(size() * sizeof(T)); Q_CHECK_PTR(data()); - a = size(); + this->a = size(); } else { - ptr = reinterpret_cast<T *>(array); - a = Prealloc; + this->ptr = this->array; + this->a = Prealloc; } - if (QTypeInfo<T>::isComplex) { + if constexpr (QTypeInfo<T>::isComplex) { T *i = end(); while (i != begin()) new (--i) T; } } -template <class T, qsizetype Prealloc> -Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::resize(qsizetype asize) -{ reallocate(asize, qMax(asize, capacity())); } - -template <class T, qsizetype Prealloc> -Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reserve(qsizetype asize) -{ if (asize > capacity()) reallocate(size(), asize); } - -template <class T, qsizetype Prealloc> +template <class T> template <typename AT> -Q_INLINE_TEMPLATE qsizetype QVarLengthArray<T, Prealloc>::indexOf(const AT &t, qsizetype from) const +Q_INLINE_TEMPLATE qsizetype QVLABase<T>::indexOf(const AT &t, qsizetype from) const { if (from < 0) from = qMax(from + size(), qsizetype(0)); @@ -435,9 +653,9 @@ Q_INLINE_TEMPLATE qsizetype QVarLengthArray<T, Prealloc>::indexOf(const AT &t, q return -1; } -template <class T, qsizetype Prealloc> +template <class T> template <typename AT> -Q_INLINE_TEMPLATE qsizetype QVarLengthArray<T, Prealloc>::lastIndexOf(const AT &t, qsizetype from) const +Q_INLINE_TEMPLATE qsizetype QVLABase<T>::lastIndexOf(const AT &t, qsizetype from) const { if (from < 0) from += size(); @@ -454,9 +672,9 @@ Q_INLINE_TEMPLATE qsizetype QVarLengthArray<T, Prealloc>::lastIndexOf(const AT & return -1; } -template <class T, qsizetype Prealloc> +template <class T> template <typename AT> -Q_INLINE_TEMPLATE bool QVarLengthArray<T, Prealloc>::contains(const AT &t) const +Q_INLINE_TEMPLATE bool QVLABase<T>::contains(const AT &t) const { const T *b = begin(); const T *i = end(); @@ -467,32 +685,28 @@ Q_INLINE_TEMPLATE bool QVarLengthArray<T, Prealloc>::contains(const AT &t) const return false; } -template <class T, qsizetype Prealloc> -Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, qsizetype increment) +template <class T> +Q_OUTOFLINE_TEMPLATE void QVLABase<T>::append_impl(qsizetype prealloc, void *array, const T *abuf, qsizetype increment) { - Q_ASSERT(abuf); + Q_ASSERT(abuf || increment == 0); if (increment <= 0) return; const qsizetype asize = size() + increment; if (asize >= capacity()) - reallocate(size(), qMax(size() * 2, asize)); + reallocate_impl(prealloc, array, size(), qMax(size() * 2, asize)); if constexpr (QTypeInfo<T>::isComplex) std::uninitialized_copy_n(abuf, increment, end()); else memcpy(static_cast<void *>(end()), static_cast<const void *>(abuf), increment * sizeof(T)); - s = asize; + this->s = asize; } -template <class T, qsizetype Prealloc> -Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::squeeze() -{ reallocate(size(), size()); } - -template <class T, qsizetype Prealloc> -Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reallocate(qsizetype asize, qsizetype aalloc) +template <class T> +Q_OUTOFLINE_TEMPLATE void QVLABase<T>::reallocate_impl(qsizetype prealloc, void *array, qsizetype asize, qsizetype aalloc, const T *v) { Q_ASSERT(aalloc >= asize); Q_ASSERT(data()); @@ -501,38 +715,27 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reallocate(qsizetype asi const qsizetype copySize = qMin(asize, osize); Q_ASSUME(copySize >= 0); + if (aalloc != capacity()) { - if (aalloc > Prealloc) { - T *newPtr = reinterpret_cast<T *>(malloc(aalloc * sizeof(T))); + QVLABaseBase::malloced_ptr guard; + void *newPtr; + qsizetype newA; + if (aalloc > prealloc) { + newPtr = malloc(aalloc * sizeof(T)); + guard.reset(newPtr); Q_CHECK_PTR(newPtr); // could throw // by design: in case of QT_NO_EXCEPTIONS malloc must not fail or it crashes here - ptr = newPtr; - a = aalloc; - } else { - ptr = reinterpret_cast<T *>(array); - a = Prealloc; - } - s = 0; - if (!QTypeInfo<T>::isRelocatable) { - QT_TRY { - // move all the old elements - while (size() < copySize) { - new (end()) T(std::move(*(oldPtr+size()))); - (oldPtr+size())->~T(); - s++; - } - } QT_CATCH(...) { - // clean up all the old objects and then free the old ptr - qsizetype sClean = size(); - while (sClean < osize) - (oldPtr+(sClean++))->~T(); - if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != data()) - free(oldPtr); - QT_RETHROW; - } + newA = aalloc; } else { - memcpy(static_cast<void *>(data()), static_cast<const void *>(oldPtr), copySize * sizeof(T)); + newPtr = array; + newA = prealloc; } + QtPrivate::q_uninitialized_relocate_n(oldPtr, copySize, + reinterpret_cast<T *>(newPtr)); + // commit: + ptr = newPtr; + guard.release(); + a = newA; } s = copySize; @@ -545,87 +748,96 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reallocate(qsizetype asi if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != data()) free(oldPtr); - if (QTypeInfo<T>::isComplex) { + if (v) { + if constexpr (std::is_copy_constructible_v<T>) { + while (size() < asize) { + new (data() + size()) T(*v); + ++s; + } + } else { + Q_UNREACHABLE(); + } + } else if constexpr (QTypeInfo<T>::isComplex) { // call default constructor for new objects (which can throw) - while (s < asize) - new (ptr+(s++)) T; + while (size() < asize) { + new (data() + size()) T; + ++s; + } } else { s = asize; } + } -template <class T, qsizetype Prealloc> -Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(qsizetype i) const +template <class T> +Q_OUTOFLINE_TEMPLATE T QVLABase<T>::value(qsizetype i) const { if (size_t(i) >= size_t(size())) return T(); - return at(i); + return operator[](i); } -template <class T, qsizetype Prealloc> -Q_OUTOFLINE_TEMPLATE T QVarLengthArray<T, Prealloc>::value(qsizetype i, const T &defaultValue) const +template <class T> +Q_OUTOFLINE_TEMPLATE T QVLABase<T>::value(qsizetype i, const T &defaultValue) const { - return (size_t(i) >= size_t(size())) ? defaultValue : at(i); + return (size_t(i) >= size_t(size())) ? defaultValue : operator[](i); } template <class T, qsizetype Prealloc> inline void QVarLengthArray<T, Prealloc>::insert(qsizetype i, T &&t) -{ Q_ASSERT_X(i >= 0 && i <= size(), "QVarLengthArray::insert", "index out of range"); +{ verify(i, 0); insert(cbegin() + i, std::move(t)); } template <class T, qsizetype Prealloc> inline void QVarLengthArray<T, Prealloc>::insert(qsizetype i, const T &t) -{ Q_ASSERT_X(i >= 0 && i <= size(), "QVarLengthArray::insert", "index out of range"); +{ verify(i, 0); insert(begin() + i, 1, t); } template <class T, qsizetype Prealloc> inline void QVarLengthArray<T, Prealloc>::insert(qsizetype i, qsizetype n, const T &t) -{ Q_ASSERT_X(i >= 0 && i <= size(), "QVarLengthArray::insert", "index out of range"); +{ verify(i, 0); insert(begin() + i, n, t); } -template <class T, qsizetype Prealloc> -inline void QVarLengthArray<T, Prealloc>::remove(qsizetype i, qsizetype n) -{ Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= size(), "QVarLengthArray::remove", "index out of range"); +template <class T> +inline void QVLABase<T>::remove(qsizetype i, qsizetype n) +{ verify(i, n); erase(begin() + i, begin() + i + n); } -template <class T, qsizetype Prealloc> -inline void QVarLengthArray<T, Prealloc>::remove(qsizetype i) -{ Q_ASSERT_X(i >= 0 && i < size(), "QVarLengthArray::remove", "index out of range"); - erase(begin() + i, begin() + i + 1); } -template <class T, qsizetype Prealloc> +template <class T> template <typename AT> -inline qsizetype QVarLengthArray<T, Prealloc>::removeAll(const AT &t) +inline qsizetype QVLABase<T>::removeAll(const AT &t) { return QtPrivate::sequential_erase_with_copy(*this, t); } -template <class T, qsizetype Prealloc> +template <class T> template <typename AT> -inline bool QVarLengthArray<T, Prealloc>::removeOne(const AT &t) +inline bool QVLABase<T>::removeOne(const AT &t) { return QtPrivate::sequential_erase_one(*this, t); } -template <class T, qsizetype Prealloc> +template <class T> template <typename Predicate> -inline qsizetype QVarLengthArray<T, Prealloc>::removeIf(Predicate pred) +inline qsizetype QVLABase<T>::removeIf(Predicate pred) { return QtPrivate::sequential_erase_if(*this, pred); } +#if QT_DEPRECATED_SINCE(6, 3) template <class T, qsizetype Prealloc> inline void QVarLengthArray<T, Prealloc>::prepend(T &&t) { insert(cbegin(), std::move(t)); } template <class T, qsizetype Prealloc> inline void QVarLengthArray<T, Prealloc>::prepend(const T &t) { insert(begin(), 1, t); } +#endif -template <class T, qsizetype Prealloc> -inline void QVarLengthArray<T, Prealloc>::replace(qsizetype i, const T &t) +template <class T> +inline void QVLABase<T>::replace(qsizetype i, const T &t) { - Q_ASSERT_X(i >= 0 && i < size(), "QVarLengthArray::replace", "index out of range"); - const T copy(t); - data()[i] = copy; + verify(i); + data()[i] = t; } -template <class T, qsizetype Prealloc> +template <class T> template <typename...Args> -Q_OUTOFLINE_TEMPLATE auto QVarLengthArray<T, Prealloc>::emplace(const_iterator before, Args &&...args) -> iterator +Q_OUTOFLINE_TEMPLATE auto QVLABase<T>::emplace_impl(qsizetype prealloc, void *array, const_iterator before, Args &&...args) -> iterator { Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid"); Q_ASSERT(size() <= capacity()); Q_ASSERT(capacity() > 0); - qsizetype offset = qsizetype(before - begin()); + qsizetype offset = qsizetype(before - cbegin()); if (size() == capacity()) - reserve(size() * 2); - if (!QTypeInfo<T>::isRelocatable) { + reallocate_impl(prealloc, array, size(), size() * 2); + if constexpr (!QTypeInfo<T>::isRelocatable) { T *b = begin() + offset; T *i = end(); T *j = i + 1; @@ -643,20 +855,20 @@ Q_OUTOFLINE_TEMPLATE auto QVarLengthArray<T, Prealloc>::emplace(const_iterator b memmove(static_cast<void *>(b + 1), static_cast<const void *>(b), (size() - offset) * sizeof(T)); new (b) T(std::forward<Args>(args)...); } - s += 1; + this->s += 1; return data() + offset; } -template <class T, qsizetype Prealloc> -Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, qsizetype n, const T &t) +template <class T> +Q_OUTOFLINE_TEMPLATE auto QVLABase<T>::insert_impl(qsizetype prealloc, void *array, const_iterator before, qsizetype n, const T &t) -> iterator { Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid"); - qsizetype offset = qsizetype(before - begin()); + qsizetype offset = qsizetype(before - cbegin()); if (n != 0) { const T copy(t); // `t` could alias an element in [begin(), end()[ - resize(size() + n); - if (!QTypeInfo<T>::isRelocatable) { + resize_impl(prealloc, array, size() + n); + if constexpr (!QTypeInfo<T>::isRelocatable) { T *b = begin() + offset; T *j = end(); T *i = j - n; @@ -676,23 +888,28 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA return data() + offset; } -template <class T, qsizetype Prealloc> -Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::erase(const_iterator abegin, const_iterator aend) +template <class T> +Q_OUTOFLINE_TEMPLATE auto QVLABase<T>::erase(const_iterator abegin, const_iterator aend) -> iterator { Q_ASSERT_X(isValidIterator(abegin), "QVarLengthArray::insert", "The specified const_iterator argument 'abegin' is invalid"); Q_ASSERT_X(isValidIterator(aend), "QVarLengthArray::insert", "The specified const_iterator argument 'aend' is invalid"); - qsizetype f = qsizetype(abegin - begin()); - qsizetype l = qsizetype(aend - begin()); + qsizetype f = qsizetype(abegin - cbegin()); + qsizetype l = qsizetype(aend - cbegin()); qsizetype n = l - f; + if (n == 0) // avoid UB in std::move() below + return data() + f; + + Q_ASSERT(n > 0); // aend must be reachable from abegin + if constexpr (QTypeInfo<T>::isComplex) { std::move(begin() + l, end(), QT_MAKE_CHECKED_ARRAY_ITERATOR(begin() + f, size() - f)); std::destroy(end() - n, end()); } else { memmove(static_cast<void *>(data() + f), static_cast<const void *>(data() + l), (size() - l) * sizeof(T)); } - s -= n; + this->s -= n; return data() + f; } @@ -720,21 +937,21 @@ bool operator>=(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T, template <typename T, qsizetype Prealloc> size_t qHash(const QVarLengthArray<T, Prealloc> &key, size_t seed = 0) - noexcept(noexcept(qHashRange(key.cbegin(), key.cend(), seed))) + noexcept(QtPrivate::QNothrowHashable_v<T>) { - return qHashRange(key.cbegin(), key.cend(), seed); + return key.hash(seed); } template <typename T, qsizetype Prealloc, typename AT> qsizetype erase(QVarLengthArray<T, Prealloc> &array, const AT &t) { - return QtPrivate::sequential_erase(array, t); + return array.removeAll(t); } template <typename T, qsizetype Prealloc, typename Predicate> qsizetype erase_if(QVarLengthArray<T, Prealloc> &array, Predicate pred) { - return QtPrivate::sequential_erase_if(array, pred); + return array.removeIf(pred); } QT_END_NAMESPACE diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index 0ba939ab60..4f41304c03 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -1,29 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \class QVarLengthArray @@ -105,6 +81,18 @@ \l{default-constructed value}. */ +/*! + \fn template<class T, qsizetype Prealloc> QVarLengthArray<T, Prealloc>::QVarLengthArray(qsizetype size, const T &v) + \since 6.4 + + Constructs an array with an initial size of \a size elements filled with + copies of \a v. + + \note This constructor is only available when \c T is copy-constructible. + + \sa size(), squeeze() +*/ + /*! \fn template<class T, qsizetype Prealloc> QVarLengthArray<T, Prealloc>::QVarLengthArray(std::initializer_list<T> args) \since 5.5 @@ -245,6 +233,19 @@ \sa size(), squeeze() */ +/*! + \fn template<class T, qsizetype Prealloc> void QVarLengthArray<T, Prealloc>::resize(qsizetype size, const T &v) + \since 6.4 + + Sets the size of the array to \a size. If \a size is greater than + the current size, copies of \a v are added to the end. If \a size is + less than the current size, elements are removed from the end. + + \note This function is only available when \c T is copy-constructible. + + \sa size(), squeeze() +*/ + /*! \fn template<class T, qsizetype Prealloc> qsizetype QVarLengthArray<T, Prealloc>::capacity() const Returns the maximum number of elements that can be stored in the @@ -545,6 +546,8 @@ \fn template<class T, qsizetype Prealloc> void QVarLengthArray<T, Prealloc>::prepend(T &&value) \since 4.8 + \deprecated [6.3] This is slow. If you must, use \c{insert(cbegin(), ~~~)} instead. + Inserts \a value at the beginning of the array. @@ -569,16 +572,6 @@ \sa operator[](), remove() */ -/*! \fn template<class T, qsizetype Prealloc> void QVarLengthArray<T, Prealloc>::remove(qsizetype i) - - \overload - \since 4.8 - - Removes the element at index position \a i. - - \sa insert(), replace() -*/ - /*! \fn template<class T, qsizetype Prealloc> void QVarLengthArray<T, Prealloc>::remove(qsizetype i, qsizetype count) \overload diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 8d880407dd..4fad2bce8f 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.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 QVECTOR_H #define QVECTOR_H @@ -43,6 +7,12 @@ #include <QtCore/qlist.h> #include <QtCore/qcontainerfwd.h> +#if 0 +#pragma qt_class(QVector) +#pragma qt_class(QMutableVectorIterator) +#pragma qt_class(QVectorIterator) +#endif + QT_BEGIN_NAMESPACE #if !defined(QT_NO_JAVA_STYLE_ITERATORS) diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index da093a417d..7d96b43898 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -1,43 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.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) 2021 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include <QtCore/qversionnumber.h> #include <QtCore/qhash.h> @@ -57,6 +21,9 @@ QT_BEGIN_NAMESPACE +QT_IMPL_METATYPE_EXTERN(QVersionNumber) +QT_IMPL_METATYPE_EXTERN(QTypeRevision) + /*! \class QVersionNumber \inmodule QtCore @@ -120,6 +87,13 @@ QT_BEGIN_NAMESPACE */ /*! + \fn template <qsizetype N> QVersionNumber::QVersionNumber(const QVarLengthArray<int, N> &seg) + \since 6.4 + + Constructs a version number from the list of numbers contained in \a seg. +*/ + +/*! \fn bool QVersionNumber::isNull() const Returns \c true if there are zero numerical segments, otherwise returns @@ -168,7 +142,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn const QList<int>& QVersionNumber::segments() const + \fn QList<int> QVersionNumber::segments() const Returns all of the numerical segments. @@ -181,13 +155,13 @@ QList<int> QVersionNumber::segments() const QList<int> result; result.resize(segmentCount()); - for (int i = 0; i < segmentCount(); ++i) + for (qsizetype i = 0; i < segmentCount(); ++i) result[i] = segmentAt(i); return result; } /*! - \fn int QVersionNumber::segmentAt(int index) const + \fn int QVersionNumber::segmentAt(qsizetype index) const Returns the segment value at \a index. If the index does not exist, returns 0. @@ -196,7 +170,7 @@ QList<int> QVersionNumber::segments() const */ /*! - \fn int QVersionNumber::segmentCount() const + \fn qsizetype QVersionNumber::segmentCount() const Returns the number of integers stored in segments(). @@ -215,7 +189,7 @@ QList<int> QVersionNumber::segments() const */ QVersionNumber QVersionNumber::normalized() const { - int i; + qsizetype i; for (i = m_segments.size(); i; --i) if (m_segments.at(i - 1) != 0) break; @@ -239,7 +213,7 @@ bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const noexcept { if (segmentCount() > other.segmentCount()) return false; - for (int i = 0; i < segmentCount(); ++i) { + for (qsizetype i = 0; i < segmentCount(); ++i) { if (segmentAt(i) != other.segmentAt(i)) return false; } @@ -261,7 +235,7 @@ bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const noexcept */ int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) noexcept { - int commonlen; + qsizetype commonlen; if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) { // we can't use memcmp because it interprets the data as unsigned bytes @@ -269,12 +243,12 @@ int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) const qint8 *ptr2 = v2.m_segments.inline_segments + InlineSegmentStartIdx; commonlen = qMin(v1.m_segments.size(), v2.m_segments.size()); - for (int i = 0; i < commonlen; ++i) + for (qsizetype i = 0; i < commonlen; ++i) if (int x = ptr1[i] - ptr2[i]) return x; } else { commonlen = qMin(v1.segmentCount(), v2.segmentCount()); - for (int i = 0; i < commonlen; ++i) { + for (qsizetype i = 0; i < commonlen; ++i) { if (v1.segmentAt(i) != v2.segmentAt(i)) return v1.segmentAt(i) - v2.segmentAt(i); } @@ -311,8 +285,8 @@ int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2) { - int commonlen = qMin(v1.segmentCount(), v2.segmentCount()); - int i; + qsizetype commonlen = qMin(v1.segmentCount(), v2.segmentCount()); + qsizetype i; for (i = 0; i < commonlen; ++i) { if (v1.segmentAt(i) != v2.segmentAt(i)) break; @@ -391,17 +365,19 @@ QString QVersionNumber::toString() const QString version; version.reserve(qMax(segmentCount() * 2 - 1, 0)); bool first = true; - for (int i = 0; i < segmentCount(); ++i) { + for (qsizetype i = 0; i < segmentCount(); ++i) { if (!first) - version += QLatin1Char('.'); + version += u'.'; version += QString::number(segmentAt(i)); first = false; } return version; } -#if QT_STRINGVIEW_LEVEL < 2 /*! + \fn QVersionNumber QVersionNumber::fromString(QAnyStringView string, qsizetype *suffixIndex) + \since 6.4 + Constructs a QVersionNumber from a specially formatted \a string of non-negative decimal numbers delimited by a period (\c{.}). @@ -409,54 +385,23 @@ QString QVersionNumber::toString() const is considered to be the suffix string. The start index of that string will be stored in \a suffixIndex if it is not null. - \snippet qversionnumber/main.cpp 3 - - \sa isNull() -*/ -QVersionNumber QVersionNumber::fromString(const QString &string, int *suffixIndex) -{ - return fromString(QLatin1String(string.toLatin1()), suffixIndex); -} -#endif - -/*! - \since 5.10 - \overload - - Constructs a QVersionNumber from a specially formatted \a string of - non-negative decimal numbers delimited by '.'. - - Once the numerical segments have been parsed, the remainder of the string - is considered to be the suffix string. The start index of that string will be - stored in \a suffixIndex if it is not null. + \snippet qversionnumber/main.cpp 3-latin1-1 - \snippet qversionnumber/main.cpp 3 + \note In versions prior to Qt 6.4, this function was overloaded for QString, + QLatin1StringView and QStringView instead, and \a suffixIndex was an \c{int*}. \sa isNull() */ -QVersionNumber QVersionNumber::fromString(QStringView string, int *suffixIndex) -{ - return fromString(QLatin1String(string.toLatin1()), suffixIndex); -} - -/*! - \since 5.10 - \overload - - Constructs a QVersionNumber from a specially formatted \a string of - non-negative decimal numbers delimited by '.'. - - Once the numerical segments have been parsed, the remainder of the string - is considered to be the suffix string. The start index of that string will be - stored in \a suffixIndex if it is not null. - - \snippet qversionnumber/main.cpp 3-latin1-1 - \sa isNull() -*/ -QVersionNumber QVersionNumber::fromString(QLatin1String string, int *suffixIndex) +static QVersionNumber from_string(QLatin1StringView string, qsizetype *suffixIndex) { - QList<int> seg; + // 32 should be more than enough, and, crucially, it means we're allocating + // not more (and often less) often when compared with direct QList usage + // for all possible segment counts (under the constraint that we don't want + // to keep more capacity around for the lifetime of the resulting + // QVersionNumber than required), esp. in the common case where the inline + // storage can be used. + QVarLengthArray<int, 32> seg; const char *start = string.begin(); const char *end = start; @@ -471,12 +416,56 @@ QVersionNumber QVersionNumber::fromString(QLatin1String string, int *suffixIndex seg.append(int(value)); start = end + 1; lastGoodEnd = end; - } while (start < endOfString && (end < endOfString && *end == '.')); + } while (start < endOfString && end < endOfString && *end == '.'); if (suffixIndex) - *suffixIndex = int(lastGoodEnd - string.begin()); + *suffixIndex = lastGoodEnd - string.begin(); - return QVersionNumber(std::move(seg)); + return QVersionNumber(seg); +} + +static QVersionNumber from_string(q_no_char8_t::QUtf8StringView string, qsizetype *suffixIndex) +{ + return from_string(QLatin1StringView(string.data(), string.size()), suffixIndex); +} + +// in qstring.cpp +extern void qt_to_latin1(uchar *dst, const char16_t *uc, qsizetype len); + +static QVersionNumber from_string(QStringView string, qsizetype *suffixIndex) +{ + QVarLengthArray<char> copy; + copy.resize(string.size()); + qt_to_latin1(reinterpret_cast<uchar*>(copy.data()), string.utf16(), string.size()); + return from_string(QLatin1StringView(copy.data(), copy.size()), suffixIndex); +} + +QVersionNumber QVersionNumber::fromString(QAnyStringView string, qsizetype *suffixIndex) +{ + return string.visit([=] (auto string) { return from_string(string, suffixIndex); }); +} + +void QVersionNumber::SegmentStorage::setListData(const QList<int> &seg) +{ + pointer_segments = new QList<int>(seg); +} + +void QVersionNumber::SegmentStorage::setListData(QList<int> &&seg) +{ + pointer_segments = new QList<int>(std::move(seg)); +} + +void QVersionNumber::SegmentStorage::setListData(const int *first, const int *last) +{ + pointer_segments = new QList<int>(first, last); +} + +void QVersionNumber::SegmentStorage::resize(qsizetype len) +{ + if (isUsingPointer()) + pointer_segments->resize(len); + else + setInlineSize(len); } void QVersionNumber::SegmentStorage::setVector(int len, int maj, int min, int mic) @@ -529,7 +518,8 @@ QDataStream& operator>>(QDataStream &in, QVersionNumber &version) QDebug operator<<(QDebug debug, const QVersionNumber &version) { QDebugStateSaver saver(debug); - debug.noquote() << version.toString(); + debug.nospace().noquote(); + debug << "QVersionNumber(" << version.toString() << ")"; return debug; } #endif diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h index 65f0952cd9..a7c2b44a7e 100644 --- a/src/corelib/tools/qversionnumber.h +++ b/src/corelib/tools/qversionnumber.h @@ -1,43 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.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) 2022 Intel Corporation. +// Copyright (C) 2015 Keith Gardner <kreios4004@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QVERSIONNUMBER_H #define QVERSIONNUMBER_H @@ -96,13 +60,15 @@ class QVersionNumber if (dataFitsInline(seg.data(), seg.size())) setInlineData(seg.data(), seg.size()); else - pointer_segments = new QList<int>(seg); + setListData(seg); } + Q_CORE_EXPORT void setListData(const QList<int> &seg); + SegmentStorage(const SegmentStorage &other) { if (other.isUsingPointer()) - pointer_segments = new QList<int>(*other.pointer_segments); + setListData(*other.pointer_segments); else dummy = other.dummy; } @@ -112,7 +78,7 @@ class QVersionNumber if (isUsingPointer() && other.isUsingPointer()) { *pointer_segments = *other.pointer_segments; } else if (other.isUsingPointer()) { - pointer_segments = new QList<int>(*other.pointer_segments); + setListData(*other.pointer_segments); } else { if (isUsingPointer()) delete pointer_segments; @@ -131,45 +97,50 @@ class QVersionNumber void swap(SegmentStorage &other) noexcept { - qSwap(dummy, other.dummy); + std::swap(dummy, other.dummy); } explicit SegmentStorage(QList<int> &&seg) { - if (dataFitsInline(seg.data(), seg.size())) - setInlineData(seg.data(), seg.size()); + if (dataFitsInline(std::as_const(seg).data(), seg.size())) + setInlineData(std::as_const(seg).data(), seg.size()); else - pointer_segments = new QList<int>(std::move(seg)); + setListData(std::move(seg)); } - SegmentStorage(std::initializer_list<int> args) + + Q_CORE_EXPORT void setListData(QList<int> &&seg); + + explicit SegmentStorage(std::initializer_list<int> args) + : SegmentStorage(args.begin(), args.end()) {} + + explicit SegmentStorage(const int *first, const int *last) { - if (dataFitsInline(std::data(args), int(args.size()))) { - setInlineData(std::data(args), int(args.size())); + if (dataFitsInline(first, last - first)) { + setInlineData(first, last - first); } else { - pointer_segments = new QList<int>(args); + setListData(first, last); } } + Q_CORE_EXPORT void setListData(const int *first, const int *last); + ~SegmentStorage() { if (isUsingPointer()) delete pointer_segments; } bool isUsingPointer() const noexcept { return (inline_segments[InlineSegmentMarker] & 1) == 0; } - int size() const noexcept + qsizetype size() const noexcept { return isUsingPointer() ? pointer_segments->size() : (inline_segments[InlineSegmentMarker] >> 1); } - void setInlineSize(int len) - { inline_segments[InlineSegmentMarker] = qint8(1 + 2 * len); } - - void resize(int len) + void setInlineSize(qsizetype len) { - if (isUsingPointer()) - pointer_segments->resize(len); - else - setInlineSize(len); + Q_ASSERT(len <= InlineSegmentCount); + inline_segments[InlineSegmentMarker] = qint8(1 + 2 * len); } - int at(int index) const + Q_CORE_EXPORT void resize(qsizetype len); + + int at(qsizetype index) const { return isUsingPointer() ? pointer_segments->at(index) : @@ -187,28 +158,29 @@ class QVersionNumber } private: - static bool dataFitsInline(const int *data, int len) + static bool dataFitsInline(const int *data, qsizetype len) { if (len > InlineSegmentCount) return false; - for (int i = 0; i < len; ++i) + for (qsizetype i = 0; i < len; ++i) if (data[i] != qint8(data[i])) return false; return true; } - void setInlineData(const int *data, int len) + void setInlineData(const int *data, qsizetype len) { + Q_ASSERT(len <= InlineSegmentCount); dummy = 1 + len * 2; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - for (int i = 0; i < len; ++i) + for (qsizetype i = 0; i < len; ++i) dummy |= quintptr(data[i] & 0xFF) << (8 * (i + 1)); #elif Q_BYTE_ORDER == Q_BIG_ENDIAN - for (int i = 0; i < len; ++i) + for (qsizetype i = 0; i < len; ++i) dummy |= quintptr(data[i] & 0xFF) << (8 * (sizeof(void *) - i - 1)); #else // the code above is equivalent to: setInlineSize(len); - for (int i = 0; i < len; ++i) + for (qsizetype i = 0; i < len; ++i) inline_segments[InlineSegmentStartIdx + i] = data[i] & 0xFF; #endif } @@ -230,6 +202,11 @@ public: : m_segments(args) {} + template <qsizetype N> + explicit QVersionNumber(const QVarLengthArray<int, N> &sec) + : m_segments(sec.begin(), sec.end()) + {} + inline explicit QVersionNumber(int maj) { m_segments.setSegments(1, maj); } @@ -258,24 +235,46 @@ public: [[nodiscard]] Q_CORE_EXPORT QList<int> segments() const; - [[nodiscard]] inline int segmentAt(int index) const noexcept + [[nodiscard]] inline int segmentAt(qsizetype index) const noexcept { return (m_segments.size() > index) ? m_segments.at(index) : 0; } - [[nodiscard]] inline int segmentCount() const noexcept + [[nodiscard]] inline qsizetype segmentCount() const noexcept { return m_segments.size(); } [[nodiscard]] Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const noexcept; [[nodiscard]] Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) noexcept; - [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2); + [[nodiscard]] Q_CORE_EXPORT static QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2); [[nodiscard]] Q_CORE_EXPORT QString toString() const; -#if QT_STRINGVIEW_LEVEL < 2 - [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr); + [[nodiscard]] Q_CORE_EXPORT static QVersionNumber fromString(QAnyStringView string, qsizetype *suffixIndex = nullptr); + +#if QT_DEPRECATED_SINCE(6, 4) && QT_POINTER_SIZE != 4 + Q_WEAK_OVERLOAD + QT_DEPRECATED_VERSION_X_6_4("Use the 'qsizetype *suffixIndex' overload.") + [[nodiscard]] static QVersionNumber fromString(QAnyStringView string, int *suffixIndex) + { + QT_WARNING_PUSH + // fromString() writes to *n unconditionally, but GCC can't know that + QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") + qsizetype n; + auto r = fromString(string, &n); + if (suffixIndex) { + Q_ASSERT(int(n) == n); + *suffixIndex = int(n); + } + return r; + QT_WARNING_POP + } +#endif + + +#if QT_CORE_REMOVED_SINCE(6, 4) + [[nodiscard]] Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex); + [[nodiscard]] Q_CORE_EXPORT static QVersionNumber fromString(QLatin1StringView string, int *suffixIndex); + [[nodiscard]] Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex); #endif - [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr); - [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr); [[nodiscard]] friend bool operator> (const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept { return compare(lhs, rhs) > 0; } @@ -295,7 +294,6 @@ public: [[nodiscard]] friend bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept { return compare(lhs, rhs) != 0; } - private: #ifndef QT_NO_DATASTREAM friend Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version); @@ -462,7 +460,7 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QTypeRevision &revision); QT_END_NAMESPACE -Q_DECLARE_METATYPE(QVersionNumber) -Q_DECLARE_METATYPE(QTypeRevision) +QT_DECL_METATYPE_EXTERN(QVersionNumber, Q_CORE_EXPORT) +QT_DECL_METATYPE_EXTERN(QTypeRevision, Q_CORE_EXPORT) #endif // QVERSIONNUMBER_H |