diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index d847dd4bee..901e0fcbc1 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 b669f065b9..badaf4f381 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 11db03c62f..40205cae9c 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); }