Implement date-time fromString(QStringView...) methods

Inline the QString versions. One const QString & variant remains in
each case: the date-time parser keeps a copy of the string it's been
given, so the methods calling it have a hybrid method taking the
string as the text to parse along with a view as the format. This
avoids copying the string when the caller has an actual QString to
pass in; the version with QStringView for both parameters has to
toString() the text to be parsed, at some point on the way into the
parser, but we can avoid that in the QString-accepting ones.

Fixes: QTBUG-86172
Change-Id: I6a4390df90945af74a5eac2f0a752febd925ad62
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2020-09-18 16:49:21 +02:00
parent 3929fd3c56
commit 0ad96eac38
2 changed files with 98 additions and 23 deletions

View File

@ -1453,6 +1453,8 @@ ParsedInt readInt(QStringView text)
} }
/*! /*!
\fn QDate QDate::fromString(const QString &string, Qt::DateFormat format)
Returns the QDate represented by the \a string, using the Returns the QDate represented by the \a string, using the
\a format given, or an invalid date if the string cannot be \a format given, or an invalid date if the string cannot be
parsed. parsed.
@ -1463,7 +1465,11 @@ ParsedInt readInt(QStringView text)
\sa toString(), QLocale::toDate() \sa toString(), QLocale::toDate()
*/ */
QDate QDate::fromString(const QString &string, Qt::DateFormat format) /*!
\overload
\since 6.0
*/
QDate QDate::fromString(QStringView string, Qt::DateFormat format)
{ {
if (string.isEmpty()) if (string.isEmpty())
return QDate(); return QDate();
@ -1473,7 +1479,7 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
return rfcDateImpl(string).date; return rfcDateImpl(string).date;
default: default:
case Qt::TextDate: { case Qt::TextDate: {
auto parts = QStringView{string}.split(u' ', Qt::SkipEmptyParts); auto parts = string.split(u' ', Qt::SkipEmptyParts);
if (parts.count() != 4) if (parts.count() != 4)
return QDate(); return QDate();
@ -1494,10 +1500,9 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
// Semi-strict parsing, must be long enough and have punctuators as separators // Semi-strict parsing, must be long enough and have punctuators as separators
if (string.size() >= 10 && string.at(4).isPunct() && string.at(7).isPunct() if (string.size() >= 10 && string.at(4).isPunct() && string.at(7).isPunct()
&& (string.size() == 10 || !string.at(10).isDigit())) { && (string.size() == 10 || !string.at(10).isDigit())) {
QStringView view(string); const ParsedInt year = readInt(string.mid(0, 4));
const ParsedInt year = readInt(view.mid(0, 4)); const ParsedInt month = readInt(string.mid(5, 2));
const ParsedInt month = readInt(view.mid(5, 2)); const ParsedInt day = readInt(string.mid(8, 2));
const ParsedInt day = readInt(view.mid(8, 2));
if (year.ok && year.value > 0 && year.value <= 9999 && month.ok && day.ok) if (year.ok && year.value > 0 && year.value <= 9999 && month.ok && day.ok)
return QDate(year.value, month.value, day.value); return QDate(year.value, month.value, day.value);
} }
@ -1571,7 +1576,17 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
QLocale::toDate() QLocale::toDate()
*/ */
QDate QDate::fromString(const QString &string, const QString &format, QCalendar cal) /*!
\fn QDate QDate::fromString(QStringView string, QStringView format, QCalendar cal)
\overload
\since 6.0
*/
/*!
\overload
\since 6.0
*/
QDate QDate::fromString(const QString &string, QStringView format, QCalendar cal)
{ {
QDate date; QDate date;
#if QT_CONFIG(datetimeparser) #if QT_CONFIG(datetimeparser)
@ -2180,12 +2195,19 @@ static QTime fromIsoTimeString(QStringView string, Qt::DateFormat format, bool *
} }
/*! /*!
\fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)
Returns the time represented in the \a string as a QTime using the Returns the time represented in the \a string as a QTime using the
\a format given, or an invalid time if this is not possible. \a format given, or an invalid time if this is not possible.
\sa toString(), QLocale::toTime() \sa toString(), QLocale::toTime()
*/ */
QTime QTime::fromString(const QString &string, Qt::DateFormat format)
/*!
\overload
\since 6.0
*/
QTime QTime::fromString(QStringView string, Qt::DateFormat format)
{ {
if (string.isEmpty()) if (string.isEmpty())
return QTime(); return QTime();
@ -2197,11 +2219,13 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
case Qt::ISODateWithMs: case Qt::ISODateWithMs:
case Qt::TextDate: case Qt::TextDate:
default: default:
return fromIsoTimeString(QStringView(string), format, nullptr); return fromIsoTimeString(string, format, nullptr);
} }
} }
/*! /*!
\fn QTime QTime::fromString(const QString &string, const QString &format)
Returns the QTime represented by the \a string, using the \a Returns the QTime represented by the \a string, using the \a
format given, or an invalid time if the string cannot be parsed. format given, or an invalid time if the string cannot be parsed.
@ -2261,7 +2285,17 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
QLocale::toTime() QLocale::toTime()
*/ */
QTime QTime::fromString(const QString &string, const QString &format) /*!
\fn QTime QTime::fromString(QStringView string, QStringView format)
\overload
\since 6.0
*/
/*!
\overload
\since 6.0
*/
QTime QTime::fromString(const QString &string, QStringView format)
{ {
QTime time; QTime time;
#if QT_CONFIG(datetimeparser) #if QT_CONFIG(datetimeparser)
@ -2275,7 +2309,6 @@ QTime QTime::fromString(const QString &string, const QString &format)
#endif #endif
return time; return time;
} }
#endif // datestring #endif // datestring
@ -4651,6 +4684,8 @@ QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone)
#if QT_CONFIG(datestring) // depends on, so implies, textdate #if QT_CONFIG(datestring) // depends on, so implies, textdate
/*! /*!
\fn QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
Returns the QDateTime represented by the \a string, using the Returns the QDateTime represented by the \a string, using the
\a format given, or an invalid datetime if this is not possible. \a format given, or an invalid datetime if this is not possible.
@ -4659,7 +4694,12 @@ QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone)
\sa toString(), QLocale::toDateTime() \sa toString(), QLocale::toDateTime()
*/ */
QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
/*!
\overload
\since 6.0
*/
QDateTime QDateTime::fromString(QStringView string, Qt::DateFormat format)
{ {
if (string.isEmpty()) if (string.isEmpty())
return QDateTime(); return QDateTime();
@ -4688,7 +4728,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
return date.startOfDay(); return date.startOfDay();
Qt::TimeSpec spec = Qt::LocalTime; Qt::TimeSpec spec = Qt::LocalTime;
QStringView isoString = QStringView(string).mid(10); // trim "yyyy-MM-dd" QStringView isoString = string.mid(10); // trim "yyyy-MM-dd"
// Must be left with T (or space) and at least one digit for the hour: // Must be left with T (or space) and at least one digit for the hour:
if (isoString.size() < 2 if (isoString.size() < 2
@ -4738,7 +4778,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
return QDateTime(date, time, spec, offset); return QDateTime(date, time, spec, offset);
} }
case Qt::TextDate: { case Qt::TextDate: {
QList<QStringView> parts = QStringView { string }.split(u' ', Qt::SkipEmptyParts); QList<QStringView> parts = string.split(u' ', Qt::SkipEmptyParts);
if ((parts.count() < 5) || (parts.count() > 6)) if ((parts.count() < 5) || (parts.count() > 6))
return QDateTime(); return QDateTime();
@ -4850,6 +4890,8 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
} }
/*! /*!
\fn QDateTime QDateTime::fromString(const QString &string, const QString &format, QCalendar cal)
Returns the QDateTime represented by the \a string, using the \a Returns the QDateTime represented by the \a string, using the \a
format given, or an invalid datetime if the string cannot be parsed. format given, or an invalid datetime if the string cannot be parsed.
@ -4908,7 +4950,17 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
QLocale::toDateTime() QLocale::toDateTime()
*/ */
QDateTime QDateTime::fromString(const QString &string, const QString &format, QCalendar cal) /*!
\fn QDateTime QDateTime::fromString(QStringView string, QStringView format, QCalendar cal)
\overload
\since 6.0
*/
/*!
\overload
\since 6.0
*/
QDateTime QDateTime::fromString(const QString &string, QStringView format, QCalendar cal)
{ {
#if QT_CONFIG(datetimeparser) #if QT_CONFIG(datetimeparser)
QDateTime datetime; QDateTime datetime;

View File

@ -126,11 +126,16 @@ public:
static QDate currentDate(); static QDate currentDate();
#if QT_CONFIG(datestring) #if QT_CONFIG(datestring)
static QDate fromString(QStringView s, Qt::DateFormat f = Qt::TextDate); static QDate fromString(QStringView string, Qt::DateFormat format = Qt::TextDate);
static QDate fromString(QStringView s, QStringView format, QCalendar cal = QCalendar()); static QDate fromString(QStringView string, QStringView format, QCalendar cal = QCalendar())
{ return fromString(string.toString(), format, cal); }
static QDate fromString(const QString &string, QStringView format, QCalendar cal = QCalendar());
# if QT_STRINGVIEW_LEVEL < 2 # if QT_STRINGVIEW_LEVEL < 2
static QDate fromString(const QString &s, Qt::DateFormat f = Qt::TextDate); static QDate fromString(const QString &string, Qt::DateFormat format = Qt::TextDate)
static QDate fromString(const QString &s, const QString &format, QCalendar cal = QCalendar()); { return fromString(qToStringViewIgnoringNull(string), format); }
static QDate fromString(const QString &string, const QString &format,
QCalendar cal = QCalendar())
{ return fromString(string, qToStringViewIgnoringNull(format), cal); }
# endif # endif
#endif #endif
static bool isValid(int y, int m, int d); static bool isValid(int y, int m, int d);
@ -200,8 +205,16 @@ public:
static QTime currentTime(); static QTime currentTime();
#if QT_CONFIG(datestring) #if QT_CONFIG(datestring)
static QTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate); static QTime fromString(QStringView string, Qt::DateFormat format = Qt::TextDate);
static QTime fromString(const QString &s, const QString &format); static QTime fromString(QStringView string, QStringView format)
{ return fromString(string.toString(), format); }
static QTime fromString(const QString &string, QStringView format);
# if QT_STRINGVIEW_LEVEL < 2
static QTime fromString(const QString &string, Qt::DateFormat format = Qt::TextDate)
{ return fromString(qToStringViewIgnoringNull(string), format); }
static QTime fromString(const QString &string, const QString &format)
{ return fromString(string, qToStringViewIgnoringNull(format)); }
# endif
#endif #endif
static bool isValid(int h, int m, int s, int ms = 0); static bool isValid(int h, int m, int s, int ms = 0);
@ -338,9 +351,19 @@ public:
static QDateTime currentDateTime(); static QDateTime currentDateTime();
static QDateTime currentDateTimeUtc(); static QDateTime currentDateTimeUtc();
#if QT_CONFIG(datestring) #if QT_CONFIG(datestring)
static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate); static QDateTime fromString(QStringView string, Qt::DateFormat format = Qt::TextDate);
static QDateTime fromString(const QString &s, const QString &format, static QDateTime fromString(QStringView string, QStringView format,
QCalendar cal = QCalendar())
{ return fromString(string.toString(), format, cal); }
static QDateTime fromString(const QString &string, QStringView format,
QCalendar cal = QCalendar()); QCalendar cal = QCalendar());
# if QT_STRINGVIEW_LEVEL < 2
static QDateTime fromString(const QString &string, Qt::DateFormat format = Qt::TextDate)
{ return fromString(qToStringViewIgnoringNull(string), format); }
static QDateTime fromString(const QString &string, const QString &format,
QCalendar cal = QCalendar())
{ return fromString(string, qToStringViewIgnoringNull(format), cal); }
# endif
#endif #endif
static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec = Qt::LocalTime, static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec = Qt::LocalTime,