Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qlocale.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2021 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qglobal.h"
6
7#if (defined(QT_STATIC) || defined(QT_BOOTSTRAPPED)) && defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1000
8QT_WARNING_DISABLE_GCC("-Wfree-nonheap-object") // false positive tracking
9#endif
10
11#if defined(Q_OS_MACOS)
12# include "private/qcore_mac_p.h"
13# include <CoreFoundation/CoreFoundation.h>
14#endif
15
16#include "qplatformdefs.h"
17
18#include "qdatastream.h"
19#include "qdebug.h"
20#include "qhashfunctions.h"
21#include "qstring.h"
22#include "qlocale.h"
23#include "qlocale_p.h"
24#include "qlocale_tools_p.h"
25#include <private/qtools_p.h>
26#if QT_CONFIG(datetimeparser)
27#include "private/qdatetimeparser_p.h"
28#endif
29#include "qnamespace.h"
30#include "qdatetime.h"
31#include "qstringlist.h"
32#include "qvariant.h"
33#include "qvarlengtharray.h"
34#include "qstringbuilder.h"
35#if QT_CONFIG(timezone)
36# include "qtimezone.h"
37#endif
38#include "private/qnumeric_p.h"
39#include "private/qtools_p.h"
40#include <cmath>
41#ifndef QT_NO_SYSTEMLOCALE
42# include "qmutex.h"
43#endif
44#ifdef Q_OS_WIN
45# include <qt_windows.h>
46# include <time.h>
47#endif
48
49#include "private/qcalendarbackend_p.h"
50#include "private/qgregoriancalendar_p.h"
51#include "qcalendar.h"
52
53#include <q20iterator.h>
54
56
58#ifndef QT_NO_SYSTEMLOCALE
60 QSystemLocale__CurrencyToStringArgument)
61#endif
62
63using namespace Qt::StringLiterals;
64using namespace QtMiscUtils;
65
66#ifndef QT_NO_SYSTEMLOCALE
67Q_CONSTINIT static QSystemLocale *_systemLocale = nullptr;
68Q_CONSTINIT static QLocaleData systemLocaleData = {};
69#endif
70
71static_assert(ascii_isspace(' '));
72static_assert(ascii_isspace('\t'));
73static_assert(ascii_isspace('\n'));
74static_assert(ascii_isspace('\v'));
75static_assert(ascii_isspace('\f'));
76static_assert(ascii_isspace('\r'));
77static_assert(!ascii_isspace('\0'));
78static_assert(!ascii_isspace('\a'));
79static_assert(!ascii_isspace('a'));
80static_assert(!ascii_isspace('\177'));
81static_assert(!ascii_isspace(uchar('\200')));
82static_assert(!ascii_isspace(uchar('\xA0'))); // NBSP (is a space but Latin 1, not ASCII)
83static_assert(!ascii_isspace(uchar('\377')));
84
85/******************************************************************************
86** Helpers for accessing Qt locale database
87*/
88
90#include "qlocale_data_p.h"
92
94 QLocale::LanguageCodeTypes codeTypes) noexcept
95{
96 const auto len = code.size();
97 if (len != 2 && len != 3)
99
100 const char16_t uc1 = code[0].toLower().unicode();
101 const char16_t uc2 = code[1].toLower().unicode();
102 const char16_t uc3 = len > 2 ? code[2].toLower().unicode() : 0;
103
104 // All language codes are ASCII.
105 if (uc1 > 0x7F || uc2 > 0x7F || uc3 > 0x7F)
107
108 const AlphaCode codeBuf = { char(uc1), char(uc2), char(uc3) };
109
110 auto searchCode = [codeBuf](auto f) {
111 return std::find_if(languageCodeList.begin(), languageCodeList.end(),
112 [=](const LanguageCodeEntry &i) { return f(i) == codeBuf; });
113 };
114
115 if (codeTypes.testFlag(QLocale::ISO639Part1) && uc3 == 0) {
116 auto i = searchCode([](const LanguageCodeEntry &i) { return i.part1; });
117 if (i != languageCodeList.end())
118 return QLocale::Language(std::distance(languageCodeList.begin(), i));
119 }
120
121 if (uc3 != 0) {
122 if (codeTypes.testFlag(QLocale::ISO639Part2B)) {
123 auto i = searchCode([](const LanguageCodeEntry &i) { return i.part2B; });
124 if (i != languageCodeList.end())
125 return QLocale::Language(std::distance(languageCodeList.begin(), i));
126 }
127
128 // Optimization: Part 2T code if present is always the same as Part 3 code.
129 // This is asserted in iso639_3.LanguageCodeData.
130 if (codeTypes.testFlag(QLocale::ISO639Part2T)
131 && !codeTypes.testFlag(QLocale::ISO639Part3)) {
132 auto i = searchCode([](const LanguageCodeEntry &i) { return i.part2T; });
133 if (i != languageCodeList.end())
134 return QLocale::Language(std::distance(languageCodeList.begin(), i));
135 }
136
137 if (codeTypes.testFlag(QLocale::ISO639Part3)) {
138 auto i = searchCode([](const LanguageCodeEntry &i) { return i.part3; });
139 if (i != languageCodeList.end())
140 return QLocale::Language(std::distance(languageCodeList.begin(), i));
141 }
142 }
143
144 if (codeTypes.testFlag(QLocale::LegacyLanguageCode) && uc3 == 0) {
145 // legacy codes
146 if (uc1 == 'n' && uc2 == 'o') // no -> nb
148 if (uc1 == 't' && uc2 == 'l') // tl -> fil
149 return QLocale::Filipino;
150 if (uc1 == 's' && uc2 == 'h') // sh -> sr[_Latn]
151 return QLocale::Serbian;
152 if (uc1 == 'm' && uc2 == 'o') // mo -> ro
153 return QLocale::Romanian;
154 // Android uses the following deprecated codes
155 if (uc1 == 'i' && uc2 == 'w') // iw -> he
156 return QLocale::Hebrew;
157 if (uc1 == 'i' && uc2 == 'n') // in -> id
158 return QLocale::Indonesian;
159 if (uc1 == 'j' && uc2 == 'i') // ji -> yi
160 return QLocale::Yiddish;
161 }
163}
164
166{
167 const auto len = code.size();
168 if (len != 4)
169 return QLocale::AnyScript;
170
171 // script is titlecased in our data
172 unsigned char c0 = code[0].toUpper().toLatin1();
173 unsigned char c1 = code[1].toLower().toLatin1();
174 unsigned char c2 = code[2].toLower().toLatin1();
175 unsigned char c3 = code[3].toLower().toLatin1();
176
177 const unsigned char *c = script_code_list;
178 for (qsizetype i = 0; i < QLocale::LastScript; ++i, c += 4) {
179 if (c0 == c[0] && c1 == c[1] && c2 == c[2] && c3 == c[3])
180 return QLocale::Script(i);
181 }
182 return QLocale::AnyScript;
183}
184
186{
187 const auto len = code.size();
188 if (len != 2 && len != 3)
190
191 char16_t uc1 = code[0].toUpper().unicode();
192 char16_t uc2 = code[1].toUpper().unicode();
193 char16_t uc3 = len > 2 ? code[2].toUpper().unicode() : 0;
194
195 const unsigned char *c = territory_code_list;
196 for (; *c != 0; c += 3) {
197 if (uc1 == c[0] && uc2 == c[1] && uc3 == c[2])
199 }
200
202}
203
205 QLocale::LanguageCodeTypes codeTypes)
206{
208 return {};
209 if (language == QLocale::C)
210 return {'C'};
211
213
214 if (codeTypes.testFlag(QLocale::ISO639Part1) && i.part1.isValid())
215 return i.part1.decode();
216
217 if (codeTypes.testFlag(QLocale::ISO639Part2B) && i.part2B.isValid())
218 return i.part2B.decode();
219
220 if (codeTypes.testFlag(QLocale::ISO639Part2T) && i.part2T.isValid())
221 return i.part2T.decode();
222
223 if (codeTypes.testFlag(QLocale::ISO639Part3))
224 return i.part3.decode();
225
226 return {};
227}
228
230{
231 if (script == QLocale::AnyScript || script > QLocale::LastScript)
232 return {};
233 const unsigned char *c = script_code_list + 4 * script;
234 return {reinterpret_cast<const char *>(c), 4};
235}
236
238{
239 if (territory == QLocale::AnyTerritory || territory > QLocale::LastTerritory)
240 return {};
241
242 const unsigned char *c = territory_code_list + 3 * territory;
243 return {reinterpret_cast<const char*>(c), c[2] == 0 ? 2 : 3};
244}
245
246namespace {
247struct LikelyPair
248{
249 QLocaleId key; // Search key.
250 QLocaleId value = QLocaleId { 0, 0, 0 };
251};
252
253bool operator<(const LikelyPair &lhs, const LikelyPair &rhs)
254{
255 // Must match the comparison LocaleDataWriter.likelySubtags() uses when
256 // sorting, see qtbase/util/locale_database.qlocalexml2cpp.py
257 const auto compare = [](int lhs, int rhs) {
258 // 0 sorts after all other values; lhs and rhs are passed ushort values.
259 const int huge = 0x10000;
260 return (lhs ? lhs : huge) - (rhs ? rhs : huge);
261 };
262 const auto &left = lhs.key;
263 const auto &right = rhs.key;
264 // Comparison order: language, region, script:
265 if (int cmp = compare(left.language_id, right.language_id))
266 return cmp < 0;
267 if (int cmp = compare(left.territory_id, right.territory_id))
268 return cmp < 0;
269 return compare(left.script_id, right.script_id) < 0;
270}
271} // anonymous namespace
272
297{
298 /* Each pattern that appears in a comments below, language_script_region and
299 similar, indicates which of this's fields (even if blank) are being
300 attended to in a given search; for fields left out of the pattern, the
301 search uses 0 regardless of whether this has specified the field.
302
303 If a key matches what we're searching for (possibly with a wildcard in
304 the key matching a non-wildcard in our search), the tags from this that
305 are specified in the key are replaced by the match (even if different);
306 but the other tags of this replace what's in the match (even when the
307 match does specify a value).
308 */
309 static_assert(std::size(likely_subtags) % 2 == 0);
310 auto *pairs = reinterpret_cast<const LikelyPair *>(likely_subtags);
311 auto *const afterPairs = pairs + std::size(likely_subtags) / 2;
312 LikelyPair sought { *this };
313 // Our array is sorted in the order that puts all candidate matches in the
314 // order we would want them; ones we should prefer appear before the others.
315 if (language_id) {
316 // language_script_region, language_region, language_script, language:
317 pairs = std::lower_bound(pairs, afterPairs, sought);
318 // Single language's block isn't long enough to warrant more binary
319 // chopping within it - just traverse it all:
320 for (; pairs < afterPairs && pairs->key.language_id == language_id; ++pairs) {
321 const QLocaleId &key = pairs->key;
322 if (key.territory_id && key.territory_id != territory_id)
323 continue;
324 if (key.script_id && key.script_id != script_id)
325 continue;
326 QLocaleId value = pairs->value;
327 if (territory_id && !key.territory_id)
329 if (script_id && !key.script_id)
330 value.script_id = script_id;
331 return value;
332 }
333 }
334 // und_script_region or und_region (in that order):
335 if (territory_id) {
336 sought.key = QLocaleId { 0, script_id, territory_id };
337 pairs = std::lower_bound(pairs, afterPairs, sought);
338 // Again, individual und_?_region block isn't long enough to make binary
339 // chop a win:
340 for (; pairs < afterPairs && pairs->key.territory_id == territory_id; ++pairs) {
341 const QLocaleId &key = pairs->key;
342 Q_ASSERT(!key.language_id);
343 if (key.script_id && key.script_id != script_id)
344 continue;
345 QLocaleId value = pairs->value;
346 if (language_id)
348 if (script_id && !key.script_id)
349 value.script_id = script_id;
350 return value;
351 }
352 }
353 // und_script:
354 if (script_id) {
355 sought.key = QLocaleId { 0, script_id, 0 };
356 pairs = std::lower_bound(pairs, afterPairs, sought);
357 if (pairs < afterPairs && pairs->key.script_id == script_id) {
358 Q_ASSERT(!pairs->key.language_id && !pairs->key.territory_id);
359 QLocaleId value = pairs->value;
360 if (language_id)
362 if (territory_id)
363 value.territory_id = territory_id;
364 return value;
365 }
366 }
367 if (matchesAll()) { // Skipped all of the above.
368 // CLDR has no match-all at v37, but might get one some day ...
369 pairs = std::lower_bound(pairs, afterPairs, sought);
370 if (pairs < afterPairs) {
371 // All other keys are < match-all.
372 Q_ASSERT(pairs + 1 == afterPairs);
373 Q_ASSERT(pairs->key.matchesAll());
374 return pairs->value;
375 }
376 }
377 return *this;
378}
379
381{
383 // language
384 {
385 QLocaleId id { language_id, 0, 0 };
386 if (id.withLikelySubtagsAdded() == max)
387 return id;
388 }
389 // language_region
390 if (territory_id) {
392 if (id.withLikelySubtagsAdded() == max)
393 return id;
394 }
395 // language_script
396 if (script_id) {
398 if (id.withLikelySubtagsAdded() == max)
399 return id;
400 }
401 return max;
402}
403
404QByteArray QLocaleId::name(char separator) const
405{
407 return QByteArray();
408 if (language_id == QLocale::C)
409 return QByteArrayLiteral("C");
410
412 AlphaCode lang;
413 qsizetype langLen;
414
415 if (language.part1.isValid()) {
416 lang = language.part1;
417 langLen = 2;
418 } else {
419 lang = language.part2B.isValid() ? language.part2B : language.part3;
420 langLen = 3;
421 }
422
423 const unsigned char *script =
425 const unsigned char *country =
427 ? territory_code_list + 3 * territory_id : nullptr);
428 qsizetype len = langLen + (script ? 4 + 1 : 0) + (country ? (country[2] != 0 ? 3 : 2) + 1 : 0);
430 char *uc = name.data();
431
432 auto langArray = lang.decode();
433
434 *uc++ = langArray[0];
435 *uc++ = langArray[1];
436 if (langLen > 2)
437 *uc++ = langArray[2];
438
439 if (script) {
440 *uc++ = separator;
441 *uc++ = script[0];
442 *uc++ = script[1];
443 *uc++ = script[2];
444 *uc++ = script[3];
445 }
446 if (country) {
447 *uc++ = separator;
448 *uc++ = country[0];
449 *uc++ = country[1];
450 if (country[2] != 0)
451 *uc++ = country[2];
452 }
453 return name;
454}
455
457{
458 if (m_data->m_language_id == QLocale::AnyLanguage)
459 return QByteArray();
460 if (m_data->m_language_id == QLocale::C)
461 return QByteArrayLiteral("en");
462
463 return m_data->id().withLikelySubtagsRemoved().name(separator);
464}
465
467{
468 qsizetype idx = locale_index[localeId.language_id];
469 // If there are no locales for specified language (so we we've got the
470 // default language, which has no associated script or country), give up:
471 if (localeId.language_id && idx == 0)
472 return idx;
473
474 Q_ASSERT(localeId.acceptLanguage(locale_data[idx].m_language_id));
475
476 do {
477 if (localeId.acceptScriptTerritory(locale_data[idx].id()))
478 return idx;
479 ++idx;
480 } while (localeId.acceptLanguage(locale_data[idx].m_language_id));
481
482 return -1;
483}
484
486{
487 QLocaleId localeId = lid;
488 QLocaleId likelyId = localeId.withLikelySubtagsAdded();
489 const ushort fallback = likelyId.language_id;
490
491 // Try a straight match with the likely data:
493 if (index >= 0)
494 return index;
496 tried.push_back(likelyId);
497
498#define CheckCandidate(id) do { \
499 if (!tried.contains(id)) { \
500 index = findLocaleIndexById(id); \
501 if (index >= 0) \
502 return index; \
503 tried.push_back(id); \
504 } \
505 } while (false) // end CheckCandidate
506
507 // No match; try again with raw data:
508 CheckCandidate(localeId);
509
510 // No match; try again with likely country for language_script
511 if (lid.territory_id && (lid.language_id || lid.script_id)) {
512 localeId.territory_id = 0;
513 likelyId = localeId.withLikelySubtagsAdded();
514 CheckCandidate(likelyId);
515
516 // No match; try again with any country
517 CheckCandidate(localeId);
518 }
519
520 // No match; try again with likely script for language_region
521 if (lid.script_id && (lid.language_id || lid.territory_id)) {
522 localeId = QLocaleId { lid.language_id, 0, lid.territory_id };
523 likelyId = localeId.withLikelySubtagsAdded();
524 CheckCandidate(likelyId);
525
526 // No match; try again with any script
527 CheckCandidate(localeId);
528 }
529#undef CheckCandidate
530
531 // No match; return base index for initial likely language:
532 return locale_index[fallback];
533}
534
536{
537 const std::u16string_view v(name.utf16(), size_t(name.size()));
538 const auto i = v.find_first_of(u"_-.@");
539 if (i == std::string_view::npos)
540 return name;
541 return name.first(qsizetype(i));
542}
543
545{
546 // Is tag is a non-empty sequence of ASCII letters and/or digits ?
547 for (QChar uc : tag) {
548 const char16_t ch = uc.unicode();
550 return false;
551 }
552 return tag.size() > 0;
553}
554
556{
557 // Every script name is 4 characters, a capital followed by three lower-case;
558 // so a search for tag in allScripts *can* only match if it's aligned.
559 static const QString allScripts =
560 QString::fromLatin1(reinterpret_cast<const char *>(script_code_list),
561 sizeof(script_code_list) - 1);
562 return tag.size() == 4 && allScripts.indexOf(tag) % 4 == 0;
563}
564
566{
567 // Assume each of lang, script and land is nullptr or points to an empty QStringView.
568 enum ParserState { NoState, LangState, ScriptState, CountryState };
569 ParserState state = LangState;
570 while (name.size() && state != NoState) {
571 const QStringView tag = findTag(name);
572 if (!validTag(tag))
573 break;
574 name = name.sliced(tag.size());
575 const bool sep = name.size() > 0;
576 if (sep) // tag wasn't all that remained; there was a separator
577 name = name.sliced(1);
578
579 switch (state) {
580 case LangState:
581 if (tag.size() != 2 && tag.size() != 3)
582 return false;
583 if (lang)
584 *lang = tag;
585 state = sep ? ScriptState : NoState;
586 break;
587 case ScriptState:
588 if (isScript(tag)) {
589 if (script)
590 *script = tag;
591 state = sep ? CountryState : NoState;
592 break;
593 }
594 // It wasn't a script, assume it's a country.
596 case CountryState:
597 if (land)
598 *land = tag;
599 state = NoState;
600 break;
601 case NoState: // Precluded by loop condition !
602 Q_UNREACHABLE();
603 break;
604 }
605 }
606 return state != LangState;
607}
608
610{
611 QStringView lang;
612 QStringView script;
613 QStringView land;
614 if (!qt_splitLocaleName(name, &lang, &script, &land))
615 return { QLocale::C, 0, 0 };
616
618 if (langId == QLocale::AnyLanguage)
619 return { QLocale::C, 0, 0 };
620 return { langId, QLocalePrivate::codeToScript(script), QLocalePrivate::codeToTerritory(land) };
621}
622
624{
625 qsizetype &i = *idx;
626
627 Q_ASSERT(format.at(i) == u'\'');
628 ++i;
629 if (i == format.size())
630 return QString();
631 if (format.at(i).unicode() == '\'') { // "''" outside of a quoted string
632 ++i;
633 return "'"_L1;
634 }
635
637
638 while (i < format.size()) {
639 if (format.at(i).unicode() == '\'') {
640 if (format.mid(i + 1).startsWith(u'\'')) {
641 // "''" inside a quoted string
642 result.append(u'\'');
643 i += 2;
644 } else {
645 break;
646 }
647 } else {
648 result.append(format.at(i++));
649 }
650 }
651 if (i < format.size())
652 ++i;
653
654 return result;
655}
656
674{
675 if (s.isEmpty())
676 return 0;
677 const QChar c = s.front();
678 qsizetype j = 1;
679 while (j < s.size() && s.at(j) == c)
680 ++j;
681 return j;
682}
683
684Q_CONSTINIT static const QLocaleData *default_data = nullptr;
685
687{
689 return &c_locale;
690}
691
692#ifndef QT_NO_SYSTEMLOCALE
693/******************************************************************************
694** Default system locale behavior
695*/
696
718{
719 _systemLocale = this;
720
721 systemLocaleData.m_language_id = 0;
722}
723
729{
730 if (_systemLocale == this) {
731 _systemLocale = next;
732
733 // Change to system locale => force refresh.
734 systemLocaleData.m_language_id = 0;
735 } else {
736 for (QSystemLocale *p = _systemLocale; p; p = p->next) {
737 if (p->next == this)
738 p->next = next;
739 }
740 }
741}
742
744{
745 if (_systemLocale)
746 return _systemLocale;
747
748 // As this is only ever instantiated with _systemLocale null, it is
749 // necessarily the ->next-most in any chain that may subsequently develop;
750 // and it won't be destructed until exit()-time.
751 static QSystemLocale globalInstance;
752 return &globalInstance;
753}
754
756{
757 // This function is NOT thread-safe!
758 // It *should not* be called by anything but systemData()
759 // It *is* called before {system,default}LocalePrivate exist.
760 const QSystemLocale *sys_locale = systemLocale();
761
762 // tell the object that the system locale has changed.
764
765 // Populate system locale with fallback as basis
767
769 if (!res.isNull()) {
770 systemLocaleData.m_language_id = res.toInt();
771 systemLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
772 }
773 res = sys_locale->query(QSystemLocale::TerritoryId);
774 if (!res.isNull()) {
775 systemLocaleData.m_territory_id = res.toInt();
776 systemLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
777 }
778 res = sys_locale->query(QSystemLocale::ScriptId);
779 if (!res.isNull())
780 systemLocaleData.m_script_id = res.toInt();
781
782 // Should we replace Any values based on likely sub-tags ?
783}
784#endif // !QT_NO_SYSTEMLOCALE
785
786static const QLocaleData *systemData()
787{
788#ifndef QT_NO_SYSTEMLOCALE
789 /*
790 Copy over the information from the fallback locale and modify.
791
792 This modifies (cross-thread) global state, so take care to only call it in
793 one thread.
794 */
795 {
796 Q_CONSTINIT static QBasicMutex systemDataMutex;
797 systemDataMutex.lock();
798 if (systemLocaleData.m_language_id == 0)
800 systemDataMutex.unlock();
801 }
802
803 return &systemLocaleData;
804#else
805 return locale_data;
806#endif
807}
808
810{
811 if (!default_data)
813 return default_data;
814}
815
817{
818 const QLocaleData *const data = defaultData();
819#ifndef QT_NO_SYSTEMLOCALE
820 if (data == &systemLocaleData) {
821 // Work out a suitable index matching the system data, for use when
822 // accessing calendar data, when not fetched from system.
824 }
825#endif
826
828 Q_ASSERT(q_points_into_range(data, locale_data));
829 return data - locale_data;
830}
831
833{
835 return locale_data;
836}
837
838#ifndef QT_NO_DATASTREAM
840{
841 ds << l.name();
842 return ds;
843}
844
846{
847 QString s;
848 ds >> s;
849 l = QLocale(s);
850 return ds;
851}
852#endif // QT_NO_DATASTREAM
853
854static constexpr qsizetype locale_data_size = q20::ssize(locale_data) - 1; // trailing guard
855
859
860static QLocalePrivate *localePrivateByName(QStringView name)
861{
862 if (name == u"C")
863 return c_private();
867 locale_data[index].m_language_id == QLocale::C
869}
870
872 QLocale::Territory territory)
873{
874 if (language == QLocale::C)
875 return c_private();
876
880
881 QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
882
883 // If not found, should use default locale:
884 if (data->m_language_id == QLocale::C) {
885 if (defaultLocalePrivate.exists())
886 numberOptions = defaultLocalePrivate->data()->m_numberOptions;
887 data = defaultData();
889 }
890 return new QLocalePrivate(data, index, numberOptions);
891}
892
893static std::optional<QString>
895{
896#ifndef QT_NO_SYSTEMLOCALE
897 if (that != &systemLocaleData)
898 return std::nullopt;
899
901 if (v.metaType() != QMetaType::fromType<QString>())
902 return std::nullopt;
903
904 return v.toString();
905#else
906 Q_UNUSED(that)
908 return std::nullopt;
909#endif
910}
911
914{
915 if (auto opt = systemLocaleString(that, type))
916 return *opt;
917 return range.getData(single_character_data);
918}
919
921{
922 return localeString(this, QSystemLocale::DecimalPoint, decimalSeparator());
923}
924
926{
927 return localeString(this, QSystemLocale::GroupSeparator, groupDelim());
928}
929
931{
932 return percent().getData(single_character_data);
933}
934
936{
937 return listDelimit().getData(single_character_data);
938}
939
941{
943}
944
945char32_t QLocaleData::zeroUcs() const
946{
947#ifndef QT_NO_SYSTEMLOCALE
948 if (this == &systemLocaleData) {
950 if (!text.isEmpty()) {
951 if (text.size() == 1 && !text.at(0).isSurrogate())
952 return text.at(0).unicode();
953 if (text.size() == 2 && text.at(0).isHighSurrogate())
954 return QChar::surrogateToUcs4(text.at(0), text.at(1));
955 }
956 }
957#endif
958 return zero().ucsFirst(single_character_data);
959}
960
962{
963 return localeString(this, QSystemLocale::NegativeSign, minus());
964}
965
967{
968 return localeString(this, QSystemLocale::PositiveSign, plus());
969}
970
972{
973 return exponential().getData(single_character_data);
974}
975
980 : d(&dd)
981{}
982
983
1014 : d(localePrivateByName(name))
1015{
1016}
1017
1033 : d(*defaultLocalePrivate)
1034{
1035 // Make sure system data is up to date:
1036 systemData();
1037}
1038
1052 : d(findLocalePrivate(language, QLocale::AnyScript, territory))
1053{
1054}
1055
1076 : d(findLocalePrivate(language, script, territory))
1077{
1078}
1079
1084QLocale::QLocale(const QLocale &other) noexcept = default;
1085
1091{
1092}
1093
1099QLocale &QLocale::operator=(const QLocale &other) noexcept = default;
1100
1106bool QLocale::equals(const QLocale &other) const
1107{
1108 return d->m_data == other.d->m_data && d->m_numberOptions == other.d->m_numberOptions;
1109}
1110
1126size_t qHash(const QLocale &key, size_t seed) noexcept
1127{
1128 return qHashMulti(seed, key.d->m_data, key.d->m_numberOptions);
1129}
1130
1139void QLocale::setNumberOptions(NumberOptions options)
1140{
1141 d->m_numberOptions = options;
1142}
1143
1155QLocale::NumberOptions QLocale::numberOptions() const
1156{
1157 return static_cast<NumberOptions>(d->m_numberOptions);
1158}
1159
1175{
1176#ifndef QT_NO_SYSTEMLOCALE
1177 if (d->m_data == &systemLocaleData) {
1178 QVariant res;
1179 if (style == QLocale::AlternateQuotation)
1182 if (res.isNull() || style == QLocale::StandardQuotation)
1185 if (!res.isNull())
1186 return res.toString();
1187 }
1188#endif
1189
1191 if (style == QLocale::StandardQuotation) {
1192 start = d->m_data->quoteStart();
1193 end = d->m_data->quoteEnd();
1194 } else {
1195 start = d->m_data->quoteStartAlternate();
1196 end = d->m_data->quoteEndAlternate();
1197 }
1198
1199 return start.viewData(single_character_data) % str % end.viewData(single_character_data);
1200}
1201
1209{
1210 // May be empty if list is empty or sole entry is empty.
1211#ifndef QT_NO_SYSTEMLOCALE
1212 if (d->m_data == &systemLocaleData) {
1213 QVariant res =
1215
1216 if (!res.isNull())
1217 return res.toString();
1218 }
1219#endif
1220
1221 const qsizetype size = list.size();
1222 if (size < 1)
1223 return QString();
1224
1225 if (size == 1)
1226 return list.at(0);
1227
1228 if (size == 2)
1229 return d->m_data->pairListPattern().getData(
1230 list_pattern_part_data).arg(list.at(0), list.at(1));
1231
1232 QStringView formatStart = d->m_data->startListPattern().viewData(list_pattern_part_data);
1233 QStringView formatMid = d->m_data->midListPattern().viewData(list_pattern_part_data);
1234 QStringView formatEnd = d->m_data->endListPattern().viewData(list_pattern_part_data);
1235 QString result = formatStart.arg(list.at(0), list.at(1));
1236 for (qsizetype i = 2; i < size - 1; ++i)
1237 result = formatMid.arg(result, list.at(i));
1238 result = formatEnd.arg(result, list.at(size - 1));
1239 return result;
1240}
1241
1257void QLocale::setDefault(const QLocale &locale)
1258{
1259 default_data = locale.d->m_data;
1260
1261 if (defaultLocalePrivate.isDestroyed())
1262 return; // avoid crash on exit
1263 if (!defaultLocalePrivate.exists()) {
1264 // Force it to exist; see QTBUG-83016
1265 QLocale ignoreme;
1266 Q_ASSERT(defaultLocalePrivate.exists());
1267 }
1268
1269 // update the cached private
1270 *defaultLocalePrivate = locale.d;
1272}
1273
1280{
1281 return Language(d->languageId());
1282}
1283
1292{
1293 return Script(d->m_data->m_script_id);
1294}
1295
1304{
1305 return Territory(d->territoryId());
1306}
1307
1308#if QT_DEPRECATED_SINCE(6, 6)
1316QLocale::Country QLocale::country() const
1317{
1318 return territory();
1319}
1320#endif
1321
1341{
1342 const auto code = d->languageCode();
1343 QLatin1StringView view{code.data()};
1344
1345 Language l = language();
1346 if (l == C)
1347 return view;
1348
1349 Territory c = territory();
1350 if (c == AnyTerritory)
1351 return view;
1352
1353 return view + u'_' + d->territoryCode();
1354}
1355
1356template <typename T> static inline
1358{
1359 constexpr bool isUnsigned = std::is_unsigned_v<T>;
1360 using Int64 = typename std::conditional_t<isUnsigned, quint64, qint64>;
1361
1362 Int64 val = 0;
1363 if constexpr (isUnsigned)
1364 val = d->m_data->stringToUnsLongLong(str, 10, ok, d->m_numberOptions);
1365 else
1366 val = d->m_data->stringToLongLong(str, 10, ok, d->m_numberOptions);
1367
1368 if (T(val) != val) {
1369 if (ok != nullptr)
1370 *ok = false;
1371 val = 0;
1372 }
1373 return T(val);
1374}
1375
1376
1398{
1399 return QString::fromLatin1(d->bcp47Name());
1400}
1401
1421{
1422 const auto code = QLocalePrivate::languageToCode(language, codeTypes);
1423 return QLatin1StringView{code.data()};
1424}
1425
1441 LanguageCodeTypes codeTypes) noexcept
1442{
1443 return QLocalePrivate::codeToLanguage(languageCode, codeTypes);
1444}
1445
1457{
1459}
1460
1472{
1473 return QLocalePrivate::codeToTerritory(territoryCode);
1474}
1475
1476#if QT_DEPRECATED_SINCE(6, 6)
1487QString QLocale::countryToCode(Country country)
1488{
1489 return territoryToCode(country);
1490}
1491
1502QLocale::Country QLocale::codeToCountry(QStringView countryCode) noexcept
1503{
1504 return QLocalePrivate::codeToTerritory(countryCode);
1505}
1506#endif
1507
1518{
1520}
1521
1532{
1533 return QLocalePrivate::codeToScript(scriptCode);
1534}
1535
1543{
1545 return "Unknown"_L1;
1547}
1548
1557{
1559 return "Unknown"_L1;
1561}
1562
1563#if QT_DEPRECATED_SINCE(6, 6)
1571QString QLocale::countryToString(Country country)
1572{
1573 return territoryToString(country);
1574}
1575#endif
1576
1585{
1587 return "Unknown"_L1;
1589}
1590
1764{
1765 return toIntegral_helper<short>(d, s, ok);
1766}
1767
1784{
1785 return toIntegral_helper<ushort>(d, s, ok);
1786}
1787
1804{
1805 return toIntegral_helper<int>(d, s, ok);
1806}
1807
1824{
1825 return toIntegral_helper<uint>(d, s, ok);
1826}
1827
1843{
1844 return toIntegral_helper<long>(d, s, ok);
1845}
1846
1863{
1864 return toIntegral_helper<ulong>(d, s, ok);
1865}
1866
1884{
1885 return toIntegral_helper<qlonglong>(d, s, ok);
1886}
1887
1905{
1906 return toIntegral_helper<qulonglong>(d, s, ok);
1907}
1908
1926{
1928}
1929
1951double QLocale::toDouble(QStringView s, bool *ok) const
1952{
1953 return d->m_data->stringToDouble(s, ok, d->m_numberOptions);
1954}
1955
1963{
1966
1967 return d->m_data->longLongToString(i, -1, 10, -1, flags);
1968}
1969
1977{
1980
1981 return d->m_data->unsLongLongToString(i, -1, 10, -1, flags);
1982}
1983
1993{
1995}
1996
2006{
2008}
2009
2031{
2032 return cal.dateTimeToString(format, QDateTime(), date, QTime(), *this);
2033}
2034
2040{
2041 return QCalendar().dateTimeToString(format, QDateTime(), date, QTime(), *this);
2042}
2043
2055{
2056 if (!date.isValid())
2057 return QString();
2058
2059#ifndef QT_NO_SYSTEMLOCALE
2060 if (cal.isGregorian() && d->m_data == &systemLocaleData) {
2064 date);
2065 if (!res.isNull())
2066 return res.toString();
2067 }
2068#endif
2069
2070 QString format_str = dateFormat(format);
2071 return toString(date, format_str, cal);
2072}
2073
2079{
2080 if (!date.isValid())
2081 return QString();
2082
2083#ifndef QT_NO_SYSTEMLOCALE
2084 if (d->m_data == &systemLocaleData) {
2088 date);
2089 if (!res.isNull())
2090 return res.toString();
2091 }
2092#endif
2093
2094 QString format_str = dateFormat(format);
2095 return toString(date, format_str);
2096}
2097
2099{
2100 qsizetype i = 0;
2101 while (i < format.size()) {
2102 if (format.at(i).unicode() == '\'') {
2104 continue;
2105 }
2106
2107 if (format.at(i).toLower().unicode() == 'a')
2108 return true;
2109
2110 ++i;
2111 }
2112 return false;
2113}
2114
2125{
2126 return QCalendar().dateTimeToString(format, QDateTime(), QDate(), time, *this);
2127}
2128
2139{
2140 return cal.dateTimeToString(format, dateTime, QDate(), QTime(), *this);
2141}
2142
2148{
2149 return QCalendar().dateTimeToString(format, dateTime, QDate(), QTime(), *this);
2150}
2151
2163{
2164 if (!dateTime.isValid())
2165 return QString();
2166
2167#ifndef QT_NO_SYSTEMLOCALE
2168 if (cal.isGregorian() && d->m_data == &systemLocaleData) {
2172 dateTime);
2173 if (!res.isNull())
2174 return res.toString();
2175 }
2176#endif
2177
2178 const QString format_str = dateTimeFormat(format);
2179 return toString(dateTime, format_str, cal);
2180}
2181
2187{
2188 if (!dateTime.isValid())
2189 return QString();
2190
2191#ifndef QT_NO_SYSTEMLOCALE
2192 if (d->m_data == &systemLocaleData) {
2196 dateTime);
2197 if (!res.isNull())
2198 return res.toString();
2199 }
2200#endif
2201
2202 const QString format_str = dateTimeFormat(format);
2203 return toString(dateTime, format_str);
2204}
2205
2206
2213{
2214 if (!time.isValid())
2215 return QString();
2216
2217#ifndef QT_NO_SYSTEMLOCALE
2218 if (d->m_data == &systemLocaleData) {
2222 time);
2223 if (!res.isNull())
2224 return res.toString();
2225 }
2226#endif
2227
2228 QString format_str = timeFormat(format);
2229 return toString(time, format_str);
2230}
2231
2245{
2246#ifndef QT_NO_SYSTEMLOCALE
2247 if (d->m_data == &systemLocaleData) {
2251 QVariant());
2252 if (!res.isNull())
2253 return res.toString();
2254 }
2255#endif
2256
2257 return (format == LongFormat
2258 ? d->m_data->longDateFormat()
2259 : d->m_data->shortDateFormat()
2261}
2262
2276{
2277#ifndef QT_NO_SYSTEMLOCALE
2278 if (d->m_data == &systemLocaleData) {
2282 QVariant());
2283 if (!res.isNull())
2284 return res.toString();
2285 }
2286#endif
2287
2288 return (format == LongFormat
2289 ? d->m_data->longTimeFormat()
2290 : d->m_data->shortTimeFormat()
2292}
2293
2307{
2308#ifndef QT_NO_SYSTEMLOCALE
2309 if (d->m_data == &systemLocaleData) {
2313 QVariant());
2314 if (!res.isNull()) {
2315 return res.toString();
2316 }
2317 }
2318#endif
2319 return dateFormat(format) + u' ' + timeFormat(format);
2320}
2321
2322#if QT_CONFIG(datestring)
2338QTime QLocale::toTime(const QString &string, FormatType format) const
2339{
2340 return toTime(string, timeFormat(format));
2341}
2342
2358QDate QLocale::toDate(const QString &string, FormatType format) const
2359{
2360 return toDate(string, dateFormat(format));
2361}
2362
2367QDate QLocale::toDate(const QString &string, FormatType format, QCalendar cal) const
2368{
2369 return toDate(string, dateFormat(format), cal);
2370}
2371
2389QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
2390{
2391 return toDateTime(string, dateTimeFormat(format));
2392}
2393
2398QDateTime QLocale::toDateTime(const QString &string, FormatType format, QCalendar cal) const
2399{
2400 return toDateTime(string, dateTimeFormat(format), cal);
2401}
2402
2418QTime QLocale::toTime(const QString &string, const QString &format) const
2419{
2420 QTime time;
2421#if QT_CONFIG(datetimeparser)
2422 QDateTimeParser dt(QMetaType::QTime, QDateTimeParser::FromString, QCalendar());
2423 dt.setDefaultLocale(*this);
2424 if (dt.parseFormat(format))
2425 dt.fromString(string, nullptr, &time);
2426#else
2427 Q_UNUSED(string);
2429#endif
2430 return time;
2431}
2432
2448QDate QLocale::toDate(const QString &string, const QString &format) const
2449{
2450 return toDate(string, format, QCalendar());
2451}
2452
2457QDate QLocale::toDate(const QString &string, const QString &format, QCalendar cal) const
2458{
2459 QDate date;
2460#if QT_CONFIG(datetimeparser)
2461 QDateTimeParser dt(QMetaType::QDate, QDateTimeParser::FromString, cal);
2462 dt.setDefaultLocale(*this);
2463 if (dt.parseFormat(format))
2464 dt.fromString(string, &date, nullptr);
2465#else
2466 Q_UNUSED(string);
2468 Q_UNUSED(cal);
2469#endif
2470 return date;
2471}
2472
2494QDateTime QLocale::toDateTime(const QString &string, const QString &format) const
2495{
2496 return toDateTime(string, format, QCalendar());
2497}
2498
2503QDateTime QLocale::toDateTime(const QString &string, const QString &format, QCalendar cal) const
2504{
2505#if QT_CONFIG(datetimeparser)
2506 QDateTime datetime;
2507
2508 QDateTimeParser dt(QMetaType::QDateTime, QDateTimeParser::FromString, cal);
2509 dt.setDefaultLocale(*this);
2510 if (dt.parseFormat(format) && (dt.fromString(string, &datetime) || !datetime.isValid()))
2511 return datetime;
2512#else
2513 Q_UNUSED(string);
2515 Q_UNUSED(cal);
2516#endif
2517 return QDateTime();
2518}
2519#endif // datestring
2520
2536{
2537 return d->m_data->decimalPoint();
2538}
2539
2555{
2556 return d->m_data->groupSeparator();
2557}
2558
2572{
2573 return d->m_data->percentSign();
2574}
2575
2591{
2592 return d->m_data->zeroDigit();
2593}
2594
2608{
2609 return d->m_data->negativeSign();
2610}
2611
2625{
2626 return d->m_data->positiveSign();
2627}
2628
2643{
2644 return d->m_data->exponentSeparator();
2645}
2646
2682{
2685
2687 case 'f':
2689 break;
2690 case 'e':
2692 break;
2693 case 'g':
2695 break;
2696 default:
2697 break;
2698 }
2699
2706 return d->m_data->doubleToString(f, precision, form, -1, flags);
2707}
2708
2743{
2744 QT_PREPEND_NAMESPACE(systemData)(); // Ensure system data is up to date.
2746
2747 return QLocale(locale);
2748}
2749
2763 QLocale::Territory territory)
2764{
2766 if (!filter.isValid())
2767 return QList<QLocale>();
2768
2769 if (language == QLocale::C)
2770 return QList<QLocale>() << QLocale(QLocale::C);
2771
2773 if (filter.matchesAll())
2774 result.reserve(locale_data_size);
2775
2777 // There may be no matches, for some languages (e.g. Abkhazian at CLDR v39).
2778 while (filter.acceptLanguage(locale_data[index].m_language_id)) {
2779 const QLocaleId id = locale_data[index].id();
2780 if (filter.acceptScriptTerritory(id)) {
2781 result.append(QLocale(*(id.language_id == C ? c_private()
2783 }
2784 ++index;
2785 }
2786
2787 // Add current system locale, if it matches
2788 const auto syslocaledata = systemData();
2789
2790 if (filter.acceptLanguage(syslocaledata->m_language_id)) {
2791 const QLocaleId id = syslocaledata->id();
2792 if (filter.acceptScriptTerritory(id))
2793 result.append(QLocale::system());
2794 }
2795
2796 return result;
2797}
2798
2799#if QT_DEPRECATED_SINCE(6, 6)
2810QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
2811{
2812 const auto locales = matchingLocales(language, AnyScript, AnyCountry);
2814 result.reserve(locales.size());
2815 for (const auto &locale : locales)
2816 result.append(locale.territory());
2817 return result;
2818}
2819#endif
2820
2834{
2835 return QCalendar().monthName(*this, month, QCalendar::Unspecified, type);
2836}
2837
2850{
2852}
2853
2868{
2869 return QCalendar().weekDayName(*this, day, type);
2870}
2871
2885{
2886 return QCalendar().standaloneWeekDayName(*this, day, type);
2887}
2888
2889// Calendar look-up of month and day names:
2890
2895static QString rawMonthName(const QCalendarLocale &localeData,
2896 const char16_t *monthsData, int month,
2898{
2900 switch (type) {
2902 range = localeData.longMonth();
2903 break;
2905 range = localeData.shortMonth();
2906 break;
2908 range = localeData.narrowMonth();
2909 break;
2910 default:
2911 return QString();
2912 }
2913 return range.getListEntry(monthsData, month - 1);
2914}
2915
2921 const char16_t *monthsData, int month,
2923{
2925 switch (type) {
2927 range = localeData.longMonthStandalone();
2928 break;
2930 range = localeData.shortMonthStandalone();
2931 break;
2933 range = localeData.narrowMonthStandalone();
2934 break;
2935 default:
2936 return QString();
2937 }
2938 QString name = range.getListEntry(monthsData, month - 1);
2939 return name.isEmpty() ? rawMonthName(localeData, monthsData, month, type) : name;
2940}
2941
2946static QString rawWeekDayName(const QLocaleData *data, const int day,
2948{
2950 switch (type) {
2952 range = data->longDayNames();
2953 break;
2955 range = data->shortDayNames();
2956 break;
2958 range = data->narrowDayNames();
2959 break;
2960 default:
2961 return QString();
2962 }
2963 return range.getListEntry(days_data, day == 7 ? 0 : day);
2964}
2965
2972{
2974 switch (type) {
2976 range =data->longDayNamesStandalone();
2977 break;
2979 range = data->shortDayNamesStandalone();
2980 break;
2982 range = data->narrowDayNamesStandalone();
2983 break;
2984 default:
2985 return QString();
2986 }
2987 QString name = range.getListEntry(days_data, day == 7 ? 0 : day);
2988 if (name.isEmpty())
2989 return rawWeekDayName(data, day, type);
2990 return name;
2991}
2992
2993// Refugees from qcalendar.cpp that need functions above:
2994
2995QString QCalendarBackend::monthName(const QLocale &locale, int month, int,
2997{
2998 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
2999 return rawMonthName(localeMonthIndexData()[locale.d->m_index],
3000 localeMonthData(), month, format);
3001}
3002
3003QString QGregorianCalendar::monthName(const QLocale &locale, int month, int year,
3005{
3006#ifndef QT_NO_SYSTEMLOCALE
3007 if (locale.d->m_data == &systemLocaleData) {
3008 Q_ASSERT(month >= 1 && month <= 12);
3010 switch (format) {
3012 queryType = QSystemLocale::MonthNameLong;
3013 break;
3016 break;
3019 break;
3020 }
3021 QVariant res = systemLocale()->query(queryType, month);
3022 if (!res.isNull())
3023 return res.toString();
3024 }
3025#endif
3026
3027 return QCalendarBackend::monthName(locale, month, year, format);
3028}
3029
3032{
3033 Q_ASSERT(month >= 1 && month <= maximumMonthsInYear());
3034 return rawStandaloneMonthName(localeMonthIndexData()[locale.d->m_index],
3035 localeMonthData(), month, format);
3036}
3037
3040{
3041#ifndef QT_NO_SYSTEMLOCALE
3042 if (locale.d->m_data == &systemLocaleData) {
3043 Q_ASSERT(month >= 1 && month <= 12);
3045 switch (format) {
3048 break;
3051 break;
3054 break;
3055 }
3056 QVariant res = systemLocale()->query(queryType, month);
3057 if (!res.isNull())
3058 return res.toString();
3059 }
3060#endif
3061
3062 return QCalendarBackend::standaloneMonthName(locale, month, year, format);
3063}
3064
3065// Most calendars share the common week-day naming, modulo locale.
3066// Calendars that don't must override these methods.
3069{
3070 if (day < 1 || day > 7)
3071 return QString();
3072
3073#ifndef QT_NO_SYSTEMLOCALE
3074 if (locale.d->m_data == &systemLocaleData) {
3076 switch (format) {
3078 queryType = QSystemLocale::DayNameLong;
3079 break;
3081 queryType = QSystemLocale::DayNameShort;
3082 break;
3084 queryType = QSystemLocale::DayNameNarrow;
3085 break;
3086 }
3087 QVariant res = systemLocale()->query(queryType, day);
3088 if (!res.isNull())
3089 return res.toString();
3090 }
3091#endif
3092
3093 return rawWeekDayName(locale.d->m_data, day, format);
3094}
3095
3098{
3099 if (day < 1 || day > 7)
3100 return QString();
3101
3102#ifndef QT_NO_SYSTEMLOCALE
3103 if (locale.d->m_data == &systemLocaleData) {
3105 switch (format) {
3108 break;
3111 break;
3114 break;
3115 }
3116 QVariant res = systemLocale()->query(queryType, day);
3117 if (!res.isNull())
3118 return res.toString();
3119 }
3120#endif
3121
3122 return rawStandaloneWeekDayName(locale.d->m_data, day, format);
3123}
3124
3125// End of this block of qcalendar.cpp refugees. (One more follows.)
3126
3133{
3134#ifndef QT_NO_SYSTEMLOCALE
3135 if (d->m_data == &systemLocaleData) {
3137 if (!res.isNull())
3138 return static_cast<Qt::DayOfWeek>(res.toUInt());
3139 }
3140#endif
3141 return static_cast<Qt::DayOfWeek>(d->m_data->m_first_day_of_week);
3142}
3143
3145{
3146 for (const auto &system : ImperialMeasurementSystems) {
3147 if (system.languageId == m_data->m_language_id
3148 && system.territoryId == m_data->m_territory_id) {
3149 return system.system;
3150 }
3151 }
3152 return QLocale::MetricSystem;
3153}
3154
3161{
3162#ifndef QT_NO_SYSTEMLOCALE
3163 if (d->m_data == &systemLocaleData) {
3164 auto res
3165 = qvariant_cast<QList<Qt::DayOfWeek> >(systemLocale()->query(QSystemLocale::Weekdays));
3166 if (!res.isEmpty())
3167 return res;
3168 }
3169#endif
3171 quint16 weekendStart = d->m_data->m_weekend_start;
3172 quint16 weekendEnd = d->m_data->m_weekend_end;
3173 for (int day = Qt::Monday; day <= Qt::Sunday; day++) {
3174 if ((weekendEnd >= weekendStart && (day < weekendStart || day > weekendEnd)) ||
3175 (weekendEnd < weekendStart && (day > weekendEnd && day < weekendStart)))
3176 weekdays << static_cast<Qt::DayOfWeek>(day);
3177 }
3178 return weekdays;
3179}
3180
3187{
3188#ifndef QT_NO_SYSTEMLOCALE
3189 if (d->m_data == &systemLocaleData) {
3191 if (!res.isNull())
3192 return MeasurementSystem(res.toInt());
3193 }
3194#endif
3195
3196 return d->measurementSystem();
3197}
3198
3205{
3206 switch (script()) {
3224 case QLocale::NkoScript:
3235 return Qt::RightToLeft;
3236 default:
3237 break;
3238 }
3239 return Qt::LeftToRight;
3240}
3241
3255{
3256#if QT_CONFIG(icu)
3257 bool ok = true;
3258 QString result = QIcu::toUpper(d->bcp47Name('_'), str, &ok);
3259 if (ok)
3260 return result;
3261 // else fall through and use Qt's toUpper
3262#endif
3263 return str.toUpper();
3264}
3265
3279{
3280#if QT_CONFIG(icu)
3281 bool ok = true;
3282 const QString result = QIcu::toLower(d->bcp47Name('_'), str, &ok);
3283 if (ok)
3284 return result;
3285 // else fall through and use Qt's toUpper
3286#endif
3287 return str.toLower();
3288}
3289
3290
3300{
3301#ifndef QT_NO_SYSTEMLOCALE
3302 if (d->m_data == &systemLocaleData) {
3304 if (!res.isEmpty())
3305 return res;
3306 }
3307#endif
3308 return d->m_data->anteMeridiem().getData(am_data);
3309}
3310
3320{
3321#ifndef QT_NO_SYSTEMLOCALE
3322 if (d->m_data == &systemLocaleData) {
3324 if (!res.isEmpty())
3325 return res;
3326 }
3327#endif
3328 return d->m_data->postMeridiem().getData(pm_data);
3329}
3330
3331// Another intrusion from QCalendar, using some of the tools above:
3332
3334 QDate dateOnly, QTime timeOnly,
3335 const QLocale &locale) const
3336{
3337 QDate date;
3338 QTime time;
3339 bool formatDate = false;
3340 bool formatTime = false;
3341 if (datetime.isValid()) {
3342 date = datetime.date();
3343 time = datetime.time();
3344 formatDate = true;
3345 formatTime = true;
3346 } else if (dateOnly.isValid()) {
3347 date = dateOnly;
3348 formatDate = true;
3349 } else if (timeOnly.isValid()) {
3350 time = timeOnly;
3351 formatTime = true;
3352 } else {
3353 return QString();
3354 }
3355
3357 int year = 0, month = 0, day = 0;
3358 if (formatDate) {
3359 const auto parts = julianDayToDate(date.toJulianDay());
3360 if (!parts.isValid())
3361 return QString();
3362 year = parts.year;
3363 month = parts.month;
3364 day = parts.day;
3365 }
3366
3367 auto appendToResult = [&](int t, int repeat) {
3368 auto data = locale.d->m_data;
3369 if (repeat > 1)
3370 result.append(data->longLongToString(t, -1, 10, repeat, QLocaleData::ZeroPadded));
3371 else
3372 result.append(data->longLongToString(t));
3373 };
3374
3375 auto formatType = [](int repeat) {
3376 return repeat == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
3377 };
3378
3379 qsizetype i = 0;
3380 while (i < format.size()) {
3381 if (format.at(i).unicode() == '\'') {
3383 continue;
3384 }
3385
3386 const QChar c = format.at(i);
3387 qsizetype rep = qt_repeatCount(format.mid(i));
3388 Q_ASSERT(rep < std::numeric_limits<int>::max());
3389 int repeat = int(rep);
3390 bool used = false;
3391 if (formatDate) {
3392 switch (c.unicode()) {
3393 case 'y':
3394 used = true;
3395 if (repeat >= 4)
3396 repeat = 4;
3397 else if (repeat >= 2)
3398 repeat = 2;
3399
3400 switch (repeat) {
3401 case 4:
3402 appendToResult(year, (year < 0) ? 5 : 4);
3403 break;
3404 case 2:
3405 appendToResult(year % 100, 2);
3406 break;
3407 default:
3408 repeat = 1;
3409 result.append(c);
3410 break;
3411 }
3412 break;
3413
3414 case 'M':
3415 used = true;
3416 repeat = qMin(repeat, 4);
3417 if (repeat <= 2)
3418 appendToResult(month, repeat);
3419 else
3420 result.append(monthName(locale, month, year, formatType(repeat)));
3421 break;
3422
3423 case 'd':
3424 used = true;
3425 repeat = qMin(repeat, 4);
3426 if (repeat <= 2)
3427 appendToResult(day, repeat);
3428 else
3429 result.append(
3430 locale.dayName(dayOfWeek(date.toJulianDay()), formatType(repeat)));
3431 break;
3432
3433 default:
3434 break;
3435 }
3436 }
3437 if (!used && formatTime) {
3438 switch (c.unicode()) {
3439 case 'h': {
3440 used = true;
3441 repeat = qMin(repeat, 2);
3442 int hour = time.hour();
3444 if (hour > 12)
3445 hour -= 12;
3446 else if (hour == 0)
3447 hour = 12;
3448 }
3449 appendToResult(hour, repeat);
3450 break;
3451 }
3452 case 'H':
3453 used = true;
3454 repeat = qMin(repeat, 2);
3455 appendToResult(time.hour(), repeat);
3456 break;
3457
3458 case 'm':
3459 used = true;
3460 repeat = qMin(repeat, 2);
3461 appendToResult(time.minute(), repeat);
3462 break;
3463
3464 case 's':
3465 used = true;
3466 repeat = qMin(repeat, 2);
3467 appendToResult(time.second(), repeat);
3468 break;
3469
3470 case 'A':
3471 case 'a': {
3472 QString text = time.hour() < 12 ? locale.amText() : locale.pmText();
3473 used = true;
3474 repeat = 1;
3475 if (format.mid(i + 1).startsWith(u'p', Qt::CaseInsensitive))
3476 ++repeat;
3477 if (c.unicode() == 'A' && (repeat == 1 || format.at(i + 1).unicode() == 'P'))
3478 text = std::move(text).toUpper();
3479 else if (c.unicode() == 'a' && (repeat == 1 || format.at(i + 1).unicode() == 'p'))
3480 text = std::move(text).toLower();
3481 // else 'Ap' or 'aP' => use CLDR text verbatim, preserving case
3483 break;
3484 }
3485
3486 case 'z':
3487 used = true;
3488 repeat = qMin(repeat, 3);
3489
3490 // note: the millisecond component is treated like the decimal part of the seconds
3491 // so ms == 2 is always printed as "002", but ms == 200 can be either "2" or "200"
3492 appendToResult(time.msec(), 3);
3493 if (repeat != 3) {
3494 if (result.endsWith(locale.zeroDigit()))
3495 result.chop(1);
3496 if (result.endsWith(locale.zeroDigit()))
3497 result.chop(1);
3498 }
3499 break;
3500
3501 case 't': {
3502 used = true;
3503 repeat = qMin(repeat, 4);
3504 // If we don't have a date-time, use the current system time:
3505 const QDateTime when = formatDate ? datetime : QDateTime::currentDateTime();
3506 QString text;
3507 switch (repeat) {
3508#if QT_CONFIG(timezone)
3509 case 4:
3510 text = when.timeZone().displayName(when, QTimeZone::LongName);
3511 break;
3512#endif // timezone
3513 case 3:
3514 case 2:
3516 // If the offset is UTC that'll be a Qt::UTC, otherwise Qt::OffsetFromUTC.
3517 Q_ASSERT(text.startsWith("UTC"_L1));
3518 // The Qt::UTC case omits the zero offset, which we want:
3519 text = text.size() == 3 ? u"+00:00"_s : text.sliced(3);
3520 if (repeat == 2) // +hhmm format, rather than +hh:mm format
3521 text = text.remove(u':');
3522 break;
3523 default:
3524 text = when.timeZoneAbbreviation();
3525 break;
3526 }
3527 if (!text.isEmpty())
3529 break;
3530 }
3531
3532 default:
3533 break;
3534 }
3535 }
3536 if (!used)
3537 result.resize(result.size() + repeat, c);
3538 i += repeat;
3539 }
3540
3541 return result;
3542}
3543
3544// End of QCalendar intrustions
3545
3547 int width, unsigned flags) const
3548{
3549 // Although the special handling of F.P.Shortest below is limited to
3550 // DFSignificantDigits, the double-conversion library does treat it
3551 // specially for the other forms, shedding trailing zeros for DFDecimal and
3552 // using the shortest mantissa that faithfully represents the value for
3553 // DFExponent.
3555 precision = 6;
3556 if (width < 0)
3557 width = 0;
3558
3559 int decpt;
3560 qsizetype bufSize = 1;
3562 bufSize += std::numeric_limits<double>::max_digits10;
3563 else if (form == DFDecimal && qIsFinite(d))
3565 else // Add extra digit due to different interpretations of precision.
3566 bufSize += qMax(2, precision) + 1; // Must also be big enough for "nan" or "inf"
3567
3569 int length;
3570 bool negative = false;
3571 qt_doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
3572
3573 const QString prefix = signPrefix(negative && !isZero(d), flags);
3574 QString numStr;
3575
3576 if (length == 3
3577 && (qstrncmp(buf.data(), "inf", 3) == 0 || qstrncmp(buf.data(), "nan", 3) == 0)) {
3578 numStr = QString::fromLatin1(buf.data(), length);
3579 } else { // Handle finite values
3580 const QString zero = zeroDigit();
3582
3583 if (zero == u"0") {
3584 // No need to convert digits.
3585 Q_ASSERT(std::all_of(buf.cbegin(), buf.cbegin() + length, isAsciiDigit));
3586 // That check is taken care of in unicodeForDigits, below.
3587 } else if (zero.size() == 2 && zero.at(0).isHighSurrogate()) {
3588 const char32_t zeroUcs4 = QChar::surrogateToUcs4(zero.at(0), zero.at(1));
3589 QString converted;
3590 converted.reserve(2 * digits.size());
3591 for (QChar ch : std::as_const(digits)) {
3592 const char32_t digit = unicodeForDigit(ch.unicode() - '0', zeroUcs4);
3594 converted.append(QChar::highSurrogate(digit));
3595 converted.append(QChar::lowSurrogate(digit));
3596 }
3597 digits = converted;
3598 } else {
3599 Q_ASSERT(zero.size() == 1);
3600 Q_ASSERT(!zero.at(0).isSurrogate());
3601 char16_t z = zero.at(0).unicode();
3602 char16_t *const value = reinterpret_cast<char16_t *>(digits.data());
3603 for (qsizetype i = 0; i < digits.size(); ++i)
3604 value[i] = unicodeForDigit(value[i] - '0', z);
3605 }
3606
3607 const bool mustMarkDecimal = flags & ForcePoint;
3608 const bool groupDigits = flags & GroupDigits;
3609 const int minExponentDigits = flags & ZeroPadExponent ? 2 : 1;
3610 switch (form) {
3611 case DFExponent:
3612 numStr = exponentForm(std::move(digits), decpt, precision, PMDecimalDigits,
3613 mustMarkDecimal, minExponentDigits);
3614 break;
3615 case DFDecimal:
3616 numStr = decimalForm(std::move(digits), decpt, precision, PMDecimalDigits,
3617 mustMarkDecimal, groupDigits);
3618 break;
3619 case DFSignificantDigits: {
3620 PrecisionMode mode
3621 = (flags & AddTrailingZeroes) ? PMSignificantDigits : PMChopTrailingZeros;
3622
3623 /* POSIX specifies sprintf() to follow fprintf(), whose 'g/G' format
3624 says; with P = 6 if precision unspecified else 1 if precision is
3625 0 else precision; when 'e/E' would have exponent X, use:
3626 * 'f/F' if P > X >= -4, with precision P-1-X
3627 * 'e/E' otherwise, with precision P-1
3628 Helpfully, we already have mapped precision < 0 to 6 - except for
3629 F.P.Shortest mode, which is its own story - and those of our
3630 callers with unspecified precision either used 6 or -1 for it.
3631 */
3632 bool useDecimal;
3634 // Find out which representation is shorter.
3635 // Set bias to everything added to exponent form but not
3636 // decimal, minus the converse.
3637
3638 // Exponent adds separator, sign and digits:
3639 int bias = 2 + minExponentDigits;
3640 // Decimal form may get grouping separators inserted:
3641 if (groupDigits && decpt >= m_grouping_top + m_grouping_least)
3643 // X = decpt - 1 needs two digits if decpt > 10:
3644 if (decpt > 10 && minExponentDigits == 1)
3645 ++bias;
3646 // Assume digitCount < 95, so we can ignore the 3-digit
3647 // exponent case (we'll set useDecimal false anyway).
3648
3649 const qsizetype digitCount = digits.size() / zero.size();
3650 if (!mustMarkDecimal) {
3651 // Decimal separator is skipped if at end; adjust if
3652 // that happens for only one form:
3653 if (digitCount <= decpt && digitCount > 1)
3654 ++bias; // decimal but not exponent
3655 else if (digitCount == 1 && decpt <= 0)
3656 --bias; // exponent but not decimal
3657 }
3658 // When 0 < decpt <= digitCount, the forms have equal digit
3659 // counts, plus things bias has taken into account; otherwise
3660 // decimal form's digit count is right-padded with zeros to
3661 // decpt, when decpt is positive, otherwise it's left-padded
3662 // with 1 - decpt zeros.
3663 useDecimal = (decpt <= 0 ? 1 - decpt <= bias
3664 : decpt <= digitCount ? 0 <= bias : decpt <= digitCount + bias);
3665 } else {
3666 // X == decpt - 1, POSIX's P; -4 <= X < P iff -4 < decpt <= P
3667 Q_ASSERT(precision >= 0);
3668 useDecimal = decpt > -4 && decpt <= (precision ? precision : 1);
3669 }
3670
3671 numStr = useDecimal
3672 ? decimalForm(std::move(digits), decpt, precision, mode,
3673 mustMarkDecimal, groupDigits)
3674 : exponentForm(std::move(digits), decpt, precision, mode,
3675 mustMarkDecimal, minExponentDigits);
3676 break;
3677 }
3678 }
3679
3680 // Pad with zeros. LeftAdjusted overrides ZeroPadded.
3681 if (flags & ZeroPadded && !(flags & LeftAdjusted)) {
3682 for (qsizetype i = numStr.size() / zero.size() + prefix.size(); i < width; ++i)
3683 numStr.prepend(zero);
3684 }
3685 }
3686
3687 return prefix + (flags & CapitalEorX ? std::move(numStr).toUpper() : numStr);
3688}
3689
3690QString QLocaleData::decimalForm(QString &&digits, int decpt, int precision,
3691 PrecisionMode pm, bool mustMarkDecimal,
3692 bool groupDigits) const
3693{
3694 const QString zero = zeroDigit();
3695 const auto digitWidth = zero.size();
3696 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
3697 Q_ASSERT(digits.size() % digitWidth == 0);
3698
3699 // Separator needs to go at index decpt: so add zeros before or after the
3700 // given digits, if they don't reach that position already:
3701 if (decpt < 0) {
3702 for (; decpt < 0; ++decpt)
3703 digits.prepend(zero);
3704 } else {
3705 for (qsizetype i = digits.size() / digitWidth; i < decpt; ++i)
3706 digits.append(zero);
3707 }
3708
3709 switch (pm) {
3710 case PMDecimalDigits:
3711 for (qsizetype i = digits.size() / digitWidth - decpt; i < precision; ++i)
3712 digits.append(zero);
3713 break;
3714 case PMSignificantDigits:
3715 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
3716 digits.append(zero);
3717 break;
3718 case PMChopTrailingZeros:
3719 Q_ASSERT(digits.size() / digitWidth <= qMax(decpt, 1) || !digits.endsWith(zero));
3720 break;
3721 }
3722
3723 if (mustMarkDecimal || decpt < digits.size() / digitWidth)
3724 digits.insert(decpt * digitWidth, decimalPoint());
3725
3726 if (groupDigits) {
3727 const QString group = groupSeparator();
3728 qsizetype i = decpt - m_grouping_least;
3729 if (i >= m_grouping_top) {
3730 digits.insert(i * digitWidth, group);
3731 while ((i -= m_grouping_higher) >= m_grouping_top)
3732 digits.insert(i * digitWidth, group);
3733 }
3734 }
3735
3736 if (decpt == 0)
3737 digits.prepend(zero);
3738
3739 return std::move(digits);
3740}
3741
3742QString QLocaleData::exponentForm(QString &&digits, int decpt, int precision,
3743 PrecisionMode pm, bool mustMarkDecimal,
3744 int minExponentDigits) const
3745{
3746 const QString zero = zeroDigit();
3747 const auto digitWidth = zero.size();
3748 Q_ASSERT(digitWidth == 1 || digitWidth == 2);
3749 Q_ASSERT(digits.size() % digitWidth == 0);
3750
3751 switch (pm) {
3752 case PMDecimalDigits:
3753 for (qsizetype i = digits.size() / digitWidth; i < precision + 1; ++i)
3754 digits.append(zero);
3755 break;
3756 case PMSignificantDigits:
3757 for (qsizetype i = digits.size() / digitWidth; i < precision; ++i)
3758 digits.append(zero);
3759 break;
3760 case PMChopTrailingZeros:
3761 Q_ASSERT(digits.size() / digitWidth <= 1 || !digits.endsWith(zero));
3762 break;
3763 }
3764
3765 if (mustMarkDecimal || digits.size() > digitWidth)
3766 digits.insert(digitWidth, decimalPoint());
3767
3768 digits.append(exponentSeparator());
3769 digits.append(longLongToString(decpt - 1, minExponentDigits, 10, -1, AlwaysShowSign));
3770
3771 return std::move(digits);
3772}
3773
3774QString QLocaleData::signPrefix(bool negative, unsigned flags) const
3775{
3776 if (negative)
3777 return negativeSign();
3778 if (flags & AlwaysShowSign)
3779 return positiveSign();
3781 return QStringView(u" ").toString();
3782 return {};
3783}
3784
3786 int base, int width, unsigned flags) const
3787{
3788 bool negative = n < 0;
3789
3790 /*
3791 Negating std::numeric_limits<qlonglong>::min() hits undefined behavior, so
3792 taking an absolute value has to take a slight detour.
3793 */
3794 QString numStr = qulltoa(negative ? 1u + qulonglong(-(n + 1)) : qulonglong(n),
3795 base, zeroDigit());
3796
3797 return applyIntegerFormatting(std::move(numStr), negative, precision, base, width, flags);
3798}
3799
3801 int base, int width, unsigned flags) const
3802{
3803 const QString zero = zeroDigit();
3804 QString resultZero = base == 10 ? zero : QStringLiteral("0");
3805 return applyIntegerFormatting(l ? qulltoa(l, base, zero) : resultZero,
3806 false, precision, base, width, flags);
3807}
3808
3809QString QLocaleData::applyIntegerFormatting(QString &&numStr, bool negative, int precision,
3810 int base, int width, unsigned flags) const
3811{
3812 const QString zero = base == 10 ? zeroDigit() : QStringLiteral("0");
3813 const auto digitWidth = zero.size();
3814 const auto digitCount = numStr.size() / digitWidth;
3815
3816 const auto basePrefix = [&] () -> QStringView {
3817 if (flags & ShowBase) {
3818 const bool upper = flags & UppercaseBase;
3819 if (base == 16)
3820 return upper ? u"0X" : u"0x";
3821 if (base == 2)
3822 return upper ? u"0B" : u"0b";
3823 if (base == 8 && !numStr.startsWith(zero))
3824 return zero;
3825 }
3826 return {};
3827 }();
3828
3829 const QString prefix = signPrefix(negative, flags) + basePrefix;
3830 // Count how much of width we've used up. Each digit counts as one
3831 qsizetype usedWidth = digitCount + prefix.size();
3832
3833 if (base == 10 && flags & GroupDigits) {
3834 const QString group = groupSeparator();
3836 if (i >= m_grouping_top) {
3837 numStr.insert(i * digitWidth, group);
3838 ++usedWidth;
3839 while ((i -= m_grouping_higher) >= m_grouping_top) {
3840 numStr.insert(i * digitWidth, group);
3841 ++usedWidth;
3842 }
3843 }
3844 // TODO: should we group any zero-padding we add later ?
3845 }
3846
3847 const bool noPrecision = precision == -1;
3848 if (noPrecision)
3849 precision = 1;
3850
3851 for (qsizetype i = numStr.size(); i < precision; ++i) {
3852 numStr.prepend(zero);
3853 usedWidth++;
3854 }
3855
3856 // LeftAdjusted overrides ZeroPadded; and sprintf() only pads when
3857 // precision is not specified in the format string.
3858 if (noPrecision && flags & ZeroPadded && !(flags & LeftAdjusted)) {
3859 for (qsizetype i = usedWidth; i < width; ++i)
3860 numStr.prepend(zero);
3861 }
3862
3863 QString result(flags & CapitalEorX ? std::move(numStr).toUpper() : std::move(numStr));
3864 if (prefix.size())
3865 result.prepend(prefix);
3866 return result;
3867}
3868
3870{
3872 if (this == c()) {
3873 result.isC = true;
3874 return result;
3875 }
3876 result.setZero(zero().viewData(single_character_data));
3877 result.group = groupDelim().viewData(single_character_data);
3878 // Note: minus, plus and exponent might not actually be single characters.
3879 result.minus = minus().viewData(single_character_data);
3880 result.plus = plus().viewData(single_character_data);
3881 if (mode != IntegerMode)
3882 result.decimal = decimalSeparator().viewData(single_character_data);
3883 if (mode == DoubleScientificMode) {
3884 result.exponent = exponential().viewData(single_character_data);
3885 // exponentCyrillic means "apply the Cyrrilic-specific exponent hack"
3886 result.exponentCyrillic = m_script_id == QLocale::CyrillicScript;
3887 }
3888#ifndef QT_NO_SYSTEMLOCALE
3889 if (this == &systemLocaleData) {
3890 const auto getString = [sys = systemLocale()](QSystemLocale::QueryType query) {
3891 return sys->query(query).toString();
3892 };
3893 if (mode != IntegerMode) {
3895 if (result.sysDecimal.size())
3896 result.decimal = QStringView{result.sysDecimal};
3897 }
3899 if (result.sysGroup.size())
3900 result.group = QStringView{result.sysGroup};
3902 if (result.sysMinus.size())
3903 result.minus = QStringView{result.sysMinus};
3905 if (result.sysPlus.size())
3906 result.plus = QStringView{result.sysPlus};
3908 }
3909#endif
3910
3911 return result;
3912}
3913
3914namespace {
3915// A bit like QStringIterator but rather specialized ... and some of the tokens
3916// it recognizes aren't single Unicode code-points (but it does map each to a
3917// single character).
3918class NumericTokenizer
3919{
3920 // TODO: use deterministic finite-state-automata.
3921 // TODO QTBUG-95460: CLDR has Inf/NaN representations per locale.
3922 static constexpr char lettersInfNaN[] = "afin"; // Letters of Inf, NaN
3923 static constexpr auto matchInfNaN = QtPrivate::makeCharacterSetMatch<lettersInfNaN>();
3924 const QStringView m_text;
3925 const QLocaleData::NumericData m_guide;
3926 qsizetype m_index = 0;
3927 const QLocaleData::NumberMode m_mode;
3928 static_assert('+' + 1 == ',' && ',' + 1 == '-' && '-' + 1 == '.');
3929 char lastMark; // C locale accepts '+' through lastMark.
3930public:
3931 NumericTokenizer(QStringView text, QLocaleData::NumericData &&guide,
3933 : m_text(text), m_guide(guide), m_mode(mode),
3934 lastMark(mode == QLocaleData::IntegerMode ? '-' : '.')
3935 {
3936 Q_ASSERT(m_guide.isValid(mode));
3937 }
3938 bool done() const { return !(m_index < m_text.size()); }
3939 qsizetype index() const { return m_index; }
3940 inline int asBmpDigit(char16_t digit) const;
3941 char nextToken();
3942};
3943
3944int NumericTokenizer::asBmpDigit(char16_t digit) const
3945{
3946 // If digit *is* a digit, result will be in range 0 through 9; otherwise not.
3947 // Must match qlocale_tools.h's unicodeForDigit()
3948 if (m_guide.zeroUcs != u'\u3007' || digit == m_guide.zeroUcs)
3949 return digit - m_guide.zeroUcs;
3950
3951 // QTBUG-85409: Suzhou's digits aren't contiguous !
3952 if (digit == u'\u3020') // U+3020 POSTAL MARK FACE is not a digit.
3953 return -1;
3954 // ... but is followed by digits 1 through 9.
3955 return digit - u'\u3020';
3956}
3957
3958char NumericTokenizer::nextToken()
3959{
3960 // As long as caller stops iterating on a zero return, those don't need to
3961 // keep m_index correctly updated.
3962 Q_ASSERT(!done());
3963 // Mauls non-letters above 'Z' but we don't care:
3964 const auto asciiLower = [](unsigned char c) { return c >= 'A' ? c | 0x20 : c; };
3965 const QStringView tail = m_text.sliced(m_index);
3966 const QChar ch = tail.front();
3967 if (ch == u'\u2212') {
3968 // Special case: match the "proper" minus sign, for all locales.
3969 ++m_index;
3970 return '-';
3971 }
3972 if (m_guide.isC) {
3973 // "Conversion" to C locale is just a filter:
3974 ++m_index;
3975 if (Q_LIKELY(ch.unicode() < 256)) {
3976 unsigned char ascii = asciiLower(ch.toLatin1());
3977 if (Q_LIKELY(isAsciiDigit(ascii) || ('+' <= ascii && ascii <= lastMark)
3978 // No caller presently (6.5) passes DoubleStandardMode,
3979 // so !IntegerMode implies scientific, for now.
3980 || (m_mode != QLocaleData::IntegerMode
3981 && matchInfNaN.matches(ascii))
3983 && ascii == 'e'))) {
3984 return ascii;
3985 }
3986 }
3987 return 0;
3988 }
3989 if (ch.unicode() < 256) {
3990 // Accept the C locale's digits and signs in all locales:
3991 char ascii = asciiLower(ch.toLatin1());
3992 if (isAsciiDigit(ascii) || ascii == '-' || ascii == '+'
3993 // Also its Inf and NaN letters:
3994 || (m_mode != QLocaleData::IntegerMode && matchInfNaN.matches(ascii))) {
3995 ++m_index;
3996 return ascii;
3997 }
3998 }
3999
4000 // Other locales may be trickier:
4001 if (tail.startsWith(m_guide.minus)) {
4002 m_index += m_guide.minus.size();
4003 return '-';
4004 }
4005 if (tail.startsWith(m_guide.plus)) {
4006 m_index += m_guide.plus.size();
4007 return '+';
4008 }
4009 if (!m_guide.group.isEmpty() && tail.startsWith(m_guide.group)) {
4010 m_index += m_guide.group.size();
4011 return ',';
4012 }
4013 if (m_mode != QLocaleData::IntegerMode && tail.startsWith(m_guide.decimal)) {
4014 m_index += m_guide.decimal.size();
4015 return '.';
4016 }
4018 && tail.startsWith(m_guide.exponent, Qt::CaseInsensitive)) {
4019 m_index += m_guide.exponent.size();
4020 return 'e';
4021 }
4022
4023 // Must match qlocale_tools.h's unicodeForDigit()
4024 if (m_guide.zeroLen == 1) {
4025 if (!ch.isSurrogate()) {
4026 const uint gap = asBmpDigit(ch.unicode());
4027 if (gap < 10u) {
4028 ++m_index;
4029 return '0' + gap;
4030 }
4031 } else if (ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()) {
4032 return 0;
4033 }
4034 } else if (ch.isHighSurrogate()) {
4035 // None of the corner cases below matches a surrogate, so (update
4036 // already and) return early if we don't have a digit.
4037 if (tail.size() > 1) {
4038 QChar low = tail.at(1);
4039 if (low.isLowSurrogate()) {
4040 m_index += 2;
4041 const uint gap = QChar::surrogateToUcs4(ch, low) - m_guide.zeroUcs;
4042 return gap < 10u ? '0' + gap : 0;
4043 }
4044 }
4045 return 0;
4046 }
4047
4048 // All cases where tail starts with properly-matched surrogate pair
4049 // have been handled by this point.
4050 Q_ASSERT(!(ch.isHighSurrogate() && tail.size() > 1 && tail.at(1).isLowSurrogate()));
4051
4052 // Weird corner cases follow (code above assumes these match no surrogates).
4053
4054 // Some locales use a non-breaking space (U+00A0) or its thin version
4055 // (U+202f) for grouping. These look like spaces, so people (and thus some
4056 // of our tests) use a regular space instead and complain if it doesn't
4057 // work.
4058 // Should this be extended generally to any case where group is a space ?
4059 if ((m_guide.group == u"\u00a0" || m_guide.group == u"\u202f") && tail.startsWith(u' ')) {
4060 ++m_index;
4061 return ',';
4062 }
4063
4064 // Cyrillic has its own E, used by Ukrainian as exponent; but others
4065 // writing Cyrillic may well use that; and Ukrainians might well use E.
4066 // All other Cyrillic locales (officially) use plain ASCII E.
4067 if (m_guide.exponentCyrillic // Only true in scientific float mode.
4068 && (tail.startsWith(u"\u0415", Qt::CaseInsensitive)
4069 || tail.startsWith(u"E", Qt::CaseInsensitive))) {
4070 ++m_index;
4071 return 'e';
4072 }
4073
4074 return 0;
4075}
4076} // namespace with no name
4077
4078/*
4079 Converts a number in locale representation to the C locale equivalent.
4080
4081 Only has to guarantee that a string that is a correct representation of a
4082 number will be converted. Checks signs, separators and digits appear in all
4083 the places they should, and nowhere else.
4084
4085 Returns true precisely if the number appears to be well-formed, modulo
4086 things a parser for C Locale strings (without digit-grouping separators;
4087 they're stripped) will catch. When it returns true, it records (and
4088 '\0'-terminates) the C locale representation in *result.
4089
4090 Note: only QString integer-parsing methods have a base parameter (hence need
4091 to cope with letters as possible digits); but these are now all routed via
4092 byteArrayToU?LongLong(), so no longer come via here. The QLocale
4093 number-parsers only work in decimal, so don't have to cope with any digits
4094 other than 0 through 9.
4095*/
4096bool QLocaleData::numberToCLocale(QStringView s, QLocale::NumberOptions number_options,
4098{
4099 s = s.trimmed();
4100 if (s.size() < 1)
4101 return false;
4102 NumericTokenizer tokens(s, numericData(mode), mode);
4103
4104 // Digit-grouping details (all modes):
4105 qsizetype digitsInGroup = 0;
4106 qsizetype last_separator_idx = -1;
4107 qsizetype start_of_digits_idx = -1;
4108
4109 // Floating-point details (non-integer modes):
4110 qsizetype decpt_idx = -1;
4111 qsizetype exponent_idx = -1;
4112
4113 char last = '\0';
4114 while (!tokens.done()) {
4115 qsizetype idx = tokens.index(); // before nextToken() advances
4116 char out = tokens.nextToken();
4117 if (out == 0)
4118 return false;
4119 Q_ASSERT(tokens.index() > idx); // it always *should* advance (except on zero return)
4120
4121 if (out == '.') {
4122 // Fail if more than one decimal point or point after e
4123 if (decpt_idx != -1 || exponent_idx != -1)
4124 return false;
4125 decpt_idx = idx;
4126 } else if (out == 'e') {
4127 exponent_idx = idx;
4128 }
4129
4130 if (number_options.testFlag(QLocale::RejectLeadingZeroInExponent)
4131 && exponent_idx != -1 && out == '0') {
4132 // After the exponent there can only be '+', '-' or digits.
4133 // If we find a '0' directly after some non-digit, then that is a
4134 // leading zero, acceptable only if it is the whole exponent.
4135 if (!tokens.done() && !isAsciiDigit(last))
4136 return false;
4137 }
4138
4139 if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot) && decpt_idx >= 0) {
4140 // In a fractional part, a 0 just before the exponent is trailing:
4141 if (idx == exponent_idx && last == '0')
4142 return false;
4143 }
4144
4145 if (!number_options.testFlag(QLocale::RejectGroupSeparator)) {
4146 if (isAsciiDigit(out)) {
4147 if (start_of_digits_idx == -1)
4148 start_of_digits_idx = idx;
4149 ++digitsInGroup;
4150 } else if (out == ',') {
4151 // Don't allow group chars after the decimal point or exponent
4152 if (decpt_idx != -1 || exponent_idx != -1)
4153 return false;
4154
4155 if (last_separator_idx == -1) {
4156 // Check distance from the beginning of the digits:
4157 if (start_of_digits_idx == -1 || m_grouping_top > digitsInGroup
4158 || digitsInGroup >= m_grouping_higher + m_grouping_top) {
4159 return false;
4160 }
4161 } else {
4162 // Check distance from the last separator:
4163 if (digitsInGroup != m_grouping_higher)
4164 return false;
4165 }
4166
4167 last_separator_idx = idx;
4168 digitsInGroup = 0;
4169 } else if (mode != IntegerMode && (out == '.' || idx == exponent_idx)
4170 && last_separator_idx != -1) {
4171 // Were there enough digits since the last group separator?
4172 if (digitsInGroup != m_grouping_least)
4173 return false;
4174
4175 // stop processing separators
4176 last_separator_idx = -1;
4177 }
4178 } else if (out == ',') {
4179 return false;
4180 }
4181
4182 last = out;
4183 if (out != ',') // Leave group separators out of the result.
4184 result->append(out);
4185 }
4186
4187 if (!number_options.testFlag(QLocale::RejectGroupSeparator) && last_separator_idx != -1) {
4188 // Were there enough digits since the last group separator?
4189 if (digitsInGroup != m_grouping_least)
4190 return false;
4191 }
4192
4193 if (number_options.testFlag(QLocale::RejectTrailingZeroesAfterDot)
4194 && decpt_idx != -1 && exponent_idx == -1) {
4195 // In the fractional part, a final zero is trailing:
4196 if (last == '0')
4197 return false;
4198 }
4199
4200 result->append('\0');
4201 return true;
4202}
4203
4205 int decDigits, QLocale::NumberOptions number_options) const
4206{
4207 buff->clear();
4208 buff->reserve(str.size());
4209
4210 enum { Whole, Fractional, Exponent } state = Whole;
4211 const bool scientific = numMode == DoubleScientificMode;
4212 NumericTokenizer tokens(str, numericData(numMode), numMode);
4213 char last = '\0';
4214
4215 while (!tokens.done()) {
4216 char c = tokens.nextToken();
4217
4218 if (isAsciiDigit(c)) {
4219 switch (state) {
4220 case Whole:
4221 // Nothing special to do (unless we want to check grouping sizes).
4222 break;
4223 case Fractional:
4224 // If a double has too many digits in its fractional part it is Invalid.
4225 if (decDigits-- == 0)
4226 return false;
4227 break;
4228 case Exponent:
4229 if (!isAsciiDigit(last)) {
4230 // This is the first digit in the exponent (there may have beena '+'
4231 // or '-' in before). If it's a zero, the exponent is zero-padded.
4232 if (c == '0' && (number_options & QLocale::RejectLeadingZeroInExponent))
4233 return false;
4234 }
4235 break;
4236 }
4237
4238 } else {
4239 switch (c) {
4240 case '.':
4241 // If an integer has a decimal point, it is Invalid.
4242 // A double can only have one, at the end of its whole-number part.
4243 if (numMode == IntegerMode || state != Whole)
4244 return false;
4245 // Even when decDigits is 0, we do allow the decimal point to be
4246 // present - just as long as no digits follow it.
4247
4248 state = Fractional;
4249 break;
4250
4251 case '+':
4252 case '-':
4253 // A sign can only appear at the start or after the e of scientific:
4254 if (last != '\0' && !(scientific && last == 'e'))
4255 return false;
4256 break;
4257
4258 case ',':
4259 // Grouping is only allowed after a digit in the whole-number portion:
4260 if ((number_options & QLocale::RejectGroupSeparator) || state != Whole
4261 || !isAsciiDigit(last)) {
4262 return false;
4263 }
4264 // We could check grouping sizes are correct, but fixup()s are
4265 // probably better off correcting any misplacement instead.
4266 break;
4267
4268 case 'e':
4269 // Only one e is allowed and only in scientific:
4270 if (!scientific || state == Exponent)
4271 return false;
4272 state = Exponent;
4273 break;
4274
4275 default:
4276 // Nothing else can validly appear in a number.
4277 // NumericTokenizer allows letters of "inf" and "nan", but
4278 // validators don't accept those values.
4279 // For anything else, tokens.nextToken() must have returned 0.
4280 Q_ASSERT(!c || c == 'a' || c == 'f' || c == 'i' || c == 'n');
4281 return false;
4282 }
4283 }
4284
4285 last = c;
4286 if (c != ',') // Skip grouping
4287 buff->append(c);
4288 }
4289
4290 return true;
4291}
4292
4294 QLocale::NumberOptions number_options) const
4295{
4296 CharBuff buff;
4297 if (!numberToCLocale(str, number_options, DoubleScientificMode, &buff)) {
4298 if (ok != nullptr)
4299 *ok = false;
4300 return 0.0;
4301 }
4302 auto r = qt_asciiToDouble(buff.constData(), buff.size() - 1);
4303 if (ok != nullptr)
4304 *ok = r.ok();
4305 return r.result;
4306}
4307
4309 QLocale::NumberOptions number_options) const
4310{
4311 CharBuff buff;
4312 if (!numberToCLocale(str, number_options, IntegerMode, &buff)) {
4313 if (ok != nullptr)
4314 *ok = false;
4315 return 0;
4316 }
4317
4318 return bytearrayToLongLong(QByteArrayView(buff.constData(), buff.size()), base, ok);
4319}
4320
4322 QLocale::NumberOptions number_options) const
4323{
4324 CharBuff buff;
4325 if (!numberToCLocale(str, number_options, IntegerMode, &buff)) {
4326 if (ok != nullptr)
4327 *ok = false;
4328 return 0;
4329 }
4330
4331 return bytearrayToUnsLongLong(QByteArrayView(buff.constData(), buff.size()), base, ok);
4332}
4333
4335{
4336 if (used <= 0)
4337 return false;
4338
4339 const qsizetype len = num.size();
4340 if (used < len && num[used] != '\0') {
4341 while (used < len && ascii_isspace(num[used]))
4342 ++used;
4343 }
4344
4345 if (used < len && num[used] != '\0')
4346 // we stopped at a non-digit character after converting some digits
4347 return false;
4348
4349 return true;
4350}
4351
4353{
4354 auto r = qstrntoll(num.data(), num.size(), base);
4355 const bool parsed = checkParsed(num, r.used);
4356 if (ok)
4357 *ok = parsed;
4358 return parsed ? r.result : 0;
4359}
4360
4362{
4363 auto r = qstrntoull(num.data(), num.size(), base);
4364 const bool parsed = checkParsed(num, r.used);
4365 if (ok)
4366 *ok = parsed;
4367 return parsed ? r.result : 0;
4368}
4369
4387{
4388#ifndef QT_NO_SYSTEMLOCALE
4389 if (d->m_data == &systemLocaleData) {
4391 if (!res.isEmpty())
4392 return res;
4393 }
4394#endif
4395 switch (format) {
4396 case CurrencySymbol:
4397 return d->m_data->currencySymbol().getData(currency_symbol_data);
4399 return d->m_data->currencyDisplayName().getData(currency_display_name_data);
4400 case CurrencyIsoCode: {
4401 const char *code = d->m_data->m_currency_iso_code;
4402 if (auto len = qstrnlen(code, 3))
4403 return QString::fromLatin1(code, qsizetype(len));
4404 break;
4405 }
4406 }
4407 return QString();
4408}
4409
4419{
4420#ifndef QT_NO_SYSTEMLOCALE
4421 if (d->m_data == &systemLocaleData) {
4425 if (!res.isEmpty())
4426 return res;
4427 }
4428#endif
4429 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
4430 if (!range.size || value >= 0)
4431 range = d->m_data->currencyFormat();
4432 else
4433 value = -value;
4435 QString sym = symbol.isNull() ? currencySymbol() : symbol;
4436 if (sym.isEmpty())
4438 return range.viewData(currency_format_data).arg(str, sym);
4439}
4440
4446{
4447#ifndef QT_NO_SYSTEMLOCALE
4448 if (d->m_data == &systemLocaleData) {
4452 if (!res.isEmpty())
4453 return res;
4454 }
4455#endif
4457 QString sym = symbol.isNull() ? currencySymbol() : symbol;
4458 if (sym.isEmpty())
4460 return d->m_data->currencyFormat().getData(currency_format_data).arg(str, sym);
4461}
4462
4474{
4475#ifndef QT_NO_SYSTEMLOCALE
4476 if (d->m_data == &systemLocaleData) {
4480 if (!res.isEmpty())
4481 return res;
4482 }
4483#endif
4484 QLocaleData::DataRange range = d->m_data->currencyFormatNegative();
4485 if (!range.size || value >= 0)
4486 range = d->m_data->currencyFormat();
4487 else
4488 value = -value;
4490 QString sym = symbol.isNull() ? currencySymbol() : symbol;
4491 if (sym.isEmpty())
4493 return range.viewData(currency_format_data).arg(str, sym);
4494}
4495
4534{
4535 int power, base = 1000;
4536 if (!bytes) {
4537 power = 0;
4538 } else if (format & DataSizeBase1000) {
4539 power = int(std::log10(qAbs(bytes)) / 3);
4540 } else { // Compute log2(bytes) / 10:
4541 power = int((63 - qCountLeadingZeroBits(quint64(qAbs(bytes)))) / 10);
4542 base = 1024;
4543 }
4544 // Only go to doubles if we'll be using a quantifier:
4545 const QString number = power
4546 ? toString(bytes / std::pow(double(base), power), 'f', qMin(precision, 3 * power))
4547 : toString(bytes);
4548
4549 // We don't support sizes in units larger than exbibytes because
4550 // the number of bytes would not fit into qint64.
4551 Q_ASSERT(power <= 6 && power >= 0);
4552 QStringView unit;
4553 if (power > 0) {
4555 ? d->m_data->byteAmountSI() : d->m_data->byteAmountIEC();
4556 unit = range.viewListEntry(byte_unit_data, power - 1);
4557 } else {
4558 unit = d->m_data->byteCount().viewData(byte_unit_data);
4559 }
4560
4561 return number + u' ' + unit;
4562}
4563
4581{
4583 QList<QLocaleId> localeIds;
4584#ifdef QT_NO_SYSTEMLOCALE
4585 constexpr bool isSystem = false;
4586#else
4587 const bool isSystem = d->m_data == &systemLocaleData;
4588 if (isSystem) {
4590 // ... but we need to include likely-adjusted forms of each of those, too.
4591 // For now, collect up locale Ids representing the entries, for later processing:
4592 for (const auto &entry : std::as_const(uiLanguages))
4593 localeIds.append(QLocaleId::fromName(entry));
4594 if (localeIds.isEmpty())
4595 localeIds.append(systemLocale()->fallbackLocale().d->m_data->id());
4596 // If the system locale (isn't C and) didn't include itself in the list,
4597 // or as fallback, presume to know better than it and put its name
4598 // first. (Known issue, QTBUG-104930, on some macOS versions when in
4599 // locale en_DE.) Our translation system might have a translation for a
4600 // locale the platform doesn't believe in.
4601 const QString name = bcp47Name();
4602 if (!name.isEmpty() && language() != C && !uiLanguages.contains(name)) {
4603 // That uses contains(name) as a cheap pre-test, but there may be an
4604 // entry that matches this on purging likely subtags.
4605 const QLocaleId mine = d->m_data->id().withLikelySubtagsRemoved();
4606 const auto isMine = [mine](const QString &entry) {
4608 };
4609 if (std::none_of(uiLanguages.constBegin(), uiLanguages.constEnd(), isMine)) {
4610 localeIds.prepend(d->m_data->id());
4611 uiLanguages.prepend(name);
4612 }
4613 }
4614 } else
4615#endif
4616 {
4617 localeIds.append(d->m_data->id());
4618 }
4619 for (qsizetype i = localeIds.size(); i-- > 0; ) {
4620 QLocaleId id = localeIds.at(i);
4621 qsizetype j;
4622 QByteArray prior;
4623 if (isSystem && i < uiLanguages.size()) {
4624 // Adding likely-adjusted forms to system locale's list.
4625 // Name the locale is derived from:
4626 prior = uiLanguages.at(i).toLatin1();
4627 // Insert just after the entry we're supplementing:
4628 j = i + 1;
4629 } else if (id.language_id == C) {
4630 // Attempt no likely sub-tag amendments to C:
4631 uiLanguages.append(QString::fromLatin1(id.name()));
4632 continue;
4633 } else {
4634 // Plain locale or empty system uiLanguages; just append.
4635 prior = id.name();
4636 uiLanguages.append(QString::fromLatin1(prior));
4637 j = uiLanguages.size();
4638 }
4639
4640 const QLocaleId max = id.withLikelySubtagsAdded();
4641 const QLocaleId min = max.withLikelySubtagsRemoved();
4642
4643 // Include minimal version (last) unless it's what our locale is derived from:
4644 if (auto name = min.name(); name != prior)
4646 else if (!isSystem)
4647 --j; // bcp47Name() matches min(): put more specific forms *before* it.
4648
4649 if (id.script_id) {
4650 // Include scriptless version if likely-equivalent and distinct:
4651 id.script_id = 0;
4652 if (id != min && id.withLikelySubtagsAdded() == max) {
4653 if (auto name = id.name(); name != prior)
4655 }
4656 }
4657
4658 if (!id.territory_id) {
4659 Q_ASSERT(!min.territory_id);
4660 Q_ASSERT(!id.script_id); // because we just cleared it.
4661 // Include version with territory if it likely-equivalent and distinct:
4662 id.territory_id = max.territory_id;
4663 if (id != max && id.withLikelySubtagsAdded() == max) {
4664 if (auto name = id.name(); name != prior)
4666 }
4667 }
4668
4669 // Include version with all likely sub-tags (first) if distinct from the rest:
4670 if (max != min && max != id) {
4671 if (auto name = max.name(); name != prior)
4673 }
4674 }
4675 return uiLanguages;
4676}
4677
4690{
4691#ifndef QT_NO_SYSTEMLOCALE
4692 if (d->m_data == &systemLocaleData) {
4694 if (!res.isEmpty())
4695 return QLocale(res);
4696 }
4697#endif
4698 return *this;
4699}
4700
4710{
4711#ifndef QT_NO_SYSTEMLOCALE
4712 if (d->m_data == &systemLocaleData) {
4714 if (!res.isEmpty())
4715 return res;
4716 }
4717#endif
4718 return d->m_data->endonymLanguage().getData(endonyms_data);
4719}
4720
4730{
4731#ifndef QT_NO_SYSTEMLOCALE
4732 if (d->m_data == &systemLocaleData) {
4734 if (!res.isEmpty())
4735 return res;
4736 }
4737#endif
4738 return d->m_data->endonymTerritory().getData(endonyms_data);
4739}
4740
4741#if QT_DEPRECATED_SINCE(6, 6)
4751QString QLocale::nativeCountryName() const
4752{
4753 return nativeTerritoryName();
4754}
4755#endif
4756
4757#ifndef QT_NO_DEBUG_STREAM
4759{
4760 QDebugStateSaver saver(dbg);
4761 dbg.nospace().noquote()
4762 << "QLocale(" << QLocale::languageToString(l.language())
4763 << ", " << QLocale::scriptToString(l.script())
4764 << ", " << QLocale::territoryToString(l.territory()) << ')';
4765 return dbg;
4766}
4767#endif
4769
4770#ifndef QT_NO_QOBJECT
4771#include "moc_qlocale.cpp"
4772#endif
T fetchAndAddRelaxed(T valueToAdd) noexcept
\inmodule QtCore
Definition qbytearray.h:57
void reserve(qsizetype size)
Attempts to allocate memory for at least size bytes.
Definition qbytearray.h:557
void clear()
Clears the contents of the byte array and makes it null.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
virtual QString standaloneWeekDayName(const QLocale &locale, int day, QLocale::FormatType format) const
Returns the standalone name of the specified day of the week in the chosen locale,...
Definition qlocale.cpp:3096
virtual const char16_t * localeMonthData() const =0
virtual QString standaloneMonthName(const QLocale &locale, int month, int year, QLocale::FormatType format) const
Returns the standalone name of the specified month in the chosen locale, using the specified format t...
Definition qlocale.cpp:3030
virtual QString dateTimeToString(QStringView format, const QDateTime &datetime, QDate dateOnly, QTime timeOnly, const QLocale &locale) const
Returns a string representing a given date, time or date-time.
Definition qlocale.cpp:3333
virtual const QCalendarLocale * localeMonthIndexData() const =0
virtual int dayOfWeek(qint64 jd) const
Returns the day of the week for the given Julian Day Number jd.
virtual QString weekDayName(const QLocale &locale, int day, QLocale::FormatType format) const
Returns the name of the specified day of the week in the chosen locale, using the specified format to...
Definition qlocale.cpp:3067
virtual QCalendar::YearMonthDay julianDayToDate(qint64 jd) const =0
Computes the year, month, and day in this calendar for the given Julian day number jd.
virtual QString monthName(const QLocale &locale, int month, int year, QLocale::FormatType format) const
Returns the name of the specified month in the given year for the chosen locale, using the given form...
Definition qlocale.cpp:2995
virtual int maximumMonthsInYear() const
Returns the maximum number of months possible in any year.
The QCalendar class describes calendar systems.
Definition qcalendar.h:53
bool isGregorian() const
Returns true if this calendar object is the Gregorian calendar object used as default calendar by oth...
QString standaloneMonthName(const QLocale &locale, int month, int year=Unspecified, QLocale::FormatType format=QLocale::LongFormat) const
Returns a suitably localised standalone name for a month.
QString dateTimeToString(QStringView format, const QDateTime &datetime, QDate dateOnly, QTime timeOnly, const QLocale &locale) const
Returns a string representing a given date, time or date-time.
QString monthName(const QLocale &locale, int month, int year=Unspecified, QLocale::FormatType format=QLocale::LongFormat) const
Returns a suitably localised name for a month.
@ Unspecified
Definition qcalendar.h:57
QString standaloneWeekDayName(const QLocale &locale, int day, QLocale::FormatType format=QLocale::LongFormat) const
Returns a suitably localised standalone name for a day of the week.
QString weekDayName(const QLocale &locale, int day, QLocale::FormatType format=QLocale::LongFormat) const
Returns a suitably localised name for a day of the week.
\inmodule QtCore
Definition qchar.h:48
static constexpr char32_t surrogateToUcs4(char16_t high, char16_t low) noexcept
Converts a UTF16 surrogate pair with the given high and low values to it's UCS-4-encoded code point.
Definition qchar.h:508
static constexpr bool requiresSurrogates(char32_t ucs4) noexcept
Returns true if the UCS-4-encoded character specified by ucs4 can be split into the high and low part...
Definition qchar.h:504
static constexpr char16_t highSurrogate(char32_t ucs4) noexcept
Returns the high surrogate part of a UCS-4-encoded code point.
Definition qchar.h:518
constexpr bool isLowSurrogate() const noexcept
Returns true if the QChar is the low part of a UTF16 surrogate (for example if its code point is in r...
Definition qchar.h:480
constexpr bool isSurrogate() const noexcept
Definition qchar.h:481
constexpr char16_t unicode() const noexcept
Returns the numeric Unicode value of the QChar.
Definition qchar.h:458
static constexpr char16_t lowSurrogate(char32_t ucs4) noexcept
Returns the low surrogate part of a UCS-4-encoded code point.
Definition qchar.h:522
constexpr bool isHighSurrogate() const noexcept
Returns true if the QChar is the high part of a UTF16 surrogate (for example if its code point is in ...
Definition qchar.h:479
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore\reentrant
Definition qdatetime.h:257
int offsetFromUtc() const
static QDateTime currentDateTime()
This is an overloaded member function, provided for convenience. It differs from the above function o...
QTime time() const
Returns the time part of the datetime.
QString timeZoneAbbreviation() const
bool isValid() const
Returns true if this datetime represents a definite moment, otherwise false.
QDateTime toOffsetFromUtc(int offsetSeconds) const
QDate date() const
Returns the date part of the datetime.
\inmodule QtCore \reentrant
Definition qdatetime.h:27
constexpr bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition qdatetime.h:86
constexpr qint64 toJulianDay() const
Converts the date to a Julian day.
Definition qdatetime.h:161
\inmodule QtCore
\inmodule QtCore
QVariant data(int key) const
Returns this item's custom data for the key key as a QVariant.
QString monthName(const QLocale &locale, int month, int year, QLocale::FormatType format) const override
Returns the name of the specified month in the given year for the chosen locale, using the given form...
Definition qlocale.cpp:3003
QString standaloneMonthName(const QLocale &locale, int month, int year, QLocale::FormatType format) const override
Returns the standalone name of the specified month in the chosen locale, using the specified format t...
Definition qlocale.cpp:3038
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void prepend(rvalue_ref t)
Definition qlist.h:456
void append(parameter_type t)
Definition qlist.h:441
static QLatin1StringView scriptToCode(QLocale::Script script)
Definition qlocale.cpp:229
quint16 languageId() const
Definition qlocale_p.h:482
static QLocale::Language codeToLanguage(QStringView code, QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode) noexcept
Definition qlocale.cpp:93
const QLocaleData *const m_data
Definition qlocale_p.h:512
QLocale::MeasurementSystem measurementSystem() const
Definition qlocale.cpp:3144
quint16 territoryId() const
Definition qlocale_p.h:483
static QLatin1StringView territoryToCode(QLocale::Territory territory)
Definition qlocale.cpp:237
static QLocale::Territory codeToTerritory(QStringView code) noexcept
Definition qlocale.cpp:185
static std::array< char, 4 > languageToCode(QLocale::Language language, QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode)
Definition qlocale.cpp:204
static QLocale::Script codeToScript(QStringView code) noexcept
Definition qlocale.cpp:165
QLocale::NumberOptions m_numberOptions
Definition qlocale_p.h:515
QLatin1StringView territoryCode() const
Definition qlocale_p.h:494
std::array< char, 4 > languageCode(QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode) const
Definition qlocale_p.h:488
static QBasicAtomicInt s_generation
Definition qlocale_p.h:517
QByteArray bcp47Name(char separator='-') const
Definition qlocale.cpp:456
QString decimalPoint() const
Definition qlocale.cpp:2535
static QString languageToCode(Language language, LanguageCodeTypes codeTypes=AnyLanguageCode)
Returns the two- or three-letter language code for language, as defined in the ISO 639 standards.
Definition qlocale.cpp:1420
QString quoteString(const QString &str, QuotationStyle style=StandardQuotation) const
Definition qlocale.h:1117
QString dateTimeFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2306
Language language() const
Returns the language of this locale.
Definition qlocale.cpp:1279
QString bcp47Name() const
Returns the BCP47 field names joined with dashes.
Definition qlocale.cpp:1397
QString zeroDigit() const
Definition qlocale.cpp:2590
QLocale & operator=(const QLocale &other) noexcept
Assigns other to this QLocale object and returns a reference to this QLocale object.
QStringList uiLanguages() const
List of locale names for use in selecting translations.
Definition qlocale.cpp:4580
double toDouble(const QString &s, bool *ok=nullptr) const
Returns the double represented by the localized string s.
Definition qlocale.h:950
QString dateFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2244
float toFloat(const QString &s, bool *ok=nullptr) const
Returns the float represented by the localized string s.
Definition qlocale.h:948
static QString scriptToString(Script script)
Definition qlocale.cpp:1584
void setNumberOptions(NumberOptions options)
Definition qlocale.cpp:1139
QString negativeSign() const
Definition qlocale.cpp:2607
Qt::DayOfWeek firstDayOfWeek() const
Definition qlocale.cpp:3132
uint toUInt(const QString &s, bool *ok=nullptr) const
Returns the unsigned int represented by the localized string s.
Definition qlocale.h:938
QString toUpper(const QString &str) const
Definition qlocale.cpp:3254
long toLong(const QString &s, bool *ok=nullptr) const
Definition qlocale.h:940
Qt::LayoutDirection textDirection() const
Definition qlocale.cpp:3204
QuotationStyle
Definition qlocale.h:1116
@ AlternateQuotation
Definition qlocale.h:1116
@ StandardQuotation
Definition qlocale.h:1116
static Territory codeToTerritory(QStringView territoryCode) noexcept
Definition qlocale.cpp:1471
@ FloatingPointShortest
Definition qlocale.h:880
QString dayName(int, FormatType format=LongFormat) const
Definition qlocale.cpp:2867
@ OldHungarianScript
Definition qlocale.h:498
@ ImperialAramaicScript
Definition qlocale.h:453
@ InscriptionalParthianScript
Definition qlocale.h:455
@ HatranScript
Definition qlocale.h:450
@ AdlamScript
Definition qlocale.h:405
@ MeroiticCursiveScript
Definition qlocale.h:484
@ NabataeanScript
Definition qlocale.h:491
@ OldSouthArabianScript
Definition qlocale.h:503
@ AvestanScript
Definition qlocale.h:410
@ NkoScript
Definition qlocale.h:494
@ ManichaeanScript
Definition qlocale.h:480
@ LastScript
Definition qlocale.h:553
@ MandaeanScript
Definition qlocale.h:479
@ ThaanaScript
Definition qlocale.h:536
@ CyrillicScript
Definition qlocale.h:431
@ MeroiticScript
Definition qlocale.h:485
@ KharoshthiScript
Definition qlocale.h:463
@ CypriotScript
Definition qlocale.h:430
@ OrkhonScript
Definition qlocale.h:504
@ LydianScript
Definition qlocale.h:476
@ HebrewScript
Definition qlocale.h:451
@ PalmyreneScript
Definition qlocale.h:508
@ SyriacScript
Definition qlocale.h:527
@ PhoenicianScript
Definition qlocale.h:511
@ MendeKikakuiScript
Definition qlocale.h:548
@ AnyScript
Definition qlocale.h:404
@ OldNorthArabianScript
Definition qlocale.h:500
@ InscriptionalPahlaviScript
Definition qlocale.h:454
@ SamaritanScript
Definition qlocale.h:516
@ PsalterPahlaviScript
Definition qlocale.h:513
@ ArabicScript
Definition qlocale.h:408
static QString territoryToCode(Territory territory)
Definition qlocale.cpp:1456
MeasurementSystem
Definition qlocale.h:857
@ MetricSystem
Definition qlocale.h:858
CurrencySymbolFormat
Definition qlocale.h:883
@ CurrencySymbol
Definition qlocale.h:885
@ CurrencyIsoCode
Definition qlocale.h:884
@ CurrencyDisplayName
Definition qlocale.h:886
@ LongFormat
Definition qlocale.h:865
@ NarrowFormat
Definition qlocale.h:865
@ ShortFormat
Definition qlocale.h:865
QString toCurrencyString(qlonglong, const QString &symbol=QString()) const
Definition qlocale.cpp:4418
QString timeFormat(FormatType format=LongFormat) const
Definition qlocale.cpp:2275
@ ISO639Part1
Definition qlocale.h:1060
@ ISO639Part2T
Definition qlocale.h:1062
@ ISO639Part2B
Definition qlocale.h:1061
@ ISO639Part3
Definition qlocale.h:1063
@ LegacyLanguageCode
Definition qlocale.h:1064
Country Territory
Definition qlocale.h:851
QString groupSeparator() const
Definition qlocale.cpp:2554
QString createSeparatedList(const QStringList &strl) const
Definition qlocale.cpp:1208
static void setDefault(const QLocale &locale)
\nonreentrant
Definition qlocale.cpp:1257
QString monthName(int, FormatType format=LongFormat) const
Definition qlocale.cpp:2833
static QString territoryToString(Territory territory)
Definition qlocale.cpp:1556
MeasurementSystem measurementSystem() const
Definition qlocale.cpp:3186
QString percent() const
Definition qlocale.cpp:2571
QString amText() const
Definition qlocale.cpp:3299
QLocale collation() const
Definition qlocale.cpp:4689
@ AnyCountry
Definition qlocale.h:821
@ AnyTerritory
Definition qlocale.h:558
@ LastTerritory
Definition qlocale.h:846
QString nativeTerritoryName() const
Definition qlocale.cpp:4729
static Script codeToScript(QStringView scriptCode) noexcept
Returns the QLocale::Script enum corresponding to the four-letter script scriptCode,...
Definition qlocale.cpp:1531
static QString languageToString(Language language)
Returns a QString containing the name of language.
Definition qlocale.cpp:1542
@ DataSizeBase1000
Definition qlocale.h:891
@ DataSizeSIQuantifiers
Definition qlocale.h:892
friend class QString
Definition qlocale.h:31
int toInt(const QString &s, bool *ok=nullptr) const
Returns the int represented by the localized string s.
Definition qlocale.h:936
static QString scriptToCode(Script script)
Returns the four-letter script code for script, as defined in the ISO 15924 standard.
Definition qlocale.cpp:1517
QString exponential() const
Definition qlocale.cpp:2642
QString pmText() const
Definition qlocale.cpp:3319
QString formattedDataSize(qint64 bytes, int precision=2, DataSizeFormats format=DataSizeIecFormat) const
Definition qlocale.cpp:4533
qulonglong toULongLong(const QString &s, bool *ok=nullptr) const
Returns the unsigned long long int represented by the localized string s.
Definition qlocale.h:946
QList< Qt::DayOfWeek > weekdays() const
Definition qlocale.cpp:3160
QString positiveSign() const
Definition qlocale.cpp:2624
QString toString(qlonglong i) const
Returns a localized string representation of i.
Definition qlocale.cpp:1962
QString name() const
The short name of this locale.
Definition qlocale.cpp:1340
ulong toULong(const QString &s, bool *ok=nullptr) const
Definition qlocale.h:942
QString standaloneMonthName(int, FormatType format=LongFormat) const
Definition qlocale.cpp:2849
NumberOptions numberOptions() const
Definition qlocale.cpp:1155
short toShort(const QString &s, bool *ok=nullptr) const
Returns the short int represented by the localized string s.
Definition qlocale.h:932
Territory territory() const
Definition qlocale.cpp:1303
qlonglong toLongLong(const QString &s, bool *ok=nullptr) const
Returns the long long int represented by the localized string s.
Definition qlocale.h:944
QLocale()
Constructs a QLocale object initialized with the default locale.
Definition qlocale.cpp:1032
ushort toUShort(const QString &s, bool *ok=nullptr) const
Returns the unsigned short int represented by the localized string s.
Definition qlocale.h:934
QString nativeLanguageName() const
Definition qlocale.cpp:4709
Script script() const
Definition qlocale.cpp:1291
static Language codeToLanguage(QStringView languageCode, LanguageCodeTypes codeTypes=AnyLanguageCode) noexcept
Returns the QLocale::Language enum corresponding to the two- or three-letter languageCode,...
Definition qlocale.cpp:1440
QString toLower(const QString &str) const
Definition qlocale.cpp:3278
QString standaloneDayName(int, FormatType format=LongFormat) const
Definition qlocale.cpp:2884
QString currencySymbol(CurrencySymbolFormat=CurrencySymbol) const
Definition qlocale.cpp:4386
~QLocale()
Destructor.
Definition qlocale.cpp:1090
friend class QLocalePrivate
Definition qlocale.h:1126
@ OmitGroupSeparator
Definition qlocale.h:869
@ RejectTrailingZeroesAfterDot
Definition qlocale.h:874
@ RejectLeadingZeroInExponent
Definition qlocale.h:872
@ IncludeTrailingZeroesAfterDot
Definition qlocale.h:873
@ OmitLeadingZeroInExponent
Definition qlocale.h:871
@ RejectGroupSeparator
Definition qlocale.h:870
@ DefaultNumberOptions
Definition qlocale.h:868
static QList< QLocale > matchingLocales(QLocale::Language language, QLocale::Script script, QLocale::Territory territory)
Returns a list of valid locale objects that match the given language, script and territory.
Definition qlocale.cpp:2762
static QLocale system()
Returns a QLocale object initialized to the system locale.
Definition qlocale.cpp:2742
@ LastLanguage
Definition qlocale.h:400
@ NorwegianBokmal
Definition qlocale.h:251
@ Filipino
Definition qlocale.h:125
@ Indonesian
Definition qlocale.h:154
@ Hebrew
Definition qlocale.h:145
@ AnyLanguage
Definition qlocale.h:42
@ Serbian
Definition qlocale.h:294
@ Yiddish
Definition qlocale.h:365
@ Romanian
Definition qlocale.h:277
\inmodule QtCore
Definition qmutex.h:285
void lock() noexcept
Locks the mutex.
Definition qmutex.h:290
\inmodule QtCore
Definition qshareddata.h:35
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:76
bool startsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
QString arg(Args &&...args) const
constexpr qsizetype size() const noexcept
Returns the size of this string view, in UTF-16 code units (that is, surrogate pairs count as two for...
QString toString() const
Returns a deep copy of this string view's data as a QString.
Definition qstring.h:1014
constexpr QChar at(qsizetype n) const noexcept
Returns the character at position n in this string view.
constexpr QChar front() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QByteArray toLatin1() const &
Definition qstring.h:559
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5299
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
Definition qstring.h:1173
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:898
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString toLower() const &
Definition qstring.h:368
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1095
QString sliced(qsizetype pos) const
Definition qstring.h:341
QString & append(QChar c)
Definition qstring.cpp:3227
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4420
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition qstring.cpp:3435
QString & prepend(QChar c)
Definition qstring.h:411
QString toUpper() const &
Definition qstring.h:372
const QChar * unicode() const
Returns a Unicode representation of the string.
Definition qstring.h:1085
void resize(qsizetype size)
Sets the size of the string to size characters.
Definition qstring.cpp:2654
qsizetype fallbackLocaleIndex() const
Definition qlocale_p.h:521
@ StringToAlternateQuotation
Definition qlocale_p.h:147
@ DateTimeToStringShort
Definition qlocale_p.h:135
@ StandaloneMonthNameLong
Definition qlocale_p.h:153
@ ListToSeparatedString
Definition qlocale_p.h:149
@ StandaloneDayNameNarrow
Definition qlocale_p.h:158
@ StandaloneMonthNameNarrow
Definition qlocale_p.h:155
@ StringToStandardQuotation
Definition qlocale_p.h:146
@ StandaloneDayNameShort
Definition qlocale_p.h:157
@ StandaloneDayNameLong
Definition qlocale_p.h:156
@ StandaloneMonthNameShort
Definition qlocale_p.h:154
virtual QVariant query(QueryType type, QVariant in=QVariant()) const
virtual ~QSystemLocale()
Definition qlocale.cpp:728
virtual QLocale fallbackLocale() const
\inmodule QtCore \reentrant
Definition qdatetime.h:189
int hour() const
Returns the hour part (0 to 23) of the time.
int minute() const
Returns the minute part (0 to 59) of the time.
bool isValid() const
Returns true if the time is valid; otherwise returns false.
int msec() const
Returns the millisecond part (0 to 999) of the time.
int second() const
Returns the second part (0 to 59) of the time.
constexpr size_type size() const noexcept
const T * constData() const
void push_back(const T &t)
\inmodule QtCore
Definition qvariant.h:64
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:531
QStringList toStringList() const
Returns the variant as a QStringList if the variant has userType() \l QMetaType::QStringList,...
QString str
[2]
QString text
QDate date
[1]
list append(new Employee("Blackpool", "Stephen"))
QStyleOptionButton opt
else opt state
[0]
short next
Definition keywords.cpp:445
Language
Definition language.h:13
Combined button and popup list for selecting options.
constexpr bool isAsciiDigit(char32_t c) noexcept
Definition qtools_p.h:67
constexpr bool isAsciiLetterOrNumber(char32_t c) noexcept
Definition qtools_p.h:82
constexpr bool isAsciiUpper(char32_t c) noexcept
Definition qtools_p.h:72
constexpr char toAsciiLower(char ch) noexcept
Definition qtools_p.h:87
static constexpr bool q_points_into_range(const T *p, const T *b, const T *e, Cmp less={}) noexcept
LayoutDirection
@ LeftToRight
@ RightToLeft
@ CaseInsensitive
constexpr Initialization Uninitialized
DayOfWeek
@ Sunday
@ Monday
constexpr auto ssize(const C &c) -> std::common_type_t< std::ptrdiff_t, std::make_signed_t< decltype(c.size())> >
Definition q20iterator.h:33
QT_POPCOUNT_RELAXED_CONSTEXPR uint qCountLeadingZeroBits(quint32 v) noexcept
#define Q_BASIC_ATOMIC_INITIALIZER(a)
static constexpr uchar asciiLower(uchar c)
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
int qstrncmp(const char *str1, const char *str2, size_t len)
size_t qstrnlen(const char *str, size_t maxlen)
#define Q_FALLTHROUGH()
#define Q_LIKELY(x)
#define QT_WARNING_DISABLE_GCC(text)
AudioChannelLayoutTag tag
static qsizetype digitCount(QStringView str)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
size_t qHash(const QFileSystemWatcherPathKey &key, size_t seed=0)
bool qIsFinite(qfloat16 f) noexcept
Definition qfloat16.h:239
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
constexpr QtPrivate::QHashMultiReturnType< T... > qHashMulti(size_t seed, const T &... args) noexcept(std::conjunction_v< QtPrivate::QNothrowHashable< T >... >)
static Q_CONSTINIT QSystemLocale * _systemLocale
Definition qlocale.cpp:67
QDataStream & operator<<(QDataStream &ds, const QLocale &l)
Definition qlocale.cpp:839
static constexpr qsizetype locale_data_size
Definition qlocale.cpp:854
static QLocalePrivate * findLocalePrivate(QLocale::Language language, QLocale::Script script, QLocale::Territory territory)
Definition qlocale.cpp:871
static std::optional< QString > systemLocaleString(const QLocaleData *that, QSystemLocale::QueryType type)
Definition qlocale.cpp:894
static const QSystemLocale * systemLocale()
Definition qlocale.cpp:743
static bool checkParsed(QByteArrayView num, qsizetype used)
Definition qlocale.cpp:4334
static QString rawWeekDayName(const QLocaleData *data, const int day, QLocale::FormatType type)
Definition qlocale.cpp:2946
QDataStream & operator>>(QDataStream &ds, QLocale &l)
Definition qlocale.cpp:845
static Q_CONSTINIT const QLocaleData * default_data
Definition qlocale.cpp:684
static Q_CONSTINIT QLocaleData systemLocaleData
Definition qlocale.cpp:68
#define CheckCandidate(id)
static QString rawStandaloneWeekDayName(const QLocaleData *data, const int day, QLocale::FormatType type)
Definition qlocale.cpp:2970
static QStringView findTag(QStringView name) noexcept
Definition qlocale.cpp:535
static bool validTag(QStringView tag)
Definition qlocale.cpp:544
static QLocalePrivate * c_private()
Definition qlocale.cpp:686
static bool isScript(QStringView tag)
Definition qlocale.cpp:555
static T toIntegral_helper(const QLocalePrivate *d, QStringView str, bool *ok)
Definition qlocale.cpp:1357
static bool timeFormatContainsAP(QStringView format)
Definition qlocale.cpp:2098
qsizetype qt_repeatCount(QStringView s)
Definition qlocale.cpp:673
bool qt_splitLocaleName(QStringView name, QStringView *lang, QStringView *script, QStringView *land)
Definition qlocale.cpp:565
static void updateSystemPrivate()
Definition qlocale.cpp:755
static QString rawMonthName(const QCalendarLocale &localeData, const char16_t *monthsData, int month, QLocale::FormatType type)
Definition qlocale.cpp:2895
QString qt_readEscapedFormatString(QStringView format, qsizetype *idx)
Definition qlocale.cpp:623
static qsizetype findLocaleIndexById(const QLocaleId &localeId)
Definition qlocale.cpp:466
static const QLocaleData * defaultData()
Definition qlocale.cpp:809
static QString rawStandaloneMonthName(const QCalendarLocale &localeData, const char16_t *monthsData, int month, QLocale::FormatType type)
Definition qlocale.cpp:2920
static QString localeString(const QLocaleData *that, QSystemLocale::QueryType type, QLocaleData::DataRange range)
Definition qlocale.cpp:912
static const QLocaleData * systemData()
Definition qlocale.cpp:786
static qsizetype defaultIndex()
Definition qlocale.cpp:816
static constexpr char16_t single_character_data[]
static constexpr char16_t days_data[]
static constexpr quint16 locale_index[]
static constexpr char16_t pm_data[]
static constexpr TerritoryLanguage ImperialMeasurementSystems[]
static constexpr QLocaleData locale_data[]
static constexpr char16_t endonyms_data[]
static constexpr QLocaleId likely_subtags[]
constexpr std::array< LanguageCodeEntry, 337 > languageCodeList
static constexpr char territory_name_list[]
static constexpr char16_t am_data[]
static constexpr char16_t currency_format_data[]
static constexpr unsigned char territory_code_list[]
static constexpr quint16 territory_name_index[]
static constexpr char language_name_list[]
static constexpr quint16 script_name_index[]
static constexpr char16_t byte_unit_data[]
static constexpr quint16 language_name_index[]
static constexpr char16_t list_pattern_part_data[]
static constexpr char16_t date_format_data[]
static constexpr char16_t currency_display_name_data[]
static constexpr char16_t time_format_data[]
static constexpr char script_name_list[]
static constexpr char16_t currency_symbol_data[]
static constexpr unsigned char script_code_list[]
bool qt_splitLocaleName(QStringView name, QStringView *lang=nullptr, QStringView *script=nullptr, QStringView *cntry=nullptr)
Definition qlocale.cpp:565
constexpr bool ascii_isspace(uchar c)
Definition qlocale_p.h:539
QT_CLOCALE_HOLDER void qt_doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, qsizetype bufSize, bool &sign, int &length, int &decpt)
static constexpr int digits(int number)
QSimpleParsedNumber< qlonglong > qstrntoll(const char *begin, qsizetype size, int base)
QSimpleParsedNumber< qulonglong > qstrntoull(const char *begin, qsizetype size, int base)
QString qulltoa(qulonglong number, int base, const QStringView zero)
QSimpleParsedNumber< double > qt_asciiToDouble(const char *num, qsizetype numLen, StrayCharacterMode strayCharMode)
constexpr bool isZero(double d)
int wholePartSpace(double d)
UcsInt unicodeForDigit(uint digit, UcsInt zero)
#define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG)
Definition qmetatype.h:1363
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLenum mode
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLenum GLuint id
[7]
GLdouble GLdouble right
GLfloat GLfloat f
GLsizei range
GLint GLsizei width
GLint left
GLenum type
GLboolean GLuint group
GLenum GLuint GLenum GLsizei const GLchar * buf
GLbitfield flags
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLuint name
GLsizei bufSize
GLfloat n
GLint GLsizei GLsizei GLenum format
GLenum query
GLuint res
const GLubyte * c
GLuint GLfloat * val
GLuint entry
GLfloat bias
GLenum GLsizei len
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
GLuint num
GLenum GLint GLint * precision
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static bool operator<(const QSettingsIniKey &k1, const QSettingsIniKey &k2)
static constexpr QChar sep
static ISC_DATE toDate(QDate t)
static ISC_TIME toTime(QTime t)
SSL_CTX int(*) void arg)
#define QStringLiteral(str)
QStringView qToStringViewIgnoringNull(const QStringLike &s) noexcept
#define zero
#define QT_BEGIN_INCLUDE_NAMESPACE
#define QT_END_INCLUDE_NAMESPACE
#define Q_UNUSED(x)
static int compare(quint64 a, quint64 b)
unsigned char uchar
Definition qtypes.h:27
unsigned short quint16
Definition qtypes.h:43
unsigned long ulong
Definition qtypes.h:30
quint64 qulonglong
Definition qtypes.h:59
unsigned long long quint64
Definition qtypes.h:56
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned int uint
Definition qtypes.h:29
long long qint64
Definition qtypes.h:55
unsigned short ushort
Definition qtypes.h:28
qint64 qlonglong
Definition qtypes.h:58
QT_END_NAMESPACE typedef QT_PREPEND_NAMESPACE(quintptr) WId
static QByteArray getData(int cf, IDataObject *pDataObj, int lindex=-1)
static QString getString(IMFActivate *device, const IID &id)
QList< int > list
[14]
QTextStream out(stdout)
[7]
MyCustomStruct c2
QDateTime dateTime
[12]
QSharedPointer< T > other(t)
[5]
QQuickView * view
[0]
std::array< char, 4 > decode() const
bool isValid(NumberMode mode) const
Definition qlocale_p.h:348
static quint64 bytearrayToUnsLongLong(QByteArrayView num, int base, bool *ok)
Definition qlocale.cpp:4361
QString positiveSign() const
Definition qlocale.cpp:966
static float convertDoubleToFloat(double d, bool *ok)
Definition qlocale_p.h:283
QString groupSeparator() const
Definition qlocale.cpp:925
char32_t zeroUcs() const
Definition qlocale.cpp:945
quint8 m_grouping_least
Definition qlocale_p.h:470
QString zeroDigit() const
Definition qlocale.cpp:940
bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options, NumberMode mode, CharBuff *result) const
Definition qlocale.cpp:4096
quint8 m_grouping_top
Definition qlocale_p.h:468
quint8 m_grouping_higher
Definition qlocale_p.h:469
QString decimalPoint() const
Definition qlocale.cpp:920
QString doubleToString(double d, int precision=-1, DoubleForm form=DFSignificantDigits, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3546
quint8 m_weekend_start
Definition qlocale_p.h:466
quint8 m_currency_digits
Definition qlocale_p.h:463
static const QLocaleData * c()
Definition qlocale.cpp:832
QLocaleId id() const
Definition qlocale_p.h:369
QString listSeparator() const
Definition qlocale.cpp:935
static qsizetype findLocaleIndex(QLocaleId localeId)
Definition qlocale.cpp:485
quint64 stringToUnsLongLong(QStringView str, int base, bool *ok, QLocale::NumberOptions options) const
Definition qlocale.cpp:4321
qint64 stringToLongLong(QStringView str, int base, bool *ok, QLocale::NumberOptions options) const
Definition qlocale.cpp:4308
QString percentSign() const
Definition qlocale.cpp:930
@ BlankBeforePositive
Definition qlocale_p.h:237
@ AddTrailingZeroes
Definition qlocale_p.h:234
Q_CORE_EXPORT bool validateChars(QStringView str, NumberMode numMode, QByteArray *buff, int decDigits=-1, QLocale::NumberOptions number_options=QLocale::DefaultNumberOptions) const
Definition qlocale.cpp:4204
double stringToDouble(QStringView str, bool *ok, QLocale::NumberOptions options) const
Definition qlocale.cpp:4293
QString longLongToString(qint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3785
@ DoubleScientificMode
Definition qlocale_p.h:248
@ DFSignificantDigits
Definition qlocale_p.h:228
quint8 m_first_day_of_week
Definition qlocale_p.h:465
quint8 m_weekend_end
Definition qlocale_p.h:467
NumericData numericData(NumberMode mode) const
Definition qlocale.cpp:3869
QString exponentSeparator() const
Definition qlocale.cpp:971
QString negativeSign() const
Definition qlocale.cpp:961
static Q_CORE_EXPORT qint64 bytearrayToLongLong(QByteArrayView num, int base, bool *ok)
Definition qlocale.cpp:4352
QString unsLongLongToString(quint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:3800
QLocaleId withLikelySubtagsRemoved() const
Definition qlocale.cpp:380
bool matchesAll() const
Definition qlocale_p.h:188
ushort script_id
Definition qlocale_p.h:210
bool acceptLanguage(quint16 lang) const
Definition qlocale_p.h:193
bool acceptScriptTerritory(QLocaleId other) const
Definition qlocale_p.h:199
QLocaleId withLikelySubtagsAdded() const
Fill in blank fields of a locale ID.
Definition qlocale.cpp:296
ushort territory_id
Definition qlocale_p.h:210
QByteArray name(char separator='-') const
Definition qlocale.cpp:404
ushort language_id
Definition qlocale_p.h:210
static Q_AUTOTEST_EXPORT QLocaleId fromName(QStringView name)
Definition qlocale.cpp:609