summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qlocale_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/text/qlocale_p.h')
-rw-r--r--src/corelib/text/qlocale_p.h528
1 files changed, 286 insertions, 242 deletions
diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h
index 1b5cc0aa55..3044d137b9 100644
--- a/src/corelib/text/qlocale_p.h
+++ b/src/corelib/text/qlocale_p.h
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLOCALE_P_H
#define QLOCALE_P_H
@@ -52,24 +16,98 @@
// We mean it.
//
-#include <QtCore/private/qglobal_p.h>
-#include "QtCore/qstring.h"
-#include "QtCore/qvarlengtharray.h"
-#include "QtCore/qvariant.h"
-#include "QtCore/qnumeric.h"
-#include <QtCore/qcalendar.h>
-
#include "qlocale.h"
+#include <QtCore/qcalendar.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/private/qnumeric_p.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qvarlengtharray.h>
+#ifdef Q_OS_WASM
+#include <private/qstdweb_p.h>
+#endif
+
#include <limits>
#include <cmath>
+#include <string_view>
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_SYSTEMLOCALE
+template <typename T> struct QSimpleParsedNumber
+{
+ T result;
+ // When used < 0, -used is how much was used, but it was an error.
+ qsizetype used;
+ bool ok() const { return used > 0; }
+};
+
+template <typename MaskType, uchar Lowest> struct QCharacterSetMatch
+{
+ static constexpr int MaxRange = std::numeric_limits<MaskType>::digits;
+ MaskType mask;
+
+ constexpr QCharacterSetMatch(std::string_view set)
+ : mask(0)
+ {
+ for (char c : set) {
+ int idx = uchar(c) - Lowest;
+ mask |= MaskType(1) << idx;
+ }
+ }
+
+ constexpr bool matches(uchar c) const
+ {
+ unsigned idx = c - Lowest;
+ if (idx >= MaxRange)
+ return false;
+ return (mask >> idx) & 1;
+ }
+};
+
+namespace QtPrivate {
+inline constexpr char ascii_space_chars[] =
+ "\t" // 9: HT - horizontal tab
+ "\n" // 10: LF - line feed
+ "\v" // 11: VT - vertical tab
+ "\f" // 12: FF - form feed
+ "\r" // 13: CR - carriage return
+ " "; // 32: space
+
+template <const char *Set, int ForcedLowest = -1>
+inline constexpr auto makeCharacterSetMatch()
+{
+ constexpr auto view = std::string_view(Set);
+ constexpr uchar MinElement = *std::min_element(view.begin(), view.end());
+ constexpr uchar MaxElement = *std::max_element(view.begin(), view.end());
+ constexpr int Range = MaxElement - MinElement;
+ static_assert(Range < 64, "Characters in the set are 64 or more values apart");
+
+ if constexpr (ForcedLowest >= 0) {
+ // use the force
+ static_assert(ForcedLowest <= int(MinElement), "The force is not with you");
+ using MaskType = std::conditional_t<MaxElement - ForcedLowest < 32, quint32, quint64>;
+ return QCharacterSetMatch<MaskType, ForcedLowest>(view);
+ } else if constexpr (MaxElement < std::numeric_limits<qregisteruint>::digits) {
+ // if we can use a Lowest of zero, we can remove a subtraction
+ // from the matches() code at runtime
+ using MaskType = std::conditional_t<(MaxElement < 32), quint32, qregisteruint>;
+ return QCharacterSetMatch<MaskType, 0>(view);
+ } else {
+ using MaskType = std::conditional_t<(Range < 32), quint32, quint64>;
+ return QCharacterSetMatch<MaskType, MinElement>(view);
+ }
+}
+} // QtPrivate
+
struct QLocaleData;
+// Subclassed by Android platform plugin:
class Q_CORE_EXPORT QSystemLocale
{
+ Q_DISABLE_COPY_MOVE(QSystemLocale)
+ QSystemLocale *next = nullptr; // Maintains a stack.
+
public:
QSystemLocale();
virtual ~QSystemLocale();
@@ -85,7 +123,7 @@ public:
enum QueryType {
LanguageId, // uint
- CountryId, // uint
+ TerritoryId, // uint
DecimalPoint, // QString
GroupSeparator, // QString (empty QString means: don't group digits)
ZeroDigit, // QString
@@ -96,8 +134,10 @@ public:
TimeFormatShort, // QString
DayNameLong, // QString, in: int
DayNameShort, // QString, in: int
+ DayNameNarrow, // QString, in: int
MonthNameLong, // QString, in: int
MonthNameShort, // QString, in: int
+ MonthNameNarrow, // QString, in: int
DateToStringLong, // QString, in: QDate
DateToStringShort, // QString in: QDate
TimeToStringLong, // QString in: QTime
@@ -122,21 +162,21 @@ public:
ListToSeparatedString, // QString
LocaleChanged, // system locale changed
NativeLanguageName, // QString
- NativeCountryName, // QString
+ NativeTerritoryName, // QString
StandaloneMonthNameLong, // QString, in: int
- StandaloneMonthNameShort // QString, in: int
+ StandaloneMonthNameShort, // QString, in: int
+ StandaloneMonthNameNarrow, // QString, in: int
+ StandaloneDayNameLong, // QString, in: int
+ StandaloneDayNameShort, // QString, in: int
+ StandaloneDayNameNarrow // QString, in: int
};
- virtual QVariant query(QueryType type, QVariant in = QVariant()) const;
- virtual QLocale fallbackUiLocale() const;
+ virtual QVariant query(QueryType type, QVariant &&in = QVariant()) const;
- inline uint fallbackUiLocaleIndex() const;
-private:
- QSystemLocale(bool);
- friend class QSystemLocaleSingleton;
+ virtual QLocale fallbackLocale() const;
+ inline qsizetype fallbackLocaleIndex() const;
};
Q_DECLARE_TYPEINFO(QSystemLocale::QueryType, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QSystemLocale::CurrencyToStringArgument, Q_RELOCATABLE_TYPE);
-#endif
#if QT_CONFIG(icu)
namespace QIcu {
@@ -148,50 +188,64 @@ namespace QIcu {
struct QLocaleId
{
- // ### Also used by Translator::languageAndCountry() in qttools:
- Q_CORE_EXPORT static QLocaleId fromName(const QString &name);
- inline bool operator==(QLocaleId other) const
- { return language_id == other.language_id && script_id == other.script_id && country_id == other.country_id; }
- inline bool operator!=(QLocaleId other) const
+ [[nodiscard]] Q_AUTOTEST_EXPORT static QLocaleId fromName(QStringView name);
+ [[nodiscard]] inline bool operator==(QLocaleId other) const
+ { return language_id == other.language_id && script_id == other.script_id && territory_id == other.territory_id; }
+ [[nodiscard]] inline bool operator!=(QLocaleId other) const
{ return !operator==(other); }
- inline bool isValid() const
+ [[nodiscard]] inline bool isValid() const
{
return language_id <= QLocale::LastLanguage && script_id <= QLocale::LastScript
- && country_id <= QLocale::LastCountry;
+ && territory_id <= QLocale::LastTerritory;
}
- inline bool matchesAll() const
+ [[nodiscard]] inline bool matchesAll() const
{
- return !language_id && !script_id && !country_id;
+ return !language_id && !script_id && !territory_id;
}
// Use as: filter.accept...(candidate)
- inline bool acceptLanguage(quint16 lang) const
+ [[nodiscard]] 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
+ [[nodiscard]] inline bool acceptScriptTerritory(QLocaleId other) const
{
- return (!country_id || other.country_id == country_id)
+ return (!territory_id || other.territory_id == territory_id)
&& (!script_id || other.script_id == script_id);
}
- QLocaleId withLikelySubtagsAdded() const;
- QLocaleId withLikelySubtagsRemoved() const;
+ [[nodiscard]] QLocaleId withLikelySubtagsAdded() const;
+ [[nodiscard]] QLocaleId withLikelySubtagsRemoved() const;
- QByteArray name(char separator = '-') const;
+ [[nodiscard]] QByteArray name(char separator = '-') const;
- ushort language_id = 0, script_id = 0, country_id = 0;
+ ushort language_id = 0, script_id = 0, territory_id = 0;
};
Q_DECLARE_TYPEINFO(QLocaleId, Q_PRIMITIVE_TYPE);
+
+using CharBuff = QVarLengthArray<char, 256>;
+
+struct ParsingResult
+{
+ enum State { // A duplicate of QValidator::State
+ Invalid,
+ Intermediate,
+ Acceptable
+ };
+
+ State state = Invalid;
+ CharBuff buff;
+};
+
struct QLocaleData
{
public:
// Having an index for each locale enables us to have diverse sources of
// data, e.g. calendar locales, as well as the main CLDR-derived data.
- static int findLocaleIndex(QLocaleId localeId);
- static const QLocaleData *c();
+ [[nodiscard]] static qsizetype findLocaleIndex(QLocaleId localeId);
+ [[nodiscard]] static const QLocaleData *c();
enum DoubleForm {
DFExponent = 0,
@@ -218,8 +272,6 @@ public:
enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
- typedef QVarLengthArray<char, 256> CharBuff;
-
private:
enum PrecisionMode {
PMDecimalDigits = 0x01,
@@ -227,103 +279,146 @@ private:
PMChopTrailingZeros = 0x03
};
- QString decimalForm(QString &&digits, int decpt, int precision,
- PrecisionMode pm, bool mustMarkDecimal,
- bool groupDigits) const;
- QString exponentForm(QString &&digits, int decpt, int precision,
- PrecisionMode pm, bool mustMarkDecimal,
- int minExponentDigits) const;
- QString signPrefix(bool negative, unsigned flags) const;
- QString applyIntegerFormatting(QString &&numStr, bool negative, int precision,
- int base, int width, unsigned flags) const;
+ [[nodiscard]] QString decimalForm(QString &&digits, int decpt, int precision,
+ PrecisionMode pm, bool mustMarkDecimal,
+ bool groupDigits) const;
+ [[nodiscard]] QString exponentForm(QString &&digits, int decpt, int precision,
+ PrecisionMode pm, bool mustMarkDecimal,
+ int minExponentDigits) const;
+ [[nodiscard]] QString signPrefix(bool negative, unsigned flags) const;
+ [[nodiscard]] QString applyIntegerFormatting(QString &&numStr, bool negative, int precision,
+ int base, int width, unsigned flags) const;
public:
- QString doubleToString(double d,
- int precision = -1,
- DoubleForm form = DFSignificantDigits,
- int width = -1,
- unsigned flags = NoFlags) const;
- QString longLongToString(qint64 l, int precision = -1,
- int base = 10,
- int width = -1,
- unsigned flags = NoFlags) const;
- QString unsLongLongToString(quint64 l, int precision = -1,
- int base = 10,
- int width = -1,
- unsigned flags = NoFlags) const;
+ [[nodiscard]] QString doubleToString(double d,
+ int precision = -1,
+ DoubleForm form = DFSignificantDigits,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ [[nodiscard]] QString longLongToString(qint64 l, int precision = -1,
+ int base = 10,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ [[nodiscard]] QString unsLongLongToString(quint64 l, int precision = -1,
+ int base = 10,
+ int width = -1,
+ unsigned flags = NoFlags) const;
// this function is meant to be called with the result of stringToDouble or bytearrayToDouble
- static float convertDoubleToFloat(double d, bool *ok)
+ // so *ok must have been properly set (if not null)
+ [[nodiscard]] static float convertDoubleToFloat(double d, bool *ok)
{
- if (qIsInf(d))
- return float(d);
- if (std::fabs(d) > std::numeric_limits<float>::max()) {
- if (ok)
- *ok = false;
- const float huge = std::numeric_limits<float>::infinity();
- return d < 0 ? -huge : huge;
- }
- if (d != 0 && float(d) == 0) {
- // Values that underflow double already failed. Match them:
- if (ok)
- *ok = false;
- return 0;
- }
- return float(d);
+ float result;
+ bool b = convertDoubleTo<float>(d, &result);
+ if (ok && *ok)
+ *ok = b;
+ return result;
}
- double stringToDouble(QStringView str, bool *ok, QLocale::NumberOptions options) const;
- qint64 stringToLongLong(QStringView str, int base, bool *ok, QLocale::NumberOptions options) const;
- quint64 stringToUnsLongLong(QStringView str, int base, bool *ok, QLocale::NumberOptions options) const;
+ [[nodiscard]] double stringToDouble(QStringView str, bool *ok,
+ QLocale::NumberOptions options) const;
+ [[nodiscard]] QSimpleParsedNumber<qint64>
+ stringToLongLong(QStringView str, int base, QLocale::NumberOptions options) const;
+ [[nodiscard]] QSimpleParsedNumber<quint64>
+ stringToUnsLongLong(QStringView str, int base, QLocale::NumberOptions options) const;
// this function is used in QIntValidator (QtGui)
- Q_CORE_EXPORT static qint64 bytearrayToLongLong(const char *num, int base, bool *ok);
- static quint64 bytearrayToUnsLongLong(const char *num, int base, bool *ok);
+ [[nodiscard]] Q_CORE_EXPORT
+ static QSimpleParsedNumber<qint64> bytearrayToLongLong(QByteArrayView num, int base);
+ [[nodiscard]] static QSimpleParsedNumber<quint64>
+ bytearrayToUnsLongLong(QByteArrayView num, int base);
+
+ [[nodiscard]] bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options,
+ NumberMode mode, CharBuff *result) const;
- bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options,
- CharBuff *result) const;
- inline char numericToCLocale(QStringView in) const;
+ struct NumericData
+ {
+#ifndef QT_NO_SYSTEMLOCALE
+ // Only used for the system locale, to store data for the view to look at:
+ QString sysDecimal, sysGroup, sysMinus, sysPlus;
+#endif
+ QStringView decimal, group, minus, plus, exponent;
+ char32_t zeroUcs = 0;
+ qint8 zeroLen = 0;
+ bool isC = false; // C locale sets this and nothing else.
+ bool exponentCyrillic = false; // True only for floating-point parsing of Cyrillic.
+ void setZero(QStringView zero)
+ {
+ // No known locale has digits that are more than one Unicode
+ // code-point, so we can safely deal with digits as plain char32_t.
+ switch (zero.size()) {
+ case 1:
+ Q_ASSERT(!zero.at(0).isSurrogate());
+ zeroUcs = zero.at(0).unicode();
+ zeroLen = 1;
+ break;
+ case 2:
+ Q_ASSERT(zero.at(0).isHighSurrogate());
+ zeroUcs = QChar::surrogateToUcs4(zero.at(0), zero.at(1));
+ zeroLen = 2;
+ break;
+ default:
+ Q_ASSERT(zero.size() == 0); // i.e. we got no value to use
+ break;
+ }
+ }
+ [[nodiscard]] bool isValid(NumberMode mode) const // Asserted as a sanity check.
+ {
+ if (isC)
+ return true;
+ if (exponentCyrillic && exponent != u"E" && exponent != u"\u0415")
+ return false;
+ return (zeroLen == 1 || zeroLen == 2) && zeroUcs > 0
+ && (mode == IntegerMode || !decimal.isEmpty())
+ // group may be empty (user config in system locale)
+ && !minus.isEmpty() && !plus.isEmpty()
+ && (mode != DoubleScientificMode || !exponent.isEmpty());
+ }
+ };
+ [[nodiscard]] inline NumericData numericData(NumberMode mode) const;
// this function is used in QIntValidator (QtGui)
- Q_CORE_EXPORT bool validateChars(QStringView str, NumberMode numMode, QByteArray *buff, int decDigits = -1,
- QLocale::NumberOptions number_options = QLocale::DefaultNumberOptions) const;
+ [[nodiscard]] Q_CORE_EXPORT ParsingResult
+ validateChars(QStringView str, NumberMode numMode, 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;
- QString percentSign() const;
- QString zeroDigit() const;
- char32_t zeroUcs() const;
- QString positiveSign() const;
- QString negativeSign() const;
- QString exponentSeparator() const;
+ [[nodiscard]] QLocaleId id() const
+ { return QLocaleId { m_language_id, m_script_id, m_territory_id }; }
+
+ [[nodiscard]] QString decimalPoint() const;
+ [[nodiscard]] QString groupSeparator() const;
+ [[nodiscard]] QString listSeparator() const;
+ [[nodiscard]] QString percentSign() const;
+ [[nodiscard]] QString zeroDigit() const;
+ [[nodiscard]] char32_t zeroUcs() const;
+ [[nodiscard]] QString positiveSign() const;
+ [[nodiscard]] QString negativeSign() const;
+ [[nodiscard]] QString exponentSeparator() const;
struct DataRange
{
quint16 offset;
quint16 size;
- QString getData(const char16_t *table) const
+ [[nodiscard]] QString getData(const char16_t *table) const
{
return size > 0
? QString::fromRawData(reinterpret_cast<const QChar *>(table + offset), size)
: QString();
}
- QStringView viewData(const char16_t *table) const
+ [[nodiscard]] QStringView viewData(const char16_t *table) const
{
return { reinterpret_cast<const QChar *>(table + offset), size };
}
- QString getListEntry(const char16_t *table, int index) const
+ [[nodiscard]] QString getListEntry(const char16_t *table, qsizetype index) const
{
return listEntry(table, index).getData(table);
}
- QStringView viewListEntry(const char16_t *table, int index) const
+ [[nodiscard]] QStringView viewListEntry(const char16_t *table, qsizetype index) const
{
return listEntry(table, index).viewData(table);
}
- char32_t ucsFirst(const char16_t *table) const
+ [[nodiscard]] char32_t ucsFirst(const char16_t *table) const
{
if (size && !QChar::isSurrogate(table[offset]))
return table[offset];
@@ -332,7 +427,7 @@ public:
return 0;
}
private:
- DataRange listEntry(const char16_t *table, int index) const
+ [[nodiscard]] DataRange listEntry(const char16_t *table, qsizetype index) const
{
const char16_t separator = ';';
quint16 i = 0;
@@ -360,15 +455,15 @@ public:
X(byteCount) X(byteAmountSI) X(byteAmountIEC) \
X(currencySymbol) X(currencyDisplayName) \
X(currencyFormat) X(currencyFormatNegative) \
- X(endonymLanguage) X(endonymCountry)
+ X(endonymLanguage) X(endonymTerritory)
#define rangeGetter(name) \
- DataRange name() const { return { m_ ## name ## _idx, m_ ## name ## _size }; }
+ [[nodiscard]] DataRange name() const { return { m_ ## name ## _idx, m_ ## name ## _size }; }
ForEachQLocaleRange(rangeGetter)
#undef rangeGetter
public:
- quint16 m_language_id, m_script_id, m_country_id;
+ quint16 m_language_id, m_script_id, m_territory_id;
// Offsets, then sizes, for each range:
#define rangeIndex(name) quint16 m_ ## name ## _idx;
@@ -387,49 +482,60 @@ public:
quint8 m_first_day_of_week : 3;
quint8 m_weekend_start : 3;
quint8 m_weekend_end : 3;
- quint8 m_grouping_top : 2; // Must have this many before the first grouping separator
+ quint8 m_grouping_top : 2; // Don't group until more significant group has this many digits.
quint8 m_grouping_higher : 3; // Number of digits between grouping separators
quint8 m_grouping_least : 3; // Number of digits after last grouping separator (before decimal).
};
-class Q_CORE_EXPORT QLocalePrivate
+class QLocalePrivate
{
public:
- constexpr QLocalePrivate(const QLocaleData *data, const uint index,
+ constexpr QLocalePrivate(const QLocaleData *data, qsizetype index,
QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions,
int refs = 0)
: m_data(data), ref Q_BASIC_ATOMIC_INITIALIZER(refs),
m_index(index), m_numberOptions(numberOptions) {}
- quint16 languageId() const { return m_data->m_language_id; }
- quint16 countryId() const { return m_data->m_country_id; }
+ [[nodiscard]] quint16 languageId() const { return m_data->m_language_id; }
+ [[nodiscard]] quint16 territoryId() const { return m_data->m_territory_id; }
- QByteArray bcp47Name(char separator = '-') const;
- QByteArray rawName(char separator = '-') const;
+ [[nodiscard]] QByteArray bcp47Name(char separator = '-') const;
- inline QLatin1String languageCode() const { return languageToCode(QLocale::Language(m_data->m_language_id)); }
- inline QLatin1String scriptCode() const { return scriptToCode(QLocale::Script(m_data->m_script_id)); }
- inline QLatin1String countryCode() const { return countryToCode(QLocale::Country(m_data->m_country_id)); }
-
- static const QLocalePrivate *get(const QLocale &l) { return l.d; }
- static QLatin1String languageToCode(QLocale::Language language);
- static QLatin1String scriptToCode(QLocale::Script script);
- static QLatin1String countryToCode(QLocale::Country country);
- static QLocale::Language codeToLanguage(QStringView code) noexcept;
- static QLocale::Script codeToScript(QStringView code) noexcept;
- static QLocale::Country codeToCountry(QStringView code) noexcept;
-
- QLocale::MeasurementSystem measurementSystem() const;
+ [[nodiscard]] inline std::array<char, 4>
+ languageCode(QLocale::LanguageCodeTypes codeTypes = QLocale::AnyLanguageCode) const
+ {
+ return languageToCode(QLocale::Language(m_data->m_language_id), codeTypes);
+ }
+ [[nodiscard]] inline QLatin1StringView scriptCode() const
+ { return scriptToCode(QLocale::Script(m_data->m_script_id)); }
+ [[nodiscard]] inline QLatin1StringView territoryCode() const
+ { return territoryToCode(QLocale::Territory(m_data->m_territory_id)); }
+
+ [[nodiscard]] static const QLocalePrivate *get(const QLocale &l) { return l.d; }
+ [[nodiscard]] static std::array<char, 4>
+ languageToCode(QLocale::Language language,
+ QLocale::LanguageCodeTypes codeTypes = QLocale::AnyLanguageCode);
+ [[nodiscard]] static QLatin1StringView scriptToCode(QLocale::Script script);
+ [[nodiscard]] static QLatin1StringView territoryToCode(QLocale::Territory territory);
+ [[nodiscard]] static QLocale::Language
+ codeToLanguage(QStringView code,
+ QLocale::LanguageCodeTypes codeTypes = QLocale::AnyLanguageCode) noexcept;
+ [[nodiscard]] static QLocale::Script codeToScript(QStringView code) noexcept;
+ [[nodiscard]] static QLocale::Territory codeToTerritory(QStringView code) noexcept;
+
+ [[nodiscard]] QLocale::MeasurementSystem measurementSystem() const;
// System locale has an m_data all its own; all others have m_data = locale_data + m_index
const QLocaleData *const m_data;
QBasicAtomicInt ref;
- const uint m_index;
+ qsizetype m_index; // System locale needs this updated when m_data->id() changes.
QLocale::NumberOptions m_numberOptions;
+
+ static QBasicAtomicInt s_generation;
};
#ifndef QT_NO_SYSTEMLOCALE
-uint QSystemLocale::fallbackUiLocaleIndex() const { return fallbackUiLocale().d->m_index; }
+qsizetype QSystemLocale::fallbackLocaleIndex() const { return fallbackLocale().d->m_index; }
#endif
template <>
@@ -440,88 +546,26 @@ inline QLocalePrivate *QSharedDataPointer<QLocalePrivate>::clone()
return new QLocalePrivate(d->m_data, d->m_index, d->m_numberOptions);
}
-inline char QLocaleData::numericToCLocale(QStringView in) const
-{
- Q_ASSERT(in.size() == 1 || (in.size() == 2 && in.at(0).isHighSurrogate()));
-
- if (in == positiveSign() || in == u"+")
- return '+';
-
- if (in == negativeSign() || in == u"-" || in == u"\x2212")
- return '-';
-
- if (in == decimalPoint())
- return '.';
-
- if (in.compare(exponentSeparator(), Qt::CaseInsensitive) == 0)
- return 'e';
-
- const QString group = groupSeparator();
- if (in == group)
- return ',';
-
- // In several languages group() is a non-breaking space (U+00A0) or its thin
- // version (U+202f), which look like spaces. People (and thus some of our
- // tests) use a regular space instead and complain if it doesn't work.
- // Should this be extended generally to any case where group is a space ?
- if ((group == u"\xa0" || group == u"\x202f") && in == u" ")
- return ',';
-
- const char32_t inUcs4 = in.size() == 2
- ? QChar::surrogateToUcs4(in.at(0), in.at(1)) : in.at(0).unicode();
- const char32_t zeroUcs4 = zeroUcs();
- // Must match qlocale_tools.h's unicodeForDigit()
- if (zeroUcs4 == u'\u3007') {
- // QTBUG-85409: Suzhou's digits aren't contiguous !
- if (inUcs4 == zeroUcs4)
- return '0';
- if (inUcs4 > u'\u3020' && inUcs4 <= u'\u3029')
- return inUcs4 - u'\u3020';
- } else if (zeroUcs4 <= inUcs4 && inUcs4 < zeroUcs4 + 10) {
- return '0' + inUcs4 - zeroUcs4;
- }
- if ('0' <= inUcs4 && inUcs4 <= '9')
- return inUcs4;
+// Also used to merely skip over an escape in a format string, advancint idx to
+// point after it (so not [[nodiscard]]):
+QString qt_readEscapedFormatString(QStringView format, qsizetype *idx);
+[[nodiscard]] bool qt_splitLocaleName(QStringView name, QStringView *lang = nullptr,
+ QStringView *script = nullptr, QStringView *cntry = nullptr);
+[[nodiscard]] qsizetype qt_repeatCount(QStringView s);
- return 0;
-}
-
-QString qt_readEscapedFormatString(QStringView format, int *idx);
-bool qt_splitLocaleName(QStringView name, QStringView *lang = nullptr,
- QStringView *script = nullptr, QStringView *cntry = nullptr);
-int qt_repeatCount(QStringView s);
-
-enum { AsciiSpaceMask = (1u << (' ' - 1)) |
- (1u << ('\t' - 1)) | // 9: HT - horizontal tab
- (1u << ('\n' - 1)) | // 10: LF - line feed
- (1u << ('\v' - 1)) | // 11: VT - vertical tab
- (1u << ('\f' - 1)) | // 12: FF - form feed
- (1u << ('\r' - 1)) }; // 13: CR - carriage return
-constexpr inline bool ascii_isspace(uchar c)
+[[nodiscard]] constexpr inline bool ascii_isspace(uchar c)
{
- return c >= 1u && c <= 32u && (AsciiSpaceMask >> uint(c - 1)) & 1u;
+ constexpr auto matcher = QtPrivate::makeCharacterSetMatch<QtPrivate::ascii_space_chars>();
+ return matcher.matches(c);
}
-static_assert(ascii_isspace(' '));
-static_assert(ascii_isspace('\t'));
-static_assert(ascii_isspace('\n'));
-static_assert(ascii_isspace('\v'));
-static_assert(ascii_isspace('\f'));
-static_assert(ascii_isspace('\r'));
-static_assert(!ascii_isspace('\0'));
-static_assert(!ascii_isspace('\a'));
-static_assert(!ascii_isspace('a'));
-static_assert(!ascii_isspace('\177'));
-static_assert(!ascii_isspace(uchar('\200')));
-static_assert(!ascii_isspace(uchar('\xA0')));
-static_assert(!ascii_isspace(uchar('\377')));
-
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QStringView)
-Q_DECLARE_METATYPE(QList<Qt::DayOfWeek>)
+// ### move to qnamespace.h
+QT_DECL_METATYPE_EXTERN_TAGGED(QList<Qt::DayOfWeek>, QList_Qt__DayOfWeek, Q_CORE_EXPORT)
#ifndef QT_NO_SYSTEMLOCALE
-Q_DECLARE_METATYPE(QSystemLocale::CurrencyToStringArgument)
+QT_DECL_METATYPE_EXTERN_TAGGED(QSystemLocale::CurrencyToStringArgument,
+ QSystemLocale__CurrencyToStringArgument, Q_CORE_EXPORT)
#endif
#endif // QLOCALE_P_H