QLocale: Added QStringRef overloads to toInt(), toUInt(), etc...

Added the following function overloads to QLocale: toShort, toUShort,
toInt, toUInt, toLong, toULong, toLongLong, toULongLong, toFloat, and
toDouble.

Change-Id: I8cd90ca08b88338b08a73a72492f4c91c4f46ea4
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Keith Gardner 2013-02-02 13:37:31 -06:00 committed by The Qt Project
parent 3654a4a3c1
commit cfc09b6564
4 changed files with 309 additions and 2 deletions

View File

@ -1326,6 +1326,224 @@ double QLocale::toDouble(const QString &s, bool *ok) const
return d->stringToDouble(s, ok, mode);
}
/*!
Returns the short int represented by the localized string \a s.
If the conversion fails the function returns 0.
If \a ok is not null, failure is reported by setting *ok to false, and
success by setting *ok to true.
This function ignores leading and trailing whitespace.
\sa toUShort(), toString()
\since 5.1
*/
short QLocale::toShort(const QStringRef &s, bool *ok) const
{
qlonglong i = toLongLong(s, ok);
if (i < SHRT_MIN || i > SHRT_MAX) {
if (ok)
*ok = false;
return 0;
}
return short(i);
}
/*!
Returns the unsigned short int represented by the localized string \a s.
If the conversion fails the function returns 0.
If \a ok is not null, failure is reported by setting *ok to false, and
success by setting *ok to true.
This function ignores leading and trailing whitespace.
\sa toShort(), toString()
\since 5.1
*/
ushort QLocale::toUShort(const QStringRef &s, bool *ok) const
{
qulonglong i = toULongLong(s, ok);
if (i > USHRT_MAX) {
if (ok)
*ok = false;
return 0;
}
return ushort(i);
}
/*!
Returns the int represented by the localized string \a s.
If the conversion fails the function returns 0.
If \a ok is not null, failure is reported by setting *ok to false, and
success by setting *ok to true.
This function ignores leading and trailing whitespace.
\sa toUInt(), toString()
\since 5.1
*/
int QLocale::toInt(const QStringRef &s, bool *ok) const
{
qlonglong i = toLongLong(s, ok);
if (i < INT_MIN || i > INT_MAX) {
if (ok)
*ok = false;
return 0;
}
return int(i);
}
/*!
Returns the unsigned int represented by the localized string \a s.
If the conversion fails the function returns 0.
If \a ok is not null, failure is reported by setting *ok to false, and
success by setting *ok to true.
This function ignores leading and trailing whitespace.
\sa toInt(), toString()
\since 5.1
*/
uint QLocale::toUInt(const QStringRef &s, bool *ok) const
{
qulonglong i = toULongLong(s, ok);
if (i > UINT_MAX) {
if (ok)
*ok = false;
return 0;
}
return uint(i);
}
/*!
Returns the long long int represented by the localized string \a s.
If the conversion fails the function returns 0.
If \a ok is not null, failure is reported by setting *ok to false, and
success by setting *ok to true.
This function ignores leading and trailing whitespace.
\sa toInt(), toULongLong(), toDouble(), toString()
\since 5.1
*/
qlonglong QLocale::toLongLong(const QStringRef &s, bool *ok) const
{
QLocalePrivate::GroupSeparatorMode mode
= d->m_numberOptions & RejectGroupSeparator
? QLocalePrivate::FailOnGroupSeparators
: QLocalePrivate::ParseGroupSeparators;
return d->stringToLongLong(s, 10, ok, mode);
}
/*!
Returns the unsigned long long int represented by the localized
string \a s.
If the conversion fails the function returns 0.
If \a ok is not null, failure is reported by setting *ok to false, and
success by setting *ok to true.
This function ignores leading and trailing whitespace.
\sa toLongLong(), toInt(), toDouble(), toString()
\since 5.1
*/
qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const
{
QLocalePrivate::GroupSeparatorMode mode
= d->m_numberOptions & RejectGroupSeparator
? QLocalePrivate::FailOnGroupSeparators
: QLocalePrivate::ParseGroupSeparators;
return d->stringToUnsLongLong(s, 10, ok, mode);
}
/*!
Returns the float represented by the localized string \a s, or 0.0
if the conversion failed.
If \a ok is not null, reports failure by setting
*ok to false and success by setting *ok to true.
This function ignores leading and trailing whitespace.
\sa toDouble(), toInt(), toString()
\since 5.1
*/
float QLocale::toFloat(const QStringRef &s, bool *ok) const
{
bool myOk;
double d = toDouble(s, &myOk);
if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
if (ok)
*ok = false;
return 0.0;
}
if (ok)
*ok = true;
return float(d);
}
/*!
Returns the double represented by the localized string \a s, or
0.0 if the conversion failed.
If \a ok is not null, reports failure by setting
*ok to false and success by setting *ok to true.
Unlike QString::toDouble(), this function does not fall back to
the "C" locale if the string cannot be interpreted in this
locale.
\snippet code/src_corelib_tools_qlocale.cpp 3
Notice that the last conversion returns 1234.0, because '.' is the
thousands group separator in the German locale.
This function ignores leading and trailing whitespace.
\sa toFloat(), toInt(), toString()
\since 5.1
*/
double QLocale::toDouble(const QStringRef &s, bool *ok) const
{
QLocalePrivate::GroupSeparatorMode mode
= d->m_numberOptions & RejectGroupSeparator
? QLocalePrivate::FailOnGroupSeparators
: QLocalePrivate::ParseGroupSeparators;
return d->stringToDouble(s, ok, mode);
}
/*!
Returns a localized string representation of \a i.
@ -3098,6 +3316,64 @@ qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base,
return bytearrayToUnsLongLong(buff.constData(), base, ok);
}
double QLocalePrivate::stringToDouble(const QStringRef &number, bool *ok,
GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
QStringRef trimmedNumber;
// Do not use the ternary operator - triggers msvc2012 bug in optimized builds
if (group().unicode() == 0xa0)
trimmedNumber = number.trimmed();
else
trimmedNumber = number;
if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0.0;
}
return bytearrayToDouble(buff.constData(), ok);
}
qlonglong QLocalePrivate::stringToLongLong(const QStringRef &number, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
QStringRef trimmedNumber;
// Do not use the ternary operator - triggers msvc2012 bug in optimized builds
if (group().unicode() == 0xa0)
trimmedNumber = number.trimmed();
else
trimmedNumber = number;
if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0;
}
return bytearrayToLongLong(buff.constData(), base, ok);
}
qulonglong QLocalePrivate::stringToUnsLongLong(const QStringRef &number, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
QStringRef trimmedNumber;
// Do not use the ternary operator - triggers msvc2012 bug in optimized builds
if (group().unicode() == 0xa0)
trimmedNumber = number.trimmed();
else
trimmedNumber = number;
if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0;
}
return bytearrayToUnsLongLong(buff.constData(), base, ok);
}
double QLocalePrivate::bytearrayToDouble(const char *num, bool *ok, bool *overflow)
{

View File

@ -67,6 +67,7 @@ class Q_CORE_EXPORT QLocale
Q_ENUMS(Country)
Q_ENUMS(MeasurementSystem)
friend class QString;
friend class QStringRef;
friend class QByteArray;
friend class QIntValidator;
friend class QDoubleValidatorPrivate;
@ -710,6 +711,15 @@ public:
float toFloat(const QString &s, bool *ok = 0) const;
double toDouble(const QString &s, bool *ok = 0) const;
short toShort(const QStringRef &s, bool *ok = 0) const;
ushort toUShort(const QStringRef &s, bool *ok = 0) const;
int toInt(const QStringRef &s, bool *ok = 0) const;
uint toUInt(const QStringRef &s, bool *ok = 0) const;
qlonglong toLongLong(const QStringRef &s, bool *ok = 0) const;
qulonglong toULongLong(const QStringRef &s, bool *ok = 0) const;
float toFloat(const QStringRef &s, bool *ok = 0) const;
double toDouble(const QStringRef &s, bool *ok = 0) const;
QString toString(qlonglong i) const;
QString toString(qulonglong i) const;
inline QString toString(short i) const;

View File

@ -311,6 +311,10 @@ public:
qint64 stringToLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
quint64 stringToUnsLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
double stringToDouble(const QStringRef &num, bool *ok, GroupSeparatorMode group_sep_mode) const;
qint64 stringToLongLong(const QStringRef &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
quint64 stringToUnsLongLong(const QStringRef &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
static double bytearrayToDouble(const char *num, bool *ok, bool *overflow = 0);
static qint64 bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow = 0);

View File

@ -712,6 +712,7 @@ void tst_QLocale::double_conversion()
QFETCH(QString, num_str);
QFETCH(bool, good);
QFETCH(double, num);
QStringRef num_strRef = num_str.leftRef(-1);
QLocale locale(locale_name);
QCOMPARE(locale.name(), locale_name);
@ -726,6 +727,16 @@ void tst_QLocale::double_conversion()
diff = -diff;
QVERIFY(diff <= MY_DOUBLE_EPSILON);
}
d = locale.toDouble(num_strRef, &ok);
QCOMPARE(ok, good);
if (ok) {
double diff = d - num;
if (diff < 0)
diff = -diff;
QVERIFY(diff <= MY_DOUBLE_EPSILON);
}
}
void tst_QLocale::long_long_conversion_data()
@ -787,6 +798,7 @@ void tst_QLocale::long_long_conversion()
QFETCH(QString, num_str);
QFETCH(bool, good);
QFETCH(qlonglong, num);
QStringRef num_strRef = num_str.leftRef(-1);
QLocale locale(locale_name);
QCOMPARE(locale.name(), locale_name);
@ -795,9 +807,14 @@ void tst_QLocale::long_long_conversion()
qlonglong l = locale.toLongLong(num_str, &ok);
QCOMPARE(ok, good);
if (ok) {
if (ok)
QCOMPARE(l, num);
l = locale.toLongLong(num_strRef, &ok);
QCOMPARE(ok, good);
if (ok)
QCOMPARE(l, num);
}
}
void tst_QLocale::long_long_conversion_extra()