diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2022-07-05 19:01:08 +0200 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2022-07-29 23:04:27 +0200 |
commit | e540d4a8647c41a3e710a555f5dcc44edb7dfcb4 (patch) | |
tree | 25c6441166d1647b95e8983ac48a2204e3390fe4 /src | |
parent | 8d6b274fa4c65e87443c0fbf8425229230385405 (diff) |
QRegularExpression: introduce (global)matchView
QRegularExpression::match (and globalMatch) is currently overloaded
for QString and QStringView. This creates a subtle API asymmetry:
QRegularExpression re;
auto m1 = re.match(getQString()); // OK
auto m2 = re.match(getStdU16String()); // Dangling
This goes against our decision that every time that there's a possible
lifetime issue at play, it should be "evident". Solving the lifetime
issue here is possible, but tricky -- since QRegularExpression
is out-of-line, one needs a type-erased container for the input
string (basically, std::any) to keep it alive and so on.
Instead I went for the simpler solution: deprecate match(QStringView)
and introduce matchView(QStringView) (same for globalMatch). This
makes it clear that the call is matching over a view and therefore
users are supposed to keep the source object alive.
Drive-by, remove the documentation that says that the QString
overloads might not keep the string alive: they do and forever will.
[ChangeLog][QtCore][QRegularExpression] Added the matchView()
and globalMatchView() functions that operate on string views.
The match(QStringView) and globalMatch(QStringView) overloads
have been deprecated.
Change-Id: I054b8605c2fdea59b556dcfea8920ef4eee78ee9
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/text/qregularexpression.cpp | 62 | ||||
-rw-r--r-- | src/corelib/text/qregularexpression.h | 18 | ||||
-rw-r--r-- | src/corelib/text/qstring.cpp | 25 |
3 files changed, 78 insertions, 27 deletions
diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index a9b7f99975..f736f47059 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -1588,11 +1588,6 @@ qsizetype QRegularExpression::patternErrorOffset() const The returned QRegularExpressionMatch object contains the results of the match. - \note The data referenced by \a subject should remain valid as long - as there are QRegularExpressionMatch objects using it. At the moment - Qt makes a (shallow) copy of the data, but this behavior may change - in a future version of Qt. - \sa QRegularExpressionMatch, {normal matching} */ QRegularExpressionMatch QRegularExpression::match(const QString &subject, @@ -1610,9 +1605,26 @@ QRegularExpressionMatch QRegularExpression::match(const QString &subject, return QRegularExpressionMatch(*priv); } +#if QT_DEPRECATED_SINCE(6, 8) /*! \since 6.0 \overload + \obsolete + + Use matchView() instead. +*/ +QRegularExpressionMatch QRegularExpression::match(QStringView subjectView, + qsizetype offset, + MatchType matchType, + MatchOptions matchOptions) const +{ + return matchView(subjectView, offset, matchType, matchOptions); +} +#endif // QT_DEPRECATED_SINCE(6, 8) + +/*! + \since 6.5 + \overload Attempts to match the regular expression against the given \a subjectView string view, starting at the position \a offset inside the subject, using a @@ -1626,10 +1638,10 @@ QRegularExpressionMatch QRegularExpression::match(const QString &subject, \sa QRegularExpressionMatch, {normal matching} */ -QRegularExpressionMatch QRegularExpression::match(QStringView subjectView, - qsizetype offset, - MatchType matchType, - MatchOptions matchOptions) const +QRegularExpressionMatch QRegularExpression::matchView(QStringView subjectView, + qsizetype offset, + MatchType matchType, + MatchOptions matchOptions) const { d.data()->compilePattern(); auto priv = new QRegularExpressionMatchPrivate(*this, @@ -1650,11 +1662,6 @@ QRegularExpressionMatch QRegularExpression::match(QStringView subjectView, The returned QRegularExpressionMatchIterator is positioned before the first match result (if any). - \note The data referenced by \a subject should remain valid as long - as there are QRegularExpressionMatch objects using it. At the moment - Qt makes a (shallow) copy of the data, but this behavior may change - in a future version of Qt. - \sa QRegularExpressionMatchIterator, {global matching} */ QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QString &subject, @@ -1671,9 +1678,26 @@ QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QString &s return QRegularExpressionMatchIterator(*priv); } +#if QT_DEPRECATED_SINCE(6, 8) /*! \since 6.0 \overload + \obsolete + + Use globalMatchView() instead. +*/ +QRegularExpressionMatchIterator QRegularExpression::globalMatch(QStringView subjectView, + qsizetype offset, + MatchType matchType, + MatchOptions matchOptions) const +{ + return globalMatchView(subjectView, offset, matchType, matchOptions); +} +#endif // QT_DEPRECATED_SINCE(6, 8) + +/*! + \since 6.5 + \overload Attempts to perform a global match of the regular expression against the given \a subjectView string view, starting at the position \a offset inside the @@ -1689,16 +1713,16 @@ QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QString &s \sa QRegularExpressionMatchIterator, {global matching} */ -QRegularExpressionMatchIterator QRegularExpression::globalMatch(QStringView subjectView, - qsizetype offset, - MatchType matchType, - MatchOptions matchOptions) const +QRegularExpressionMatchIterator QRegularExpression::globalMatchView(QStringView subjectView, + qsizetype offset, + MatchType matchType, + MatchOptions matchOptions) const { QRegularExpressionMatchIteratorPrivate *priv = new QRegularExpressionMatchIteratorPrivate(*this, matchType, matchOptions, - match(subjectView, offset, matchType, matchOptions)); + matchView(subjectView, offset, matchType, matchOptions)); return QRegularExpressionMatchIterator(*priv); } diff --git a/src/corelib/text/qregularexpression.h b/src/corelib/text/qregularexpression.h index 9b7de26d07..fc0f1302e3 100644 --- a/src/corelib/text/qregularexpression.h +++ b/src/corelib/text/qregularexpression.h @@ -91,11 +91,20 @@ public: MatchType matchType = NormalMatch, MatchOptions matchOptions = NoMatchOption) const; +#if QT_DEPRECATED_SINCE(6, 8) [[nodiscard]] + QT_DEPRECATED_VERSION_X_6_8("Use matchView instead.") QRegularExpressionMatch match(QStringView subjectView, qsizetype offset = 0, MatchType matchType = NormalMatch, MatchOptions matchOptions = NoMatchOption) const; +#endif + + [[nodiscard]] + QRegularExpressionMatch matchView(QStringView subjectView, + qsizetype offset = 0, + MatchType matchType = NormalMatch, + MatchOptions matchOptions = NoMatchOption) const; [[nodiscard]] QRegularExpressionMatchIterator globalMatch(const QString &subject, @@ -103,11 +112,20 @@ public: MatchType matchType = NormalMatch, MatchOptions matchOptions = NoMatchOption) const; +#if QT_DEPRECATED_SINCE(6, 8) [[nodiscard]] + QT_DEPRECATED_VERSION_X_6_8("Use globalMatchView instead.") QRegularExpressionMatchIterator globalMatch(QStringView subjectView, qsizetype offset = 0, MatchType matchType = NormalMatch, MatchOptions matchOptions = NoMatchOption) const; +#endif + + [[nodiscard]] + QRegularExpressionMatchIterator globalMatchView(QStringView subjectView, + qsizetype offset = 0, + MatchType matchType = NormalMatch, + MatchOptions matchOptions = NoMatchOption) const; void optimize() const; diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 5fbc3c6a48..f52f7317b9 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -7690,8 +7690,9 @@ QList<QStringView> QStringView::split(QChar sep, Qt::SplitBehavior behavior, Qt: #if QT_CONFIG(regularexpression) namespace { -template<class ResultList, typename String> +template<class ResultList, typename String, typename MatchingFunction> static ResultList splitString(const String &source, const QRegularExpression &re, + MatchingFunction matchingFunction, Qt::SplitBehavior behavior) { ResultList list; @@ -7702,7 +7703,7 @@ static ResultList splitString(const String &source, const QRegularExpression &re qsizetype start = 0; qsizetype end = 0; - QRegularExpressionMatchIterator iterator = re.globalMatch(source); + QRegularExpressionMatchIterator iterator = (re.*matchingFunction)(source, 0, QRegularExpression::NormalMatch, QRegularExpression::NoMatchOption); while (iterator.hasNext()) { QRegularExpressionMatch match = iterator.next(); end = match.capturedStart(); @@ -7747,7 +7748,15 @@ static ResultList splitString(const String &source, const QRegularExpression &re */ QStringList QString::split(const QRegularExpression &re, Qt::SplitBehavior behavior) const { - return splitString<QStringList>(*this, re, behavior); +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + const auto matchingFunction = qOverload<const QString &, qsizetype, QRegularExpression::MatchType, QRegularExpression::MatchOptions>(&QRegularExpression::globalMatch); +#else + const auto matchingFunction = &QRegularExpression::globalMatch; +#endif + return splitString<QStringList>(*this, + re, + matchingFunction, + behavior); } /*! @@ -7764,7 +7773,7 @@ QStringList QString::split(const QRegularExpression &re, Qt::SplitBehavior behav */ QList<QStringView> QStringView::split(const QRegularExpression &re, Qt::SplitBehavior behavior) const { - return splitString<QList<QStringView>>(*this, re, behavior); + return splitString<QList<QStringView>>(*this, re, &QRegularExpression::globalMatchView, behavior); } #endif // QT_CONFIG(regularexpression) @@ -10793,7 +10802,7 @@ qsizetype QtPrivate::indexOf(QStringView viewHaystack, const QString *stringHays QRegularExpressionMatch match = stringHaystack ? re.match(*stringHaystack, from) - : re.match(viewHaystack, from); + : re.matchView(viewHaystack, from); if (match.hasMatch()) { const qsizetype ret = match.capturedStart(); if (rmatch) @@ -10819,7 +10828,7 @@ qsizetype QtPrivate::lastIndexOf(QStringView viewHaystack, const QString *string qsizetype endpos = (from < 0) ? (viewHaystack.size() + from + 1) : (from + 1); QRegularExpressionMatchIterator iterator = stringHaystack ? re.globalMatch(*stringHaystack) - : re.globalMatch(viewHaystack); + : re.globalMatchView(viewHaystack); qsizetype lastIndex = -1; while (iterator.hasNext()) { QRegularExpressionMatch match = iterator.next(); @@ -10849,7 +10858,7 @@ bool QtPrivate::contains(QStringView viewHaystack, const QString *stringHaystack } QRegularExpressionMatch m = stringHaystack ? re.match(*stringHaystack) - : re.match(viewHaystack); + : re.matchView(viewHaystack); bool hasMatch = m.hasMatch(); if (hasMatch && rmatch) *rmatch = std::move(m); @@ -10871,7 +10880,7 @@ qsizetype QtPrivate::count(QStringView haystack, const QRegularExpression &re) qsizetype index = -1; qsizetype len = haystack.length(); while (index <= len - 1) { - QRegularExpressionMatch match = re.match(haystack, index + 1); + QRegularExpressionMatch match = re.matchView(haystack, index + 1); if (!match.hasMatch()) break; index = match.capturedStart(); |