8#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1000
10
11
12
13
14
15
16
17QT_WARNING_DISABLE_GCC(
"-Wfree-nonheap-object")
20#if defined(Q_OS_MACOS)
21# include "private/qcore_mac_p.h"
22# include <CoreFoundation/CoreFoundation.h>
25#include "qplatformdefs.h"
30#include "private/qduplicatetracker_p.h"
37#include <private/qtools_p.h>
38#if QT_CONFIG(datetimeparser)
39#include "private/qdatetimeparser_p.h"
47#if QT_CONFIG(timezone)
48# include "qtimezone.h"
50#include "private/qnumeric_p.h"
51#include "private/qtools_p.h"
53#ifndef QT_NO_SYSTEMLOCALE
57# include <qt_windows.h>
61#include "private/qcalendarbackend_p.h"
62#include "private/qgregoriancalendar_p.h"
63#if QT_CONFIG(timezone) && QT_CONFIG(timezone_locale) && !QT_CONFIG(icu)
64# include "private/qtimezonelocale_p.h"
66#if QT_CONFIG(datestring)
67# include "private/qttemporalpattern_p.h"
70#include <q20iterator.h>
74constexpr int QLocale::DefaultTwoDigitBaseYear;
76QT_IMPL_METATYPE_EXTERN_TAGGED(QList<Qt::DayOfWeek>, QList_Qt__DayOfWeek)
77#ifndef QT_NO_SYSTEMLOCALE
78QT_IMPL_METATYPE_EXTERN_TAGGED(QSystemLocale::CurrencyToStringArgument,
79 QSystemLocale__CurrencyToStringArgument)
82using namespace Qt::StringLiterals;
83using namespace QtMiscUtils;
85#ifndef QT_NO_SYSTEMLOCALE
86Q_CONSTINIT
static QSystemLocale *_systemLocale =
nullptr;
87Q_CONSTINIT
static QLocaleData systemLocaleData = {};
90static_assert(ascii_isspace(
' '));
91static_assert(ascii_isspace(
'\t'));
92static_assert(ascii_isspace(
'\n'));
93static_assert(ascii_isspace(
'\v'));
94static_assert(ascii_isspace(
'\f'));
95static_assert(ascii_isspace(
'\r'));
96static_assert(!ascii_isspace(
'\0'));
97static_assert(!ascii_isspace(
'\a'));
98static_assert(!ascii_isspace(
'a'));
99static_assert(!ascii_isspace(
'\177'));
100static_assert(!ascii_isspace(uchar(
'\200')));
101static_assert(!ascii_isspace(uchar(
'\xA0')));
102static_assert(!ascii_isspace(uchar(
'\377')));
105
106
108QT_BEGIN_INCLUDE_NAMESPACE
110QT_END_INCLUDE_NAMESPACE
112QLocale::Language QLocalePrivate::codeToLanguage(QStringView code,
113 QLocale::LanguageCodeTypes codeTypes)
noexcept
115 const auto len = code.size();
116 if (len != 2 && len != 3)
117 return QLocale::AnyLanguage;
119 const char16_t uc1 = code[0].toLower().unicode();
120 const char16_t uc2 = code[1].toLower().unicode();
121 const char16_t uc3 = len > 2 ? code[2].toLower().unicode() : 0;
124 if (uc1 > 0x7F || uc2 > 0x7F || uc3 > 0x7F)
125 return QLocale::AnyLanguage;
127 const AlphaCode codeBuf = {
char(uc1),
char(uc2),
char(uc3) };
129 auto searchCode = [codeBuf](
auto f) {
130 return std::find_if(languageCodeList.begin(), languageCodeList.end(),
131 [=](LanguageCodeEntry i) {
return f(i) == codeBuf; });
134 if (codeTypes.testFlag(QLocale::ISO639Part1) && uc3 == 0) {
135 auto i = searchCode([](LanguageCodeEntry i) {
return i.part1; });
136 if (i != languageCodeList.end())
137 return QLocale::Language(std::distance(languageCodeList.begin(), i));
141 if (codeTypes.testFlag(QLocale::ISO639Part2B)) {
142 auto i = searchCode([](LanguageCodeEntry i) {
return i.part2B; });
143 if (i != languageCodeList.end())
144 return QLocale::Language(std::distance(languageCodeList.begin(), i));
149 if (codeTypes.testFlag(QLocale::ISO639Part2T)
150 && !codeTypes.testFlag(QLocale::ISO639Part3)) {
151 auto i = searchCode([](LanguageCodeEntry i) {
return i.part2T; });
152 if (i != languageCodeList.end())
153 return QLocale::Language(std::distance(languageCodeList.begin(), i));
156 if (codeTypes.testFlag(QLocale::ISO639Part3)) {
157 auto i = searchCode([](LanguageCodeEntry i) {
return i.part3; });
158 if (i != languageCodeList.end())
159 return QLocale::Language(std::distance(languageCodeList.begin(), i));
163 if (codeTypes.testFlag(QLocale::LegacyLanguageCode) && uc3 == 0) {
164 constexpr struct LegacyCodes {
166 QLocale::Language language;
168 { {
'n',
'o'}, QLocale::NorwegianBokmal },
169 { {
't',
'l'}, QLocale::Filipino },
170 { {
's',
'h'}, QLocale::Serbian },
171 { {
'm',
'o'}, QLocale::Romanian },
173 { {
'i',
'w'}, QLocale::Hebrew },
174 { {
'i',
'n'}, QLocale::Indonesian },
175 { {
'j',
'i'}, QLocale::Yiddish },
179 for (
const auto &e : legacyCodes) {
180 if (codeBuf == e.code)
184 return QLocale::AnyLanguage;
189 if (code.size() != 4)
194 const unsigned char c0 = (fixCase ? code[0].toUpper() : code[0]).toLatin1();
195 const unsigned char c1 = (fixCase ? code[1].toLower() : code[1]).toLatin1();
196 const unsigned char c2 = (fixCase ? code[2].toLower() : code[2]).toLatin1();
197 const unsigned char c3 = (fixCase ? code[3].toLower() : code[3]).toLatin1();
199 if (!c0 || !c1 || !c2 || !c3)
202 constexpr qsizetype NumScripts = QLocale::LastScript + 1;
205 for (qsizetype i = 0; i < NumScripts; ++i, c += 4) {
206 if (c0 == c[0] && c1 == c[1] && c2 == c[2] && c3 == c[3])
214 qsizetype index = scriptIndex(code, Qt::CaseInsensitive);
215 return index < 0 ? QLocale::AnyScript : QLocale::Script(index);
220 const auto len = code.size();
221 if (len != 2 && len != 3)
222 return QLocale::AnyTerritory;
224 char16_t uc1 = code[0].toUpper().unicode();
225 char16_t uc2 = code[1].toUpper().unicode();
226 char16_t uc3 = len > 2 ? code[2].toUpper().unicode() : 0;
229 for (; *c != 0; c += 3) {
230 if (uc1 == c[0] && uc2 == c[1] && uc3 == c[2])
231 return QLocale::Territory((c - territory_code_list)/3);
234 return QLocale::AnyTerritory;
238 QLocale::LanguageCodeTypes codeTypes)
240 if (language == QLocale::AnyLanguage || language > QLocale::LastLanguage)
242 if (language == QLocale::C)
247 if (codeTypes.testFlag(QLocale::ISO639Part1) && i
.part1.isValid())
250 if (codeTypes.testFlag(QLocale::ISO639Part2B) && i
.part2B.isValid())
253 if (codeTypes.testFlag(QLocale::ISO639Part2T) && i
.part2T.isValid())
256 if (codeTypes.testFlag(QLocale::ISO639Part3))
264 if (script == QLocale::AnyScript || script > QLocale::LastScript)
267 return {
reinterpret_cast<
const char *>(c), 4};
272 if (territory == QLocale::AnyTerritory || territory > QLocale::LastTerritory)
276 return {
reinterpret_cast<
const char*>(c), c[2] == 0 ? 2 : 3};
286bool operator<(LikelyPair lhs, LikelyPair rhs)
290 const auto compare = [](
int lhs,
int rhs) {
292 const int huge = 0x10000;
293 return (lhs ? lhs : huge) - (rhs ? rhs : huge);
295 const auto &left = lhs.key;
296 const auto &right = rhs.key;
298 if (
int cmp = compare(left.language_id, right.language_id))
300 if (
int cmp = compare(left.territory_id, right.territory_id))
302 return compare(left.script_id, right.script_id) < 0;
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
333
334
335
336
337
338
339
340
341
342
343
344
345
347 auto *pairs =
reinterpret_cast<
const LikelyPair *>(
likely_subtags);
349 LikelyPair sought { *
this };
354 pairs =
std::lower_bound(pairs, afterPairs, sought);
357 for (; pairs < afterPairs && pairs->key.language_id ==
language_id; ++pairs) {
374 pairs =
std::lower_bound(pairs, afterPairs, sought);
377 for (; pairs < afterPairs && pairs->key.territory_id ==
territory_id; ++pairs) {
392 sought.key = QLocaleId { 0,
script_id, 0 };
393 pairs =
std::lower_bound(pairs, afterPairs, sought);
394 if (pairs < afterPairs && pairs->key.script_id ==
script_id) {
395 Q_ASSERT(!pairs->key.language_id && !pairs->key.territory_id);
405 pairs = afterPairs - 1;
406 if (pairs->key.matchesAll()) {
445 if (language_id == QLocale::AnyLanguage)
447 if (language_id == QLocale::C)
448 return QByteArrayLiteral(
"C");
449 Q_ASSERT(language_id <= QLocale::LastLanguage);
450 Q_ASSERT(script_id <= QLocale::LastScript);
451 Q_ASSERT(territory_id <= QLocale::LastTerritory);
457 if (language
.part1.isValid()) {
465 const unsigned char *script =
466 (script_id != QLocale::AnyScript ? script_code_list + 4 * script_id :
nullptr);
467 const unsigned char *country =
468 (territory_id != QLocale::AnyTerritory
469 ? territory_code_list + 3 * territory_id :
nullptr);
470 qsizetype len = langLen + (script ? 4 + 1 : 0) + (country ? (country[2] != 0 ? 3 : 2) + 1 : 0);
472 char *uc = name.data();
474 auto langArray = lang.decode();
476 *uc++ = langArray[0];
477 *uc++ = langArray[1];
479 *uc++ = langArray[2];
500 if (m_data->m_language_id == QLocale::AnyLanguage)
502 if (m_data->m_language_id == QLocale::C)
503 return QByteArrayView(
"en") % separator % QByteArrayView(
"POSIX");
510 qsizetype idx = locale_index[localeId.language_id];
513 if (localeId.language_id && idx == 0)
516 Q_ASSERT(localeId.acceptLanguage(locale_data[idx].m_language_id));
519 if (localeId.acceptScriptTerritory(locale_data[idx].id()))
522 }
while (localeId.acceptLanguage(locale_data[idx].m_language_id));
528bool QLocaleData::allLocaleDataRows(
bool (*check)(qsizetype,
const QLocaleData &))
530 for (qsizetype index = 0; index < locale_data_size; ++index) {
531 if (!(*check)(index, locale_data[index]))
541 Q_PRE(index < locale_data_size);
545#if QT_CONFIG(timezone) && QT_CONFIG(timezone_locale) && !QT_CONFIG(icu)
546namespace QtTimeZoneLocale {
549QList<qsizetype> fallbackLocalesFor(qsizetype index)
553 Q_ASSERT(index < locale_data_size);
554 QList<qsizetype> result = {index};
555 QLocaleId id = locale_data[index].id();
556 if (id.language_id == QLocale::C) {
557 id = { QLocale::English, QLocale::LatinScript, QLocale::UnitedStates };
558 qsizetype it = findLocaleIndexById(id);
559 Q_ASSERT_X(it != -1, Q_FUNC_INFO,
"Missing en_Latn_US from locale data");
560 Q_ASSERT_X(it != index,
561 Q_FUNC_INFO,
"en_Latn_US != C");
565 const QLocaleId base = id;
566 QLocaleId likely = id.withLikelySubtagsAdded();
567 if (likely != base) {
568 qsizetype it = findLocaleIndexById(likely);
569 if (it != -1 && !result.contains(it))
572 if (id.territory_id) {
574 likely = id.withLikelySubtagsAdded();
575 if (likely != base) {
576 qsizetype it = findLocaleIndexById(likely);
577 if (it != -1 && !result.contains(it))
583 likely = id.withLikelySubtagsAdded();
584 if (likely != base) {
585 qsizetype it = findLocaleIndexById(likely);
586 if (it != -1 && !result.contains(it))
603 qsizetype index = findLocaleIndexById(likelyId);
607 tried.push_back(likelyId);
609#define CheckCandidate(id) do {
610 if (!tried.contains(id)) {
611 index = findLocaleIndexById(id);
643 return locale_index[fallback];
648 const std::u16string_view v(name.utf16(), size_t(name.size()));
649 const auto i = v.find_first_of(u"_-.@");
650 if (i == std::string_view::npos)
652 return name.first(qsizetype(i));
658 for (QChar uc : tag) {
659 const char16_t ch = uc.unicode();
660 if (!isAsciiLetterOrNumber(ch))
663 return tag.size() > 0;
667 QStringView *lang, QStringView *script, QStringView *land)
noexcept
670 enum ParserState { NoState, LangState, ScriptState, CountryState };
671 ParserState state = LangState;
672 while (name.size() && state != NoState) {
673 const QStringView tag = findTag(name);
676 name = name.sliced(tag.size());
677 const bool sep = name.size() > 0;
679 name = name.sliced(1);
683 if (tag.size() != 2 && tag.size() != 3)
687 state = sep ? ScriptState : NoState;
693 state = sep ? CountryState : NoState;
708 return state != LangState;
716 if (!qt_splitLocaleName(name, &lang, &script, &land))
717 return { QLocale::C, 0, 0 };
720 if (land.compare(
"POSIX", Qt::CaseInsensitive) == 0)
721 return { QLocale::C, 0, 0 };
723 QLocale::Language langId = QLocalePrivate::codeToLanguage(lang);
724 if (langId == QLocale::AnyLanguage)
725 return { QLocale::C, 0, 0 };
726 return { langId, QLocalePrivate::codeToScript(script), QLocalePrivate::codeToTerritory(land) };
733 Q_ASSERT(format.at(i) == u'\'');
735 if (i == format.size())
737 if (format.at(i).unicode() ==
'\'') {
744 while (i < format.size()) {
745 if (format.at(i).unicode() ==
'\'') {
746 if (format.mid(i + 1).startsWith(u'\'')) {
748 result.append(u'\'');
754 result.append(format.at(i++));
757 if (i < format.size())
763Q_CONSTINIT
static const QLocaleData *default_data =
nullptr;
764Q_CONSTINIT QBasicAtomicInt QLocalePrivate::s_generation = Q_BASIC_ATOMIC_INITIALIZER(0);
768 Q_CONSTINIT
static QLocalePrivate c_locale(locale_data, 0, QLocale::OmitGroupSeparator, 1);
774 return forLanguage == QLocale::C ? QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions;
779 return defaultNumberOptions(QLocale::Language(forLanguage));
782#ifndef QT_NO_SYSTEMLOCALE
784
785
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807QSystemLocale::QSystemLocale() : next(_systemLocale)
809 _systemLocale =
this;
811 systemLocaleData.m_language_id = 0;
815
816
817
818QSystemLocale::~QSystemLocale()
820 if (_systemLocale ==
this) {
821 _systemLocale = next;
824 systemLocaleData.m_language_id = 0;
826 for (QSystemLocale *p = _systemLocale; p; p = p->next) {
836 return _systemLocale;
841 static QSystemLocale globalInstance;
842 return &globalInstance;
850 const QSystemLocale *sys_locale = systemLocale();
853 sys_locale->query(QSystemLocale::LocaleChanged);
856 systemLocaleData = locale_data[sys_locale->fallbackLocaleIndex()];
858 QVariant res = sys_locale->query(QSystemLocale::LanguageId);
860 systemLocaleData.m_language_id = res.toInt();
861 systemLocaleData.m_script_id = QLocale::AnyScript;
863 res = sys_locale->query(QSystemLocale::TerritoryId);
865 systemLocaleData.m_territory_id = res.toInt();
866 systemLocaleData.m_script_id = QLocale::AnyScript;
868 res = sys_locale->query(QSystemLocale::ScriptId);
870 systemLocaleData.m_script_id = res.toInt();
875 if (default_data == &systemLocaleData)
876 QLocalePrivate::s_generation.fetchAndAddRelaxed(1);
882#ifndef QT_NO_SYSTEMLOCALE
884
885
886
887
888
889
890
892 Q_CONSTINIT
static QLocaleId sysId;
893 bool updated =
false;
895 Q_CONSTINIT
static QBasicMutex systemDataMutex;
896 systemDataMutex.lock();
897 if (systemLocaleData.m_language_id == 0) {
898 updateSystemPrivate();
902 if (sysIndex && (updated || *sysIndex < 0)) {
903 const QLocaleId nowId = systemLocaleData.id();
904 if (sysId != nowId || *sysIndex < 0) {
906 *sysIndex = QLocaleData::findLocaleIndex(nowId);
910 systemDataMutex.unlock();
913 return &systemLocaleData;
923 default_data = systemData();
930#ifndef QT_NO_SYSTEMLOCALE
931 if (data == &systemLocaleData) {
934 return QLocaleData::findLocaleIndex(data->id());
945 Q_ASSERT(locale_index[QLocale::C] == 0);
949#ifndef QT_NO_DATASTREAM
950QDataStream &operator<<(QDataStream &ds,
const QLocale &l)
956QDataStream &
operator>>(QDataStream &ds, QLocale &l)
966 new QLocalePrivate(defaultData(), defaultIndex(),
967 defaultNumberOptions(defaultData()->m_language_id)))
973 const qsizetype index = QLocaleData::findLocaleIndex(QLocaleId::fromName(name));
974 return new QLocalePrivate(QLocaleData::dataForLocaleIndex(index), index,
975 defaultNumberOptions(locale_data[index].m_language_id));
979 QLocale::Territory territory)
981 if (language == QLocale::C)
984 qsizetype index = QLocaleData::findLocaleIndex(QLocaleId { language, script, territory });
985 const QLocaleData *data = QLocaleData::dataForLocaleIndex(index);
987 QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
990 if (data->m_language_id == QLocale::C) {
991 if (defaultLocalePrivate.exists())
992 numberOptions = defaultLocalePrivate->data()->m_numberOptions;
994 index = defaultIndex();
1002 auto compareWithPrivate = [&loc](
const QLocaleData *data, QLocale::NumberOptions opts)
1004 return loc.d->m_data == data && loc.d->m_numberOptions == opts;
1007 if (lang == QLocale::C)
1010 qsizetype index = QLocaleData::findLocaleIndex(QLocaleId { lang });
1011 const QLocaleData *data = QLocaleData::dataForLocaleIndex(index);
1013 QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
1016 if (data->m_language_id == QLocale::C) {
1017 if (defaultLocalePrivate.exists())
1018 numberOptions = defaultLocalePrivate->data()->m_numberOptions;
1021 return compareWithPrivate(data, numberOptions);
1024static std::optional<QString>
1027#ifndef QT_NO_SYSTEMLOCALE
1028 if (that != &systemLocaleData)
1029 return std::nullopt;
1031 QVariant v = systemLocale()->query(type);
1032 if (v.metaType() != QMetaType::fromType<QString>())
1033 return std::nullopt;
1035 return v.toString();
1039 return std::nullopt;
1046 if (
auto opt = systemLocaleString(that, type))
1053 return localeString(
this, QSystemLocale::DecimalPoint, decimalSeparator());
1058 return localeString(
this, QSystemLocale::GroupSeparator, groupDelim());
1073 return localeString(
this, QSystemLocale::ZeroDigit, zero());
1078#ifndef QT_NO_SYSTEMLOCALE
1079 if (
this == &systemLocaleData) {
1080 const auto text = systemLocale()->query(QSystemLocale::ZeroDigit).toString();
1081 if (!text.isEmpty()) {
1082 if (text.size() == 1 && !text.at(0).isSurrogate())
1083 return text.at(0).unicode();
1084 if (text.size() == 2 && text.at(0).isHighSurrogate())
1085 return QChar::surrogateToUcs4(text.at(0), text.at(1));
1094 return localeString(
this, QSystemLocale::NegativeSign, minus());
1099 return localeString(
this, QSystemLocale::PositiveSign, plus());
1109#ifndef QT_NO_SYSTEMLOCALE
1110 if (
this == &systemLocaleData) {
1111 QVariant queryResult = systemLocale()->query(QSystemLocale::Grouping);
1112 if (!queryResult.isNull()) {
1115 if (sysGroupSizes.first <= 0)
1116 sysGroupSizes.first = m_grouping_first;
1117 if (sysGroupSizes.higher <= 0)
1118 sysGroupSizes.higher = m_grouping_higher;
1119 if (sysGroupSizes.least <= 0)
1120 sysGroupSizes.least = m_grouping_least;
1121 return sysGroupSizes;
1125 return { m_grouping_first,
1131
1132
1133QLocale::QLocale(QLocalePrivate &dd)
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184QLocale::QLocale(QStringView name)
1185 : d(localePrivateByName(name))
1190
1191
1192
1195
1196
1197
1198
1199
1200
1201
1206 if (!defaultLocalePrivate.isDestroyed()) {
1209 d = *defaultLocalePrivate;
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1225QLocale::QLocale(Language language, Territory territory)
1226 : d(findLocalePrivate(language, AnyScript, territory))
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1249QLocale::QLocale(Language language, Script script, Territory territory)
1250 : d(findLocalePrivate(language, script, territory))
1255
1256
1258QLocale::QLocale(
const QLocale &other)
noexcept =
default;
1261
1262
1269
1270
1271
1273QLocale &QLocale::operator=(
const QLocale &other)
noexcept =
default;
1276
1277
1278
1280bool QLocale::equals(
const QLocale &other)
const noexcept
1282 return d->m_data == other.d->m_data && d->m_numberOptions == other.d->m_numberOptions;
1286
1287
1288
1289
1292
1293
1294
1297 return qHashMulti(seed, key.d->m_data, key.d->m_numberOptions);
1301
1302
1303
1304
1305
1306
1307void QLocale::setNumberOptions(NumberOptions options)
1309 d->m_numberOptions = options;
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322QLocale::NumberOptions QLocale::numberOptions()
const
1324 return d->m_numberOptions;
1328
1329
1330
1331
1332
1333
1334
1337
1338
1339
1340
1341QString QLocale::quoteString(QStringView str, QuotationStyle style)
const
1343#ifndef QT_NO_SYSTEMLOCALE
1344 if (d->m_data == &systemLocaleData) {
1346 if (style == AlternateQuotation)
1347 res = systemLocale()->query(QSystemLocale::StringToAlternateQuotation,
1348 QVariant::fromValue(str));
1349 if (res.isNull() || style == StandardQuotation)
1350 res = systemLocale()->query(QSystemLocale::StringToStandardQuotation,
1351 QVariant::fromValue(str));
1353 return res.toString();
1357 QLocaleData::DataRange start, end;
1358 if (style == StandardQuotation) {
1359 start = d->m_data->quoteStart();
1360 end = d->m_data->quoteEnd();
1362 start = d->m_data->quoteStartAlternate();
1363 end = d->m_data->quoteEndAlternate();
1366 return start.viewData(single_character_data) % str % end.viewData(single_character_data);
1370
1371
1372
1373
1374
1375QString QLocale::createSeparatedList(
const QStringList &list)
const
1378#ifndef QT_NO_SYSTEMLOCALE
1379 if (d->m_data == &systemLocaleData) {
1381 systemLocale()->query(QSystemLocale::ListToSeparatedString, QVariant::fromValue(list));
1384 return res.toString();
1388 const qsizetype size = list.size();
1396 return d->m_data->pairListPattern().getData(
1397 list_pattern_part_data).arg(list.at(0), list.at(1));
1399 QStringView formatStart = d->m_data->startListPattern().viewData(list_pattern_part_data);
1400 QStringView formatMid = d->m_data->midListPattern().viewData(list_pattern_part_data);
1401 QStringView formatEnd = d->m_data->endListPattern().viewData(list_pattern_part_data);
1402 QString result = formatStart.arg(list.at(0), list.at(1));
1403 for (qsizetype i = 2; i < size - 1; ++i)
1404 result = formatMid.arg(result, list.at(i));
1405 result = formatEnd.arg(result, list.at(size - 1));
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1423void QLocale::setDefault(
const QLocale &locale)
1425 default_data = locale.d->m_data;
1427 if (defaultLocalePrivate.isDestroyed())
1429 if (!defaultLocalePrivate.exists()) {
1431 [[maybe_unused]] QLocale ignoreme;
1432 Q_ASSERT(defaultLocalePrivate.exists());
1436 *defaultLocalePrivate = locale.d;
1437 QLocalePrivate::s_generation.fetchAndAddRelaxed(1);
1441
1442
1443
1444
1445QLocale::Language QLocale::language()
const
1447 return Language(d->languageId());
1451
1452
1453
1454
1455
1456
1457QLocale::Script QLocale::script()
const
1459 return Script(d->m_data->m_script_id);
1463
1464
1465
1466
1467
1468
1469QLocale::Territory QLocale::territory()
const
1471 return Territory(d->territoryId());
1474#if QT_DEPRECATED_SINCE(6
, 6
)
1476
1477
1478
1479
1480
1481
1482QLocale::Country QLocale::country()
const
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1516 qWarning(
"QLocale::%s(): Using non-ASCII separator '%c' (%02x) is unsupported",
1517 method, sep, uint(uchar(sep)));
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1540QString QLocale::name(TagSeparator separator)
const
1542 const char sep =
char(separator);
1543 if (uchar(sep) > 0x7f) {
1544 badSeparatorWarning(
"name", sep);
1547 const auto code = d->languageCode();
1548 QLatin1StringView view{code.data()};
1550 Language l = language();
1554 Territory c = territory();
1555 if (c == AnyTerritory)
1558 return view + QLatin1Char(sep) + d->territoryCode();
1561template <
typename T>
static inline
1564 constexpr bool isUnsigned =
std::is_unsigned_v<T>;
1565 using Int64 =
typename std::conditional_t<isUnsigned, quint64, qint64>;
1567 QSimpleParsedNumber<Int64> r{};
1568 if constexpr (isUnsigned)
1569 r = d
->m_data->stringToUnsLongLong(str, 10, d->m_numberOptions);
1571 r = d
->m_data->stringToLongLong(str, 10, d->m_numberOptions);
1576 Int64 val = r.result;
1577 if (T(val) != val) {
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610QString QLocale::bcp47Name(TagSeparator separator)
const
1612 const char sep =
char(separator);
1613 if (uchar(sep) > 0x7f) {
1614 badSeparatorWarning(
"bcp47Name", sep);
1617 return QString::fromLatin1(d->bcp47Name(sep));
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638QString QLocale::languageToCode(Language language, LanguageCodeTypes codeTypes)
1640 const auto code = QLocalePrivate::languageToCode(language, codeTypes);
1641 return QLatin1StringView{code.data()};
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658QLocale::Language QLocale::codeToLanguage(QStringView languageCode,
1659 LanguageCodeTypes codeTypes)
noexcept
1661 return QLocalePrivate::codeToLanguage(languageCode, codeTypes);
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674QString QLocale::territoryToCode(QLocale::Territory territory)
1676 return QLocalePrivate::territoryToCode(territory);
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689QLocale::Territory QLocale::codeToTerritory(QStringView territoryCode)
noexcept
1691 return QLocalePrivate::codeToTerritory(territoryCode);
1694#if QT_DEPRECATED_SINCE(6
, 6
)
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705QString QLocale::countryToCode(Country country)
1707 return territoryToCode(country);
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720QLocale::Country QLocale::codeToCountry(QStringView countryCode)
noexcept
1722 return QLocalePrivate::codeToTerritory(countryCode);
1727
1728
1729
1730
1731
1732
1733
1734
1735QString QLocale::scriptToCode(Script script)
1737 return QLocalePrivate::scriptToCode(script);
1741
1742
1743
1744
1745
1746
1747
1748
1749QLocale::Script QLocale::codeToScript(QStringView scriptCode)
noexcept
1751 return QLocalePrivate::codeToScript(scriptCode);
1755
1756
1757
1758
1760QString QLocale::languageToString(Language language)
1762 if (language > LastLanguage)
1763 return "Unknown"_L1;
1764 return QString::fromUtf8(language_name_list + language_name_index[language]);
1768
1769
1770
1771
1772
1773
1774QString QLocale::territoryToString(Territory territory)
1776 if (territory > LastTerritory)
1777 return "Unknown"_L1;
1778 return QString::fromUtf8(territory_name_list + territory_name_index[territory]);
1781#if QT_DEPRECATED_SINCE(6
, 6
)
1783
1784
1785
1786
1787
1788
1789QString QLocale::countryToString(Country country)
1791 return territoryToString(country);
1796
1797
1798
1799
1800
1801
1802QString QLocale::scriptToString(Script script)
1804 if (script > LastScript)
1805 return "Unknown"_L1;
1806 return QString::fromUtf8(script_name_list + script_name_index[script]);
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1981short QLocale::toShort(QStringView s,
bool *ok)
const
1983 return toIntegral_helper<
short>(d, s, ok);
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2001ushort QLocale::toUShort(QStringView s,
bool *ok)
const
2003 return toIntegral_helper<ushort>(d, s, ok);
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2021int QLocale::toInt(QStringView s,
bool *ok)
const
2023 return toIntegral_helper<
int>(d, s, ok);
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2041uint QLocale::toUInt(QStringView s,
bool *ok)
const
2043 return toIntegral_helper<uint>(d, s, ok);
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2060long QLocale::toLong(QStringView s,
bool *ok)
const
2062 return toIntegral_helper<
long>(d, s, ok);
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2080ulong QLocale::toULong(QStringView s,
bool *ok)
const
2082 return toIntegral_helper<ulong>(d, s, ok);
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2101qlonglong QLocale::toLongLong(QStringView s,
bool *ok)
const
2103 return toIntegral_helper<qlonglong>(d, s, ok);
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2122qulonglong QLocale::toULongLong(QStringView s,
bool *ok)
const
2124 return toIntegral_helper<qulonglong>(d, s, ok);
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2143float QLocale::toFloat(QStringView s,
bool *ok)
const
2145 return QLocaleData::convertDoubleToFloat(toDouble(s, ok), ok);
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2169double QLocale::toDouble(QStringView s,
bool *ok)
const
2171 return d->m_data->stringToDouble(s, ok, d->m_numberOptions);
2175
2176
2177
2178
2180QString QLocale::toString(qlonglong i)
const
2182 int flags = (d->m_numberOptions & OmitGroupSeparator
2183 ? 0 : QLocaleData::GroupDigits);
2185 return d->m_data->longLongToString(i, -1, 10, -1, flags);
2189
2190
2191
2192
2194QString QLocale::toString(qulonglong i)
const
2196 int flags = (d->m_numberOptions & OmitGroupSeparator
2197 ? 0 : QLocaleData::GroupDigits);
2199 return d->m_data->unsLongLongToString(i, -1, 10, -1, flags);
2205 qsizetype count = 0;
2208 [[maybe_unused]]
auto ch = counter
.next();
2214 const QLocale &locale)
2217 if (!(locale.numberOptions() & QLocale::OmitGroupSeparator))
2221 else if (fillChar == U'0')
2233 if (fillChar == U'0') {
2234 Q_ASSERT(fieldWidth < 0);
2235 filler = localeData->zeroDigit();
2237 filler = QString(QChar::fromUcs4(fillChar));
2241 filler = filler.repeated(padding);
2246
2247
2248
2249
2250
2251
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271QString QLocale::toString(qlonglong number,
int fieldWidth,
char32_t fillChar)
const
2273 int absFieldWidth = qAbs(fieldWidth);
2274 int width = (fillChar == U'0') ? absFieldWidth : -1;
2275 unsigned flags = calculateFlags(fieldWidth, fillChar, *
this);
2277 QString result = d->m_data->longLongToString(number, -1, 10, width, flags);
2278 qsizetype padding = absFieldWidth - stringWidth(result);
2281 QString filler = calculateFiller(padding, fillChar, fieldWidth, d->m_data);
2283 result.append(filler);
2285 result.prepend(filler);
2291
2292
2293
2294
2295
2296
2298
2299
2300
2301QString QLocale::toString(qulonglong number,
int fieldWidth,
char32_t fillChar)
const
2303 int absFieldWidth = qAbs(fieldWidth);
2304 int width = (fillChar == U'0') ? absFieldWidth : -1;
2305 unsigned flags = calculateFlags(fieldWidth, fillChar, *
this);
2307 QString result = d->m_data->unsLongLongToString(number, -1, 10, width, flags);
2308 qsizetype padding = absFieldWidth - stringWidth(result);
2311 QString filler = calculateFiller(padding, fillChar, fieldWidth, d->m_data);
2313 result.append(filler);
2315 result.prepend(filler);
2321
2322
2324QString QLocale::toString(QDate date,
const QString &format)
const
2326 return toString(date, qToStringViewIgnoringNull(format));
2330
2331
2332
2333
2334
2335
2336
2337
2339QString QLocale::toString(QTime time,
const QString &format)
const
2341 return toString(time, qToStringViewIgnoringNull(format));
2345
2346
2347
2348
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362QString QLocale::toString(QDate date, QStringView format, QCalendar cal)
const
2364 return cal.dateTimeToString(format, QDateTime(), date, QTime(), *
this);
2368
2369
2370
2371QString QLocale::toString(QDate date, QStringView format)
const
2373 return QCalendar().dateTimeToString(format, QDateTime(), date, QTime(), *
this);
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386QString QLocale::toString(QDate date, FormatType format, QCalendar cal)
const
2388 if (!date.isValid())
2391#ifndef QT_NO_SYSTEMLOCALE
2392 if (cal.isGregorian() && d->m_data == &systemLocaleData) {
2393 QVariant res = systemLocale()->query(format == LongFormat
2394 ? QSystemLocale::DateToStringLong
2395 : QSystemLocale::DateToStringShort,
2398 return res.toString();
2402 QString format_str = dateFormat(format);
2403 return toString(date, format_str, cal);
2407
2408
2409
2410QString QLocale::toString(QDate date, FormatType format)
const
2412 if (!date.isValid())
2415#ifndef QT_NO_SYSTEMLOCALE
2416 if (d->m_data == &systemLocaleData) {
2417 QVariant res = systemLocale()->query(format == LongFormat
2418 ? QSystemLocale::DateToStringLong
2419 : QSystemLocale::DateToStringShort,
2422 return res.toString();
2426 QString format_str = dateFormat(format);
2427 return toString(date, format_str);
2433 while (i < format.size()) {
2434 if (format.at(i).unicode() ==
'\'') {
2435 qt_readEscapedFormatString(format, &i);
2439 if (format.at(i).toLower().unicode() ==
'a')
2448
2449
2450
2451QString QLocale::toString(QTime time, QStringView format)
const
2453 return QCalendar().dateTimeToString(format, QDateTime(), QDate(), time, *
this);
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467QString QLocale::toString(
const QDateTime &dateTime, QStringView format, QCalendar cal)
const
2469 return cal.dateTimeToString(format, dateTime, QDate(), QTime(), *
this);
2473
2474
2475
2476QString QLocale::toString(
const QDateTime &dateTime, QStringView format)
const
2478 return QCalendar().dateTimeToString(format, dateTime, QDate(), QTime(), *
this);
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491QString QLocale::toString(
const QDateTime &dateTime, FormatType format, QCalendar cal)
const
2493 if (!dateTime.isValid())
2496#ifndef QT_NO_SYSTEMLOCALE
2497 if (cal.isGregorian() && d->m_data == &systemLocaleData) {
2498 QVariant res = systemLocale()->query(format == LongFormat
2499 ? QSystemLocale::DateTimeToStringLong
2500 : QSystemLocale::DateTimeToStringShort,
2503 return res.toString();
2507 const QString format_str = dateTimeFormat(format);
2508 return toString(dateTime, format_str, cal);
2512
2513
2514
2515QString QLocale::toString(
const QDateTime &dateTime, FormatType format)
const
2517 if (!dateTime.isValid())
2520#ifndef QT_NO_SYSTEMLOCALE
2521 if (d->m_data == &systemLocaleData) {
2522 QVariant res = systemLocale()->query(format == LongFormat
2523 ? QSystemLocale::DateTimeToStringLong
2524 : QSystemLocale::DateTimeToStringShort,
2527 return res.toString();
2531 const QString format_str = dateTimeFormat(format);
2532 return toString(dateTime, format_str);
2537
2538
2539
2541QString QLocale::toString(QTime time, FormatType format)
const
2543 if (!time.isValid())
2546#ifndef QT_NO_SYSTEMLOCALE
2547 if (d->m_data == &systemLocaleData) {
2548 QVariant res = systemLocale()->query(format == LongFormat
2549 ? QSystemLocale::TimeToStringLong
2550 : QSystemLocale::TimeToStringShort,
2553 return res.toString();
2557 QString format_str = timeFormat(format);
2558 return toString(time, format_str);
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2573QString QLocale::dateFormat(FormatType format)
const
2575#ifndef QT_NO_SYSTEMLOCALE
2576 if (d->m_data == &systemLocaleData) {
2577 QVariant res = systemLocale()->query(format == LongFormat
2578 ? QSystemLocale::DateFormatLong
2579 : QSystemLocale::DateFormatShort,
2582 return res.toString();
2586 return (format == LongFormat
2587 ? d->m_data->longDateFormat()
2588 : d->m_data->shortDateFormat()
2589 ).getData(date_format_data);
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2604QString QLocale::timeFormat(FormatType format)
const
2606#ifndef QT_NO_SYSTEMLOCALE
2607 if (d->m_data == &systemLocaleData) {
2608 QVariant res = systemLocale()->query(format == LongFormat
2609 ? QSystemLocale::TimeFormatLong
2610 : QSystemLocale::TimeFormatShort,
2613 return res.toString();
2617 return (format == LongFormat
2618 ? d->m_data->longTimeFormat()
2619 : d->m_data->shortTimeFormat()
2620 ).getData(time_format_data);
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2635QString QLocale::dateTimeFormat(FormatType format)
const
2637#ifndef QT_NO_SYSTEMLOCALE
2638 if (d->m_data == &systemLocaleData) {
2639 QVariant res = systemLocale()->query(format == LongFormat
2640 ? QSystemLocale::DateTimeFormatLong
2641 : QSystemLocale::DateTimeFormatShort,
2643 if (!res.isNull()) {
2644 return res.toString();
2648 return dateFormat(format) + u' ' + timeFormat(format);
2651#if QT_CONFIG(datestring)
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667QTime QLocale::toTime(
const QString &string, FormatType format)
const
2669 return toTime(string, timeFormat(format));
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697QDate QLocale::toDate(
const QString &string, FormatType format,
int baseYear)
const
2699 return toDate(string, dateFormat(format), baseYear);
2703
2704
2705
2706QDate QLocale::toDate(
const QString &string, FormatType format, QCalendar cal,
int baseYear)
const
2708 return toDate(string, dateFormat(format), cal, baseYear);
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730QDateTime QLocale::toDateTime(
const QString &string, FormatType format,
int baseYear)
const
2732 return toDateTime(string, dateTimeFormat(format), baseYear);
2736
2737
2738
2739QDateTime QLocale::toDateTime(
const QString &string, FormatType format, QCalendar cal,
2742 return toDateTime(string, dateTimeFormat(format), cal, baseYear);
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760QTime QLocale::toTime(
const QString &string,
const QString &format)
const
2762#if QT_CONFIG(datetimeparser)
2763 QTimePattern pattern = QTimePattern::fromQtFormat(format);
2764 pattern.setLocale(*
this);
2765 if (
auto match = pattern.parse(string, QTime(0, 0)); match.size == string.size())
2766 return std::move(match.payload);
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799QDate QLocale::toDate(
const QString &string,
const QString &format,
int baseYear)
const
2801 return toDate(string, format, QCalendar(), baseYear);
2805
2806
2807
2808QDate QLocale::toDate(
const QString &string,
const QString &format, QCalendar cal,
int baseYear)
const
2810#if QT_CONFIG(datetimeparser)
2811 QDatePattern pattern = QDatePattern::fromQtFormat(format);
2812 pattern.setLocale(*
this);
2813 pattern.setCalendar(cal);
2814 pattern.setBaseYear(baseYear);
2815 if (
auto match = pattern.parse(string, QDate(baseYear, 1, 1, cal));
2816 match.size == string.size()) {
2817 return std::move(match.payload);
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852QDateTime QLocale::toDateTime(
const QString &string,
const QString &format,
int baseYear)
const
2854 return toDateTime(string, format, QCalendar(), baseYear);
2858
2859
2860
2861QDateTime QLocale::toDateTime(
const QString &string,
const QString &format, QCalendar cal,
2864#if QT_CONFIG(datetimeparser)
2865 QDateTimePattern pattern = QDateTimePattern::fromQtFormat(format);
2866 pattern.setLocale(*
this);
2867 pattern.setCalendar(cal);
2868 pattern.setBaseYear(baseYear);
2869 if (
auto match = pattern.parse(string, QDate(baseYear, 1, 1, cal).startOfDay());
2870 match.size == string.size()) {
2871 return std::move(match.payload);
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897QString QLocale::decimalPoint()
const
2899 return d->m_data->decimalPoint();
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916QString QLocale::groupSeparator()
const
2918 return d->m_data->groupSeparator();
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933QString QLocale::percent()
const
2935 return d->m_data->percentSign();
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952QString QLocale::zeroDigit()
const
2954 return d->m_data->zeroDigit();
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969QString QLocale::negativeSign()
const
2971 return d->m_data->negativeSign();
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986QString QLocale::positiveSign()
const
2988 return d->m_data->positiveSign();
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004QString QLocale::exponential()
const
3006 return d->m_data->exponentSeparator();
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3043QString QLocale::toString(
double f,
char format,
int precision)
const
3045 QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
3046 uint flags = isAsciiUpper(format) ? QLocaleData::CapitalEorX : 0;
3048 switch (QtMiscUtils::toAsciiLower(format)) {
3050 form = QLocaleData::DFDecimal;
3053 form = QLocaleData::DFExponent;
3056 form = QLocaleData::DFSignificantDigits;
3062 if (!(d->m_numberOptions & OmitGroupSeparator))
3063 flags |= QLocaleData::GroupDigits;
3064 if (!(d->m_numberOptions & OmitLeadingZeroInExponent))
3065 flags |= QLocaleData::ZeroPadExponent;
3066 if (d->m_numberOptions & IncludeTrailingZeroesAfterDot)
3067 flags |= QLocaleData::AddTrailingZeroes;
3068 return d->m_data->doubleToString(f, precision, form, -1, flags);
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087QLocale QLocale::c()
noexcept
3089 return QLocale(*c_private());
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3106QLocale QLocale::system()
3108 constexpr auto sysData = []() {
3110#ifdef QT_NO_SYSTEMLOCALE
3113 return &systemLocaleData;
3116 Q_CONSTINIT
static QLocalePrivate locale(sysData(), -1, DefaultNumberOptions, 1);
3119 systemData(&locale.m_index);
3120 Q_ASSERT(locale.m_index >= 0 && locale.m_index < locale_data_size);
3121 locale.m_numberOptions = defaultNumberOptions(locale.m_data->m_language_id);
3123 return QLocale(locale);
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138QList<QLocale> QLocale::matchingLocales(Language language, Script script, Territory territory)
3140 QList<QLocale> result;
3142 const QLocaleId filter { language, script, territory };
3143 if (!filter.isValid())
3146 if (language == C) {
3147 result.emplace_back(C);
3151 if (filter.matchesAll())
3152 result.reserve(locale_data_size);
3154 quint16 index = locale_index[language];
3156 while (index < locale_data_size
3157 && filter.acceptLanguage(locale_data[index].m_language_id)) {
3158 const QLocaleId id = locale_data[index].id();
3159 if (filter.acceptScriptTerritory(id)) {
3160 result.append(QLocale(*(id.language_id == C ? c_private()
3161 :
new QLocalePrivate(locale_data + index, index))));
3167 const auto syslocaledata = systemData();
3169 if (filter.acceptLanguage(syslocaledata->m_language_id)) {
3170 const QLocaleId id = syslocaledata->id();
3171 if (filter.acceptScriptTerritory(id))
3172 result.append(system());
3178#if QT_DEPRECATED_SINCE(6
, 6
)
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
3191 const auto locales = matchingLocales(language, AnyScript, AnyCountry);
3192 QList<Country> result;
3193 result.reserve(locales.size());
3194 for (
const auto &locale : locales)
3195 result.append(locale.territory());
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212QString QLocale::monthName(
int month, FormatType type)
const
3214 return QCalendar().monthName(*
this, month, QCalendar::Unspecified, type);
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228QString QLocale::standaloneMonthName(
int month, FormatType type)
const
3230 return QCalendar().standaloneMonthName(*
this, month, QCalendar::Unspecified, type);
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246QString QLocale::dayName(
int day, FormatType type)
const
3248 return QCalendar().weekDayName(*
this, day, type);
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263QString QLocale::standaloneDayName(
int day, FormatType type)
const
3265 return QCalendar().standaloneWeekDayName(*
this, day, type);
3272 const QCalendarLocale *table)
3275 [[maybe_unused]]
const auto sameLocale = [](
const QLocaleData &locale,
3276 const QCalendarLocale &cal) {
3277 return locale.m_language_id == cal.m_language_id
3278 && locale.m_script_id == cal.m_script_id
3279 && locale.m_territory_id == cal.m_territory_id;
3281 const QCalendarLocale &monthly = table[loc->m_index];
3282#ifdef QT_NO_SYSTEMLOCALE
3283 [[maybe_unused]]
constexpr bool isSys =
false;
3285 [[maybe_unused]]
const bool isSys = loc->m_data == &systemLocaleData;
3290 Q_ASSERT(sameLocale(
locale_data[loc->m_index], monthly));
3295
3296
3299 const char16_t *monthsData,
int month,
3300 QLocale::FormatType type)
3303 return range.getListEntry(monthsData, month - 1);
3307
3308
3311 const char16_t *monthsData,
int month,
3312 QLocale::FormatType type)
3315 if (QString name = range.getListEntry(monthsData, month - 1); !name.isEmpty())
3317 return rawMonthName(localeData, monthsData, month, type);
3321
3322
3325 QLocale::FormatType type)
3329 case QLocale::LongFormat:
3330 range = data->longDayNames();
3332 case QLocale::ShortFormat:
3333 range = data->shortDayNames();
3335 case QLocale::NarrowFormat:
3336 range = data->narrowDayNames();
3341 return range.getListEntry(
days_data, day == 7 ? 0 : day);
3345
3346
3349 QLocale::FormatType type)
3353 case QLocale::LongFormat:
3354 range =data->longDayNamesStandalone();
3356 case QLocale::ShortFormat:
3357 range = data->shortDayNamesStandalone();
3359 case QLocale::NarrowFormat:
3360 range = data->narrowDayNamesStandalone();
3365 QString name = range.getListEntry(days_data, day == 7 ? 0 : day);
3367 return rawWeekDayName(data, day, type);
3373QString QCalendarBackend::monthName(
const QLocale &locale,
int month,
int,
3374 QLocale::FormatType format)
const
3376 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3377 return rawMonthName(getMonthDataFor(locale.d, localeMonthIndexData()),
3378 localeMonthData(), month, format);
3381QString QRomanCalendar::monthName(
const QLocale &locale,
int month,
int year,
3382 QLocale::FormatType format)
const
3384#ifndef QT_NO_SYSTEMLOCALE
3385 if (locale.d->m_data == &systemLocaleData) {
3386 Q_ASSERT(month >= 1 && month <= 12);
3387 QSystemLocale::QueryType queryType = QSystemLocale::MonthNameLong;
3389 case QLocale::LongFormat:
3390 queryType = QSystemLocale::MonthNameLong;
3392 case QLocale::ShortFormat:
3393 queryType = QSystemLocale::MonthNameShort;
3395 case QLocale::NarrowFormat:
3396 queryType = QSystemLocale::MonthNameNarrow;
3399 QVariant res = systemLocale()->query(queryType, month);
3401 return res.toString();
3405 return QCalendarBackend::monthName(locale, month, year, format);
3408QString QCalendarBackend::standaloneMonthName(
const QLocale &locale,
int month,
int,
3409 QLocale::FormatType format)
const
3411 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3412 return rawStandaloneMonthName(getMonthDataFor(locale.d, localeMonthIndexData()),
3413 localeMonthData(), month, format);
3416QString QRomanCalendar::standaloneMonthName(
const QLocale &locale,
int month,
int year,
3417 QLocale::FormatType format)
const
3419#ifndef QT_NO_SYSTEMLOCALE
3420 if (locale.d->m_data == &systemLocaleData) {
3421 Q_ASSERT(month >= 1 && month <= 12);
3422 QSystemLocale::QueryType queryType = QSystemLocale::StandaloneMonthNameLong;
3424 case QLocale::LongFormat:
3425 queryType = QSystemLocale::StandaloneMonthNameLong;
3427 case QLocale::ShortFormat:
3428 queryType = QSystemLocale::StandaloneMonthNameShort;
3430 case QLocale::NarrowFormat:
3431 queryType = QSystemLocale::StandaloneMonthNameNarrow;
3434 QVariant res = systemLocale()->query(queryType, month);
3436 return res.toString();
3440 return QCalendarBackend::standaloneMonthName(locale, month, year, format);
3445QString QCalendarBackend::weekDayName(
const QLocale &locale,
int day,
3446 QLocale::FormatType format)
const
3448 if (day < 1 || day > 7)
3451#ifndef QT_NO_SYSTEMLOCALE
3452 if (locale.d->m_data == &systemLocaleData) {
3453 QSystemLocale::QueryType queryType = QSystemLocale::DayNameLong;
3455 case QLocale::LongFormat:
3456 queryType = QSystemLocale::DayNameLong;
3458 case QLocale::ShortFormat:
3459 queryType = QSystemLocale::DayNameShort;
3461 case QLocale::NarrowFormat:
3462 queryType = QSystemLocale::DayNameNarrow;
3465 QVariant res = systemLocale()->query(queryType, day);
3467 return res.toString();
3471 return rawWeekDayName(locale.d->m_data, day, format);
3474QString QCalendarBackend::standaloneWeekDayName(
const QLocale &locale,
int day,
3475 QLocale::FormatType format)
const
3477 if (day < 1 || day > 7)
3480#ifndef QT_NO_SYSTEMLOCALE
3481 if (locale.d->m_data == &systemLocaleData) {
3482 QSystemLocale::QueryType queryType = QSystemLocale::StandaloneDayNameLong;
3484 case QLocale::LongFormat:
3485 queryType = QSystemLocale::StandaloneDayNameLong;
3487 case QLocale::ShortFormat:
3488 queryType = QSystemLocale::StandaloneDayNameShort;
3490 case QLocale::NarrowFormat:
3491 queryType = QSystemLocale::StandaloneDayNameNarrow;
3494 QVariant res = systemLocale()->query(queryType, day);
3496 return res.toString();
3500 return rawStandaloneWeekDayName(locale.d->m_data, day, format);
3506
3507
3508
3509
3510Qt::DayOfWeek QLocale::firstDayOfWeek()
const
3512#ifndef QT_NO_SYSTEMLOCALE
3513 if (d->m_data == &systemLocaleData) {
3514 const auto res = systemLocale()->query(QSystemLocale::FirstDayOfWeek);
3516 return static_cast<Qt::DayOfWeek>(res.toUInt());
3519 return static_cast<Qt::DayOfWeek>(d->m_data->m_first_day_of_week);
3525
3526
3527
3528
3529 struct TerritoryLanguage
3532 quint16 territoryId;
3533 QLocale::MeasurementSystem system;
3536 constexpr TerritoryLanguage ImperialMeasurementSystems[] = {
3537 { QLocale::English, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3538 { QLocale::English, QLocale::UnitedStatesMinorOutlyingIslands, QLocale::ImperialUSSystem },
3539 { QLocale::Spanish, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3540 { QLocale::Hawaiian, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3541 { QLocale::English, QLocale::UnitedKingdom, QLocale::ImperialUKSystem }
3544 for (
const auto &system : ImperialMeasurementSystems) {
3545 if (system.languageId == m_data->m_language_id
3546 && system.territoryId == m_data->m_territory_id) {
3547 return system.system;
3550 return QLocale::MetricSystem;
3554
3555
3556
3557
3558QList<Qt::DayOfWeek> QLocale::weekdays()
const
3560#ifndef QT_NO_SYSTEMLOCALE
3561 if (d->m_data == &systemLocaleData) {
3563 = qvariant_cast<QList<Qt::DayOfWeek> >(systemLocale()->query(QSystemLocale::Weekdays));
3568 QList<Qt::DayOfWeek> weekdays;
3569 quint16 weekendStart = d->m_data->m_weekend_start;
3570 quint16 weekendEnd = d->m_data->m_weekend_end;
3571 for (
int day = Qt::Monday; day <= Qt::Sunday; day++) {
3572 if ((weekendEnd >= weekendStart && (day < weekendStart || day > weekendEnd)) ||
3573 (weekendEnd < weekendStart && (day > weekendEnd && day < weekendStart)))
3574 weekdays <<
static_cast<Qt::DayOfWeek>(day);
3580
3581
3582
3583
3584QLocale::MeasurementSystem QLocale::measurementSystem()
const
3586#ifndef QT_NO_SYSTEMLOCALE
3587 if (d->m_data == &systemLocaleData) {
3588 const auto res = systemLocale()->query(QSystemLocale::MeasurementSystem);
3590 return MeasurementSystem(res.toInt());
3594 return d->measurementSystem();
3598
3599
3600
3601
3602Qt::LayoutDirection QLocale::textDirection()
const
3611 case ImperialAramaicScript:
3612 case InscriptionalPahlaviScript:
3613 case InscriptionalParthianScript:
3614 case KharoshthiScript:
3616 case MandaeanScript:
3617 case ManichaeanScript:
3618 case MendeKikakuiScript:
3619 case MeroiticCursiveScript:
3620 case MeroiticScript:
3621 case NabataeanScript:
3623 case OldHungarianScript:
3624 case OldNorthArabianScript:
3625 case OldSouthArabianScript:
3627 case PalmyreneScript:
3628 case PhoenicianScript:
3629 case PsalterPahlaviScript:
3630 case SamaritanScript:
3633 return Qt::RightToLeft;
3637 return Qt::LeftToRight;
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655QString QLocale::toUpper(
const QString &str)
const
3657#if !defined(QT_BOOTSTRAPPED) && (QT_CONFIG(icu) || defined(Q_OS_WIN) || defined(Q_OS_APPLE))
3659 QString result = d->toUpper(str, &ok);
3664 return str.toUpper();
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679QString QLocale::toLower(
const QString &str)
const
3681#if !defined(QT_BOOTSTRAPPED) && (QT_CONFIG(icu) || defined(Q_OS_WIN) || defined(Q_OS_APPLE))
3683 const QString result = d->toLower(str, &ok);
3688 return str.toLower();
3693
3694
3695
3696
3697
3698
3699
3700QString QLocale::amText()
const
3702#ifndef QT_NO_SYSTEMLOCALE
3703 if (d->m_data == &systemLocaleData) {
3704 auto res = systemLocale()->query(QSystemLocale::AMText).toString();
3709 return d->m_data->anteMeridiem().getData(am_data);
3713
3714
3715
3716
3717
3718
3719
3720QString QLocale::pmText()
const
3722#ifndef QT_NO_SYSTEMLOCALE
3723 if (d->m_data == &systemLocaleData) {
3724 auto res = systemLocale()->query(QSystemLocale::PMText).toString();
3729 return d->m_data->postMeridiem().getData(pm_data);
3735 QStringView tail{text};
3737 if (tail.startsWith(
"UTC"_L1) || tail.startsWith(
"GMT"_L1))
3738 tail = tail.sliced(3);
3741 return (tail.isEmpty()
3746 : std::move(text).right(tail.size())));
3750#if !QT_CONFIG(datestring)
3752#elif QT_CONFIG(icu) || !(QT_CONFIG(timezone) && QT_CONFIG(timezone_locale))
3753namespace QtTimeZoneLocale {
3757QString zoneOffsetFormat([[maybe_unused]]
const QLocale &locale,
3759 QtTemporalPattern::TemporalFieldFlags,
3760 const QDateTime &when,
3766#if QT_CONFIG(timezone)
3767 locale != QLocale::system()
3768 ? when.timeRepresentation().displayName(when, QTimeZone::OffsetName, locale)
3771 when.toOffsetFromUtc(offsetSeconds).timeZoneAbbreviation();
3773 if (!text.isEmpty())
3774 text = offsetFromAbbreviation(std::move(text));
3783QString QCalendarBackend::dateTimeToString(QStringView format,
const QDateTime &datetime,
3784 QDate dateOnly, QTime timeOnly,
3785 const QLocale &locale)
const
3789 bool formatDate =
false;
3790 bool formatTime =
false;
3791 if (datetime.isValid()) {
3792 date = datetime.date();
3793 time = datetime.time();
3796 }
else if (dateOnly.isValid()) {
3799 }
else if (timeOnly.isValid()) {
3807 int year = 0, month = 0, day = 0;
3809 const auto parts = julianDayToDate(date.toJulianDay());
3810 if (!parts.isValid())
3813 month = parts.month;
3817 auto appendToResult = [&](
int t,
int repeat) {
3818 auto data = locale.d->m_data;
3820 result.append(data->longLongToString(t, -1, 10, repeat, QLocaleData::ZeroPadded));
3822 result.append(data->longLongToString(t));
3825 auto formatType = [](
int repeat) {
3826 return repeat == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
3830 while (i < format.size()) {
3831 if (format.at(i).unicode() ==
'\'') {
3832 result.append(qt_readEscapedFormatString(format, &i));
3836 const QChar c = format.at(i);
3837 qsizetype rep = qt_repeatCount(format.mid(i));
3838 Q_ASSERT(rep < std::numeric_limits<
int>::max());
3839 int repeat =
int(rep);
3842 switch (c.unicode()) {
3847 else if (repeat >= 2)
3854 result.append(locale.positiveSign());
3855 appendToResult(year, (year < 0) ? 5 : 4);
3858 appendToResult(year % 100, 2);
3869 repeat = qMin(repeat, 4);
3871 appendToResult(month, repeat);
3873 result.append(monthName(locale, month, year, formatType(repeat)));
3878 repeat = qMin(repeat, 4);
3880 appendToResult(day, repeat);
3883 locale.dayName(dayOfWeek(date.toJulianDay()), formatType(repeat)));
3890 if (!used && formatTime) {
3891 switch (c.unicode()) {
3894 repeat = qMin(repeat, 2);
3895 int hour = time.hour();
3896 if (timeFormatContainsAP(format)) {
3902 appendToResult(hour, repeat);
3907 repeat = qMin(repeat, 2);
3908 appendToResult(time.hour(), repeat);
3913 repeat = qMin(repeat, 2);
3914 appendToResult(time.minute(), repeat);
3919 repeat = qMin(repeat, 2);
3920 appendToResult(time.second(), repeat);
3925 QString text = time.hour() < 12 ? locale.amText() : locale.pmText();
3928 if (format.mid(i + 1).startsWith(u'p', Qt::CaseInsensitive))
3930 if (c.unicode() ==
'A' && (repeat == 1 || format.at(i + 1).unicode() ==
'P'))
3931 text = std::move(text).toUpper();
3932 else if (c.unicode() ==
'a' && (repeat == 1 || format.at(i + 1).unicode() ==
'p'))
3933 text = std::move(text).toLower();
3935 result.append(text);
3941 repeat = qMin(repeat, 3);
3945 appendToResult(time.msec(), 3);
3947 const QString zero = locale.zeroDigit();
3948 if (result.endsWith(zero))
3949 result.chop(zero.size());
3950 if (result.endsWith(zero))
3951 result.chop(zero.size());
3956#if QT_CONFIG(datestring)
3960 enum AbbrType { Long, Offset, Short };
3961 const auto tzAbbr = [locale](
const QDateTime &when, AbbrType type) {
3963 if (type == Offset) {
3964 using Flag = QtTemporalPattern::TemporalFieldFlag;
3965 constexpr auto noPrefixOffset = Flag::Numeric | Flag::Abbreviated
3966 | Flag::NeedNoUtcPrefix | Flag::ZeroPad;
3967 text = QtTimeZoneLocale::zoneOffsetFormat(locale, locale.d->m_index,
3969 when, when.offsetFromUtc());
3971 if (!text.isEmpty())
3974# if QT_CONFIG(timezone)
3975 if (type != Short || locale != QLocale::system()) {
3976 QTimeZone::NameType mode =
3977 type == Short ? QTimeZone::ShortName
3978 : type == Long ? QTimeZone::LongName : QTimeZone::OffsetName;
3979 text = when.timeRepresentation().displayName(when, mode, locale);
3980 if (!text.isEmpty())
3986 text = QString::fromLatin1(when.timeZone().id());
3987 if (!text.isEmpty())
3994 text = when.toOffsetFromUtc(when.offsetFromUtc()).timeZoneAbbreviation();
3996 text = when.timeZoneAbbreviation();
3998 text = offsetFromAbbreviation(std::move(text));
4003 repeat = qMin(repeat, 4);
4005 const QDateTime when = formatDate ? datetime : QDateTime::currentDateTime();
4009 text = tzAbbr(when, Long);
4013 text = tzAbbr(when, Offset);
4018 text = tzAbbr(when, Short);
4020 if (text.startsWith(
"UTC"_L1) && text.size() == 6)
4024 if (!text.isEmpty())
4025 result.append(text);
4035 result.resize(result.size() + repeat, c);
4044 int width,
unsigned flags)
const
4051 if (precision != QLocale::FloatingPointShortest && precision < 0)
4057 qsizetype bufSize = 1;
4058 if (precision == QLocale::FloatingPointShortest)
4059 bufSize += std::numeric_limits<
double>::max_digits10;
4060 else if (form == DFDecimal && qt_is_finite(d))
4061 bufSize += wholePartSpace(qAbs(d)) + precision;
4063 bufSize += qMax(2, precision) + 1;
4065 QVarLengthArray<
char> buf(bufSize);
4067 bool negative =
false;
4068 qt_doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
4070 const QString prefix = signPrefix(negative && !qIsNull(d), flags);
4074 && (qstrncmp(buf.data(),
"inf", 3) == 0 || qstrncmp(buf.data(),
"nan", 3) == 0)) {
4075 numStr = QString::fromLatin1(buf.data(), length);
4077 const QString zero = zeroDigit();
4078 QString digits = QString::fromLatin1(buf.data(), length);
4082 Q_ASSERT(
std::all_of(buf.cbegin(), buf.cbegin() + length, isAsciiDigit));
4084 }
else if (zero.size() == 2 && zero.at(0).isHighSurrogate()) {
4085 const char32_t zeroUcs4 = QChar::surrogateToUcs4(zero.at(0), zero.at(1));
4087 converted.reserve(2 * digits.size());
4088 for (QChar ch : std::as_const(digits)) {
4089 const char32_t digit = unicodeForDigit(ch.unicode() -
'0', zeroUcs4);
4090 Q_ASSERT(QChar::requiresSurrogates(digit));
4091 converted.append(QChar::highSurrogate(digit));
4092 converted.append(QChar::lowSurrogate(digit));
4094 digits =
std::move(converted);
4096 Q_ASSERT(zero.size() == 1);
4097 Q_ASSERT(!zero.at(0).isSurrogate());
4098 char16_t z = zero.at(0).unicode();
4099 char16_t *
const value =
reinterpret_cast<
char16_t *>(digits.data());
4100 for (qsizetype i = 0; i < digits.size(); ++i)
4101 value[i] = unicodeForDigit(value[i] -
'0', z);
4104 const bool mustMarkDecimal = flags &
ForcePoint;
4109 numStr = exponentForm(
std::move(digits), decpt, precision, PMDecimalDigits,
4110 mustMarkDecimal, minExponentDigits);
4113 numStr = decimalForm(
std::move(digits), decpt, precision, PMDecimalDigits,
4114 mustMarkDecimal, groupDigits);
4121
4122
4123
4124
4125
4126
4127
4128
4130 if (precision == QLocale::FloatingPointShortest) {
4137 int bias = 2 + minExponentDigits;
4139 if (groupDigits && decpt >= grouping
.first + grouping
.least)
4142 if (decpt > 10 && minExponentDigits == 1)
4147 const qsizetype digitCount = digits.size() / zero.size();
4148 if (!mustMarkDecimal) {
4151 if (digitCount <= decpt && digitCount > 1)
4153 else if (digitCount == 1 && decpt <= 0)
4161 useDecimal = (decpt <= 0 ? 1 - decpt <= bias
4162 : decpt <= digitCount ? 0 <= bias : decpt <= digitCount + bias);
4165 Q_ASSERT(precision >= 0);
4166 useDecimal = decpt > -4 && decpt <= (precision ? precision : 1);
4170 ? decimalForm(
std::move(digits), decpt, precision, mode,
4171 mustMarkDecimal, groupDigits)
4172 : exponentForm(
std::move(digits), decpt, precision, mode,
4173 mustMarkDecimal, minExponentDigits);
4180 for (qsizetype i = numStr.size() / zero.size() + prefix.size(); i < width; ++i)
4181 numStr.prepend(zero);
4186 ?
std::move(numStr).toUpper()
4187 :
std::move(numStr).toLower());
4190QString
QLocaleData::decimalForm(QString &&digits,
int decpt,
int precision,
4191 PrecisionMode pm,
bool mustMarkDecimal,
4192 bool groupDigits)
const
4194 const QString zero = zeroDigit();
4195 const auto digitWidth = zero.size();
4196 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
4197 Q_ASSERT(digits.size() % digitWidth == 0);
4202 for (; decpt < 0; ++decpt)
4203 digits.prepend(zero);
4205 for (qsizetype i = digits.size() / digitWidth; i < decpt; ++i)
4206 digits.append(zero);
4210 case PMDecimalDigits:
4211 for (qsizetype i = digits.size() / digitWidth - decpt; i < precision; ++i)
4212 digits.append(zero);
4214 case PMSignificantDigits:
4215 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
4216 digits.append(zero);
4218 case PMChopTrailingZeros:
4219 Q_ASSERT(digits.size() / digitWidth <= qMax(decpt, 1) || !digits.endsWith(zero));
4223 if (mustMarkDecimal || decpt < digits.size() / digitWidth)
4224 digits.insert(decpt * digitWidth, decimalPoint());
4228 const QString group = groupSeparator();
4229 qsizetype i = decpt - grouping.least;
4230 if (i >= grouping.first) {
4231 digits.insert(i * digitWidth, group);
4232 while ((i -= grouping.higher) > 0)
4233 digits.insert(i * digitWidth, group);
4238 digits.prepend(zero);
4240 return std::move(digits);
4243QString
QLocaleData::exponentForm(QString &&digits,
int decpt,
int precision,
4244 PrecisionMode pm,
bool mustMarkDecimal,
4245 int minExponentDigits)
const
4247 const QString zero = zeroDigit();
4248 const auto digitWidth = zero.size();
4249 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
4250 Q_ASSERT(digits.size() % digitWidth == 0);
4253 case PMDecimalDigits:
4254 for (qsizetype i = digits.size() / digitWidth; i < precision + 1; ++i)
4255 digits.append(zero);
4257 case PMSignificantDigits:
4258 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
4259 digits.append(zero);
4261 case PMChopTrailingZeros:
4262 Q_ASSERT(digits.size() / digitWidth <= 1 || !digits.endsWith(zero));
4266 if (mustMarkDecimal || digits.size() > digitWidth)
4267 digits.insert(digitWidth, decimalPoint());
4269 digits.append(exponentSeparator());
4270 digits.append(longLongToString(decpt - 1, minExponentDigits, 10, -1, AlwaysShowSign));
4272 return std::move(digits);
4275QString
QLocaleData::signPrefix(
bool negative,
unsigned flags)
const
4278 return negativeSign();
4279 if (flags & AlwaysShowSign)
4280 return positiveSign();
4281 if (flags & BlankBeforePositive)
4287 int base,
int width,
unsigned flags)
const
4289 bool negative = n < 0;
4292
4293
4294
4295 QString numStr = qulltoa(negative ? 1u + qulonglong(-(n + 1)) : qulonglong(n),
4298 return applyIntegerFormatting(
std::move(numStr), negative, precision, base, width, flags);
4302 int base,
int width,
unsigned flags)
const
4304 return applyIntegerFormatting(qulltoa(l, base, zeroDigit()),
4305 false, precision, base, width, flags);
4308QString
QLocaleData::applyIntegerFormatting(QString &&numStr,
bool negative,
int precision,
4309 int base,
int width,
unsigned flags)
const
4311 const QString zero = base == 10 ? zeroDigit() :
QStringLiteral(
"0");
4312 const auto digitWidth = zero.size();
4313 const auto digitCount = numStr.size() / digitWidth;
4315 const auto basePrefix = [&] () -> QStringView {
4316 if (flags & ShowBase) {
4317 const bool upper = flags & UppercaseBase;
4319 return upper ? u"0X" : u"0x";
4321 return upper ? u"0B" : u"0b";
4322 if (base == 8 && !numStr.startsWith(zero))
4328 const QString prefix = signPrefix(negative, flags) + basePrefix;
4330 qsizetype usedWidth = digitCount + prefix.size();
4334 const QString group = groupSeparator();
4335 qsizetype i = digitCount - grouping.least;
4336 if (i >= grouping.first) {
4337 numStr.insert(i * digitWidth, group);
4339 while ((i -= grouping.higher) > 0) {
4340 numStr.insert(i * digitWidth, group);
4347 const bool noPrecision = precision == -1;
4351 for (qsizetype i = numStr.size(); i < precision; ++i) {
4352 numStr.prepend(zero);
4359 for (qsizetype i = usedWidth; i < width; ++i)
4360 numStr.prepend(zero);
4363 QString result(flags & CapitalEorX ? std::move(numStr).toUpper() : std::move(numStr));
4365 result.prepend(prefix);
4370 :
grouping(data->groupSizes()), isC(data == c())
4376 setZero(data->zero().viewData(single_character_data));
4377 group = data->groupDelim().viewData(single_character_data);
4379 minus = data->minus().viewData(single_character_data);
4380 plus = data->plus().viewData(single_character_data);
4381 if (mode != IntegerMode)
4382 decimal = data->decimalSeparator().viewData(single_character_data);
4384 exponent = data->exponential().viewData(single_character_data);
4386 exponentCyrillic = data->m_script_id == QLocale::CyrillicScript;
4388#ifndef QT_NO_SYSTEMLOCALE
4389 if (data == &systemLocaleData) {
4390 const auto getString = [sys = systemLocale()](QSystemLocale::QueryType query) {
4391 return sys->query(query).toString();
4394 sysDecimal = getString(QSystemLocale::DecimalPoint);
4395 if (sysDecimal.size())
4396 decimal = QStringView{sysDecimal};
4398 sysGroup = getString(QSystemLocale::GroupSeparator);
4399 if (sysGroup.size())
4400 group = QStringView{sysGroup};
4401 sysMinus = getString(QSystemLocale::NegativeSign);
4402 if (sysMinus.size())
4403 minus = QStringView{sysMinus};
4404 sysPlus = getString(QSystemLocale::PositiveSign);
4406 plus = QStringView{sysPlus};
4407 setZero(getString(QSystemLocale::ZeroDigit));
4416class NumericTokenizer
4420 static constexpr char lettersInfNaN[] =
"afin";
4421 static constexpr auto matchInfNaN =
QtPrivate::makeCharacterSetMatch<lettersInfNaN>();
4422 const QStringView m_text;
4426 static_assert(
'+' + 1 ==
',' &&
',' + 1 ==
'-' &&
'-' + 1 ==
'.');
4431 : m_text(text), m_guide(guide), m_index(from), m_mode(mode),
4434 Q_ASSERT(m_guide.isValid(mode));
4436 bool done()
const {
return !(m_index < m_text.size()); }
4437 qsizetype index()
const {
return m_index; }
4438 int digitValue(
char32_t digit)
const {
return m_guide.digitValue(digit); }
4439 bool isInfNanChar(
char ch)
const {
return matchInfNaN.matches(ch); }
4441 bool fractionGroupClash()
const
4446 return Q_UNLIKELY(m_mode != QLocaleData::IntegerMode && m_guide.fractionalIsGroup());
4451char NumericTokenizer::nextToken()
4458 const auto asciiLower = [](
unsigned char c) {
return c >=
'A' ? c | 0x20 : c; };
4459 const QStringView tail = m_text.sliced(m_index);
4460 const QChar ch = tail.front();
4461 if (ch == u'\u2212') {
4468 if (Q_LIKELY(ch.unicode() < 256)) {
4469 unsigned char ascii = asciiLower(ch.toLatin1());
4470 if (Q_LIKELY(isAsciiDigit(ascii) || (
'+' <= ascii && ascii <= lastMark)
4481 if (ch.unicode() < 256) {
4483 char ascii = asciiLower(ch.toLatin1());
4484 if (isAsciiDigit(ascii) || ascii ==
'-' || ascii ==
'+'
4493 if (tail.startsWith(m_guide.minus)) {
4494 m_index += m_guide.minus.size();
4497 if (tail.startsWith(m_guide.plus)) {
4498 m_index += m_guide.plus.size();
4501 if (!m_guide.group.isEmpty() && tail.startsWith(m_guide.group)) {
4502 m_index += m_guide.group.size();
4507 if (fractionGroupClash() && tail.indexOf(m_guide.decimal, m_guide.group.size()) == -1)
4512 m_index += m_guide.decimal.size();
4517 m_index += m_guide.exponent.size();
4522 if (m_guide.zeroLen == 1) {
4523 if (!ch.isSurrogate()) {
4524 if (
const int gap = digitValue(
char32_t(ch.unicode())); gap >= 0) {
4528 }
else if (ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()) {
4532 }
else if (ch.isHighSurrogate()) {
4535 if (tail.size() > 1) {
4536 if (
const QChar low = tail.at(1); low.isLowSurrogate()) {
4537 if (
const int gap = digitValue(QChar::surrogateToUcs4(ch, low)); gap >= 0) {
4548 Q_ASSERT(!(ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()));
4551 switch (ch.unicode()) {
4565 if (m_guide.group == u"\u00a0" || m_guide.group == u"\u202f") {
4579 if (m_guide.exponentCyrillic) {
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4626
4627
4628
4629
4630
4631
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4671
4672
4673
4674
4675
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4698
4699
4700
4701
4702
4703
4704
4705
4708
4709
4710
4711
4712
4713
4714
4715
4718
4719
4720
4721
4722
4723
4724
4725
4726
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4764 Options flags, qsizetype from)
4765 : digitStart(from), digitWidth(numeric.zeroWidth())
4767 NumericTokenizer tokens(text,
std::move(numeric),
IntegerMode, from);
4770 char currentToken = tokens.nextToken();
4775 if (currentToken ==
'+' || currentToken ==
'-') {
4778 digitStart = tokens.index();
4779 sign = currentToken;
4780 currentToken =
'\0';
4784 while (currentToken || !tokens.done()) {
4786 currentToken = tokens.nextToken();
4790 if (currentToken <
'0' || currentToken >
'9')
4794 digits.push_back(currentToken);
4795 currentToken =
'\0';
4800
4801
4802
4803
4804
4805
4806
4807
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4833 NumericTokenizer tokens(s, NumericData(
this, mode), mode);
4836 enum { Whole, Grouped, Fraction, Exponent, Name } stage = Whole;
4842 bool wantDigits =
true;
4845 bool needHigherGroup =
false;
4846 qsizetype digitsInGroup = 0;
4848 const auto badLeastGroup = [&]() {
4854 if (stage == Grouped) {
4855 Q_ASSERT(!number_options.testFlag(QLocale::RejectGroupSeparator));
4857 if (needHigherGroup)
4860 if (digitsInGroup != grouping.least)
4867 while (!tokens.done()) {
4868 char out = tokens.nextToken();
4876 if (stage > Grouped)
4879 if (tokens.fractionGroupClash() && badLeastGroup()
4880 && digitsInGroup == grouping.higher) {
4886 needHigherGroup =
false;
4890 if (badLeastGroup())
4894 }
else if (out ==
'e') {
4895 if (wantDigits || stage == Name || stage > Fraction)
4898 if (stage < Fraction) {
4900 if (badLeastGroup())
4902 }
else if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot)) {
4909 }
else if (out ==
',') {
4915 if (number_options.testFlag(QLocale::RejectGroupSeparator))
4921 if (digitsInGroup == 0
4922 || digitsInGroup > qMax(grouping.first, grouping.higher)) {
4925 Q_ASSERT(!needHigherGroup);
4929 if (grouping.first > digitsInGroup)
4930 needHigherGroup =
true;
4935 if (digitsInGroup != grouping.higher)
4937 needHigherGroup =
false;
4946 }
else if (isAsciiDigit(out)) {
4949 if (out ==
'0' && number_options.testFlag(QLocale::RejectLeadingZeroInExponent)
4950 && stage > Fraction && !tokens.done() && !isAsciiDigit(last)) {
4958 }
else if (stage == Whole && tokens.isInfNanChar(out)) {
4968 result->append(out);
4973 if (!number_options.testFlag(QLocale::RejectGroupSeparator)) {
4975 if (stage < Fraction && badLeastGroup())
4979 if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot) && stage == Fraction) {
4990 QLocale::NumberOptions number_options)
const
4993 result.buff.reserve(str.size());
4995 enum { Whole, Fractional, Exponent } state = Whole;
4997 NumericTokenizer tokens(str, NumericData(
this, numMode), numMode);
5000 while (!tokens.done()) {
5001 char c = tokens.nextToken();
5003 if (isAsciiDigit(c)) {
5010 if (decDigits-- == 0)
5014 if (!isAsciiDigit(last)) {
5017 if (c ==
'0' && (number_options & QLocale::RejectLeadingZeroInExponent))
5039 if (last !=
'\0' && !(scientific && last ==
'e'))
5045 if ((number_options & QLocale::RejectGroupSeparator) || state != Whole
5046 || !isAsciiDigit(last)) {
5055 if (!scientific || state == Exponent)
5065 Q_ASSERT(!c || c ==
'a' || c ==
'f' || c ==
'i' || c ==
'n');
5072 result.buff.append(c);
5079 if (last ==
',' || last ==
'-' || last ==
'+' || last ==
'e')
5086 QLocale::NumberOptions number_options)
const
5089 if (!numberToCLocale(str, number_options, DoubleScientificMode, &buff)) {
5094 auto r = qt_asciiToDouble(buff.constData(), buff.size());
5102 QLocale::NumberOptions number_options)
const
5105 if (!numberToCLocale(str, number_options, IntegerMode, &buff))
5108 return bytearrayToLongLong(QByteArrayView(buff), base);
5113 QLocale::NumberOptions number_options)
const
5116 if (!numberToCLocale(str, number_options, IntegerMode, &buff))
5119 return bytearrayToUnsLongLong(QByteArrayView(buff), base);
5127 const qsizetype len = num.size();
5128 if (used < len && num[used] !=
'\0') {
5129 while (used < len && ascii_isspace(num[used]))
5133 if (used < len && num[used] !=
'\0')
5140QSimpleParsedNumber<qint64>
QLocaleData::bytearrayToLongLong(QByteArrayView num,
int base)
5142 auto r = qstrntoll(num.data(), num.size(), base);
5143 if (!checkParsed(num, r.used))
5148QSimpleParsedNumber<quint64>
QLocaleData::bytearrayToUnsLongLong(QByteArrayView num,
int base)
5150 auto r = qstrntoull(num.data(), num.size(), base);
5151 if (!checkParsed(num, r.used))
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5169
5170
5171
5172QString QLocale::currencySymbol(CurrencySymbolFormat format)
const
5174#ifndef QT_NO_SYSTEMLOCALE
5175 if (d->m_data == &systemLocaleData) {
5176 auto res = systemLocale()->query(QSystemLocale::CurrencySymbol, format).toString();
5182 case CurrencySymbol:
5183 return d->m_data->currencySymbol().getData(currency_symbol_data);
5184 case CurrencyDisplayName:
5185 return d->m_data->currencyDisplayName().getData(currency_display_name_data);
5186 case CurrencyIsoCode: {
5187 const char *code = d->m_data->m_currency_iso_code;
5188 if (
auto len = qstrnlen(code, 3))
5189 return QString::fromLatin1(code, qsizetype(len));
5197
5198
5199
5200
5201
5202
5203
5204QString QLocale::toCurrencyString(qlonglong value,
const QString &symbol)
const
5206#ifndef QT_NO_SYSTEMLOCALE
5207 if (d->m_data == &systemLocaleData) {
5208 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5209 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5210 QVariant::fromValue(arg)).toString();
5215 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
5216 if (!range.size || value >= 0)
5217 range = d->m_data->currencyFormat();
5220 QString str = toString(value);
5221 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5223 sym = currencySymbol(CurrencyIsoCode);
5224 return range.viewData(currency_format_data).arg(str, sym);
5228
5229
5230
5231QString QLocale::toCurrencyString(qulonglong value,
const QString &symbol)
const
5233#ifndef QT_NO_SYSTEMLOCALE
5234 if (d->m_data == &systemLocaleData) {
5235 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5236 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5237 QVariant::fromValue(arg)).toString();
5242 QString str = toString(value);
5243 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5245 sym = currencySymbol(CurrencyIsoCode);
5246 return d->m_data->currencyFormat().getData(currency_format_data).arg(str, sym);
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259QString QLocale::toCurrencyString(
double value,
const QString &symbol,
int precision)
const
5261#ifndef QT_NO_SYSTEMLOCALE
5262 if (d->m_data == &systemLocaleData) {
5263 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5264 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5265 QVariant::fromValue(arg)).toString();
5270 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
5271 if (!range.size || value >= 0)
5272 range = d->m_data->currencyFormat();
5275 QString str = toString(value,
'f', precision == -1 ? d->m_data->m_currency_digits : precision);
5276 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5278 sym = currencySymbol(CurrencyIsoCode);
5279 return range.viewData(currency_format_data).arg(str, sym);
5283
5284
5285
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319QString QLocale::formattedDataSize(qint64 bytes,
int precision, DataSizeFormats format)
const
5321 int power, base = 1000;
5324 }
else if (format & DataSizeBase1000) {
5325 constexpr auto log10_1000 = 3;
5326 power =
int(std::log10(QtPrivate::qUnsignedAbs(bytes))) / log10_1000;
5328 constexpr auto log2_1024 = 10;
5329 power = QtPrivate::log2i(QtPrivate::qUnsignedAbs(bytes)) / log2_1024;
5333 const QString number = power
5334 ? toString(bytes / std::pow(
double(base), power),
'f', qMin(precision, 3 * power))
5339 Q_ASSERT(power <= 6 && power >= 0);
5342 QLocaleData::DataRange range = (format & DataSizeSIQuantifiers)
5343 ? d->m_data->byteAmountSI() : d->m_data->byteAmountIEC();
5344 unit = range.viewListEntry(byte_unit_data, power - 1);
5346 unit = d->m_data->byteCount().viewData(byte_unit_data);
5349 return number + u' ' + unit;
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395QStringList QLocale::uiLanguages(TagSeparator separator)
const
5397 const char sep =
char(separator);
5398 QStringList uiLanguages;
5399 if (uchar(sep) > 0x7f) {
5400 badSeparatorWarning(
"uiLanguages", sep);
5403 QList<QLocaleId> localeIds;
5404#ifdef QT_NO_SYSTEMLOCALE
5405 constexpr bool isSystem =
false;
5407 const bool isSystem = d->m_data == &systemLocaleData;
5409 uiLanguages = systemLocale()->query(QSystemLocale::UILanguages).toStringList();
5410 if (separator != TagSeparator::Dash) {
5412 const QChar join = QLatin1Char(sep);
5413 uiLanguages.replaceInStrings(u"-", QStringView(&join, 1));
5417 for (
const auto &entry : std::as_const(uiLanguages))
5418 localeIds.append(QLocaleId::fromName(entry));
5419 if (localeIds.isEmpty())
5420 localeIds.append(systemLocale()->fallbackLocale().d->m_data->id());
5422
5423
5424
5425
5426
5427
5428
5429 const QString name = QString::fromLatin1(d->m_data->id().name(sep));
5430 if (!name.isEmpty() && language() != C && !uiLanguages.contains(name)) {
5433 const QLocaleId id = d->m_data->id();
5434 const QLocaleId max = id.withLikelySubtagsAdded();
5435 const QLocaleId mine = max.withLikelySubtagsRemoved();
5437 qsizetype lastAlike = uiLanguages.size() - 1;
5439 for (qsizetype i = 0; !seen && i < uiLanguages.size(); ++i) {
5440 const auto its = QLocaleId::fromName(uiLanguages.at(i)).withLikelySubtagsAdded();
5441 seen = its.withLikelySubtagsRemoved() == mine;
5442 if (!seen && its.language_id == max.language_id && its.script_id == max.script_id)
5446 localeIds.insert(lastAlike + 1, id);
5447 uiLanguages.insert(lastAlike + 1, QString::fromLatin1(id.name(sep)));
5453 localeIds.append(d->m_data->id());
5456 for (qsizetype i = localeIds.size(); i-- > 0; ) {
5457 const QLocaleId id = localeIds.at(i);
5458 Q_ASSERT(id.language_id);
5459 if (id.language_id == C) {
5460 if (!uiLanguages.contains(u"C"_s))
5461 uiLanguages.append(u"C"_s);
5467 const QByteArray prior = id.name(sep);
5468 bool faithful =
true;
5469 if (isSystem && i < uiLanguages.size()) {
5471 faithful = uiLanguages.at(i) == QLatin1StringView(prior);
5474 || QLocaleId::fromName(uiLanguages.at(i)).name(sep) == prior);
5479 if (!uiLanguages.contains(QLatin1StringView(prior)))
5480 uiLanguages.append(QString::fromLatin1(prior));
5481 j = uiLanguages.size();
5484 const QLocaleId max = id.withLikelySubtagsAdded();
5485 Q_ASSERT(max.language_id);
5486 Q_ASSERT(max.language_id == id.language_id);
5490 const auto addIfEquivalent = [&j, &uiLanguages, max, sep, &prior, faithful](QLocaleId cid) {
5491 if (cid.withLikelySubtagsAdded() == max) {
5492 if (
const QByteArray name = cid.name(sep); name != prior)
5493 uiLanguages.insert(j, QString::fromLatin1(name));
5499 addIfEquivalent({ max.language_id, 0, 0 });
5502 addIfEquivalent({ max.language_id, max.script_id, 0 });
5503 if (id.script_id && id.script_id != max.script_id)
5504 addIfEquivalent({ id.language_id, id.script_id, 0 });
5506 if (max.territory_id)
5507 addIfEquivalent({ max.language_id, 0, max.territory_id });
5508 if (id.territory_id && id.territory_id != max.territory_id)
5509 addIfEquivalent({ id.language_id, 0, id.territory_id });
5511 if (max.territory_id && max.script_id)
5512 addIfEquivalent(max);
5513 if (max.territory_id && id.script_id && id.script_id != max.script_id)
5514 addIfEquivalent({ id.language_id, id.script_id, max.territory_id });
5515 if (max.script_id && id.territory_id && id.territory_id != max.territory_id)
5516 addIfEquivalent({ id.language_id, max.script_id, id.territory_id });
5517 if (id.territory_id && id.territory_id != max.territory_id
5518 && id.script_id && id.script_id != max.script_id) {
5519 addIfEquivalent(id);
5526 QDuplicateTracker<QString> known(uiLanguages.size());
5527 uiLanguages.removeIf([&](
const QString &s) {
return known.hasSeen(s); });
5531 const QLatin1Char cut(sep);
5532 const auto hasPrefix = [cut](
auto name, QStringView stem) {
5534 return name.startsWith(stem)
5535 && (name.size() == stem.size() || name.at(stem.size()) == cut);
5546 qsizetype afterEquivs = 0;
5547 qsizetype afterTruncs = 0;
5551 for (qsizetype i = 0; i < uiLanguages.size(); ++i >= afterEquivs && (i = afterTruncs)) {
5552 const QString entry = uiLanguages.at(i);
5553 const QLocaleId max = QLocaleId::fromName(entry).withLikelySubtagsAdded();
5555 if (i >= afterEquivs) {
5556 Q_ASSERT(i >= afterTruncs);
5557 afterEquivs = i + 1;
5559 while (afterEquivs < uiLanguages.size()
5560 && QLocaleId::fromName(uiLanguages.at(afterEquivs))
5561 .withLikelySubtagsAdded() == max) {
5565 afterTruncs = afterEquivs;
5567 if (hasPrefix(entry, u"C") || hasPrefix(entry, u"und"))
5569 qsizetype stopAt = uiLanguages.size();
5570 qsizetype at = entry.size();
5571 while ((at = entry.lastIndexOf(cut, at - 1)) > 0) {
5572 QString prefix = entry.first(at);
5576 bool found = known.contains(prefix);
5578
5579
5580
5581
5582
5583
5584
5585
5586
5588 = (QLocaleId::fromName(prefix).withLikelySubtagsAdded().script_id == max.script_id);
5589 for (qsizetype j = afterTruncs; !found && j < stopAt; ++j) {
5590 QString later = uiLanguages.at(j);
5591 if (!later.startsWith(prefix)) {
5592 const QByteArray laterFull =
5593 QLocaleId::fromName(later.replace(cut, u'-')
5594 ).withLikelySubtagsAdded().name(sep);
5596 if (hasPrefix(QLatin1StringView(laterFull), prefix))
5601 Q_ASSERT(later.size() > prefix.size());
5602 if (later.at(prefix.size()) == cut) {
5609 QStringView head{later};
5610 for (qsizetype as = head.lastIndexOf(cut);
5611 !found && as > prefix.size(); as = head.lastIndexOf(cut)) {
5612 head = head.first(as);
5614 for (qsizetype k = j + 1; !seen && k < uiLanguages.size(); ++k)
5615 seen = uiLanguages.at(k) == head;
5624 (
void) known.hasSeen(prefix);
5626 uiLanguages.insert(afterTruncs++, std::move(prefix));
5629 uiLanguages.append(std::move(prefix));
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648QLocale QLocale::collation()
const
5650#ifndef QT_NO_SYSTEMLOCALE
5651 if (d->m_data == &systemLocaleData) {
5652 const auto res = systemLocale()->query(QSystemLocale::Collation).toString();
5654 return QLocale(res);
5661
5662
5663
5664
5665
5666
5667
5668QString QLocale::nativeLanguageName()
const
5670#ifndef QT_NO_SYSTEMLOCALE
5671 if (d->m_data == &systemLocaleData) {
5672 auto res = systemLocale()->query(QSystemLocale::NativeLanguageName).toString();
5677 return d->m_data->endonymLanguage().getData(endonyms_data);
5681
5682
5683
5684
5685
5686
5687
5688QString QLocale::nativeTerritoryName()
const
5690#ifndef QT_NO_SYSTEMLOCALE
5691 if (d->m_data == &systemLocaleData) {
5692 auto res = systemLocale()->query(QSystemLocale::NativeTerritoryName).toString();
5697 return d->m_data->endonymTerritory().getData(endonyms_data);
5700#if QT_DEPRECATED_SINCE(6
, 6
)
5702
5703
5704
5705
5706
5707
5708
5709
5710QString QLocale::nativeCountryName()
const
5712 return nativeTerritoryName();
5716#ifndef QT_NO_DEBUG_STREAM
5719 QDebugStateSaver saver(dbg);
5720 const bool isSys = l == QLocale::system();
5721 dbg.nospace().noquote()
5722 << (isSys ?
"QLocale::system()/* " :
"QLocale(")
5723 << QLocale::languageToString(l.language()) <<
", "
5724 << QLocale::scriptToString(l.script()) <<
", "
5725 << QLocale::territoryToString(l.territory()) << (isSys ?
" */" :
")");
5731#ifndef QT_NO_QOBJECT
5732#include "moc_qlocale.cpp"
const QLocaleData *const m_data
QLocale::MeasurementSystem measurementSystem() const
QByteArray bcp47Name(char separator='-') const
char32_t next(char32_t invalidAs=QChar::ReplacementCharacter)
Combined button and popup list for selecting options.
Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames, { { Qt::DisplayRole, "display" }, { Qt::DecorationRole, "decoration" }, { Qt::EditRole, "edit" }, { Qt::ToolTipRole, "toolTip" }, { Qt::StatusTipRole, "statusTip" }, { Qt::WhatsThisRole, "whatsThis" }, }) const QHash< int
static unsigned calculateFlags(int fieldWidth, char32_t fillChar, const QLocale &locale)
static QString calculateFiller(qsizetype padding, char32_t fillChar, qsizetype fieldWidth, const QLocaleData *localeData)
QDebug operator<<(QDebug dbg, const QLocale &l)
static QLocalePrivate * findLocalePrivate(QLocale::Language language, QLocale::Script script, QLocale::Territory territory)
static std::optional< QString > systemLocaleString(const QLocaleData *that, QSystemLocale::QueryType type)
static const QSystemLocale * systemLocale()
static bool checkParsed(QByteArrayView num, qsizetype used)
static QString rawWeekDayName(const QLocaleData *data, const int day, QLocale::FormatType type)
QDataStream & operator>>(QDataStream &ds, QLocale &l)
#define CheckCandidate(id)
static Q_DECL_COLD_FUNCTION void badSeparatorWarning(const char *method, char sep)
static QString rawStandaloneWeekDayName(const QLocaleData *data, const int day, QLocale::FormatType type)
static constexpr QLocale::NumberOptions defaultNumberOptions(QLocale::Language forLanguage)
static QStringView findTag(QStringView name) noexcept
static bool validTag(QStringView tag)
static qsizetype scriptIndex(QStringView code, Qt::CaseSensitivity cs) noexcept
static const QCalendarLocale & getMonthDataFor(const QLocalePrivate *loc, const QCalendarLocale *table)
static T toIntegral_helper(const QLocalePrivate *d, QStringView str, bool *ok)
static bool timeFormatContainsAP(QStringView format)
size_t qHash(const QLocale &key, size_t seed) noexcept
bool comparesEqual(const QLocale &loc, QLocale::Language lang)
static qsizetype findLocaleIndexById(QLocaleId localeId) noexcept
static constexpr qsizetype locale_data_size
static void updateSystemPrivate()
static QString rawMonthName(const QCalendarLocale &localeData, const char16_t *monthsData, int month, QLocale::FormatType type)
static qsizetype stringWidth(QStringView text)
static QLocalePrivate * c_private() noexcept
static const QLocaleData * defaultData()
static QString rawStandaloneMonthName(const QCalendarLocale &localeData, const char16_t *monthsData, int month, QLocale::FormatType type)
static QString localeString(const QLocaleData *that, QSystemLocale::QueryType type, QLocaleData::DataRange range)
static const QLocaleData * systemData(qsizetype *sysIndex=nullptr)
static QString offsetFromAbbreviation(QString &&text)
static qsizetype defaultIndex()
static constexpr char16_t single_character_data[]
static constexpr char16_t days_data[]
static constexpr QLocaleData locale_data[]
static constexpr QLocaleId likely_subtags[]
static constexpr unsigned char territory_code_list[]
static constexpr unsigned char script_code_list[]
bool qt_splitLocaleName(QStringView name, QStringView *lang=nullptr, QStringView *script=nullptr, QStringView *cntry=nullptr) noexcept
QString qt_readEscapedFormatString(QStringView format, qsizetype *idx)
#define QStringLiteral(str)
char32_t ucsFirst(const char16_t *table) const
Descriptor for a digit sequence within a text.
const GroupSizes grouping
QString positiveSign() const
QString groupSeparator() const
QSimpleParsedNumber< qint64 > stringToLongLong(QStringView str, int base, QLocale::NumberOptions options) const
Q_AUTOTEST_EXPORT char32_t zeroUcs() const
QString zeroDigit() const
bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options, NumberMode mode, CharBuff *result) const
Returns a DigitSequence describing some portion of text starting at from.
QString decimalPoint() const
QString doubleToString(double d, int precision=-1, DoubleForm form=DFSignificantDigits, int width=-1, unsigned flags=NoFlags) const
QString listSeparator() const
QString percentSign() const
double stringToDouble(QStringView str, bool *ok, QLocale::NumberOptions options) const
QString longLongToString(qint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
QString exponentSeparator() const
QString negativeSign() const
QSimpleParsedNumber< quint64 > stringToUnsLongLong(QStringView str, int base, QLocale::NumberOptions options) const
QString unsLongLongToString(quint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
QLocaleId withLikelySubtagsAdded() const noexcept
QLocaleId withLikelySubtagsRemoved() const noexcept
bool operator==(QLocaleId other) const noexcept