Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qlocale_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2016 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// Qt-Security score:critical reason:data-parser
5
6#ifndef QLOCALE_P_H
7#define QLOCALE_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists for the convenience
14// of internal files. This header file may change from version to version
15// without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include "qlocale.h"
21
22#include <QtCore/qcalendar.h>
23#include <QtCore/qlist.h>
24#include <QtCore/qnumeric.h>
25#include <QtCore/private/qnumeric_p.h>
26#include <QtCore/qstring.h>
27#include <QtCore/qvariant.h>
28#include <QtCore/qvarlengtharray.h>
29#ifdef Q_OS_WASM
30#include <private/qstdweb_p.h>
31#endif
32
33#include <limits>
34#include <cmath>
35#include <string_view>
36
37QT_BEGIN_NAMESPACE
38
39template <typename T> struct QSimpleParsedNumber
40{
41 T result;
42 // When used < 0, -used is how much was used, but it was an error.
43 qsizetype used;
44 bool ok() const { return used > 0; }
45};
46
47template <int Extent, uchar Lowest> struct QCharacterSetMatch
48{
50 static constexpr int WordBits = std::numeric_limits<Word>::digits;
51 static constexpr int MaxRange = WordBits * Extent;
53
54 constexpr QCharacterSetMatch(std::string_view set) noexcept
55 : mask{}
56 {
57 for (char c : set) {
58 auto [offset, shift] = maskLocation(c);
59 mask[offset] |= Word(1) << shift;
60 }
61 }
62
63 constexpr bool matches(uchar c) const noexcept
64 {
65 auto [offset, shift] = maskLocation(c);
66 if (offset < 0)
67 return false;
68 Word m = 0;
69 if constexpr (Extent == 2) {
70 // special case for faster code (with GCC, at least)
71 m = (c - Lowest < WordBits) ? mask[0] : mask[1];
72 } else {
73 m = mask[offset];
74 }
75 return (m >> shift) & 1;
76 }
77
78 constexpr auto maskLocation(uchar c) const noexcept
79 {
80 struct { int offset; int shift; } r = { -1, -1 };
81 unsigned idx = c - Lowest;
82 if (idx < MaxRange) {
83 r.offset = idx / WordBits;
84 r.shift = idx % WordBits;
85 }
86 return r;
87 }
88};
89
90namespace QtPrivate {
91inline constexpr char ascii_space_chars[] =
92 "\t" // 9: HT - horizontal tab
93 "\n" // 10: LF - line feed
94 "\v" // 11: VT - vertical tab
95 "\f" // 12: FF - form feed
96 "\r" // 13: CR - carriage return
97 " "; // 32: space
98
99template <const char *Set, int ForcedLowest = -1>
100inline constexpr auto makeCharacterSetMatch() noexcept
101{
102 constexpr int BitsPerWord = std::numeric_limits<qregisteruint>::digits;
103 constexpr auto view = std::string_view(Set);
104 constexpr uchar MinElement = *std::min_element(view.begin(), view.end());
105 constexpr uchar MaxElement = *std::max_element(view.begin(), view.end());
106 constexpr int Range = MaxElement - MinElement;
107 constexpr int Extent = (Range + BitsPerWord - 1) / BitsPerWord;
108 constexpr int TotalBits = BitsPerWord * Extent;
109
110 if constexpr (ForcedLowest >= 0) {
111 // use the force
112 static_assert(ForcedLowest <= int(MinElement), "The force is not with you");
113 static_assert(ForcedLowest + TotalBits >= MaxElement, "The force is not with you");
114 return QCharacterSetMatch<Extent, ForcedLowest>(view);
115 } else if constexpr (MaxElement < TotalBits) {
116 // if we can use a Lowest of zero, we can remove a subtraction
117 // from the matches() code at runtime
118 return QCharacterSetMatch<Extent, 0>(view);
119 } else {
120 return QCharacterSetMatch<Extent, MinElement>(view);
121 }
122}
123} // QtPrivate
124
125// Subclassed by Android platform plugin:
126class Q_CORE_EXPORT QSystemLocale
127{
128 Q_DISABLE_COPY_MOVE(QSystemLocale)
129 QSystemLocale *next = nullptr; // Maintains a stack.
130
131public:
132 QSystemLocale();
133 virtual ~QSystemLocale();
134
136 {
138 CurrencyToStringArgument(const QVariant &v, const QString &s)
139 : value(v), symbol(s) { }
140 QVariant value;
141 QString symbol;
142 };
143
145 LanguageId, // uint
146 TerritoryId, // uint
147 DecimalPoint, // QString
148 Grouping, // QLocaleData::GroupSizes
149 GroupSeparator, // QString (empty QString means: don't group digits)
150 ZeroDigit, // QString
151 NegativeSign, // QString
152 DateFormatLong, // QString
153 DateFormatShort, // QString
154 TimeFormatLong, // QString
155 TimeFormatShort, // QString
156 DayNameLong, // QString, in: int
157 DayNameShort, // QString, in: int
158 DayNameNarrow, // QString, in: int
159 MonthNameLong, // QString, in: int
160 MonthNameShort, // QString, in: int
161 MonthNameNarrow, // QString, in: int
162 DateToStringLong, // QString, in: QDate
163 DateToStringShort, // QString in: QDate
164 TimeToStringLong, // QString in: QTime
165 TimeToStringShort, // QString in: QTime
168 DateTimeToStringLong, // QString in: QDateTime
169 DateTimeToStringShort, // QString in: QDateTime
171 PositiveSign, // QString
172 AMText, // QString
173 PMText, // QString
174 FirstDayOfWeek, // Qt::DayOfWeek
175 Weekdays, // QList<Qt::DayOfWeek>
176 CurrencySymbol, // QString in: CurrencyToStringArgument
177 CurrencyToString, // QString in: qlonglong, qulonglong or double
178 Collation, // QString
179 UILanguages, // QStringList
180 StringToStandardQuotation, // QString in: QStringView to quote
181 StringToAlternateQuotation, // QString in: QStringView to quote
182 ScriptId, // uint
184 LocaleChanged, // system locale changed
187 StandaloneMonthNameLong, // QString, in: int
188 StandaloneMonthNameShort, // QString, in: int
189 StandaloneMonthNameNarrow, // QString, in: int
190 StandaloneDayNameLong, // QString, in: int
191 StandaloneDayNameShort, // QString, in: int
192 StandaloneDayNameNarrow // QString, in: int
193 };
194 virtual QVariant query(QueryType type, QVariant &&in = QVariant()) const;
195
196 virtual QLocale fallbackLocale() const;
197 inline qsizetype fallbackLocaleIndex() const;
198
199protected:
200 inline const QSharedDataPointer<QLocalePrivate> localeData(const QLocale &locale) const
201 {
202 return locale.d;
203 }
204};
205Q_DECLARE_TYPEINFO(QSystemLocale::QueryType, Q_PRIMITIVE_TYPE);
206Q_DECLARE_TYPEINFO(QSystemLocale::CurrencyToStringArgument, Q_RELOCATABLE_TYPE);
207
209{
210 [[nodiscard]] Q_AUTOTEST_EXPORT static QLocaleId fromName(QStringView name) noexcept;
211 [[nodiscard]] inline bool operator==(QLocaleId other) const noexcept
212 { return language_id == other.language_id && script_id == other.script_id && territory_id == other.territory_id; }
213 [[nodiscard]] inline bool operator!=(QLocaleId other) const noexcept
214 { return !operator==(other); }
215 [[nodiscard]] inline bool isValid() const noexcept
216 {
217 return language_id <= QLocale::LastLanguage && script_id <= QLocale::LastScript
218 && territory_id <= QLocale::LastTerritory;
219 }
220 [[nodiscard]] inline bool matchesAll() const noexcept
221 {
222 return !language_id && !script_id && !territory_id;
223 }
224 // Use as: filter.accept...(candidate)
225 [[nodiscard]] inline bool acceptLanguage(quint16 lang) const noexcept
226 {
227 // Always reject AnyLanguage (only used for last entry in locale_data array).
228 // So, when searching for AnyLanguage, accept everything *but* AnyLanguage.
229 return language_id ? lang == language_id : lang;
230 }
231 [[nodiscard]] inline bool acceptScriptTerritory(QLocaleId other) const noexcept
232 {
233 return (!territory_id || other.territory_id == territory_id)
234 && (!script_id || other.script_id == script_id);
235 }
236 [[nodiscard]] inline bool sameLanguageScript(QLocaleId other) const noexcept
237 {
238 return language_id && language_id == other.language_id
239 && script_id == other.script_id;
240 }
241
242 [[nodiscard]] QLocaleId withLikelySubtagsAdded() const noexcept;
243 [[nodiscard]] QLocaleId withLikelySubtagsRemoved() const noexcept;
244
245 [[nodiscard]] Q_AUTOTEST_EXPORT QByteArray name(char separator = '-') const;
246
247 ushort language_id = 0, script_id = 0, territory_id = 0;
248};
250
252{
253public:
254 // Having an index for each locale enables us to have diverse sources of
255 // data, e.g. calendar locales, as well as the main CLDR-derived data.
256 [[nodiscard]] Q_AUTOTEST_EXPORT static qsizetype findLocaleIndex(QLocaleId localeId) noexcept;
257 [[nodiscard]] Q_AUTOTEST_EXPORT static const QLocaleData *c() noexcept;
258 [[nodiscard]] Q_AUTOTEST_EXPORT
259 static bool allLocaleDataRows(bool (*check)(qsizetype, const QLocaleData &));
260 [[nodiscard]] Q_AUTOTEST_EXPORT
261 static const QLocaleData *dataForLocaleIndex(qsizetype index);
262
269
285
287
288 struct GroupSizes // Numbers of digits in various groups:
289 {
290 int first = 0; // Min needed before the separator, when there's only one.
291 int higher = 0; // Each group between separators.
292 int least = 0; // Least significant, when any separators appear.
293 bool isValid() const { return least > 0 && higher > first && first > 0; }
294 };
295
296 using CharBuff = QVarLengthArray<char, 256>;
297
299 {
300 enum State { // A duplicate of QValidator::State
304 };
305
308 };
309
310private:
311 enum PrecisionMode {
312 PMDecimalDigits = 0x01,
313 PMSignificantDigits = 0x02,
314 PMChopTrailingZeros = 0x03
315 };
316
317 [[nodiscard]] QString decimalForm(QString &&digits, int decpt, int precision,
318 PrecisionMode pm, bool mustMarkDecimal,
319 bool groupDigits) const;
320 [[nodiscard]] QString exponentForm(QString &&digits, int decpt, int precision,
321 PrecisionMode pm, bool mustMarkDecimal,
322 int minExponentDigits) const;
323 [[nodiscard]] QString signPrefix(bool negative, unsigned flags) const;
324 [[nodiscard]] QString applyIntegerFormatting(QString &&numStr, bool negative, int precision,
325 int base, int width, unsigned flags) const;
326
327public:
328 [[nodiscard]] QString doubleToString(double d,
329 int precision = -1,
331 int width = -1,
332 unsigned flags = NoFlags) const;
333 [[nodiscard]] QString longLongToString(qint64 l, int precision = -1,
334 int base = 10,
335 int width = -1,
336 unsigned flags = NoFlags) const;
337 [[nodiscard]] QString unsLongLongToString(quint64 l, int precision = -1,
338 int base = 10,
339 int width = -1,
340 unsigned flags = NoFlags) const;
341
342 // this function is meant to be called with the result of stringToDouble or bytearrayToDouble
343 // so *ok must have been properly set (if not null)
344 [[nodiscard]] static float convertDoubleToFloat(double d, bool *ok)
345 {
346 float result;
347 bool b = convertDoubleTo<float>(d, &result);
348 if (ok && *ok)
349 *ok = b;
350 return result;
351 }
352
353 [[nodiscard]] double stringToDouble(QStringView str, bool *ok,
354 QLocale::NumberOptions options) const;
355 [[nodiscard]] QSimpleParsedNumber<qint64>
356 stringToLongLong(QStringView str, int base, QLocale::NumberOptions options) const;
357 [[nodiscard]] QSimpleParsedNumber<quint64>
358 stringToUnsLongLong(QStringView str, int base, QLocale::NumberOptions options) const;
359
360 // this function is used in QIntValidator (QtGui)
363 [[nodiscard]] static QSimpleParsedNumber<quint64>
364 bytearrayToUnsLongLong(QByteArrayView num, int base);
365
366 [[nodiscard]] bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options,
367 NumberMode mode, CharBuff *result) const;
368
370 {
371#ifndef QT_NO_SYSTEMLOCALE
372 // Only used for the system locale, to store data for the view to look at:
374#endif
377 char32_t zeroUcs = 0;
379 bool exponentCyrillic = false; // True only for floating-point parsing of Cyrillic.
380 const bool isC; // C locale sets this and nothing else.
381
382 void setZero(QStringView zero)
383 {
384 Q_PRE(!isC);
385 // No known locale has digits that are more than one Unicode
386 // code-point, so we can safely deal with digits as plain char32_t.
387 switch (zero.size()) {
388 case 1:
389 Q_ASSERT(!zero.at(0).isSurrogate());
390 zeroUcs = zero.at(0).unicode();
391 Q_ASSERT(!QChar::requiresSurrogates(zeroUcs + 9));
392 zeroLen = 1;
393 break;
394 case 2:
395 Q_ASSERT(zero.at(0).isHighSurrogate());
396 Q_ASSERT(zero.at(1).isLowSurrogate());
397 zeroUcs = QChar::surrogateToUcs4(zero.at(0), zero.at(1));
398 Q_ASSERT(QChar::requiresSurrogates(zeroUcs));
399 zeroLen = 2;
400 break;
401 default:
402 Q_ASSERT(zero.size() == 0); // i.e. we got no value to use
403 break;
404 }
405 }
406 Q_NODISCARD_CTOR Q_AUTOTEST_EXPORT
408
409 [[nodiscard]] qsizetype zeroWidth() const { return isC ? 1 : zeroLen; }
410 [[nodiscard]] const GroupSizes &groupSizes() const { return grouping; }
411
412 [[nodiscard]] bool isValid(NumberMode mode) const // Asserted as a sanity check.
413 {
414 if (isC)
415 return true;
416 if (exponentCyrillic && exponent != u"E" && exponent != u"\u0415")
417 return false;
418 return (zeroLen == 1 || zeroLen == 2) && zeroUcs > 0
419 && (mode == IntegerMode || !decimal.isEmpty())
420 // group may be empty (user config in system locale)
421 && !minus.isEmpty() && !plus.isEmpty()
422 && (mode != DoubleScientificMode || !exponent.isEmpty());
423 }
424
425 [[nodiscard]] qint8 digitValue(char32_t digit) const
426 {
427 // Compute locale-appropriate digit value (or -1)
428 if (!isC && zeroUcs != U'0') {
429 // Must match qlocale_tools_p.h's unicodeForDigit().
430 if (digit == zeroUcs || zeroUcs != U'\u3007') {
431 if (qint32 ans = digit - zeroUcs; 0 <= ans && ans <= 9)
432 return qint8(ans);
433 } else if (digit > U'\u3020') {
434 if (qint32 ans = digit - U'\u3020'; 0 <= ans && ans <= 9)
435 return qint8(ans);
436 }
437 // Accepting ASCII with zeroLen != 1 would mess up code that
438 // assumes consistent digit width.
439 if (zeroLen != 1)
440 return -1;
441 }
442 qint32 ans = digit - U'0';
443 return qint8(0 <= ans && ans <= 9 ? ans : -1);
444 }
445
446 [[nodiscard]] bool fractionalIsGroup() const
447 {
448 // True precisely if fractional part separator and digit-grouping
449 // separator are the same. This can happen due to user
450 // mis-configuration. (Our CLDR-digestion scripts check against CLDR
451 // having such clashes.)
452 // For C locale we don't store separators, we just know them.
453 return Q_UNLIKELY(!isC && group == decimal);
454 }
455 };
456
458 {
459 QByteArray digits; // ASCII digits
460 // Indices of (starts of) digits and the index just after the last digit:
462 // digits.sliced(n, m), a.k.a. digits.first(n+m).sliced(n), comes from
463 // text.first(digitBounds(n+m)).sliced(digitBounds[n])
464 char sign = '\0'; // '\0' for unspecified, or '-' or '+' if specified.
465
466 enum class Option {
469 };
471
472 Q_AUTOTEST_EXPORT // All the hard work is in this constructor:
475 qsizetype from = 0);
476 DigitSequence(const DigitSequence &) = default;
480 ~DigitSequence() = default;
481
482 // Where in text did the parse end:
484 {
485 return digitBounds.back();
486 }
487
488 // How many ASCII characters the sequence transcribes to:
490 {
491 return digits.size() + (hasSign() ? 1 : 0);
492 }
493
494 bool isEmpty() const { return size() == 0; }
495 bool hasSign() const { return sign != '\0'; }
496
497 void transcribeTo(CharBuff *buff) const
498 {
499 if (sign)
500 buff->append(sign);
501 buff->append(digits.constData(), digits.size());
502 }
503
504 // Subsequences (for when partitioning among fields).
505 // Sign, when present, is treated as entry 0, bumping digit indices up by 1.
506 // Generally, first(c) and sliced(c) abut but don't overlap.
507 DigitSequence first(qsizetype count) const
508 {
509 Q_PRE(count >= 0);
510 Q_PRE(count <= size());
511 const qsizetype n = hasSign() ? count - 1 : count;
512 // Stop at end of last included (sign or) digit:
513 return { digits.first(n), digitBounds.first(n + 1), count ? sign : '\0' };
514 }
515 DigitSequence last(qsizetype count) const
516 { return sliced(size() - count); }
517 DigitSequence sliced(qsizetype from) const
518 {
519 Q_PRE(from >= 0);
520 Q_PRE(from <= size());
521 const qsizetype n = hasSign() ? from - 1 : from;
522 Q_ASSERT(n <= digits.size());
523 return { digits.sliced(n), digitBounds.sliced(n), from ? '\0' : sign };
524 }
525 DigitSequence sliced(qsizetype from, qsizetype count) const
526 { return sliced(from).first(count); }
527
528 // Portion of the view from which it was constructed:
529 [[nodiscard]] QStringView used(const QStringView text, qsizetype from) const
530 { return text.first(endIndex()).sliced(from); }
531 [[nodiscard]] QStringView used(const QStringView text) const // digits-only:
532 { return text.first(digitBounds.back()).sliced(digitBounds.front()); }
533 // (can apply to the first()/last()/sliced() of the result of parsing)
534 private:
535 // Used by first(), sliced():
536 DigitSequence(QByteArray &&digs, QList<qsizetype> &&bounds, char sgn)
537 : digits(std::move(digs)), digitBounds(std::move(bounds)), sign(sgn)
538 {
539 }
540 };
541
542 [[nodiscard]]
543 DigitSequence digitSequence(QStringView text,
544 DigitSequence::Options flags = DigitSequence::Option::Default,
545 qsizetype from = 0) const
546 { return DigitSequence(text, NumericData(this, IntegerMode), flags, from); }
547
548 // this function is used in QIntValidator (QtGui)
552
553 // Access to assorted data members:
554 [[nodiscard]] QLocaleId id() const
555 { return QLocaleId { m_language_id, m_script_id, m_territory_id }; }
556
557 [[nodiscard]] QString decimalPoint() const;
558 [[nodiscard]] QString groupSeparator() const;
559 [[nodiscard]] QString listSeparator() const;
560 [[nodiscard]] QString percentSign() const;
561 [[nodiscard]] QString zeroDigit() const;
562 [[nodiscard]] Q_AUTOTEST_EXPORT char32_t zeroUcs() const;
563 [[nodiscard]] QString positiveSign() const;
564 [[nodiscard]] QString negativeSign() const;
565 [[nodiscard]] QString exponentSeparator() const;
567
569 {
570 using Index = quint32;
571 Index offset; // Some zone data tables are big.
572 Index size; // (for consistency and to avoid struct-padding)
573 [[nodiscard]] QString getData(const char16_t *table) const
574 {
575 return size > 0
576 ? QString::fromRawData(stringStart(table), stringSize())
577 : QString();
578 }
579 [[nodiscard]] QStringView viewData(const char16_t *table) const
580 {
581 return { stringStart(table), stringSize() };
582 }
583 [[nodiscard]] QString getListEntry(const char16_t *table, qsizetype index) const
584 {
585 return listEntry(table, index).getData(table);
586 }
587 [[nodiscard]] QStringView viewListEntry(const char16_t *table, qsizetype index) const
588 {
589 return listEntry(table, index).viewData(table);
590 }
591 [[nodiscard]] char32_t ucsFirst(const char16_t *table) const
592 {
593 if (size && !QChar::isSurrogate(table[offset]))
594 return table[offset];
595 if (size > 1 && QChar::isHighSurrogate(table[offset]))
596 return QChar::surrogateToUcs4(table[offset], table[offset + 1]);
597 return 0;
598 }
599 private:
600 [[nodiscard]] const QChar *stringStart(const char16_t *table) const
601 {
602 return reinterpret_cast<const QChar *>(table + offset);
603 }
604 [[nodiscard]] qsizetype stringSize() const
605 {
606 // On 32-bit platforms, this is a narrowing cast, but the size has
607 // always come from an 8-bit or 16-bit table value so can't actually
608 // have a problem with that.
609 qsizetype result = static_cast<qsizetype>(size);
610 Q_ASSERT(result >= 0);
611 return result;
612 }
613 [[nodiscard]] DataRange listEntry(const char16_t *table, qsizetype index) const
614 {
615 constexpr char16_t separator = u';';
616 Index i = 0;
617 while (index > 0 && i < size) {
618 if (table[offset + i] == separator)
619 index--;
620 i++;
621 }
622 Index end = i;
623 while (end < size && table[offset + end] != separator)
624 end++;
625 return { offset + i, end - i };
626 }
627 };
628
629#define ForEachQLocaleRange(X)
630 X(startListPattern) X(midListPattern) X(endListPattern) X(pairListPattern) X(listDelimit)
631 X(decimalSeparator) X(groupDelim) X(percent) X(zero) X(minus) X(plus) X(exponential)
632 X(quoteStart) X(quoteEnd) X(quoteStartAlternate) X(quoteEndAlternate)
633 X(longDateFormat) X(shortDateFormat) X(longTimeFormat) X(shortTimeFormat)
634 X(longDayNamesStandalone) X(longDayNames)
635 X(shortDayNamesStandalone) X(shortDayNames)
636 X(narrowDayNamesStandalone) X(narrowDayNames)
637 X(anteMeridiem) X(postMeridiem)
638 X(byteCount) X(byteAmountSI) X(byteAmountIEC)
639 X(currencySymbol) X(currencyDisplayName)
640 X(currencyFormat) X(currencyFormatNegative)
641 X(endonymLanguage) X(endonymTerritory)
642
643#define rangeGetter(name)
644 [[nodiscard]] DataRange name() const { return { m_ ## name ## _idx, m_ ## name ## _size }; }
646#undef rangeGetter
647
648public:
649 quint16 m_language_id, m_script_id, m_territory_id;
650
651 // Offsets, then sizes, for each range:
652#define rangeIndex(name) quint16 m_ ## name ## _idx;
654#undef rangeIndex
655#define Size(name) quint8 m_ ## name ## _size;
657#undef Size
658
659#undef ForEachQLocaleRange
660
661 // Strays:
662 char m_currency_iso_code[3];
664 quint8 m_currency_rounding : 3; // (not yet used !)
668 quint8 m_grouping_first : 2; // Don't group until more significant group has this many digits.
669 quint8 m_grouping_higher : 3; // Number of digits between grouping separators
670 quint8 m_grouping_least : 3; // Number of digits after last grouping separator (before decimal).
671};
672
673Q_DECLARE_OPERATORS_FOR_FLAGS(QLocaleData::DigitSequence::Options)
674Q_DECLARE_TYPEINFO(QLocaleData::GroupSizes, Q_PRIMITIVE_TYPE);
675
677{
678public:
679 constexpr QLocalePrivate(const QLocaleData *data, qsizetype index,
680 QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions,
681 int refs = 0)
684
685 [[nodiscard]] quint16 languageId() const { return m_data->m_language_id; }
686 [[nodiscard]] quint16 territoryId() const { return m_data->m_territory_id; }
687
688 [[nodiscard]] QByteArray bcp47Name(char separator = '-') const;
689
690 [[nodiscard]] inline std::array<char, 4>
691 languageCode(QLocale::LanguageCodeTypes codeTypes = QLocale::AnyLanguageCode) const
692 {
693 return languageToCode(QLocale::Language(m_data->m_language_id), codeTypes);
694 }
695 [[nodiscard]] inline QLatin1StringView scriptCode() const
696 { return scriptToCode(QLocale::Script(m_data->m_script_id)); }
697 [[nodiscard]] inline QLatin1StringView territoryCode() const
698 { return territoryToCode(QLocale::Territory(m_data->m_territory_id)); }
699
700 [[nodiscard]] static const QLocalePrivate *get(const QLocale &l) { return l.d; }
701 [[nodiscard]] static std::array<char, 4>
702 languageToCode(QLocale::Language language,
703 QLocale::LanguageCodeTypes codeTypes = QLocale::AnyLanguageCode);
704 [[nodiscard]] static QLatin1StringView scriptToCode(QLocale::Script script);
705 [[nodiscard]] static QLatin1StringView territoryToCode(QLocale::Territory territory);
706 [[nodiscard]] static QLocale::Language
707 codeToLanguage(QStringView code,
708 QLocale::LanguageCodeTypes codeTypes = QLocale::AnyLanguageCode) noexcept;
709 [[nodiscard]] static QLocale::Script codeToScript(QStringView code) noexcept;
710 [[nodiscard]] static QLocale::Territory codeToTerritory(QStringView code) noexcept;
711
712 [[nodiscard]] QLocale::MeasurementSystem measurementSystem() const;
713
714 [[nodiscard]] QString toUpper(const QString &str, bool *ok) const;
715 [[nodiscard]] QString toLower(const QString &str, bool *ok) const;
716
717 // System locale has an m_data all its own; all others have m_data = locale_data + m_index
718 const QLocaleData *const m_data;
720 qsizetype m_index; // System locale needs this updated when m_data->id() changes.
722
724};
725
726#ifndef QT_NO_SYSTEMLOCALE
727qsizetype QSystemLocale::fallbackLocaleIndex() const { return fallbackLocale().d->m_index; }
728#endif
729
730template <>
731inline QLocalePrivate *QSharedDataPointer<QLocalePrivate>::clone()
732{
733 // cannot use QLocalePrivate's copy constructor
734 // since it is deleted in C++11
735 return new QLocalePrivate(d->m_data, d->m_index, d->m_numberOptions);
736}
737
738// Also used to merely skip over an escape in a format string, advancint idx to
739// point after it (so not [[nodiscard]]):
740QString qt_readEscapedFormatString(QStringView format, qsizetype *idx);
741[[nodiscard]] bool qt_splitLocaleName(QStringView name, QStringView *lang = nullptr,
742 QStringView *script = nullptr,
743 QStringView *cntry = nullptr) noexcept;
744
745[[nodiscard]] constexpr inline bool ascii_isspace(uchar c) noexcept
746{
747 constexpr auto matcher = QtPrivate::makeCharacterSetMatch<QtPrivate::ascii_space_chars>();
748 return matcher.matches(c);
749}
750
751QT_END_NAMESPACE
752
753// ### move to qnamespace.h
754QT_DECL_METATYPE_EXTERN_TAGGED(QList<Qt::DayOfWeek>, QList_Qt__DayOfWeek, Q_CORE_EXPORT)
755#ifndef QT_NO_SYSTEMLOCALE
756QT_DECL_METATYPE_EXTERN_TAGGED(QSystemLocale::CurrencyToStringArgument,
757 QSystemLocale__CurrencyToStringArgument, Q_CORE_EXPORT)
758#endif
759
760#endif // QLOCALE_P_H
\inmodule QtCore
QDataStream & operator>>(QDataStream &in, QByteArray &ba)
Reads a byte array into ba from the stream in and returns a reference to the stream.
quint16 qChecksum(QByteArrayView data, Qt::ChecksumType standard)
Definition qlist.h:82
static QLatin1StringView scriptToCode(QLocale::Script script)
Definition qlocale.cpp:262
QString toUpper(const QString &str, bool *ok) const
static const QLocalePrivate * get(const QLocale &l)
Definition qlocale_p.h:700
QString toLower(const QString &str, bool *ok) const
quint16 languageId() const
Definition qlocale_p.h:685
static QLocale::Language codeToLanguage(QStringView code, QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode) noexcept
Definition qlocale.cpp:112
const QLocaleData *const m_data
Definition qlocale_p.h:718
QLatin1StringView scriptCode() const
Definition qlocale_p.h:695
QLocale::MeasurementSystem measurementSystem() const
Definition qlocale.cpp:3531
quint16 territoryId() const
Definition qlocale_p.h:686
static QLatin1StringView territoryToCode(QLocale::Territory territory)
Definition qlocale.cpp:270
qsizetype m_index
Definition qlocale_p.h:720
static QLocale::Territory codeToTerritory(QStringView code) noexcept
Definition qlocale.cpp:218
static std::array< char, 4 > languageToCode(QLocale::Language language, QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode)
Definition qlocale.cpp:237
static QLocale::Script codeToScript(QStringView code) noexcept
Definition qlocale.cpp:212
QLocale::NumberOptions m_numberOptions
Definition qlocale_p.h:721
QLatin1StringView territoryCode() const
Definition qlocale_p.h:697
constexpr QLocalePrivate(const QLocaleData *data, qsizetype index, QLocale::NumberOptions numberOptions=QLocale::DefaultNumberOptions, int refs=0)
Definition qlocale_p.h:679
std::array< char, 4 > languageCode(QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode) const
Definition qlocale_p.h:691
static QBasicAtomicInt s_generation
Definition qlocale_p.h:723
QByteArray bcp47Name(char separator='-') const
Definition qlocale.cpp:498
QBasicAtomicInt ref
Definition qlocale_p.h:719
qsizetype fallbackLocaleIndex() const
Definition qlocale_p.h:727
@ StringToAlternateQuotation
Definition qlocale_p.h:181
@ DateTimeToStringShort
Definition qlocale_p.h:169
@ StandaloneMonthNameLong
Definition qlocale_p.h:187
@ ListToSeparatedString
Definition qlocale_p.h:183
@ StandaloneDayNameNarrow
Definition qlocale_p.h:192
@ StandaloneMonthNameNarrow
Definition qlocale_p.h:189
@ StringToStandardQuotation
Definition qlocale_p.h:180
@ StandaloneDayNameShort
Definition qlocale_p.h:191
@ StandaloneDayNameLong
Definition qlocale_p.h:190
@ StandaloneMonthNameShort
Definition qlocale_p.h:188
virtual QLocale fallbackLocale() const
virtual QVariant query(QueryType type, QVariant &&in=QVariant()) const
constexpr char ascii_space_chars[]
Definition qlocale_p.h:91
constexpr auto makeCharacterSetMatch() noexcept
Definition qlocale_p.h:100
static constexpr bool isLowerCaseAscii(char c)
static const quint16 crc_tbl[16]
QByteArray qCompress(const uchar *data, qsizetype nbytes, int compressionLevel)
ZLibOp
@ Decompression
static Q_DECL_COLD_FUNCTION const char * zlibOpAsString(ZLibOp op)
static QByteArray toCase(const QByteArray &input, QByteArray *rvalue, uchar(*lookup)(uchar))
static qsizetype q_fromPercentEncoding(QByteArrayView src, char percent, QSpan< char > buffer)
static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle, qsizetype ol, qsizetype from)
static constexpr bool isUpperCaseAscii(char c)
static QByteArray xxflate(ZLibOp op, QArrayDataPointer< char > out, QByteArrayView input, qxp::function_ref< int(z_stream *) const > init, qxp::function_ref< int(z_stream *, size_t) const > processChunk, qxp::function_ref< void(z_stream *) const > deinit)
static constexpr uchar asciiLower(uchar c)
static qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept
static S b64_to_decoded_size(S n)
static constexpr uchar asciiUpper(uchar c)
Q_CORE_EXPORT char * qstrncpy(char *dst, const char *src, size_t len)
Q_CORE_EXPORT int qstricmp(const char *, const char *)
Q_CORE_EXPORT char * qstrdup(const char *)
Q_CORE_EXPORT char * qstrcpy(char *dst, const char *src)
Q_DECL_PURE_FUNCTION Q_CORE_EXPORT const void * qmemrchr(const void *s, int needle, size_t n) noexcept
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
#define __has_feature(x)
bool qt_splitLocaleName(QStringView name, QStringView *lang=nullptr, QStringView *script=nullptr, QStringView *cntry=nullptr) noexcept
Definition qlocale.cpp:666
Q_DECLARE_TYPEINFO(QLocaleId, Q_PRIMITIVE_TYPE)
constexpr bool ascii_isspace(uchar c) noexcept
Definition qlocale_p.h:745
#define ForEachQLocaleRange(X)
Definition qlocale_p.h:629
QString qt_readEscapedFormatString(QStringView format, qsizetype *idx)
Definition qlocale.cpp:729
QByteArray qdtoAscii(double d, QLocaleData::DoubleForm form, int precision, bool uppercase)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition qsize.h:192
qregisteruint mask[Extent]
Definition qlocale_p.h:52
static constexpr int WordBits
Definition qlocale_p.h:50
static constexpr int MaxRange
Definition qlocale_p.h:51
constexpr auto maskLocation(uchar c) const noexcept
Definition qlocale_p.h:78
constexpr QCharacterSetMatch(std::string_view set) noexcept
Definition qlocale_p.h:54
constexpr bool matches(uchar c) const noexcept
Definition qlocale_p.h:63
QStringView viewListEntry(const char16_t *table, qsizetype index) const
Definition qlocale_p.h:587
char32_t ucsFirst(const char16_t *table) const
Definition qlocale_p.h:591
QString getData(const char16_t *table) const
Definition qlocale_p.h:573
QString getListEntry(const char16_t *table, qsizetype index) const
Definition qlocale_p.h:583
QStringView viewData(const char16_t *table) const
Definition qlocale_p.h:579
Descriptor for a digit sequence within a text.
Definition qlocale_p.h:458
qsizetype size() const
Returns the number of ASCII characters describing the digit sequence.
Definition qlocale_p.h:489
DigitSequence sliced(qsizetype from, qsizetype count) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qlocale_p.h:525
DigitSequence & operator=(const DigitSequence &)=default
QStringView used(const QStringView text) const
Returns the slice of text described by this digit sequence.
Definition qlocale_p.h:531
Q_DECLARE_FLAGS(Options, Option)
bool hasSign() const
Returns true precisely if the digit sequence parsed includes a leading sign.
Definition qlocale_p.h:495
bool isEmpty() const
Returns true precisely if this digit sequence represents nothing.
Definition qlocale_p.h:494
DigitSequence first(qsizetype count) const
Returns a DigitSequence describing a prefix of this.
Definition qlocale_p.h:507
QList< qsizetype > digitBounds
Definition qlocale_p.h:461
void transcribeTo(CharBuff *buff) const
Transcribes the ASCII form of this digit sequence to buff.
Definition qlocale_p.h:497
DigitSequence(DigitSequence &&)=default
DigitSequence & operator=(DigitSequence &&)=default
DigitSequence sliced(qsizetype from) const
Returns a DigitSequence describing a tail of this.
Definition qlocale_p.h:517
QStringView used(const QStringView text, qsizetype from) const
Definition qlocale_p.h:529
DigitSequence last(qsizetype count) const
Returns a DigitSequence describing a tail of this.
Definition qlocale_p.h:515
qsizetype endIndex() const
Definition qlocale_p.h:483
DigitSequence(const DigitSequence &)=default
void setZero(QStringView zero)
Definition qlocale_p.h:382
bool fractionalIsGroup() const
Definition qlocale_p.h:446
qsizetype zeroWidth() const
Definition qlocale_p.h:409
const GroupSizes & groupSizes() const
Definition qlocale_p.h:410
bool isValid(NumberMode mode) const
Definition qlocale_p.h:412
const GroupSizes grouping
Definition qlocale_p.h:376
qint8 digitValue(char32_t digit) const
Definition qlocale_p.h:425
QString positiveSign() const
Definition qlocale.cpp:1097
static float convertDoubleToFloat(double d, bool *ok)
Definition qlocale_p.h:344
QString groupSeparator() const
Definition qlocale.cpp:1056
QSimpleParsedNumber< qint64 > stringToLongLong(QStringView str, int base, QLocale::NumberOptions options) const
Definition qlocale.cpp:5116
Q_AUTOTEST_EXPORT char32_t zeroUcs() const
Definition qlocale.cpp:1076
quint8 m_grouping_least
Definition qlocale_p.h:670
QString zeroDigit() const
Definition qlocale.cpp:1071
bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options, NumberMode mode, CharBuff *result) const
Returns a DigitSequence describing some portion of text starting at from.
Definition qlocale.cpp:4842
quint8 m_grouping_higher
Definition qlocale_p.h:669
QString decimalPoint() const
Definition qlocale.cpp:1051
QString doubleToString(double d, int precision=-1, DoubleForm form=DFSignificantDigits, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:4052
static Q_AUTOTEST_EXPORT bool allLocaleDataRows(bool(*check)(qsizetype, const QLocaleData &))
Definition qlocale.cpp:528
quint8 m_weekend_start
Definition qlocale_p.h:666
quint8 m_currency_digits
Definition qlocale_p.h:663
QLocaleId id() const
Definition qlocale_p.h:554
QString listSeparator() const
Definition qlocale.cpp:1066
DigitSequence digitSequence(QStringView text, DigitSequence::Options flags=DigitSequence::Option::Default, qsizetype from=0) const
Definition qlocale_p.h:543
static QSimpleParsedNumber< quint64 > bytearrayToUnsLongLong(QByteArrayView num, int base)
Definition qlocale.cpp:5163
QString percentSign() const
Definition qlocale.cpp:1061
@ BlankBeforePositive
Definition qlocale_p.h:275
@ AddTrailingZeroes
Definition qlocale_p.h:272
double stringToDouble(QStringView str, bool *ok, QLocale::NumberOptions options) const
Definition qlocale.cpp:5100
QString longLongToString(qint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:4295
@ DoubleScientificMode
Definition qlocale_p.h:286
@ DoubleStandardMode
Definition qlocale_p.h:286
@ DFSignificantDigits
Definition qlocale_p.h:266
quint8 m_first_day_of_week
Definition qlocale_p.h:665
quint8 m_weekend_end
Definition qlocale_p.h:667
quint8 m_currency_rounding
Definition qlocale_p.h:664
QString exponentSeparator() const
Definition qlocale.cpp:1102
QString negativeSign() const
Definition qlocale.cpp:1092
QSimpleParsedNumber< quint64 > stringToUnsLongLong(QStringView str, int base, QLocale::NumberOptions options) const
Definition qlocale.cpp:5127
QString unsLongLongToString(quint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:4310
quint8 m_grouping_first
Definition qlocale_p.h:668
QLocaleId withLikelySubtagsAdded() const noexcept
Definition qlocale.cpp:330
QLocaleId withLikelySubtagsRemoved() const noexcept
Definition qlocale.cpp:419
ushort script_id
Definition qlocale_p.h:247
bool operator==(QLocaleId other) const noexcept
Definition qlocale_p.h:211
bool matchesAll() const noexcept
Definition qlocale_p.h:220
bool sameLanguageScript(QLocaleId other) const noexcept
Definition qlocale_p.h:236
bool isValid() const noexcept
Definition qlocale_p.h:215
bool operator!=(QLocaleId other) const noexcept
Definition qlocale_p.h:213
bool acceptScriptTerritory(QLocaleId other) const noexcept
Definition qlocale_p.h:231
ushort territory_id
Definition qlocale_p.h:247
bool acceptLanguage(quint16 lang) const noexcept
Definition qlocale_p.h:225
ushort language_id
Definition qlocale_p.h:247
CurrencyToStringArgument(const QVariant &v, const QString &s)
Definition qlocale_p.h:138