diff --git a/src/corelib/text/qlatin1stringmatcher.h b/src/corelib/text/qlatin1stringmatcher.h index a256250e9c6..3b8c24fc924 100644 --- a/src/corelib/text/qlatin1stringmatcher.h +++ b/src/corelib/text/qlatin1stringmatcher.h @@ -98,6 +98,18 @@ struct QCaseInsensitiveLatin1Hash return std::size_t(latin1Lower[uchar(c)]); } + static int difference(char lhs, char rhs) + { + return int(latin1Lower[uchar(lhs)]) - int(latin1Lower[uchar(rhs)]); + } + + static auto matcher(char ch) + { + return [sought = latin1Lower[uchar(ch)]](char other) { + return latin1Lower[uchar(other)] == sought; + }; + } + private: static constexpr uchar latin1Lower[256] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index c8c7ce395a3..33a54ab2e16 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -1383,25 +1383,8 @@ static int ucstrcmp(const char16_t *a, size_t alen, const Char2 *b, size_t blen) return cmp ? cmp : lencmp(alen, blen); } -static constexpr uchar latin1Lower[256] = { - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x5b,0x5c,0x5d,0x5e,0x5f, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, - 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, - 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, - // 0xd7 (multiplication sign) and 0xdf (sz ligature) complicate life - 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, - 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xd7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xdf, - 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, - 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff -}; +using CaseInsensitiveL1 = QtPrivate::QCaseInsensitiveLatin1Hash; + static int latin1nicmp(const char *lhsChar, qsizetype lSize, const char *rhsChar, qsizetype rSize) { // We're called with QLatin1StringView's .data() and .size(): @@ -1412,11 +1395,9 @@ static int latin1nicmp(const char *lhsChar, qsizetype lSize, const char *rhsChar return 1; const qsizetype size = std::min(lSize, rSize); - const uchar *lhs = reinterpret_cast(lhsChar); - const uchar *rhs = reinterpret_cast(rhsChar); - Q_ASSERT(lhs && rhs); // since both lSize and rSize are positive + Q_ASSERT(lhsChar && rhsChar); // since both lSize and rSize are positive for (qsizetype i = 0; i < size; i++) { - if (int res = latin1Lower[lhs[i]] - latin1Lower[rhs[i]]) + if (int res = CaseInsensitiveL1::difference(lhsChar[i], rhsChar[i])) return res; } return lencmp(lSize, rSize); @@ -10674,11 +10655,8 @@ qsizetype QtPrivate::count(QLatin1StringView haystack, QChar needle, Qt::CaseSen if (cs == Qt::CaseSensitive) { return std::count(haystack.cbegin(), haystack.cend(), needle.toLatin1()); } else { - auto toLower = [](char ch) { return latin1Lower[uchar(ch)]; }; - const uchar ch = toLower(needle.toLatin1()); - return std::count_if(haystack.cbegin(), haystack.cend(), [&toLower, ch](const char c) { - return toLower(c) == ch; - }); + return std::count_if(haystack.cbegin(), haystack.cend(), + CaseInsensitiveL1::matcher(needle.toLatin1())); } } @@ -10908,10 +10886,7 @@ qsizetype QtPrivate::findString(QLatin1StringView haystack, qsizetype from, QLat if (needle.size() <= threshold) { const auto begin = haystack.begin(); const auto end = haystack.end() - needle.size() + 1; - const uchar needle1 = latin1Lower[uchar(needle[0].toLatin1())]; - auto ciMatch = [needle1](const char ch) { - return latin1Lower[uchar(ch)] == needle1; - }; + auto ciMatch = CaseInsensitiveL1::matcher(needle[0].toLatin1()); const qsizetype nlen1 = needle.size() - 1; for (auto it = std::find_if(begin + from, end, ciMatch); it < end; it = std::find_if(it + 1, end, ciMatch)) {