QLatin1String, QStringView: add contains

[ChangeLog][QtCore][QLatin1String] Added contains().

[ChangeLog][QtCore][QStringView] Added contains().

Change-Id: I19fd2e155180edd8620c520f4e60a1f86f0603ac
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Anton Kudryavtsev 2019-04-11 15:57:59 +03:00 committed by Marc Mutz
parent ed99a591a8
commit 638f2749a0
5 changed files with 220 additions and 5 deletions

View File

@ -4273,7 +4273,7 @@ int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs));
}
#if QT_STRINGVIEW_LEVEL < 2
/*! \fn bool QString::contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
Returns \c true if this string contains an occurrence of the string
@ -4287,6 +4287,7 @@ int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
#endif // QT_STRINGVIEW_LEVEL < 2
/*! \fn bool QString::contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\since 5.3
@ -4305,6 +4306,7 @@ int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
character \a ch; otherwise returns \c false.
*/
#if QT_STRINGVIEW_LEVEL < 2
/*! \fn bool QString::contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\since 4.8
@ -4316,6 +4318,20 @@ int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
#endif // QT_STRINGVIEW_LEVEL < 2
/*! \fn bool QString::contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\since 5.14
\overload contains()
Returns \c true if this string contains an occurrence of the string view
\a str; otherwise returns \c false.
If \a cs is Qt::CaseSensitive (default), the search is
case sensitive; otherwise the search is case insensitive.
\sa indexOf(), count()
*/
/*! \fn bool QString::contains(const QRegExp &rx) const
@ -9530,6 +9546,21 @@ QString &QString::setRawData(const QChar *unicode, int size)
\sa QString::indexOf()
*/
/*!
\fn bool QLatin1String::contains(QStringView str, Qt::CaseSensitivity cs) const
\fn bool QLatin1String::contains(QLatin1String l1, Qt::CaseSensitivity cs) const
\fn bool QLatin1String::contains(QChar c, Qt::CaseSensitivity cs) const
\since 5.14
Returns \c true if this Latin-1 string contains an occurrence of the string-view
\a str, Latin-1 string \a l1, or character \a ch; otherwise returns \c false.
If \a cs is Qt::CaseSensitive (the default), the search is
case-sensitive; otherwise the search is case-insensitive.
\sa indexOf(), QStringView::contains(), QStringView::indexOf(), QString::indexOf()
*/
/*!
\fn QLatin1String::const_iterator QLatin1String::begin() const
\since 5.10
@ -11514,7 +11545,7 @@ bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
return qt_ends_with(*this, str, cs);
}
#if QT_STRINGVIEW_LEVEL < 2
/*! \fn bool QStringRef::contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\since 4.8
@ -11526,6 +11557,7 @@ bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
#endif // QT_STRINGVIEW_LEVEL < 2
/*! \fn bool QStringRef::contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
@ -11540,6 +11572,7 @@ bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
*/
#if QT_STRINGVIEW_LEVEL < 2
/*! \fn bool QStringRef::contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\overload contains()
\since 4.8
@ -11552,6 +11585,7 @@ bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
#endif // QT_STRINGVIEW_LEVEL < 2
/*! \fn bool QStringRef::contains(QLatin1String str, Qt::CaseSensitivity cs) const
\since 4.8
@ -11566,6 +11600,19 @@ bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
/*! \fn bool QStringRef::contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\since 5.14
\overload contains()
Returns \c true if this string reference contains an occurrence of
the string view \a str; otherwise returns \c false.
If \a cs is Qt::CaseSensitive (default), the search is
case sensitive; otherwise the search is case insensitive.
\sa indexOf(), count()
*/
static inline qsizetype qt_last_index_of(QStringView haystack, QChar needle,
qsizetype from, Qt::CaseSensitivity cs)
{

View File

@ -138,6 +138,13 @@ public:
Q_REQUIRED_RESULT inline int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return int(QtPrivate::findString(*this, from, QStringView(&c, 1), cs)); } // ### Qt6: qsize
Q_REQUIRED_RESULT bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(s, 0, cs) != -1; }
Q_REQUIRED_RESULT bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(s, 0, cs) != -1; }
Q_REQUIRED_RESULT inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(QStringView(&c, 1), 0, cs) != -1; }
using value_type = const char;
using reference = value_type&;
using const_reference = reference;
@ -224,6 +231,8 @@ bool QStringView::endsWith(QLatin1String s, Qt::CaseSensitivity cs) const noexce
{ return QtPrivate::endsWith(*this, s, cs); }
qsizetype QStringView::indexOf(QLatin1String s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
{ return QtPrivate::findString(*this, from, s, cs); }
bool QStringView::contains(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
{ return indexOf(s, 0, cs) != qsizetype(-1); }
class Q_CORE_EXPORT QString
{
@ -351,9 +360,12 @@ public:
int lastIndexOf(const QStringRef &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2
inline bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
inline bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@ -1240,14 +1252,18 @@ inline QString::const_iterator QString::cend() const
{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
inline QString::const_iterator QString::constEnd() const
{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
#if QT_STRINGVIEW_LEVEL < 2
inline bool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
inline bool QString::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
#endif
inline bool QString::contains(QLatin1String s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
inline bool QString::contains(QChar c, Qt::CaseSensitivity cs) const
{ return indexOf(c, 0, cs) != -1; }
inline bool QString::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
{ return indexOf(s, 0, cs) != -1; }
#if QT_DEPRECATED_SINCE(5, 9)
inline bool operator==(QString::Null, QString::Null) { return true; }
@ -1528,10 +1544,13 @@ public:
int lastIndexOf(QLatin1String str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(const QStringRef &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2
inline bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
inline bool contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@ -1893,13 +1912,17 @@ inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QString &s
inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef &s2)
{ return QString::localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
#if QT_STRINGVIEW_LEVEL < 2
inline bool QStringRef::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
inline bool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
#endif
inline bool QStringRef::contains(QLatin1String s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
inline bool QStringRef::contains(QChar c, Qt::CaseSensitivity cs) const
{ return indexOf(c, 0, cs) != -1; }
inline bool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
inline bool QStringRef::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
{ return indexOf(s, 0, cs) != -1; }
inline QString &QString::insert(int i, const QStringRef &s)

View File

@ -739,6 +739,21 @@ QT_BEGIN_NAMESPACE
\sa QString::indexOf()
*/
/*!
\fn bool QStringView::contains(QStringView str, Qt::CaseSensitivity cs) const
\fn bool QStringView::contains(QLatin1String l1, Qt::CaseSensitivity cs) const
\fn bool QStringView::contains(QChar c, Qt::CaseSensitivity cs) const
\since 5.14
Returns \c true if this string-view contains an occurrence of the string-view
\a str, Latin-1 string \a l1, or character \a ch; otherwise returns \c false.
If \a cs is Qt::CaseSensitive (the default), the search is
case-sensitive; otherwise the search is case-insensitive.
\sa indexOf()
*/
/*!
\fn QByteArray QStringView::toLatin1() const

View File

@ -276,6 +276,12 @@ public:
{ return QtPrivate::findString(*this, from, s, cs); }
Q_REQUIRED_RESULT inline qsizetype indexOf(QLatin1String s, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
Q_REQUIRED_RESULT bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(QStringView(&c, 1), 0, cs) != qsizetype(-1); }
Q_REQUIRED_RESULT bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(s, 0, cs) != qsizetype(-1); }
Q_REQUIRED_RESULT inline bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
Q_REQUIRED_RESULT bool isRightToLeft() const noexcept
{ return QtPrivate::isRightToLeft(*this); }

View File

@ -485,6 +485,47 @@ private Q_SLOTS:
void indexOf_QStringView_QStringRef() { indexOf_impl<QStringView, QStringRef>(); }
void indexOf_QStringView_QStringView_data() { indexOf_data(); }
void indexOf_QStringView_QStringView() { indexOf_impl<QStringView, QStringView>(); }
private:
template <typename Haystack, typename Needle> void contains_impl() const;
void contains_data();
private Q_SLOTS:
void contains_QString_QString_data() { contains_data(); }
void contains_QString_QString() { contains_impl<QString, QString>(); }
void contains_QString_QLatin1String_data() { contains_data(); }
void contains_QString_QLatin1String() { contains_impl<QString, QLatin1String>(); }
void contains_QString_QStringRef_data() { contains_data(); }
void contains_QString_QStringRef() { contains_impl<QString, QStringRef>(); }
void contains_QString_QStringView_data() { contains_data(); }
void contains_QString_QStringView() { contains_impl<QString, QStringView>(); }
void contains_QLatin1String_QString_data() { contains_data(); }
void contains_QLatin1String_QString() { contains_impl<QLatin1String, QString>(); }
void contains_QLatin1String_QLatin1String_data() { contains_data(); }
void contains_QLatin1String_QLatin1String() { contains_impl<QLatin1String, QLatin1String>(); }
void contains_QLatin1String_QStringRef_data() { contains_data(); }
void contains_QLatin1String_QStringRef() { contains_impl<QLatin1String, QStringRef>(); }
void contains_QLatin1String_QStringView_data() { contains_data(); }
void contains_QLatin1String_QStringView() { contains_impl<QLatin1String, QStringView>(); }
void contains_QStringRef_QString_data() { contains_data(); }
void contains_QStringRef_QString() { contains_impl<QStringRef, QString>(); }
void contains_QStringRef_QLatin1String_data() { contains_data(); }
void contains_QStringRef_QLatin1String() { contains_impl<QStringRef, QLatin1String>(); }
void contains_QStringRef_QStringRef_data() { contains_data(); }
void contains_QStringRef_QStringRef() { contains_impl<QStringRef, QStringRef>(); }
void contains_QStringRef_QStringView_data() { contains_data(); }
void contains_QStringRef_QStringView() { contains_impl<QStringRef, QStringView>(); }
void contains_QStringView_QString_data() { contains_data(); }
void contains_QStringView_QString() { contains_impl<QStringView, QString>(); }
void contains_QStringView_QLatin1String_data() { contains_data(); }
void contains_QStringView_QLatin1String() { contains_impl<QStringView, QLatin1String>(); }
void contains_QStringView_QStringRef_data() { contains_data(); }
void contains_QStringView_QStringRef() { contains_impl<QStringView, QStringRef>(); }
void contains_QStringView_QStringView_data() { contains_data(); }
void contains_QStringView_QStringView() { contains_impl<QStringView, QStringView>(); }
};
void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty)
@ -617,6 +658,14 @@ static QString b = QStringLiteral("b");
static QString B = QStringLiteral("B");
static QString c = QStringLiteral("c");
static QString C = QStringLiteral("C");
static QString d = QStringLiteral("d");
static QString D = QStringLiteral("D");
static QString e = QStringLiteral("e");
static QString E = QStringLiteral("E");
static QString f = QStringLiteral("f");
static QString F = QStringLiteral("F");
static QString g = QStringLiteral("g");
static QString G = QStringLiteral("G");
static QString ab = QStringLiteral("ab");
static QString aB = QStringLiteral("aB");
static QString Ab = QStringLiteral("Ab");
@ -1501,6 +1550,81 @@ void tst_QStringApiSymmetry::indexOf_impl() const
}
}
static QString ABCDEFGHIEfGEFG = QStringLiteral("ABCDEFGHIEfGEFG");
static QString EFG = QStringLiteral("EFG");
static QString efg = QStringLiteral("efg");
static QString asd = QStringLiteral("asd");
static QString asdf = QStringLiteral("asdf");
static QString Z = QStringLiteral("Z");
void tst_QStringApiSymmetry::contains_data()
{
QTest::addColumn<QString>("haystackU16");
QTest::addColumn<QLatin1String>("haystackL1");
QTest::addColumn<QString>("needleU16");
QTest::addColumn<QLatin1String>("needleL1");
QTest::addColumn<bool>("resultCS");
QTest::addColumn<bool>("resultCIS");
QTest::addRow("haystack: null, needle: null") << null << QLatin1String()
<< null << QLatin1String() << true << true;
QTest::addRow("haystack: empty, needle: null") << empty << QLatin1String("")
<< null << QLatin1String() << true << true;
QTest::addRow("haystack: a, needle: null") << a << QLatin1String("a")
<< null << QLatin1String() << true << true;
QTest::addRow("haystack: null, needle: empty") << null << QLatin1String()
<< empty << QLatin1String("") << true << true;
QTest::addRow("haystack: a, needle: empty") << a << QLatin1String("a")
<< empty << QLatin1String("") << true << true;;
QTest::addRow("haystack: empty, needle: empty") << empty << QLatin1String("")
<< empty << QLatin1String("") << true << true;
QTest::addRow("haystack: empty, needle: a") << empty << QLatin1String("")
<< a << QLatin1String("a") << false << false;
QTest::addRow("haystack: null, needle: a") << null << QLatin1String()
<< a << QLatin1String("a") << false << false;
#define ROW(h, n, cs, cis) \
QTest::addRow("haystack: %s, needle: %s", #h, #n) << h << QLatin1String(#h) \
<< n << QLatin1String(#n) \
<< cs << cis
ROW(ABCDEFGHIEfGEFG, A, true, true);
ROW(ABCDEFGHIEfGEFG, a, false, true);
ROW(ABCDEFGHIEfGEFG, Z, false, false);
ROW(ABCDEFGHIEfGEFG, EFG, true, true);
ROW(ABCDEFGHIEfGEFG, efg, false, true);
ROW(ABCDEFGHIEfGEFG, E, true, true);
ROW(ABCDEFGHIEfGEFG, e, false, true);
#undef ROW
}
template <typename Haystack, typename Needle>
void tst_QStringApiSymmetry::contains_impl() const
{
QFETCH(const QString, haystackU16);
QFETCH(const QLatin1String, haystackL1);
QFETCH(const QString, needleU16);
QFETCH(const QLatin1String, needleL1);
QFETCH(const bool, resultCS);
QFETCH(const bool, resultCIS);
const auto haystackU8 = haystackU16.toUtf8();
const auto needleU8 = needleU16.toUtf8();
const auto haystack = make<Haystack>(QStringRef(&haystackU16), haystackL1, haystackU8);
const auto needle = make<Needle>(QStringRef(&needleU16), needleL1, needleU8);
QCOMPARE(haystack.contains(needle), resultCS);
QCOMPARE(haystack.contains(needle, Qt::CaseSensitive), resultCS);
QCOMPARE(haystack.contains(needle, Qt::CaseInsensitive), resultCIS);
if (needle.size() == 1)
{
QCOMPARE(haystack.contains(needle[0]), resultCS);
QCOMPARE(haystack.contains(needle[0], Qt::CaseSensitive), resultCS);
QCOMPARE(haystack.contains(needle[0], Qt::CaseInsensitive), resultCIS);
}
}
QTEST_APPLESS_MAIN(tst_QStringApiSymmetry)