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())
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
783 const QChar c = s.front();
785 while (j < s.size() && s.at(j) == c)
790Q_CONSTINIT
static const QLocaleData *default_data =
nullptr;
791Q_CONSTINIT QBasicAtomicInt QLocalePrivate::s_generation = Q_BASIC_ATOMIC_INITIALIZER(0);
795 Q_CONSTINIT
static QLocalePrivate c_locale(locale_data, 0, QLocale::OmitGroupSeparator, 1);
801 return forLanguage == QLocale::C ? QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions;
806 return defaultNumberOptions(QLocale::Language(forLanguage));
809#ifndef QT_NO_SYSTEMLOCALE
811
812
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834QSystemLocale::QSystemLocale() : next(_systemLocale)
836 _systemLocale =
this;
838 systemLocaleData.m_language_id = 0;
842
843
844
845QSystemLocale::~QSystemLocale()
847 if (_systemLocale ==
this) {
848 _systemLocale = next;
851 systemLocaleData.m_language_id = 0;
853 for (QSystemLocale *p = _systemLocale; p; p = p->next) {
863 return _systemLocale;
868 static QSystemLocale globalInstance;
869 return &globalInstance;
877 const QSystemLocale *sys_locale = systemLocale();
880 sys_locale->query(QSystemLocale::LocaleChanged);
883 systemLocaleData = locale_data[sys_locale->fallbackLocaleIndex()];
885 QVariant res = sys_locale->query(QSystemLocale::LanguageId);
887 systemLocaleData.m_language_id = res.toInt();
888 systemLocaleData.m_script_id = QLocale::AnyScript;
890 res = sys_locale->query(QSystemLocale::TerritoryId);
892 systemLocaleData.m_territory_id = res.toInt();
893 systemLocaleData.m_script_id = QLocale::AnyScript;
895 res = sys_locale->query(QSystemLocale::ScriptId);
897 systemLocaleData.m_script_id = res.toInt();
902 if (default_data == &systemLocaleData)
903 QLocalePrivate::s_generation.fetchAndAddRelaxed(1);
909#ifndef QT_NO_SYSTEMLOCALE
911
912
913
914
915
916
917
919 Q_CONSTINIT
static QLocaleId sysId;
920 bool updated =
false;
922 Q_CONSTINIT
static QBasicMutex systemDataMutex;
923 systemDataMutex.lock();
924 if (systemLocaleData.m_language_id == 0) {
925 updateSystemPrivate();
929 if (sysIndex && (updated || *sysIndex < 0)) {
930 const QLocaleId nowId = systemLocaleData.id();
931 if (sysId != nowId || *sysIndex < 0) {
933 *sysIndex = QLocaleData::findLocaleIndex(nowId);
937 systemDataMutex.unlock();
940 return &systemLocaleData;
950 default_data = systemData();
957#ifndef QT_NO_SYSTEMLOCALE
958 if (data == &systemLocaleData) {
961 return QLocaleData::findLocaleIndex(data->id());
972 Q_ASSERT(locale_index[QLocale::C] == 0);
976#ifndef QT_NO_DATASTREAM
977QDataStream &operator<<(QDataStream &ds,
const QLocale &l)
983QDataStream &
operator>>(QDataStream &ds, QLocale &l)
993 new QLocalePrivate(defaultData(), defaultIndex(),
994 defaultNumberOptions(defaultData()->m_language_id)))
1000 const qsizetype index = QLocaleData::findLocaleIndex(QLocaleId::fromName(name));
1001 return new QLocalePrivate(QLocaleData::dataForLocaleIndex(index), index,
1002 defaultNumberOptions(locale_data[index].m_language_id));
1006 QLocale::Territory territory)
1008 if (language == QLocale::C)
1011 qsizetype index = QLocaleData::findLocaleIndex(QLocaleId { language, script, territory });
1012 const QLocaleData *data = QLocaleData::dataForLocaleIndex(index);
1014 QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
1017 if (data->m_language_id == QLocale::C) {
1018 if (defaultLocalePrivate.exists())
1019 numberOptions = defaultLocalePrivate->data()->m_numberOptions;
1021 index = defaultIndex();
1029 auto compareWithPrivate = [&loc](
const QLocaleData *data, QLocale::NumberOptions opts)
1031 return loc.d->m_data == data && loc.d->m_numberOptions == opts;
1034 if (lang == QLocale::C)
1037 qsizetype index = QLocaleData::findLocaleIndex(QLocaleId { lang });
1038 const QLocaleData *data = QLocaleData::dataForLocaleIndex(index);
1040 QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
1043 if (data->m_language_id == QLocale::C) {
1044 if (defaultLocalePrivate.exists())
1045 numberOptions = defaultLocalePrivate->data()->m_numberOptions;
1048 return compareWithPrivate(data, numberOptions);
1051static std::optional<QString>
1054#ifndef QT_NO_SYSTEMLOCALE
1055 if (that != &systemLocaleData)
1056 return std::nullopt;
1058 QVariant v = systemLocale()->query(type);
1059 if (v.metaType() != QMetaType::fromType<QString>())
1060 return std::nullopt;
1062 return v.toString();
1066 return std::nullopt;
1073 if (
auto opt = systemLocaleString(that, type))
1080 return localeString(
this, QSystemLocale::DecimalPoint, decimalSeparator());
1085 return localeString(
this, QSystemLocale::GroupSeparator, groupDelim());
1100 return localeString(
this, QSystemLocale::ZeroDigit, zero());
1105#ifndef QT_NO_SYSTEMLOCALE
1106 if (
this == &systemLocaleData) {
1107 const auto text = systemLocale()->query(QSystemLocale::ZeroDigit).toString();
1108 if (!text.isEmpty()) {
1109 if (text.size() == 1 && !text.at(0).isSurrogate())
1110 return text.at(0).unicode();
1111 if (text.size() == 2 && text.at(0).isHighSurrogate())
1112 return QChar::surrogateToUcs4(text.at(0), text.at(1));
1121 return localeString(
this, QSystemLocale::NegativeSign, minus());
1126 return localeString(
this, QSystemLocale::PositiveSign, plus());
1136#ifndef QT_NO_SYSTEMLOCALE
1137 if (
this == &systemLocaleData) {
1138 QVariant queryResult = systemLocale()->query(QSystemLocale::Grouping);
1139 if (!queryResult.isNull()) {
1142 if (sysGroupSizes.first <= 0)
1143 sysGroupSizes.first = m_grouping_first;
1144 if (sysGroupSizes.higher <= 0)
1145 sysGroupSizes.higher = m_grouping_higher;
1146 if (sysGroupSizes.least <= 0)
1147 sysGroupSizes.least = m_grouping_least;
1148 return sysGroupSizes;
1152 return { m_grouping_first,
1158
1159
1160QLocale::QLocale(QLocalePrivate &dd)
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211QLocale::QLocale(QStringView name)
1212 : d(localePrivateByName(name))
1217
1218
1219
1222
1223
1224
1225
1226
1227
1228
1233 if (!defaultLocalePrivate.isDestroyed()) {
1236 d = *defaultLocalePrivate;
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1252QLocale::QLocale(Language language, Territory territory)
1253 : d(findLocalePrivate(language, AnyScript, territory))
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1276QLocale::QLocale(Language language, Script script, Territory territory)
1277 : d(findLocalePrivate(language, script, territory))
1282
1283
1285QLocale::QLocale(
const QLocale &other)
noexcept =
default;
1288
1289
1296
1297
1298
1300QLocale &QLocale::operator=(
const QLocale &other)
noexcept =
default;
1303
1304
1305
1307bool QLocale::equals(
const QLocale &other)
const noexcept
1309 return d->m_data == other.d->m_data && d->m_numberOptions == other.d->m_numberOptions;
1313
1314
1315
1316
1319
1320
1321
1324 return qHashMulti(seed, key.d->m_data, key.d->m_numberOptions);
1328
1329
1330
1331
1332
1333
1334void QLocale::setNumberOptions(NumberOptions options)
1336 d->m_numberOptions = options;
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349QLocale::NumberOptions QLocale::numberOptions()
const
1351 return d->m_numberOptions;
1355
1356
1357
1358
1359
1360
1361
1364
1365
1366
1367
1368QString QLocale::quoteString(QStringView str, QuotationStyle style)
const
1370#ifndef QT_NO_SYSTEMLOCALE
1371 if (d->m_data == &systemLocaleData) {
1373 if (style == AlternateQuotation)
1374 res = systemLocale()->query(QSystemLocale::StringToAlternateQuotation,
1375 QVariant::fromValue(str));
1376 if (res.isNull() || style == StandardQuotation)
1377 res = systemLocale()->query(QSystemLocale::StringToStandardQuotation,
1378 QVariant::fromValue(str));
1380 return res.toString();
1384 QLocaleData::DataRange start, end;
1385 if (style == StandardQuotation) {
1386 start = d->m_data->quoteStart();
1387 end = d->m_data->quoteEnd();
1389 start = d->m_data->quoteStartAlternate();
1390 end = d->m_data->quoteEndAlternate();
1393 return start.viewData(single_character_data) % str % end.viewData(single_character_data);
1397
1398
1399
1400
1401
1402QString QLocale::createSeparatedList(
const QStringList &list)
const
1405#ifndef QT_NO_SYSTEMLOCALE
1406 if (d->m_data == &systemLocaleData) {
1408 systemLocale()->query(QSystemLocale::ListToSeparatedString, QVariant::fromValue(list));
1411 return res.toString();
1415 const qsizetype size = list.size();
1423 return d->m_data->pairListPattern().getData(
1424 list_pattern_part_data).arg(list.at(0), list.at(1));
1426 QStringView formatStart = d->m_data->startListPattern().viewData(list_pattern_part_data);
1427 QStringView formatMid = d->m_data->midListPattern().viewData(list_pattern_part_data);
1428 QStringView formatEnd = d->m_data->endListPattern().viewData(list_pattern_part_data);
1429 QString result = formatStart.arg(list.at(0), list.at(1));
1430 for (qsizetype i = 2; i < size - 1; ++i)
1431 result = formatMid.arg(result, list.at(i));
1432 result = formatEnd.arg(result, list.at(size - 1));
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1450void QLocale::setDefault(
const QLocale &locale)
1452 default_data = locale.d->m_data;
1454 if (defaultLocalePrivate.isDestroyed())
1456 if (!defaultLocalePrivate.exists()) {
1458 [[maybe_unused]] QLocale ignoreme;
1459 Q_ASSERT(defaultLocalePrivate.exists());
1463 *defaultLocalePrivate = locale.d;
1464 QLocalePrivate::s_generation.fetchAndAddRelaxed(1);
1468
1469
1470
1471
1472QLocale::Language QLocale::language()
const
1474 return Language(d->languageId());
1478
1479
1480
1481
1482
1483
1484QLocale::Script QLocale::script()
const
1486 return Script(d->m_data->m_script_id);
1490
1491
1492
1493
1494
1495
1496QLocale::Territory QLocale::territory()
const
1498 return Territory(d->territoryId());
1501#if QT_DEPRECATED_SINCE(6
, 6
)
1503
1504
1505
1506
1507
1508
1509QLocale::Country QLocale::country()
const
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1543 qWarning(
"QLocale::%s(): Using non-ASCII separator '%c' (%02x) is unsupported",
1544 method, sep, uint(uchar(sep)));
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1567QString QLocale::name(TagSeparator separator)
const
1569 const char sep =
char(separator);
1570 if (uchar(sep) > 0x7f) {
1571 badSeparatorWarning(
"name", sep);
1574 const auto code = d->languageCode();
1575 QLatin1StringView view{code.data()};
1577 Language l = language();
1581 Territory c = territory();
1582 if (c == AnyTerritory)
1585 return view + QLatin1Char(sep) + d->territoryCode();
1588template <
typename T>
static inline
1591 constexpr bool isUnsigned =
std::is_unsigned_v<T>;
1592 using Int64 =
typename std::conditional_t<isUnsigned, quint64, qint64>;
1594 QSimpleParsedNumber<Int64> r{};
1595 if constexpr (isUnsigned)
1596 r = d
->m_data->stringToUnsLongLong(str, 10, d->m_numberOptions);
1598 r = d
->m_data->stringToLongLong(str, 10, d->m_numberOptions);
1603 Int64 val = r.result;
1604 if (T(val) != val) {
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637QString QLocale::bcp47Name(TagSeparator separator)
const
1639 const char sep =
char(separator);
1640 if (uchar(sep) > 0x7f) {
1641 badSeparatorWarning(
"bcp47Name", sep);
1644 return QString::fromLatin1(d->bcp47Name(sep));
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665QString QLocale::languageToCode(Language language, LanguageCodeTypes codeTypes)
1667 const auto code = QLocalePrivate::languageToCode(language, codeTypes);
1668 return QLatin1StringView{code.data()};
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685QLocale::Language QLocale::codeToLanguage(QStringView languageCode,
1686 LanguageCodeTypes codeTypes)
noexcept
1688 return QLocalePrivate::codeToLanguage(languageCode, codeTypes);
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701QString QLocale::territoryToCode(QLocale::Territory territory)
1703 return QLocalePrivate::territoryToCode(territory);
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716QLocale::Territory QLocale::codeToTerritory(QStringView territoryCode)
noexcept
1718 return QLocalePrivate::codeToTerritory(territoryCode);
1721#if QT_DEPRECATED_SINCE(6
, 6
)
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732QString QLocale::countryToCode(Country country)
1734 return territoryToCode(country);
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747QLocale::Country QLocale::codeToCountry(QStringView countryCode)
noexcept
1749 return QLocalePrivate::codeToTerritory(countryCode);
1754
1755
1756
1757
1758
1759
1760
1761
1762QString QLocale::scriptToCode(Script script)
1764 return QLocalePrivate::scriptToCode(script);
1768
1769
1770
1771
1772
1773
1774
1775
1776QLocale::Script QLocale::codeToScript(QStringView scriptCode)
noexcept
1778 return QLocalePrivate::codeToScript(scriptCode);
1782
1783
1784
1785
1787QString QLocale::languageToString(Language language)
1789 if (language > LastLanguage)
1790 return "Unknown"_L1;
1791 return QString::fromUtf8(language_name_list + language_name_index[language]);
1795
1796
1797
1798
1799
1800
1801QString QLocale::territoryToString(Territory territory)
1803 if (territory > LastTerritory)
1804 return "Unknown"_L1;
1805 return QString::fromUtf8(territory_name_list + territory_name_index[territory]);
1808#if QT_DEPRECATED_SINCE(6
, 6
)
1810
1811
1812
1813
1814
1815
1816QString QLocale::countryToString(Country country)
1818 return territoryToString(country);
1823
1824
1825
1826
1827
1828
1829QString QLocale::scriptToString(Script script)
1831 if (script > LastScript)
1832 return "Unknown"_L1;
1833 return QString::fromUtf8(script_name_list + script_name_index[script]);
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2008short QLocale::toShort(QStringView s,
bool *ok)
const
2010 return toIntegral_helper<
short>(d, s, ok);
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2028ushort QLocale::toUShort(QStringView s,
bool *ok)
const
2030 return toIntegral_helper<ushort>(d, s, ok);
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2048int QLocale::toInt(QStringView s,
bool *ok)
const
2050 return toIntegral_helper<
int>(d, s, ok);
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2068uint QLocale::toUInt(QStringView s,
bool *ok)
const
2070 return toIntegral_helper<uint>(d, s, ok);
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2087long QLocale::toLong(QStringView s,
bool *ok)
const
2089 return toIntegral_helper<
long>(d, s, ok);
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2107ulong QLocale::toULong(QStringView s,
bool *ok)
const
2109 return toIntegral_helper<ulong>(d, s, ok);
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2128qlonglong QLocale::toLongLong(QStringView s,
bool *ok)
const
2130 return toIntegral_helper<qlonglong>(d, s, ok);
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2149qulonglong QLocale::toULongLong(QStringView s,
bool *ok)
const
2151 return toIntegral_helper<qulonglong>(d, s, ok);
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2170float QLocale::toFloat(QStringView s,
bool *ok)
const
2172 return QLocaleData::convertDoubleToFloat(toDouble(s, ok), ok);
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2196double QLocale::toDouble(QStringView s,
bool *ok)
const
2198 return d->m_data->stringToDouble(s, ok, d->m_numberOptions);
2202
2203
2204
2205
2207QString QLocale::toString(qlonglong i)
const
2209 int flags = (d->m_numberOptions & OmitGroupSeparator
2210 ? 0 : QLocaleData::GroupDigits);
2212 return d->m_data->longLongToString(i, -1, 10, -1, flags);
2216
2217
2218
2219
2221QString QLocale::toString(qulonglong i)
const
2223 int flags = (d->m_numberOptions & OmitGroupSeparator
2224 ? 0 : QLocaleData::GroupDigits);
2226 return d->m_data->unsLongLongToString(i, -1, 10, -1, flags);
2232 qsizetype count = 0;
2235 [[maybe_unused]]
auto ch = counter
.next();
2241 const QLocale &locale)
2244 if (!(locale.numberOptions() & QLocale::OmitGroupSeparator))
2248 else if (fillChar == U'0')
2260 if (fillChar == U'0') {
2261 Q_ASSERT(fieldWidth < 0);
2262 filler = localeData->zeroDigit();
2264 filler = QString(QChar::fromUcs4(fillChar));
2268 filler = filler.repeated(padding);
2273
2274
2275
2276
2277
2278
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298QString QLocale::toString(qlonglong number,
int fieldWidth,
char32_t fillChar)
const
2300 int absFieldWidth = qAbs(fieldWidth);
2301 int width = (fillChar == U'0') ? absFieldWidth : -1;
2302 unsigned flags = calculateFlags(fieldWidth, fillChar, *
this);
2304 QString result = d->m_data->longLongToString(number, -1, 10, width, flags);
2305 qsizetype padding = absFieldWidth - stringWidth(result);
2308 QString filler = calculateFiller(padding, fillChar, fieldWidth, d->m_data);
2310 result.append(filler);
2312 result.prepend(filler);
2318
2319
2320
2321
2322
2323
2325
2326
2327
2328QString QLocale::toString(qulonglong number,
int fieldWidth,
char32_t fillChar)
const
2330 int absFieldWidth = qAbs(fieldWidth);
2331 int width = (fillChar == U'0') ? absFieldWidth : -1;
2332 unsigned flags = calculateFlags(fieldWidth, fillChar, *
this);
2334 QString result = d->m_data->unsLongLongToString(number, -1, 10, width, flags);
2335 qsizetype padding = absFieldWidth - stringWidth(result);
2338 QString filler = calculateFiller(padding, fillChar, fieldWidth, d->m_data);
2340 result.append(filler);
2342 result.prepend(filler);
2348
2349
2350
2351
2352
2353
2355QString QLocale::toString(QDate date,
const QString &format)
const
2357 return toString(date, qToStringViewIgnoringNull(format));
2361
2362
2363
2364
2365
2366
2368QString QLocale::toString(QTime time,
const QString &format)
const
2370 return toString(time, qToStringViewIgnoringNull(format));
2374
2375
2376
2377
2378
2379
2380
2381
2382
2385
2386
2387
2388
2389
2390
2391
2392
2393QString QLocale::toString(QDate date, QStringView format, QCalendar cal)
const
2395 return cal.dateTimeToString(format, QDateTime(), date, QTime(), *
this);
2399
2400
2401
2402QString QLocale::toString(QDate date, QStringView format)
const
2404 return QCalendar().dateTimeToString(format, QDateTime(), date, QTime(), *
this);
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417QString QLocale::toString(QDate date, FormatType format, QCalendar cal)
const
2419 if (!date.isValid())
2422#ifndef QT_NO_SYSTEMLOCALE
2423 if (cal.isGregorian() && d->m_data == &systemLocaleData) {
2424 QVariant res = systemLocale()->query(format == LongFormat
2425 ? QSystemLocale::DateToStringLong
2426 : QSystemLocale::DateToStringShort,
2429 return res.toString();
2433 QString format_str = dateFormat(format);
2434 return toString(date, format_str, cal);
2438
2439
2440
2441QString QLocale::toString(QDate date, FormatType format)
const
2443 if (!date.isValid())
2446#ifndef QT_NO_SYSTEMLOCALE
2447 if (d->m_data == &systemLocaleData) {
2448 QVariant res = systemLocale()->query(format == LongFormat
2449 ? QSystemLocale::DateToStringLong
2450 : QSystemLocale::DateToStringShort,
2453 return res.toString();
2457 QString format_str = dateFormat(format);
2458 return toString(date, format_str);
2464 while (i < format.size()) {
2465 if (format.at(i).unicode() ==
'\'') {
2466 qt_readEscapedFormatString(format, &i);
2470 if (format.at(i).toLower().unicode() ==
'a')
2479
2480
2481
2482
2483
2484
2485
2486
2487QString QLocale::toString(QTime time, QStringView format)
const
2489 return QCalendar().dateTimeToString(format, QDateTime(), QDate(), time, *
this);
2493
2494
2495
2496
2497
2498
2499
2500
2501QString QLocale::toString(
const QDateTime &dateTime, QStringView format, QCalendar cal)
const
2503 return cal.dateTimeToString(format, dateTime, QDate(), QTime(), *
this);
2507
2508
2509
2510QString QLocale::toString(
const QDateTime &dateTime, QStringView format)
const
2512 return QCalendar().dateTimeToString(format, dateTime, QDate(), QTime(), *
this);
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525QString QLocale::toString(
const QDateTime &dateTime, FormatType format, QCalendar cal)
const
2527 if (!dateTime.isValid())
2530#ifndef QT_NO_SYSTEMLOCALE
2531 if (cal.isGregorian() && d->m_data == &systemLocaleData) {
2532 QVariant res = systemLocale()->query(format == LongFormat
2533 ? QSystemLocale::DateTimeToStringLong
2534 : QSystemLocale::DateTimeToStringShort,
2537 return res.toString();
2541 const QString format_str = dateTimeFormat(format);
2542 return toString(dateTime, format_str, cal);
2546
2547
2548
2549QString QLocale::toString(
const QDateTime &dateTime, FormatType format)
const
2551 if (!dateTime.isValid())
2554#ifndef QT_NO_SYSTEMLOCALE
2555 if (d->m_data == &systemLocaleData) {
2556 QVariant res = systemLocale()->query(format == LongFormat
2557 ? QSystemLocale::DateTimeToStringLong
2558 : QSystemLocale::DateTimeToStringShort,
2561 return res.toString();
2565 const QString format_str = dateTimeFormat(format);
2566 return toString(dateTime, format_str);
2571
2572
2573
2575QString QLocale::toString(QTime time, FormatType format)
const
2577 if (!time.isValid())
2580#ifndef QT_NO_SYSTEMLOCALE
2581 if (d->m_data == &systemLocaleData) {
2582 QVariant res = systemLocale()->query(format == LongFormat
2583 ? QSystemLocale::TimeToStringLong
2584 : QSystemLocale::TimeToStringShort,
2587 return res.toString();
2591 QString format_str = timeFormat(format);
2592 return toString(time, format_str);
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2607QString QLocale::dateFormat(FormatType format)
const
2609#ifndef QT_NO_SYSTEMLOCALE
2610 if (d->m_data == &systemLocaleData) {
2611 QVariant res = systemLocale()->query(format == LongFormat
2612 ? QSystemLocale::DateFormatLong
2613 : QSystemLocale::DateFormatShort,
2616 return res.toString();
2620 return (format == LongFormat
2621 ? d->m_data->longDateFormat()
2622 : d->m_data->shortDateFormat()
2623 ).getData(date_format_data);
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2638QString QLocale::timeFormat(FormatType format)
const
2640#ifndef QT_NO_SYSTEMLOCALE
2641 if (d->m_data == &systemLocaleData) {
2642 QVariant res = systemLocale()->query(format == LongFormat
2643 ? QSystemLocale::TimeFormatLong
2644 : QSystemLocale::TimeFormatShort,
2647 return res.toString();
2651 return (format == LongFormat
2652 ? d->m_data->longTimeFormat()
2653 : d->m_data->shortTimeFormat()
2654 ).getData(time_format_data);
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2669QString QLocale::dateTimeFormat(FormatType format)
const
2671#ifndef QT_NO_SYSTEMLOCALE
2672 if (d->m_data == &systemLocaleData) {
2673 QVariant res = systemLocale()->query(format == LongFormat
2674 ? QSystemLocale::DateTimeFormatLong
2675 : QSystemLocale::DateTimeFormatShort,
2677 if (!res.isNull()) {
2678 return res.toString();
2682 return dateFormat(format) + u' ' + timeFormat(format);
2685#if QT_CONFIG(datestring)
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701QTime QLocale::toTime(
const QString &string, FormatType format)
const
2703 return toTime(string, timeFormat(format));
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731QDate QLocale::toDate(
const QString &string, FormatType format,
int baseYear)
const
2733 return toDate(string, dateFormat(format), baseYear);
2737
2738
2739
2740QDate QLocale::toDate(
const QString &string, FormatType format, QCalendar cal,
int baseYear)
const
2742 return toDate(string, dateFormat(format), cal, baseYear);
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764QDateTime QLocale::toDateTime(
const QString &string, FormatType format,
int baseYear)
const
2766 return toDateTime(string, dateTimeFormat(format), baseYear);
2770
2771
2772
2773QDateTime QLocale::toDateTime(
const QString &string, FormatType format, QCalendar cal,
2776 return toDateTime(string, dateTimeFormat(format), cal, baseYear);
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794QTime QLocale::toTime(
const QString &string,
const QString &format)
const
2796#if QT_CONFIG(datetimeparser)
2797 QTimePattern pattern = QTimePattern::fromQtFormat(format);
2798 pattern.setLocale(*
this);
2799 if (
auto match = pattern.parse(string, QTime(0, 0)); match.size == string.size())
2800 return std::move(match.payload);
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833QDate QLocale::toDate(
const QString &string,
const QString &format,
int baseYear)
const
2835 return toDate(string, format, QCalendar(), baseYear);
2839
2840
2841
2842QDate QLocale::toDate(
const QString &string,
const QString &format, QCalendar cal,
int baseYear)
const
2844#if QT_CONFIG(datetimeparser)
2845 QDatePattern pattern = QDatePattern::fromQtFormat(format);
2846 pattern.setLocale(*
this);
2847 pattern.setCalendar(cal);
2848 pattern.setBaseYear(baseYear);
2849 if (
auto match = pattern.parse(string, QDate(baseYear, 1, 1, cal));
2850 match.size == string.size()) {
2851 return std::move(match.payload);
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886QDateTime QLocale::toDateTime(
const QString &string,
const QString &format,
int baseYear)
const
2888 return toDateTime(string, format, QCalendar(), baseYear);
2892
2893
2894
2895QDateTime QLocale::toDateTime(
const QString &string,
const QString &format, QCalendar cal,
2898#if QT_CONFIG(datetimeparser)
2899 QDateTimePattern pattern = QDateTimePattern::fromQtFormat(format);
2900 pattern.setLocale(*
this);
2901 pattern.setCalendar(cal);
2902 pattern.setBaseYear(baseYear);
2903 if (
auto match = pattern.parse(string, QDate(baseYear, 1, 1, cal).startOfDay());
2904 match.size == string.size()) {
2905 return std::move(match.payload);
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931QString QLocale::decimalPoint()
const
2933 return d->m_data->decimalPoint();
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950QString QLocale::groupSeparator()
const
2952 return d->m_data->groupSeparator();
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967QString QLocale::percent()
const
2969 return d->m_data->percentSign();
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986QString QLocale::zeroDigit()
const
2988 return d->m_data->zeroDigit();
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003QString QLocale::negativeSign()
const
3005 return d->m_data->negativeSign();
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020QString QLocale::positiveSign()
const
3022 return d->m_data->positiveSign();
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038QString QLocale::exponential()
const
3040 return d->m_data->exponentSeparator();
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3077QString QLocale::toString(
double f,
char format,
int precision)
const
3079 QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
3080 uint flags = isAsciiUpper(format) ? QLocaleData::CapitalEorX : 0;
3082 switch (QtMiscUtils::toAsciiLower(format)) {
3084 form = QLocaleData::DFDecimal;
3087 form = QLocaleData::DFExponent;
3090 form = QLocaleData::DFSignificantDigits;
3096 if (!(d->m_numberOptions & OmitGroupSeparator))
3097 flags |= QLocaleData::GroupDigits;
3098 if (!(d->m_numberOptions & OmitLeadingZeroInExponent))
3099 flags |= QLocaleData::ZeroPadExponent;
3100 if (d->m_numberOptions & IncludeTrailingZeroesAfterDot)
3101 flags |= QLocaleData::AddTrailingZeroes;
3102 return d->m_data->doubleToString(f, precision, form, -1, flags);
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121QLocale QLocale::c()
noexcept
3123 return QLocale(*c_private());
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3140QLocale QLocale::system()
3142 constexpr auto sysData = []() {
3144#ifdef QT_NO_SYSTEMLOCALE
3147 return &systemLocaleData;
3150 Q_CONSTINIT
static QLocalePrivate locale(sysData(), -1, DefaultNumberOptions, 1);
3153 systemData(&locale.m_index);
3154 Q_ASSERT(locale.m_index >= 0 && locale.m_index < locale_data_size);
3155 locale.m_numberOptions = defaultNumberOptions(locale.m_data->m_language_id);
3157 return QLocale(locale);
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172QList<QLocale> QLocale::matchingLocales(Language language, Script script, Territory territory)
3174 QList<QLocale> result;
3176 const QLocaleId filter { language, script, territory };
3177 if (!filter.isValid())
3180 if (language == C) {
3181 result.emplace_back(C);
3185 if (filter.matchesAll())
3186 result.reserve(locale_data_size);
3188 quint16 index = locale_index[language];
3190 while (index < locale_data_size
3191 && filter.acceptLanguage(locale_data[index].m_language_id)) {
3192 const QLocaleId id = locale_data[index].id();
3193 if (filter.acceptScriptTerritory(id)) {
3194 result.append(QLocale(*(id.language_id == C ? c_private()
3195 :
new QLocalePrivate(locale_data + index, index))));
3201 const auto syslocaledata = systemData();
3203 if (filter.acceptLanguage(syslocaledata->m_language_id)) {
3204 const QLocaleId id = syslocaledata->id();
3205 if (filter.acceptScriptTerritory(id))
3206 result.append(system());
3212#if QT_DEPRECATED_SINCE(6
, 6
)
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
3225 const auto locales = matchingLocales(language, AnyScript, AnyCountry);
3226 QList<Country> result;
3227 result.reserve(locales.size());
3228 for (
const auto &locale : locales)
3229 result.append(locale.territory());
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246QString QLocale::monthName(
int month, FormatType type)
const
3248 return QCalendar().monthName(*
this, month, QCalendar::Unspecified, type);
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262QString QLocale::standaloneMonthName(
int month, FormatType type)
const
3264 return QCalendar().standaloneMonthName(*
this, month, QCalendar::Unspecified, type);
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280QString QLocale::dayName(
int day, FormatType type)
const
3282 return QCalendar().weekDayName(*
this, day, type);
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297QString QLocale::standaloneDayName(
int day, FormatType type)
const
3299 return QCalendar().standaloneWeekDayName(*
this, day, type);
3306 const QCalendarLocale *table)
3309 [[maybe_unused]]
const auto sameLocale = [](
const QLocaleData &locale,
3310 const QCalendarLocale &cal) {
3311 return locale.m_language_id == cal.m_language_id
3312 && locale.m_script_id == cal.m_script_id
3313 && locale.m_territory_id == cal.m_territory_id;
3315 const QCalendarLocale &monthly = table[loc->m_index];
3316#ifdef QT_NO_SYSTEMLOCALE
3317 [[maybe_unused]]
constexpr bool isSys =
false;
3319 [[maybe_unused]]
const bool isSys = loc->m_data == &systemLocaleData;
3324 Q_ASSERT(sameLocale(
locale_data[loc->m_index], monthly));
3329
3330
3333 const char16_t *monthsData,
int month,
3334 QLocale::FormatType type)
3337 return range.getListEntry(monthsData, month - 1);
3341
3342
3345 const char16_t *monthsData,
int month,
3346 QLocale::FormatType type)
3349 if (QString name = range.getListEntry(monthsData, month - 1); !name.isEmpty())
3351 return rawMonthName(localeData, monthsData, month, type);
3355
3356
3359 QLocale::FormatType type)
3363 case QLocale::LongFormat:
3364 range = data->longDayNames();
3366 case QLocale::ShortFormat:
3367 range = data->shortDayNames();
3369 case QLocale::NarrowFormat:
3370 range = data->narrowDayNames();
3375 return range.getListEntry(
days_data, day == 7 ? 0 : day);
3379
3380
3383 QLocale::FormatType type)
3387 case QLocale::LongFormat:
3388 range =data->longDayNamesStandalone();
3390 case QLocale::ShortFormat:
3391 range = data->shortDayNamesStandalone();
3393 case QLocale::NarrowFormat:
3394 range = data->narrowDayNamesStandalone();
3399 QString name = range.getListEntry(days_data, day == 7 ? 0 : day);
3401 return rawWeekDayName(data, day, type);
3407QString QCalendarBackend::monthName(
const QLocale &locale,
int month,
int,
3408 QLocale::FormatType format)
const
3410 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3411 return rawMonthName(getMonthDataFor(locale.d, localeMonthIndexData()),
3412 localeMonthData(), month, format);
3415QString QRomanCalendar::monthName(
const QLocale &locale,
int month,
int year,
3416 QLocale::FormatType format)
const
3418#ifndef QT_NO_SYSTEMLOCALE
3419 if (locale.d->m_data == &systemLocaleData) {
3420 Q_ASSERT(month >= 1 && month <= 12);
3421 QSystemLocale::QueryType queryType = QSystemLocale::MonthNameLong;
3423 case QLocale::LongFormat:
3424 queryType = QSystemLocale::MonthNameLong;
3426 case QLocale::ShortFormat:
3427 queryType = QSystemLocale::MonthNameShort;
3429 case QLocale::NarrowFormat:
3430 queryType = QSystemLocale::MonthNameNarrow;
3433 QVariant res = systemLocale()->query(queryType, month);
3435 return res.toString();
3439 return QCalendarBackend::monthName(locale, month, year, format);
3442QString QCalendarBackend::standaloneMonthName(
const QLocale &locale,
int month,
int,
3443 QLocale::FormatType format)
const
3445 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3446 return rawStandaloneMonthName(getMonthDataFor(locale.d, localeMonthIndexData()),
3447 localeMonthData(), month, format);
3450QString QRomanCalendar::standaloneMonthName(
const QLocale &locale,
int month,
int year,
3451 QLocale::FormatType format)
const
3453#ifndef QT_NO_SYSTEMLOCALE
3454 if (locale.d->m_data == &systemLocaleData) {
3455 Q_ASSERT(month >= 1 && month <= 12);
3456 QSystemLocale::QueryType queryType = QSystemLocale::StandaloneMonthNameLong;
3458 case QLocale::LongFormat:
3459 queryType = QSystemLocale::StandaloneMonthNameLong;
3461 case QLocale::ShortFormat:
3462 queryType = QSystemLocale::StandaloneMonthNameShort;
3464 case QLocale::NarrowFormat:
3465 queryType = QSystemLocale::StandaloneMonthNameNarrow;
3468 QVariant res = systemLocale()->query(queryType, month);
3470 return res.toString();
3474 return QCalendarBackend::standaloneMonthName(locale, month, year, format);
3479QString QCalendarBackend::weekDayName(
const QLocale &locale,
int day,
3480 QLocale::FormatType format)
const
3482 if (day < 1 || day > 7)
3485#ifndef QT_NO_SYSTEMLOCALE
3486 if (locale.d->m_data == &systemLocaleData) {
3487 QSystemLocale::QueryType queryType = QSystemLocale::DayNameLong;
3489 case QLocale::LongFormat:
3490 queryType = QSystemLocale::DayNameLong;
3492 case QLocale::ShortFormat:
3493 queryType = QSystemLocale::DayNameShort;
3495 case QLocale::NarrowFormat:
3496 queryType = QSystemLocale::DayNameNarrow;
3499 QVariant res = systemLocale()->query(queryType, day);
3501 return res.toString();
3505 return rawWeekDayName(locale.d->m_data, day, format);
3508QString QCalendarBackend::standaloneWeekDayName(
const QLocale &locale,
int day,
3509 QLocale::FormatType format)
const
3511 if (day < 1 || day > 7)
3514#ifndef QT_NO_SYSTEMLOCALE
3515 if (locale.d->m_data == &systemLocaleData) {
3516 QSystemLocale::QueryType queryType = QSystemLocale::StandaloneDayNameLong;
3518 case QLocale::LongFormat:
3519 queryType = QSystemLocale::StandaloneDayNameLong;
3521 case QLocale::ShortFormat:
3522 queryType = QSystemLocale::StandaloneDayNameShort;
3524 case QLocale::NarrowFormat:
3525 queryType = QSystemLocale::StandaloneDayNameNarrow;
3528 QVariant res = systemLocale()->query(queryType, day);
3530 return res.toString();
3534 return rawStandaloneWeekDayName(locale.d->m_data, day, format);
3540
3541
3542
3543
3544Qt::DayOfWeek QLocale::firstDayOfWeek()
const
3546#ifndef QT_NO_SYSTEMLOCALE
3547 if (d->m_data == &systemLocaleData) {
3548 const auto res = systemLocale()->query(QSystemLocale::FirstDayOfWeek);
3550 return static_cast<Qt::DayOfWeek>(res.toUInt());
3553 return static_cast<Qt::DayOfWeek>(d->m_data->m_first_day_of_week);
3559
3560
3561
3562
3563 struct TerritoryLanguage
3566 quint16 territoryId;
3567 QLocale::MeasurementSystem system;
3570 constexpr TerritoryLanguage ImperialMeasurementSystems[] = {
3571 { QLocale::English, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3572 { QLocale::English, QLocale::UnitedStatesMinorOutlyingIslands, QLocale::ImperialUSSystem },
3573 { QLocale::Spanish, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3574 { QLocale::Hawaiian, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3575 { QLocale::English, QLocale::UnitedKingdom, QLocale::ImperialUKSystem }
3578 for (
const auto &system : ImperialMeasurementSystems) {
3579 if (system.languageId == m_data->m_language_id
3580 && system.territoryId == m_data->m_territory_id) {
3581 return system.system;
3584 return QLocale::MetricSystem;
3588
3589
3590
3591
3592QList<Qt::DayOfWeek> QLocale::weekdays()
const
3594#ifndef QT_NO_SYSTEMLOCALE
3595 if (d->m_data == &systemLocaleData) {
3597 = qvariant_cast<QList<Qt::DayOfWeek> >(systemLocale()->query(QSystemLocale::Weekdays));
3602 QList<Qt::DayOfWeek> weekdays;
3603 quint16 weekendStart = d->m_data->m_weekend_start;
3604 quint16 weekendEnd = d->m_data->m_weekend_end;
3605 for (
int day = Qt::Monday; day <= Qt::Sunday; day++) {
3606 if ((weekendEnd >= weekendStart && (day < weekendStart || day > weekendEnd)) ||
3607 (weekendEnd < weekendStart && (day > weekendEnd && day < weekendStart)))
3608 weekdays <<
static_cast<Qt::DayOfWeek>(day);
3614
3615
3616
3617
3618QLocale::MeasurementSystem QLocale::measurementSystem()
const
3620#ifndef QT_NO_SYSTEMLOCALE
3621 if (d->m_data == &systemLocaleData) {
3622 const auto res = systemLocale()->query(QSystemLocale::MeasurementSystem);
3624 return MeasurementSystem(res.toInt());
3628 return d->measurementSystem();
3632
3633
3634
3635
3636Qt::LayoutDirection QLocale::textDirection()
const
3645 case ImperialAramaicScript:
3646 case InscriptionalPahlaviScript:
3647 case InscriptionalParthianScript:
3648 case KharoshthiScript:
3650 case MandaeanScript:
3651 case ManichaeanScript:
3652 case MendeKikakuiScript:
3653 case MeroiticCursiveScript:
3654 case MeroiticScript:
3655 case NabataeanScript:
3657 case OldHungarianScript:
3658 case OldNorthArabianScript:
3659 case OldSouthArabianScript:
3661 case PalmyreneScript:
3662 case PhoenicianScript:
3663 case PsalterPahlaviScript:
3664 case SamaritanScript:
3667 return Qt::RightToLeft;
3671 return Qt::LeftToRight;
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689QString QLocale::toUpper(
const QString &str)
const
3691#if !defined(QT_BOOTSTRAPPED) && (QT_CONFIG(icu) || defined(Q_OS_WIN) || defined(Q_OS_APPLE))
3693 QString result = d->toUpper(str, &ok);
3698 return str.toUpper();
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713QString QLocale::toLower(
const QString &str)
const
3715#if !defined(QT_BOOTSTRAPPED) && (QT_CONFIG(icu) || defined(Q_OS_WIN) || defined(Q_OS_APPLE))
3717 const QString result = d->toLower(str, &ok);
3722 return str.toLower();
3727
3728
3729
3730
3731
3732
3733
3734QString QLocale::amText()
const
3736#ifndef QT_NO_SYSTEMLOCALE
3737 if (d->m_data == &systemLocaleData) {
3738 auto res = systemLocale()->query(QSystemLocale::AMText).toString();
3743 return d->m_data->anteMeridiem().getData(am_data);
3747
3748
3749
3750
3751
3752
3753
3754QString QLocale::pmText()
const
3756#ifndef QT_NO_SYSTEMLOCALE
3757 if (d->m_data == &systemLocaleData) {
3758 auto res = systemLocale()->query(QSystemLocale::PMText).toString();
3763 return d->m_data->postMeridiem().getData(pm_data);
3769 QStringView tail{text};
3771 if (tail.startsWith(
"UTC"_L1) || tail.startsWith(
"GMT"_L1))
3772 tail = tail.sliced(3);
3775 return (tail.isEmpty()
3780 : std::move(text).right(tail.size())));
3784#if !QT_CONFIG(datestring)
3786#elif QT_CONFIG(icu) || !(QT_CONFIG(timezone) && QT_CONFIG(timezone_locale))
3787namespace QtTimeZoneLocale {
3791QString zoneOffsetFormat([[maybe_unused]]
const QLocale &locale,
3793 QtTemporalPattern::TemporalFieldFlags,
3794 const QDateTime &when,
3800#if QT_CONFIG(timezone)
3801 locale != QLocale::system()
3802 ? when.timeRepresentation().displayName(when, QTimeZone::OffsetName, locale)
3805 when.toOffsetFromUtc(offsetSeconds).timeZoneAbbreviation();
3807 if (!text.isEmpty())
3808 text = offsetFromAbbreviation(std::move(text));
3817QString QCalendarBackend::dateTimeToString(QStringView format,
const QDateTime &datetime,
3818 QDate dateOnly, QTime timeOnly,
3819 const QLocale &locale)
const
3823 bool formatDate =
false;
3824 bool formatTime =
false;
3825 if (datetime.isValid()) {
3826 date = datetime.date();
3827 time = datetime.time();
3830 }
else if (dateOnly.isValid()) {
3833 }
else if (timeOnly.isValid()) {
3841 int year = 0, month = 0, day = 0;
3843 const auto parts = julianDayToDate(date.toJulianDay());
3844 if (!parts.isValid())
3847 month = parts.month;
3851 auto appendToResult = [&](
int t,
int repeat) {
3852 auto data = locale.d->m_data;
3854 result.append(data->longLongToString(t, -1, 10, repeat, QLocaleData::ZeroPadded));
3856 result.append(data->longLongToString(t));
3859 auto formatType = [](
int repeat) {
3860 return repeat == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
3864 while (i < format.size()) {
3865 if (format.at(i).unicode() ==
'\'') {
3866 result.append(qt_readEscapedFormatString(format, &i));
3870 const QChar c = format.at(i);
3871 qsizetype rep = qt_repeatCount(format.mid(i));
3872 Q_ASSERT(rep < std::numeric_limits<
int>::max());
3873 int repeat =
int(rep);
3876 switch (c.unicode()) {
3881 else if (repeat >= 2)
3886 appendToResult(year, (year < 0) ? 5 : 4);
3889 appendToResult(year % 100, 2);
3900 repeat = qMin(repeat, 4);
3902 appendToResult(month, repeat);
3904 result.append(monthName(locale, month, year, formatType(repeat)));
3909 repeat = qMin(repeat, 4);
3911 appendToResult(day, repeat);
3914 locale.dayName(dayOfWeek(date.toJulianDay()), formatType(repeat)));
3921 if (!used && formatTime) {
3922 switch (c.unicode()) {
3925 repeat = qMin(repeat, 2);
3926 int hour = time.hour();
3927 if (timeFormatContainsAP(format)) {
3933 appendToResult(hour, repeat);
3938 repeat = qMin(repeat, 2);
3939 appendToResult(time.hour(), repeat);
3944 repeat = qMin(repeat, 2);
3945 appendToResult(time.minute(), repeat);
3950 repeat = qMin(repeat, 2);
3951 appendToResult(time.second(), repeat);
3956 QString text = time.hour() < 12 ? locale.amText() : locale.pmText();
3959 if (format.mid(i + 1).startsWith(u'p', Qt::CaseInsensitive))
3961 if (c.unicode() ==
'A' && (repeat == 1 || format.at(i + 1).unicode() ==
'P'))
3962 text = std::move(text).toUpper();
3963 else if (c.unicode() ==
'a' && (repeat == 1 || format.at(i + 1).unicode() ==
'p'))
3964 text = std::move(text).toLower();
3966 result.append(text);
3972 repeat = qMin(repeat, 3);
3976 appendToResult(time.msec(), 3);
3978 const QString zero = locale.zeroDigit();
3979 if (result.endsWith(zero))
3980 result.chop(zero.size());
3981 if (result.endsWith(zero))
3982 result.chop(zero.size());
3987#if QT_CONFIG(datestring)
3991 enum AbbrType { Long, Offset, Short };
3992 const auto tzAbbr = [locale](
const QDateTime &when, AbbrType type) {
3994 if (type == Offset) {
3995 using Flag = QtTemporalPattern::TemporalFieldFlag;
3996 constexpr auto noPrefixOffset = Flag::Numeric | Flag::Abbreviated
3997 | Flag::NeedNoUtcPrefix | Flag::ZeroPad;
3998 text = QtTimeZoneLocale::zoneOffsetFormat(locale, locale.d->m_index,
4000 when, when.offsetFromUtc());
4002 if (!text.isEmpty())
4005# if QT_CONFIG(timezone)
4006 if (type != Short || locale != QLocale::system()) {
4007 QTimeZone::NameType mode =
4008 type == Short ? QTimeZone::ShortName
4009 : type == Long ? QTimeZone::LongName : QTimeZone::OffsetName;
4010 text = when.timeRepresentation().displayName(when, mode, locale);
4011 if (!text.isEmpty())
4017 text = QString::fromLatin1(when.timeZone().id());
4018 if (!text.isEmpty())
4025 text = when.toOffsetFromUtc(when.offsetFromUtc()).timeZoneAbbreviation();
4027 text = when.timeZoneAbbreviation();
4029 text = offsetFromAbbreviation(std::move(text));
4034 repeat = qMin(repeat, 4);
4036 const QDateTime when = formatDate ? datetime : QDateTime::currentDateTime();
4040 text = tzAbbr(when, Long);
4044 text = tzAbbr(when, Offset);
4049 text = tzAbbr(when, Short);
4051 if (text.startsWith(
"UTC"_L1) && text.size() == 6)
4055 if (!text.isEmpty())
4056 result.append(text);
4066 result.resize(result.size() + repeat, c);
4075 int width,
unsigned flags)
const
4082 if (precision != QLocale::FloatingPointShortest && precision < 0)
4088 qsizetype bufSize = 1;
4089 if (precision == QLocale::FloatingPointShortest)
4090 bufSize += std::numeric_limits<
double>::max_digits10;
4091 else if (form == DFDecimal && qt_is_finite(d))
4092 bufSize += wholePartSpace(qAbs(d)) + precision;
4094 bufSize += qMax(2, precision) + 1;
4096 QVarLengthArray<
char> buf(bufSize);
4098 bool negative =
false;
4099 qt_doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
4101 const QString prefix = signPrefix(negative && !qIsNull(d), flags);
4105 && (qstrncmp(buf.data(),
"inf", 3) == 0 || qstrncmp(buf.data(),
"nan", 3) == 0)) {
4106 numStr = QString::fromLatin1(buf.data(), length);
4108 const QString zero = zeroDigit();
4109 QString digits = QString::fromLatin1(buf.data(), length);
4113 Q_ASSERT(
std::all_of(buf.cbegin(), buf.cbegin() + length, isAsciiDigit));
4115 }
else if (zero.size() == 2 && zero.at(0).isHighSurrogate()) {
4116 const char32_t zeroUcs4 = QChar::surrogateToUcs4(zero.at(0), zero.at(1));
4118 converted.reserve(2 * digits.size());
4119 for (QChar ch : std::as_const(digits)) {
4120 const char32_t digit = unicodeForDigit(ch.unicode() -
'0', zeroUcs4);
4121 Q_ASSERT(QChar::requiresSurrogates(digit));
4122 converted.append(QChar::highSurrogate(digit));
4123 converted.append(QChar::lowSurrogate(digit));
4125 digits =
std::move(converted);
4127 Q_ASSERT(zero.size() == 1);
4128 Q_ASSERT(!zero.at(0).isSurrogate());
4129 char16_t z = zero.at(0).unicode();
4130 char16_t *
const value =
reinterpret_cast<
char16_t *>(digits.data());
4131 for (qsizetype i = 0; i < digits.size(); ++i)
4132 value[i] = unicodeForDigit(value[i] -
'0', z);
4135 const bool mustMarkDecimal = flags &
ForcePoint;
4140 numStr = exponentForm(
std::move(digits), decpt, precision, PMDecimalDigits,
4141 mustMarkDecimal, minExponentDigits);
4144 numStr = decimalForm(
std::move(digits), decpt, precision, PMDecimalDigits,
4145 mustMarkDecimal, groupDigits);
4152
4153
4154
4155
4156
4157
4158
4159
4161 if (precision == QLocale::FloatingPointShortest) {
4168 int bias = 2 + minExponentDigits;
4170 if (groupDigits && decpt >= grouping
.first + grouping
.least)
4173 if (decpt > 10 && minExponentDigits == 1)
4178 const qsizetype digitCount = digits.size() / zero.size();
4179 if (!mustMarkDecimal) {
4182 if (digitCount <= decpt && digitCount > 1)
4184 else if (digitCount == 1 && decpt <= 0)
4192 useDecimal = (decpt <= 0 ? 1 - decpt <= bias
4193 : decpt <= digitCount ? 0 <= bias : decpt <= digitCount + bias);
4196 Q_ASSERT(precision >= 0);
4197 useDecimal = decpt > -4 && decpt <= (precision ? precision : 1);
4201 ? decimalForm(
std::move(digits), decpt, precision, mode,
4202 mustMarkDecimal, groupDigits)
4203 : exponentForm(
std::move(digits), decpt, precision, mode,
4204 mustMarkDecimal, minExponentDigits);
4211 for (qsizetype i = numStr.size() / zero.size() + prefix.size(); i < width; ++i)
4212 numStr.prepend(zero);
4217 ?
std::move(numStr).toUpper()
4218 :
std::move(numStr).toLower());
4221QString
QLocaleData::decimalForm(QString &&digits,
int decpt,
int precision,
4222 PrecisionMode pm,
bool mustMarkDecimal,
4223 bool groupDigits)
const
4225 const QString zero = zeroDigit();
4226 const auto digitWidth = zero.size();
4227 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
4228 Q_ASSERT(digits.size() % digitWidth == 0);
4233 for (; decpt < 0; ++decpt)
4234 digits.prepend(zero);
4236 for (qsizetype i = digits.size() / digitWidth; i < decpt; ++i)
4237 digits.append(zero);
4241 case PMDecimalDigits:
4242 for (qsizetype i = digits.size() / digitWidth - decpt; i < precision; ++i)
4243 digits.append(zero);
4245 case PMSignificantDigits:
4246 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
4247 digits.append(zero);
4249 case PMChopTrailingZeros:
4250 Q_ASSERT(digits.size() / digitWidth <= qMax(decpt, 1) || !digits.endsWith(zero));
4254 if (mustMarkDecimal || decpt < digits.size() / digitWidth)
4255 digits.insert(decpt * digitWidth, decimalPoint());
4259 const QString group = groupSeparator();
4260 qsizetype i = decpt - grouping.least;
4261 if (i >= grouping.first) {
4262 digits.insert(i * digitWidth, group);
4263 while ((i -= grouping.higher) > 0)
4264 digits.insert(i * digitWidth, group);
4269 digits.prepend(zero);
4271 return std::move(digits);
4274QString
QLocaleData::exponentForm(QString &&digits,
int decpt,
int precision,
4275 PrecisionMode pm,
bool mustMarkDecimal,
4276 int minExponentDigits)
const
4278 const QString zero = zeroDigit();
4279 const auto digitWidth = zero.size();
4280 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
4281 Q_ASSERT(digits.size() % digitWidth == 0);
4284 case PMDecimalDigits:
4285 for (qsizetype i = digits.size() / digitWidth; i < precision + 1; ++i)
4286 digits.append(zero);
4288 case PMSignificantDigits:
4289 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
4290 digits.append(zero);
4292 case PMChopTrailingZeros:
4293 Q_ASSERT(digits.size() / digitWidth <= 1 || !digits.endsWith(zero));
4297 if (mustMarkDecimal || digits.size() > digitWidth)
4298 digits.insert(digitWidth, decimalPoint());
4300 digits.append(exponentSeparator());
4301 digits.append(longLongToString(decpt - 1, minExponentDigits, 10, -1, AlwaysShowSign));
4303 return std::move(digits);
4306QString
QLocaleData::signPrefix(
bool negative,
unsigned flags)
const
4309 return negativeSign();
4310 if (flags & AlwaysShowSign)
4311 return positiveSign();
4312 if (flags & BlankBeforePositive)
4318 int base,
int width,
unsigned flags)
const
4320 bool negative = n < 0;
4323
4324
4325
4326 QString numStr = qulltoa(negative ? 1u + qulonglong(-(n + 1)) : qulonglong(n),
4329 return applyIntegerFormatting(
std::move(numStr), negative, precision, base, width, flags);
4333 int base,
int width,
unsigned flags)
const
4335 return applyIntegerFormatting(qulltoa(l, base, zeroDigit()),
4336 false, precision, base, width, flags);
4339QString
QLocaleData::applyIntegerFormatting(QString &&numStr,
bool negative,
int precision,
4340 int base,
int width,
unsigned flags)
const
4342 const QString zero = base == 10 ? zeroDigit() :
QStringLiteral(
"0");
4343 const auto digitWidth = zero.size();
4344 const auto digitCount = numStr.size() / digitWidth;
4346 const auto basePrefix = [&] () -> QStringView {
4347 if (flags & ShowBase) {
4348 const bool upper = flags & UppercaseBase;
4350 return upper ? u"0X" : u"0x";
4352 return upper ? u"0B" : u"0b";
4353 if (base == 8 && !numStr.startsWith(zero))
4359 const QString prefix = signPrefix(negative, flags) + basePrefix;
4361 qsizetype usedWidth = digitCount + prefix.size();
4365 const QString group = groupSeparator();
4366 qsizetype i = digitCount - grouping.least;
4367 if (i >= grouping.first) {
4368 numStr.insert(i * digitWidth, group);
4370 while ((i -= grouping.higher) > 0) {
4371 numStr.insert(i * digitWidth, group);
4378 const bool noPrecision = precision == -1;
4382 for (qsizetype i = numStr.size(); i < precision; ++i) {
4383 numStr.prepend(zero);
4390 for (qsizetype i = usedWidth; i < width; ++i)
4391 numStr.prepend(zero);
4394 QString result(flags & CapitalEorX ? std::move(numStr).toUpper() : std::move(numStr));
4396 result.prepend(prefix);
4401 :
grouping(data->groupSizes()), isC(data == c())
4407 setZero(data->zero().viewData(single_character_data));
4408 group = data->groupDelim().viewData(single_character_data);
4410 minus = data->minus().viewData(single_character_data);
4411 plus = data->plus().viewData(single_character_data);
4412 if (mode != IntegerMode)
4413 decimal = data->decimalSeparator().viewData(single_character_data);
4415 exponent = data->exponential().viewData(single_character_data);
4417 exponentCyrillic = data->m_script_id == QLocale::CyrillicScript;
4419#ifndef QT_NO_SYSTEMLOCALE
4420 if (data == &systemLocaleData) {
4421 const auto getString = [sys = systemLocale()](QSystemLocale::QueryType query) {
4422 return sys->query(query).toString();
4425 sysDecimal = getString(QSystemLocale::DecimalPoint);
4426 if (sysDecimal.size())
4427 decimal = QStringView{sysDecimal};
4429 sysGroup = getString(QSystemLocale::GroupSeparator);
4430 if (sysGroup.size())
4431 group = QStringView{sysGroup};
4432 sysMinus = getString(QSystemLocale::NegativeSign);
4433 if (sysMinus.size())
4434 minus = QStringView{sysMinus};
4435 sysPlus = getString(QSystemLocale::PositiveSign);
4437 plus = QStringView{sysPlus};
4438 setZero(getString(QSystemLocale::ZeroDigit));
4447class NumericTokenizer
4451 static constexpr char lettersInfNaN[] =
"afin";
4452 static constexpr auto matchInfNaN =
QtPrivate::makeCharacterSetMatch<lettersInfNaN>();
4453 const QStringView m_text;
4457 static_assert(
'+' + 1 ==
',' &&
',' + 1 ==
'-' &&
'-' + 1 ==
'.');
4462 : m_text(text), m_guide(guide), m_index(from), m_mode(mode),
4465 Q_ASSERT(m_guide.isValid(mode));
4467 bool done()
const {
return !(m_index < m_text.size()); }
4468 qsizetype index()
const {
return m_index; }
4469 int digitValue(
char32_t digit)
const {
return m_guide.digitValue(digit); }
4470 bool isInfNanChar(
char ch)
const {
return matchInfNaN.matches(ch); }
4472 bool fractionGroupClash()
const
4477 return Q_UNLIKELY(m_mode != QLocaleData::IntegerMode && m_guide.fractionalIsGroup());
4482char NumericTokenizer::nextToken()
4489 const auto asciiLower = [](
unsigned char c) {
return c >=
'A' ? c | 0x20 : c; };
4490 const QStringView tail = m_text.sliced(m_index);
4491 const QChar ch = tail.front();
4492 if (ch == u'\u2212') {
4499 if (Q_LIKELY(ch.unicode() < 256)) {
4500 unsigned char ascii = asciiLower(ch.toLatin1());
4501 if (Q_LIKELY(isAsciiDigit(ascii) || (
'+' <= ascii && ascii <= lastMark)
4512 if (ch.unicode() < 256) {
4514 char ascii = asciiLower(ch.toLatin1());
4515 if (isAsciiDigit(ascii) || ascii ==
'-' || ascii ==
'+'
4524 if (tail.startsWith(m_guide.minus)) {
4525 m_index += m_guide.minus.size();
4528 if (tail.startsWith(m_guide.plus)) {
4529 m_index += m_guide.plus.size();
4532 if (!m_guide.group.isEmpty() && tail.startsWith(m_guide.group)) {
4533 m_index += m_guide.group.size();
4538 if (fractionGroupClash() && tail.indexOf(m_guide.decimal, m_guide.group.size()) == -1)
4543 m_index += m_guide.decimal.size();
4548 m_index += m_guide.exponent.size();
4553 if (m_guide.zeroLen == 1) {
4554 if (!ch.isSurrogate()) {
4555 if (
const int gap = digitValue(
char32_t(ch.unicode())); gap >= 0) {
4559 }
else if (ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()) {
4563 }
else if (ch.isHighSurrogate()) {
4566 if (tail.size() > 1) {
4567 if (
const QChar low = tail.at(1); low.isLowSurrogate()) {
4568 if (
const int gap = digitValue(QChar::surrogateToUcs4(ch, low)); gap >= 0) {
4579 Q_ASSERT(!(ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()));
4582 switch (ch.unicode()) {
4596 if (m_guide.group == u"\u00a0" || m_guide.group == u"\u202f") {
4610 if (m_guide.exponentCyrillic) {
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4657
4658
4659
4660
4661
4662
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4702
4703
4704
4705
4706
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4729
4730
4731
4732
4733
4734
4735
4736
4739
4740
4741
4742
4743
4744
4745
4746
4749
4750
4751
4752
4753
4754
4755
4756
4757
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4795 Options flags, qsizetype from)
4796 : digitStart(from), digitWidth(numeric.zeroWidth())
4798 NumericTokenizer tokens(text,
std::move(numeric),
IntegerMode, from);
4801 char currentToken = tokens.nextToken();
4806 if (currentToken ==
'+' || currentToken ==
'-') {
4809 digitStart = tokens.index();
4810 sign = currentToken;
4811 currentToken =
'\0';
4815 while (currentToken || !tokens.done()) {
4817 currentToken = tokens.nextToken();
4821 if (currentToken <
'0' || currentToken >
'9')
4825 digits.push_back(currentToken);
4826 currentToken =
'\0';
4831
4832
4833
4834
4835
4836
4837
4838
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4864 NumericTokenizer tokens(s, NumericData(
this, mode), mode);
4867 enum { Whole, Grouped, Fraction, Exponent, Name } stage = Whole;
4873 bool wantDigits =
true;
4876 bool needHigherGroup =
false;
4877 qsizetype digitsInGroup = 0;
4879 const auto badLeastGroup = [&]() {
4885 if (stage == Grouped) {
4886 Q_ASSERT(!number_options.testFlag(QLocale::RejectGroupSeparator));
4888 if (needHigherGroup)
4891 if (digitsInGroup != grouping.least)
4898 while (!tokens.done()) {
4899 char out = tokens.nextToken();
4907 if (stage > Grouped)
4910 if (tokens.fractionGroupClash() && badLeastGroup()
4911 && digitsInGroup == grouping.higher) {
4917 needHigherGroup =
false;
4921 if (badLeastGroup())
4925 }
else if (out ==
'e') {
4926 if (wantDigits || stage == Name || stage > Fraction)
4929 if (stage < Fraction) {
4931 if (badLeastGroup())
4933 }
else if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot)) {
4940 }
else if (out ==
',') {
4946 if (number_options.testFlag(QLocale::RejectGroupSeparator))
4952 if (digitsInGroup == 0
4953 || digitsInGroup > qMax(grouping.first, grouping.higher)) {
4956 Q_ASSERT(!needHigherGroup);
4960 if (grouping.first > digitsInGroup)
4961 needHigherGroup =
true;
4966 if (digitsInGroup != grouping.higher)
4968 needHigherGroup =
false;
4977 }
else if (isAsciiDigit(out)) {
4980 if (out ==
'0' && number_options.testFlag(QLocale::RejectLeadingZeroInExponent)
4981 && stage > Fraction && !tokens.done() && !isAsciiDigit(last)) {
4989 }
else if (stage == Whole && tokens.isInfNanChar(out)) {
4999 result->append(out);
5004 if (!number_options.testFlag(QLocale::RejectGroupSeparator)) {
5006 if (stage < Fraction && badLeastGroup())
5010 if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot) && stage == Fraction) {
5021 QLocale::NumberOptions number_options)
const
5024 result.buff.reserve(str.size());
5026 enum { Whole, Fractional, Exponent } state = Whole;
5028 NumericTokenizer tokens(str, NumericData(
this, numMode), numMode);
5031 while (!tokens.done()) {
5032 char c = tokens.nextToken();
5034 if (isAsciiDigit(c)) {
5041 if (decDigits-- == 0)
5045 if (!isAsciiDigit(last)) {
5048 if (c ==
'0' && (number_options & QLocale::RejectLeadingZeroInExponent))
5070 if (last !=
'\0' && !(scientific && last ==
'e'))
5076 if ((number_options & QLocale::RejectGroupSeparator) || state != Whole
5077 || !isAsciiDigit(last)) {
5086 if (!scientific || state == Exponent)
5096 Q_ASSERT(!c || c ==
'a' || c ==
'f' || c ==
'i' || c ==
'n');
5103 result.buff.append(c);
5110 if (last ==
',' || last ==
'-' || last ==
'+' || last ==
'e')
5117 QLocale::NumberOptions number_options)
const
5120 if (!numberToCLocale(str, number_options, DoubleScientificMode, &buff)) {
5125 auto r = qt_asciiToDouble(buff.constData(), buff.size());
5133 QLocale::NumberOptions number_options)
const
5136 if (!numberToCLocale(str, number_options, IntegerMode, &buff))
5139 return bytearrayToLongLong(QByteArrayView(buff), base);
5144 QLocale::NumberOptions number_options)
const
5147 if (!numberToCLocale(str, number_options, IntegerMode, &buff))
5150 return bytearrayToUnsLongLong(QByteArrayView(buff), base);
5158 const qsizetype len = num.size();
5159 if (used < len && num[used] !=
'\0') {
5160 while (used < len && ascii_isspace(num[used]))
5164 if (used < len && num[used] !=
'\0')
5171QSimpleParsedNumber<qint64>
QLocaleData::bytearrayToLongLong(QByteArrayView num,
int base)
5173 auto r = qstrntoll(num.data(), num.size(), base);
5174 if (!checkParsed(num, r.used))
5179QSimpleParsedNumber<quint64>
QLocaleData::bytearrayToUnsLongLong(QByteArrayView num,
int base)
5181 auto r = qstrntoull(num.data(), num.size(), base);
5182 if (!checkParsed(num, r.used))
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5200
5201
5202
5203QString QLocale::currencySymbol(CurrencySymbolFormat format)
const
5205#ifndef QT_NO_SYSTEMLOCALE
5206 if (d->m_data == &systemLocaleData) {
5207 auto res = systemLocale()->query(QSystemLocale::CurrencySymbol, format).toString();
5213 case CurrencySymbol:
5214 return d->m_data->currencySymbol().getData(currency_symbol_data);
5215 case CurrencyDisplayName:
5216 return d->m_data->currencyDisplayName().getData(currency_display_name_data);
5217 case CurrencyIsoCode: {
5218 const char *code = d->m_data->m_currency_iso_code;
5219 if (
auto len = qstrnlen(code, 3))
5220 return QString::fromLatin1(code, qsizetype(len));
5228
5229
5230
5231
5232
5233
5234
5235QString QLocale::toCurrencyString(qlonglong value,
const QString &symbol)
const
5237#ifndef QT_NO_SYSTEMLOCALE
5238 if (d->m_data == &systemLocaleData) {
5239 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5240 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5241 QVariant::fromValue(arg)).toString();
5246 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
5247 if (!range.size || value >= 0)
5248 range = d->m_data->currencyFormat();
5251 QString str = toString(value);
5252 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5254 sym = currencySymbol(CurrencyIsoCode);
5255 return range.viewData(currency_format_data).arg(str, sym);
5259
5260
5261
5262QString QLocale::toCurrencyString(qulonglong value,
const QString &symbol)
const
5264#ifndef QT_NO_SYSTEMLOCALE
5265 if (d->m_data == &systemLocaleData) {
5266 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5267 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5268 QVariant::fromValue(arg)).toString();
5273 QString str = toString(value);
5274 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5276 sym = currencySymbol(CurrencyIsoCode);
5277 return d->m_data->currencyFormat().getData(currency_format_data).arg(str, sym);
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290QString QLocale::toCurrencyString(
double value,
const QString &symbol,
int precision)
const
5292#ifndef QT_NO_SYSTEMLOCALE
5293 if (d->m_data == &systemLocaleData) {
5294 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5295 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5296 QVariant::fromValue(arg)).toString();
5301 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
5302 if (!range.size || value >= 0)
5303 range = d->m_data->currencyFormat();
5306 QString str = toString(value,
'f', precision == -1 ? d->m_data->m_currency_digits : precision);
5307 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5309 sym = currencySymbol(CurrencyIsoCode);
5310 return range.viewData(currency_format_data).arg(str, sym);
5314
5315
5316
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350QString QLocale::formattedDataSize(qint64 bytes,
int precision, DataSizeFormats format)
const
5352 int power, base = 1000;
5355 }
else if (format & DataSizeBase1000) {
5356 constexpr auto log10_1000 = 3;
5357 power =
int(std::log10(QtPrivate::qUnsignedAbs(bytes))) / log10_1000;
5359 constexpr auto log2_1024 = 10;
5360 power = QtPrivate::log2i(QtPrivate::qUnsignedAbs(bytes)) / log2_1024;
5364 const QString number = power
5365 ? toString(bytes / std::pow(
double(base), power),
'f', qMin(precision, 3 * power))
5370 Q_ASSERT(power <= 6 && power >= 0);
5373 QLocaleData::DataRange range = (format & DataSizeSIQuantifiers)
5374 ? d->m_data->byteAmountSI() : d->m_data->byteAmountIEC();
5375 unit = range.viewListEntry(byte_unit_data, power - 1);
5377 unit = d->m_data->byteCount().viewData(byte_unit_data);
5380 return number + u' ' + unit;
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
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426QStringList QLocale::uiLanguages(TagSeparator separator)
const
5428 const char sep =
char(separator);
5429 QStringList uiLanguages;
5430 if (uchar(sep) > 0x7f) {
5431 badSeparatorWarning(
"uiLanguages", sep);
5434 QList<QLocaleId> localeIds;
5435#ifdef QT_NO_SYSTEMLOCALE
5436 constexpr bool isSystem =
false;
5438 const bool isSystem = d->m_data == &systemLocaleData;
5440 uiLanguages = systemLocale()->query(QSystemLocale::UILanguages).toStringList();
5441 if (separator != TagSeparator::Dash) {
5443 const QChar join = QLatin1Char(sep);
5444 uiLanguages.replaceInStrings(u"-", QStringView(&join, 1));
5448 for (
const auto &entry : std::as_const(uiLanguages))
5449 localeIds.append(QLocaleId::fromName(entry));
5450 if (localeIds.isEmpty())
5451 localeIds.append(systemLocale()->fallbackLocale().d->m_data->id());
5453
5454
5455
5456
5457
5458
5459
5460 const QString name = QString::fromLatin1(d->m_data->id().name(sep));
5461 if (!name.isEmpty() && language() != C && !uiLanguages.contains(name)) {
5464 const QLocaleId id = d->m_data->id();
5465 const QLocaleId max = id.withLikelySubtagsAdded();
5466 const QLocaleId mine = max.withLikelySubtagsRemoved();
5468 qsizetype lastAlike = uiLanguages.size() - 1;
5470 for (qsizetype i = 0; !seen && i < uiLanguages.size(); ++i) {
5471 const auto its = QLocaleId::fromName(uiLanguages.at(i)).withLikelySubtagsAdded();
5472 seen = its.withLikelySubtagsRemoved() == mine;
5473 if (!seen && its.language_id == max.language_id && its.script_id == max.script_id)
5477 localeIds.insert(lastAlike + 1, id);
5478 uiLanguages.insert(lastAlike + 1, QString::fromLatin1(id.name(sep)));
5484 localeIds.append(d->m_data->id());
5487 for (qsizetype i = localeIds.size(); i-- > 0; ) {
5488 const QLocaleId id = localeIds.at(i);
5489 Q_ASSERT(id.language_id);
5490 if (id.language_id == C) {
5491 if (!uiLanguages.contains(u"C"_s))
5492 uiLanguages.append(u"C"_s);
5498 const QByteArray prior = id.name(sep);
5499 bool faithful =
true;
5500 if (isSystem && i < uiLanguages.size()) {
5502 faithful = uiLanguages.at(i) == QLatin1StringView(prior);
5505 || QLocaleId::fromName(uiLanguages.at(i)).name(sep) == prior);
5510 if (!uiLanguages.contains(QLatin1StringView(prior)))
5511 uiLanguages.append(QString::fromLatin1(prior));
5512 j = uiLanguages.size();
5515 const QLocaleId max = id.withLikelySubtagsAdded();
5516 Q_ASSERT(max.language_id);
5517 Q_ASSERT(max.language_id == id.language_id);
5521 const auto addIfEquivalent = [&j, &uiLanguages, max, sep, &prior, faithful](QLocaleId cid) {
5522 if (cid.withLikelySubtagsAdded() == max) {
5523 if (
const QByteArray name = cid.name(sep); name != prior)
5524 uiLanguages.insert(j, QString::fromLatin1(name));
5530 addIfEquivalent({ max.language_id, 0, 0 });
5533 addIfEquivalent({ max.language_id, max.script_id, 0 });
5534 if (id.script_id && id.script_id != max.script_id)
5535 addIfEquivalent({ id.language_id, id.script_id, 0 });
5537 if (max.territory_id)
5538 addIfEquivalent({ max.language_id, 0, max.territory_id });
5539 if (id.territory_id && id.territory_id != max.territory_id)
5540 addIfEquivalent({ id.language_id, 0, id.territory_id });
5542 if (max.territory_id && max.script_id)
5543 addIfEquivalent(max);
5544 if (max.territory_id && id.script_id && id.script_id != max.script_id)
5545 addIfEquivalent({ id.language_id, id.script_id, max.territory_id });
5546 if (max.script_id && id.territory_id && id.territory_id != max.territory_id)
5547 addIfEquivalent({ id.language_id, max.script_id, id.territory_id });
5548 if (id.territory_id && id.territory_id != max.territory_id
5549 && id.script_id && id.script_id != max.script_id) {
5550 addIfEquivalent(id);
5557 QDuplicateTracker<QString> known(uiLanguages.size());
5558 uiLanguages.removeIf([&](
const QString &s) {
return known.hasSeen(s); });
5562 const QLatin1Char cut(sep);
5563 const auto hasPrefix = [cut](
auto name, QStringView stem) {
5565 return name.startsWith(stem)
5566 && (name.size() == stem.size() || name.at(stem.size()) == cut);
5577 qsizetype afterEquivs = 0;
5578 qsizetype afterTruncs = 0;
5582 for (qsizetype i = 0; i < uiLanguages.size(); ++i >= afterEquivs && (i = afterTruncs)) {
5583 const QString entry = uiLanguages.at(i);
5584 const QLocaleId max = QLocaleId::fromName(entry).withLikelySubtagsAdded();
5586 if (i >= afterEquivs) {
5587 Q_ASSERT(i >= afterTruncs);
5588 afterEquivs = i + 1;
5590 while (afterEquivs < uiLanguages.size()
5591 && QLocaleId::fromName(uiLanguages.at(afterEquivs))
5592 .withLikelySubtagsAdded() == max) {
5596 afterTruncs = afterEquivs;
5598 if (hasPrefix(entry, u"C") || hasPrefix(entry, u"und"))
5600 qsizetype stopAt = uiLanguages.size();
5601 qsizetype at = entry.size();
5602 while ((at = entry.lastIndexOf(cut, at - 1)) > 0) {
5603 QString prefix = entry.first(at);
5607 bool found = known.contains(prefix);
5609
5610
5611
5612
5613
5614
5615
5616
5617
5619 = (QLocaleId::fromName(prefix).withLikelySubtagsAdded().script_id == max.script_id);
5620 for (qsizetype j = afterTruncs; !found && j < stopAt; ++j) {
5621 QString later = uiLanguages.at(j);
5622 if (!later.startsWith(prefix)) {
5623 const QByteArray laterFull =
5624 QLocaleId::fromName(later.replace(cut, u'-')
5625 ).withLikelySubtagsAdded().name(sep);
5627 if (hasPrefix(QLatin1StringView(laterFull), prefix))
5632 Q_ASSERT(later.size() > prefix.size());
5633 if (later.at(prefix.size()) == cut) {
5640 QStringView head{later};
5641 for (qsizetype as = head.lastIndexOf(cut);
5642 !found && as > prefix.size(); as = head.lastIndexOf(cut)) {
5643 head = head.first(as);
5645 for (qsizetype k = j + 1; !seen && k < uiLanguages.size(); ++k)
5646 seen = uiLanguages.at(k) == head;
5655 (
void) known.hasSeen(prefix);
5657 uiLanguages.insert(afterTruncs++, std::move(prefix));
5660 uiLanguages.append(std::move(prefix));
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679QLocale QLocale::collation()
const
5681#ifndef QT_NO_SYSTEMLOCALE
5682 if (d->m_data == &systemLocaleData) {
5683 const auto res = systemLocale()->query(QSystemLocale::Collation).toString();
5685 return QLocale(res);
5692
5693
5694
5695
5696
5697
5698
5699QString QLocale::nativeLanguageName()
const
5701#ifndef QT_NO_SYSTEMLOCALE
5702 if (d->m_data == &systemLocaleData) {
5703 auto res = systemLocale()->query(QSystemLocale::NativeLanguageName).toString();
5708 return d->m_data->endonymLanguage().getData(endonyms_data);
5712
5713
5714
5715
5716
5717
5718
5719QString QLocale::nativeTerritoryName()
const
5721#ifndef QT_NO_SYSTEMLOCALE
5722 if (d->m_data == &systemLocaleData) {
5723 auto res = systemLocale()->query(QSystemLocale::NativeTerritoryName).toString();
5728 return d->m_data->endonymTerritory().getData(endonyms_data);
5731#if QT_DEPRECATED_SINCE(6
, 6
)
5733
5734
5735
5736
5737
5738
5739
5740
5741QString QLocale::nativeCountryName()
const
5743 return nativeTerritoryName();
5747#ifndef QT_NO_DEBUG_STREAM
5750 QDebugStateSaver saver(dbg);
5751 const bool isSys = l == QLocale::system();
5752 dbg.nospace().noquote()
5753 << (isSys ?
"QLocale::system()/* " :
"QLocale(")
5754 << QLocale::languageToString(l.language()) <<
", "
5755 << QLocale::scriptToString(l.script()) <<
", "
5756 << QLocale::territoryToString(l.territory()) << (isSys ?
" */" :
")");
5762#ifndef QT_NO_QOBJECT
5763#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
qsizetype qt_repeatCount(QStringView s) 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