summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qalgorithms.qdoc12
-rw-r--r--src/corelib/tools/qarraydataops.h11
-rw-r--r--src/corelib/tools/qatomicscopedvaluerollback_p.h1
-rw-r--r--src/corelib/tools/qcommandlineparser.cpp18
-rw-r--r--src/corelib/tools/qcontainerfwd.h2
-rw-r--r--src/corelib/tools/qcontainertools_impl.h40
-rw-r--r--src/corelib/tools/qcontiguouscache.h4
-rw-r--r--src/corelib/tools/qcryptographichash.cpp205
-rw-r--r--src/corelib/tools/qcryptographichash.h5
-rw-r--r--src/corelib/tools/qduplicatetracker_p.h4
-rw-r--r--src/corelib/tools/qeasingcurve.cpp24
-rw-r--r--src/corelib/tools/qflatmap_p.h36
-rw-r--r--src/corelib/tools/qfreelist_p.h3
-rw-r--r--src/corelib/tools/qhash.cpp45
-rw-r--r--src/corelib/tools/qhash.h18
-rw-r--r--src/corelib/tools/qhashfunctions.h32
-rw-r--r--src/corelib/tools/qiterator.qdoc8
-rw-r--r--src/corelib/tools/qlist.h6
-rw-r--r--src/corelib/tools/qlist.qdoc33
-rw-r--r--src/corelib/tools/qmap.h8
-rw-r--r--src/corelib/tools/qmap.qdoc33
-rw-r--r--src/corelib/tools/qmultimap.qdoc24
-rw-r--r--src/corelib/tools/qoffsetstringarray_p.h27
-rw-r--r--src/corelib/tools/qrect.h10
-rw-r--r--src/corelib/tools/qscopedpointer.cpp10
-rw-r--r--src/corelib/tools/qscopedpointer.h8
-rw-r--r--src/corelib/tools/qscopeguard.h2
-rw-r--r--src/corelib/tools/qset.h6
-rw-r--r--src/corelib/tools/qshareddata.h12
-rw-r--r--src/corelib/tools/qshareddata_impl.h4
-rw-r--r--src/corelib/tools/qtaggedpointer.h29
-rw-r--r--src/corelib/tools/qversionnumber.cpp13
32 files changed, 462 insertions, 231 deletions
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index 4a9c03a43c..5fe0b3e8c3 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -109,18 +109,6 @@
\sa {container classes}, <QtGlobal>
*/
-/*! \fn template <typename T> void qSwap(T &var1, T &var2)
- \relates <QtAlgorithms>
- \deprecated
-
- Use \c std::swap instead.
-
- Exchanges the values of variables \a var1 and \a var2.
-
- Example:
- \snippet code/doc_src_qalgorithms.cpp 0
-*/
-
/*!
\fn template <typename ForwardIterator> void qDeleteAll(ForwardIterator begin, ForwardIterator end)
\relates <QtAlgorithms>
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index afd1a264bd..13d5572c03 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -213,6 +213,17 @@ public:
--this->size;
}
+ struct Span { T *begin; T *end; };
+
+ void copyRanges(const std::initializer_list<Span> &ranges)
+ {
+ auto it = this->begin();
+ std::for_each(ranges.begin(), ranges.end(), [&it](const auto &span) {
+ it = std::copy(span.begin, span.end, it);
+ });
+ this->size = std::distance(this->begin(), it);
+ }
+
void assign(T *b, T *e, parameter_type t) noexcept
{
Q_ASSERT(b <= e);
diff --git a/src/corelib/tools/qatomicscopedvaluerollback_p.h b/src/corelib/tools/qatomicscopedvaluerollback_p.h
index a0f088ec45..147156d585 100644
--- a/src/corelib/tools/qatomicscopedvaluerollback_p.h
+++ b/src/corelib/tools/qatomicscopedvaluerollback_p.h
@@ -43,6 +43,7 @@ class [[nodiscard]] QAtomicScopedValueRollback
}
// GCC 8.x does not tread __builtin_unreachable() as constexpr
#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
+ // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
Q_UNREACHABLE();
#endif
return std::memory_order_seq_cst;
diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp
index e771877265..f63b0c5c59 100644
--- a/src/corelib/tools/qcommandlineparser.cpp
+++ b/src/corelib/tools/qcommandlineparser.cpp
@@ -500,9 +500,9 @@ QString QCommandLineParser::errorText() const
{
if (!d->errorText.isEmpty())
return d->errorText;
- if (d->unknownOptionNames.count() == 1)
+ if (d->unknownOptionNames.size() == 1)
return tr("Unknown option '%1'.").arg(d->unknownOptionNames.first());
- if (d->unknownOptionNames.count() > 1)
+ if (d->unknownOptionNames.size() > 1)
return tr("Unknown options: %1.").arg(d->unknownOptionNames.join(QStringLiteral(", ")));
return QString();
}
@@ -691,7 +691,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args)
if (forcePositional) {
positionalArgumentList.append(argument);
} else if (argument.startsWith(doubleDashString)) {
- if (argument.length() > 2) {
+ if (argument.size() > 2) {
QString optionName = argument.mid(2).section(assignChar, 0, 0);
if (registerFoundOption(optionName)) {
if (!parseOptionValue(optionName, argument, &argumentIterator, args.end()))
@@ -793,7 +793,7 @@ bool QCommandLineParser::isSet(const QString &name) const
if (d->optionNames.contains(name))
return true;
const QStringList aliases = d->aliases(name);
- for (const QString &optionName : qAsConst(d->optionNames)) {
+ for (const QString &optionName : std::as_const(d->optionNames)) {
if (aliases.contains(optionName))
return true;
}
@@ -1042,7 +1042,7 @@ static QString wrapText(const QString &names, int optionNameMaxWidth, const QStr
int lastBreakable = -1;
const int max = 79 - (indentation.size() + optionNameMaxWidth + 1);
int x = 0;
- const int len = description.length();
+ const int len = description.size();
for (int i = 0; i < len; ++i) {
++x;
@@ -1110,13 +1110,13 @@ QString QCommandLineParserPrivate::helpText(bool includeQtOptions) const
QStringList optionNameList;
optionNameList.reserve(options.size());
int longestOptionNameString = 0;
- for (const QCommandLineOption &option : qAsConst(options)) {
+ for (const QCommandLineOption &option : std::as_const(options)) {
if (option.flags() & QCommandLineOption::HiddenFromHelp)
continue;
const QStringList optionNames = option.names();
QString optionNamesString;
for (const QString &optionName : optionNames) {
- const int numDashes = optionName.length() == 1 ? 1 : 2;
+ const int numDashes = optionName.size() == 1 ? 1 : 2;
optionNamesString += QLatin1StringView("--", numDashes) + optionName + ", "_L1;
}
if (!optionNames.isEmpty())
@@ -1125,12 +1125,12 @@ QString QCommandLineParserPrivate::helpText(bool includeQtOptions) const
if (!valueName.isEmpty())
optionNamesString += " <"_L1 + valueName + u'>';
optionNameList.append(optionNamesString);
- longestOptionNameString = qMax(longestOptionNameString, optionNamesString.length());
+ longestOptionNameString = qMax(longestOptionNameString, optionNamesString.size());
}
++longestOptionNameString;
const int optionNameMaxWidth = qMin(50, longestOptionNameString);
auto optionNameIterator = optionNameList.cbegin();
- for (const QCommandLineOption &option : qAsConst(options)) {
+ for (const QCommandLineOption &option : std::as_const(options)) {
if (option.flags() & QCommandLineOption::HiddenFromHelp)
continue;
text += wrapText(*optionNameIterator, optionNameMaxWidth, option.description());
diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h
index c8d791f200..b876c4648f 100644
--- a/src/corelib/tools/qcontainerfwd.h
+++ b/src/corelib/tools/qcontainerfwd.h
@@ -28,7 +28,7 @@ template <typename T> class QStack;
template <typename T, qsizetype Prealloc = 256> class QVarLengthArray;
template <typename T> class QList;
class QString;
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template<typename T> using QVector = QList<T>;
using QStringList = QList<QString>;
class QByteArray;
diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h
index 4a5f9f184f..9b0bd2ad6b 100644
--- a/src/corelib/tools/qcontainertools_impl.h
+++ b/src/corelib/tools/qcontainertools_impl.h
@@ -14,6 +14,8 @@
#include <QtCore/qglobal.h>
#include <QtCore/qtypeinfo.h>
+#include <QtCore/qxptype_traits.h>
+
#include <cstring>
#include <iterator>
#include <memory>
@@ -203,43 +205,25 @@ void reserveIfForwardIterator(Container *c, ForwardIterator f, ForwardIterator l
c->reserve(static_cast<typename Container::size_type>(std::distance(f, l)));
}
-template <typename Iterator, typename = std::void_t<>>
-struct AssociativeIteratorHasKeyAndValue : std::false_type
-{
-};
-
template <typename Iterator>
-struct AssociativeIteratorHasKeyAndValue<
- Iterator,
- std::void_t<decltype(std::declval<Iterator &>().key()),
- decltype(std::declval<Iterator &>().value())>
- >
- : std::true_type
-{
-};
-
-template <typename Iterator, typename = std::void_t<>, typename = std::void_t<>>
-struct AssociativeIteratorHasFirstAndSecond : std::false_type
-{
-};
+using KeyAndValueTest = decltype(
+ std::declval<Iterator &>().key(),
+ std::declval<Iterator &>().value()
+);
template <typename Iterator>
-struct AssociativeIteratorHasFirstAndSecond<
- Iterator,
- std::void_t<decltype(std::declval<Iterator &>()->first),
- decltype(std::declval<Iterator &>()->second)>
- >
- : std::true_type
-{
-};
+using FirstAndSecondTest = decltype(
+ std::declval<Iterator &>()->first,
+ std::declval<Iterator &>()->second
+);
template <typename Iterator>
using IfAssociativeIteratorHasKeyAndValue =
- typename std::enable_if<AssociativeIteratorHasKeyAndValue<Iterator>::value, bool>::type;
+ std::enable_if_t<qxp::is_detected_v<KeyAndValueTest, Iterator>, bool>;
template <typename Iterator>
using IfAssociativeIteratorHasFirstAndSecond =
- typename std::enable_if<AssociativeIteratorHasFirstAndSecond<Iterator>::value, bool>::type;
+ std::enable_if_t<qxp::is_detected_v<FirstAndSecondTest, Iterator>, bool>;
template <typename T, typename U>
using IfIsNotSame =
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index 70703fe0ab..98fa82fda9 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -63,7 +63,7 @@ public:
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QContiguousCache)
void swap(QContiguousCache &other) noexcept { qt_ptr_swap(d, other.d); }
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template <typename U = T>
QTypeTraits::compare_eq_result<U> operator==(const QContiguousCache<T> &other) const
{
@@ -85,7 +85,7 @@ public:
#else
bool operator==(const QContiguousCache &other) const;
bool operator!=(const QContiguousCache &other) const;
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
inline qsizetype capacity() const {return d->alloc; }
inline qsizetype count() const { return d->count; }
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index 8d60be175e..7ccafaeb36 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -5,6 +5,8 @@
#include <qcryptographichash.h>
#include <qiodevice.h>
+#include <array>
+
#include "../../3rdparty/sha1/sha1.cpp"
#if defined(QT_BOOTSTRAPPED) && !defined(QT_CRYPTOGRAPHICHASH_ONLY_SHA1)
@@ -12,6 +14,7 @@
#endif
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+#if !QT_CONFIG(opensslv30) || !QT_CONFIG(openssl_linked)
// qdoc and qmake only need SHA-1
#include "../../3rdparty/md5/md5.h"
#include "../../3rdparty/md5/md5.cpp"
@@ -91,6 +94,9 @@ static inline int SHA384_512AddLength(SHA512Context *context, unsigned int lengt
uint64_t addTemp;
return SHA384_512AddLengthM(context, length);
}
+#endif // !QT_CONFIG(opensslv30)
+
+#include "qtcore-config_p.h"
#if QT_CONFIG(system_libb2)
#include <blake2.h>
@@ -100,6 +106,13 @@ static inline int SHA384_512AddLength(SHA512Context *context, unsigned int lengt
#endif
#endif // QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(opensslv30) && QT_CONFIG(openssl_linked)
+#define USING_OPENSSL30
+#include <openssl/evp.h>
+#include <openssl/provider.h>
+#include <openssl/sha.h>
+#endif
+
QT_BEGIN_NAMESPACE
static constexpr qsizetype MaxHashLength = 64;
@@ -117,10 +130,17 @@ static constexpr int hashLengthInternal(QCryptographicHash::Algorithm method) no
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
CASE(Md4, 16);
CASE(Md5, 16);
+#ifdef USING_OPENSSL30
+ CASE(Sha224, SHA224_DIGEST_LENGTH);
+ CASE(Sha256, SHA256_DIGEST_LENGTH);
+ CASE(Sha384, SHA384_DIGEST_LENGTH);
+ CASE(Sha512, SHA512_DIGEST_LENGTH);
+#else
CASE(Sha224, SHA224HashSize);
CASE(Sha256, SHA256HashSize);
CASE(Sha384, SHA384HashSize);
CASE(Sha512, SHA512HashSize);
+#endif
CASE(Blake2s_128, 128 / 8);
case QCryptographicHash::Blake2b_160:
case QCryptographicHash::Blake2s_160:
@@ -153,6 +173,37 @@ static constexpr int hashLengthInternal(QCryptographicHash::Algorithm method) no
return 0;
}
+#ifdef USING_OPENSSL30
+static constexpr const char * methodToName(QCryptographicHash::Algorithm method) noexcept
+{
+ switch (method) {
+#define CASE(Enum, Name) \
+ case QCryptographicHash:: Enum : \
+ return Name \
+ /*end*/
+ CASE(Sha1, "SHA1");
+ CASE(Md4, "MD4");
+ CASE(Md5, "MD5");
+ CASE(Sha224, "SHA224");
+ CASE(Sha256, "SHA256");
+ CASE(Sha384, "SHA384");
+ CASE(Sha512, "SHA512");
+ CASE(RealSha3_224, "SHA3-224");
+ CASE(RealSha3_256, "SHA3-256");
+ CASE(RealSha3_384, "SHA3-384");
+ CASE(RealSha3_512, "SHA3-512");
+ CASE(Keccak_224, "SHA3-224");
+ CASE(Keccak_256, "SHA3-256");
+ CASE(Keccak_384, "SHA3-384");
+ CASE(Keccak_512, "SHA3-512");
+ CASE(Blake2b_512, "BLAKE2B512");
+ CASE(Blake2s_256, "BLAKE2S256");
+#undef CASE
+ default: return nullptr;
+ }
+}
+#endif
+
class QCryptographicHashPrivate
{
public:
@@ -168,9 +219,29 @@ public:
QByteArrayView resultView() const noexcept { return result.toByteArrayView(); }
const QCryptographicHash::Algorithm method;
+
+#ifdef USING_OPENSSL30
+ struct EVP_MD_CTX_deleter {
+ void operator()(EVP_MD_CTX *ctx) const noexcept {
+ EVP_MD_CTX_free(ctx);
+ }
+ };
+ struct EVP_MD_deleter {
+ void operator()(EVP_MD *md) const noexcept {
+ EVP_MD_free(md);
+ }
+ };
+ using EVP_MD_CTX_ptr = std::unique_ptr<EVP_MD_CTX, EVP_MD_CTX_deleter>;
+ using EVP_MD_ptr = std::unique_ptr<EVP_MD, EVP_MD_deleter>;
+ EVP_MD_ptr algorithm;
+ EVP_MD_CTX_ptr context;
+ bool initializationFailed = false;
+#endif
+
union {
Sha1State sha1Context;
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+#ifndef USING_OPENSSL30
MD5Context md5Context;
md4_context md4Context;
SHA224Context sha224Context;
@@ -178,11 +249,13 @@ public:
SHA384Context sha384Context;
SHA512Context sha512Context;
SHA3Context sha3Context;
+#endif
blake2b_state blake2bContext;
blake2s_state blake2sContext;
#endif
};
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+#ifndef USING_OPENSSL30
enum class Sha3Variant
{
Sha3,
@@ -190,6 +263,7 @@ public:
};
void sha3Finish(int bitCount, Sha3Variant sha3Variant);
#endif
+#endif
class SmallByteArray {
std::array<char, MaxHashLength> m_data;
static_assert(MaxHashLength <= std::numeric_limits<std::uint8_t>::max());
@@ -212,6 +286,7 @@ public:
};
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+#ifndef USING_OPENSSL30
void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant)
{
/*
@@ -250,6 +325,7 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant
sha3Final(&copy, reinterpret_cast<BitSequence *>(result.data()));
}
+#endif // !QT_CONFIG(opensslv30)
#endif
/*!
@@ -316,6 +392,18 @@ QCryptographicHash::QCryptographicHash(Algorithm method)
}
/*!
+ \fn QCryptographicHash::QCryptographicHash(QCryptographicHash &&other)
+
+ Move-constructs a new QCryptographicHash from \a other.
+
+ \note The moved-from object \a other is placed in a
+ partially-formed state, in which the only valid operations are
+ destruction and assignment of a new value.
+
+ \since 6.5
+*/
+
+/*!
Destroys the object.
*/
QCryptographicHash::~QCryptographicHash()
@@ -324,6 +412,27 @@ QCryptographicHash::~QCryptographicHash()
}
/*!
+ \fn QCryptographicHash &QCryptographicHash::operator=(QCryptographicHash &&other)
+
+ Move-assigns \a other to this QCryptographicHash instance.
+
+ \note The moved-from object \a other is placed in a
+ partially-formed state, in which the only valid operations are
+ destruction and assignment of a new value.
+
+ \since 6.5
+*/
+
+/*!
+ \fn void QCryptographicHash::swap(QCryptographicHash &other)
+
+ Swaps cryptographic hash \a other with this cryptographic hash. This
+ operation is very fast and never fails.
+
+ \since 6.5
+*/
+
+/*!
Resets the object.
*/
void QCryptographicHash::reset() noexcept
@@ -331,8 +440,64 @@ void QCryptographicHash::reset() noexcept
d->reset();
}
+/*!
+ Returns the algorithm used to generate the cryptographic hash.
+
+ \since 6.5
+*/
+QCryptographicHash::Algorithm QCryptographicHash::algorithm() const noexcept
+{
+ return d->method;
+}
+
void QCryptographicHashPrivate::reset() noexcept
{
+#ifdef USING_OPENSSL30
+ if (method == QCryptographicHash::Blake2b_160 ||
+ method == QCryptographicHash::Blake2b_256 ||
+ method == QCryptographicHash::Blake2b_384) {
+ new (&blake2bContext) blake2b_state;
+ blake2b_init(&blake2bContext, hashLengthInternal(method));
+ return;
+ } else if (method == QCryptographicHash::Blake2s_128 ||
+ method == QCryptographicHash::Blake2s_160 ||
+ method == QCryptographicHash::Blake2s_224) {
+ new (&blake2sContext) blake2s_state;
+ blake2s_init(&blake2sContext, hashLengthInternal(method));
+ return;
+ }
+
+ initializationFailed = true;
+
+ if (method == QCryptographicHash::Md4) {
+ /*
+ * We need to load the legacy provider in order to have the MD4
+ * algorithm available.
+ */
+ if (!OSSL_PROVIDER_load(nullptr, "legacy"))
+ return;
+ if (!OSSL_PROVIDER_load(nullptr, "default"))
+ return;
+ }
+
+ context = EVP_MD_CTX_ptr(EVP_MD_CTX_new());
+
+ if (!context) {
+ return;
+ }
+
+ /*
+ * Using the "-fips" option will disable the global "fips=yes" for
+ * this one lookup and the algorithm can be fetched from any provider
+ * that implements the algorithm (including the FIPS provider).
+ */
+ algorithm = EVP_MD_ptr(EVP_MD_fetch(nullptr, methodToName(method), "-fips"));
+ if (!algorithm) {
+ return;
+ }
+
+ initializationFailed = !EVP_DigestInit_ex(context.get(), algorithm.get(), nullptr);
+#else
switch (method) {
case QCryptographicHash::Sha1:
new (&sha1Context) Sha1State;
@@ -396,6 +561,7 @@ void QCryptographicHashPrivate::reset() noexcept
#endif
}
result.clear();
+#endif // !QT_CONFIG(opensslv30)
}
#if QT_DEPRECATED_SINCE(6, 4)
@@ -438,6 +604,22 @@ void QCryptographicHashPrivate::addData(QByteArrayView bytes) noexcept
#else
{
#endif
+
+#ifdef USING_OPENSSL30
+ if (method == QCryptographicHash::Blake2b_160 ||
+ method == QCryptographicHash::Blake2b_256 ||
+ method == QCryptographicHash::Blake2b_384) {
+ blake2b_update(&blake2bContext, reinterpret_cast<const uint8_t *>(data), length);
+ } else if (method == QCryptographicHash::Blake2s_128 ||
+ method == QCryptographicHash::Blake2s_160 ||
+ method == QCryptographicHash::Blake2s_224) {
+ blake2s_update(&blake2sContext, reinterpret_cast<const uint8_t *>(data), length);
+ } else if (!initializationFailed) {
+ result.resizeForOverwrite(EVP_MD_get_size(algorithm.get()));
+ const int ret = EVP_DigestUpdate(context.get(), (const unsigned char *)data, length);
+ Q_UNUSED(ret);
+ }
+#else
switch (method) {
case QCryptographicHash::Sha1:
sha1Update(&sha1Context, (const unsigned char *)data, length);
@@ -490,6 +672,7 @@ void QCryptographicHashPrivate::addData(QByteArrayView bytes) noexcept
break;
#endif
}
+#endif // !QT_CONFIG(opensslv30)
}
result.clear();
}
@@ -548,6 +731,27 @@ void QCryptographicHashPrivate::finalize() noexcept
if (!result.isEmpty())
return;
+#ifdef USING_OPENSSL30
+ if (method == QCryptographicHash::Blake2b_160 ||
+ method == QCryptographicHash::Blake2b_256 ||
+ method == QCryptographicHash::Blake2b_384) {
+ const auto length = hashLengthInternal(method);
+ blake2b_state copy = blake2bContext;
+ result.resizeForOverwrite(length);
+ blake2b_final(&copy, reinterpret_cast<uint8_t *>(result.data()), length);
+ } else if (method == QCryptographicHash::Blake2s_128 ||
+ method == QCryptographicHash::Blake2s_160 ||
+ method == QCryptographicHash::Blake2s_224) {
+ const auto length = hashLengthInternal(method);
+ blake2s_state copy = blake2sContext;
+ result.resizeForOverwrite(length);
+ blake2s_final(&copy, reinterpret_cast<uint8_t *>(result.data()), length);
+ } else if (!initializationFailed) {
+ result.resizeForOverwrite(EVP_MD_get_size(algorithm.get()));
+ const int ret = EVP_DigestFinal_ex(context.get(), (unsigned char *)result.data(), nullptr);
+ Q_UNUSED(ret);
+ }
+#else
switch (method) {
case QCryptographicHash::Sha1: {
Sha1State copy = sha1Context;
@@ -634,6 +838,7 @@ void QCryptographicHashPrivate::finalize() noexcept
}
#endif
}
+#endif // !QT_CONFIG(opensslv30)
}
/*!
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
index f5710015cf..5f9104fe9f 100644
--- a/src/corelib/tools/qcryptographichash.h
+++ b/src/corelib/tools/qcryptographichash.h
@@ -64,9 +64,14 @@ public:
Q_ENUM(Algorithm)
explicit QCryptographicHash(Algorithm method);
+ QCryptographicHash(QCryptographicHash &&other) noexcept : d(std::exchange(other.d, nullptr)) {}
~QCryptographicHash();
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QCryptographicHash)
+ void swap(QCryptographicHash &other) noexcept { qt_ptr_swap(d, other.d); }
+
void reset() noexcept;
+ [[nodiscard]] Algorithm algorithm() const noexcept;
#if QT_DEPRECATED_SINCE(6, 4)
QT_DEPRECATED_VERSION_X_6_4("Use the QByteArrayView overload instead")
diff --git a/src/corelib/tools/qduplicatetracker_p.h b/src/corelib/tools/qduplicatetracker_p.h
index 4d0e6e4777..950220184f 100644
--- a/src/corelib/tools/qduplicatetracker_p.h
+++ b/src/corelib/tools/qduplicatetracker_p.h
@@ -56,13 +56,13 @@ class QDuplicateTracker {
auto insert(const T &e) {
auto it = QSet<T>::insert(e);
const auto n = this->size();
- return std::pair{it, qExchange(setSize, n) != n};
+ return std::pair{it, std::exchange(setSize, n) != n};
}
auto insert(T &&e) {
auto it = QSet<T>::insert(std::move(e));
const auto n = this->size();
- return std::pair{it, qExchange(setSize, n) != n};
+ return std::pair{it, std::exchange(setSize, n) != n};
}
};
Set set{Prealloc};
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index 9242a617ba..d8b3367de3 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -447,7 +447,7 @@ struct BezierEase : public QEasingCurveFunction
{
if (_bezierCurves.constLast() == QPointF(1.0, 1.0)) {
_init = true;
- _curveCount = _bezierCurves.count() / 3;
+ _curveCount = _bezierCurves.size() / 3;
for (int i=0; i < _curveCount; i++) {
_intervals[i] = _bezierCurves.at(i * 3 + 2).x();
@@ -466,17 +466,17 @@ struct BezierEase : public QEasingCurveFunction
_curves[0].p3y = _bezierCurves.at(2).y();
} else if (i == (_curveCount - 1)) {
- _curves[i].p0x = _bezierCurves.at(_bezierCurves.count() - 4).x();
- _curves[i].p0y = _bezierCurves.at(_bezierCurves.count() - 4).y();
+ _curves[i].p0x = _bezierCurves.at(_bezierCurves.size() - 4).x();
+ _curves[i].p0y = _bezierCurves.at(_bezierCurves.size() - 4).y();
- _curves[i].p1x = _bezierCurves.at(_bezierCurves.count() - 3).x();
- _curves[i].p1y = _bezierCurves.at(_bezierCurves.count() - 3).y();
+ _curves[i].p1x = _bezierCurves.at(_bezierCurves.size() - 3).x();
+ _curves[i].p1y = _bezierCurves.at(_bezierCurves.size() - 3).y();
- _curves[i].p2x = _bezierCurves.at(_bezierCurves.count() - 2).x();
- _curves[i].p2y = _bezierCurves.at(_bezierCurves.count() - 2).y();
+ _curves[i].p2x = _bezierCurves.at(_bezierCurves.size() - 2).x();
+ _curves[i].p2y = _bezierCurves.at(_bezierCurves.size() - 2).y();
- _curves[i].p3x = _bezierCurves.at(_bezierCurves.count() - 1).x();
- _curves[i].p3y = _bezierCurves.at(_bezierCurves.count() - 1).y();
+ _curves[i].p3x = _bezierCurves.at(_bezierCurves.size() - 1).x();
+ _curves[i].p3y = _bezierCurves.at(_bezierCurves.size() - 1).y();
} else {
_curves[i].p0x = _bezierCurves.at(i * 3 - 1).x();
_curves[i].p0y = _bezierCurves.at(i * 3 - 1).y();
@@ -535,7 +535,7 @@ struct BezierEase : public QEasingCurveFunction
qreal value(qreal x) override
{
- Q_ASSERT(_bezierCurves.count() % 3 == 0);
+ Q_ASSERT(_bezierCurves.size() % 3 == 0);
if (_bezierCurves.isEmpty()) {
return x;
@@ -869,7 +869,7 @@ struct TCBEase : public BezierEase
qreal value(qreal x) override
{
- Q_ASSERT(_bezierCurves.count() % 3 == 0);
+ Q_ASSERT(_bezierCurves.size() % 3 == 0);
if (_bezierCurves.isEmpty()) {
qWarning("QEasingCurve: Invalid tcb curve");
@@ -1274,7 +1274,7 @@ void QEasingCurve::addCubicBezierSegment(const QPointF & c1, const QPointF & c2,
QList<QPointF> static inline tcbToBezier(const TCBPoints &tcbPoints)
{
- const int count = tcbPoints.count();
+ const int count = tcbPoints.size();
QList<QPointF> bezierPoints;
bezierPoints.reserve(3 * (count - 1));
diff --git a/src/corelib/tools/qflatmap_p.h b/src/corelib/tools/qflatmap_p.h
index 28bb72c864..6937d21544 100644
--- a/src/corelib/tools/qflatmap_p.h
+++ b/src/corelib/tools/qflatmap_p.h
@@ -74,7 +74,7 @@ public:
using value_type = std::pair<const Key, T>;
static constexpr bool is_comparator_noexcept = noexcept(
- std::declval<Compare>()(std::declval<Key>(), std::declval<Key>()));
+ std::declval<Compare>()(std::declval<const Key &>(), std::declval<const Key &>()));
bool operator()(const value_type &lhs, const value_type &rhs) const
noexcept(is_comparator_noexcept)
@@ -83,6 +83,24 @@ public:
}
};
+namespace detail {
+template <class T>
+class QFlatMapMockPointer
+{
+ T ref;
+public:
+ QFlatMapMockPointer(T r)
+ : ref(r)
+ {
+ }
+
+ T *operator->()
+ {
+ return &ref;
+ }
+};
+} // namespace detail
+
template<class Key, class T, class Compare = std::less<Key>, class KeyContainer = QList<Key>,
class MappedContainer = QList<T>>
class QFlatMap : private QFlatMapValueCompare<Key, T, Compare>
@@ -90,21 +108,7 @@ 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.");
template <class U>
- class mock_pointer
- {
- U ref;
- public:
- mock_pointer(U r)
- : ref(r)
- {
- }
-
- U *operator->()
- {
- return &ref;
- }
- };
-
+ using mock_pointer = detail::QFlatMapMockPointer<U>;
public:
using key_type = Key;
using mapped_type = T;
diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h
index c06c569d23..6bbde5b4b6 100644
--- a/src/corelib/tools/qfreelist_p.h
+++ b/src/corelib/tools/qfreelist_p.h
@@ -124,8 +124,7 @@ class QFreeList
return i;
x -= size;
}
- Q_UNREACHABLE();
- return -1;
+ Q_UNREACHABLE_RETURN(-1);
}
// allocate a block of the given \a size, initialized starting with the given \a offset
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 9b69c79389..59d84f5094 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -107,26 +107,22 @@ private:
StateResult result = { 0, OverriddenByEnvironment };
#ifdef QT_BOOTSTRAPPED
Q_UNUSED(which);
- Q_UNREACHABLE();
+ Q_UNREACHABLE_RETURN(result);
#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)
- fprintf(stderr, "QT_HASH_SEED: forced seed value is not 0; ignored.\n");
+ if (seedstr) {
+ auto r = qstrntoll(seedstr, strlen(seedstr), 10);
+ if (r.used > 0 && size_t(r.used) == strlen(seedstr)) {
+ if (r.result) {
+ // can't use qWarning here (reentrancy)
+ fprintf(stderr, "QT_HASH_SEED: forced seed value is not 0; ignored.\n");
+ }
+
+ // we don't have to store to the seed, since it's pre-initialized by
+ // the compiler to zero
+ return result;
}
-
- // we don't have to store to the seed, since it's pre-initialized by
- // the compiler to zero
- return result;
}
// update the full seed
@@ -137,8 +133,8 @@ private:
result.requestedSeed = x.data[i];
}
result.state = JustInitialized;
-#endif
return result;
+#endif
}
inline HashSeedStorage::StateResult HashSeedStorage::state(int which)
@@ -1440,7 +1436,7 @@ size_t qHash(double key, size_t seed) noexcept
}
}
-#if !defined(Q_OS_DARWIN) || defined(Q_CLANG_QDOC)
+#if !defined(Q_OS_DARWIN) || defined(Q_QDOC)
/*! \relates QHash
\since 5.3
@@ -1683,10 +1679,15 @@ size_t qHash(long double key, size_t seed) noexcept
The two-arguments overloads take an unsigned integer that should be used to
seed the calculation of the hash function. This seed is provided by QHash
- in order to prevent a family of \l{algorithmic complexity attacks}. If both
- a one-argument and a two-arguments overload are defined for a key type,
- the latter is used by QHash (note that you can simply define a
- two-arguments version, and use a default value for the seed parameter).
+ in order to prevent a family of \l{algorithmic complexity attacks}.
+
+ \note In Qt 6 it is possible to define a \c{qHash()} overload
+ taking only one argument; support for this is deprecated. Starting
+ with Qt 7, it will be mandatory to use a two-arguments overload. If
+ both a one-argument and a two-arguments overload are defined for a
+ key type, the latter is used by QHash (note that you can simply
+ define a two-arguments version, and use a default value for the
+ seed parameter).
The second way to provide a hashing function is by specializing
the \c{std::hash} class for the key type \c{K}, and providing a
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 5075459531..eedb594e26 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -172,7 +172,7 @@ struct MultiNode
MultiNode(MultiNode &&other)
: key(other.key),
- value(qExchange(other.value, nullptr))
+ value(std::exchange(other.value, nullptr))
{
}
@@ -203,7 +203,7 @@ struct MultiNode
void insertMulti(Args &&... args)
{
Chain *e = new Chain{ T(std::forward<Args>(args)...), nullptr };
- e->next = qExchange(value, e);
+ e->next = std::exchange(value, e);
}
template<typename ...Args>
void emplaceValue(Args &&... args)
@@ -891,7 +891,7 @@ public:
#endif
void swap(QHash &other) noexcept { qt_ptr_swap(d, other.d); }
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template <typename AKey = Key, typename AT = T>
QTypeTraits::compare_eq_result_container<QHash, AKey, AT> operator==(const QHash &other) const noexcept
{
@@ -914,7 +914,7 @@ public:
#else
bool operator==(const QHash &other) const;
bool operator!=(const QHash &other) const;
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
inline qsizetype size() const noexcept { return d ? qsizetype(d->size) : 0; }
inline bool isEmpty() const noexcept { return !d || d->size == 0; }
@@ -1412,8 +1412,8 @@ public:
return *this;
}
QMultiHash(QMultiHash &&other) noexcept
- : d(qExchange(other.d, nullptr)),
- m_size(qExchange(other.m_size, 0))
+ : d(std::exchange(other.d, nullptr)),
+ m_size(std::exchange(other.m_size, 0))
{
}
QMultiHash &operator=(QMultiHash &&other) noexcept(std::is_nothrow_destructible<Node>::value)
@@ -1438,7 +1438,7 @@ public:
std::swap(m_size, other.m_size);
}
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template <typename AKey = Key, typename AT = T>
QTypeTraits::compare_eq_result_container<QMultiHash, AKey, AT> operator==(const QMultiHash &other) const noexcept
{
@@ -1479,7 +1479,7 @@ public:
#else
bool operator==(const QMultiHash &other) const;
bool operator!=(const QMultiHash &other) const;
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
inline qsizetype size() const noexcept { return m_size; }
@@ -2121,7 +2121,7 @@ public:
{
const auto copy = isDetached() ? QMultiHash() : *this; // keep 'key' alive across the detach
detach();
- auto pair = qAsConst(*this).equal_range(key);
+ auto pair = std::as_const(*this).equal_range(key);
return qMakePair(iterator(pair.first.i), iterator(pair.second.i));
}
diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h
index c946cc61bc..bcb8caf1f7 100644
--- a/src/corelib/tools/qhashfunctions.h
+++ b/src/corelib/tools/qhashfunctions.h
@@ -68,14 +68,6 @@ Q_DECL_CONST_FUNCTION constexpr size_t hash(size_t key, size_t seed) noexcept
}
}
-template <typename T, typename = void>
-constexpr inline bool HasQHashSingleArgOverload = false;
-
-template <typename T>
-constexpr inline bool HasQHashSingleArgOverload<T, std::enable_if_t<
- std::is_convertible_v<decltype(qHash(std::declval<const T &>())), size_t>
->> = true;
-
template <typename T1, typename T2> static constexpr bool noexceptPairHash();
}
@@ -120,7 +112,7 @@ Q_DECL_CONST_FUNCTION inline size_t qHash(float key, size_t seed = 0) noexcept
return QHashPrivate::hash(k, seed);
}
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION size_t qHash(double key, size_t seed = 0) noexcept;
-#if !defined(Q_OS_DARWIN) || defined(Q_CLANG_QDOC)
+#if !defined(Q_OS_DARWIN) || defined(Q_QDOC)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION size_t qHash(long double key, size_t seed = 0) noexcept;
#endif
Q_DECL_CONST_FUNCTION constexpr inline size_t qHash(wchar_t key, size_t seed = 0) noexcept
@@ -141,6 +133,9 @@ Q_DECL_CONST_FUNCTION constexpr inline size_t qHash(std::nullptr_t, size_t seed
{
return seed;
}
+template <class Enum, std::enable_if_t<std::is_enum_v<Enum>, bool> = true>
+Q_DECL_CONST_FUNCTION constexpr inline size_t qHash(Enum e, size_t seed = 0) noexcept
+{ return QHashPrivate::hash(qToUnderlying(e), seed); }
// (some) Qt types
Q_DECL_CONST_FUNCTION constexpr inline size_t qHash(const QChar key, size_t seed = 0) noexcept { return qHash(key.unicode(), seed); }
@@ -168,9 +163,26 @@ template <typename Enum>
Q_DECL_CONST_FUNCTION constexpr inline size_t qHash(QFlags<Enum> flags, size_t seed = 0) noexcept
{ return qHash(flags.toInt(), seed); }
-template <typename T, std::enable_if_t<QHashPrivate::HasQHashSingleArgOverload<T>, bool> = true>
+// ### Qt 7: remove this "catch-all" overload logic, and require users
+// to provide the two-argument version of qHash.
+#if (QT_VERSION < QT_VERSION_CHECK(7, 0, 0))
+// Beware of moving this code from here. It needs to see all the
+// declarations of qHash overloads for C++ fundamental types *before*
+// its own declaration.
+namespace QHashPrivate {
+template <typename T, typename = void>
+constexpr inline bool HasQHashSingleArgOverload = false;
+
+template <typename T>
+constexpr inline bool HasQHashSingleArgOverload<T, std::enable_if_t<
+ std::is_convertible_v<decltype(qHash(std::declval<const T &>())), size_t>
+>> = true;
+}
+
+template <typename T, std::enable_if_t<QHashPrivate::HasQHashSingleArgOverload<T> && !std::is_enum_v<T>, bool> = true>
size_t qHash(const T &t, size_t seed) noexcept(noexcept(qHash(t)))
{ return qHash(t) ^ seed; }
+#endif // < Qt 7
template<typename T>
bool qHashEquals(const T &a, const T &b)
diff --git a/src/corelib/tools/qiterator.qdoc b/src/corelib/tools/qiterator.qdoc
index f4286c99ea..3fc68e0874 100644
--- a/src/corelib/tools/qiterator.qdoc
+++ b/src/corelib/tools/qiterator.qdoc
@@ -84,7 +84,7 @@
/*!
\fn template<typename Key, typename T, class Iterator> QKeyValueIterator &QKeyValueIterator<Key, T, Iterator>::operator++()
- The prefix ++ operator (\c{++i}) advances the iterator to the
+ The prefix \c{++} operator (\c{++i}) advances the iterator to the
next item in the container and returns the iterator.
\note Advancing the iterator past its container's end() constitutes
@@ -97,7 +97,7 @@
\overload
- The postfix ++ operator (\c{i++}) advances the iterator to the
+ The postfix \c{++} operator (\c{i++}) advances the iterator to the
next item in the container and returns the iterator's prior value.
\note Advancing the iterator past its container's end() constitutes
@@ -106,7 +106,7 @@
/*! \fn template<typename Key, typename T, class Iterator> QKeyValueIterator &QKeyValueIterator<Key, T, Iterator>::operator--()
- The prefix -- operator (\c{--i}) backs the iterator up to the previous item
+ The prefix c{--} operator (\c{--i}) backs the iterator up to the previous item
in the container and returns the iterator.
\note Backing up an iterator to before its container's begin() constitutes
@@ -119,7 +119,7 @@
\overload
- The postfix -- operator (\c{i--}) backs the iterator up to the previous item
+ The postfix c{--} operator (\c{i--}) backs the iterator up to the previous item
in the container and returns the iterator's prior value.
\note Backing up an iterator to before its container's begin() constitutes
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 0cc62e5f6e..2856510d93 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -317,7 +317,7 @@ public:
void swap(QList &other) noexcept { d.swap(other.d); }
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template <typename U = T>
QTypeTraits::compare_eq_result_container<QList, U> operator==(const QList &other) const
{
@@ -373,7 +373,7 @@ public:
bool operator>(const QList &other) const;
bool operator<=(const QList &other) const;
bool operator>=(const QList &other) const;
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
qsizetype size() const noexcept { return d->size; }
qsizetype count() const noexcept { return size(); }
@@ -426,7 +426,7 @@ public:
reference operator[](qsizetype i)
{
Q_ASSERT_X(size_t(i) < size_t(d->size), "QList::operator[]", "index out of range");
- detach();
+ // don't detach() here, we detach in data below:
return data()[i];
}
const_reference operator[](qsizetype i) const noexcept { return at(i); }
diff --git a/src/corelib/tools/qlist.qdoc b/src/corelib/tools/qlist.qdoc
index e8e5a73596..f3b501a0e9 100644
--- a/src/corelib/tools/qlist.qdoc
+++ b/src/corelib/tools/qlist.qdoc
@@ -129,21 +129,7 @@
support \c operator==(). These requirements are documented on a
per-function basis.
- Like the other container classes, QList provides \l{Java-style iterators}
- (QListIterator and QMutableListIterator) and \l{STL-style iterators}
- (QList::const_iterator and QList::iterator). In practice, iterators are
- handy when working with generic algorithms provided by \l{generic
- algorithms}{Qt} and the C++ standard library. \l{Java-style iterators} are
- provided for backwards compatibility, prefer \l{STL-style iterators} when
- writing C++ code.
-
- \note Iterators over a QList, and references to individual elements
- within one, cannot be relied on to remain valid when any non-const method
- of the QList is called. Accessing such an iterator or reference after
- the call to a non-const method leads to undefined behavior. When stability
- for iterator-like functionality is required, you should use indexes instead
- of iterators as they are not tied to QList's internal state and thus do
- not get invalidated.
+ For iterating over the items, see \l {Iterating over Containers}.
In addition to QList, Qt also provides QVarLengthArray, a very
low-level class with little functionality that is optimized for
@@ -563,17 +549,14 @@
Removes all the elements from the list.
- \note Until Qt 5.6, this also released the memory used by
- the list. From Qt 5.7, the capacity is preserved. To shed
- all capacity, swap with a default-constructed list:
- \code
- QList<T> l ...;
- QList<T>().swap(l);
- Q_ASSERT(l.capacity() == 0);
- \endcode
- or call squeeze().
+ If this list is not shared, the capacity() is preserved. Use squeeze() to
+ shed excess capacity.
+
+ \note In Qt versions prior to 5.7 (for QVector) and 6.0 (for QList), this
+ function released the memory used by the list instead of preserving the
+ capacity.
- \sa squeeze()
+ \sa resize(), squeeze()
*/
/*! \fn template <typename T> const T &QList<T>::at(qsizetype i) const
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 9ba01bee2c..1a6506348f 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -240,7 +240,7 @@ public:
return {};
}
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template <typename AKey = Key, typename AT = T> friend
QTypeTraits::compare_eq_result_container<QMap, AKey, AT> operator==(const QMap &lhs, const QMap &rhs)
{
@@ -261,7 +261,7 @@ public:
#else
friend bool operator==(const QMap &lhs, const QMap &rhs);
friend bool operator!=(const QMap &lhs, const QMap &rhs);
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
size_type size() const { return d ? size_type(d->m.size()) : size_type(0); }
@@ -885,7 +885,7 @@ public:
return {};
}
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template <typename AKey = Key, typename AT = T> friend
QTypeTraits::compare_eq_result_container<QMultiMap, AKey, AT> operator==(const QMultiMap &lhs, const QMultiMap &rhs)
{
@@ -906,7 +906,7 @@ public:
#else
friend bool operator==(const QMultiMap &lhs, const QMultiMap &rhs);
friend bool operator!=(const QMultiMap &lhs, const QMultiMap &rhs);
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
size_type size() const { return d ? size_type(d->m.size()) : size_type(0); }
diff --git a/src/corelib/tools/qmap.qdoc b/src/corelib/tools/qmap.qdoc
index 2e767acc4a..b8ce4224a3 100644
--- a/src/corelib/tools/qmap.qdoc
+++ b/src/corelib/tools/qmap.qdoc
@@ -202,6 +202,15 @@
Returns an STL map equivalent to this QMap.
*/
+/*! \fn template <class Key, class T> std::map<Key, T> QMap<Key, T>::toStdMap() &&
+
+ \overload
+ \since 6.0
+
+ \note Calling this function will leave this QMap in the partially-formed state, in which
+ the only valid operations are destruction or assignment of a new value.
+*/
+
/*! \fn template <class Key, class T> bool QMap<Key, T>::operator==(const QMap<Key, T> &lhs, const QMap<Key, T> &rhs)
Returns \c true if \a lhs is equal to \a rhs; otherwise returns
@@ -989,7 +998,7 @@
/*! \fn template <class Key, class T> QMap<Key, T>::iterator &QMap<Key, T>::iterator::operator++()
- The prefix ++ operator (\c{++i}) advances the iterator to the
+ The prefix \c{++} operator (\c{++i}) advances the iterator to the
next item in the map and returns an iterator to the new current
item.
@@ -1002,14 +1011,14 @@
\overload
- The postfix ++ operator (\c{i++}) advances the iterator to the
+ The postfix \c{++} operator (\c{i++}) advances the iterator to the
next item in the map and returns an iterator to the previously
current item.
*/
/*! \fn template <class Key, class T> QMap<Key, T>::iterator &QMap<Key, T>::iterator::operator--()
- The prefix -- operator (\c{--i}) makes the preceding item
+ The prefix \c{--} operator (\c{--i}) makes the preceding item
current and returns an iterator pointing to the new current item.
Calling this function on QMap::begin() leads to undefined
@@ -1022,7 +1031,7 @@
\overload
- The postfix -- operator (\c{i--}) makes the preceding item
+ The postfix \c{--} operator (\c{i--}) makes the preceding item
current and returns an iterator pointing to the previously
current item.
*/
@@ -1160,7 +1169,7 @@
/*! \fn template <class Key, class T> QMap<Key, T>::const_iterator &QMap<Key, T>::const_iterator::operator++()
- The prefix ++ operator (\c{++i}) advances the iterator to the
+ The prefix \c{++} operator (\c{++i}) advances the iterator to the
next item in the map and returns an iterator to the new current
item.
@@ -1173,14 +1182,14 @@
\overload
- The postfix ++ operator (\c{i++}) advances the iterator to the
+ The postfix \c{++} operator (\c{i++}) advances the iterator to the
next item in the map and returns an iterator to the previously
current item.
*/
/*! \fn template <class Key, class T> QMap<Key, T>::const_iterator &QMap<Key, T>::const_iterator::operator--()
- The prefix -- operator (\c{--i}) makes the preceding item
+ The prefix \c{--} operator (\c{--i}) makes the preceding item
current and returns an iterator pointing to the new current item.
Calling this function on QMap::begin() leads to undefined
@@ -1193,7 +1202,7 @@
\overload
- The postfix -- operator (\c{i--}) makes the preceding item
+ The postfix \c{--} operator (\c{i--}) makes the preceding item
current and returns an iterator pointing to the previously
current item.
*/
@@ -1301,7 +1310,7 @@
/*!
\fn template <class Key, class T> QMap<Key, T>::key_iterator &QMap<Key, T>::key_iterator::operator++()
- The prefix ++ operator (\c{++i}) advances the iterator to the
+ The prefix \c{++} operator (\c{++i}) advances the iterator to the
next item in the hash and returns an iterator to the new current
item.
@@ -1314,14 +1323,14 @@
\overload
- The postfix ++ operator (\c{i++}) advances the iterator to the
+ The postfix \c{++} operator (\c{i++}) advances the iterator to the
next item in the hash and returns an iterator to the previous
item.
*/
/*! \fn template <class Key, class T> QMap<Key, T>::key_iterator &QMap<Key, T>::key_iterator::operator--()
- The prefix -- operator (\c{--i}) makes the preceding item
+ The prefix \c{--} operator (\c{--i}) makes the preceding item
current and returns an iterator pointing to the new current item.
Calling this function on QMap::keyBegin() leads to undefined
@@ -1334,7 +1343,7 @@
\overload
- The postfix -- operator (\c{i--}) makes the preceding item
+ The postfix \c{--} operator (\c{i--}) makes the preceding item
current and returns an iterator pointing to the previous
item.
*/
diff --git a/src/corelib/tools/qmultimap.qdoc b/src/corelib/tools/qmultimap.qdoc
index f4751fdc45..c4b073bd94 100644
--- a/src/corelib/tools/qmultimap.qdoc
+++ b/src/corelib/tools/qmultimap.qdoc
@@ -1142,7 +1142,7 @@
/*! \fn template <class Key, class T> QMultiMap<Key, T>::iterator &QMultiMap<Key, T>::iterator::operator++()
- The prefix ++ operator (\c{++i}) advances the iterator to the
+ The prefix \c{++} operator (\c{++i}) advances the iterator to the
next item in the multi map and returns an iterator to the new current
item.
@@ -1155,14 +1155,14 @@
\overload
- The postfix ++ operator (\c{i++}) advances the iterator to the
+ The postfix \c{++} operator (\c{i++}) advances the iterator to the
next item in the multi map and returns an iterator to the previously
current item.
*/
/*! \fn template <class Key, class T> QMultiMap<Key, T>::iterator &QMultiMap<Key, T>::iterator::operator--()
- The prefix -- operator (\c{--i}) makes the preceding item
+ The prefix \c{--} operator (\c{--i}) makes the preceding item
current and returns an iterator pointing to the new current item.
Calling this function on QMultiMap::begin() leads to undefined
@@ -1175,7 +1175,7 @@
\overload
- The postfix -- operator (\c{i--}) makes the preceding item
+ The postfix \c{--} operator (\c{i--}) makes the preceding item
current and returns an iterator pointing to the previously
current item.
*/
@@ -1316,7 +1316,7 @@
/*! \fn template <class Key, class T> QMultiMap<Key, T>::const_iterator &QMultiMap<Key, T>::const_iterator::operator++()
- The prefix ++ operator (\c{++i}) advances the iterator to the
+ The prefix \c{++} operator (\c{++i}) advances the iterator to the
next item in the map and returns an iterator to the new current
item.
@@ -1329,14 +1329,14 @@
\overload
- The postfix ++ operator (\c{i++}) advances the iterator to the
+ The postfix \c{++} operator (\c{i++}) advances the iterator to the
next item in the map and returns an iterator to the previously
current item.
*/
/*! \fn template <class Key, class T> QMultiMap<Key, T>::const_iterator &QMultiMap<Key, T>::const_iterator::operator--()
- The prefix -- operator (\c{--i}) makes the preceding item
+ The prefix \c{--} operator (\c{--i}) makes the preceding item
current and returns an iterator pointing to the new current item.
Calling this function on QMultiMap::begin() leads to undefined
@@ -1349,7 +1349,7 @@
\overload
- The postfix -- operator (\c{i--}) makes the preceding item
+ The postfix \c{--} operator (\c{i--}) makes the preceding item
current and returns an iterator pointing to the previously
current item.
*/
@@ -1458,7 +1458,7 @@
/*!
\fn template <class Key, class T> QMultiMap<Key, T>::key_iterator &QMultiMap<Key, T>::key_iterator::operator++()
- The prefix ++ operator (\c{++i}) advances the iterator to the
+ The prefix \c{++} operator (\c{++i}) advances the iterator to the
next item in the hash and returns an iterator to the new current
item.
@@ -1471,14 +1471,14 @@
\overload
- The postfix ++ operator (\c{i++}) advances the iterator to the
+ The postfix \c{++} operator (\c{i++}) advances the iterator to the
next item in the hash and returns an iterator to the previous
item.
*/
/*! \fn template <class Key, class T> QMultiMap<Key, T>::key_iterator &QMultiMap<Key, T>::key_iterator::operator--()
- The prefix -- operator (\c{--i}) makes the preceding item
+ The prefix \c{--} operator (\c{--i}) makes the preceding item
current and returns an iterator pointing to the new current item.
Calling this function on QMultiMap::keyBegin() leads to undefined
@@ -1491,7 +1491,7 @@
\overload
- The postfix -- operator (\c{i--}) makes the preceding item
+ The postfix \c{--} operator (\c{i--}) makes the preceding item
current and returns an iterator pointing to the previous
item.
*/
diff --git a/src/corelib/tools/qoffsetstringarray_p.h b/src/corelib/tools/qoffsetstringarray_p.h
index a3b56badc6..2a0e6de55b 100644
--- a/src/corelib/tools/qoffsetstringarray_p.h
+++ b/src/corelib/tools/qoffsetstringarray_p.h
@@ -20,6 +20,7 @@
#include <QByteArrayView>
+#include <QtCore/q20algorithm.h>
#include <array>
#include <limits>
#include <string_view>
@@ -69,16 +70,6 @@ private:
};
namespace QtPrivate {
-// std::copy is not constexpr in C++17
-template <typename II, typename OO>
-static constexpr OO copyData(II input, qsizetype n, OO output)
-{
- using E = decltype(+*output);
- for (qsizetype i = 0; i < n; ++i)
- output[i] = E(input[i]);
- return output + n;
-}
-
template <size_t Highest> constexpr auto minifyValue()
{
if constexpr (Highest <= (std::numeric_limits<quint8>::max)()) {
@@ -100,7 +91,7 @@ constexpr auto makeStaticString(Extractor extract, const T &... entries)
const char *strings[] = { extract(entries).operator const char *()... };
size_t lengths[] = { sizeof(extract(T{}))... };
for (size_t i = 0; i < std::size(strings); ++i) {
- copyData(strings[i], lengths[i], result.begin() + offset);
+ q20::copy_n(strings[i], lengths[i], result.begin() + offset);
offset += lengths[i];
}
return result;
@@ -110,7 +101,7 @@ template <size_t N> struct StaticString
{
char value[N] = {};
constexpr StaticString() = default;
- constexpr StaticString(const char (&s)[N]) { copyData(s, N, value); }
+ constexpr StaticString(const char (&s)[N]) { q20::copy_n(s, N, value); }
constexpr operator const char *() const { return value; }
};
@@ -125,10 +116,10 @@ template <size_t KL, size_t VL> struct StaticMapEntry
};
template <typename StringExtractor, typename... T>
-constexpr auto qOffsetStringArray(StringExtractor extractString, const T &... entries)
+constexpr auto makeOffsetStringArray(StringExtractor extractString, const T &... entries)
{
constexpr size_t Count = sizeof...(T);
- constexpr qsizetype StringLength = (sizeof(extractString(T{})) + ...);
+ constexpr size_t StringLength = (sizeof(extractString(T{})) + ...);
using MinifiedOffsetType = decltype(QtPrivate::minifyValue<StringLength>());
size_t offset = 0;
@@ -136,18 +127,20 @@ constexpr auto qOffsetStringArray(StringExtractor extractString, const T &... en
// prepend zero
std::array<MinifiedOffsetType, Count + 1> minifiedOffsetList = {};
- QtPrivate::copyData(fullOffsetList.begin(), Count, minifiedOffsetList.begin() + 1);
+ q20::transform(fullOffsetList.begin(), fullOffsetList.end(),
+ minifiedOffsetList.begin() + 1,
+ [] (auto e) { return MinifiedOffsetType(e); });
std::array staticString = QtPrivate::makeStaticString<StringLength>(extractString, entries...);
return QOffsetStringArray(staticString, minifiedOffsetList);
}
-}
+} // namespace QtPrivate
template<int ... Nx>
constexpr auto qOffsetStringArray(const char (&...strings)[Nx]) noexcept
{
auto extractString = [](const auto &s) -> decltype(auto) { return s; };
- return QtPrivate::qOffsetStringArray(extractString, QtPrivate::StaticString(strings)...);
+ return QtPrivate::makeOffsetStringArray(extractString, QtPrivate::StaticString(strings)...);
}
QT_WARNING_POP
diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h
index d114fa7ae0..e69a217f48 100644
--- a/src/corelib/tools/qrect.h
+++ b/src/corelib/tools/qrect.h
@@ -16,6 +16,11 @@
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
struct CGRect;
#endif
+#if defined(Q_OS_WASM) || defined(Q_QDOC)
+namespace emscripten {
+class val;
+}
+#endif
QT_BEGIN_NAMESPACE
@@ -586,6 +591,11 @@ public:
[[nodiscard]] CGRect toCGRect() const noexcept;
#endif
+#if defined(Q_OS_WASM) || defined(Q_QDOC)
+ [[nodiscard]] static QRectF fromDOMRect(emscripten::val domRect);
+ [[nodiscard]] emscripten::val toDOMRect() const;
+#endif
+
private:
qreal xp;
qreal yp;
diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp
index e569267c65..28cc39ae5d 100644
--- a/src/corelib/tools/qscopedpointer.cpp
+++ b/src/corelib/tools/qscopedpointer.cpp
@@ -276,24 +276,30 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn template <typename T, typename Cleanup> T *QScopedArrayPointer<T, Cleanup>::operator[](int i)
+ \fn template <typename T, typename Cleanup> T *QScopedArrayPointer<T, Cleanup>::operator[](qsizetype i)
Provides access to entry \a i of the scoped pointer's array of
objects.
If the contained pointer is \nullptr, behavior is undefined.
+ \note In Qt versions prior to 6.5, \a i was of type \c{int}, not
+ \c{qsizetype}, possibly causing truncation on 64-bit platforms.
+
\sa isNull()
*/
/*!
- \fn template <typename T, typename Cleanup> T *QScopedArrayPointer<T, Cleanup>::operator[](int i) const
+ \fn template <typename T, typename Cleanup> T *QScopedArrayPointer<T, Cleanup>::operator[](qsizetype i) const
Provides access to entry \a i of the scoped pointer's array of
objects.
If the contained pointer is \nullptr behavior is undefined.
+ \note In Qt versions prior to 6.5, \a i was of type \c{int}, not
+ \c{qsizetype}, possibly causing truncation on 64-bit platforms.
+
\sa isNull()
*/
diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h
index 508816a7e7..1637bb40a5 100644
--- a/src/corelib/tools/qscopedpointer.h
+++ b/src/corelib/tools/qscopedpointer.h
@@ -120,7 +120,7 @@ public:
{
if (d == other)
return;
- T *oldD = qExchange(d, other);
+ T *oldD = std::exchange(d, other);
Cleanup::cleanup(oldD);
}
@@ -128,7 +128,7 @@ public:
QT_DEPRECATED_VERSION_X_6_1("Use std::unique_ptr instead, and call release().")
T *take() noexcept
{
- T *oldD = qExchange(d, nullptr);
+ T *oldD = std::exchange(d, nullptr);
return oldD;
}
#endif
@@ -201,12 +201,12 @@ public:
{
}
- inline T &operator[](int i)
+ T &operator[](qsizetype i)
{
return this->d[i];
}
- inline const T &operator[](int i) const
+ const T &operator[](qsizetype i) const
{
return this->d[i];
}
diff --git a/src/corelib/tools/qscopeguard.h b/src/corelib/tools/qscopeguard.h
index 2639b41222..5bd202ce33 100644
--- a/src/corelib/tools/qscopeguard.h
+++ b/src/corelib/tools/qscopeguard.h
@@ -28,7 +28,7 @@ public:
QScopeGuard(QScopeGuard &&other) noexcept
: m_func(std::move(other.m_func))
- , m_invoke(qExchange(other.m_invoke, false))
+ , m_invoke(std::exchange(other.m_invoke, false))
{
}
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 2a945a31e8..cdd9ceda20 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -35,7 +35,7 @@ public:
inline void swap(QSet<T> &other) noexcept { q_hash.swap(other.q_hash); }
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template <typename U = T>
QTypeTraits::compare_eq_result_container<QSet, U> operator==(const QSet<T> &other) const
{ return q_hash == other.q_hash; }
@@ -151,7 +151,7 @@ public:
// more Qt
typedef iterator Iterator;
typedef const_iterator ConstIterator;
- inline qsizetype count() const { return q_hash.count(); }
+ inline qsizetype count() const { return q_hash.size(); }
inline iterator insert(const T &value)
{ return q_hash.insert(value, QHashDummyValue()); }
inline iterator insert(T &&value)
@@ -244,7 +244,7 @@ Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
copy2 = *this;
*this = copy1;
}
- for (const auto &e : qAsConst(copy1)) {
+ for (const auto &e : std::as_const(copy1)) {
if (!copy2.contains(e))
remove(e);
}
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index be848e2ef8..826152b63a 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -49,7 +49,7 @@ public:
const T *data() const noexcept { return d; }
const T *get() const noexcept { return d; }
const T *constData() const noexcept { return d; }
- T *take() noexcept { return qExchange(d, nullptr); }
+ T *take() noexcept { return std::exchange(d, nullptr); }
QSharedDataPointer() noexcept : d(nullptr) { }
~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }
@@ -66,7 +66,7 @@ public:
if (ptr != d) {
if (ptr)
ptr->ref.ref();
- T *old = qExchange(d, ptr);
+ T *old = std::exchange(d, ptr);
if (old && !old->ref.deref())
delete old;
}
@@ -82,7 +82,7 @@ public:
reset(o);
return *this;
}
- QSharedDataPointer(QSharedDataPointer &&o) noexcept : d(qExchange(o.d, nullptr)) {}
+ QSharedDataPointer(QSharedDataPointer &&o) noexcept : d(std::exchange(o.d, nullptr)) {}
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QSharedDataPointer)
operator bool () const noexcept { return d != nullptr; }
@@ -135,7 +135,7 @@ public:
T *data() const noexcept { return d; }
T *get() const noexcept { return d; }
const T *constData() const noexcept { return d; }
- T *take() noexcept { return qExchange(d, nullptr); }
+ T *take() noexcept { return std::exchange(d, nullptr); }
void detach() { if (d && d->ref.loadRelaxed() != 1) detach_helper(); }
@@ -163,7 +163,7 @@ public:
if (ptr != d) {
if (ptr)
ptr->ref.ref();
- T *old = qExchange(d, ptr);
+ T *old = std::exchange(d, ptr);
if (old && !old->ref.deref())
delete old;
}
@@ -179,7 +179,7 @@ public:
reset(o);
return *this;
}
- QExplicitlySharedDataPointer(QExplicitlySharedDataPointer &&o) noexcept : d(qExchange(o.d, nullptr)) {}
+ QExplicitlySharedDataPointer(QExplicitlySharedDataPointer &&o) noexcept : d(std::exchange(o.d, nullptr)) {}
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QExplicitlySharedDataPointer)
operator bool () const noexcept { return d != nullptr; }
diff --git a/src/corelib/tools/qshareddata_impl.h b/src/corelib/tools/qshareddata_impl.h
index 61a9d1d105..e0b4695e36 100644
--- a/src/corelib/tools/qshareddata_impl.h
+++ b/src/corelib/tools/qshareddata_impl.h
@@ -51,7 +51,7 @@ public:
}
QExplicitlySharedDataPointerV2(QExplicitlySharedDataPointerV2 &&other) noexcept
- : d(qExchange(other.d, nullptr))
+ : d(std::exchange(other.d, nullptr))
{
}
@@ -92,7 +92,7 @@ public:
constexpr T *take() noexcept
{
- return qExchange(d, nullptr);
+ return std::exchange(d, nullptr);
}
bool isShared() const noexcept
diff --git a/src/corelib/tools/qtaggedpointer.h b/src/corelib/tools/qtaggedpointer.h
index 504645993a..d0c180ac5f 100644
--- a/src/corelib/tools/qtaggedpointer.h
+++ b/src/corelib/tools/qtaggedpointer.h
@@ -72,11 +72,30 @@ public:
return !isNull();
}
- QTaggedPointer &operator=(T *other) noexcept
+#ifdef Q_QDOC
+ QTaggedPointer &operator=(T *other) noexcept;
+#else
+ // Disables the usage of `ptr = {}`, which would go through this operator
+ // (rather than using the implicitly-generated assignment operator).
+ // The operators have different semantics: the ones here leave the tag intact,
+ // the implicitly-generated one overwrites it.
+ template <typename U,
+ std::enable_if_t<std::is_convertible_v<U *, T *>, bool> = false>
+ QTaggedPointer &operator=(U *other) noexcept
+ {
+ T *otherT = other;
+ d = reinterpret_cast<quintptr>(otherT) | (d & tagMask());
+ return *this;
+ }
+
+ template <typename U,
+ std::enable_if_t<std::is_null_pointer_v<U>, bool> = false>
+ QTaggedPointer &operator=(U) noexcept
{
- d = reinterpret_cast<quintptr>(other) | (d & tagMask());
+ d = reinterpret_cast<quintptr>(static_cast<T *>(nullptr)) | (d & tagMask());
return *this;
}
+#endif
static constexpr Tag maximumTag() noexcept
{
@@ -85,8 +104,10 @@ public:
void setTag(Tag tag)
{
- Q_ASSERT_X((static_cast<typename QtPrivate::TagInfo<T>::TagType>(tag) & pointerMask()) == 0,
- "QTaggedPointer<T, Tag>::setTag", "Tag is larger than allowed by number of available tag bits");
+ Q_ASSERT_X(
+ (static_cast<quintptr>(tag) & pointerMask()) == 0,
+ "QTaggedPointer<T, Tag>::setTag",
+ "Tag is larger than allowed by number of available tag bits");
d = (d & pointerMask()) | static_cast<quintptr>(tag);
}
diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp
index 7d6ddc9bcd..dcb2a3ad64 100644
--- a/src/corelib/tools/qversionnumber.cpp
+++ b/src/corelib/tools/qversionnumber.cpp
@@ -404,19 +404,18 @@ static QVersionNumber from_string(QLatin1StringView string, qsizetype *suffixInd
QVarLengthArray<int, 32> seg;
const char *start = string.begin();
- const char *end = start;
const char *lastGoodEnd = start;
const char *endOfString = string.end();
do {
- bool ok = false;
- const qulonglong value = qstrntoull(start, endOfString - start, &end, 10, &ok);
- if (!ok || value > qulonglong(std::numeric_limits<int>::max()))
+ // parsing as unsigned so a minus sign is rejected
+ auto [value, used] = qstrntoull(start, endOfString - start, 10);
+ if (used <= 0 || value > qulonglong(std::numeric_limits<int>::max()))
break;
seg.append(int(value));
- start = end + 1;
- lastGoodEnd = end;
- } while (start < endOfString && end < endOfString && *end == '.');
+ start += used + 1;
+ lastGoodEnd = start - 1;
+ } while (start < endOfString && *lastGoodEnd == '.');
if (suffixIndex)
*suffixIndex = lastGoodEnd - string.begin();