From 9c35ab1cc22f742e6f914c80baa5f365ec2d85c7 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Mon, 21 Feb 2022 17:58:20 +0100 Subject: [PATCH] Make QByteArrayView's numeric conversion methods inline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the implementations of these methods free functions in the QtPrivate namespace, so that they can be called also from QByteArrayView's corresponding inline methods. These methods were added in 6.3, so we can still make them inline without breaking BC. Fixes: QTBUG-101077 Pick-to: 6.3 Change-Id: Id50c6d4df5471127ae787a544a5651ced9aece99 Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Marc Mutz Reviewed-by: Edward Welbourne --- src/corelib/text/qbytearray.cpp | 99 +++++++------------------ src/corelib/text/qbytearrayalgorithms.h | 26 +++++++ src/corelib/text/qbytearrayview.h | 30 +++++--- 3 files changed, 74 insertions(+), 81 deletions(-) diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index d847dd4beeb..901e0fcbc1f 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -3514,21 +3514,8 @@ bool QByteArray::isNull() const noexcept return d->isNull(); } -static qlonglong toIntegral_helper(QByteArrayView data, bool *ok, int base, qlonglong) +qlonglong QtPrivate::toSignedInteger(QByteArrayView data, bool *ok, int base) { - return QLocaleData::bytearrayToLongLong(data, base, ok); -} - -static qulonglong toIntegral_helper(QByteArrayView data, bool *ok, int base, qulonglong) -{ - return QLocaleData::bytearrayToUnsLongLong(data, base, ok); -} - -template static inline -T toIntegral_helper(QByteArrayView data, bool *ok, int base) -{ - using Int64 = typename std::conditional::value, qulonglong, qlonglong>::type; - #if defined(QT_CHECK_RANGE) if (base != 0 && (base < 2 || base > 36)) { qWarning("QByteArray::toIntegral: Invalid base %d", base); @@ -3541,14 +3528,24 @@ T toIntegral_helper(QByteArrayView data, bool *ok, int base) return 0; } - // we select the right overload by the last, unused parameter - Int64 val = toIntegral_helper(data, ok, base, Int64()); - if (T(val) != val) { + return QLocaleData::bytearrayToLongLong(data, base, ok); +} + +qulonglong QtPrivate::toUnsignedInteger(QByteArrayView data, bool *ok, int base) +{ +#if defined(QT_CHECK_RANGE) + if (base != 0 && (base < 2 || base > 36)) { + qWarning("QByteArray::toIntegral: Invalid base %d", base); + base = 10; + } +#endif + if (data.isEmpty()) { if (ok) *ok = false; - val = 0; + return 0; } - return T(val); + + return QLocaleData::bytearrayToUnsLongLong(data, base, ok); } /*! @@ -3575,12 +3572,7 @@ T toIntegral_helper(QByteArrayView data, bool *ok, int base) qlonglong QByteArray::toLongLong(bool *ok, int base) const { - return toIntegral_helper(*this, ok, base); -} - -qlonglong QByteArrayView::toLongLong(bool *ok, int base) const -{ - return toIntegral_helper(*this, ok, base); + return QtPrivate::toIntegral(qToByteArrayViewIgnoringNull(*this), ok, base); } /*! @@ -3607,12 +3599,7 @@ qlonglong QByteArrayView::toLongLong(bool *ok, int base) const qulonglong QByteArray::toULongLong(bool *ok, int base) const { - return toIntegral_helper(*this, ok, base); -} - -qulonglong QByteArrayView::toULongLong(bool *ok, int base) const -{ - return toIntegral_helper(*this, ok, base); + return QtPrivate::toIntegral(qToByteArrayViewIgnoringNull(*this), ok, base); } /*! @@ -3641,12 +3628,7 @@ qulonglong QByteArrayView::toULongLong(bool *ok, int base) const int QByteArray::toInt(bool *ok, int base) const { - return toIntegral_helper(*this, ok, base); -} - -int QByteArrayView::toInt(bool *ok, int base) const -{ - return toIntegral_helper(*this, ok, base); + return QtPrivate::toIntegral(qToByteArrayViewIgnoringNull(*this), ok, base); } /*! @@ -3673,12 +3655,7 @@ int QByteArrayView::toInt(bool *ok, int base) const uint QByteArray::toUInt(bool *ok, int base) const { - return toIntegral_helper(*this, ok, base); -} - -uint QByteArrayView::toUInt(bool *ok, int base) const -{ - return toIntegral_helper(*this, ok, base); + return QtPrivate::toIntegral(qToByteArrayViewIgnoringNull(*this), ok, base); } /*! @@ -3708,12 +3685,7 @@ uint QByteArrayView::toUInt(bool *ok, int base) const */ long QByteArray::toLong(bool *ok, int base) const { - return toIntegral_helper(*this, ok, base); -} - -long QByteArrayView::toLong(bool *ok, int base) const -{ - return toIntegral_helper(*this, ok, base); + return QtPrivate::toIntegral(qToByteArrayViewIgnoringNull(*this), ok, base); } /*! @@ -3741,12 +3713,7 @@ long QByteArrayView::toLong(bool *ok, int base) const */ ulong QByteArray::toULong(bool *ok, int base) const { - return toIntegral_helper(*this, ok, base); -} - -ulong QByteArrayView::toULong(bool *ok, int base) const -{ - return toIntegral_helper(*this, ok, base); + return QtPrivate::toIntegral(qToByteArrayViewIgnoringNull(*this), ok, base); } /*! @@ -3773,12 +3740,7 @@ ulong QByteArrayView::toULong(bool *ok, int base) const short QByteArray::toShort(bool *ok, int base) const { - return toIntegral_helper(*this, ok, base); -} - -short QByteArrayView::toShort(bool *ok, int base) const -{ - return toIntegral_helper(*this, ok, base); + return QtPrivate::toIntegral(qToByteArrayViewIgnoringNull(*this), ok, base); } /*! @@ -3805,12 +3767,7 @@ short QByteArrayView::toShort(bool *ok, int base) const ushort QByteArray::toUShort(bool *ok, int base) const { - return toIntegral_helper(*this, ok, base); -} - -ushort QByteArrayView::toUShort(bool *ok, int base) const -{ - return toIntegral_helper(*this, ok, base); + return QtPrivate::toIntegral(qToByteArrayViewIgnoringNull(*this), ok, base); } /*! @@ -3843,11 +3800,11 @@ double QByteArray::toDouble(bool *ok) const return QByteArrayView(*this).toDouble(ok); } -double QByteArrayView::toDouble(bool *ok) const +double QtPrivate::toDouble(QByteArrayView a, bool *ok) { bool nonNullOk = false; int processed = 0; - double d = qt_asciiToDouble(data(), size(), nonNullOk, processed, WhitespacesAllowed); + double d = qt_asciiToDouble(a.data(), a.size(), nonNullOk, processed, WhitespacesAllowed); if (ok) *ok = nonNullOk; return d; @@ -3883,9 +3840,9 @@ float QByteArray::toFloat(bool *ok) const return QLocaleData::convertDoubleToFloat(toDouble(ok), ok); } -float QByteArrayView::toFloat(bool *ok) const +float QtPrivate::toFloat(QByteArrayView a, bool *ok) { - return QLocaleData::convertDoubleToFloat(toDouble(ok), ok); + return QLocaleData::convertDoubleToFloat(a.toDouble(ok), ok); } /*! diff --git a/src/corelib/text/qbytearrayalgorithms.h b/src/corelib/text/qbytearrayalgorithms.h index b669f065b9e..badaf4f381a 100644 --- a/src/corelib/text/qbytearrayalgorithms.h +++ b/src/corelib/text/qbytearrayalgorithms.h @@ -76,6 +76,32 @@ qsizetype count(QByteArrayView haystack, QByteArrayView needle) noexcept; [[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isValidUtf8(QByteArrayView s) noexcept; +[[nodiscard]] Q_CORE_EXPORT double toDouble(QByteArrayView a, bool *ok); +[[nodiscard]] Q_CORE_EXPORT float toFloat(QByteArrayView a, bool *ok); +[[nodiscard]] Q_CORE_EXPORT qlonglong toSignedInteger(QByteArrayView data, bool *ok, int base); +[[nodiscard]] Q_CORE_EXPORT qulonglong toUnsignedInteger(QByteArrayView data, bool *ok, int base); + +// QByteArrayView has incomplete type here, and we can't include qbytearrayview.h, +// since it includes qbytearrayalgorithms.h. Use the ByteArrayView template type as +// a workaround. +template >> static inline +T toIntegral(ByteArrayView data, bool *ok, int base) +{ + auto val = [&] { + if constexpr (std::is_unsigned_v) + return toUnsignedInteger(data, ok, base); + else + return toSignedInteger(data, ok, base); + }(); + if (T(val) != val) { + if (ok) + *ok = false; + val = 0; + } + return T(val); +} + } // namespace QtPrivate /***************************************************************************** diff --git a/src/corelib/text/qbytearrayview.h b/src/corelib/text/qbytearrayview.h index 11db03c62fe..40205cae9c6 100644 --- a/src/corelib/text/qbytearrayview.h +++ b/src/corelib/text/qbytearrayview.h @@ -243,16 +243,26 @@ public: // Defined in qbytearray.cpp: [[nodiscard]] QByteArrayView trimmed() const noexcept { return QtPrivate::trimmed(*this); } - [[nodiscard]] short toShort(bool *ok = nullptr, int base = 10) const; - [[nodiscard]] ushort toUShort(bool *ok = nullptr, int base = 10) const; - [[nodiscard]] int toInt(bool *ok = nullptr, int base = 10) const; - [[nodiscard]] uint toUInt(bool *ok = nullptr, int base = 10) const; - [[nodiscard]] long toLong(bool *ok = nullptr, int base = 10) const; - [[nodiscard]] ulong toULong(bool *ok = nullptr, int base = 10) const; - [[nodiscard]] qlonglong toLongLong(bool *ok = nullptr, int base = 10) const; - [[nodiscard]] qulonglong toULongLong(bool *ok = nullptr, int base = 10) const; - [[nodiscard]] float toFloat(bool *ok = nullptr) const; - [[nodiscard]] double toDouble(bool *ok = nullptr) const; + [[nodiscard]] short toShort(bool *ok = nullptr, int base = 10) const + { return QtPrivate::toIntegral(*this, ok, base); } + [[nodiscard]] ushort toUShort(bool *ok = nullptr, int base = 10) const + { return QtPrivate::toIntegral(*this, ok, base); } + [[nodiscard]] int toInt(bool *ok = nullptr, int base = 10) const + { return QtPrivate::toIntegral(*this, ok, base); } + [[nodiscard]] uint toUInt(bool *ok = nullptr, int base = 10) const + { return QtPrivate::toIntegral(*this, ok, base); } + [[nodiscard]] long toLong(bool *ok = nullptr, int base = 10) const + { return QtPrivate::toIntegral(*this, ok, base); } + [[nodiscard]] ulong toULong(bool *ok = nullptr, int base = 10) const + { return QtPrivate::toIntegral(*this, ok, base); } + [[nodiscard]] qlonglong toLongLong(bool *ok = nullptr, int base = 10) const + { return QtPrivate::toIntegral(*this, ok, base); } + [[nodiscard]] qulonglong toULongLong(bool *ok = nullptr, int base = 10) const + { return QtPrivate::toIntegral(*this, ok, base); } + [[nodiscard]] float toFloat(bool *ok = nullptr) const + { return QtPrivate::toFloat(*this, ok); } + [[nodiscard]] double toDouble(bool *ok = nullptr) const + { return QtPrivate::toDouble(*this, ok); } [[nodiscard]] bool startsWith(QByteArrayView other) const noexcept { return QtPrivate::startsWith(*this, other); }