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
2760
2761QTime QLocale::toTime(
const QString &string,
const QString &format)
const
2763#if QT_CONFIG(datetimeparser)
2764 QTimePattern pattern = QTimePattern::fromQtFormat(format);
2765 if (pattern.isNull() && !format.isEmpty())
2767 pattern.setLocale(*
this);
2768 if (
auto match = pattern.parse(string, QTime(0, 0)); match.size == string.size())
2769 return std::move(match.payload);
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803QDate QLocale::toDate(
const QString &string,
const QString &format,
int baseYear)
const
2805 return toDate(string, format, QCalendar(), baseYear);
2809
2810
2811
2812QDate QLocale::toDate(
const QString &string,
const QString &format, QCalendar cal,
int baseYear)
const
2814#if QT_CONFIG(datetimeparser)
2815 QDatePattern pattern = QDatePattern::fromQtFormat(format);
2816 if (pattern.isNull() && !format.isEmpty())
2818 pattern.setLocale(*
this);
2819 pattern.setCalendar(cal);
2820 pattern.setBaseYear(baseYear);
2821 if (
auto match = pattern.parse(string, QDate(baseYear, 1, 1, cal));
2822 match.size == string.size()) {
2823 return std::move(match.payload);
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859QDateTime QLocale::toDateTime(
const QString &string,
const QString &format,
int baseYear)
const
2861 return toDateTime(string, format, QCalendar(), baseYear);
2865
2866
2867
2868QDateTime QLocale::toDateTime(
const QString &string,
const QString &format, QCalendar cal,
2871#if QT_CONFIG(datetimeparser)
2872 QDateTimePattern pattern = QDateTimePattern::fromQtFormat(format);
2873 if (pattern.isNull() && !format.isEmpty())
2875 pattern.setLocale(*
this);
2876 pattern.setCalendar(cal);
2877 pattern.setBaseYear(baseYear);
2878 if (
auto match = pattern.parse(string, QDate(baseYear, 1, 1, cal).startOfDay());
2879 match.size == string.size()) {
2880 return std::move(match.payload);
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906QString QLocale::decimalPoint()
const
2908 return d->m_data->decimalPoint();
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925QString QLocale::groupSeparator()
const
2927 return d->m_data->groupSeparator();
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942QString QLocale::percent()
const
2944 return d->m_data->percentSign();
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961QString QLocale::zeroDigit()
const
2963 return d->m_data->zeroDigit();
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978QString QLocale::negativeSign()
const
2980 return d->m_data->negativeSign();
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995QString QLocale::positiveSign()
const
2997 return d->m_data->positiveSign();
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013QString QLocale::exponential()
const
3015 return d->m_data->exponentSeparator();
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3052QString QLocale::toString(
double f,
char format,
int precision)
const
3054 QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
3055 uint flags = isAsciiUpper(format) ? QLocaleData::CapitalEorX : 0;
3057 switch (QtMiscUtils::toAsciiLower(format)) {
3059 form = QLocaleData::DFDecimal;
3062 form = QLocaleData::DFExponent;
3065 form = QLocaleData::DFSignificantDigits;
3071 if (!(d->m_numberOptions & OmitGroupSeparator))
3072 flags |= QLocaleData::GroupDigits;
3073 if (!(d->m_numberOptions & OmitLeadingZeroInExponent))
3074 flags |= QLocaleData::ZeroPadExponent;
3075 if (d->m_numberOptions & IncludeTrailingZeroesAfterDot)
3076 flags |= QLocaleData::AddTrailingZeroes;
3077 return d->m_data->doubleToString(f, precision, form, -1, flags);
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096QLocale QLocale::c()
noexcept
3098 return QLocale(*c_private());
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3115QLocale QLocale::system()
3117 constexpr auto sysData = []() {
3119#ifdef QT_NO_SYSTEMLOCALE
3122 return &systemLocaleData;
3125 Q_CONSTINIT
static QLocalePrivate locale(sysData(), -1, DefaultNumberOptions, 1);
3128 systemData(&locale.m_index);
3129 Q_ASSERT(locale.m_index >= 0 && locale.m_index < locale_data_size);
3130 locale.m_numberOptions = defaultNumberOptions(locale.m_data->m_language_id);
3132 return QLocale(locale);
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147QList<QLocale> QLocale::matchingLocales(Language language, Script script, Territory territory)
3149 QList<QLocale> result;
3151 const QLocaleId filter { language, script, territory };
3152 if (!filter.isValid())
3155 if (language == C) {
3156 result.emplace_back(C);
3160 if (filter.matchesAll())
3161 result.reserve(locale_data_size);
3163 quint16 index = locale_index[language];
3165 while (index < locale_data_size
3166 && filter.acceptLanguage(locale_data[index].m_language_id)) {
3167 const QLocaleId id = locale_data[index].id();
3168 if (filter.acceptScriptTerritory(id)) {
3169 result.append(QLocale(*(id.language_id == C ? c_private()
3170 :
new QLocalePrivate(locale_data + index, index))));
3176 const auto syslocaledata = systemData();
3178 if (filter.acceptLanguage(syslocaledata->m_language_id)) {
3179 const QLocaleId id = syslocaledata->id();
3180 if (filter.acceptScriptTerritory(id))
3181 result.append(system());
3187#if QT_DEPRECATED_SINCE(6
, 6
)
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
3200 const auto locales = matchingLocales(language, AnyScript, AnyCountry);
3201 QList<Country> result;
3202 result.reserve(locales.size());
3203 for (
const auto &locale : locales)
3204 result.append(locale.territory());
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221QString QLocale::monthName(
int month, FormatType type)
const
3223 return QCalendar().monthName(*
this, month, QCalendar::Unspecified, type);
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237QString QLocale::standaloneMonthName(
int month, FormatType type)
const
3239 return QCalendar().standaloneMonthName(*
this, month, QCalendar::Unspecified, type);
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255QString QLocale::dayName(
int day, FormatType type)
const
3257 return QCalendar().weekDayName(*
this, day, type);
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272QString QLocale::standaloneDayName(
int day, FormatType type)
const
3274 return QCalendar().standaloneWeekDayName(*
this, day, type);
3281 const QCalendarLocale *table)
3284 [[maybe_unused]]
const auto sameLocale = [](
const QLocaleData &locale,
3285 const QCalendarLocale &cal) {
3286 return locale.m_language_id == cal.m_language_id
3287 && locale.m_script_id == cal.m_script_id
3288 && locale.m_territory_id == cal.m_territory_id;
3290 const QCalendarLocale &monthly = table[loc->m_index];
3291#ifdef QT_NO_SYSTEMLOCALE
3292 [[maybe_unused]]
constexpr bool isSys =
false;
3294 [[maybe_unused]]
const bool isSys = loc->m_data == &systemLocaleData;
3299 Q_ASSERT(sameLocale(
locale_data[loc->m_index], monthly));
3304
3305
3308 const char16_t *monthsData,
int month,
3309 QLocale::FormatType type)
3312 return range.getListEntry(monthsData, month - 1);
3316
3317
3320 const char16_t *monthsData,
int month,
3321 QLocale::FormatType type)
3324 if (QString name = range.getListEntry(monthsData, month - 1); !name.isEmpty())
3326 return rawMonthName(localeData, monthsData, month, type);
3330
3331
3334 QLocale::FormatType type)
3338 case QLocale::LongFormat:
3339 range = data->longDayNames();
3341 case QLocale::ShortFormat:
3342 range = data->shortDayNames();
3344 case QLocale::NarrowFormat:
3345 range = data->narrowDayNames();
3350 return range.getListEntry(
days_data, day == 7 ? 0 : day);
3354
3355
3358 QLocale::FormatType type)
3362 case QLocale::LongFormat:
3363 range =data->longDayNamesStandalone();
3365 case QLocale::ShortFormat:
3366 range = data->shortDayNamesStandalone();
3368 case QLocale::NarrowFormat:
3369 range = data->narrowDayNamesStandalone();
3374 QString name = range.getListEntry(days_data, day == 7 ? 0 : day);
3376 return rawWeekDayName(data, day, type);
3382QString QCalendarBackend::monthName(
const QLocale &locale,
int month,
int,
3383 QLocale::FormatType format)
const
3385 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3386 return rawMonthName(getMonthDataFor(locale.d, localeMonthIndexData()),
3387 localeMonthData(), month, format);
3390QString QRomanCalendar::monthName(
const QLocale &locale,
int month,
int year,
3391 QLocale::FormatType format)
const
3393#ifndef QT_NO_SYSTEMLOCALE
3394 if (locale.d->m_data == &systemLocaleData) {
3395 Q_ASSERT(month >= 1 && month <= 12);
3396 QSystemLocale::QueryType queryType = QSystemLocale::MonthNameLong;
3398 case QLocale::LongFormat:
3399 queryType = QSystemLocale::MonthNameLong;
3401 case QLocale::ShortFormat:
3402 queryType = QSystemLocale::MonthNameShort;
3404 case QLocale::NarrowFormat:
3405 queryType = QSystemLocale::MonthNameNarrow;
3408 QVariant res = systemLocale()->query(queryType, month);
3410 return res.toString();
3414 return QCalendarBackend::monthName(locale, month, year, format);
3417QString QCalendarBackend::standaloneMonthName(
const QLocale &locale,
int month,
int,
3418 QLocale::FormatType format)
const
3420 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3421 return rawStandaloneMonthName(getMonthDataFor(locale.d, localeMonthIndexData()),
3422 localeMonthData(), month, format);
3425QString QRomanCalendar::standaloneMonthName(
const QLocale &locale,
int month,
int year,
3426 QLocale::FormatType format)
const
3428#ifndef QT_NO_SYSTEMLOCALE
3429 if (locale.d->m_data == &systemLocaleData) {
3430 Q_ASSERT(month >= 1 && month <= 12);
3431 QSystemLocale::QueryType queryType = QSystemLocale::StandaloneMonthNameLong;
3433 case QLocale::LongFormat:
3434 queryType = QSystemLocale::StandaloneMonthNameLong;
3436 case QLocale::ShortFormat:
3437 queryType = QSystemLocale::StandaloneMonthNameShort;
3439 case QLocale::NarrowFormat:
3440 queryType = QSystemLocale::StandaloneMonthNameNarrow;
3443 QVariant res = systemLocale()->query(queryType, month);
3445 return res.toString();
3449 return QCalendarBackend::standaloneMonthName(locale, month, year, format);
3454QString QCalendarBackend::weekDayName(
const QLocale &locale,
int day,
3455 QLocale::FormatType format)
const
3457 if (day < 1 || day > 7)
3460#ifndef QT_NO_SYSTEMLOCALE
3461 if (locale.d->m_data == &systemLocaleData) {
3462 QSystemLocale::QueryType queryType = QSystemLocale::DayNameLong;
3464 case QLocale::LongFormat:
3465 queryType = QSystemLocale::DayNameLong;
3467 case QLocale::ShortFormat:
3468 queryType = QSystemLocale::DayNameShort;
3470 case QLocale::NarrowFormat:
3471 queryType = QSystemLocale::DayNameNarrow;
3474 QVariant res = systemLocale()->query(queryType, day);
3476 return res.toString();
3480 return rawWeekDayName(locale.d->m_data, day, format);
3483QString QCalendarBackend::standaloneWeekDayName(
const QLocale &locale,
int day,
3484 QLocale::FormatType format)
const
3486 if (day < 1 || day > 7)
3489#ifndef QT_NO_SYSTEMLOCALE
3490 if (locale.d->m_data == &systemLocaleData) {
3491 QSystemLocale::QueryType queryType = QSystemLocale::StandaloneDayNameLong;
3493 case QLocale::LongFormat:
3494 queryType = QSystemLocale::StandaloneDayNameLong;
3496 case QLocale::ShortFormat:
3497 queryType = QSystemLocale::StandaloneDayNameShort;
3499 case QLocale::NarrowFormat:
3500 queryType = QSystemLocale::StandaloneDayNameNarrow;
3503 QVariant res = systemLocale()->query(queryType, day);
3505 return res.toString();
3509 return rawStandaloneWeekDayName(locale.d->m_data, day, format);
3515
3516
3517
3518
3519Qt::DayOfWeek QLocale::firstDayOfWeek()
const
3521#ifndef QT_NO_SYSTEMLOCALE
3522 if (d->m_data == &systemLocaleData) {
3523 const auto res = systemLocale()->query(QSystemLocale::FirstDayOfWeek);
3525 return static_cast<Qt::DayOfWeek>(res.toUInt());
3528 return static_cast<Qt::DayOfWeek>(d->m_data->m_first_day_of_week);
3534
3535
3536
3537
3538 struct TerritoryLanguage
3541 quint16 territoryId;
3542 QLocale::MeasurementSystem system;
3545 constexpr TerritoryLanguage ImperialMeasurementSystems[] = {
3546 { QLocale::English, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3547 { QLocale::English, QLocale::UnitedStatesMinorOutlyingIslands, QLocale::ImperialUSSystem },
3548 { QLocale::Spanish, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3549 { QLocale::Hawaiian, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3550 { QLocale::English, QLocale::UnitedKingdom, QLocale::ImperialUKSystem }
3553 for (
const auto &system : ImperialMeasurementSystems) {
3554 if (system.languageId == m_data->m_language_id
3555 && system.territoryId == m_data->m_territory_id) {
3556 return system.system;
3559 return QLocale::MetricSystem;
3563
3564
3565
3566
3567QList<Qt::DayOfWeek> QLocale::weekdays()
const
3569#ifndef QT_NO_SYSTEMLOCALE
3570 if (d->m_data == &systemLocaleData) {
3572 = qvariant_cast<QList<Qt::DayOfWeek> >(systemLocale()->query(QSystemLocale::Weekdays));
3577 QList<Qt::DayOfWeek> weekdays;
3578 quint16 weekendStart = d->m_data->m_weekend_start;
3579 quint16 weekendEnd = d->m_data->m_weekend_end;
3580 for (
int day = Qt::Monday; day <= Qt::Sunday; day++) {
3581 if ((weekendEnd >= weekendStart && (day < weekendStart || day > weekendEnd)) ||
3582 (weekendEnd < weekendStart && (day > weekendEnd && day < weekendStart)))
3583 weekdays <<
static_cast<Qt::DayOfWeek>(day);
3589
3590
3591
3592
3593QLocale::MeasurementSystem QLocale::measurementSystem()
const
3595#ifndef QT_NO_SYSTEMLOCALE
3596 if (d->m_data == &systemLocaleData) {
3597 const auto res = systemLocale()->query(QSystemLocale::MeasurementSystem);
3599 return MeasurementSystem(res.toInt());
3603 return d->measurementSystem();
3607
3608
3609
3610
3611Qt::LayoutDirection QLocale::textDirection()
const
3620 case ImperialAramaicScript:
3621 case InscriptionalPahlaviScript:
3622 case InscriptionalParthianScript:
3623 case KharoshthiScript:
3625 case MandaeanScript:
3626 case ManichaeanScript:
3627 case MendeKikakuiScript:
3628 case MeroiticCursiveScript:
3629 case MeroiticScript:
3630 case NabataeanScript:
3632 case OldHungarianScript:
3633 case OldNorthArabianScript:
3634 case OldSouthArabianScript:
3636 case PalmyreneScript:
3637 case PhoenicianScript:
3638 case PsalterPahlaviScript:
3639 case SamaritanScript:
3642 return Qt::RightToLeft;
3646 return Qt::LeftToRight;
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664QString QLocale::toUpper(
const QString &str)
const
3666#if !defined(QT_BOOTSTRAPPED) && (QT_CONFIG(icu) || defined(Q_OS_WIN) || defined(Q_OS_APPLE))
3668 QString result = d->toUpper(str, &ok);
3673 return str.toUpper();
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688QString QLocale::toLower(
const QString &str)
const
3690#if !defined(QT_BOOTSTRAPPED) && (QT_CONFIG(icu) || defined(Q_OS_WIN) || defined(Q_OS_APPLE))
3692 const QString result = d->toLower(str, &ok);
3697 return str.toLower();
3702
3703
3704
3705
3706
3707
3708
3709QString QLocale::amText()
const
3711#ifndef QT_NO_SYSTEMLOCALE
3712 if (d->m_data == &systemLocaleData) {
3713 auto res = systemLocale()->query(QSystemLocale::AMText).toString();
3718 return d->m_data->anteMeridiem().getData(am_data);
3722
3723
3724
3725
3726
3727
3728
3729QString QLocale::pmText()
const
3731#ifndef QT_NO_SYSTEMLOCALE
3732 if (d->m_data == &systemLocaleData) {
3733 auto res = systemLocale()->query(QSystemLocale::PMText).toString();
3738 return d->m_data->postMeridiem().getData(pm_data);
3744 QStringView tail{text};
3746 if (tail.startsWith(
"UTC"_L1) || tail.startsWith(
"GMT"_L1))
3747 tail = tail.sliced(3);
3750 return (tail.isEmpty()
3755 : std::move(text).right(tail.size())));
3759#if !QT_CONFIG(datestring)
3761#elif QT_CONFIG(icu) || !(QT_CONFIG(timezone) && QT_CONFIG(timezone_locale))
3762namespace QtTimeZoneLocale {
3766QString zoneOffsetFormat([[maybe_unused]]
const QLocale &locale,
3768 QtTemporalPattern::TemporalFieldFlags,
3769 const QDateTime &when,
3775#if QT_CONFIG(timezone)
3776 locale != QLocale::system()
3777 ? when.timeRepresentation().displayName(when, QTimeZone::OffsetName, locale)
3780 when.toOffsetFromUtc(offsetSeconds).timeZoneAbbreviation();
3782 if (!text.isEmpty())
3783 text = offsetFromAbbreviation(std::move(text));
3792QString QCalendarBackend::dateTimeToString(QStringView format,
const QDateTime &datetime,
3793 QDate dateOnly, QTime timeOnly,
3794 const QLocale &locale)
const
3798 bool formatDate =
false;
3799 bool formatTime =
false;
3800 if (datetime.isValid()) {
3801 date = datetime.date();
3802 time = datetime.time();
3805 }
else if (dateOnly.isValid()) {
3808 }
else if (timeOnly.isValid()) {
3816 int year = 0, month = 0, day = 0;
3818 const auto parts = julianDayToDate(date.toJulianDay());
3819 if (!parts.isValid())
3822 month = parts.month;
3826 auto appendToResult = [&](
int t,
int repeat) {
3827 auto data = locale.d->m_data;
3829 result.append(data->longLongToString(t, -1, 10, repeat, QLocaleData::ZeroPadded));
3831 result.append(data->longLongToString(t));
3834 auto formatType = [](
int repeat) {
3835 return repeat == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
3839 while (i < format.size()) {
3840 if (format.at(i).unicode() ==
'\'') {
3841 result.append(qt_readEscapedFormatString(format, &i));
3845 const QChar c = format.at(i);
3846 qsizetype rep = qt_repeatCount(format.mid(i));
3847 Q_ASSERT(rep < std::numeric_limits<
int>::max());
3848 int repeat =
int(rep);
3851 switch (c.unicode()) {
3856 else if (repeat >= 2)
3863 result.append(locale.positiveSign());
3864 appendToResult(year, (year < 0) ? 5 : 4);
3867 appendToResult(year % 100, 2);
3878 repeat = qMin(repeat, 4);
3880 appendToResult(month, repeat);
3882 result.append(monthName(locale, month, year, formatType(repeat)));
3887 repeat = qMin(repeat, 4);
3889 appendToResult(day, repeat);
3892 locale.dayName(dayOfWeek(date.toJulianDay()), formatType(repeat)));
3899 if (!used && formatTime) {
3900 switch (c.unicode()) {
3903 repeat = qMin(repeat, 2);
3904 int hour = time.hour();
3905 if (timeFormatContainsAP(format)) {
3911 appendToResult(hour, repeat);
3916 repeat = qMin(repeat, 2);
3917 appendToResult(time.hour(), repeat);
3922 repeat = qMin(repeat, 2);
3923 appendToResult(time.minute(), repeat);
3928 repeat = qMin(repeat, 2);
3929 appendToResult(time.second(), repeat);
3934 QString text = time.hour() < 12 ? locale.amText() : locale.pmText();
3937 if (format.mid(i + 1).startsWith(u'p', Qt::CaseInsensitive))
3939 if (c.unicode() ==
'A' && (repeat == 1 || format.at(i + 1).unicode() ==
'P'))
3940 text = std::move(text).toUpper();
3941 else if (c.unicode() ==
'a' && (repeat == 1 || format.at(i + 1).unicode() ==
'p'))
3942 text = std::move(text).toLower();
3944 result.append(text);
3950 repeat = qMin(repeat, 3);
3954 appendToResult(time.msec(), 3);
3956 const QString zero = locale.zeroDigit();
3957 if (result.endsWith(zero))
3958 result.chop(zero.size());
3959 if (result.endsWith(zero))
3960 result.chop(zero.size());
3965#if QT_CONFIG(datestring)
3969 enum AbbrType { Long, Offset, Short };
3970 const auto tzAbbr = [locale](
const QDateTime &when, AbbrType type) {
3972 if (type == Offset) {
3973 using Flag = QtTemporalPattern::TemporalFieldFlag;
3974 constexpr auto noPrefixOffset = Flag::Numeric | Flag::Abbreviated
3975 | Flag::NeedNoUtcPrefix | Flag::ZeroPad;
3976 text = QtTimeZoneLocale::zoneOffsetFormat(locale, locale.d->m_index,
3978 when, when.offsetFromUtc());
3980 if (!text.isEmpty())
3983# if QT_CONFIG(timezone)
3984 if (type != Short || locale != QLocale::system()) {
3985 QTimeZone::NameType mode =
3986 type == Short ? QTimeZone::ShortName
3987 : type == Long ? QTimeZone::LongName : QTimeZone::OffsetName;
3988 text = when.timeRepresentation().displayName(when, mode, locale);
3989 if (!text.isEmpty())
3995 text = QString::fromLatin1(when.timeZone().id());
3996 if (!text.isEmpty())
4003 text = when.toOffsetFromUtc(when.offsetFromUtc()).timeZoneAbbreviation();
4005 text = when.timeZoneAbbreviation();
4007 text = offsetFromAbbreviation(std::move(text));
4012 repeat = qMin(repeat, 4);
4014 const QDateTime when = formatDate ? datetime : QDateTime::currentDateTime();
4018 text = tzAbbr(when, Long);
4022 text = tzAbbr(when, Offset);
4027 text = tzAbbr(when, Short);
4029 if (text.startsWith(
"UTC"_L1) && text.size() == 6)
4033 if (!text.isEmpty())
4034 result.append(text);
4044 result.resize(result.size() + repeat, c);
4053 int width,
unsigned flags)
const
4060 if (precision != QLocale::FloatingPointShortest && precision < 0)
4066 qsizetype bufSize = 1;
4067 if (precision == QLocale::FloatingPointShortest)
4068 bufSize += std::numeric_limits<
double>::max_digits10;
4069 else if (form == DFDecimal && qt_is_finite(d))
4070 bufSize += wholePartSpace(qAbs(d)) + precision;
4072 bufSize += qMax(2, precision) + 1;
4074 QVarLengthArray<
char> buf(bufSize);
4076 bool negative =
false;
4077 qt_doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
4079 const QString prefix = signPrefix(negative && !qIsNull(d), flags);
4083 && (qstrncmp(buf.data(),
"inf", 3) == 0 || qstrncmp(buf.data(),
"nan", 3) == 0)) {
4084 numStr = QString::fromLatin1(buf.data(), length);
4086 const QString zero = zeroDigit();
4087 QString digits = QString::fromLatin1(buf.data(), length);
4091 Q_ASSERT(
std::all_of(buf.cbegin(), buf.cbegin() + length, isAsciiDigit));
4093 }
else if (zero.size() == 2 && zero.at(0).isHighSurrogate()) {
4094 const char32_t zeroUcs4 = QChar::surrogateToUcs4(zero.at(0), zero.at(1));
4096 converted.reserve(2 * digits.size());
4097 for (QChar ch : std::as_const(digits)) {
4098 const char32_t digit = unicodeForDigit(ch.unicode() -
'0', zeroUcs4);
4099 Q_ASSERT(QChar::requiresSurrogates(digit));
4100 converted.append(QChar::highSurrogate(digit));
4101 converted.append(QChar::lowSurrogate(digit));
4103 digits =
std::move(converted);
4105 Q_ASSERT(zero.size() == 1);
4106 Q_ASSERT(!zero.at(0).isSurrogate());
4107 char16_t z = zero.at(0).unicode();
4108 char16_t *
const value =
reinterpret_cast<
char16_t *>(digits.data());
4109 for (qsizetype i = 0; i < digits.size(); ++i)
4110 value[i] = unicodeForDigit(value[i] -
'0', z);
4113 const bool mustMarkDecimal = flags &
ForcePoint;
4118 numStr = exponentForm(
std::move(digits), decpt, precision, PMDecimalDigits,
4119 mustMarkDecimal, minExponentDigits);
4122 numStr = decimalForm(
std::move(digits), decpt, precision, PMDecimalDigits,
4123 mustMarkDecimal, groupDigits);
4130
4131
4132
4133
4134
4135
4136
4137
4139 if (precision == QLocale::FloatingPointShortest) {
4146 int bias = 2 + minExponentDigits;
4148 if (groupDigits && decpt >= grouping
.first + grouping
.least)
4151 if (decpt > 10 && minExponentDigits == 1)
4156 const qsizetype digitCount = digits.size() / zero.size();
4157 if (!mustMarkDecimal) {
4160 if (digitCount <= decpt && digitCount > 1)
4162 else if (digitCount == 1 && decpt <= 0)
4170 useDecimal = (decpt <= 0 ? 1 - decpt <= bias
4171 : decpt <= digitCount ? 0 <= bias : decpt <= digitCount + bias);
4174 Q_ASSERT(precision >= 0);
4175 useDecimal = decpt > -4 && decpt <= (precision ? precision : 1);
4179 ? decimalForm(
std::move(digits), decpt, precision, mode,
4180 mustMarkDecimal, groupDigits)
4181 : exponentForm(
std::move(digits), decpt, precision, mode,
4182 mustMarkDecimal, minExponentDigits);
4189 for (qsizetype i = numStr.size() / zero.size() + prefix.size(); i < width; ++i)
4190 numStr.prepend(zero);
4195 ?
std::move(numStr).toUpper()
4196 :
std::move(numStr).toLower());
4199QString
QLocaleData::decimalForm(QString &&digits,
int decpt,
int precision,
4200 PrecisionMode pm,
bool mustMarkDecimal,
4201 bool groupDigits)
const
4203 const QString zero = zeroDigit();
4204 const auto digitWidth = zero.size();
4205 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
4206 Q_ASSERT(digits.size() % digitWidth == 0);
4211 for (; decpt < 0; ++decpt)
4212 digits.prepend(zero);
4214 for (qsizetype i = digits.size() / digitWidth; i < decpt; ++i)
4215 digits.append(zero);
4219 case PMDecimalDigits:
4220 for (qsizetype i = digits.size() / digitWidth - decpt; i < precision; ++i)
4221 digits.append(zero);
4223 case PMSignificantDigits:
4224 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
4225 digits.append(zero);
4227 case PMChopTrailingZeros:
4228 Q_ASSERT(digits.size() / digitWidth <= qMax(decpt, 1) || !digits.endsWith(zero));
4232 if (mustMarkDecimal || decpt < digits.size() / digitWidth)
4233 digits.insert(decpt * digitWidth, decimalPoint());
4237 const QString group = groupSeparator();
4238 qsizetype i = decpt - grouping.least;
4239 if (i >= grouping.first) {
4240 digits.insert(i * digitWidth, group);
4241 while ((i -= grouping.higher) > 0)
4242 digits.insert(i * digitWidth, group);
4247 digits.prepend(zero);
4249 return std::move(digits);
4252QString
QLocaleData::exponentForm(QString &&digits,
int decpt,
int precision,
4253 PrecisionMode pm,
bool mustMarkDecimal,
4254 int minExponentDigits)
const
4256 const QString zero = zeroDigit();
4257 const auto digitWidth = zero.size();
4258 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
4259 Q_ASSERT(digits.size() % digitWidth == 0);
4262 case PMDecimalDigits:
4263 for (qsizetype i = digits.size() / digitWidth; i < precision + 1; ++i)
4264 digits.append(zero);
4266 case PMSignificantDigits:
4267 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
4268 digits.append(zero);
4270 case PMChopTrailingZeros:
4271 Q_ASSERT(digits.size() / digitWidth <= 1 || !digits.endsWith(zero));
4275 if (mustMarkDecimal || digits.size() > digitWidth)
4276 digits.insert(digitWidth, decimalPoint());
4278 digits.append(exponentSeparator());
4279 digits.append(longLongToString(decpt - 1, minExponentDigits, 10, -1, AlwaysShowSign));
4281 return std::move(digits);
4284QString
QLocaleData::signPrefix(
bool negative,
unsigned flags)
const
4287 return negativeSign();
4288 if (flags & AlwaysShowSign)
4289 return positiveSign();
4290 if (flags & BlankBeforePositive)
4296 int base,
int width,
unsigned flags)
const
4298 bool negative = n < 0;
4301
4302
4303
4304 QString numStr = qulltoa(negative ? 1u + qulonglong(-(n + 1)) : qulonglong(n),
4307 return applyIntegerFormatting(
std::move(numStr), negative, precision, base, width, flags);
4311 int base,
int width,
unsigned flags)
const
4313 return applyIntegerFormatting(qulltoa(l, base, zeroDigit()),
4314 false, precision, base, width, flags);
4317QString
QLocaleData::applyIntegerFormatting(QString &&numStr,
bool negative,
int precision,
4318 int base,
int width,
unsigned flags)
const
4320 const QString zero = base == 10 ? zeroDigit() :
QStringLiteral(
"0");
4321 const auto digitWidth = zero.size();
4322 const auto digitCount = numStr.size() / digitWidth;
4324 const auto basePrefix = [&] () -> QStringView {
4325 if (flags & ShowBase) {
4326 const bool upper = flags & UppercaseBase;
4328 return upper ? u"0X" : u"0x";
4330 return upper ? u"0B" : u"0b";
4331 if (base == 8 && !numStr.startsWith(zero))
4337 const QString prefix = signPrefix(negative, flags) + basePrefix;
4339 qsizetype usedWidth = digitCount + prefix.size();
4343 const QString group = groupSeparator();
4344 qsizetype i = digitCount - grouping.least;
4345 if (i >= grouping.first) {
4346 numStr.insert(i * digitWidth, group);
4348 while ((i -= grouping.higher) > 0) {
4349 numStr.insert(i * digitWidth, group);
4356 const bool noPrecision = precision == -1;
4360 for (qsizetype i = numStr.size(); i < precision; ++i) {
4361 numStr.prepend(zero);
4368 for (qsizetype i = usedWidth; i < width; ++i)
4369 numStr.prepend(zero);
4372 QString result(flags & CapitalEorX ? std::move(numStr).toUpper() : std::move(numStr));
4374 result.prepend(prefix);
4379 :
grouping(data->groupSizes()), isC(data == c())
4385 setZero(data->zero().viewData(single_character_data));
4386 group = data->groupDelim().viewData(single_character_data);
4388 minus = data->minus().viewData(single_character_data);
4389 plus = data->plus().viewData(single_character_data);
4390 if (mode != IntegerMode)
4391 decimal = data->decimalSeparator().viewData(single_character_data);
4393 exponent = data->exponential().viewData(single_character_data);
4395 exponentCyrillic = data->m_script_id == QLocale::CyrillicScript;
4397#ifndef QT_NO_SYSTEMLOCALE
4398 if (data == &systemLocaleData) {
4399 const auto getString = [sys = systemLocale()](QSystemLocale::QueryType query) {
4400 return sys->query(query).toString();
4403 sysDecimal = getString(QSystemLocale::DecimalPoint);
4404 if (sysDecimal.size())
4405 decimal = QStringView{sysDecimal};
4407 sysGroup = getString(QSystemLocale::GroupSeparator);
4408 if (sysGroup.size())
4409 group = QStringView{sysGroup};
4410 sysMinus = getString(QSystemLocale::NegativeSign);
4411 if (sysMinus.size())
4412 minus = QStringView{sysMinus};
4413 sysPlus = getString(QSystemLocale::PositiveSign);
4415 plus = QStringView{sysPlus};
4416 setZero(getString(QSystemLocale::ZeroDigit));
4425class NumericTokenizer
4429 static constexpr char lettersInfNaN[] =
"afin";
4430 static constexpr auto matchInfNaN =
QtPrivate::makeCharacterSetMatch<lettersInfNaN>();
4431 const QStringView m_text;
4435 static_assert(
'+' + 1 ==
',' &&
',' + 1 ==
'-' &&
'-' + 1 ==
'.');
4440 : m_text(text), m_guide(guide), m_index(from), m_mode(mode),
4443 Q_ASSERT(m_guide.isValid(mode));
4445 bool done()
const {
return !(m_index < m_text.size()); }
4446 qsizetype index()
const {
return m_index; }
4447 int digitValue(
char32_t digit)
const {
return m_guide.digitValue(digit); }
4448 bool isInfNanChar(
char ch)
const {
return matchInfNaN.matches(ch); }
4450 bool fractionGroupClash()
const
4455 return Q_UNLIKELY(m_mode != QLocaleData::IntegerMode && m_guide.fractionalIsGroup());
4460char NumericTokenizer::nextToken()
4467 const auto asciiLower = [](
unsigned char c) {
return c >=
'A' ? c | 0x20 : c; };
4468 const QStringView tail = m_text.sliced(m_index);
4469 const QChar ch = tail.front();
4470 if (ch == u'\u2212') {
4477 if (Q_LIKELY(ch.unicode() < 256)) {
4478 unsigned char ascii = asciiLower(ch.toLatin1());
4479 if (Q_LIKELY(isAsciiDigit(ascii) || (
'+' <= ascii && ascii <= lastMark)
4490 if (ch.unicode() < 256) {
4492 char ascii = asciiLower(ch.toLatin1());
4493 if (isAsciiDigit(ascii) || ascii ==
'-' || ascii ==
'+'
4502 if (tail.startsWith(m_guide.minus)) {
4503 m_index += m_guide.minus.size();
4506 if (tail.startsWith(m_guide.plus)) {
4507 m_index += m_guide.plus.size();
4510 if (!m_guide.group.isEmpty() && tail.startsWith(m_guide.group)) {
4511 m_index += m_guide.group.size();
4516 if (fractionGroupClash() && tail.indexOf(m_guide.decimal, m_guide.group.size()) == -1)
4521 m_index += m_guide.decimal.size();
4526 m_index += m_guide.exponent.size();
4531 if (m_guide.zeroLen == 1) {
4532 if (!ch.isSurrogate()) {
4533 if (
const int gap = digitValue(
char32_t(ch.unicode())); gap >= 0) {
4537 }
else if (ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()) {
4541 }
else if (ch.isHighSurrogate()) {
4544 if (tail.size() > 1) {
4545 if (
const QChar low = tail.at(1); low.isLowSurrogate()) {
4546 if (
const int gap = digitValue(QChar::surrogateToUcs4(ch, low)); gap >= 0) {
4557 Q_ASSERT(!(ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()));
4560 switch (ch.unicode()) {
4574 if (m_guide.group == u"\u00a0" || m_guide.group == u"\u202f") {
4588 if (m_guide.exponentCyrillic) {
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4635
4636
4637
4638
4639
4640
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4680
4681
4682
4683
4684
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4707
4708
4709
4710
4711
4712
4713
4714
4717
4718
4719
4720
4721
4722
4723
4724
4727
4728
4729
4730
4731
4732
4733
4734
4735
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4777 Options flags, qsizetype from)
4778 : digitBounds({ from })
4780 NumericTokenizer tokens(text,
std::move(numeric),
IntegerMode, from);
4783 char currentToken = tokens.nextToken();
4788 if (currentToken ==
'+' || currentToken ==
'-') {
4791 digitBounds[0] = tokens.index();
4792 sign = currentToken;
4793 currentToken =
'\0';
4797 while (currentToken || !tokens.done()) {
4799 currentToken = tokens.nextToken();
4803 if (currentToken <
'0' || currentToken >
'9')
4807 digits.push_back(currentToken);
4808 digitBounds.push_back(tokens.index());
4809 currentToken =
'\0';
4811 Q_ASSERT(digitBounds.size() == digits.size() + 1);
4815
4816
4817
4818
4819
4820
4821
4822
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4848 NumericTokenizer tokens(s, NumericData(
this, mode), mode);
4851 enum { Whole, Grouped, Fraction, Exponent, Name } stage = Whole;
4857 bool wantDigits =
true;
4860 bool needHigherGroup =
false;
4861 qsizetype digitsInGroup = 0;
4863 const auto badLeastGroup = [&]() {
4869 if (stage == Grouped) {
4870 Q_ASSERT(!number_options.testFlag(QLocale::RejectGroupSeparator));
4872 if (needHigherGroup)
4875 if (digitsInGroup != grouping.least)
4882 while (!tokens.done()) {
4883 char out = tokens.nextToken();
4891 if (stage > Grouped)
4894 if (tokens.fractionGroupClash() && badLeastGroup()
4895 && digitsInGroup == grouping.higher) {
4901 needHigherGroup =
false;
4905 if (badLeastGroup())
4909 }
else if (out ==
'e') {
4910 if (wantDigits || stage == Name || stage > Fraction)
4913 if (stage < Fraction) {
4915 if (badLeastGroup())
4917 }
else if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot)) {
4924 }
else if (out ==
',') {
4930 if (number_options.testFlag(QLocale::RejectGroupSeparator))
4936 if (digitsInGroup == 0
4937 || digitsInGroup > qMax(grouping.first, grouping.higher)) {
4940 Q_ASSERT(!needHigherGroup);
4944 if (grouping.first > digitsInGroup)
4945 needHigherGroup =
true;
4950 if (digitsInGroup != grouping.higher)
4952 needHigherGroup =
false;
4961 }
else if (isAsciiDigit(out)) {
4964 if (out ==
'0' && number_options.testFlag(QLocale::RejectLeadingZeroInExponent)
4965 && stage > Fraction && !tokens.done() && !isAsciiDigit(last)) {
4973 }
else if (stage == Whole && tokens.isInfNanChar(out)) {
4983 result->append(out);
4988 if (!number_options.testFlag(QLocale::RejectGroupSeparator)) {
4990 if (stage < Fraction && badLeastGroup())
4994 if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot) && stage == Fraction) {
5005 QLocale::NumberOptions number_options)
const
5008 result.buff.reserve(str.size());
5010 enum { Whole, Fractional, Exponent } state = Whole;
5012 NumericTokenizer tokens(str, NumericData(
this, numMode), numMode);
5015 while (!tokens.done()) {
5016 char c = tokens.nextToken();
5018 if (isAsciiDigit(c)) {
5025 if (decDigits-- == 0)
5029 if (!isAsciiDigit(last)) {
5032 if (c ==
'0' && (number_options & QLocale::RejectLeadingZeroInExponent))
5054 if (last !=
'\0' && !(scientific && last ==
'e'))
5060 if ((number_options & QLocale::RejectGroupSeparator) || state != Whole
5061 || !isAsciiDigit(last)) {
5070 if (!scientific || state == Exponent)
5080 Q_ASSERT(!c || c ==
'a' || c ==
'f' || c ==
'i' || c ==
'n');
5087 result.buff.append(c);
5094 if (last ==
',' || last ==
'-' || last ==
'+' || last ==
'e')
5101 QLocale::NumberOptions number_options)
const
5104 if (!numberToCLocale(str, number_options, DoubleScientificMode, &buff)) {
5109 auto r = qt_asciiToDouble(buff.constData(), buff.size());
5117 QLocale::NumberOptions number_options)
const
5120 if (!numberToCLocale(str, number_options, IntegerMode, &buff))
5123 return bytearrayToLongLong(QByteArrayView(buff), base);
5128 QLocale::NumberOptions number_options)
const
5131 if (!numberToCLocale(str, number_options, IntegerMode, &buff))
5134 return bytearrayToUnsLongLong(QByteArrayView(buff), base);
5142 const qsizetype len = num.size();
5143 if (used < len && num[used] !=
'\0') {
5144 while (used < len && ascii_isspace(num[used]))
5148 if (used < len && num[used] !=
'\0')
5155QSimpleParsedNumber<qint64>
QLocaleData::bytearrayToLongLong(QByteArrayView num,
int base)
5157 auto r = qstrntoll(num.data(), num.size(), base);
5158 if (!checkParsed(num, r.used))
5163QSimpleParsedNumber<quint64>
QLocaleData::bytearrayToUnsLongLong(QByteArrayView num,
int base)
5165 auto r = qstrntoull(num.data(), num.size(), base);
5166 if (!checkParsed(num, r.used))
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5184
5185
5186
5187QString QLocale::currencySymbol(CurrencySymbolFormat format)
const
5189#ifndef QT_NO_SYSTEMLOCALE
5190 if (d->m_data == &systemLocaleData) {
5191 auto res = systemLocale()->query(QSystemLocale::CurrencySymbol, format).toString();
5197 case CurrencySymbol:
5198 return d->m_data->currencySymbol().getData(currency_symbol_data);
5199 case CurrencyDisplayName:
5200 return d->m_data->currencyDisplayName().getData(currency_display_name_data);
5201 case CurrencyIsoCode: {
5202 const char *code = d->m_data->m_currency_iso_code;
5203 if (
auto len = qstrnlen(code, 3))
5204 return QString::fromLatin1(code, qsizetype(len));
5212
5213
5214
5215
5216
5217
5218
5219QString QLocale::toCurrencyString(qlonglong value,
const QString &symbol)
const
5221#ifndef QT_NO_SYSTEMLOCALE
5222 if (d->m_data == &systemLocaleData) {
5223 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5224 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5225 QVariant::fromValue(arg)).toString();
5230 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
5231 if (!range.size || value >= 0)
5232 range = d->m_data->currencyFormat();
5235 QString str = toString(value);
5236 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5238 sym = currencySymbol(CurrencyIsoCode);
5239 return range.viewData(currency_format_data).arg(str, sym);
5243
5244
5245
5246QString QLocale::toCurrencyString(qulonglong value,
const QString &symbol)
const
5248#ifndef QT_NO_SYSTEMLOCALE
5249 if (d->m_data == &systemLocaleData) {
5250 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5251 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5252 QVariant::fromValue(arg)).toString();
5257 QString str = toString(value);
5258 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5260 sym = currencySymbol(CurrencyIsoCode);
5261 return d->m_data->currencyFormat().getData(currency_format_data).arg(str, sym);
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274QString QLocale::toCurrencyString(
double value,
const QString &symbol,
int precision)
const
5276#ifndef QT_NO_SYSTEMLOCALE
5277 if (d->m_data == &systemLocaleData) {
5278 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5279 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5280 QVariant::fromValue(arg)).toString();
5285 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
5286 if (!range.size || value >= 0)
5287 range = d->m_data->currencyFormat();
5290 QString str = toString(value,
'f', precision == -1 ? d->m_data->m_currency_digits : precision);
5291 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5293 sym = currencySymbol(CurrencyIsoCode);
5294 return range.viewData(currency_format_data).arg(str, sym);
5298
5299
5300
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334QString QLocale::formattedDataSize(qint64 bytes,
int precision, DataSizeFormats format)
const
5336 int power, base = 1000;
5339 }
else if (format & DataSizeBase1000) {
5340 constexpr auto log10_1000 = 3;
5341 power =
int(std::log10(QtPrivate::qUnsignedAbs(bytes))) / log10_1000;
5343 constexpr auto log2_1024 = 10;
5344 power = QtPrivate::log2i(QtPrivate::qUnsignedAbs(bytes)) / log2_1024;
5348 const QString number = power
5349 ? toString(bytes / std::pow(
double(base), power),
'f', qMin(precision, 3 * power))
5354 Q_ASSERT(power <= 6 && power >= 0);
5357 QLocaleData::DataRange range = (format & DataSizeSIQuantifiers)
5358 ? d->m_data->byteAmountSI() : d->m_data->byteAmountIEC();
5359 unit = range.viewListEntry(byte_unit_data, power - 1);
5361 unit = d->m_data->byteCount().viewData(byte_unit_data);
5364 return number + u' ' + unit;
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
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410QStringList QLocale::uiLanguages(TagSeparator separator)
const
5412 const char sep =
char(separator);
5413 QStringList uiLanguages;
5414 if (uchar(sep) > 0x7f) {
5415 badSeparatorWarning(
"uiLanguages", sep);
5418 QList<QLocaleId> localeIds;
5419#ifdef QT_NO_SYSTEMLOCALE
5420 constexpr bool isSystem =
false;
5422 const bool isSystem = d->m_data == &systemLocaleData;
5424 uiLanguages = systemLocale()->query(QSystemLocale::UILanguages).toStringList();
5425 if (separator != TagSeparator::Dash) {
5427 const QChar join = QLatin1Char(sep);
5428 uiLanguages.replaceInStrings(u"-", QStringView(&join, 1));
5432 for (
const auto &entry : std::as_const(uiLanguages))
5433 localeIds.append(QLocaleId::fromName(entry));
5434 if (localeIds.isEmpty())
5435 localeIds.append(systemLocale()->fallbackLocale().d->m_data->id());
5437
5438
5439
5440
5441
5442
5443
5444 const QString name = QString::fromLatin1(d->m_data->id().name(sep));
5445 if (!name.isEmpty() && language() != C && !uiLanguages.contains(name)) {
5448 const QLocaleId id = d->m_data->id();
5449 const QLocaleId max = id.withLikelySubtagsAdded();
5450 const QLocaleId mine = max.withLikelySubtagsRemoved();
5452 qsizetype lastAlike = uiLanguages.size() - 1;
5454 for (qsizetype i = 0; !seen && i < uiLanguages.size(); ++i) {
5455 const auto its = QLocaleId::fromName(uiLanguages.at(i)).withLikelySubtagsAdded();
5456 seen = its.withLikelySubtagsRemoved() == mine;
5457 if (!seen && its.language_id == max.language_id && its.script_id == max.script_id)
5461 localeIds.insert(lastAlike + 1, id);
5462 uiLanguages.insert(lastAlike + 1, QString::fromLatin1(id.name(sep)));
5468 localeIds.append(d->m_data->id());
5471 for (qsizetype i = localeIds.size(); i-- > 0; ) {
5472 const QLocaleId id = localeIds.at(i);
5473 Q_ASSERT(id.language_id);
5474 if (id.language_id == C) {
5475 if (!uiLanguages.contains(u"C"_s))
5476 uiLanguages.append(u"C"_s);
5482 const QByteArray prior = id.name(sep);
5483 bool faithful =
true;
5484 if (isSystem && i < uiLanguages.size()) {
5486 faithful = uiLanguages.at(i) == QLatin1StringView(prior);
5489 || QLocaleId::fromName(uiLanguages.at(i)).name(sep) == prior);
5494 if (!uiLanguages.contains(QLatin1StringView(prior)))
5495 uiLanguages.append(QString::fromLatin1(prior));
5496 j = uiLanguages.size();
5499 const QLocaleId max = id.withLikelySubtagsAdded();
5500 Q_ASSERT(max.language_id);
5501 Q_ASSERT(max.language_id == id.language_id);
5505 const auto addIfEquivalent = [&j, &uiLanguages, max, sep, &prior, faithful](QLocaleId cid) {
5506 if (cid.withLikelySubtagsAdded() == max) {
5507 if (
const QByteArray name = cid.name(sep); name != prior)
5508 uiLanguages.insert(j, QString::fromLatin1(name));
5514 addIfEquivalent({ max.language_id, 0, 0 });
5517 addIfEquivalent({ max.language_id, max.script_id, 0 });
5518 if (id.script_id && id.script_id != max.script_id)
5519 addIfEquivalent({ id.language_id, id.script_id, 0 });
5521 if (max.territory_id)
5522 addIfEquivalent({ max.language_id, 0, max.territory_id });
5523 if (id.territory_id && id.territory_id != max.territory_id)
5524 addIfEquivalent({ id.language_id, 0, id.territory_id });
5526 if (max.territory_id && max.script_id)
5527 addIfEquivalent(max);
5528 if (max.territory_id && id.script_id && id.script_id != max.script_id)
5529 addIfEquivalent({ id.language_id, id.script_id, max.territory_id });
5530 if (max.script_id && id.territory_id && id.territory_id != max.territory_id)
5531 addIfEquivalent({ id.language_id, max.script_id, id.territory_id });
5532 if (id.territory_id && id.territory_id != max.territory_id
5533 && id.script_id && id.script_id != max.script_id) {
5534 addIfEquivalent(id);
5541 QDuplicateTracker<QString> known(uiLanguages.size());
5542 uiLanguages.removeIf([&](
const QString &s) {
return known.hasSeen(s); });
5546 const QLatin1Char cut(sep);
5547 const auto hasPrefix = [cut](
auto name, QStringView stem) {
5549 return name.startsWith(stem)
5550 && (name.size() == stem.size() || name.at(stem.size()) == cut);
5561 qsizetype afterEquivs = 0;
5562 qsizetype afterTruncs = 0;
5566 for (qsizetype i = 0; i < uiLanguages.size(); ++i >= afterEquivs && (i = afterTruncs)) {
5567 const QString entry = uiLanguages.at(i);
5568 const QLocaleId max = QLocaleId::fromName(entry).withLikelySubtagsAdded();
5570 if (i >= afterEquivs) {
5571 Q_ASSERT(i >= afterTruncs);
5572 afterEquivs = i + 1;
5574 while (afterEquivs < uiLanguages.size()
5575 && QLocaleId::fromName(uiLanguages.at(afterEquivs))
5576 .withLikelySubtagsAdded() == max) {
5580 afterTruncs = afterEquivs;
5582 if (hasPrefix(entry, u"C") || hasPrefix(entry, u"und"))
5584 qsizetype stopAt = uiLanguages.size();
5585 qsizetype at = entry.size();
5586 while ((at = entry.lastIndexOf(cut, at - 1)) > 0) {
5587 QString prefix = entry.first(at);
5591 bool found = known.contains(prefix);
5593
5594
5595
5596
5597
5598
5599
5600
5601
5603 = (QLocaleId::fromName(prefix).withLikelySubtagsAdded().script_id == max.script_id);
5604 for (qsizetype j = afterTruncs; !found && j < stopAt; ++j) {
5605 QString later = uiLanguages.at(j);
5606 if (!later.startsWith(prefix)) {
5607 const QByteArray laterFull =
5608 QLocaleId::fromName(later.replace(cut, u'-')
5609 ).withLikelySubtagsAdded().name(sep);
5611 if (hasPrefix(QLatin1StringView(laterFull), prefix))
5616 Q_ASSERT(later.size() > prefix.size());
5617 if (later.at(prefix.size()) == cut) {
5624 QStringView head{later};
5625 for (qsizetype as = head.lastIndexOf(cut);
5626 !found && as > prefix.size(); as = head.lastIndexOf(cut)) {
5627 head = head.first(as);
5629 for (qsizetype k = j + 1; !seen && k < uiLanguages.size(); ++k)
5630 seen = uiLanguages.at(k) == head;
5639 (
void) known.hasSeen(prefix);
5641 uiLanguages.insert(afterTruncs++, std::move(prefix));
5644 uiLanguages.append(std::move(prefix));
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663QLocale QLocale::collation()
const
5665#ifndef QT_NO_SYSTEMLOCALE
5666 if (d->m_data == &systemLocaleData) {
5667 const auto res = systemLocale()->query(QSystemLocale::Collation).toString();
5669 return QLocale(res);
5676
5677
5678
5679
5680
5681
5682
5683QString QLocale::nativeLanguageName()
const
5685#ifndef QT_NO_SYSTEMLOCALE
5686 if (d->m_data == &systemLocaleData) {
5687 auto res = systemLocale()->query(QSystemLocale::NativeLanguageName).toString();
5692 return d->m_data->endonymLanguage().getData(endonyms_data);
5696
5697
5698
5699
5700
5701
5702
5703QString QLocale::nativeTerritoryName()
const
5705#ifndef QT_NO_SYSTEMLOCALE
5706 if (d->m_data == &systemLocaleData) {
5707 auto res = systemLocale()->query(QSystemLocale::NativeTerritoryName).toString();
5712 return d->m_data->endonymTerritory().getData(endonyms_data);
5715#if QT_DEPRECATED_SINCE(6
, 6
)
5717
5718
5719
5720
5721
5722
5723
5724
5725QString QLocale::nativeCountryName()
const
5727 return nativeTerritoryName();
5731#ifndef QT_NO_DEBUG_STREAM
5734 QDebugStateSaver saver(dbg);
5735 const bool isSys = l == QLocale::system();
5736 dbg.nospace().noquote()
5737 << (isSys ?
"QLocale::system()/* " :
"QLocale(")
5738 << QLocale::languageToString(l.language()) <<
", "
5739 << QLocale::scriptToString(l.script()) <<
", "
5740 << QLocale::territoryToString(l.territory()) << (isSys ?
" */" :
")");
5746#ifndef QT_NO_QOBJECT
5747#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