summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qarraydata.h14
-rw-r--r--src/corelib/tools/qarraydataops.h8
-rw-r--r--src/corelib/tools/qcontainertools_impl.h34
-rw-r--r--src/corelib/tools/qcryptographichash.cpp8
-rw-r--r--src/corelib/tools/qduplicatetracker_p.h13
-rw-r--r--src/corelib/tools/qeasingcurve.cpp2
-rw-r--r--src/corelib/tools/qfreelist_p.h2
-rw-r--r--src/corelib/tools/qline.cpp11
-rw-r--r--src/corelib/tools/qline.h11
-rw-r--r--src/corelib/tools/qlist.cpp68
-rw-r--r--src/corelib/tools/qmap.h4
-rw-r--r--src/corelib/tools/qmargins.cpp24
-rw-r--r--src/corelib/tools/qmessageauthenticationcode.cpp37
-rw-r--r--src/corelib/tools/qoffsetstringarray_p.h1
-rw-r--r--src/corelib/tools/qpoint.cpp16
-rw-r--r--src/corelib/tools/qrect.cpp14
-rw-r--r--src/corelib/tools/qscopedvaluerollback.cpp2
-rw-r--r--src/corelib/tools/qset.qdoc55
-rw-r--r--src/corelib/tools/qsharedpointer.cpp53
-rw-r--r--src/corelib/tools/qsharedpointer.h10
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h14
-rw-r--r--src/corelib/tools/qsimd.cpp22
-rw-r--r--src/corelib/tools/qsize.cpp15
-rw-r--r--src/corelib/tools/qtools_p.h11
-rw-r--r--src/corelib/tools/qvarlengtharray.h101
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc5
-rw-r--r--src/corelib/tools/qvector.h56
-rw-r--r--src/corelib/tools/qversionnumber.cpp2
-rw-r--r--src/corelib/tools/qversionnumber.h12
29 files changed, 427 insertions, 198 deletions
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index dcd95924c1..5e21186bbd 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -56,16 +56,16 @@ struct Q_CORE_EXPORT QArrayData
void *data()
{
- Q_ASSERT(size == 0
- || offset < 0 || size_t(offset) >= sizeof(QArrayData));
- return reinterpret_cast<char *>(this) + offset;
+ Q_ASSERT(size == 0 || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+ const quintptr self = reinterpret_cast<qintptr>(this);
+ return reinterpret_cast<void *>(self + offset);
}
const void *data() const
{
- Q_ASSERT(size == 0
- || offset < 0 || size_t(offset) >= sizeof(QArrayData));
- return reinterpret_cast<const char *>(this) + offset;
+ Q_ASSERT(size == 0 || offset < 0 || size_t(offset) >= sizeof(QArrayData));
+ const quintptr self = reinterpret_cast<qintptr>(this);
+ return reinterpret_cast<const void *>(self + offset);
}
// This refers to array data mutability, not "header data" represented by
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index 8e19525f07..0b967a84f7 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -65,8 +65,10 @@ struct QPodArrayOps
Q_ASSERT(newSize > uint(this->size));
Q_ASSERT(newSize <= this->alloc);
- ::memset(static_cast<void *>(this->end()), 0, (newSize - this->size) * sizeof(T));
- this->size = int(newSize);
+ T *const begin = this->begin();
+ do {
+ new (begin + this->size) T();
+ } while (uint(++this->size) != newSize);
}
void copyAppend(const T *b, const T *e)
@@ -154,7 +156,7 @@ struct QGenericArrayOps
T *const begin = this->begin();
do {
- new (begin + this->size) T;
+ new (begin + this->size) T();
} while (uint(++this->size) != newSize);
}
diff --git a/src/corelib/tools/qcontainertools_impl.h b/src/corelib/tools/qcontainertools_impl.h
index 3a0c4381f1..1716e0a5a8 100644
--- a/src/corelib/tools/qcontainertools_impl.h
+++ b/src/corelib/tools/qcontainertools_impl.h
@@ -53,6 +53,40 @@ QT_BEGIN_NAMESPACE
namespace QtPrivate
{
+
+/*!
+ \internal
+
+ Returns whether \a p is within a range [b, e). In simplest form equivalent to:
+ b <= p < e.
+*/
+template<typename T, typename Cmp = std::less<const T *>>
+static constexpr bool q_points_into_range(const T *p, const T *b, const T *e,
+ Cmp less = {}) noexcept
+{
+ return !less(p, b) && less(p, e);
+}
+
+/*!
+ \internal
+
+ A wrapper around std::rotate(), with an optimization for
+ Q_RELOCATABLE_TYPEs. We omit the return value, as it would be more work to
+ compute in the Q_RELOCATABLE_TYPE case and, unlike std::rotate on
+ ForwardIterators, callers can compute the result in constant time
+ themselves.
+*/
+template <typename T>
+void q_rotate(T *first, T *mid, T *last)
+{
+ if (QTypeInfo<T>::isRelocatable) {
+ const auto cast = [](T *p) { return reinterpret_cast<uchar*>(p); };
+ std::rotate(cast(first), cast(mid), cast(last));
+ } else {
+ std::rotate(first, mid, last);
+ }
+}
+
template <typename Iterator>
using IfIsInputIterator = typename std::enable_if<
std::is_convertible<typename std::iterator_traits<Iterator>::iterator_category, std::input_iterator_tag>::value,
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index fa8d21e07a..b46bbeb41e 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -40,6 +40,8 @@
#include <qcryptographichash.h>
#include <qiodevice.h>
+#include <qmutex.h>
+#include <private/qlocking_p.h>
#include "../../3rdparty/sha1/sha1.cpp"
@@ -192,6 +194,8 @@ public:
};
void sha3Finish(int bitCount, Sha3Variant sha3Variant);
#endif
+ // protects result in result()
+ QMutex finalizeMutex;
QByteArray result;
};
@@ -448,6 +452,9 @@ bool QCryptographicHash::addData(QIODevice* device)
*/
QByteArray QCryptographicHash::result() const
{
+ // result() is a const function, so concurrent calls are allowed; protect:
+ const auto lock = qt_scoped_lock(d->finalizeMutex);
+ // check that no other thread already finalized before us:
if (!d->result.isEmpty())
return d->result;
@@ -535,6 +542,7 @@ QByteArray QCryptographicHash::result() const
}
#endif
}
+
return d->result;
}
diff --git a/src/corelib/tools/qduplicatetracker_p.h b/src/corelib/tools/qduplicatetracker_p.h
index 99068c01a3..68284fb916 100644
--- a/src/corelib/tools/qduplicatetracker_p.h
+++ b/src/corelib/tools/qduplicatetracker_p.h
@@ -64,11 +64,18 @@ QT_BEGIN_NAMESPACE
template <typename T, size_t Prealloc = 32>
class QDuplicateTracker {
#ifdef __cpp_lib_memory_resource
- char buffer[Prealloc * sizeof(T)];
+ struct node_guesstimate { void *next; size_t hash; T value; };
+ static constexpr size_t bufferSize(size_t N) {
+ return N * sizeof(void*) // bucket list
+ + N * sizeof(node_guesstimate); // nodes
+ }
+
+ char buffer[bufferSize(Prealloc)];
std::pmr::monotonic_buffer_resource res{buffer, sizeof buffer};
- std::pmr::unordered_set<T> set{&res};
+ std::pmr::unordered_set<T> set{Prealloc, &res};
#else
- QSet<T> set;
+ static QSet<T> makeQSet() { QSet<T> r; r.reserve(Prealloc); return r; }
+ QSet<T> set = makeQSet();
int setSize = 0;
#endif
Q_DISABLE_COPY_MOVE(QDuplicateTracker);
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index 62d2fa33ae..5cf548f4bf 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -1356,7 +1356,7 @@ QVector<QPointF> static inline tcbToBezier(const TCBPoints &tcbPoints)
/*!
Adds a segment of a TCB bezier spline to define a custom easing curve.
It is only applicable if type() is QEasingCurve::TCBSpline.
- The spline has to start explitly at (0.0, 0.0) and has to end at (1.0, 1.0) to
+ The spline has to start explicitly at (0.0, 0.0) and has to end at (1.0, 1.0) to
be a valid easing curve.
The tension \a t changes the length of the tangent vector.
The continuity \a c changes the sharpness in change between the tangents.
diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h
index 5ba23b344b..9974102136 100644
--- a/src/corelib/tools/qfreelist_p.h
+++ b/src/corelib/tools/qfreelist_p.h
@@ -161,7 +161,7 @@ class QFreeList
return i;
x -= size;
}
- Q_ASSERT(false);
+ Q_UNREACHABLE();
return -1;
}
diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp
index a2a7839a0b..7e13d4db92 100644
--- a/src/corelib/tools/qline.cpp
+++ b/src/corelib/tools/qline.cpp
@@ -529,12 +529,13 @@ QDataStream &operator>>(QDataStream &stream, QLine &line)
\fn void QLineF::setLength(qreal length)
Sets the length of the line to the given \a length. QLineF will
- move the end point - p2() - of the line to give the line its new length.
+ move the end point - p2() - of the line to give the line its new
+ length, unless length() was previously zero, in which case no
+ scaling is attempted. For lines with very short lengths
+ (represented by denormal floating-point values), results may be
+ imprecise.
- A null line will not be rescaled. For non-null lines with very short lengths
- (represented by denormal floating-point values), results may be imprecise.
-
- \sa length(), isNull(), unitVector()
+ \sa length(), unitVector()
*/
/*!
diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h
index 2b687c1a0a..b2f8f491ed 100644
--- a/src/corelib/tools/qline.h
+++ b/src/corelib/tools/qline.h
@@ -378,12 +378,11 @@ Q_DECL_CONSTEXPR inline QPointF QLineF::center() const
inline void QLineF::setLength(qreal len)
{
- if (isNull())
- return;
- Q_ASSERT(length() > 0);
- const QLineF v = unitVector();
- len /= v.length(); // In case it's not quite exactly 1.
- pt2 = QPointF(pt1.x() + len * v.dx(), pt1.y() + len * v.dy());
+ const qreal oldLength = length();
+ // Scale len by dx() / length() and dy() / length(), two O(1) quantities,
+ // rather than scaling dx() and dy() by len / length(), which might overflow.
+ if (oldLength > 0)
+ pt2 = QPointF(pt1.x() + len * (dx() / oldLength), pt1.y() + len * (dy() / oldLength));
}
Q_DECL_CONSTEXPR inline QPointF QLineF::pointAt(qreal t) const
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 5d5da20752..f0b92b5206 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -2017,7 +2017,7 @@ void **QListData::erase(void **xi)
\include containers-range-constructor.qdocinc
- \sa fromSet(), toVector(), QVector::toList()
+ \sa toVector(), QVector::toList()
*/
/*! \fn template <class T> QVector<T> QList<T>::toVector() const
@@ -2030,61 +2030,91 @@ void **QListData::erase(void **xi)
\include containers-range-constructor.qdocinc
- \sa toSet(), fromVector(), QVector::fromList()
+ \sa fromVector(), QVector::fromList()
*/
/*! \fn template <class T> QList<T> QList<T>::fromSet(const QSet<T> &set)
+ \obsolete
Returns a QList object with the data contained in \a set. The
order of the elements in the QList is undefined.
- Example:
-
- \snippet code/src_corelib_tools_qlistdata.cpp 23
-
\include containers-range-constructor.qdocinc
- \sa fromVector(), toSet(), QSet::toList()
+ \oldcode
+ QSet<int> set;
+ // ...
+ QList<int> list = QList<int>::fromSet(set);
+ \newcode
+ QSet<int> set;
+ // ...
+ QList<int> list(set.begin(), set.end());
+ \endcode
+
+ \sa QList(InputIterator, InputIterator), fromVector(), toSet(), QSet::toList()
*/
/*! \fn template <class T> QSet<T> QList<T>::toSet() const
+ \obsolete
Returns a QSet object with the data contained in this QList.
Since QSet doesn't allow duplicates, the resulting QSet might be
smaller than the original list was.
- Example:
-
- \snippet code/src_corelib_tools_qlistdata.cpp 24
-
\include containers-range-constructor.qdocinc
- \sa toVector(), fromSet(), QSet::fromList()
+ \oldcode
+ QStringList list;
+ // ...
+ QSet<QString> set = list.toSet();
+ \newcode
+ QStringList list;
+ // ...
+ QSet<QString> set(list.begin(), list.end());
+ \endcode
+
+ \sa QSet::QSet(InputIterator, InputIterator), toVector(), fromSet(), QSet::fromList()
*/
/*! \fn template <class T> QList<T> QList<T>::fromStdList(const std::list<T> &list)
+ \obsolete
Returns a QList object with the data contained in \a list. The
order of the elements in the QList is the same as in \a list.
- Example:
-
- \snippet code/src_corelib_tools_qlistdata.cpp 25
-
\include containers-range-constructor.qdocinc
- \sa toStdList(), QVector::fromStdVector()
+ \oldcode
+ std::list<double> stdlist;
+ // ...
+ QList<double> list = QList<double>::fromStdList(stdlist);
+ \newcode
+ std::list<double> stdlist;
+ // ...
+ QList<double> list(stdlist.begin(), stdlist.end());
+ \endcode
+
+ \sa QList(InputIterator, InputIterator), toStdList(), QVector::fromStdVector()
*/
/*! \fn template <class T> std::list<T> QList<T>::toStdList() const
+ \obsolete
Returns a std::list object with the data contained in this QList.
Example:
- \snippet code/src_corelib_tools_qlistdata.cpp 26
-
\include containers-range-constructor.qdocinc
+ \oldcode
+ QList<double> list;
+ // ...
+ std::list<double> stdlist = list.toStdList();
+ \newcode
+ QList<double> list;
+ // ...
+ std::list<double> stdlist(list.begin(), list.end());
+ \endcode
+
\sa fromStdList(), QVector::toStdVector()
*/
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 0c69d13295..676d9a1fec 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -141,6 +141,7 @@ private:
QMapNode() = delete;
Q_DISABLE_COPY(QMapNode)
+ friend struct QMapNodeBase;
};
template <class Key, class T>
@@ -208,8 +209,11 @@ struct QMapData : public QMapDataBase
// using reinterpret_cast because QMapDataBase::header is not
// actually a QMapNode.
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wstrict-aliasing")
const Node *end() const { return reinterpret_cast<const Node *>(&header); }
Node *end() { return reinterpret_cast<Node *>(&header); }
+QT_WARNING_POP
const Node *begin() const { if (root()) return static_cast<const Node*>(mostLeftNode); return end(); }
Node *begin() { if (root()) return static_cast<Node*>(mostLeftNode); return end(); }
diff --git a/src/corelib/tools/qmargins.cpp b/src/corelib/tools/qmargins.cpp
index 74be7bb2ba..3d6a62af64 100644
--- a/src/corelib/tools/qmargins.cpp
+++ b/src/corelib/tools/qmargins.cpp
@@ -460,7 +460,7 @@ QDebug operator<<(QDebug dbg, const QMargins &m)
QMarginsF defines a set of four margins; left, top, right and bottom,
that describe the size of the borders surrounding a rectangle.
- The isNull() function returns \c true only if all margins are set to zero.
+ The isNull() function returns \c true only if all margins are very close to zero.
QMarginsF objects can be streamed as well as compared.
*/
@@ -489,14 +489,16 @@ 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.
*/
/*!
\fn bool QMarginsF::isNull() const
- Returns \c true if all margins are 0; otherwise returns
+ Returns \c true if all margins are very close to 0; otherwise returns
false.
+
+ \sa qFuzzyIsNull
*/
@@ -557,14 +559,26 @@ QDebug operator<<(QDebug dbg, const QMargins &m)
\fn bool operator==(const QMarginsF &lhs, const QMarginsF &rhs)
\relates QMarginsF
- Returns \c true if \a lhs and \a rhs are equal; otherwise returns \c false.
+ Returns \c true if \a lhs and \a rhs are approximately equal; otherwise
+ returns false.
+
+ \warning This function does not check for strict equality; instead,
+ it uses a fuzzy comparison to compare the margins.
+
+ \sa qFuzzyCompare
*/
/*!
\fn bool operator!=(const QMarginsF &lhs, const QMarginsF &rhs)
\relates QMarginsF
- Returns \c true if \a lhs and \a rhs are different; otherwise returns \c false.
+ Returns \c true if \a lhs and \a rhs are sufficiently different; otherwise
+ returns \c false.
+
+ \warning This function does not check for strict inequality; instead,
+ it uses a fuzzy comparison to compare the margins.
+
+ \sa qFuzzyCompare
*/
/*!
diff --git a/src/corelib/tools/qmessageauthenticationcode.cpp b/src/corelib/tools/qmessageauthenticationcode.cpp
index 40a1193622..40d120eb52 100644
--- a/src/corelib/tools/qmessageauthenticationcode.cpp
+++ b/src/corelib/tools/qmessageauthenticationcode.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2023 The Qt Company Ltd.
** Copyright (C) 2013 Ruslan Nigmatullin <euroelessar@yandex.ru>
** Contact: https://www.qt.io/licensing/
**
@@ -39,6 +40,8 @@
#include "qmessageauthenticationcode.h"
#include "qvarlengtharray.h"
+#include "qmutex.h"
+#include "private/qlocking_p.h"
/*
These #defines replace the typedefs needed by the RFC6234 code. Normally
@@ -125,11 +128,18 @@ public:
QByteArray key;
QByteArray result;
+ QMutex finalizeMutex;
QCryptographicHash messageHash;
QCryptographicHash::Algorithm method;
bool messageHashInited;
void initMessageHash();
+ void finalize();
+
+ // when not called from the static hash() function, this function needs to be
+ // called with finalizeMutex held:
+ void finalizeUnchecked();
+ // END functions that need to be called with finalizeMutex held
};
void QMessageAuthenticationCodePrivate::initMessageHash()
@@ -266,27 +276,36 @@ bool QMessageAuthenticationCode::addData(QIODevice *device)
*/
QByteArray QMessageAuthenticationCode::result() const
{
- if (!d->result.isEmpty())
- return d->result;
+ d->finalize();
+ return d->result;
+}
- d->initMessageHash();
+void QMessageAuthenticationCodePrivate::finalize()
+{
+ const auto lock = qt_scoped_lock(finalizeMutex);
+ if (!result.isEmpty())
+ return;
+ initMessageHash();
+ finalizeUnchecked();
+}
- const int blockSize = qt_hash_block_size(d->method);
+void QMessageAuthenticationCodePrivate::finalizeUnchecked()
+{
+ const int blockSize = qt_hash_block_size(method);
- QByteArray hashedMessage = d->messageHash.result();
+ QByteArray hashedMessage = messageHash.result();
QVarLengthArray<char> oKeyPad(blockSize);
- const char * const keyData = d->key.constData();
+ const char * const keyData = key.constData();
for (int i = 0; i < blockSize; ++i)
oKeyPad[i] = keyData[i] ^ 0x5c;
- QCryptographicHash hash(d->method);
+ QCryptographicHash hash(method);
hash.addData(oKeyPad.data(), oKeyPad.size());
hash.addData(hashedMessage);
- d->result = hash.result();
- return d->result;
+ result = hash.result();
}
/*!
diff --git a/src/corelib/tools/qoffsetstringarray_p.h b/src/corelib/tools/qoffsetstringarray_p.h
index 4dd9e9603b..e26a57ff43 100644
--- a/src/corelib/tools/qoffsetstringarray_p.h
+++ b/src/corelib/tools/qoffsetstringarray_p.h
@@ -55,6 +55,7 @@
#include <tuple>
#include <array>
+#include <limits>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp
index 432fb33297..5b9ae5314d 100644
--- a/src/corelib/tools/qpoint.cpp
+++ b/src/corelib/tools/qpoint.cpp
@@ -762,14 +762,26 @@ QDebug operator<<(QDebug dbg, const QPointF &p)
\fn bool operator==(const QPointF &p1, const QPointF &p2)
\relates QPointF
- Returns \c true if \a p1 is equal to \a p2; otherwise returns \c false.
+ Returns \c true if \a p1 is approximately equal to \a p2; otherwise
+ returns \c false.
+
+ \warning This function does not check for strict equality; instead,
+ it uses a fuzzy comparison to compare the points' coordinates.
+
+ \sa qFuzzyCompare
*/
/*!
\fn bool operator!=(const QPointF &p1, const QPointF &p2);
\relates QPointF
- Returns \c true if \a p1 is not equal to \a p2; otherwise returns \c false.
+ Returns \c true if \a p1 is sufficiently different from \a p2;
+ otherwise returns \c false.
+
+ \warning This function does not check for strict inequality; instead,
+ it uses a fuzzy comparison to compare the points' coordinates.
+
+ \sa qFuzzyCompare
*/
#ifndef QT_NO_DATASTREAM
diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp
index 6f120b9d10..2d4c55ad85 100644
--- a/src/corelib/tools/qrect.cpp
+++ b/src/corelib/tools/qrect.cpp
@@ -2391,8 +2391,13 @@ QRect QRectF::toAlignedRect() const noexcept
\fn bool operator==(const QRectF &r1, const QRectF &r2)
\relates QRectF
- Returns \c true if the rectangles \a r1 and \a r2 are equal,
+ Returns \c true if the rectangles \a r1 and \a r2 are \b approximately equal,
otherwise returns \c false.
+
+ \warning This function does not check for strict equality; instead,
+ it uses a fuzzy comparison to compare the rectangles' coordinates.
+
+ \sa qFuzzyCompare
*/
@@ -2400,8 +2405,11 @@ QRect QRectF::toAlignedRect() const noexcept
\fn bool operator!=(const QRectF &r1, const QRectF &r2)
\relates QRectF
- Returns \c true if the rectangles \a r1 and \a r2 are different, otherwise
- returns \c false.
+ Returns \c true if the rectangles \a r1 and \a r2 are sufficiently
+ different, otherwise returns \c false.
+
+ \warning This function does not check for strict inequality; instead,
+ it uses a fuzzy comparison to compare the rectangles' coordinates.
*/
/*!
diff --git a/src/corelib/tools/qscopedvaluerollback.cpp b/src/corelib/tools/qscopedvaluerollback.cpp
index baca7c8229..0c1c43ac49 100644
--- a/src/corelib/tools/qscopedvaluerollback.cpp
+++ b/src/corelib/tools/qscopedvaluerollback.cpp
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
The template can only be instantiated with a type that supports assignment.
- \sa QScopedPointer
+ \sa QScopedPointer, QScopeGuard
*/
/*!
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index 42dd1288ac..dcd6de3d5c 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -1071,17 +1071,32 @@
*/
/*! \fn template <class T> QList<T> QSet<T>::toList() const
+ \obsolete
Returns a new QList containing the elements in the set. The
order of the elements in the QList is undefined.
- Example:
+ \include containers-range-constructor.qdocinc
- \snippet code/doc_src_qset.cpp 13
+ \oldcode
+ QSet<QString> set;
+ // ...
+ QList<QString> list = set.toList();
+ \newcode
+ QSet<QString> set;
+ // ...
+ QList<QString> list(set.begin(), set.end());
+ \endcode
- \include containers-range-constructor.qdocinc
+ or
- \sa fromList(), QList::fromSet()
+ \code
+ QSet<QString> set;
+ // ...
+ QList<QString> list = set.values();
+ \endcode
+
+ \sa QList::QList(InputIterator, InputIterator), values(), fromList(), QList::fromSet()
*/
/*! \fn template <class T> QList<T> QSet<T>::values() const
@@ -1089,28 +1104,44 @@
Returns a new QList containing the elements in the set. The
order of the elements in the QList is undefined.
- This is the same as toList().
-
\include containers-range-constructor.qdocinc
- \sa fromList(), QList::fromSet()
+ \oldcode
+ QSet<QString> set;
+ // ...
+ QList<QString> list = set.values();
+ \newcode
+ QSet<QString> set;
+ // ...
+ QList<QString> list(set.begin(), set.end());
+ \endcode
+
+
+ \sa QList::QList(InputIterator, InputIterator)
*/
/*! \fn template <class T> QSet<T> QSet<T>::fromList(const QList<T> &list)
+ \obsolete
Returns a new QSet object containing the data contained in \a
list. Since QSet doesn't allow duplicates, the resulting QSet
might be smaller than the \a list, because QList can contain
duplicates.
- Example:
-
- \snippet code/doc_src_qset.cpp 14
-
\include containers-range-constructor.qdocinc
- \sa toList(), QList::toSet()
+ \oldcode
+ QStringList list;
+ // ...
+ QSet<QString> set = QSet<QString>::fromList(list);
+ \newcode
+ QStringList list;
+ // ...
+ QSet<QString> set(list.begin(), list.end());
+ \endcode
+
+ \sa QSet(InputIterator, InputIterator), values(), QList::toSet()
*/
/*!
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index a24b689181..bc7a5f80d7 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -479,6 +479,46 @@
*/
/*!
+ \fn template <class T> QSharedPointer<T>::QSharedPointer(QSharedPointer &&other)
+
+ Move-constructs a QSharedPointer instance, making it point at the same
+ object that \a other was pointing to.
+
+ \since 5.4
+*/
+
+/*!
+ \fn template <class T> QSharedPointer<T>::operator=(QSharedPointer &&other)
+
+ Move-assigns \a other to this QSharedPointer instance.
+
+ \since 5.0
+*/
+
+/*!
+ \fn template <class T> template <class X> QSharedPointer<T>::QSharedPointer(QSharedPointer<X> &&other)
+
+ Move-constructs a QSharedPointer instance, making it point at the same
+ object that \a other was pointing to.
+
+ This constructor participates in overload resolution only if \c{X*}
+ implicitly converts to \c{T*}.
+
+ \since 5.6
+*/
+
+/*!
+ \fn template <class T> template <class X> QSharedPointer<T>::operator=(QSharedPointer<X> &&other)
+
+ Move-assigns \a other to this QSharedPointer instance.
+
+ This assignment operator participates in overload resolution only if \c{X*}
+ implicitly converts to \c{T*}.
+
+ \since 5.6
+*/
+
+/*!
\fn template <class T> QSharedPointer<T>::QSharedPointer(const QWeakPointer<T> &other)
Creates a QSharedPointer by promoting the weak reference \a other
@@ -932,6 +972,15 @@
*/
/*!
+ \fn template <class T> qHash(const QSharedPointer<T> &key, size_t seed)
+ \relates QSharedPointer
+
+ Returns the hash value for \a key, using \a seed to seed the calculation.
+
+ \since 5.0
+*/
+
+/*!
\fn template <class T> template <class X> bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
\relates QSharedPointer
@@ -1400,7 +1449,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
}
// we can create the refcount data because it doesn't exist
- ExternalRefCountData *x = new ExternalRefCountData(Qt::Uninitialized);
+ ExternalRefCountData *x = ::new ExternalRefCountData(Qt::Uninitialized);
x->strongref.storeRelaxed(-1);
x->weakref.storeRelaxed(2); // the QWeakPointer that called us plus the QObject itself
@@ -1411,7 +1460,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
// ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
// only execute this if Q_ASSERTs are enabled
Q_ASSERT((x->weakref.storeRelaxed(0), true));
- delete x;
+ ::delete x;
ret->weakref.ref();
}
return ret;
diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h
index 5d47369687..72e48d8a16 100644
--- a/src/corelib/tools/qsharedpointer.h
+++ b/src/corelib/tools/qsharedpointer.h
@@ -82,7 +82,12 @@ public:
QSharedPointer<T> &operator=(const QSharedPointer<T> &other);
QSharedPointer<T> &operator=(const QWeakPointer<T> &other);
- void swap(QSharedPointer<T> &other);
+ template <class X>
+ QSharedPointer(QSharedPointer<X> && other) noexcept;
+ template <class X>
+ QSharedPointer &operator=(QSharedPointer<X> && other) noexcept;
+
+ void swap(QSharedPointer<T> &other) noexcept;
QWeakPointer<T> toWeakRef() const;
@@ -104,6 +109,9 @@ public:
};
template <class T>
+size_t qHash(const QSharedPointer<T> &key, size_t seed = 0) noexcept;
+
+template <class T>
class QWeakPointer
{
public:
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 790c187cb9..d262e4ebc9 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -156,6 +156,12 @@ namespace QtSharedPointer {
inline void checkQObjectShared(...) { }
inline void setQObjectShared(...) { }
+ // Normally, only subclasses of ExternalRefCountData are allocated
+ // One exception exists in getAndRef; that uses the global operator new
+ // to prevent a mismatch with the custom operator delete
+ inline void *operator new(std::size_t) = delete;
+ // placement new
+ inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
inline void operator delete(void *ptr) { ::operator delete(ptr); }
inline void operator delete(void *, void *) { }
};
@@ -881,7 +887,7 @@ Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2)
template <class T>
Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr, uint seed = 0)
{
- return QT_PREPEND_NAMESPACE(qHash)(ptr.data(), seed);
+ return qHash(ptr.data(), seed);
}
@@ -1012,15 +1018,11 @@ std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
using element_type = typename std::shared_ptr<X>::element_type;
auto castResult = qobject_cast<element_type *>(src.get());
if (castResult) {
- auto result = std::shared_ptr<X>(std::move(src), castResult);
-#if __cplusplus <= 201703L
// C++2a's move aliasing constructor will leave src empty.
// Before C++2a we don't really know if the compiler has support for it.
// The move aliasing constructor is the resolution for LWG2996,
// which does not impose a feature-testing macro. So: clear src.
- src.reset();
-#endif
- return result;
+ return std::shared_ptr<X>(qExchange(src, nullptr), castResult);
}
return std::shared_ptr<X>();
}
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 6ad6795fec..798ac93ad2 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -132,7 +132,7 @@ static inline quint64 detectProcessorFeatures()
#if defined(Q_OS_LINUX)
# if defined(Q_PROCESSOR_ARM_V8) && defined(Q_PROCESSOR_ARM_64)
- features |= Q_UINT64_C(1) << CpuFeatureNEON; // NEON is always available on ARMv8 64bit.
+ features |= CpuFeatureNEON; // NEON is always available on ARMv8 64bit.
# endif
int auxv = qt_safe_open("/proc/self/auxv", O_RDONLY);
if (auxv != -1) {
@@ -151,17 +151,17 @@ static inline quint64 detectProcessorFeatures()
# if defined(Q_PROCESSOR_ARM_V8) && defined(Q_PROCESSOR_ARM_64)
// For Aarch64:
if (vector[i+1] & HWCAP_CRC32)
- features |= Q_UINT64_C(1) << CpuFeatureCRC32;
+ features |= CpuFeatureCRC32;
# endif
// Aarch32, or ARMv7 or before:
if (vector[i+1] & HWCAP_NEON)
- features |= Q_UINT64_C(1) << CpuFeatureNEON;
+ features |= CpuFeatureNEON;
}
# if defined(Q_PROCESSOR_ARM_32)
// For Aarch32:
if (vector[i] == AT_HWCAP2) {
if (vector[i+1] & HWCAP2_CRC32)
- features |= Q_UINT64_C(1) << CpuFeatureCRC32;
+ features |= CpuFeatureCRC32;
}
# endif
}
@@ -174,10 +174,10 @@ static inline quint64 detectProcessorFeatures()
#endif
#if defined(__ARM_NEON__)
- features |= Q_UINT64_C(1) << CpuFeatureNEON;
+ features |= CpuFeatureNEON;
#endif
#if defined(__ARM_FEATURE_CRC32)
- features |= Q_UINT64_C(1) << CpuFeatureCRC32;
+ features |= CpuFeatureCRC32;
#endif
return features;
@@ -505,18 +505,18 @@ static inline quint64 detectProcessorFeatures()
quint64 flags = 0;
#if defined __mips_dsp
- flags |= Q_UINT64_C(1) << CpuFeatureDSP;
+ flags |= CpuFeatureDSP;
# if defined __mips_dsp_rev && __mips_dsp_rev >= 2
- flags |= Q_UINT64_C(1) << CpuFeatureDSPR2;
+ flags |= CpuFeatureDSPR2;
# elif defined(Q_OS_LINUX)
if (procCpuinfoContains("cpu model", "MIPS 74Kc") || procCpuinfoContains("cpu model", "MIPS 74Kf"))
- flags |= Q_UINT64_C(1) << CpuFeatureDSPR2;
+ flags |= CpuFeatureDSPR2;
# endif
#elif defined(Q_OS_LINUX)
if (procCpuinfoContains("ASEs implemented", "dsp")) {
- flags |= Q_UINT64_C(1) << CpuFeatureDSP;
+ flags |= CpuFeatureDSP;
if (procCpuinfoContains("cpu model", "MIPS 74Kc") || procCpuinfoContains("cpu model", "MIPS 74Kf"))
- flags |= Q_UINT64_C(1) << CpuFeatureDSPR2;
+ flags |= CpuFeatureDSPR2;
}
#endif
diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp
index 2cbaae117d..1bc7d4c15b 100644
--- a/src/corelib/tools/qsize.cpp
+++ b/src/corelib/tools/qsize.cpp
@@ -751,15 +751,24 @@ QSizeF QSizeF::scaled(const QSizeF &s, Qt::AspectRatioMode mode) const noexcept
\fn bool operator==(const QSizeF &s1, const QSizeF &s2)
\relates QSizeF
- Returns \c true if \a s1 and \a s2 are equal; otherwise returns
- false.
+ Returns \c true if \a s1 and \a s2 are approximately equal; otherwise
+ returns false.
+
+ \warning This function does not check for strict equality; instead,
+ it uses a fuzzy comparison to compare the sizes' extents.
+
+ \sa qFuzzyCompare
*/
/*!
\fn bool operator!=(const QSizeF &s1, const QSizeF &s2)
\relates QSizeF
- Returns \c true if \a s1 and \a s2 are different; otherwise returns \c false.
+ Returns \c true if \a s1 and \a s2 are sufficiently different; otherwise
+ returns \c false.
+
+ \warning This function does not check for strict inequality; instead,
+ it uses a fuzzy comparison to compare the sizes' extents.
*/
/*!
diff --git a/src/corelib/tools/qtools_p.h b/src/corelib/tools/qtools_p.h
index d48318b474..ca52b15870 100644
--- a/src/corelib/tools/qtools_p.h
+++ b/src/corelib/tools/qtools_p.h
@@ -84,6 +84,17 @@ Q_DECL_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 char toAsciiUpper(char ch) noexcept
+{
+ return (ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch;
+}
+
}
// 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 6be695e317..f0e4342e06 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -49,6 +49,7 @@
#include <algorithm>
#include <initializer_list>
#include <iterator>
+#include <memory>
#include <new>
#include <string.h>
#include <stdlib.h>
@@ -152,30 +153,18 @@ public:
if (s == a) { // i.e. s != 0
T copy(t);
realloc(s, s<<1);
- const int idx = s++;
- if (QTypeInfo<T>::isComplex) {
- new (ptr + idx) T(std::move(copy));
- } else {
- ptr[idx] = std::move(copy);
- }
+ new (end()) T(std::move(copy));
} else {
- const int idx = s++;
- if (QTypeInfo<T>::isComplex) {
- new (ptr + idx) T(t);
- } else {
- ptr[idx] = t;
- }
+ new (end()) T(t);
}
+ ++s;
}
void append(T &&t) {
if (s == a)
realloc(s, s << 1);
- const int idx = s++;
- if (QTypeInfo<T>::isComplex)
- new (ptr + idx) T(std::move(t));
- else
- ptr[idx] = std::move(t);
+ new (end()) T(std::move(t));
+ ++s;
}
void append(const T *buf, int size);
@@ -249,6 +238,20 @@ public:
private:
void realloc(int size, int alloc);
+ void resize_impl(int newSize, const T &t)
+ {
+ const auto increment = newSize - size();
+ if (increment > 0 && QtPrivate::q_points_into_range(&t, cbegin(), cend())) {
+ resize_impl(newSize, T(t));
+ return;
+ }
+ realloc(qMin(size(), newSize), qMax(newSize, capacity()));
+
+ if (increment > 0)
+ std::uninitialized_fill_n(end(), increment, t);
+ s = newSize;
+ }
+
int a; // capacity
int s; // size
T *ptr; // data
@@ -487,57 +490,25 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
{
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
- int offset = int(before - ptr);
- reserve(s + 1);
- if (!QTypeInfo<T>::isRelocatable) {
- T *b = ptr + offset;
- T *i = ptr + s;
- T *j = i + 1;
- // The new end-element needs to be constructed, the rest must be move assigned
- if (i != b) {
- new (--j) T(std::move(*--i));
- while (i != b)
- *--j = std::move(*--i);
- *b = std::move(t);
- } else {
- new (b) T(std::move(t));
- }
- } else {
- T *b = ptr + offset;
- memmove(static_cast<void *>(b + 1), static_cast<const void *>(b), (s - offset) * sizeof(T));
- new (b) T(std::move(t));
- }
- s += 1;
- return ptr + offset;
+ const int offset = int(before - ptr);
+ append(std::move(t));
+ const auto b = begin() + offset;
+ const auto e = end();
+ QtPrivate::q_rotate(b, e - 1, e);
+ return b;
}
template <class T, int Prealloc>
-Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, size_type n, const T &t)
+Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, int n, const T &t)
{
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
- int offset = int(before - ptr);
- if (n != 0) {
- resize(s + n);
- const T copy(t);
- if (!QTypeInfoQuery<T>::isRelocatable) {
- T *b = ptr + offset;
- T *j = ptr + s;
- T *i = j - n;
- while (i != b)
- *--j = *--i;
- i = b + n;
- while (i != b)
- *--i = copy;
- } else {
- T *b = ptr + offset;
- T *i = b + n;
- memmove(static_cast<void *>(i), static_cast<const void *>(b), (s - offset - n) * sizeof(T));
- while (i != b)
- new (--i) T(copy);
- }
- }
- return ptr + offset;
+ const int offset = int(before - cbegin());
+ resize_impl(size() + n, t);
+ const auto b = begin() + offset;
+ const auto e = end();
+ QtPrivate::q_rotate(b, e - n, e);
+ return b;
}
template <class T, int Prealloc>
@@ -549,6 +520,12 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
int f = int(abegin - ptr);
int l = int(aend - ptr);
int n = l - f;
+
+ if (n == 0) // avoid UB in std::copy() below
+ return data() + f;
+
+ Q_ASSERT(n > 0); // aend must be reachable from abegin
+
if (QTypeInfo<T>::isComplex) {
std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f));
T *i = ptr + s;
diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc
index 3dab41dd22..30f12478aa 100644
--- a/src/corelib/tools/qvarlengtharray.qdoc
+++ b/src/corelib/tools/qvarlengtharray.qdoc
@@ -90,6 +90,11 @@
\sa QVector, QList, QLinkedList
*/
+/*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::QVarLengthArray()
+
+ Constructs an array with an initial size of zero.
+*/
+
/*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::QVarLengthArray(int size)
Constructs an array with an initial size of \a size elements.
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 8d1b15b507..85393a3598 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -343,13 +343,8 @@ QVector(InputIterator, InputIterator) -> QVector<ValueType>;
template <typename T>
void QVector<T>::defaultConstruct(T *from, T *to)
{
- if (QTypeInfo<T>::isComplex) {
- while (from != to) {
- new (from++) T();
- }
- } else {
- ::memset(static_cast<void *>(from), 0, (to - from) * sizeof(T));
- }
+ while (from != to)
+ new (from++) T();
}
template <typename T>
@@ -528,7 +523,7 @@ QVector<T>::QVector(int asize, const T &t)
d = Data::allocate(asize);
Q_CHECK_PTR(d);
d->size = asize;
- T* i = d->end();
+ auto i = d->end();
while (i != d->begin())
new (--i) T(t);
} else {
@@ -640,17 +635,13 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
if (asize > d->size) {
// construct all new objects when growing
- if (!QTypeInfo<T>::isComplex) {
- ::memset(static_cast<void *>(dst), 0, (static_cast<T *>(x->end()) - dst) * sizeof(T));
- } else {
- QT_TRY {
- while (dst != x->end())
- new (dst++) T();
- } QT_CATCH (...) {
- // destruct already copied objects
- destruct(x->begin(), dst);
- QT_RETHROW;
- }
+ QT_TRY {
+ while (dst != x->end())
+ new (dst++) T();
+ } QT_CATCH (...) {
+ // destruct already copied objects
+ destruct(x->begin(), dst);
+ QT_RETHROW;
}
}
} QT_CATCH (...) {
@@ -844,18 +835,25 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
if (!isDetached() || d->size + n > int(d->alloc))
realloc(d->size + n, QArrayData::Grow);
if (!QTypeInfoQuery<T>::isRelocatable) {
- T *b = d->end();
- T *i = d->end() + n;
- while (i != b)
- new (--i) T;
- i = d->end();
+ T *const e = d->end();
+ T *const b = d->begin() + offset;
+
+ T *i = e;
T *j = i + n;
- b = d->begin() + offset;
- while (i != b)
- *--j = *--i;
- i = b+n;
+
+ // move old elements into the uninitialized space
+ while (i != b && j > e)
+ new (--j) T(std::move(*--i));
+ // move the rest of old elements into the tail using assignment
while (i != b)
- *--i = copy;
+ *--j = std::move(*--i);
+
+ // construct copies of t inside the uninitialized space
+ while (j != b && j > e)
+ new (--j) T(copy);
+ // use assignment to fill the recently-moved-from space
+ while (j != b)
+ *--j = copy;
} else {
T *b = d->begin() + offset;
T *i = b + n;
diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp
index 58e3c15560..575d7b12a5 100644
--- a/src/corelib/tools/qversionnumber.cpp
+++ b/src/corelib/tools/qversionnumber.cpp
@@ -189,7 +189,7 @@ QVector<int> QVersionNumber::segments() const
/*!
\fn int QVersionNumber::segmentAt(int index) const
- Returns the segement value at \a index. If the index does not exist,
+ Returns the segment value at \a index. If the index does not exist,
returns 0.
\sa segments(), segmentCount()
diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h
index d43b86ba51..d1180b54e6 100644
--- a/src/corelib/tools/qversionnumber.h
+++ b/src/corelib/tools/qversionnumber.h
@@ -133,8 +133,8 @@ class QVersionNumber
explicit SegmentStorage(QVector<int> &&seg)
{
- if (dataFitsInline(seg.begin(), seg.size()))
- setInlineData(seg.begin(), seg.size());
+ if (dataFitsInline(seg.cbegin(), seg.size()))
+ setInlineData(seg.cbegin(), seg.size());
else
pointer_segments = new QVector<int>(std::move(seg));
}
@@ -269,14 +269,14 @@ public:
Q_REQUIRED_RESULT Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) noexcept;
- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2);
+ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2);
Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const;
#if QT_STRINGVIEW_LEVEL < 2
- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
+ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(const QString &string, int *suffixIndex = nullptr);
#endif
- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
- Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
+ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QLatin1String string, int *suffixIndex = nullptr);
+ Q_REQUIRED_RESULT Q_CORE_EXPORT static QVersionNumber fromString(QStringView string, int *suffixIndex = nullptr);
private:
#ifndef QT_NO_DATASTREAM