QVersionNumber: change int to qsizetype for index and length

This class is not exported, so we can change the non-exported
methods. None of the exported methods required change; notably,
QVersionNumber::Segments::setVector didn't because it's only called with
values 1, 2, and 3.

[ChangeLog][Potentially source-incompatible changes] Updated the
QVersionNumber API to use qsizetype where length and index values were
used. This change retains binary compatibility and the vast majority of
users will not experience a source compatibility problem. It could occur
with ambiguous overloads when passing results from QVersionNumber to
other API not using either int or qsizetype. There could also be new
warnings from compilers about converting 64-bit types to 32-bit ones.

Change-Id: I0e5f6bec596a4a78bd3bfffd16c9984b61c9b55b
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Thiago Macieira 2022-01-12 10:09:48 -08:00 committed by Marc Mutz
parent 3976449c0e
commit b387fbd122
2 changed files with 34 additions and 30 deletions

View File

@ -168,7 +168,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
\fn const QList<int>& QVersionNumber::segments() const
\fn QList<int> QVersionNumber::segments() const
Returns all of the numerical segments.
@ -181,13 +181,13 @@ QList<int> QVersionNumber::segments() const
QList<int> result;
result.resize(segmentCount());
for (int i = 0; i < segmentCount(); ++i)
for (qsizetype i = 0; i < segmentCount(); ++i)
result[i] = segmentAt(i);
return result;
}
/*!
\fn int QVersionNumber::segmentAt(int index) const
\fn int QVersionNumber::segmentAt(qsizetype index) const
Returns the segment value at \a index. If the index does not exist,
returns 0.
@ -196,7 +196,7 @@ QList<int> QVersionNumber::segments() const
*/
/*!
\fn int QVersionNumber::segmentCount() const
\fn qsizetype QVersionNumber::segmentCount() const
Returns the number of integers stored in segments().
@ -215,7 +215,7 @@ QList<int> QVersionNumber::segments() const
*/
QVersionNumber QVersionNumber::normalized() const
{
int i;
qsizetype i;
for (i = m_segments.size(); i; --i)
if (m_segments.at(i - 1) != 0)
break;
@ -239,7 +239,7 @@ bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const noexcept
{
if (segmentCount() > other.segmentCount())
return false;
for (int i = 0; i < segmentCount(); ++i) {
for (qsizetype i = 0; i < segmentCount(); ++i) {
if (segmentAt(i) != other.segmentAt(i))
return false;
}
@ -261,7 +261,7 @@ bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const noexcept
*/
int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) noexcept
{
int commonlen;
qsizetype commonlen;
if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) {
// we can't use memcmp because it interprets the data as unsigned bytes
@ -269,12 +269,12 @@ int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2)
const qint8 *ptr2 = v2.m_segments.inline_segments + InlineSegmentStartIdx;
commonlen = qMin(v1.m_segments.size(),
v2.m_segments.size());
for (int i = 0; i < commonlen; ++i)
for (qsizetype i = 0; i < commonlen; ++i)
if (int x = ptr1[i] - ptr2[i])
return x;
} else {
commonlen = qMin(v1.segmentCount(), v2.segmentCount());
for (int i = 0; i < commonlen; ++i) {
for (qsizetype i = 0; i < commonlen; ++i) {
if (v1.segmentAt(i) != v2.segmentAt(i))
return v1.segmentAt(i) - v2.segmentAt(i);
}
@ -311,8 +311,8 @@ int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2)
QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1,
const QVersionNumber &v2)
{
int commonlen = qMin(v1.segmentCount(), v2.segmentCount());
int i;
qsizetype commonlen = qMin(v1.segmentCount(), v2.segmentCount());
qsizetype i;
for (i = 0; i < commonlen; ++i) {
if (v1.segmentAt(i) != v2.segmentAt(i))
break;
@ -391,7 +391,7 @@ QString QVersionNumber::toString() const
QString version;
version.reserve(qMax(segmentCount() * 2 - 1, 0));
bool first = true;
for (int i = 0; i < segmentCount(); ++i) {
for (qsizetype i = 0; i < segmentCount(); ++i) {
if (!first)
version += QLatin1Char('.');
version += QString::number(segmentAt(i));

View File

@ -1,8 +1,8 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2022 Intel Corporation.
** Copyright (C) 2015 Keith Gardner <kreios4004@gmail.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -143,8 +143,8 @@ class QVersionNumber
}
SegmentStorage(std::initializer_list<int> args)
{
if (dataFitsInline(std::data(args), int(args.size()))) {
setInlineData(std::data(args), int(args.size()));
if (dataFitsInline(std::data(args), args.size())) {
setInlineData(std::data(args), args.size());
} else {
pointer_segments = new QList<int>(args);
}
@ -155,13 +155,16 @@ class QVersionNumber
bool isUsingPointer() const noexcept
{ return (inline_segments[InlineSegmentMarker] & 1) == 0; }
int size() const noexcept
qsizetype size() const noexcept
{ return isUsingPointer() ? pointer_segments->size() : (inline_segments[InlineSegmentMarker] >> 1); }
void setInlineSize(int len)
{ inline_segments[InlineSegmentMarker] = qint8(1 + 2 * len); }
void setInlineSize(qsizetype len)
{
Q_ASSERT(len <= InlineSegmentCount);
inline_segments[InlineSegmentMarker] = qint8(1 + 2 * len);
}
void resize(int len)
void resize(qsizetype len)
{
if (isUsingPointer())
pointer_segments->resize(len);
@ -169,7 +172,7 @@ class QVersionNumber
setInlineSize(len);
}
int at(int index) const
int at(qsizetype index) const
{
return isUsingPointer() ?
pointer_segments->at(index) :
@ -187,28 +190,29 @@ class QVersionNumber
}
private:
static bool dataFitsInline(const int *data, int len)
static bool dataFitsInline(const int *data, qsizetype len)
{
if (len > InlineSegmentCount)
return false;
for (int i = 0; i < len; ++i)
for (qsizetype i = 0; i < len; ++i)
if (data[i] != qint8(data[i]))
return false;
return true;
}
void setInlineData(const int *data, int len)
void setInlineData(const int *data, qsizetype len)
{
Q_ASSERT(len <= InlineSegmentCount);
dummy = 1 + len * 2;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
for (int i = 0; i < len; ++i)
for (qsizetype i = 0; i < len; ++i)
dummy |= quintptr(data[i] & 0xFF) << (8 * (i + 1));
#elif Q_BYTE_ORDER == Q_BIG_ENDIAN
for (int i = 0; i < len; ++i)
for (qsizetype i = 0; i < len; ++i)
dummy |= quintptr(data[i] & 0xFF) << (8 * (sizeof(void *) - i - 1));
#else
// the code above is equivalent to:
setInlineSize(len);
for (int i = 0; i < len; ++i)
for (qsizetype i = 0; i < len; ++i)
inline_segments[InlineSegmentStartIdx + i] = data[i] & 0xFF;
#endif
}
@ -258,10 +262,10 @@ public:
[[nodiscard]] Q_CORE_EXPORT QList<int> segments() const;
[[nodiscard]] inline int segmentAt(int index) const noexcept
[[nodiscard]] inline int segmentAt(qsizetype index) const noexcept
{ return (m_segments.size() > index) ? m_segments.at(index) : 0; }
[[nodiscard]] inline int segmentCount() const noexcept
[[nodiscard]] inline qsizetype segmentCount() const noexcept
{ return m_segments.size(); }
[[nodiscard]] Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const noexcept;