diff options
author | Marc Mutz <marc.mutz@qt.io> | 2022-01-15 23:48:52 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2022-01-18 01:31:33 +0100 |
commit | 9ffcab65629539c0335c78d9896153d9c31f475e (patch) | |
tree | 5276bfbe28dc2dcb5db1eba15051adf370ebfc32 | |
parent | 1a440e557b0efa9758f7d41112f09016ad385bab (diff) |
QVersionNumber: port fromString() to QAnyStringView
We can handle the UTF-8 case by reinterpreting it as Latin-1.
This way, the suffixIndex stays valid as a return value.
As a drive-by, optimize away toLatin1() calls by using a QVLA.
We really need a better way of converting UTF-16 -> L1 than
qt_to_latin1()...
[ChangeLog][QtCore][QVersionNumber] fromString() now takes
QAnyStringView (was: QString, QStringView, QLatin1String)
and a qsizetype pointer (was: int pointer).
Change-Id: I86abaadba2792658fbf93ccd1e0b86e3302c697c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/compat/removed_api.cpp | 26 | ||||
-rw-r--r-- | src/corelib/doc/snippets/qversionnumber/main.cpp | 4 | ||||
-rw-r--r-- | src/corelib/text/qstring.cpp | 2 | ||||
-rw-r--r-- | src/corelib/tools/qversionnumber.cpp | 70 | ||||
-rw-r--r-- | src/corelib/tools/qversionnumber.h | 26 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp | 41 |
6 files changed, 101 insertions, 68 deletions
diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index 61d3842e64..5f59cf047a 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -114,38 +114,30 @@ QByteArray QtPrivate::QByteArrayList_join(const QByteArrayList *that, const char } #endif // QT_REMOVED_SINCE(6, 3) + #if QT_REMOVED_SINCE(6, 4) #include "qversionnumber.h" -# if QT_POINTER_SIZE != 4 +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + QVersionNumber QVersionNumber::fromString(const QString &string, int *suffixIndex) { - qsizetype si; - QVersionNumber r = fromString(QLatin1String(string.toLatin1()), &si); - if (suffixIndex) - *suffixIndex = si; - return r; + return fromString(qToAnyStringViewIgnoringNull(string), suffixIndex); } QVersionNumber QVersionNumber::fromString(QStringView string, int *suffixIndex) { - qsizetype si; - QVersionNumber r = fromString(QLatin1String(string.toLatin1()), &si); - if (suffixIndex) - *suffixIndex = si; - return r; + return fromString(QAnyStringView{string}, suffixIndex); } QVersionNumber QVersionNumber::fromString(QLatin1String string, int *suffixIndex) { - qsizetype si; - QVersionNumber r = fromString(string, &si); - if (suffixIndex) - *suffixIndex = si; - return r; + return fromString(QAnyStringView{string}, suffixIndex); } -# endif // QT_POINTER_SIZE != 4 + +QT_WARNING_POP // #include <qotherheader.h> // // implement removed functions from qotherheader.h diff --git a/src/corelib/doc/snippets/qversionnumber/main.cpp b/src/corelib/doc/snippets/qversionnumber/main.cpp index 27b7b1a7ef..1a520a1cef 100644 --- a/src/corelib/doc/snippets/qversionnumber/main.cpp +++ b/src/corelib/doc/snippets/qversionnumber/main.cpp @@ -90,7 +90,7 @@ void QObject::parse() { //! [3] QString string("5.4.0-alpha"); - int suffixIndex; + qsizetype suffixIndex; QVersionNumber version = QVersionNumber::fromString(string, &suffixIndex); // version is 5.4.0 // suffixIndex is 5 @@ -98,7 +98,7 @@ void QObject::parse() //! [3-latin1-1] QLatin1String string("5.4.0-alpha"); - int suffixIndex; + qsizetype suffixIndex; auto version = QVersionNumber::fromString(string, &suffixIndex); // version is 5.4.0 // suffixIndex is 5 diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 9742f5ad83..23927b0e84 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -995,7 +995,7 @@ static void qt_to_latin1_internal(uchar *dst, const char16_t *src, qsizetype len #endif } -static void qt_to_latin1(uchar *dst, const char16_t *src, qsizetype length) +void qt_to_latin1(uchar *dst, const char16_t *src, qsizetype length) { qt_to_latin1_internal<true>(dst, src, length); } diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index d30608534f..4aa8cdd346 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -400,48 +400,9 @@ QString QVersionNumber::toString() const return version; } -#if QT_STRINGVIEW_LEVEL < 2 /*! - Constructs a QVersionNumber from a specially formatted \a string of - non-negative decimal numbers delimited by a period (\c{.}). - - Once the numerical segments have been parsed, the remainder of the string - is considered to be the suffix string. The start index of that string will be - stored in \a suffixIndex if it is not null. - - \snippet qversionnumber/main.cpp 3 - - \sa isNull() -*/ -QVersionNumber QVersionNumber::fromString(const QString &string, qsizetype *suffixIndex) -{ - return fromString(QLatin1String(string.toLatin1()), suffixIndex); -} -#endif - -/*! - \since 5.10 - \overload - - Constructs a QVersionNumber from a specially formatted \a string of - non-negative decimal numbers delimited by '.'. - - Once the numerical segments have been parsed, the remainder of the string - is considered to be the suffix string. The start index of that string will be - stored in \a suffixIndex if it is not null. - - \snippet qversionnumber/main.cpp 3 - - \sa isNull() -*/ -QVersionNumber QVersionNumber::fromString(QStringView string, qsizetype *suffixIndex) -{ - return fromString(QLatin1String(string.toLatin1()), suffixIndex); -} - -/*! - \since 5.10 - \overload + \fn QVersionNumber QVersionNumber::fromString(QAnyStringView string, qsizetype *suffixIndex) + \since 6.4 Constructs a QVersionNumber from a specially formatted \a string of non-negative decimal numbers delimited by '.'. @@ -452,9 +413,13 @@ QVersionNumber QVersionNumber::fromString(QStringView string, qsizetype *suffixI \snippet qversionnumber/main.cpp 3-latin1-1 + \note In versions prior to Qt 6.4, this function was overloaded for QString, + QLatin1String and QStringView instead, and \a suffixIndex was an \c{int*}. + \sa isNull() */ -QVersionNumber QVersionNumber::fromString(QLatin1String string, qsizetype *suffixIndex) + +static QVersionNumber from_string(QLatin1String string, qsizetype *suffixIndex) { QList<int> seg; @@ -479,6 +444,27 @@ QVersionNumber QVersionNumber::fromString(QLatin1String string, qsizetype *suffi return QVersionNumber(std::move(seg)); } +static QVersionNumber from_string(q_no_char8_t::QUtf8StringView string, qsizetype *suffixIndex) +{ + return from_string(QLatin1String(string.data(), string.size()), suffixIndex); +} + +// in qstring.cpp +extern void qt_to_latin1(uchar *dst, const char16_t *uc, qsizetype len); + +static QVersionNumber from_string(QStringView string, qsizetype *suffixIndex) +{ + QVarLengthArray<char> copy; + copy.resize(string.size()); + qt_to_latin1(reinterpret_cast<uchar*>(copy.data()), string.utf16(), string.size()); + return from_string(QLatin1String(copy.data(), copy.size()), suffixIndex); +} + +QVersionNumber QVersionNumber::fromString(QAnyStringView string, qsizetype *suffixIndex) +{ + return string.visit([=] (auto string) { return from_string(string, suffixIndex); }); +} + void QVersionNumber::SegmentStorage::setVector(int len, int maj, int min, int mic) { pointer_segments = new QList<int>; diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h index 175abe4e61..ad8367c135 100644 --- a/src/corelib/tools/qversionnumber.h +++ b/src/corelib/tools/qversionnumber.h @@ -275,13 +275,28 @@ public: [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2); [[nodiscard]] Q_CORE_EXPORT QString toString() const; -#if QT_STRINGVIEW_LEVEL < 2 - [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, qsizetype *suffixIndex = nullptr); + [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QAnyStringView string, qsizetype *suffixIndex = nullptr); + +#if QT_DEPRECATED_SINCE(6, 4) && QT_POINTER_SIZE != 4 + Q_WEAK_OVERLOAD + QT_DEPRECATED_VERSION_X_6_4("Use the 'qsizetype *suffixIndex' overload.") + [[nodiscard]] static QVersionNumber fromString(QAnyStringView string, int *suffixIndex) + { + QT_WARNING_PUSH + // fromString() writes to *n unconditionally, but GCC can't know that + QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") + qsizetype n; + auto r = fromString(string, &n); + if (suffixIndex) { + Q_ASSERT(int(n) == n); + *suffixIndex = int(n); + } + return r; + QT_WARNING_POP + } #endif - [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, qsizetype *suffixIndex = nullptr); - [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, qsizetype *suffixIndex = nullptr); -#if QT_REMOVED_SINCE(6, 4) && QT_POINTER_SIZE != 4 +#if QT_REMOVED_SINCE(6, 4) [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex); [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QLatin1String string, int *suffixIndex); [[nodiscard]] Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(QStringView string, int *suffixIndex); @@ -305,7 +320,6 @@ public: [[nodiscard]] friend bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept { return compare(lhs, rhs) != 0; } - private: #ifndef QT_NO_DATASTREAM friend Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version); diff --git a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp index 35c5dec36e..42ef770817 100644 --- a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp +++ b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp @@ -73,6 +73,7 @@ private slots: void assignment(); void fromString_data(); void fromString(); + void fromString_extra(); void toString_data(); void toString(); void isNull_data(); @@ -523,6 +524,46 @@ void tst_QVersionNumber::fromString() QCOMPARE(QVersionNumber::fromString(QLatin1String(constructionString.toLatin1())), expectedVersion); QCOMPARE(QVersionNumber::fromString(QLatin1String(constructionString.toLatin1()), &index), expectedVersion); QCOMPARE(index, suffixIndex); + +#if QT_DEPRECATED_SINCE(6, 4) + QT_WARNING_PUSH + QT_WARNING_DISABLE_DEPRECATED + // check deprecated `int *suffixIndex` overload, too + { + int i; + QCOMPARE(QVersionNumber::fromString(constructionString, &i), expectedVersion); + QCOMPARE(i, suffixIndex); + + QCOMPARE(QVersionNumber::fromString(QStringView(constructionString), &i), expectedVersion); + QCOMPARE(i, suffixIndex); + + QCOMPARE(QVersionNumber::fromString(QLatin1String(constructionString.toLatin1()), &i), expectedVersion); + QCOMPARE(i, suffixIndex); + } + QT_WARNING_POP +#endif +} + +void tst_QVersionNumber::fromString_extra() +{ + // check the overloaded fromString() functions aren't ambiguous + // when passing explicit nullptr: + { + auto v = QVersionNumber::fromString("1.2.3-rc1", nullptr); + QCOMPARE(v, QVersionNumber({1, 2, 3})); + } + { + auto v = QVersionNumber::fromString("1.2.3-rc1", 0); + QCOMPARE(v, QVersionNumber({1, 2, 3})); + } + + // check the UTF16->L1 conversion isn't doing something weird + { + qsizetype i = -1; + auto v = QVersionNumber::fromString(u"1.0ı", &i); // LATIN SMALL LETTER DOTLESS I + QCOMPARE(v, QVersionNumber(1, 0)); + QCOMPARE(i, 3); + } } void tst_QVersionNumber::toString_data() |