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 <andrei.golubev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Edward Welbourne 2020-10-13 13:25:55 +02:00
parent d11bf5fc24
commit 8bf36025f5
2 changed files with 43 additions and 47 deletions

View File

@ -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> 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<QLocale>();
if (language == QLocale::C)
return QList<QLocale>() << QLocale(QLocale::C);
QList<QLocale> 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.

View File

@ -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;