Make QByteArrayView's numeric conversion methods inline

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 <marten.nordheim@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Sona Kurazyan 2022-02-21 17:58:20 +01:00
parent cfe421cee2
commit 9c35ab1cc2
3 changed files with 74 additions and 81 deletions

View File

@ -3514,21 +3514,8 @@ bool QByteArray::isNull() const noexcept
return d->isNull(); 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 <typename T> static inline
T toIntegral_helper(QByteArrayView data, bool *ok, int base)
{
using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
#if defined(QT_CHECK_RANGE) #if defined(QT_CHECK_RANGE)
if (base != 0 && (base < 2 || base > 36)) { if (base != 0 && (base < 2 || base > 36)) {
qWarning("QByteArray::toIntegral: Invalid base %d", base); qWarning("QByteArray::toIntegral: Invalid base %d", base);
@ -3541,14 +3528,24 @@ T toIntegral_helper(QByteArrayView data, bool *ok, int base)
return 0; return 0;
} }
// we select the right overload by the last, unused parameter return QLocaleData::bytearrayToLongLong(data, base, ok);
Int64 val = toIntegral_helper(data, ok, base, Int64()); }
if (T(val) != val) {
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) if (ok)
*ok = false; *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 qlonglong QByteArray::toLongLong(bool *ok, int base) const
{ {
return toIntegral_helper<qlonglong>(*this, ok, base); return QtPrivate::toIntegral<qlonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
}
qlonglong QByteArrayView::toLongLong(bool *ok, int base) const
{
return toIntegral_helper<qlonglong>(*this, ok, base);
} }
/*! /*!
@ -3607,12 +3599,7 @@ qlonglong QByteArrayView::toLongLong(bool *ok, int base) const
qulonglong QByteArray::toULongLong(bool *ok, int base) const qulonglong QByteArray::toULongLong(bool *ok, int base) const
{ {
return toIntegral_helper<qulonglong>(*this, ok, base); return QtPrivate::toIntegral<qulonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
}
qulonglong QByteArrayView::toULongLong(bool *ok, int base) const
{
return toIntegral_helper<qulonglong>(*this, ok, base);
} }
/*! /*!
@ -3641,12 +3628,7 @@ qulonglong QByteArrayView::toULongLong(bool *ok, int base) const
int QByteArray::toInt(bool *ok, int base) const int QByteArray::toInt(bool *ok, int base) const
{ {
return toIntegral_helper<int>(*this, ok, base); return QtPrivate::toIntegral<int>(qToByteArrayViewIgnoringNull(*this), ok, base);
}
int QByteArrayView::toInt(bool *ok, int base) const
{
return toIntegral_helper<int>(*this, ok, base);
} }
/*! /*!
@ -3673,12 +3655,7 @@ int QByteArrayView::toInt(bool *ok, int base) const
uint QByteArray::toUInt(bool *ok, int base) const uint QByteArray::toUInt(bool *ok, int base) const
{ {
return toIntegral_helper<uint>(*this, ok, base); return QtPrivate::toIntegral<uint>(qToByteArrayViewIgnoringNull(*this), ok, base);
}
uint QByteArrayView::toUInt(bool *ok, int base) const
{
return toIntegral_helper<uint>(*this, ok, base);
} }
/*! /*!
@ -3708,12 +3685,7 @@ uint QByteArrayView::toUInt(bool *ok, int base) const
*/ */
long QByteArray::toLong(bool *ok, int base) const long QByteArray::toLong(bool *ok, int base) const
{ {
return toIntegral_helper<long>(*this, ok, base); return QtPrivate::toIntegral<long>(qToByteArrayViewIgnoringNull(*this), ok, base);
}
long QByteArrayView::toLong(bool *ok, int base) const
{
return toIntegral_helper<long>(*this, ok, base);
} }
/*! /*!
@ -3741,12 +3713,7 @@ long QByteArrayView::toLong(bool *ok, int base) const
*/ */
ulong QByteArray::toULong(bool *ok, int base) const ulong QByteArray::toULong(bool *ok, int base) const
{ {
return toIntegral_helper<ulong>(*this, ok, base); return QtPrivate::toIntegral<ulong>(qToByteArrayViewIgnoringNull(*this), ok, base);
}
ulong QByteArrayView::toULong(bool *ok, int base) const
{
return toIntegral_helper<ulong>(*this, ok, base);
} }
/*! /*!
@ -3773,12 +3740,7 @@ ulong QByteArrayView::toULong(bool *ok, int base) const
short QByteArray::toShort(bool *ok, int base) const short QByteArray::toShort(bool *ok, int base) const
{ {
return toIntegral_helper<short>(*this, ok, base); return QtPrivate::toIntegral<short>(qToByteArrayViewIgnoringNull(*this), ok, base);
}
short QByteArrayView::toShort(bool *ok, int base) const
{
return toIntegral_helper<short>(*this, ok, base);
} }
/*! /*!
@ -3805,12 +3767,7 @@ short QByteArrayView::toShort(bool *ok, int base) const
ushort QByteArray::toUShort(bool *ok, int base) const ushort QByteArray::toUShort(bool *ok, int base) const
{ {
return toIntegral_helper<ushort>(*this, ok, base); return QtPrivate::toIntegral<ushort>(qToByteArrayViewIgnoringNull(*this), ok, base);
}
ushort QByteArrayView::toUShort(bool *ok, int base) const
{
return toIntegral_helper<ushort>(*this, ok, base);
} }
/*! /*!
@ -3843,11 +3800,11 @@ double QByteArray::toDouble(bool *ok) const
return QByteArrayView(*this).toDouble(ok); return QByteArrayView(*this).toDouble(ok);
} }
double QByteArrayView::toDouble(bool *ok) const double QtPrivate::toDouble(QByteArrayView a, bool *ok)
{ {
bool nonNullOk = false; bool nonNullOk = false;
int processed = 0; 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) if (ok)
*ok = nonNullOk; *ok = nonNullOk;
return d; return d;
@ -3883,9 +3840,9 @@ float QByteArray::toFloat(bool *ok) const
return QLocaleData::convertDoubleToFloat(toDouble(ok), ok); 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);
} }
/*! /*!

View File

@ -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 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 <typename T, typename ByteArrayView,
typename = std::enable_if_t<std::is_same_v<ByteArrayView, QByteArrayView>>> static inline
T toIntegral(ByteArrayView data, bool *ok, int base)
{
auto val = [&] {
if constexpr (std::is_unsigned_v<T>)
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 } // namespace QtPrivate
/***************************************************************************** /*****************************************************************************

View File

@ -243,16 +243,26 @@ public:
// Defined in qbytearray.cpp: // Defined in qbytearray.cpp:
[[nodiscard]] QByteArrayView trimmed() const noexcept [[nodiscard]] QByteArrayView trimmed() const noexcept
{ return QtPrivate::trimmed(*this); } { return QtPrivate::trimmed(*this); }
[[nodiscard]] short toShort(bool *ok = nullptr, int base = 10) const; [[nodiscard]] short toShort(bool *ok = nullptr, int base = 10) const
[[nodiscard]] ushort toUShort(bool *ok = nullptr, int base = 10) const; { return QtPrivate::toIntegral<short>(*this, ok, base); }
[[nodiscard]] int toInt(bool *ok = nullptr, int base = 10) const; [[nodiscard]] ushort toUShort(bool *ok = nullptr, int base = 10) const
[[nodiscard]] uint toUInt(bool *ok = nullptr, int base = 10) const; { return QtPrivate::toIntegral<ushort>(*this, ok, base); }
[[nodiscard]] long toLong(bool *ok = nullptr, int base = 10) const; [[nodiscard]] int toInt(bool *ok = nullptr, int base = 10) const
[[nodiscard]] ulong toULong(bool *ok = nullptr, int base = 10) const; { return QtPrivate::toIntegral<int>(*this, ok, base); }
[[nodiscard]] qlonglong toLongLong(bool *ok = nullptr, int base = 10) const; [[nodiscard]] uint toUInt(bool *ok = nullptr, int base = 10) const
[[nodiscard]] qulonglong toULongLong(bool *ok = nullptr, int base = 10) const; { return QtPrivate::toIntegral<uint>(*this, ok, base); }
[[nodiscard]] float toFloat(bool *ok = nullptr) const; [[nodiscard]] long toLong(bool *ok = nullptr, int base = 10) const
[[nodiscard]] double toDouble(bool *ok = nullptr) const; { return QtPrivate::toIntegral<long>(*this, ok, base); }
[[nodiscard]] ulong toULong(bool *ok = nullptr, int base = 10) const
{ return QtPrivate::toIntegral<ulong>(*this, ok, base); }
[[nodiscard]] qlonglong toLongLong(bool *ok = nullptr, int base = 10) const
{ return QtPrivate::toIntegral<qlonglong>(*this, ok, base); }
[[nodiscard]] qulonglong toULongLong(bool *ok = nullptr, int base = 10) const
{ return QtPrivate::toIntegral<qulonglong>(*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 [[nodiscard]] bool startsWith(QByteArrayView other) const noexcept
{ return QtPrivate::startsWith(*this, other); } { return QtPrivate::startsWith(*this, other); }