Make QStringMatcher ready for Qt 6

Use qsizetype for string indices everywhere.
Clean up the data structures and remove some Qt 3 or Qt 4
left-overs. This reduces the size of the QStringMatcher from
1056 to 288 bytes.

Change-Id: Icc351da8e3aad10a6c940196f52c39f8d2f5bf80
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Lars Knoll 2020-08-27 09:19:21 +02:00
parent c93b91c766
commit fae4f80ecc
2 changed files with 31 additions and 48 deletions

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2019 Mail.ru Group. ** Copyright (C) 2019 Mail.ru Group.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
@ -46,7 +46,7 @@ static void bm_init_skiptable(QStringView needle, uchar *skiptable, Qt::CaseSens
{ {
const char16_t *uc = needle.utf16(); const char16_t *uc = needle.utf16();
const qsizetype len = needle.size(); const qsizetype len = needle.size();
int l = int(qMin(len, qsizetype(255))); qsizetype l = qMin(len, qsizetype(255));
memset(skiptable, l, 256 * sizeof(uchar)); memset(skiptable, l, 256 * sizeof(uchar));
uc += len - l; uc += len - l;
if (cs == Qt::CaseSensitive) { if (cs == Qt::CaseSensitive) {
@ -130,7 +130,7 @@ static inline qsizetype bm_find(QStringView haystack, qsizetype index, QStringVi
void QStringMatcher::updateSkipTable() void QStringMatcher::updateSkipTable()
{ {
bm_init_skiptable(p.sv, p.q_skiptable, q_cs); bm_init_skiptable(q_sv, q_skiptable, q_cs);
} }
/*! /*!
@ -156,15 +156,11 @@ void QStringMatcher::updateSkipTable()
\sa QString, QByteArrayMatcher, QRegularExpression \sa QString, QByteArrayMatcher, QRegularExpression
*/ */
/*! /*! \fn QStringMatcher::QStringMatcher()
Constructs an empty string matcher that won't match anything. Constructs an empty string matcher that won't match anything.
Call setPattern() to give it a pattern to match. Call setPattern() to give it a pattern to match.
*/ */
QStringMatcher::QStringMatcher()
: d_ptr(nullptr), q_cs(Qt::CaseSensitive)
{
memset(q_data, 0, sizeof(q_data));
}
/*! /*!
Constructs a string matcher that will search for \a pattern, with Constructs a string matcher that will search for \a pattern, with
@ -173,23 +169,19 @@ QStringMatcher::QStringMatcher()
Call indexIn() to perform a search. Call indexIn() to perform a search.
*/ */
QStringMatcher::QStringMatcher(const QString &pattern, Qt::CaseSensitivity cs) QStringMatcher::QStringMatcher(const QString &pattern, Qt::CaseSensitivity cs)
: d_ptr(nullptr), q_pattern(pattern), q_cs(cs) : d_ptr(nullptr), q_cs(cs), q_pattern(pattern)
{ {
p.sv = q_pattern; q_sv = q_pattern;
updateSkipTable(); updateSkipTable();
} }
/*! /*!
\fn QStringMatcher::QStringMatcher(const QChar *uc, int length, Qt::CaseSensitivity cs) \fn QStringMatcher::QStringMatcher(const QChar *uc, qsizetype length, Qt::CaseSensitivity cs)
\since 4.5 \since 4.5
Constructs a string matcher that will search for the pattern referred to Constructs a string matcher that will search for the pattern referred to
by \a uc with the given \a length and case sensitivity specified by \a cs. by \a uc with the given \a length and case sensitivity specified by \a cs.
*/ */
QStringMatcher::QStringMatcher(const QChar *uc, int len, Qt::CaseSensitivity cs)
: QStringMatcher(QStringView(uc, len), cs)
{
}
/*! /*!
\fn QStringMatcher::QStringMatcher(QStringView pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive) \fn QStringMatcher::QStringMatcher(QStringView pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive)
@ -201,9 +193,8 @@ QStringMatcher::QStringMatcher(const QChar *uc, int len, Qt::CaseSensitivity cs)
Call indexIn() to perform a search. Call indexIn() to perform a search.
*/ */
QStringMatcher::QStringMatcher(QStringView str, Qt::CaseSensitivity cs) QStringMatcher::QStringMatcher(QStringView str, Qt::CaseSensitivity cs)
: d_ptr(nullptr), q_cs(cs) : d_ptr(nullptr), q_cs(cs), q_sv(str)
{ {
p.sv = str;
updateSkipTable(); updateSkipTable();
} }
/*! /*!
@ -231,7 +222,8 @@ QStringMatcher &QStringMatcher::operator=(const QStringMatcher &other)
if (this != &other) { if (this != &other) {
q_pattern = other.q_pattern; q_pattern = other.q_pattern;
q_cs = other.q_cs; q_cs = other.q_cs;
memcpy(q_data, other.q_data, sizeof(q_data)); q_sv = other.q_sv;
memcpy(q_skiptable, other.q_skiptable, sizeof(q_skiptable));
} }
return *this; return *this;
} }
@ -245,7 +237,7 @@ QStringMatcher &QStringMatcher::operator=(const QStringMatcher &other)
void QStringMatcher::setPattern(const QString &pattern) void QStringMatcher::setPattern(const QString &pattern)
{ {
q_pattern = pattern; q_pattern = pattern;
p.sv = q_pattern; q_sv = q_pattern;
updateSkipTable(); updateSkipTable();
} }
@ -262,7 +254,7 @@ QString QStringMatcher::pattern() const
{ {
if (!q_pattern.isEmpty()) if (!q_pattern.isEmpty())
return q_pattern; return q_pattern;
return p.sv.toString(); return q_sv.toString();
} }
/*! /*!
@ -279,7 +271,8 @@ void QStringMatcher::setCaseSensitivity(Qt::CaseSensitivity cs)
updateSkipTable(); updateSkipTable();
} }
/*! /*! \fn qsizetype QStringMatcher::indexIn(const QString &str, qsizetype from) const
Searches the string \a str from character position \a from Searches the string \a str from character position \a from
(default 0, i.e. from the first character), for the string (default 0, i.e. from the first character), for the string
pattern() that was set in the constructor or in the most recent pattern() that was set in the constructor or in the most recent
@ -288,12 +281,8 @@ void QStringMatcher::setCaseSensitivity(Qt::CaseSensitivity cs)
\sa setPattern(), setCaseSensitivity() \sa setPattern(), setCaseSensitivity()
*/ */
int QStringMatcher::indexIn(const QString &str, qsizetype from) const
{
return int(indexIn(QStringView(str), from));
}
/*! /*! \fn qsizetype QStringMatcher::indexIn(const QChar *str, qsizetype length, qsizetype from) const
\since 4.5 \since 4.5
Searches the string starting at \a str (of length \a length) from Searches the string starting at \a str (of length \a length) from
@ -305,10 +294,6 @@ int QStringMatcher::indexIn(const QString &str, qsizetype from) const
\sa setPattern(), setCaseSensitivity() \sa setPattern(), setCaseSensitivity()
*/ */
int QStringMatcher::indexIn(const QChar *str, qsizetype length, qsizetype from) const
{
return int(indexIn(QStringView(str, length), from));
}
/*! /*!
\since 5.14 \since 5.14
@ -325,7 +310,7 @@ qsizetype QStringMatcher::indexIn(QStringView str, qsizetype from) const
{ {
if (from < 0) if (from < 0)
from = 0; from = 0;
return bm_find(str, from, p.sv, p.q_skiptable, q_cs); return bm_find(str, from, q_sv, q_skiptable, q_cs);
} }
/*! /*!

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2019 Mail.ru Group. ** Copyright (C) 2019 Mail.ru Group.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
@ -53,11 +53,13 @@ class Q_CORE_EXPORT QStringMatcher
{ {
void updateSkipTable(); void updateSkipTable();
public: public:
QStringMatcher(); QStringMatcher() = default;
explicit QStringMatcher(const QString &pattern, explicit QStringMatcher(const QString &pattern,
Qt::CaseSensitivity cs = Qt::CaseSensitive); Qt::CaseSensitivity cs = Qt::CaseSensitive);
QStringMatcher(const QChar *uc, int len, QStringMatcher(const QChar *uc, qsizetype len,
Qt::CaseSensitivity cs = Qt::CaseSensitive); Qt::CaseSensitivity cs = Qt::CaseSensitive)
: QStringMatcher(QStringView(uc, len), cs)
{}
QStringMatcher(QStringView pattern, QStringMatcher(QStringView pattern,
Qt::CaseSensitivity cs = Qt::CaseSensitive); Qt::CaseSensitivity cs = Qt::CaseSensitive);
QStringMatcher(const QStringMatcher &other); QStringMatcher(const QStringMatcher &other);
@ -68,24 +70,20 @@ public:
void setPattern(const QString &pattern); void setPattern(const QString &pattern);
void setCaseSensitivity(Qt::CaseSensitivity cs); void setCaseSensitivity(Qt::CaseSensitivity cs);
int indexIn(const QString &str, qsizetype from = 0) const; qsizetype indexIn(const QString &str, qsizetype from = 0) const
int indexIn(const QChar *str, qsizetype length, qsizetype from = 0) const; { return indexIn(QStringView(str), from); }
qsizetype indexIn(const QChar *str, qsizetype length, qsizetype from = 0) const
{ return indexIn(QStringView(str, length), from); }
qsizetype indexIn(QStringView str, qsizetype from = 0) const; qsizetype indexIn(QStringView str, qsizetype from = 0) const;
QString pattern() const; QString pattern() const;
inline Qt::CaseSensitivity caseSensitivity() const { return q_cs; } inline Qt::CaseSensitivity caseSensitivity() const { return q_cs; }
private: private:
QStringMatcherPrivate *d_ptr; QStringMatcherPrivate *d_ptr = nullptr;
Qt::CaseSensitivity q_cs = Qt::CaseSensitive;
QString q_pattern; QString q_pattern;
Qt::CaseSensitivity q_cs; QStringView q_sv;
struct Data { uchar q_skiptable[256] = {};
uchar q_skiptable[256];
QStringView sv;
};
union {
uint q_data[256];
Data p;
};
}; };
QT_END_NAMESPACE QT_END_NAMESPACE