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"
67#include <q20iterator.h>
71constexpr int QLocale::DefaultTwoDigitBaseYear;
73QT_IMPL_METATYPE_EXTERN_TAGGED(QList<Qt::DayOfWeek>, QList_Qt__DayOfWeek)
74#ifndef QT_NO_SYSTEMLOCALE
75QT_IMPL_METATYPE_EXTERN_TAGGED(QSystemLocale::CurrencyToStringArgument,
76 QSystemLocale__CurrencyToStringArgument)
79using namespace Qt::StringLiterals;
80using namespace QtMiscUtils;
82#ifndef QT_NO_SYSTEMLOCALE
83Q_CONSTINIT
static QSystemLocale *_systemLocale =
nullptr;
84Q_CONSTINIT
static QLocaleData systemLocaleData = {};
87static_assert(ascii_isspace(
' '));
88static_assert(ascii_isspace(
'\t'));
89static_assert(ascii_isspace(
'\n'));
90static_assert(ascii_isspace(
'\v'));
91static_assert(ascii_isspace(
'\f'));
92static_assert(ascii_isspace(
'\r'));
93static_assert(!ascii_isspace(
'\0'));
94static_assert(!ascii_isspace(
'\a'));
95static_assert(!ascii_isspace(
'a'));
96static_assert(!ascii_isspace(
'\177'));
97static_assert(!ascii_isspace(uchar(
'\200')));
98static_assert(!ascii_isspace(uchar(
'\xA0')));
99static_assert(!ascii_isspace(uchar(
'\377')));
102
103
105QT_BEGIN_INCLUDE_NAMESPACE
107QT_END_INCLUDE_NAMESPACE
109QLocale::Language QLocalePrivate::codeToLanguage(QStringView code,
110 QLocale::LanguageCodeTypes codeTypes)
noexcept
112 const auto len = code.size();
113 if (len != 2 && len != 3)
114 return QLocale::AnyLanguage;
116 const char16_t uc1 = code[0].toLower().unicode();
117 const char16_t uc2 = code[1].toLower().unicode();
118 const char16_t uc3 = len > 2 ? code[2].toLower().unicode() : 0;
121 if (uc1 > 0x7F || uc2 > 0x7F || uc3 > 0x7F)
122 return QLocale::AnyLanguage;
124 const AlphaCode codeBuf = {
char(uc1),
char(uc2),
char(uc3) };
126 auto searchCode = [codeBuf](
auto f) {
127 return std::find_if(languageCodeList.begin(), languageCodeList.end(),
128 [=](LanguageCodeEntry i) {
return f(i) == codeBuf; });
131 if (codeTypes.testFlag(QLocale::ISO639Part1) && uc3 == 0) {
132 auto i = searchCode([](LanguageCodeEntry i) {
return i.part1; });
133 if (i != languageCodeList.end())
134 return QLocale::Language(std::distance(languageCodeList.begin(), i));
138 if (codeTypes.testFlag(QLocale::ISO639Part2B)) {
139 auto i = searchCode([](LanguageCodeEntry i) {
return i.part2B; });
140 if (i != languageCodeList.end())
141 return QLocale::Language(std::distance(languageCodeList.begin(), i));
146 if (codeTypes.testFlag(QLocale::ISO639Part2T)
147 && !codeTypes.testFlag(QLocale::ISO639Part3)) {
148 auto i = searchCode([](LanguageCodeEntry i) {
return i.part2T; });
149 if (i != languageCodeList.end())
150 return QLocale::Language(std::distance(languageCodeList.begin(), i));
153 if (codeTypes.testFlag(QLocale::ISO639Part3)) {
154 auto i = searchCode([](LanguageCodeEntry i) {
return i.part3; });
155 if (i != languageCodeList.end())
156 return QLocale::Language(std::distance(languageCodeList.begin(), i));
160 if (codeTypes.testFlag(QLocale::LegacyLanguageCode) && uc3 == 0) {
161 constexpr struct LegacyCodes {
163 QLocale::Language language;
165 { {
'n',
'o'}, QLocale::NorwegianBokmal },
166 { {
't',
'l'}, QLocale::Filipino },
167 { {
's',
'h'}, QLocale::Serbian },
168 { {
'm',
'o'}, QLocale::Romanian },
170 { {
'i',
'w'}, QLocale::Hebrew },
171 { {
'i',
'n'}, QLocale::Indonesian },
172 { {
'j',
'i'}, QLocale::Yiddish },
176 for (
const auto &e : legacyCodes) {
177 if (codeBuf == e.code)
181 return QLocale::AnyLanguage;
186 if (code.size() != 4)
191 const unsigned char c0 = (fixCase ? code[0].toUpper() : code[0]).toLatin1();
192 const unsigned char c1 = (fixCase ? code[1].toLower() : code[1]).toLatin1();
193 const unsigned char c2 = (fixCase ? code[2].toLower() : code[2]).toLatin1();
194 const unsigned char c3 = (fixCase ? code[3].toLower() : code[3]).toLatin1();
196 if (!c0 || !c1 || !c2 || !c3)
199 constexpr qsizetype NumScripts = QLocale::LastScript + 1;
202 for (qsizetype i = 0; i < NumScripts; ++i, c += 4) {
203 if (c0 == c[0] && c1 == c[1] && c2 == c[2] && c3 == c[3])
211 qsizetype index = scriptIndex(code, Qt::CaseInsensitive);
212 return index < 0 ? QLocale::AnyScript : QLocale::Script(index);
217 const auto len = code.size();
218 if (len != 2 && len != 3)
219 return QLocale::AnyTerritory;
221 char16_t uc1 = code[0].toUpper().unicode();
222 char16_t uc2 = code[1].toUpper().unicode();
223 char16_t uc3 = len > 2 ? code[2].toUpper().unicode() : 0;
226 for (; *c != 0; c += 3) {
227 if (uc1 == c[0] && uc2 == c[1] && uc3 == c[2])
228 return QLocale::Territory((c - territory_code_list)/3);
231 return QLocale::AnyTerritory;
235 QLocale::LanguageCodeTypes codeTypes)
237 if (language == QLocale::AnyLanguage || language > QLocale::LastLanguage)
239 if (language == QLocale::C)
244 if (codeTypes.testFlag(QLocale::ISO639Part1) && i.part1.isValid())
247 if (codeTypes.testFlag(QLocale::ISO639Part2B) && i.part2B.isValid())
250 if (codeTypes.testFlag(QLocale::ISO639Part2T) && i.part2T.isValid())
253 if (codeTypes.testFlag(QLocale::ISO639Part3))
261 if (script == QLocale::AnyScript || script > QLocale::LastScript)
264 return {
reinterpret_cast<
const char *>(c), 4};
269 if (territory == QLocale::AnyTerritory || territory > QLocale::LastTerritory)
273 return {
reinterpret_cast<
const char*>(c), c[2] == 0 ? 2 : 3};
283bool operator<(LikelyPair lhs, LikelyPair rhs)
287 const auto compare = [](
int lhs,
int rhs) {
289 const int huge = 0x10000;
290 return (lhs ? lhs : huge) - (rhs ? rhs : huge);
292 const auto &left = lhs.key;
293 const auto &right = rhs.key;
295 if (
int cmp = compare(left.language_id, right.language_id))
297 if (
int cmp = compare(left.territory_id, right.territory_id))
299 return compare(left.script_id, right.script_id) < 0;
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
329
330
331
332
333
334
335
336
337
338
339
340
341
343 auto *pairs =
reinterpret_cast<
const LikelyPair *>(
likely_subtags);
345 LikelyPair sought { *
this };
350 pairs =
std::lower_bound(pairs, afterPairs, sought);
353 for (; pairs < afterPairs && pairs->key.language_id ==
language_id; ++pairs) {
370 pairs =
std::lower_bound(pairs, afterPairs, sought);
373 for (; pairs < afterPairs && pairs->key.territory_id ==
territory_id; ++pairs) {
388 sought.key = QLocaleId { 0,
script_id, 0 };
389 pairs =
std::lower_bound(pairs, afterPairs, sought);
390 if (pairs < afterPairs && pairs->key.script_id ==
script_id) {
391 Q_ASSERT(!pairs->key.language_id && !pairs->key.territory_id);
401 pairs = afterPairs - 1;
402 if (pairs->key.matchesAll()) {
441 if (language_id == QLocale::AnyLanguage)
443 if (language_id == QLocale::C)
444 return QByteArrayLiteral(
"C");
445 Q_ASSERT(language_id <= QLocale::LastLanguage);
446 Q_ASSERT(script_id <= QLocale::LastScript);
447 Q_ASSERT(territory_id <= QLocale::LastTerritory);
453 if (language
.part1.isValid()) {
461 const unsigned char *script =
462 (script_id != QLocale::AnyScript ? script_code_list + 4 * script_id :
nullptr);
463 const unsigned char *country =
464 (territory_id != QLocale::AnyTerritory
465 ? territory_code_list + 3 * territory_id :
nullptr);
466 qsizetype len = langLen + (script ? 4 + 1 : 0) + (country ? (country[2] != 0 ? 3 : 2) + 1 : 0);
468 char *uc = name.data();
470 auto langArray = lang.decode();
472 *uc++ = langArray[0];
473 *uc++ = langArray[1];
475 *uc++ = langArray[2];
496 if (m_data->m_language_id == QLocale::AnyLanguage)
498 if (m_data->m_language_id == QLocale::C)
499 return QByteArrayView(
"en") % separator % QByteArrayView(
"POSIX");
506 qsizetype idx = locale_index[localeId.language_id];
509 if (localeId.language_id && idx == 0)
512 Q_ASSERT(localeId.acceptLanguage(locale_data[idx].m_language_id));
515 if (localeId.acceptScriptTerritory(locale_data[idx].id()))
518 }
while (localeId.acceptLanguage(locale_data[idx].m_language_id));
524bool QLocaleData::allLocaleDataRows(
bool (*check)(qsizetype,
const QLocaleData &))
526 for (qsizetype index = 0; index < locale_data_size; ++index) {
527 if (!(*check)(index, locale_data[index]))
537 Q_PRE(index < locale_data_size);
541#if QT_CONFIG(timezone) && QT_CONFIG(timezone_locale) && !QT_CONFIG(icu)
542namespace QtTimeZoneLocale {
545QList<qsizetype> fallbackLocalesFor(qsizetype index)
549 Q_ASSERT(index < locale_data_size);
550 QList<qsizetype> result = {index};
551 QLocaleId id = locale_data[index].id();
552 if (id.language_id == QLocale::C) {
553 id = { QLocale::English, QLocale::LatinScript, QLocale::UnitedStates };
554 qsizetype it = findLocaleIndexById(id);
555 Q_ASSERT_X(it != -1, Q_FUNC_INFO,
"Missing en_Latn_US from locale data");
556 Q_ASSERT_X(it != index,
557 Q_FUNC_INFO,
"en_Latn_US != C");
561 const QLocaleId base = id;
562 QLocaleId likely = id.withLikelySubtagsAdded();
563 if (likely != base) {
564 qsizetype it = findLocaleIndexById(likely);
565 if (it != -1 && !result.contains(it))
568 if (id.territory_id) {
570 likely = id.withLikelySubtagsAdded();
571 if (likely != base) {
572 qsizetype it = findLocaleIndexById(likely);
573 if (it != -1 && !result.contains(it))
579 likely = id.withLikelySubtagsAdded();
580 if (likely != base) {
581 qsizetype it = findLocaleIndexById(likely);
582 if (it != -1 && !result.contains(it))
599 qsizetype index = findLocaleIndexById(likelyId);
603 tried.push_back(likelyId);
605#define CheckCandidate(id) do {
606 if (!tried.contains(id)) {
607 index = findLocaleIndexById(id);
639 return locale_index[fallback];
644 const std::u16string_view v(name.utf16(), size_t(name.size()));
645 const auto i = v.find_first_of(u"_-.@");
646 if (i == std::string_view::npos)
648 return name.first(qsizetype(i));
654 for (QChar uc : tag) {
655 const char16_t ch = uc.unicode();
656 if (!isAsciiLetterOrNumber(ch))
659 return tag.size() > 0;
663 QStringView *lang, QStringView *script, QStringView *land)
noexcept
666 enum ParserState { NoState, LangState, ScriptState, CountryState };
667 ParserState state = LangState;
668 while (name.size() && state != NoState) {
669 const QStringView tag = findTag(name);
672 name = name.sliced(tag.size());
673 const bool sep = name.size() > 0;
675 name = name.sliced(1);
679 if (tag.size() != 2 && tag.size() != 3)
683 state = sep ? ScriptState : NoState;
689 state = sep ? CountryState : NoState;
704 return state != LangState;
712 if (!qt_splitLocaleName(name, &lang, &script, &land))
713 return { QLocale::C, 0, 0 };
716 if (land.compare(
"POSIX", Qt::CaseInsensitive) == 0)
717 return { QLocale::C, 0, 0 };
719 QLocale::Language langId = QLocalePrivate::codeToLanguage(lang);
720 if (langId == QLocale::AnyLanguage)
721 return { QLocale::C, 0, 0 };
722 return { langId, QLocalePrivate::codeToScript(script), QLocalePrivate::codeToTerritory(land) };
729 Q_ASSERT(format.at(i) == u'\'');
731 if (i == format.size())
733 if (format.at(i).unicode() ==
'\'') {
740 while (i < format.size()) {
741 if (format.at(i).unicode() ==
'\'') {
742 if (format.mid(i + 1).startsWith(u'\'')) {
744 result.append(u'\'');
750 result.append(format.at(i++));
753 if (i < format.size())
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
779 const QChar c = s.front();
781 while (j < s.size() && s.at(j) == c)
786Q_CONSTINIT
static const QLocaleData *default_data =
nullptr;
787Q_CONSTINIT QBasicAtomicInt QLocalePrivate::s_generation = Q_BASIC_ATOMIC_INITIALIZER(0);
791 Q_CONSTINIT
static QLocalePrivate c_locale(locale_data, 0, QLocale::OmitGroupSeparator, 1);
797 return forLanguage == QLocale::C ? QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions;
802 return defaultNumberOptions(QLocale::Language(forLanguage));
805#ifndef QT_NO_SYSTEMLOCALE
807
808
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830QSystemLocale::QSystemLocale() : next(_systemLocale)
832 _systemLocale =
this;
834 systemLocaleData.m_language_id = 0;
838
839
840
841QSystemLocale::~QSystemLocale()
843 if (_systemLocale ==
this) {
844 _systemLocale = next;
847 systemLocaleData.m_language_id = 0;
849 for (QSystemLocale *p = _systemLocale; p; p = p->next) {
859 return _systemLocale;
864 static QSystemLocale globalInstance;
865 return &globalInstance;
873 const QSystemLocale *sys_locale = systemLocale();
876 sys_locale->query(QSystemLocale::LocaleChanged);
879 systemLocaleData = locale_data[sys_locale->fallbackLocaleIndex()];
881 QVariant res = sys_locale->query(QSystemLocale::LanguageId);
883 systemLocaleData.m_language_id = res.toInt();
884 systemLocaleData.m_script_id = QLocale::AnyScript;
886 res = sys_locale->query(QSystemLocale::TerritoryId);
888 systemLocaleData.m_territory_id = res.toInt();
889 systemLocaleData.m_script_id = QLocale::AnyScript;
891 res = sys_locale->query(QSystemLocale::ScriptId);
893 systemLocaleData.m_script_id = res.toInt();
898 if (default_data == &systemLocaleData)
899 QLocalePrivate::s_generation.fetchAndAddRelaxed(1);
905#ifndef QT_NO_SYSTEMLOCALE
907
908
909
910
911
912
913
915 Q_CONSTINIT
static QLocaleId sysId;
916 bool updated =
false;
918 Q_CONSTINIT
static QBasicMutex systemDataMutex;
919 systemDataMutex.lock();
920 if (systemLocaleData.m_language_id == 0) {
921 updateSystemPrivate();
925 if (sysIndex && (updated || *sysIndex < 0)) {
926 const QLocaleId nowId = systemLocaleData.id();
927 if (sysId != nowId || *sysIndex < 0) {
929 *sysIndex = QLocaleData::findLocaleIndex(nowId);
933 systemDataMutex.unlock();
936 return &systemLocaleData;
946 default_data = systemData();
953#ifndef QT_NO_SYSTEMLOCALE
954 if (data == &systemLocaleData) {
957 return QLocaleData::findLocaleIndex(data->id());
968 Q_ASSERT(locale_index[QLocale::C] == 0);
972#ifndef QT_NO_DATASTREAM
973QDataStream &operator<<(QDataStream &ds,
const QLocale &l)
979QDataStream &
operator>>(QDataStream &ds, QLocale &l)
989 new QLocalePrivate(defaultData(), defaultIndex(),
990 defaultNumberOptions(defaultData()->m_language_id)))
996 const qsizetype index = QLocaleData::findLocaleIndex(QLocaleId::fromName(name));
997 return new QLocalePrivate(QLocaleData::dataForLocaleIndex(index), index,
998 defaultNumberOptions(locale_data[index].m_language_id));
1002 QLocale::Territory territory)
1004 if (language == QLocale::C)
1007 qsizetype index = QLocaleData::findLocaleIndex(QLocaleId { language, script, territory });
1008 const QLocaleData *data = QLocaleData::dataForLocaleIndex(index);
1010 QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
1013 if (data->m_language_id == QLocale::C) {
1014 if (defaultLocalePrivate.exists())
1015 numberOptions = defaultLocalePrivate->data()->m_numberOptions;
1017 index = defaultIndex();
1025 auto compareWithPrivate = [&loc](
const QLocaleData *data, QLocale::NumberOptions opts)
1027 return loc.d->m_data == data && loc.d->m_numberOptions == opts;
1030 if (lang == QLocale::C)
1033 qsizetype index = QLocaleData::findLocaleIndex(QLocaleId { lang });
1034 const QLocaleData *data = QLocaleData::dataForLocaleIndex(index);
1036 QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
1039 if (data->m_language_id == QLocale::C) {
1040 if (defaultLocalePrivate.exists())
1041 numberOptions = defaultLocalePrivate->data()->m_numberOptions;
1044 return compareWithPrivate(data, numberOptions);
1047static std::optional<QString>
1050#ifndef QT_NO_SYSTEMLOCALE
1051 if (that != &systemLocaleData)
1052 return std::nullopt;
1054 QVariant v = systemLocale()->query(type);
1055 if (v.metaType() != QMetaType::fromType<QString>())
1056 return std::nullopt;
1058 return v.toString();
1062 return std::nullopt;
1069 if (
auto opt = systemLocaleString(that, type))
1076 return localeString(
this, QSystemLocale::DecimalPoint, decimalSeparator());
1081 return localeString(
this, QSystemLocale::GroupSeparator, groupDelim());
1096 return localeString(
this, QSystemLocale::ZeroDigit, zero());
1101#ifndef QT_NO_SYSTEMLOCALE
1102 if (
this == &systemLocaleData) {
1103 const auto text = systemLocale()->query(QSystemLocale::ZeroDigit).toString();
1104 if (!text.isEmpty()) {
1105 if (text.size() == 1 && !text.at(0).isSurrogate())
1106 return text.at(0).unicode();
1107 if (text.size() == 2 && text.at(0).isHighSurrogate())
1108 return QChar::surrogateToUcs4(text.at(0), text.at(1));
1117 return localeString(
this, QSystemLocale::NegativeSign, minus());
1122 return localeString(
this, QSystemLocale::PositiveSign, plus());
1132#ifndef QT_NO_SYSTEMLOCALE
1133 if (
this == &systemLocaleData) {
1134 QVariant queryResult = systemLocale()->query(QSystemLocale::Grouping);
1135 if (!queryResult.isNull()) {
1138 if (sysGroupSizes.first <= 0)
1139 sysGroupSizes.first = m_grouping_first;
1140 if (sysGroupSizes.higher <= 0)
1141 sysGroupSizes.higher = m_grouping_higher;
1142 if (sysGroupSizes.least <= 0)
1143 sysGroupSizes.least = m_grouping_least;
1144 return sysGroupSizes;
1148 return { m_grouping_first,
1154
1155
1156QLocale::QLocale(QLocalePrivate &dd)
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207QLocale::QLocale(QStringView name)
1208 : d(localePrivateByName(name))
1213
1214
1215
1218
1219
1220
1221
1222
1223
1224
1229 if (!defaultLocalePrivate.isDestroyed()) {
1232 d = *defaultLocalePrivate;
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1248QLocale::QLocale(Language language, Territory territory)
1249 : d(findLocalePrivate(language, AnyScript, territory))
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1272QLocale::QLocale(Language language, Script script, Territory territory)
1273 : d(findLocalePrivate(language, script, territory))
1278
1279
1281QLocale::QLocale(
const QLocale &other)
noexcept =
default;
1284
1285
1292
1293
1294
1296QLocale &QLocale::operator=(
const QLocale &other)
noexcept =
default;
1299
1300
1301
1303bool QLocale::equals(
const QLocale &other)
const noexcept
1305 return d->m_data == other.d->m_data && d->m_numberOptions == other.d->m_numberOptions;
1309
1310
1311
1312
1315
1316
1317
1320 return qHashMulti(seed, key.d->m_data, key.d->m_numberOptions);
1324
1325
1326
1327
1328
1329
1330void QLocale::setNumberOptions(NumberOptions options)
1332 d->m_numberOptions = options;
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345QLocale::NumberOptions QLocale::numberOptions()
const
1347 return d->m_numberOptions;
1351
1352
1353
1354
1355
1356
1357
1360
1361
1362
1363
1364QString QLocale::quoteString(QStringView str, QuotationStyle style)
const
1366#ifndef QT_NO_SYSTEMLOCALE
1367 if (d->m_data == &systemLocaleData) {
1369 if (style == AlternateQuotation)
1370 res = systemLocale()->query(QSystemLocale::StringToAlternateQuotation,
1371 QVariant::fromValue(str));
1372 if (res.isNull() || style == StandardQuotation)
1373 res = systemLocale()->query(QSystemLocale::StringToStandardQuotation,
1374 QVariant::fromValue(str));
1376 return res.toString();
1380 QLocaleData::DataRange start, end;
1381 if (style == StandardQuotation) {
1382 start = d->m_data->quoteStart();
1383 end = d->m_data->quoteEnd();
1385 start = d->m_data->quoteStartAlternate();
1386 end = d->m_data->quoteEndAlternate();
1389 return start.viewData(single_character_data) % str % end.viewData(single_character_data);
1393
1394
1395
1396
1397
1398QString QLocale::createSeparatedList(
const QStringList &list)
const
1401#ifndef QT_NO_SYSTEMLOCALE
1402 if (d->m_data == &systemLocaleData) {
1404 systemLocale()->query(QSystemLocale::ListToSeparatedString, QVariant::fromValue(list));
1407 return res.toString();
1411 const qsizetype size = list.size();
1419 return d->m_data->pairListPattern().getData(
1420 list_pattern_part_data).arg(list.at(0), list.at(1));
1422 QStringView formatStart = d->m_data->startListPattern().viewData(list_pattern_part_data);
1423 QStringView formatMid = d->m_data->midListPattern().viewData(list_pattern_part_data);
1424 QStringView formatEnd = d->m_data->endListPattern().viewData(list_pattern_part_data);
1425 QString result = formatStart.arg(list.at(0), list.at(1));
1426 for (qsizetype i = 2; i < size - 1; ++i)
1427 result = formatMid.arg(result, list.at(i));
1428 result = formatEnd.arg(result, list.at(size - 1));
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1446void QLocale::setDefault(
const QLocale &locale)
1448 default_data = locale.d->m_data;
1450 if (defaultLocalePrivate.isDestroyed())
1452 if (!defaultLocalePrivate.exists()) {
1455 Q_ASSERT(defaultLocalePrivate.exists());
1459 *defaultLocalePrivate = locale.d;
1460 QLocalePrivate::s_generation.fetchAndAddRelaxed(1);
1464
1465
1466
1467
1468QLocale::Language QLocale::language()
const
1470 return Language(d->languageId());
1474
1475
1476
1477
1478
1479
1480QLocale::Script QLocale::script()
const
1482 return Script(d->m_data->m_script_id);
1486
1487
1488
1489
1490
1491
1492QLocale::Territory QLocale::territory()
const
1494 return Territory(d->territoryId());
1497#if QT_DEPRECATED_SINCE(6
, 6
)
1499
1500
1501
1502
1503
1504
1505QLocale::Country QLocale::country()
const
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1539 qWarning(
"QLocale::%s(): Using non-ASCII separator '%c' (%02x) is unsupported",
1540 method, sep, uint(uchar(sep)));
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1563QString QLocale::name(TagSeparator separator)
const
1565 const char sep =
char(separator);
1566 if (uchar(sep) > 0x7f) {
1567 badSeparatorWarning(
"name", sep);
1570 const auto code = d->languageCode();
1571 QLatin1StringView view{code.data()};
1573 Language l = language();
1577 Territory c = territory();
1578 if (c == AnyTerritory)
1581 return view + QLatin1Char(sep) + d->territoryCode();
1584template <
typename T>
static inline
1587 constexpr bool isUnsigned =
std::is_unsigned_v<T>;
1588 using Int64 =
typename std::conditional_t<isUnsigned, quint64, qint64>;
1590 QSimpleParsedNumber<Int64> r{};
1591 if constexpr (isUnsigned)
1592 r = d
->m_data->stringToUnsLongLong(str, 10, d->m_numberOptions);
1594 r = d
->m_data->stringToLongLong(str, 10, d->m_numberOptions);
1599 Int64 val = r.result;
1600 if (T(val) != val) {
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633QString QLocale::bcp47Name(TagSeparator separator)
const
1635 const char sep =
char(separator);
1636 if (uchar(sep) > 0x7f) {
1637 badSeparatorWarning(
"bcp47Name", sep);
1640 return QString::fromLatin1(d->bcp47Name(sep));
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661QString QLocale::languageToCode(Language language, LanguageCodeTypes codeTypes)
1663 const auto code = QLocalePrivate::languageToCode(language, codeTypes);
1664 return QLatin1StringView{code.data()};
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681QLocale::Language QLocale::codeToLanguage(QStringView languageCode,
1682 LanguageCodeTypes codeTypes)
noexcept
1684 return QLocalePrivate::codeToLanguage(languageCode, codeTypes);
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697QString QLocale::territoryToCode(QLocale::Territory territory)
1699 return QLocalePrivate::territoryToCode(territory);
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712QLocale::Territory QLocale::codeToTerritory(QStringView territoryCode)
noexcept
1714 return QLocalePrivate::codeToTerritory(territoryCode);
1717#if QT_DEPRECATED_SINCE(6
, 6
)
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728QString QLocale::countryToCode(Country country)
1730 return territoryToCode(country);
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743QLocale::Country QLocale::codeToCountry(QStringView countryCode)
noexcept
1745 return QLocalePrivate::codeToTerritory(countryCode);
1750
1751
1752
1753
1754
1755
1756
1757
1758QString QLocale::scriptToCode(Script script)
1760 return QLocalePrivate::scriptToCode(script);
1764
1765
1766
1767
1768
1769
1770
1771
1772QLocale::Script QLocale::codeToScript(QStringView scriptCode)
noexcept
1774 return QLocalePrivate::codeToScript(scriptCode);
1778
1779
1780
1781
1783QString QLocale::languageToString(Language language)
1785 if (language > LastLanguage)
1786 return "Unknown"_L1;
1787 return QString::fromUtf8(language_name_list + language_name_index[language]);
1791
1792
1793
1794
1795
1796
1797QString QLocale::territoryToString(Territory territory)
1799 if (territory > LastTerritory)
1800 return "Unknown"_L1;
1801 return QString::fromUtf8(territory_name_list + territory_name_index[territory]);
1804#if QT_DEPRECATED_SINCE(6
, 6
)
1806
1807
1808
1809
1810
1811
1812QString QLocale::countryToString(Country country)
1814 return territoryToString(country);
1819
1820
1821
1822
1823
1824
1825QString QLocale::scriptToString(Script script)
1827 if (script > LastScript)
1828 return "Unknown"_L1;
1829 return QString::fromUtf8(script_name_list + script_name_index[script]);
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2004short QLocale::toShort(QStringView s,
bool *ok)
const
2006 return toIntegral_helper<
short>(d, s, ok);
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2024ushort QLocale::toUShort(QStringView s,
bool *ok)
const
2026 return toIntegral_helper<ushort>(d, s, ok);
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2044int QLocale::toInt(QStringView s,
bool *ok)
const
2046 return toIntegral_helper<
int>(d, s, ok);
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2064uint QLocale::toUInt(QStringView s,
bool *ok)
const
2066 return toIntegral_helper<uint>(d, s, ok);
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2083long QLocale::toLong(QStringView s,
bool *ok)
const
2085 return toIntegral_helper<
long>(d, s, ok);
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2103ulong QLocale::toULong(QStringView s,
bool *ok)
const
2105 return toIntegral_helper<ulong>(d, s, ok);
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2124qlonglong QLocale::toLongLong(QStringView s,
bool *ok)
const
2126 return toIntegral_helper<qlonglong>(d, s, ok);
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2145qulonglong QLocale::toULongLong(QStringView s,
bool *ok)
const
2147 return toIntegral_helper<qulonglong>(d, s, ok);
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2166float QLocale::toFloat(QStringView s,
bool *ok)
const
2168 return QLocaleData::convertDoubleToFloat(toDouble(s, ok), ok);
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2192double QLocale::toDouble(QStringView s,
bool *ok)
const
2194 return d->m_data->stringToDouble(s, ok, d->m_numberOptions);
2198
2199
2200
2201
2203QString QLocale::toString(qlonglong i)
const
2205 int flags = (d->m_numberOptions & OmitGroupSeparator
2206 ? 0 : QLocaleData::GroupDigits);
2208 return d->m_data->longLongToString(i, -1, 10, -1, flags);
2212
2213
2214
2215
2217QString QLocale::toString(qulonglong i)
const
2219 int flags = (d->m_numberOptions & OmitGroupSeparator
2220 ? 0 : QLocaleData::GroupDigits);
2222 return d->m_data->unsLongLongToString(i, -1, 10, -1, flags);
2228 qsizetype count = 0;
2231 [[maybe_unused]]
auto ch = counter
.next();
2237 const QLocale &locale)
2240 if (!(locale.numberOptions() & QLocale::OmitGroupSeparator))
2244 else if (fillChar == U'0')
2256 if (fillChar == U'0') {
2257 Q_ASSERT(fieldWidth < 0);
2258 filler = localeData->zeroDigit();
2260 filler = QString(QChar::fromUcs4(fillChar));
2264 filler = filler.repeated(padding);
2269
2270
2271
2272
2273
2274
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294QString QLocale::toString(qlonglong number,
int fieldWidth,
char32_t fillChar)
const
2296 int absFieldWidth = qAbs(fieldWidth);
2297 int width = (fillChar == U'0') ? absFieldWidth : -1;
2298 unsigned flags = calculateFlags(fieldWidth, fillChar, *
this);
2300 QString result = d->m_data->longLongToString(number, -1, 10, width, flags);
2301 qsizetype padding = absFieldWidth - stringWidth(result);
2304 QString filler = calculateFiller(padding, fillChar, fieldWidth, d->m_data);
2306 result.append(filler);
2308 result.prepend(filler);
2314
2315
2316
2317
2318
2319
2321
2322
2323
2324QString QLocale::toString(qulonglong number,
int fieldWidth,
char32_t fillChar)
const
2326 int absFieldWidth = qAbs(fieldWidth);
2327 int width = (fillChar == U'0') ? absFieldWidth : -1;
2328 unsigned flags = calculateFlags(fieldWidth, fillChar, *
this);
2330 QString result = d->m_data->unsLongLongToString(number, -1, 10, width, flags);
2331 qsizetype padding = absFieldWidth - stringWidth(result);
2334 QString filler = calculateFiller(padding, fillChar, fieldWidth, d->m_data);
2336 result.append(filler);
2338 result.prepend(filler);
2344
2345
2346
2347
2348
2349
2351QString QLocale::toString(QDate date,
const QString &format)
const
2353 return toString(date, qToStringViewIgnoringNull(format));
2357
2358
2359
2360
2361
2362
2364QString QLocale::toString(QTime time,
const QString &format)
const
2366 return toString(time, qToStringViewIgnoringNull(format));
2370
2371
2372
2373
2374
2375
2376
2377
2378
2381
2382
2383
2384
2385
2386
2387
2388
2389QString QLocale::toString(QDate date, QStringView format, QCalendar cal)
const
2391 return cal.dateTimeToString(format, QDateTime(), date, QTime(), *
this);
2395
2396
2397
2398QString QLocale::toString(QDate date, QStringView format)
const
2400 return QCalendar().dateTimeToString(format, QDateTime(), date, QTime(), *
this);
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413QString QLocale::toString(QDate date, FormatType format, QCalendar cal)
const
2415 if (!date.isValid())
2418#ifndef QT_NO_SYSTEMLOCALE
2419 if (cal.isGregorian() && d->m_data == &systemLocaleData) {
2420 QVariant res = systemLocale()->query(format == LongFormat
2421 ? QSystemLocale::DateToStringLong
2422 : QSystemLocale::DateToStringShort,
2425 return res.toString();
2429 QString format_str = dateFormat(format);
2430 return toString(date, format_str, cal);
2434
2435
2436
2437QString QLocale::toString(QDate date, FormatType format)
const
2439 if (!date.isValid())
2442#ifndef QT_NO_SYSTEMLOCALE
2443 if (d->m_data == &systemLocaleData) {
2444 QVariant res = systemLocale()->query(format == LongFormat
2445 ? QSystemLocale::DateToStringLong
2446 : QSystemLocale::DateToStringShort,
2449 return res.toString();
2453 QString format_str = dateFormat(format);
2454 return toString(date, format_str);
2460 while (i < format.size()) {
2461 if (format.at(i).unicode() ==
'\'') {
2462 qt_readEscapedFormatString(format, &i);
2466 if (format.at(i).toLower().unicode() ==
'a')
2475
2476
2477
2478
2479
2480
2481
2482
2483QString QLocale::toString(QTime time, QStringView format)
const
2485 return QCalendar().dateTimeToString(format, QDateTime(), QDate(), time, *
this);
2489
2490
2491
2492
2493
2494
2495
2496
2497QString QLocale::toString(
const QDateTime &dateTime, QStringView format, QCalendar cal)
const
2499 return cal.dateTimeToString(format, dateTime, QDate(), QTime(), *
this);
2503
2504
2505
2506QString QLocale::toString(
const QDateTime &dateTime, QStringView format)
const
2508 return QCalendar().dateTimeToString(format, dateTime, QDate(), QTime(), *
this);
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521QString QLocale::toString(
const QDateTime &dateTime, FormatType format, QCalendar cal)
const
2523 if (!dateTime.isValid())
2526#ifndef QT_NO_SYSTEMLOCALE
2527 if (cal.isGregorian() && d->m_data == &systemLocaleData) {
2528 QVariant res = systemLocale()->query(format == LongFormat
2529 ? QSystemLocale::DateTimeToStringLong
2530 : QSystemLocale::DateTimeToStringShort,
2533 return res.toString();
2537 const QString format_str = dateTimeFormat(format);
2538 return toString(dateTime, format_str, cal);
2542
2543
2544
2545QString QLocale::toString(
const QDateTime &dateTime, FormatType format)
const
2547 if (!dateTime.isValid())
2550#ifndef QT_NO_SYSTEMLOCALE
2551 if (d->m_data == &systemLocaleData) {
2552 QVariant res = systemLocale()->query(format == LongFormat
2553 ? QSystemLocale::DateTimeToStringLong
2554 : QSystemLocale::DateTimeToStringShort,
2557 return res.toString();
2561 const QString format_str = dateTimeFormat(format);
2562 return toString(dateTime, format_str);
2567
2568
2569
2571QString QLocale::toString(QTime time, FormatType format)
const
2573 if (!time.isValid())
2576#ifndef QT_NO_SYSTEMLOCALE
2577 if (d->m_data == &systemLocaleData) {
2578 QVariant res = systemLocale()->query(format == LongFormat
2579 ? QSystemLocale::TimeToStringLong
2580 : QSystemLocale::TimeToStringShort,
2583 return res.toString();
2587 QString format_str = timeFormat(format);
2588 return toString(time, format_str);
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2603QString QLocale::dateFormat(FormatType format)
const
2605#ifndef QT_NO_SYSTEMLOCALE
2606 if (d->m_data == &systemLocaleData) {
2607 QVariant res = systemLocale()->query(format == LongFormat
2608 ? QSystemLocale::DateFormatLong
2609 : QSystemLocale::DateFormatShort,
2612 return res.toString();
2616 return (format == LongFormat
2617 ? d->m_data->longDateFormat()
2618 : d->m_data->shortDateFormat()
2619 ).getData(date_format_data);
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2634QString QLocale::timeFormat(FormatType format)
const
2636#ifndef QT_NO_SYSTEMLOCALE
2637 if (d->m_data == &systemLocaleData) {
2638 QVariant res = systemLocale()->query(format == LongFormat
2639 ? QSystemLocale::TimeFormatLong
2640 : QSystemLocale::TimeFormatShort,
2643 return res.toString();
2647 return (format == LongFormat
2648 ? d->m_data->longTimeFormat()
2649 : d->m_data->shortTimeFormat()
2650 ).getData(time_format_data);
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2665QString QLocale::dateTimeFormat(FormatType format)
const
2667#ifndef QT_NO_SYSTEMLOCALE
2668 if (d->m_data == &systemLocaleData) {
2669 QVariant res = systemLocale()->query(format == LongFormat
2670 ? QSystemLocale::DateTimeFormatLong
2671 : QSystemLocale::DateTimeFormatShort,
2673 if (!res.isNull()) {
2674 return res.toString();
2678 return dateFormat(format) + u' ' + timeFormat(format);
2681#if QT_CONFIG(datestring)
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697QTime QLocale::toTime(
const QString &string, FormatType format)
const
2699 return toTime(string, timeFormat(format));
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727QDate QLocale::toDate(
const QString &string, FormatType format,
int baseYear)
const
2729 return toDate(string, dateFormat(format), baseYear);
2733
2734
2735
2736QDate QLocale::toDate(
const QString &string, FormatType format, QCalendar cal,
int baseYear)
const
2738 return toDate(string, dateFormat(format), cal, baseYear);
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760QDateTime QLocale::toDateTime(
const QString &string, FormatType format,
int baseYear)
const
2762 return toDateTime(string, dateTimeFormat(format), baseYear);
2766
2767
2768
2769QDateTime QLocale::toDateTime(
const QString &string, FormatType format, QCalendar cal,
2772 return toDateTime(string, dateTimeFormat(format), cal, baseYear);
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790QTime QLocale::toTime(
const QString &string,
const QString &format)
const
2793#if QT_CONFIG(datetimeparser)
2794 QDateTimeParser dt(QMetaType::QTime, QDateTimeParser::FromString, QCalendar());
2795 dt.setDefaultLocale(*
this);
2796 if (dt.parseFormat(format))
2797 dt.fromString(string,
nullptr, &time);
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830QDate QLocale::toDate(
const QString &string,
const QString &format,
int baseYear)
const
2832 return toDate(string, format, QCalendar(), baseYear);
2836
2837
2838
2839QDate QLocale::toDate(
const QString &string,
const QString &format, QCalendar cal,
int baseYear)
const
2842#if QT_CONFIG(datetimeparser)
2843 QDateTimeParser dt(QMetaType::QDate, QDateTimeParser::FromString, cal);
2844 dt.setDefaultLocale(*
this);
2845 if (dt.parseFormat(format))
2846 dt.fromString(string, &date,
nullptr, baseYear);
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879QDateTime QLocale::toDateTime(
const QString &string,
const QString &format,
int baseYear)
const
2881 return toDateTime(string, format, QCalendar(), baseYear);
2885
2886
2887
2888QDateTime QLocale::toDateTime(
const QString &string,
const QString &format, QCalendar cal,
2891#if QT_CONFIG(datetimeparser)
2894 QDateTimeParser dt(QMetaType::QDateTime, QDateTimeParser::FromString, cal);
2895 dt.setDefaultLocale(*
this);
2896 if (dt.parseFormat(format) && (dt.fromString(string, &datetime, baseYear)
2897 || !datetime.isValid())) {
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924QString QLocale::decimalPoint()
const
2926 return d->m_data->decimalPoint();
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943QString QLocale::groupSeparator()
const
2945 return d->m_data->groupSeparator();
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960QString QLocale::percent()
const
2962 return d->m_data->percentSign();
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979QString QLocale::zeroDigit()
const
2981 return d->m_data->zeroDigit();
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996QString QLocale::negativeSign()
const
2998 return d->m_data->negativeSign();
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013QString QLocale::positiveSign()
const
3015 return d->m_data->positiveSign();
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031QString QLocale::exponential()
const
3033 return d->m_data->exponentSeparator();
3037
3038
3039
3040
3041
3042
3043
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
3070QString QLocale::toString(
double f,
char format,
int precision)
const
3072 QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
3073 uint flags = isAsciiUpper(format) ? QLocaleData::CapitalEorX : 0;
3075 switch (QtMiscUtils::toAsciiLower(format)) {
3077 form = QLocaleData::DFDecimal;
3080 form = QLocaleData::DFExponent;
3083 form = QLocaleData::DFSignificantDigits;
3089 if (!(d->m_numberOptions & OmitGroupSeparator))
3090 flags |= QLocaleData::GroupDigits;
3091 if (!(d->m_numberOptions & OmitLeadingZeroInExponent))
3092 flags |= QLocaleData::ZeroPadExponent;
3093 if (d->m_numberOptions & IncludeTrailingZeroesAfterDot)
3094 flags |= QLocaleData::AddTrailingZeroes;
3095 return d->m_data->doubleToString(f, precision, form, -1, flags);
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114QLocale QLocale::c()
noexcept
3116 return QLocale(*c_private());
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3133QLocale QLocale::system()
3135 constexpr auto sysData = []() {
3137#ifdef QT_NO_SYSTEMLOCALE
3140 return &systemLocaleData;
3143 Q_CONSTINIT
static QLocalePrivate locale(sysData(), -1, DefaultNumberOptions, 1);
3146 systemData(&locale.m_index);
3147 Q_ASSERT(locale.m_index >= 0 && locale.m_index < locale_data_size);
3148 locale.m_numberOptions = defaultNumberOptions(locale.m_data->m_language_id);
3150 return QLocale(locale);
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165QList<QLocale> QLocale::matchingLocales(Language language, Script script, Territory territory)
3167 QList<QLocale> result;
3169 const QLocaleId filter { language, script, territory };
3170 if (!filter.isValid())
3173 if (language == C) {
3174 result.emplace_back(C);
3178 if (filter.matchesAll())
3179 result.reserve(locale_data_size);
3181 quint16 index = locale_index[language];
3183 while (index < locale_data_size
3184 && filter.acceptLanguage(locale_data[index].m_language_id)) {
3185 const QLocaleId id = locale_data[index].id();
3186 if (filter.acceptScriptTerritory(id)) {
3187 result.append(QLocale(*(id.language_id == C ? c_private()
3188 :
new QLocalePrivate(locale_data + index, index))));
3194 const auto syslocaledata = systemData();
3196 if (filter.acceptLanguage(syslocaledata->m_language_id)) {
3197 const QLocaleId id = syslocaledata->id();
3198 if (filter.acceptScriptTerritory(id))
3199 result.append(system());
3205#if QT_DEPRECATED_SINCE(6
, 6
)
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
3218 const auto locales = matchingLocales(language, AnyScript, AnyCountry);
3219 QList<Country> result;
3220 result.reserve(locales.size());
3221 for (
const auto &locale : locales)
3222 result.append(locale.territory());
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239QString QLocale::monthName(
int month, FormatType type)
const
3241 return QCalendar().monthName(*
this, month, QCalendar::Unspecified, type);
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255QString QLocale::standaloneMonthName(
int month, FormatType type)
const
3257 return QCalendar().standaloneMonthName(*
this, month, QCalendar::Unspecified, type);
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273QString QLocale::dayName(
int day, FormatType type)
const
3275 return QCalendar().weekDayName(*
this, day, type);
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290QString QLocale::standaloneDayName(
int day, FormatType type)
const
3292 return QCalendar().standaloneWeekDayName(*
this, day, type);
3299 const QCalendarLocale *table)
3302 [[maybe_unused]]
const auto sameLocale = [](
const QLocaleData &locale,
3303 const QCalendarLocale &cal) {
3304 return locale.m_language_id == cal.m_language_id
3305 && locale.m_script_id == cal.m_script_id
3306 && locale.m_territory_id == cal.m_territory_id;
3308 const QCalendarLocale &monthly = table[loc->m_index];
3309#ifdef QT_NO_SYSTEMLOCALE
3310 [[maybe_unused]]
constexpr bool isSys =
false;
3312 [[maybe_unused]]
const bool isSys = loc->m_data == &systemLocaleData;
3317 Q_ASSERT(sameLocale(
locale_data[loc->m_index], monthly));
3322
3323
3326 const char16_t *monthsData,
int month,
3327 QLocale::FormatType type)
3330 return range.getListEntry(monthsData, month - 1);
3334
3335
3338 const char16_t *monthsData,
int month,
3339 QLocale::FormatType type)
3342 if (QString name = range.getListEntry(monthsData, month - 1); !name.isEmpty())
3344 return rawMonthName(localeData, monthsData, month, type);
3348
3349
3352 QLocale::FormatType type)
3356 case QLocale::LongFormat:
3357 range = data->longDayNames();
3359 case QLocale::ShortFormat:
3360 range = data->shortDayNames();
3362 case QLocale::NarrowFormat:
3363 range = data->narrowDayNames();
3368 return range.getListEntry(
days_data, day == 7 ? 0 : day);
3372
3373
3376 QLocale::FormatType type)
3380 case QLocale::LongFormat:
3381 range =data->longDayNamesStandalone();
3383 case QLocale::ShortFormat:
3384 range = data->shortDayNamesStandalone();
3386 case QLocale::NarrowFormat:
3387 range = data->narrowDayNamesStandalone();
3392 QString name = range.getListEntry(days_data, day == 7 ? 0 : day);
3394 return rawWeekDayName(data, day, type);
3400QString QCalendarBackend::monthName(
const QLocale &locale,
int month,
int,
3401 QLocale::FormatType format)
const
3403 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3404 return rawMonthName(getMonthDataFor(locale.d, localeMonthIndexData()),
3405 localeMonthData(), month, format);
3408QString QRomanCalendar::monthName(
const QLocale &locale,
int month,
int year,
3409 QLocale::FormatType format)
const
3411#ifndef QT_NO_SYSTEMLOCALE
3412 if (locale.d->m_data == &systemLocaleData) {
3413 Q_ASSERT(month >= 1 && month <= 12);
3414 QSystemLocale::QueryType queryType = QSystemLocale::MonthNameLong;
3416 case QLocale::LongFormat:
3417 queryType = QSystemLocale::MonthNameLong;
3419 case QLocale::ShortFormat:
3420 queryType = QSystemLocale::MonthNameShort;
3422 case QLocale::NarrowFormat:
3423 queryType = QSystemLocale::MonthNameNarrow;
3426 QVariant res = systemLocale()->query(queryType, month);
3428 return res.toString();
3432 return QCalendarBackend::monthName(locale, month, year, format);
3435QString QCalendarBackend::standaloneMonthName(
const QLocale &locale,
int month,
int,
3436 QLocale::FormatType format)
const
3438 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3439 return rawStandaloneMonthName(getMonthDataFor(locale.d, localeMonthIndexData()),
3440 localeMonthData(), month, format);
3443QString QRomanCalendar::standaloneMonthName(
const QLocale &locale,
int month,
int year,
3444 QLocale::FormatType format)
const
3446#ifndef QT_NO_SYSTEMLOCALE
3447 if (locale.d->m_data == &systemLocaleData) {
3448 Q_ASSERT(month >= 1 && month <= 12);
3449 QSystemLocale::QueryType queryType = QSystemLocale::StandaloneMonthNameLong;
3451 case QLocale::LongFormat:
3452 queryType = QSystemLocale::StandaloneMonthNameLong;
3454 case QLocale::ShortFormat:
3455 queryType = QSystemLocale::StandaloneMonthNameShort;
3457 case QLocale::NarrowFormat:
3458 queryType = QSystemLocale::StandaloneMonthNameNarrow;
3461 QVariant res = systemLocale()->query(queryType, month);
3463 return res.toString();
3467 return QCalendarBackend::standaloneMonthName(locale, month, year, format);
3472QString QCalendarBackend::weekDayName(
const QLocale &locale,
int day,
3473 QLocale::FormatType format)
const
3475 if (day < 1 || day > 7)
3478#ifndef QT_NO_SYSTEMLOCALE
3479 if (locale.d->m_data == &systemLocaleData) {
3480 QSystemLocale::QueryType queryType = QSystemLocale::DayNameLong;
3482 case QLocale::LongFormat:
3483 queryType = QSystemLocale::DayNameLong;
3485 case QLocale::ShortFormat:
3486 queryType = QSystemLocale::DayNameShort;
3488 case QLocale::NarrowFormat:
3489 queryType = QSystemLocale::DayNameNarrow;
3492 QVariant res = systemLocale()->query(queryType, day);
3494 return res.toString();
3498 return rawWeekDayName(locale.d->m_data, day, format);
3501QString QCalendarBackend::standaloneWeekDayName(
const QLocale &locale,
int day,
3502 QLocale::FormatType format)
const
3504 if (day < 1 || day > 7)
3507#ifndef QT_NO_SYSTEMLOCALE
3508 if (locale.d->m_data == &systemLocaleData) {
3509 QSystemLocale::QueryType queryType = QSystemLocale::StandaloneDayNameLong;
3511 case QLocale::LongFormat:
3512 queryType = QSystemLocale::StandaloneDayNameLong;
3514 case QLocale::ShortFormat:
3515 queryType = QSystemLocale::StandaloneDayNameShort;
3517 case QLocale::NarrowFormat:
3518 queryType = QSystemLocale::StandaloneDayNameNarrow;
3521 QVariant res = systemLocale()->query(queryType, day);
3523 return res.toString();
3527 return rawStandaloneWeekDayName(locale.d->m_data, day, format);
3533
3534
3535
3536
3537Qt::DayOfWeek QLocale::firstDayOfWeek()
const
3539#ifndef QT_NO_SYSTEMLOCALE
3540 if (d->m_data == &systemLocaleData) {
3541 const auto res = systemLocale()->query(QSystemLocale::FirstDayOfWeek);
3543 return static_cast<Qt::DayOfWeek>(res.toUInt());
3546 return static_cast<Qt::DayOfWeek>(d->m_data->m_first_day_of_week);
3552
3553
3554
3555
3556 struct TerritoryLanguage
3559 quint16 territoryId;
3560 QLocale::MeasurementSystem system;
3563 constexpr TerritoryLanguage ImperialMeasurementSystems[] = {
3564 { QLocale::English, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3565 { QLocale::English, QLocale::UnitedStatesMinorOutlyingIslands, QLocale::ImperialUSSystem },
3566 { QLocale::Spanish, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3567 { QLocale::Hawaiian, QLocale::UnitedStates, QLocale::ImperialUSSystem },
3568 { QLocale::English, QLocale::UnitedKingdom, QLocale::ImperialUKSystem }
3571 for (
const auto &system : ImperialMeasurementSystems) {
3572 if (system.languageId == m_data->m_language_id
3573 && system.territoryId == m_data->m_territory_id) {
3574 return system.system;
3577 return QLocale::MetricSystem;
3581
3582
3583
3584
3585QList<Qt::DayOfWeek> QLocale::weekdays()
const
3587#ifndef QT_NO_SYSTEMLOCALE
3588 if (d->m_data == &systemLocaleData) {
3590 = qvariant_cast<QList<Qt::DayOfWeek> >(systemLocale()->query(QSystemLocale::Weekdays));
3595 QList<Qt::DayOfWeek> weekdays;
3596 quint16 weekendStart = d->m_data->m_weekend_start;
3597 quint16 weekendEnd = d->m_data->m_weekend_end;
3598 for (
int day = Qt::Monday; day <= Qt::Sunday; day++) {
3599 if ((weekendEnd >= weekendStart && (day < weekendStart || day > weekendEnd)) ||
3600 (weekendEnd < weekendStart && (day > weekendEnd && day < weekendStart)))
3601 weekdays <<
static_cast<Qt::DayOfWeek>(day);
3607
3608
3609
3610
3611QLocale::MeasurementSystem QLocale::measurementSystem()
const
3613#ifndef QT_NO_SYSTEMLOCALE
3614 if (d->m_data == &systemLocaleData) {
3615 const auto res = systemLocale()->query(QSystemLocale::MeasurementSystem);
3617 return MeasurementSystem(res.toInt());
3621 return d->measurementSystem();
3625
3626
3627
3628
3629Qt::LayoutDirection QLocale::textDirection()
const
3638 case ImperialAramaicScript:
3639 case InscriptionalPahlaviScript:
3640 case InscriptionalParthianScript:
3641 case KharoshthiScript:
3643 case MandaeanScript:
3644 case ManichaeanScript:
3645 case MendeKikakuiScript:
3646 case MeroiticCursiveScript:
3647 case MeroiticScript:
3648 case NabataeanScript:
3650 case OldHungarianScript:
3651 case OldNorthArabianScript:
3652 case OldSouthArabianScript:
3654 case PalmyreneScript:
3655 case PhoenicianScript:
3656 case PsalterPahlaviScript:
3657 case SamaritanScript:
3660 return Qt::RightToLeft;
3664 return Qt::LeftToRight;
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682QString QLocale::toUpper(
const QString &str)
const
3684#if !defined(QT_BOOTSTRAPPED) && (QT_CONFIG(icu) || defined(Q_OS_WIN) || defined(Q_OS_APPLE))
3686 QString result = d->toUpper(str, &ok);
3691 return str.toUpper();
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706QString QLocale::toLower(
const QString &str)
const
3708#if !defined(QT_BOOTSTRAPPED) && (QT_CONFIG(icu) || defined(Q_OS_WIN) || defined(Q_OS_APPLE))
3710 const QString result = d->toLower(str, &ok);
3715 return str.toLower();
3720
3721
3722
3723
3724
3725
3726
3727QString QLocale::amText()
const
3729#ifndef QT_NO_SYSTEMLOCALE
3730 if (d->m_data == &systemLocaleData) {
3731 auto res = systemLocale()->query(QSystemLocale::AMText).toString();
3736 return d->m_data->anteMeridiem().getData(am_data);
3740
3741
3742
3743
3744
3745
3746
3747QString QLocale::pmText()
const
3749#ifndef QT_NO_SYSTEMLOCALE
3750 if (d->m_data == &systemLocaleData) {
3751 auto res = systemLocale()->query(QSystemLocale::PMText).toString();
3756 return d->m_data->postMeridiem().getData(pm_data);
3762 QStringView tail{text};
3764 if (tail.startsWith(
"UTC"_L1) || tail.startsWith(
"GMT"_L1))
3765 tail = tail.sliced(3);
3768 return (tail.isEmpty()
3773 : std::move(text).right(tail.size())));
3777#if QT_CONFIG(icu) || !(QT_CONFIG(timezone) && QT_CONFIG(timezone_locale))
3778namespace QtTimeZoneLocale {
3782QString zoneOffsetFormat([[maybe_unused]]
const QLocale &locale,
3784 [[maybe_unused]] QLocale::FormatType width,
3785 const QDateTime &when,
3789 Q_ASSERT(width == QLocale::ShortFormat);
3791#if QT_CONFIG(timezone)
3792 locale != QLocale::system()
3793 ? when.timeRepresentation().displayName(when, QTimeZone::OffsetName, locale)
3796 when.toOffsetFromUtc(offsetSeconds).timeZoneAbbreviation();
3798 if (!text.isEmpty())
3799 text = offsetFromAbbreviation(std::move(text));
3809QString QCalendarBackend::dateTimeToString(QStringView format,
const QDateTime &datetime,
3810 QDate dateOnly, QTime timeOnly,
3811 const QLocale &locale)
const
3815 bool formatDate =
false;
3816 bool formatTime =
false;
3817 if (datetime.isValid()) {
3818 date = datetime.date();
3819 time = datetime.time();
3822 }
else if (dateOnly.isValid()) {
3825 }
else if (timeOnly.isValid()) {
3833 int year = 0, month = 0, day = 0;
3835 const auto parts = julianDayToDate(date.toJulianDay());
3836 if (!parts.isValid())
3839 month = parts.month;
3843 auto appendToResult = [&](
int t,
int repeat) {
3844 auto data = locale.d->m_data;
3846 result.append(data->longLongToString(t, -1, 10, repeat, QLocaleData::ZeroPadded));
3848 result.append(data->longLongToString(t));
3851 auto formatType = [](
int repeat) {
3852 return repeat == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
3856 while (i < format.size()) {
3857 if (format.at(i).unicode() ==
'\'') {
3858 result.append(qt_readEscapedFormatString(format, &i));
3862 const QChar c = format.at(i);
3863 qsizetype rep = qt_repeatCount(format.mid(i));
3864 Q_ASSERT(rep < std::numeric_limits<
int>::max());
3865 int repeat =
int(rep);
3868 switch (c.unicode()) {
3873 else if (repeat >= 2)
3878 appendToResult(year, (year < 0) ? 5 : 4);
3881 appendToResult(year % 100, 2);
3892 repeat = qMin(repeat, 4);
3894 appendToResult(month, repeat);
3896 result.append(monthName(locale, month, year, formatType(repeat)));
3901 repeat = qMin(repeat, 4);
3903 appendToResult(day, repeat);
3906 locale.dayName(dayOfWeek(date.toJulianDay()), formatType(repeat)));
3913 if (!used && formatTime) {
3914 switch (c.unicode()) {
3917 repeat = qMin(repeat, 2);
3918 int hour = time.hour();
3919 if (timeFormatContainsAP(format)) {
3925 appendToResult(hour, repeat);
3930 repeat = qMin(repeat, 2);
3931 appendToResult(time.hour(), repeat);
3936 repeat = qMin(repeat, 2);
3937 appendToResult(time.minute(), repeat);
3942 repeat = qMin(repeat, 2);
3943 appendToResult(time.second(), repeat);
3948 QString text = time.hour() < 12 ? locale.amText() : locale.pmText();
3951 if (format.mid(i + 1).startsWith(u'p', Qt::CaseInsensitive))
3953 if (c.unicode() ==
'A' && (repeat == 1 || format.at(i + 1).unicode() ==
'P'))
3954 text = std::move(text).toUpper();
3955 else if (c.unicode() ==
'a' && (repeat == 1 || format.at(i + 1).unicode() ==
'p'))
3956 text = std::move(text).toLower();
3958 result.append(text);
3964 repeat = qMin(repeat, 3);
3968 appendToResult(time.msec(), 3);
3970 if (result.endsWith(locale.zeroDigit()))
3972 if (result.endsWith(locale.zeroDigit()))
3978 enum AbbrType { Long, Offset, Short };
3979 const auto tzAbbr = [locale](
const QDateTime &when, AbbrType type) {
3981 if (type == Offset) {
3982 text = QtTimeZoneLocale::zoneOffsetFormat(locale, locale.d->m_index,
3983 QLocale::ShortFormat,
3984 when, when.offsetFromUtc());
3986 if (!text.isEmpty())
3989#if QT_CONFIG(timezone)
3990 if (type != Short || locale != QLocale::system()) {
3991 QTimeZone::NameType mode =
3992 type == Short ? QTimeZone::ShortName
3993 : type == Long ? QTimeZone::LongName : QTimeZone::OffsetName;
3994 text = when.timeRepresentation().displayName(when, mode, locale);
3995 if (!text.isEmpty())
4001 text = QString::fromLatin1(when.timeZone().id());
4002 if (!text.isEmpty())
4009 text = when.toOffsetFromUtc(when.offsetFromUtc()).timeZoneAbbreviation();
4011 text = when.timeZoneAbbreviation();
4013 text = offsetFromAbbreviation(std::move(text));
4018 repeat = qMin(repeat, 4);
4020 const QDateTime when = formatDate ? datetime : QDateTime::currentDateTime();
4024 text = tzAbbr(when, Long);
4028 text = tzAbbr(when, Offset);
4033 text = tzAbbr(when, Short);
4035 if (text.startsWith(
"UTC"_L1) && text.size() == 6)
4039 if (!text.isEmpty())
4040 result.append(text);
4049 result.resize(result.size() + repeat, c);
4059 int width,
unsigned flags)
const
4066 if (precision != QLocale::FloatingPointShortest && precision < 0)
4072 qsizetype bufSize = 1;
4073 if (precision == QLocale::FloatingPointShortest)
4074 bufSize += std::numeric_limits<
double>::max_digits10;
4075 else if (form == DFDecimal && qt_is_finite(d))
4076 bufSize += wholePartSpace(qAbs(d)) + precision;
4078 bufSize += qMax(2, precision) + 1;
4080 QVarLengthArray<
char> buf(bufSize);
4082 bool negative =
false;
4083 qt_doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
4085 const QString prefix = signPrefix(negative && !qIsNull(d), flags);
4089 && (qstrncmp(buf.data(),
"inf", 3) == 0 || qstrncmp(buf.data(),
"nan", 3) == 0)) {
4090 numStr = QString::fromLatin1(buf.data(), length);
4092 const QString zero = zeroDigit();
4093 QString digits = QString::fromLatin1(buf.data(), length);
4097 Q_ASSERT(std::all_of(buf.cbegin(), buf.cbegin() + length, isAsciiDigit));
4099 }
else if (zero.size() == 2 && zero.at(0).isHighSurrogate()) {
4100 const char32_t zeroUcs4 = QChar::surrogateToUcs4(zero.at(0), zero.at(1));
4102 converted.reserve(2 * digits.size());
4103 for (QChar ch : std::as_const(digits)) {
4104 const char32_t digit = unicodeForDigit(ch.unicode() -
'0', zeroUcs4);
4105 Q_ASSERT(QChar::requiresSurrogates(digit));
4106 converted.append(QChar::highSurrogate(digit));
4107 converted.append(QChar::lowSurrogate(digit));
4109 digits =
std::move(converted);
4111 Q_ASSERT(zero.size() == 1);
4112 Q_ASSERT(!zero.at(0).isSurrogate());
4113 char16_t z = zero.at(0).unicode();
4114 char16_t *
const value =
reinterpret_cast<
char16_t *>(digits.data());
4115 for (qsizetype i = 0; i < digits.size(); ++i)
4116 value[i] = unicodeForDigit(value[i] -
'0', z);
4119 const bool mustMarkDecimal = flags &
ForcePoint;
4124 numStr = exponentForm(
std::move(digits), decpt, precision, PMDecimalDigits,
4125 mustMarkDecimal, minExponentDigits);
4128 numStr = decimalForm(
std::move(digits), decpt, precision, PMDecimalDigits,
4129 mustMarkDecimal, groupDigits);
4136
4137
4138
4139
4140
4141
4142
4143
4145 if (precision == QLocale::FloatingPointShortest) {
4152 int bias = 2 + minExponentDigits;
4154 if (groupDigits && decpt >= grouping
.first + grouping
.least)
4157 if (decpt > 10 && minExponentDigits == 1)
4162 const qsizetype digitCount = digits.size() / zero.size();
4163 if (!mustMarkDecimal) {
4166 if (digitCount <= decpt && digitCount > 1)
4168 else if (digitCount == 1 && decpt <= 0)
4176 useDecimal = (decpt <= 0 ? 1 - decpt <= bias
4177 : decpt <= digitCount ? 0 <= bias : decpt <= digitCount + bias);
4180 Q_ASSERT(precision >= 0);
4181 useDecimal = decpt > -4 && decpt <= (precision ? precision : 1);
4185 ? decimalForm(
std::move(digits), decpt, precision, mode,
4186 mustMarkDecimal, groupDigits)
4187 : exponentForm(
std::move(digits), decpt, precision, mode,
4188 mustMarkDecimal, minExponentDigits);
4195 for (qsizetype i = numStr.size() / zero.size() + prefix.size(); i < width; ++i)
4196 numStr.prepend(zero);
4201 ?
std::move(numStr).toUpper()
4202 :
std::move(numStr).toLower());
4205QString
QLocaleData::decimalForm(QString &&digits,
int decpt,
int precision,
4206 PrecisionMode pm,
bool mustMarkDecimal,
4207 bool groupDigits)
const
4209 const QString zero = zeroDigit();
4210 const auto digitWidth = zero.size();
4211 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
4212 Q_ASSERT(digits.size() % digitWidth == 0);
4217 for (; decpt < 0; ++decpt)
4218 digits.prepend(zero);
4220 for (qsizetype i = digits.size() / digitWidth; i < decpt; ++i)
4221 digits.append(zero);
4225 case PMDecimalDigits:
4226 for (qsizetype i = digits.size() / digitWidth - decpt; i < precision; ++i)
4227 digits.append(zero);
4229 case PMSignificantDigits:
4230 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
4231 digits.append(zero);
4233 case PMChopTrailingZeros:
4234 Q_ASSERT(digits.size() / digitWidth <= qMax(decpt, 1) || !digits.endsWith(zero));
4238 if (mustMarkDecimal || decpt < digits.size() / digitWidth)
4239 digits.insert(decpt * digitWidth, decimalPoint());
4243 const QString group = groupSeparator();
4244 qsizetype i = decpt - grouping.least;
4245 if (i >= grouping.first) {
4246 digits.insert(i * digitWidth, group);
4247 while ((i -= grouping.higher) > 0)
4248 digits.insert(i * digitWidth, group);
4253 digits.prepend(zero);
4255 return std::move(digits);
4258QString
QLocaleData::exponentForm(QString &&digits,
int decpt,
int precision,
4259 PrecisionMode pm,
bool mustMarkDecimal,
4260 int minExponentDigits)
const
4262 const QString zero = zeroDigit();
4263 const auto digitWidth = zero.size();
4264 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
4265 Q_ASSERT(digits.size() % digitWidth == 0);
4268 case PMDecimalDigits:
4269 for (qsizetype i = digits.size() / digitWidth; i < precision + 1; ++i)
4270 digits.append(zero);
4272 case PMSignificantDigits:
4273 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
4274 digits.append(zero);
4276 case PMChopTrailingZeros:
4277 Q_ASSERT(digits.size() / digitWidth <= 1 || !digits.endsWith(zero));
4281 if (mustMarkDecimal || digits.size() > digitWidth)
4282 digits.insert(digitWidth, decimalPoint());
4284 digits.append(exponentSeparator());
4285 digits.append(longLongToString(decpt - 1, minExponentDigits, 10, -1, AlwaysShowSign));
4287 return std::move(digits);
4290QString
QLocaleData::signPrefix(
bool negative,
unsigned flags)
const
4293 return negativeSign();
4294 if (flags & AlwaysShowSign)
4295 return positiveSign();
4296 if (flags & BlankBeforePositive)
4302 int base,
int width,
unsigned flags)
const
4304 bool negative = n < 0;
4307
4308
4309
4310 QString numStr = qulltoa(negative ? 1u + qulonglong(-(n + 1)) : qulonglong(n),
4313 return applyIntegerFormatting(
std::move(numStr), negative, precision, base, width, flags);
4317 int base,
int width,
unsigned flags)
const
4319 return applyIntegerFormatting(qulltoa(l, base, zeroDigit()),
4320 false, precision, base, width, flags);
4323QString
QLocaleData::applyIntegerFormatting(QString &&numStr,
bool negative,
int precision,
4324 int base,
int width,
unsigned flags)
const
4326 const QString zero = base == 10 ? zeroDigit() :
QStringLiteral(
"0");
4327 const auto digitWidth = zero.size();
4328 const auto digitCount = numStr.size() / digitWidth;
4330 const auto basePrefix = [&] () -> QStringView {
4331 if (flags & ShowBase) {
4332 const bool upper = flags & UppercaseBase;
4334 return upper ? u"0X" : u"0x";
4336 return upper ? u"0B" : u"0b";
4337 if (base == 8 && !numStr.startsWith(zero))
4343 const QString prefix = signPrefix(negative, flags) + basePrefix;
4345 qsizetype usedWidth = digitCount + prefix.size();
4349 const QString group = groupSeparator();
4350 qsizetype i = digitCount - grouping.least;
4351 if (i >= grouping.first) {
4352 numStr.insert(i * digitWidth, group);
4354 while ((i -= grouping.higher) > 0) {
4355 numStr.insert(i * digitWidth, group);
4362 const bool noPrecision = precision == -1;
4366 for (qsizetype i = numStr.size(); i < precision; ++i) {
4367 numStr.prepend(zero);
4374 for (qsizetype i = usedWidth; i < width; ++i)
4375 numStr.prepend(zero);
4378 QString result(flags & CapitalEorX ? std::move(numStr).toUpper() : std::move(numStr));
4380 result.prepend(prefix);
4386#ifndef QT_BUILD_INTERNAL
4390 :
grouping(data->groupSizes()), isC(data == c())
4396 setZero(data->zero().viewData(single_character_data));
4397 group = data->groupDelim().viewData(single_character_data);
4399 minus = data->minus().viewData(single_character_data);
4400 plus = data->plus().viewData(single_character_data);
4401 if (mode != IntegerMode)
4402 decimal = data->decimalSeparator().viewData(single_character_data);
4404 exponent = data->exponential().viewData(single_character_data);
4406 exponentCyrillic = data->m_script_id == QLocale::CyrillicScript;
4408#ifndef QT_NO_SYSTEMLOCALE
4409 if (data == &systemLocaleData) {
4410 const auto getString = [sys = systemLocale()](QSystemLocale::QueryType query) {
4411 return sys->query(query).toString();
4414 sysDecimal = getString(QSystemLocale::DecimalPoint);
4415 if (sysDecimal.size())
4416 decimal = QStringView{sysDecimal};
4418 sysGroup = getString(QSystemLocale::GroupSeparator);
4419 if (sysGroup.size())
4420 group = QStringView{sysGroup};
4421 sysMinus = getString(QSystemLocale::NegativeSign);
4422 if (sysMinus.size())
4423 minus = QStringView{sysMinus};
4424 sysPlus = getString(QSystemLocale::PositiveSign);
4426 plus = QStringView{sysPlus};
4427 setZero(getString(QSystemLocale::ZeroDigit));
4436class NumericTokenizer
4440 static constexpr char lettersInfNaN[] =
"afin";
4441 static constexpr auto matchInfNaN =
QtPrivate::makeCharacterSetMatch<lettersInfNaN>();
4442 const QStringView m_text;
4446 static_assert(
'+' + 1 ==
',' &&
',' + 1 ==
'-' &&
'-' + 1 ==
'.');
4451 : m_text(text), m_guide(guide), m_index(from), m_mode(mode),
4454 Q_ASSERT(m_guide.isValid(mode));
4456 bool done()
const {
return !(m_index < m_text.size()); }
4457 qsizetype index()
const {
return m_index; }
4458 int digitValue(
char32_t digit)
const {
return m_guide.digitValue(digit); }
4459 bool isInfNanChar(
char ch)
const {
return matchInfNaN.matches(ch); }
4461 bool fractionGroupClash()
const
4466 return Q_UNLIKELY(m_mode != QLocaleData::IntegerMode && m_guide.fractionalIsGroup());
4471char NumericTokenizer::nextToken()
4478 const auto asciiLower = [](
unsigned char c) {
return c >=
'A' ? c | 0x20 : c; };
4479 const QStringView tail = m_text.sliced(m_index);
4480 const QChar ch = tail.front();
4481 if (ch == u'\u2212') {
4488 if (Q_LIKELY(ch.unicode() < 256)) {
4489 unsigned char ascii = asciiLower(ch.toLatin1());
4490 if (Q_LIKELY(isAsciiDigit(ascii) || (
'+' <= ascii && ascii <= lastMark)
4501 if (ch.unicode() < 256) {
4503 char ascii = asciiLower(ch.toLatin1());
4504 if (isAsciiDigit(ascii) || ascii ==
'-' || ascii ==
'+'
4513 if (tail.startsWith(m_guide.minus)) {
4514 m_index += m_guide.minus.size();
4517 if (tail.startsWith(m_guide.plus)) {
4518 m_index += m_guide.plus.size();
4521 if (!m_guide.group.isEmpty() && tail.startsWith(m_guide.group)) {
4522 m_index += m_guide.group.size();
4527 if (fractionGroupClash() && tail.indexOf(m_guide.decimal, m_guide.group.size()) == -1)
4531 if (m_mode != QLocaleData::IntegerMode && tail.startsWith(m_guide.decimal)) {
4532 m_index += m_guide.decimal.size();
4535 if (m_mode == QLocaleData::DoubleScientificMode
4536 && tail.startsWith(m_guide.exponent, Qt::CaseInsensitive)) {
4537 m_index += m_guide.exponent.size();
4542 if (m_guide.zeroLen == 1) {
4543 if (!ch.isSurrogate()) {
4544 if (
const int gap = digitValue(
char32_t(ch.unicode())); gap >= 0) {
4548 }
else if (ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()) {
4552 }
else if (ch.isHighSurrogate()) {
4555 if (tail.size() > 1) {
4556 if (
const QChar low = tail.at(1); low.isLowSurrogate()) {
4557 if (
const int gap = digitValue(QChar::surrogateToUcs4(ch, low)); gap >= 0) {
4568 Q_ASSERT(!(ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()));
4571 switch (ch.unicode()) {
4585 if (m_guide.group == u"\u00a0" || m_guide.group == u"\u202f") {
4599 if (m_guide.exponentCyrillic) {
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4636 NumericTokenizer tokens(s, NumericData(
this, mode), mode);
4639 enum { Whole, Grouped, Fraction, Exponent, Name } stage = Whole;
4645 bool wantDigits =
true;
4648 bool needHigherGroup =
false;
4649 qsizetype digitsInGroup = 0;
4651 const auto badLeastGroup = [&]() {
4657 if (stage == Grouped) {
4658 Q_ASSERT(!number_options.testFlag(QLocale::RejectGroupSeparator));
4660 if (needHigherGroup)
4663 if (digitsInGroup != grouping.least)
4670 while (!tokens.done()) {
4671 char out = tokens.nextToken();
4679 if (stage > Grouped)
4682 if (tokens.fractionGroupClash() && badLeastGroup()
4683 && digitsInGroup == grouping.higher) {
4689 needHigherGroup =
false;
4693 if (badLeastGroup())
4697 }
else if (out ==
'e') {
4698 if (wantDigits || stage == Name || stage > Fraction)
4701 if (stage < Fraction) {
4703 if (badLeastGroup())
4705 }
else if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot)) {
4712 }
else if (out ==
',') {
4718 if (number_options.testFlag(QLocale::RejectGroupSeparator))
4724 if (digitsInGroup == 0
4725 || digitsInGroup > qMax(grouping.first, grouping.higher)) {
4728 Q_ASSERT(!needHigherGroup);
4732 if (grouping.first > digitsInGroup)
4733 needHigherGroup =
true;
4738 if (digitsInGroup != grouping.higher)
4740 needHigherGroup =
false;
4749 }
else if (isAsciiDigit(out)) {
4752 if (out ==
'0' && number_options.testFlag(QLocale::RejectLeadingZeroInExponent)
4753 && stage > Fraction && !tokens.done() && !isAsciiDigit(last)) {
4761 }
else if (stage == Whole && tokens.isInfNanChar(out)) {
4771 result->append(out);
4776 if (!number_options.testFlag(QLocale::RejectGroupSeparator)) {
4778 if (stage < Fraction && badLeastGroup())
4782 if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot) && stage == Fraction) {
4793 QLocale::NumberOptions number_options)
const
4796 result.buff.reserve(str.size());
4798 enum { Whole, Fractional, Exponent } state = Whole;
4800 NumericTokenizer tokens(str, NumericData(
this, numMode), numMode);
4803 while (!tokens.done()) {
4804 char c = tokens.nextToken();
4806 if (isAsciiDigit(c)) {
4813 if (decDigits-- == 0)
4817 if (!isAsciiDigit(last)) {
4820 if (c ==
'0' && (number_options & QLocale::RejectLeadingZeroInExponent))
4842 if (last !=
'\0' && !(scientific && last ==
'e'))
4848 if ((number_options & QLocale::RejectGroupSeparator) || state != Whole
4849 || !isAsciiDigit(last)) {
4858 if (!scientific || state == Exponent)
4868 Q_ASSERT(!c || c ==
'a' || c ==
'f' || c ==
'i' || c ==
'n');
4875 result.buff.append(c);
4882 if (last ==
',' || last ==
'-' || last ==
'+' || last ==
'e')
4889 QLocale::NumberOptions number_options)
const
4892 if (!numberToCLocale(str, number_options, DoubleScientificMode, &buff)) {
4897 auto r = qt_asciiToDouble(buff.constData(), buff.size());
4905 QLocale::NumberOptions number_options)
const
4908 if (!numberToCLocale(str, number_options, IntegerMode, &buff))
4911 return bytearrayToLongLong(QByteArrayView(buff), base);
4916 QLocale::NumberOptions number_options)
const
4919 if (!numberToCLocale(str, number_options, IntegerMode, &buff))
4922 return bytearrayToUnsLongLong(QByteArrayView(buff), base);
4930 const qsizetype len = num.size();
4931 if (used < len && num[used] !=
'\0') {
4932 while (used < len && ascii_isspace(num[used]))
4936 if (used < len && num[used] !=
'\0')
4943QSimpleParsedNumber<qint64>
QLocaleData::bytearrayToLongLong(QByteArrayView num,
int base)
4945 auto r = qstrntoll(num.data(), num.size(), base);
4946 if (!checkParsed(num, r.used))
4951QSimpleParsedNumber<quint64>
QLocaleData::bytearrayToUnsLongLong(QByteArrayView num,
int base)
4953 auto r = qstrntoull(num.data(), num.size(), base);
4954 if (!checkParsed(num, r.used))
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4972
4973
4974
4975QString QLocale::currencySymbol(CurrencySymbolFormat format)
const
4977#ifndef QT_NO_SYSTEMLOCALE
4978 if (d->m_data == &systemLocaleData) {
4979 auto res = systemLocale()->query(QSystemLocale::CurrencySymbol, format).toString();
4985 case CurrencySymbol:
4986 return d->m_data->currencySymbol().getData(currency_symbol_data);
4987 case CurrencyDisplayName:
4988 return d->m_data->currencyDisplayName().getData(currency_display_name_data);
4989 case CurrencyIsoCode: {
4990 const char *code = d->m_data->m_currency_iso_code;
4991 if (
auto len = qstrnlen(code, 3))
4992 return QString::fromLatin1(code, qsizetype(len));
5000
5001
5002
5003
5004
5005
5006
5007QString QLocale::toCurrencyString(qlonglong value,
const QString &symbol)
const
5009#ifndef QT_NO_SYSTEMLOCALE
5010 if (d->m_data == &systemLocaleData) {
5011 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5012 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5013 QVariant::fromValue(arg)).toString();
5018 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
5019 if (!range.size || value >= 0)
5020 range = d->m_data->currencyFormat();
5023 QString str = toString(value);
5024 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5026 sym = currencySymbol(CurrencyIsoCode);
5027 return range.viewData(currency_format_data).arg(str, sym);
5031
5032
5033
5034QString QLocale::toCurrencyString(qulonglong value,
const QString &symbol)
const
5036#ifndef QT_NO_SYSTEMLOCALE
5037 if (d->m_data == &systemLocaleData) {
5038 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5039 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5040 QVariant::fromValue(arg)).toString();
5045 QString str = toString(value);
5046 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5048 sym = currencySymbol(CurrencyIsoCode);
5049 return d->m_data->currencyFormat().getData(currency_format_data).arg(str, sym);
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062QString QLocale::toCurrencyString(
double value,
const QString &symbol,
int precision)
const
5064#ifndef QT_NO_SYSTEMLOCALE
5065 if (d->m_data == &systemLocaleData) {
5066 QSystemLocale::CurrencyToStringArgument arg(value, symbol);
5067 auto res = systemLocale()->query(QSystemLocale::CurrencyToString,
5068 QVariant::fromValue(arg)).toString();
5073 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
5074 if (!range.size || value >= 0)
5075 range = d->m_data->currencyFormat();
5078 QString str = toString(value,
'f', precision == -1 ? d->m_data->m_currency_digits : precision);
5079 QString sym = symbol.isNull() ? currencySymbol() : symbol;
5081 sym = currencySymbol(CurrencyIsoCode);
5082 return range.viewData(currency_format_data).arg(str, sym);
5086
5087
5088
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122QString QLocale::formattedDataSize(qint64 bytes,
int precision, DataSizeFormats format)
const
5124 int power, base = 1000;
5127 }
else if (format & DataSizeBase1000) {
5128 constexpr auto log10_1000 = 3;
5129 power =
int(std::log10(QtPrivate::qUnsignedAbs(bytes))) / log10_1000;
5131 constexpr auto log2_1024 = 10;
5132 power = QtPrivate::log2i(QtPrivate::qUnsignedAbs(bytes)) / log2_1024;
5136 const QString number = power
5137 ? toString(bytes / std::pow(
double(base), power),
'f', qMin(precision, 3 * power))
5142 Q_ASSERT(power <= 6 && power >= 0);
5145 QLocaleData::DataRange range = (format & DataSizeSIQuantifiers)
5146 ? d->m_data->byteAmountSI() : d->m_data->byteAmountIEC();
5147 unit = range.viewListEntry(byte_unit_data, power - 1);
5149 unit = d->m_data->byteCount().viewData(byte_unit_data);
5152 return number + u' ' + unit;
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198QStringList QLocale::uiLanguages(TagSeparator separator)
const
5200 const char sep =
char(separator);
5201 QStringList uiLanguages;
5202 if (uchar(sep) > 0x7f) {
5203 badSeparatorWarning(
"uiLanguages", sep);
5206 QList<QLocaleId> localeIds;
5207#ifdef QT_NO_SYSTEMLOCALE
5208 constexpr bool isSystem =
false;
5210 const bool isSystem = d->m_data == &systemLocaleData;
5212 uiLanguages = systemLocale()->query(QSystemLocale::UILanguages).toStringList();
5213 if (separator != TagSeparator::Dash) {
5215 const QChar join = QLatin1Char(sep);
5216 uiLanguages.replaceInStrings(u"-", QStringView(&join, 1));
5220 for (
const auto &entry : std::as_const(uiLanguages))
5221 localeIds.append(QLocaleId::fromName(entry));
5222 if (localeIds.isEmpty())
5223 localeIds.append(systemLocale()->fallbackLocale().d->m_data->id());
5225
5226
5227
5228
5229
5230
5231
5232 const QString name = QString::fromLatin1(d->m_data->id().name(sep));
5233 if (!name.isEmpty() && language() != C && !uiLanguages.contains(name)) {
5236 const QLocaleId id = d->m_data->id();
5237 const QLocaleId max = id.withLikelySubtagsAdded();
5238 const QLocaleId mine = max.withLikelySubtagsRemoved();
5240 qsizetype lastAlike = uiLanguages.size() - 1;
5242 for (qsizetype i = 0; !seen && i < uiLanguages.size(); ++i) {
5243 const auto its = QLocaleId::fromName(uiLanguages.at(i)).withLikelySubtagsAdded();
5244 seen = its.withLikelySubtagsRemoved() == mine;
5245 if (!seen && its.language_id == max.language_id && its.script_id == max.script_id)
5249 localeIds.insert(lastAlike + 1, id);
5250 uiLanguages.insert(lastAlike + 1, QString::fromLatin1(id.name(sep)));
5256 localeIds.append(d->m_data->id());
5259 for (qsizetype i = localeIds.size(); i-- > 0; ) {
5260 const QLocaleId id = localeIds.at(i);
5261 Q_ASSERT(id.language_id);
5262 if (id.language_id == C) {
5263 if (!uiLanguages.contains(u"C"_s))
5264 uiLanguages.append(u"C"_s);
5270 const QByteArray prior = id.name(sep);
5271 bool faithful =
true;
5272 if (isSystem && i < uiLanguages.size()) {
5274 faithful = uiLanguages.at(i) == QLatin1StringView(prior);
5277 || QLocaleId::fromName(uiLanguages.at(i)).name(sep) == prior);
5282 if (!uiLanguages.contains(QLatin1StringView(prior)))
5283 uiLanguages.append(QString::fromLatin1(prior));
5284 j = uiLanguages.size();
5287 const QLocaleId max = id.withLikelySubtagsAdded();
5288 Q_ASSERT(max.language_id);
5289 Q_ASSERT(max.language_id == id.language_id);
5293 const auto addIfEquivalent = [&j, &uiLanguages, max, sep, &prior, faithful](QLocaleId cid) {
5294 if (cid.withLikelySubtagsAdded() == max) {
5295 if (
const QByteArray name = cid.name(sep); name != prior)
5296 uiLanguages.insert(j, QString::fromLatin1(name));
5302 addIfEquivalent({ max.language_id, 0, 0 });
5305 addIfEquivalent({ max.language_id, max.script_id, 0 });
5306 if (id.script_id && id.script_id != max.script_id)
5307 addIfEquivalent({ id.language_id, id.script_id, 0 });
5309 if (max.territory_id)
5310 addIfEquivalent({ max.language_id, 0, max.territory_id });
5311 if (id.territory_id && id.territory_id != max.territory_id)
5312 addIfEquivalent({ id.language_id, 0, id.territory_id });
5314 if (max.territory_id && max.script_id)
5315 addIfEquivalent(max);
5316 if (max.territory_id && id.script_id && id.script_id != max.script_id)
5317 addIfEquivalent({ id.language_id, id.script_id, max.territory_id });
5318 if (max.script_id && id.territory_id && id.territory_id != max.territory_id)
5319 addIfEquivalent({ id.language_id, max.script_id, id.territory_id });
5320 if (id.territory_id && id.territory_id != max.territory_id
5321 && id.script_id && id.script_id != max.script_id) {
5322 addIfEquivalent(id);
5329 QDuplicateTracker<QString> known(uiLanguages.size());
5330 uiLanguages.removeIf([&](
const QString &s) {
return known.hasSeen(s); });
5334 const QLatin1Char cut(sep);
5335 const auto hasPrefix = [cut](
auto name, QStringView stem) {
5337 return name.startsWith(stem)
5338 && (name.size() == stem.size() || name.at(stem.size()) == cut);
5349 qsizetype afterEquivs = 0;
5350 qsizetype afterTruncs = 0;
5354 for (qsizetype i = 0; i < uiLanguages.size(); ++i >= afterEquivs && (i = afterTruncs)) {
5355 const QString entry = uiLanguages.at(i);
5356 const QLocaleId max = QLocaleId::fromName(entry).withLikelySubtagsAdded();
5358 if (i >= afterEquivs) {
5359 Q_ASSERT(i >= afterTruncs);
5360 afterEquivs = i + 1;
5362 while (afterEquivs < uiLanguages.size()
5363 && QLocaleId::fromName(uiLanguages.at(afterEquivs))
5364 .withLikelySubtagsAdded() == max) {
5368 afterTruncs = afterEquivs;
5370 if (hasPrefix(entry, u"C") || hasPrefix(entry, u"und"))
5372 qsizetype stopAt = uiLanguages.size();
5373 qsizetype at = entry.size();
5374 while ((at = entry.lastIndexOf(cut, at - 1)) > 0) {
5375 QString prefix = entry.first(at);
5379 bool found = known.contains(prefix);
5381
5382
5383
5384
5385
5386
5387
5388
5389
5391 = (QLocaleId::fromName(prefix).withLikelySubtagsAdded().script_id == max.script_id);
5392 for (qsizetype j = afterTruncs; !found && j < stopAt; ++j) {
5393 QString later = uiLanguages.at(j);
5394 if (!later.startsWith(prefix)) {
5395 const QByteArray laterFull =
5396 QLocaleId::fromName(later.replace(cut, u'-')
5397 ).withLikelySubtagsAdded().name(sep);
5399 if (hasPrefix(QLatin1StringView(laterFull), prefix))
5404 Q_ASSERT(later.size() > prefix.size());
5405 if (later.at(prefix.size()) == cut) {
5412 QStringView head{later};
5413 for (qsizetype as = head.lastIndexOf(cut);
5414 !found && as > prefix.size(); as = head.lastIndexOf(cut)) {
5415 head = head.first(as);
5417 for (qsizetype k = j + 1; !seen && k < uiLanguages.size(); ++k)
5418 seen = uiLanguages.at(k) == head;
5427 (
void) known.hasSeen(prefix);
5429 uiLanguages.insert(afterTruncs++, std::move(prefix));
5432 uiLanguages.append(std::move(prefix));
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451QLocale QLocale::collation()
const
5453#ifndef QT_NO_SYSTEMLOCALE
5454 if (d->m_data == &systemLocaleData) {
5455 const auto res = systemLocale()->query(QSystemLocale::Collation).toString();
5457 return QLocale(res);
5464
5465
5466
5467
5468
5469
5470
5471QString QLocale::nativeLanguageName()
const
5473#ifndef QT_NO_SYSTEMLOCALE
5474 if (d->m_data == &systemLocaleData) {
5475 auto res = systemLocale()->query(QSystemLocale::NativeLanguageName).toString();
5480 return d->m_data->endonymLanguage().getData(endonyms_data);
5484
5485
5486
5487
5488
5489
5490
5491QString QLocale::nativeTerritoryName()
const
5493#ifndef QT_NO_SYSTEMLOCALE
5494 if (d->m_data == &systemLocaleData) {
5495 auto res = systemLocale()->query(QSystemLocale::NativeTerritoryName).toString();
5500 return d->m_data->endonymTerritory().getData(endonyms_data);
5503#if QT_DEPRECATED_SINCE(6
, 6
)
5505
5506
5507
5508
5509
5510
5511
5512
5513QString QLocale::nativeCountryName()
const
5515 return nativeTerritoryName();
5519#ifndef QT_NO_DEBUG_STREAM
5522 QDebugStateSaver saver(dbg);
5523 const bool isSys = l == QLocale::system();
5524 dbg.nospace().noquote()
5525 << (isSys ?
"QLocale::system()/* " :
"QLocale(")
5526 << QLocale::languageToString(l.language()) <<
", "
5527 << QLocale::scriptToString(l.script()) <<
", "
5528 << QLocale::territoryToString(l.territory()) << (isSys ?
" */" :
")");
5534#ifndef QT_NO_QOBJECT
5535#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)
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
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
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
Fill in blank fields of a locale ID.
QLocaleId withLikelySubtagsRemoved() const noexcept
bool operator==(QLocaleId other) const noexcept