From 8bf36025f5602e3067448941ee4d0ccca3928a40 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 13 Oct 2020 13:25:55 +0200 Subject: [PATCH] Add some inline methods to make code more readable Give QLocaleId matchesAny() and isValid() checks and some acceptance tests for their use as filters. Give QLocaleData a QLocaleId id(). A few messy pieces of code get easier to read. In the process, greatly simplify a do-while loop (sacrificing some pretest-before-loop optimizations - benchmarking shows they made negligible difference) and change a while loop to match its form, since it was doing essentially the same iteration and (thus) its condition was guaranteed true on the first iteration. Change-Id: I36b1a6ca8a3cf350b3f3abbe75b177e5a7637cd8 Reviewed-by: Andrei Golubev Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- src/corelib/text/qlocale.cpp | 66 +++++++++++------------------------- src/corelib/text/qlocale_p.h | 24 +++++++++++++ 2 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 1ac7742593..7438ed2e61 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -331,8 +331,7 @@ QByteArray QLocalePrivate::bcp47Name(char separator) const if (m_data->m_language_id == QLocale::C) return QByteArrayLiteral("en"); - QLocaleId localeId { m_data->m_language_id, m_data->m_script_id, m_data->m_country_id }; - return localeId.withLikelySubtagsRemoved().name(separator); + return m_data->id().withLikelySubtagsRemoved().name(separator); } /*! @@ -360,40 +359,13 @@ static const QLocaleData *findLocaleDataById(const QLocaleId &localeId) return locale_data; const QLocaleData *data = locale_data + idx; - Q_ASSERT(localeId.language_id - ? data->m_language_id == localeId.language_id - : data->m_language_id); + Q_ASSERT(localeId.acceptLanguage(data->m_language_id)); - if (localeId.script_id == QLocale::AnyScript && localeId.country_id == QLocale::AnyCountry) - return data; - - if (localeId.script_id == QLocale::AnyScript) { - do { - if (data->m_country_id == localeId.country_id) - return data; - ++data; - } while (localeId.language_id - ? data->m_language_id == localeId.language_id - : data->m_language_id); - } else if (localeId.country_id == QLocale::AnyCountry) { - do { - if (data->m_script_id == localeId.script_id) - return data; - ++data; - } while (localeId.language_id - ? data->m_language_id == localeId.language_id - : data->m_language_id); - } else { - do { - if (data->m_script_id == localeId.script_id - && data->m_country_id == localeId.country_id) { - return data; - } - ++data; - } while (localeId.language_id - ? data->m_language_id == localeId.language_id - : data->m_language_id); - } + do { + if (localeId.acceptScriptCountry(data->id())) + return data; + ++data; + } while (localeId.acceptLanguage(data->m_language_id)); return nullptr; } @@ -2516,28 +2488,28 @@ QList QLocale::matchingLocales(QLocale::Language language, QLocale::Script script, QLocale::Country country) { - if (uint(language) > QLocale::LastLanguage || uint(script) > QLocale::LastScript || - uint(country) > QLocale::LastCountry) + const QLocaleId filter { language, script, country }; + if (!filter.isValid()) return QList(); if (language == QLocale::C) return QList() << QLocale(QLocale::C); QList result; - if (language == QLocale::AnyLanguage && script == QLocale::AnyScript - && country == QLocale::AnyCountry) { + if (filter.matchesAll()) result.reserve(locale_data_size); - } + const QLocaleData *data = locale_data + locale_index[language]; - while ( (data != locale_data + locale_data_size) - && (language == QLocale::AnyLanguage || data->m_language_id == uint(language))) { - if ((script == QLocale::AnyScript || data->m_script_id == uint(script)) - && (country == QLocale::AnyCountry || data->m_country_id == uint(country))) { - result.append(QLocale(*(data->m_language_id == C ? c_private() + Q_ASSERT(filter.acceptLanguage(data->m_language_id)); + do { + const QLocaleId id = data->id(); + if (filter.acceptScriptCountry(id)) { + result.append(QLocale(*(id.language_id == C ? c_private() : QLocalePrivate::create(data)))); } ++data; - } + // Only the terminating entry in locale_data has 0 as language_id: + } while (filter.acceptLanguage(data->m_language_id)); return result; } @@ -4204,7 +4176,7 @@ QStringList QLocale::uiLanguages() const } const auto data = locale.d->m_data; - QLocaleId id { data->m_language_id, data->m_script_id, data->m_country_id }; + QLocaleId id = data->id(); const QLocaleId max = id.withLikelySubtagsAdded(); const QLocaleId min = max.withLikelySubtagsRemoved(); id.script_id = 0; // For re-use as script-less variant. diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h index fec7517111..8943edddb8 100644 --- a/src/corelib/text/qlocale_p.h +++ b/src/corelib/text/qlocale_p.h @@ -152,6 +152,27 @@ struct QLocaleId { return language_id == other.language_id && script_id == other.script_id && country_id == other.country_id; } inline bool operator!=(QLocaleId other) const { return !operator==(other); } + inline bool isValid() const + { + return language_id <= QLocale::LastLanguage && script_id <= QLocale::LastScript + && country_id <= QLocale::LastCountry; + } + inline bool matchesAll() const + { + return !language_id && !script_id && !country_id; + } + // Use as: filter.accept...(candidate) + inline bool acceptLanguage(quint16 lang) const + { + // Always reject AnyLanguage (only used for last entry in locale_data array). + // So, when searching for AnyLanguage, accept everything *but* AnyLanguage. + return language_id ? lang == language_id : lang; + } + inline bool acceptScriptCountry(QLocaleId other) const + { + return (!country_id || other.country_id == country_id) + && (!script_id || other.script_id == script_id); + } QLocaleId withLikelySubtagsAdded() const; QLocaleId withLikelySubtagsRemoved() const; @@ -270,6 +291,9 @@ public: Q_CORE_EXPORT bool validateChars(QStringView str, NumberMode numMode, QByteArray *buff, int decDigits = -1, QLocale::NumberOptions number_options = QLocale::DefaultNumberOptions) const; + // Access to assorted data members: + QLocaleId id() const { return QLocaleId { m_language_id, m_script_id, m_country_id }; } + QString decimalPoint() const; QString groupSeparator() const; QString listSeparator() const;