diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2019-07-20 14:58:03 +0300 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2019-08-01 10:16:04 +0000 |
commit | ece86693b7bba9092b9b191c9fbe5e2c1ec550a8 (patch) | |
tree | 2cd90d35e2835e3aaa3468925982af0df01744b4 | |
parent | 8af01ac984908ba58e682263187b2ceb5faf2f8f (diff) |
ZhuyinTable: throughly QStringView-enable
Nothing in the implementation of ZhuyinTable needs QList, or
QString. This is all very basic parsing. So use QStringView. Now all
operations are free of dynamic memory allocations.
Saves ~2.7KiB (0.9%) in text size on optimized AMD64 Linux GCC 9.1
builds.
Change-Id: Iefa38980b52ede17a0c11f752653616d1944911a
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r-- | src/plugins/tcime/3rdparty/tcime/zhuyindictionary.cpp | 6 | ||||
-rw-r--r-- | src/plugins/tcime/3rdparty/tcime/zhuyintable.cpp | 106 | ||||
-rw-r--r-- | src/plugins/tcime/3rdparty/tcime/zhuyintable.h | 55 | ||||
-rw-r--r-- | src/plugins/tcime/plugin/tcinputmethod.cpp | 16 |
4 files changed, 83 insertions, 100 deletions
diff --git a/src/plugins/tcime/3rdparty/tcime/zhuyindictionary.cpp b/src/plugins/tcime/3rdparty/tcime/zhuyindictionary.cpp index 1cf303c1..6bcc08a1 100644 --- a/src/plugins/tcime/3rdparty/tcime/zhuyindictionary.cpp +++ b/src/plugins/tcime/3rdparty/tcime/zhuyindictionary.cpp @@ -32,8 +32,8 @@ ZhuyinDictionary::ZhuyinDictionary() : QStringList ZhuyinDictionary::getWords(const QString &input) const { // Look up the syllables index; return empty string for invalid syllables. - QStringList pair = ZhuyinTable::stripTones(input); - int syllablesIndex = !pair.isEmpty() ? ZhuyinTable::getSyllablesIndex(pair[0]) : -1; + auto strippedTones = ZhuyinTable::stripTones(input); + int syllablesIndex = strippedTones.ok ? ZhuyinTable::getSyllablesIndex(strippedTones.pair[0]) : -1; if (syllablesIndex < 0 || syllablesIndex >= dictionary().size()) return QStringList(); @@ -44,7 +44,7 @@ QStringList ZhuyinDictionary::getWords(const QString &input) const return QStringList(); // Counts of words for each tone are stored in the array beginning. - int tone = ZhuyinTable::getTones(pair[1].at(0)); + int tone = ZhuyinTable::getTones(strippedTones.pair[1].at(0)); int length = (int) data[tone].unicode(); if (length == 0) return QStringList(); diff --git a/src/plugins/tcime/3rdparty/tcime/zhuyintable.cpp b/src/plugins/tcime/3rdparty/tcime/zhuyintable.cpp index 7dc62f37..2f3da2ab 100644 --- a/src/plugins/tcime/3rdparty/tcime/zhuyintable.cpp +++ b/src/plugins/tcime/3rdparty/tcime/zhuyintable.cpp @@ -20,41 +20,51 @@ */ #include "zhuyintable.h" -#include <QStringList> + +#include <QStringView> using namespace tcime; -const int ZhuyinTable::INITIALS_SIZE = 22; -const QList<QChar> ZhuyinTable::yiEndingFinals = QList<QChar>() - << QChar(0x311a) << QChar(0x311b) << QChar(0x311d) << QChar(0x311e) << QChar(0x3120) << QChar(0x3121) << QChar(0x3122) - << QChar(0x3123) << QChar(0x3124) << QChar(0x3125); -const QList<QChar> ZhuyinTable::wuEndingFinals = QList<QChar>() - << QChar(0x311a) << QChar(0x311b) << QChar(0x311e) << QChar(0x311f) << QChar(0x3122) << QChar(0x3123) << QChar(0x3124) - << QChar(0x3125); -const QList<QChar> ZhuyinTable::yuEndingFinals = QList<QChar>() - << QChar(0x311d) << QChar(0x3122) << QChar(0x3123) << QChar(0x3125); -const int ZhuyinTable::YI_FINALS_INDEX = 14; -const int ZhuyinTable::WU_FINALS_INDEX = 25; -const int ZhuyinTable::YU_FINALS_INDEX = 34; -const QChar ZhuyinTable::YI_FINALS(0x3127); -const QChar ZhuyinTable::WU_FINALS(0x3128); -const QChar ZhuyinTable::YU_FINALS (0x3129); -const QList<QChar> ZhuyinTable::tones = QList<QChar>() - << ZhuyinTable::DEFAULT_TONE << QChar(0x02d9) << QChar(0x02ca) << QChar(0x02c7) << QChar(0x02cb); +// All Chinese characters are mapped into a zhuyin table as described in +// http://en.wikipedia.org/wiki/Zhuyin_table. +const int INITIALS_SIZE = 22; + +// Finals that can be appended after 'ㄧ' (yi), 'ㄨ' (wu), or 'ㄩ' (yu). +static Q_CONSTEXPR char16_t yiEndingFinals[] = + u"\x311a\x311b\x311d\x311e\x3120\x3121\x3122\x3123\x3124\x3125"; +static Q_CONSTEXPR char16_t wuEndingFinals[] = + u"\x311a\x311b\x311e\x311f\x3122\x3123\x3124\x3125"; +static Q_CONSTEXPR char16_t yuEndingFinals[] = + u"\x311d\x3122\x3123\x3125"; + +// 'ㄧ' (yi) finals start from position 14 and are followed by 'ㄨ' (wu) +// finals, and 'ㄩ' (yu) finals follow after 'ㄨ' (wu) finals. +const int YI_FINALS_INDEX = 14; +const int WU_FINALS_INDEX = 25; +const int YU_FINALS_INDEX = 34; + +// 'ㄧ' (yi), 'ㄨ' (wu) , and 'ㄩ' (yu) finals. +const QChar YI_FINALS(0x3127); +const QChar WU_FINALS(0x3128); +const QChar YU_FINALS (0x3129); + const QChar ZhuyinTable::DEFAULT_TONE = QLatin1Char(' '); -int ZhuyinTable::getInitials(const QChar &initials) +// Default tone and four tone symbols: '˙', 'ˊ', 'ˇ', and 'ˋ'. +static Q_CONSTEXPR char16_t tones[] = u" \x02d9\x02ca\x02c7\x02cb"; + +int ZhuyinTable::getInitials(QChar initials) { // Calculate the index by its distance to the first initials 'ㄅ' (b). int index = initials.unicode() - 0x3105 + 1; - if (index >= ZhuyinTable::INITIALS_SIZE) + if (index >= INITIALS_SIZE) // Syllables starting with finals can still be valid. return 0; return (index >= 0) ? index : -1; } -int ZhuyinTable::getFinals(const QString &finals) +int ZhuyinTable::getFinals(QStringView finals) { if (finals.length() == 0) // Syllables ending with no finals can still be valid. @@ -72,7 +82,7 @@ int ZhuyinTable::getFinals(const QString &finals) return index; // Check 'ㄧ' (yi), 'ㄨ' (wu) , and 'ㄩ' (yu) group finals. - QList<QChar> endingFinals; + QStringView endingFinals; if (firstFinal == YI_FINALS) { index = YI_FINALS_INDEX; endingFinals = yiEndingFinals; @@ -96,7 +106,7 @@ int ZhuyinTable::getFinals(const QString &finals) return -1; } -int ZhuyinTable::getSyllablesIndex(const QString &syllables) +int ZhuyinTable::getSyllablesIndex(QStringView syllables) { if (syllables.isEmpty()) return -1; @@ -113,48 +123,50 @@ int ZhuyinTable::getSyllablesIndex(const QString &syllables) return (finals * INITIALS_SIZE + initials); } -int ZhuyinTable::getTones(const QChar &c) +int ZhuyinTable::getTones(QChar c) { - for (int i = 0; i < tones.size(); ++i) { - if (tones[i] == c) - return i; - } + const qsizetype i = QStringView(tones).indexOf(c); + if (i >= 0) + return int(i); // Treat all other characters as the default tone with the index 0. return 0; } int ZhuyinTable::getTonesCount() { - return tones.size(); + return int(QStringView(tones).size()); } -bool ZhuyinTable::isTone(const QChar &c) +bool ZhuyinTable::isTone(QChar c) { - for (int i = 0; i < tones.size(); ++i) { - if (tones[i] == c) - return true; - } - return false; + return QStringView(tones).contains(c); } -bool ZhuyinTable::isYiWuYuFinals(const QChar &c) +bool ZhuyinTable::isYiWuYuFinals(QChar c) { return c == YI_FINALS || c == WU_FINALS || c == YU_FINALS; } -QStringList ZhuyinTable::stripTones(const QString &input) +auto ZhuyinTable::stripTones(QStringView input) -> StripTonesResult { - const int last = input.length() - 1; - if (last < 0) - return QStringList(); + StripTonesResult result; + result.ok = false; + if (input.isEmpty()) + return result; - QChar tone = input.at(last); + const QChar tone = input.back(); if (isTone(tone)) { - QString syllables = input.left(last); - if (syllables.length() <= 0) - return QStringList(); - return QStringList() << syllables << QString(tone); + QStringView syllables = input.chopped(1); + if (!syllables.isEmpty()) { + result.pair[0] = syllables; + result.pair[1] = input.right(1); + result.ok = true; + } + } else { + // Treat the tone-less input as the default tone (tone-0). + result.pair[0] = input; + result.pair[1] = QStringView(&DEFAULT_TONE, 1); + result.ok = true; } - // Treat the tone-less input as the default tone (tone-0). - return QStringList() << input << QString(DEFAULT_TONE); + return result; } diff --git a/src/plugins/tcime/3rdparty/tcime/zhuyintable.h b/src/plugins/tcime/3rdparty/tcime/zhuyintable.h index 8512574e..57e9d36c 100644 --- a/src/plugins/tcime/3rdparty/tcime/zhuyintable.h +++ b/src/plugins/tcime/3rdparty/tcime/zhuyintable.h @@ -22,53 +22,24 @@ #ifndef ZHUYINTABLE_H #define ZHUYINTABLE_H -#include <QMap> -#include <QChar> -#include <QString> +#include <QtCore/QStringView> namespace tcime { - -class ZhuyinTable -{ - Q_DISABLE_COPY(ZhuyinTable) - ZhuyinTable() {} - - // All Chinese characters are mapped into a zhuyin table as described in - // http://en.wikipedia.org/wiki/Zhuyin_table. - static const int INITIALS_SIZE; - - // Finals that can be appended after 'ㄧ' (yi), 'ㄨ' (wu), or 'ㄩ' (yu). - static const QList<QChar> yiEndingFinals; - static const QList<QChar> wuEndingFinals; - static const QList<QChar> yuEndingFinals; - - // 'ㄧ' (yi) finals start from position 14 and are followed by 'ㄨ' (wu) - // finals, and 'ㄩ' (yu) finals follow after 'ㄨ' (wu) finals. - static const int YI_FINALS_INDEX; - static const int WU_FINALS_INDEX; - static const int YU_FINALS_INDEX; - - // 'ㄧ' (yi), 'ㄨ' (wu) , and 'ㄩ' (yu) finals. - static const QChar YI_FINALS; - static const QChar WU_FINALS; - static const QChar YU_FINALS; - - // Default tone and four tone symbols: '˙', 'ˊ', 'ˇ', and 'ˋ'. - static const QList<QChar> tones; - -public: +struct ZhuyinTable { static const QChar DEFAULT_TONE; - - static int getInitials(const QChar &initials); - static int getFinals(const QString &finals); - static int getSyllablesIndex(const QString &syllables); - static int getTones(const QChar &c); + static int getInitials(QChar initials); + static int getFinals(QStringView finals); + static int getSyllablesIndex(QStringView syllables); + static int getTones(QChar c); static int getTonesCount(); - static bool isTone(const QChar &c); - static bool isYiWuYuFinals(const QChar &c); - static QStringList stripTones(const QString &input); + static bool isTone(QChar c); + static bool isYiWuYuFinals(QChar c); + struct StripTonesResult { + bool ok; + QStringView pair[2]; + }; + static StripTonesResult stripTones(QStringView input); }; - } #endif // ZHUYINTABLE_H diff --git a/src/plugins/tcime/plugin/tcinputmethod.cpp b/src/plugins/tcime/plugin/tcinputmethod.cpp index 1f5fc6e3..73a4b900 100644 --- a/src/plugins/tcime/plugin/tcinputmethod.cpp +++ b/src/plugins/tcime/plugin/tcinputmethod.cpp @@ -206,14 +206,14 @@ public: // Tones are accepted only when there's text in composing. return false; - QStringList pair = ZhuyinTable::stripTones(input); - if (pair.isEmpty()) + auto strippedTones = ZhuyinTable::stripTones(input); + if (!strippedTones.ok) // Tones cannot be composed if there's no syllables. return false; // Replace the original tone with the new tone, but the default tone // character should not be composed into the composing text. - QChar tone = pair[1].at(0); + QChar tone = strippedTones.pair[1].at(0); if (c == ZhuyinTable::DEFAULT_TONE) { if (tone != ZhuyinTable::DEFAULT_TONE) input.remove(input.length() - 1, 1); @@ -229,7 +229,7 @@ public: input.insert(0, c); else input.replace(0, 1, c); - } else if (ZhuyinTable::getFinals(QString(c)) > 0) { + } else if (ZhuyinTable::getFinals(QStringView(&c, 1)) > 0) { // Replace the finals in the decomposed of syllables and tones. QList<QChar> decomposed = decomposeZhuyin(); if (ZhuyinTable::isYiWuYuFinals(c)) { @@ -261,15 +261,15 @@ public: QList<QChar> decomposeZhuyin() { QList<QChar> results = {QChar::Null, QChar::Null, QChar::Null, QChar::Null}; - QStringList pair = ZhuyinTable::stripTones(input); - if (!pair.isEmpty()) { + auto strippedTones = ZhuyinTable::stripTones(input); + if (strippedTones.ok) { // Decompose tones. - QChar tone = pair[1].at(0); + QChar tone = strippedTones.pair[1].at(0); if (tone != ZhuyinTable::DEFAULT_TONE) results[3] = tone; // Decompose initials. - QString syllables = pair[0]; + QStringView syllables = strippedTones.pair[0]; if (ZhuyinTable::getInitials(syllables.at(0)) > 0) { results[0] = syllables.at(0); syllables = syllables.mid(1); |