Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:32:00

0001 // Copyright (C) 2020 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 // Qt-Security score:critical reason:data-parser
0004 
0005 #ifndef QCHAR_H
0006 #define QCHAR_H
0007 
0008 #include <QtCore/qglobal.h>
0009 #include <QtCore/qcompare.h>
0010 
0011 #include <functional> // for std::hash
0012 
0013 QT_BEGIN_NAMESPACE
0014 
0015 class QString;
0016 
0017 struct QLatin1Char
0018 {
0019 public:
0020     constexpr inline explicit QLatin1Char(char c) noexcept : ch(c) {}
0021     constexpr inline char toLatin1() const noexcept { return ch; }
0022     constexpr inline char16_t unicode() const noexcept { return char16_t(uchar(ch)); }
0023 
0024     friend constexpr bool
0025     comparesEqual(const QLatin1Char &lhs, const QLatin1Char &rhs) noexcept
0026     { return lhs.ch == rhs.ch; }
0027     friend constexpr Qt::strong_ordering
0028     compareThreeWay(const QLatin1Char &lhs, const QLatin1Char &rhs) noexcept
0029     { return Qt::compareThreeWay(uchar(lhs.ch), uchar(rhs.ch)); }
0030     Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QLatin1Char)
0031 
0032     friend constexpr bool comparesEqual(const QLatin1Char &lhs, char rhs) noexcept
0033     { return lhs.toLatin1() == rhs; }
0034     friend constexpr Qt::strong_ordering
0035     compareThreeWay(const QLatin1Char &lhs, char rhs) noexcept
0036     { return Qt::compareThreeWay(uchar(lhs.toLatin1()), uchar(rhs)); }
0037     Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QLatin1Char, char)
0038 
0039 private:
0040     friend class QChar;
0041     // this is for QChar's ctor only:
0042     explicit constexpr operator char16_t() const noexcept { return unicode(); }
0043 
0044     char ch;
0045 };
0046 
0047 #define QT_CHAR_FASTCALL QT7_ONLY(Q_CORE_EXPORT) QT_FASTCALL
0048 class QT6_ONLY(Q_CORE_EXPORT) QChar {
0049 public:
0050     enum SpecialCharacter {
0051         Null = 0x0000,
0052         Tabulation = 0x0009,
0053         LineFeed = 0x000a,
0054         FormFeed = 0x000c,
0055         CarriageReturn = 0x000d,
0056         Space = 0x0020,
0057         Nbsp = 0x00a0,
0058         SoftHyphen = 0x00ad,
0059         ReplacementCharacter = 0xfffd,
0060         ObjectReplacementCharacter = 0xfffc,
0061         ByteOrderMark = 0xfeff,
0062         ByteOrderSwapped = 0xfffe,
0063         ParagraphSeparator = 0x2029,
0064         LineSeparator = 0x2028,
0065         VisualTabCharacter = 0x2192,
0066         LastValidCodePoint = 0x10ffff
0067     };
0068 
0069 #ifdef QT_IMPLICIT_QCHAR_CONSTRUCTION
0070 #error This macro has been removed in Qt 6.8.
0071 #endif
0072 private:
0073     using is_wide_wchar_t = std::bool_constant<(sizeof(wchar_t) > 2)>;
0074     template <typename Char>
0075     using is_implicit_conversion_char = std::disjunction<
0076             std::is_same<Char, ushort>,
0077             std::is_same<Char, short>,
0078             std::is_same<Char, SpecialCharacter>,
0079             std::is_same<Char, QLatin1Char>,
0080             std::conjunction<std::is_same<Char, wchar_t>, std::negation<is_wide_wchar_t>>,
0081             std::is_same<Char, char16_t>
0082         >;
0083     template <typename Char>
0084     using is_explicit_conversion_char = std::disjunction<
0085             std::is_same<Char, char32_t>, // implicit conversion to uint(?) before 6.8
0086             std::conjunction<std::is_same<Char, wchar_t>, is_wide_wchar_t>,
0087             std::is_same<Char, int>,
0088             std::is_same<Char, uint>
0089         >;
0090     template <typename Char>
0091     using is_conversion_char = std::disjunction<
0092             is_implicit_conversion_char<Char>,
0093             is_explicit_conversion_char<Char>
0094         >;
0095     template <typename Char>
0096     using is_implicit_ascii_warn_char = std::is_same<Char, char>;
0097     template <typename Char>
0098     using is_explicit_ascii_warn_char = std::is_same<Char, uchar>;
0099     template <typename Char>
0100     using if_compatible_char = std::enable_if_t<is_conversion_char<Char>::value, bool>;
0101     template <typename Char>
0102     using if_implicit_conversion_char = std::enable_if_t<is_implicit_conversion_char<Char>::value, bool>;
0103     template <typename Char>
0104     using if_explicit_conversion_char = std::enable_if_t<is_explicit_conversion_char<Char>::value, bool>;
0105     template <typename Char>
0106     using if_implicit_ascii_warn_char = std::enable_if_t<is_implicit_ascii_warn_char<Char>::value, bool>;
0107     template <typename Char>
0108     using if_explicit_ascii_warn_char = std::enable_if_t<is_explicit_ascii_warn_char<Char>::value, bool>;
0109     template <typename Char>
0110     [[maybe_unused]] static constexpr bool is_explicit_char_v = std::disjunction_v<
0111             is_explicit_conversion_char<Char>,
0112             is_explicit_ascii_warn_char<Char>
0113         >;
0114 public:
0115     constexpr Q_IMPLICIT QChar() noexcept : ucs(0) {}
0116 #if QT_CORE_REMOVED_SINCE(6, 9) || defined(Q_QDOC)
0117     constexpr Q_IMPLICIT QChar(ushort rc) noexcept : ucs(rc) {}
0118 #endif
0119     constexpr explicit QChar(uchar c, uchar r) noexcept : ucs(char16_t((r << 8) | c)) {}
0120 #if QT_CORE_REMOVED_SINCE(6, 9) || defined(Q_QDOC)
0121     constexpr Q_IMPLICIT QChar(short rc) noexcept : ucs(char16_t(rc)) {}
0122     constexpr explicit QChar(uint rc) noexcept : ucs((Q_ASSERT(rc <= 0xffff), char16_t(rc))) {}
0123     constexpr explicit QChar(int rc) noexcept : QChar(uint(rc)) {}
0124     constexpr Q_IMPLICIT QChar(SpecialCharacter s) noexcept : ucs(char16_t(s)) {}
0125     constexpr Q_IMPLICIT QChar(QLatin1Char ch) noexcept : ucs(ch.unicode()) {}
0126     constexpr Q_IMPLICIT QChar(char16_t ch) noexcept : ucs(ch) {}
0127 #if defined(Q_OS_WIN) || defined(Q_QDOC)
0128     constexpr Q_IMPLICIT QChar(wchar_t ch) noexcept : ucs(char16_t(ch)) {}
0129 #endif
0130 #endif // QT_CORE_REMOVED_SINCE(6, 9)
0131     template <typename Char, if_implicit_conversion_char<Char> = true>
0132     constexpr Q_IMPLICIT QChar(const Char ch) noexcept : ucs(char16_t(ch)) {}
0133     template <typename Char, if_explicit_conversion_char<Char> = true>
0134     constexpr explicit QChar(const Char ch) noexcept
0135         : ucs((Q_ASSERT(char32_t(ch) <= 0xffff), char16_t(ch))) {}
0136 
0137 #ifndef QT_NO_CAST_FROM_ASCII
0138     // Always implicit -- allow for 'x' => QChar conversions
0139 #if QT_CORE_REMOVED_SINCE(6, 9) || defined(Q_QDOC)
0140     QT_ASCII_CAST_WARN constexpr Q_IMPLICIT QChar(char c) noexcept : ucs(uchar(c)) { }
0141 #endif
0142     template <typename Char, if_implicit_ascii_warn_char<Char> = true>
0143     QT_ASCII_CAST_WARN constexpr Q_IMPLICIT QChar(const Char ch) noexcept : ucs(uchar(ch)) {}
0144 #ifndef QT_RESTRICTED_CAST_FROM_ASCII
0145 #if QT_CORE_REMOVED_SINCE(6, 9) || defined(Q_QDOC)
0146     QT_ASCII_CAST_WARN constexpr explicit QChar(uchar c) noexcept : ucs(c) { }
0147 #endif
0148     template <typename Char, if_explicit_ascii_warn_char<Char> = true>
0149     QT_ASCII_CAST_WARN constexpr explicit QChar(const Char c) noexcept : ucs(c) { }
0150 #endif
0151 #endif
0152 
0153     static constexpr QChar fromUcs2(char16_t c) noexcept { return QChar{c}; }
0154     static constexpr inline auto fromUcs4(char32_t c) noexcept;
0155 
0156     // Unicode information
0157 
0158     enum Category
0159     {
0160         Mark_NonSpacing,          //   Mn
0161         Mark_SpacingCombining,    //   Mc
0162         Mark_Enclosing,           //   Me
0163 
0164         Number_DecimalDigit,      //   Nd
0165         Number_Letter,            //   Nl
0166         Number_Other,             //   No
0167 
0168         Separator_Space,          //   Zs
0169         Separator_Line,           //   Zl
0170         Separator_Paragraph,      //   Zp
0171 
0172         Other_Control,            //   Cc
0173         Other_Format,             //   Cf
0174         Other_Surrogate,          //   Cs
0175         Other_PrivateUse,         //   Co
0176         Other_NotAssigned,        //   Cn
0177 
0178         Letter_Uppercase,         //   Lu
0179         Letter_Lowercase,         //   Ll
0180         Letter_Titlecase,         //   Lt
0181         Letter_Modifier,          //   Lm
0182         Letter_Other,             //   Lo
0183 
0184         Punctuation_Connector,    //   Pc
0185         Punctuation_Dash,         //   Pd
0186         Punctuation_Open,         //   Ps
0187         Punctuation_Close,        //   Pe
0188         Punctuation_InitialQuote, //   Pi
0189         Punctuation_FinalQuote,   //   Pf
0190         Punctuation_Other,        //   Po
0191 
0192         Symbol_Math,              //   Sm
0193         Symbol_Currency,          //   Sc
0194         Symbol_Modifier,          //   Sk
0195         Symbol_Other              //   So
0196     };
0197 
0198     enum Script
0199     {
0200         Script_Unknown,
0201         Script_Inherited,
0202         Script_Common,
0203 
0204         Script_Latin,
0205         Script_Greek,
0206         Script_Cyrillic,
0207         Script_Armenian,
0208         Script_Hebrew,
0209         Script_Arabic,
0210         Script_Syriac,
0211         Script_Thaana,
0212         Script_Devanagari,
0213         Script_Bengali,
0214         Script_Gurmukhi,
0215         Script_Gujarati,
0216         Script_Oriya,
0217         Script_Tamil,
0218         Script_Telugu,
0219         Script_Kannada,
0220         Script_Malayalam,
0221         Script_Sinhala,
0222         Script_Thai,
0223         Script_Lao,
0224         Script_Tibetan,
0225         Script_Myanmar,
0226         Script_Georgian,
0227         Script_Hangul,
0228         Script_Ethiopic,
0229         Script_Cherokee,
0230         Script_CanadianAboriginal,
0231         Script_Ogham,
0232         Script_Runic,
0233         Script_Khmer,
0234         Script_Mongolian,
0235         Script_Hiragana,
0236         Script_Katakana,
0237         Script_Bopomofo,
0238         Script_Han,
0239         Script_Yi,
0240         Script_OldItalic,
0241         Script_Gothic,
0242         Script_Deseret,
0243         Script_Tagalog,
0244         Script_Hanunoo,
0245         Script_Buhid,
0246         Script_Tagbanwa,
0247         Script_Coptic,
0248 
0249         // Unicode 4.0 additions
0250         Script_Limbu,
0251         Script_TaiLe,
0252         Script_LinearB,
0253         Script_Ugaritic,
0254         Script_Shavian,
0255         Script_Osmanya,
0256         Script_Cypriot,
0257         Script_Braille,
0258 
0259         // Unicode 4.1 additions
0260         Script_Buginese,
0261         Script_NewTaiLue,
0262         Script_Glagolitic,
0263         Script_Tifinagh,
0264         Script_SylotiNagri,
0265         Script_OldPersian,
0266         Script_Kharoshthi,
0267 
0268         // Unicode 5.0 additions
0269         Script_Balinese,
0270         Script_Cuneiform,
0271         Script_Phoenician,
0272         Script_PhagsPa,
0273         Script_Nko,
0274 
0275         // Unicode 5.1 additions
0276         Script_Sundanese,
0277         Script_Lepcha,
0278         Script_OlChiki,
0279         Script_Vai,
0280         Script_Saurashtra,
0281         Script_KayahLi,
0282         Script_Rejang,
0283         Script_Lycian,
0284         Script_Carian,
0285         Script_Lydian,
0286         Script_Cham,
0287 
0288         // Unicode 5.2 additions
0289         Script_TaiTham,
0290         Script_TaiViet,
0291         Script_Avestan,
0292         Script_EgyptianHieroglyphs,
0293         Script_Samaritan,
0294         Script_Lisu,
0295         Script_Bamum,
0296         Script_Javanese,
0297         Script_MeeteiMayek,
0298         Script_ImperialAramaic,
0299         Script_OldSouthArabian,
0300         Script_InscriptionalParthian,
0301         Script_InscriptionalPahlavi,
0302         Script_OldTurkic,
0303         Script_Kaithi,
0304 
0305         // Unicode 6.0 additions
0306         Script_Batak,
0307         Script_Brahmi,
0308         Script_Mandaic,
0309 
0310         // Unicode 6.1 additions
0311         Script_Chakma,
0312         Script_MeroiticCursive,
0313         Script_MeroiticHieroglyphs,
0314         Script_Miao,
0315         Script_Sharada,
0316         Script_SoraSompeng,
0317         Script_Takri,
0318 
0319         // Unicode 7.0 additions
0320         Script_CaucasianAlbanian,
0321         Script_BassaVah,
0322         Script_Duployan,
0323         Script_Elbasan,
0324         Script_Grantha,
0325         Script_PahawhHmong,
0326         Script_Khojki,
0327         Script_LinearA,
0328         Script_Mahajani,
0329         Script_Manichaean,
0330         Script_MendeKikakui,
0331         Script_Modi,
0332         Script_Mro,
0333         Script_OldNorthArabian,
0334         Script_Nabataean,
0335         Script_Palmyrene,
0336         Script_PauCinHau,
0337         Script_OldPermic,
0338         Script_PsalterPahlavi,
0339         Script_Siddham,
0340         Script_Khudawadi,
0341         Script_Tirhuta,
0342         Script_WarangCiti,
0343 
0344         // Unicode 8.0 additions
0345         Script_Ahom,
0346         Script_AnatolianHieroglyphs,
0347         Script_Hatran,
0348         Script_Multani,
0349         Script_OldHungarian,
0350         Script_SignWriting,
0351 
0352         // Unicode 9.0 additions
0353         Script_Adlam,
0354         Script_Bhaiksuki,
0355         Script_Marchen,
0356         Script_Newa,
0357         Script_Osage,
0358         Script_Tangut,
0359 
0360         // Unicode 10.0 additions
0361         Script_MasaramGondi,
0362         Script_Nushu,
0363         Script_Soyombo,
0364         Script_ZanabazarSquare,
0365 
0366         // Unicode 12.1 additions
0367         Script_Dogra,
0368         Script_GunjalaGondi,
0369         Script_HanifiRohingya,
0370         Script_Makasar,
0371         Script_Medefaidrin,
0372         Script_OldSogdian,
0373         Script_Sogdian,
0374         Script_Elymaic,
0375         Script_Nandinagari,
0376         Script_NyiakengPuachueHmong,
0377         Script_Wancho,
0378 
0379         // Unicode 13.0 additions
0380         Script_Chorasmian,
0381         Script_DivesAkuru,
0382         Script_KhitanSmallScript,
0383         Script_Yezidi,
0384 
0385         // Unicode 14.0 additions
0386         Script_CyproMinoan,
0387         Script_OldUyghur,
0388         Script_Tangsa,
0389         Script_Toto,
0390         Script_Vithkuqi,
0391 
0392         // Unicode 15.0 additions
0393         Script_Kawi,
0394         Script_NagMundari,
0395 
0396         // Unicode 16.0 additions
0397         Script_Garay,
0398         Script_GurungKhema,
0399         Script_KiratRai,
0400         Script_OlOnal,
0401         Script_Sunuwar,
0402         Script_Todhri,
0403         Script_TuluTigalari,
0404 
0405         // Unicode 17.0 additions
0406         Script_Sidetic,
0407         Script_TaiYo,
0408         Script_TolongSiki,
0409         Script_BeriaErfe,
0410 
0411         ScriptCount
0412     };
0413 
0414     enum Direction
0415     {
0416         DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
0417         DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN,
0418         DirLRI, DirRLI, DirFSI, DirPDI
0419     };
0420 
0421     enum Decomposition
0422     {
0423         NoDecomposition,
0424         Canonical,
0425         Font,
0426         NoBreak,
0427         Initial,
0428         Medial,
0429         Final,
0430         Isolated,
0431         Circle,
0432         Super,
0433         Sub,
0434         Vertical,
0435         Wide,
0436         Narrow,
0437         Small,
0438         Square,
0439         Compat,
0440         Fraction
0441     };
0442 
0443     enum JoiningType {
0444         Joining_None,
0445         Joining_Causing,
0446         Joining_Dual,
0447         Joining_Right,
0448         Joining_Left,
0449         Joining_Transparent
0450     };
0451 
0452     enum CombiningClass
0453     {
0454         Combining_BelowLeftAttached       = 200,
0455         Combining_BelowAttached           = 202,
0456         Combining_BelowRightAttached      = 204,
0457         Combining_LeftAttached            = 208,
0458         Combining_RightAttached           = 210,
0459         Combining_AboveLeftAttached       = 212,
0460         Combining_AboveAttached           = 214,
0461         Combining_AboveRightAttached      = 216,
0462 
0463         Combining_BelowLeft               = 218,
0464         Combining_Below                   = 220,
0465         Combining_BelowRight              = 222,
0466         Combining_Left                    = 224,
0467         Combining_Right                   = 226,
0468         Combining_AboveLeft               = 228,
0469         Combining_Above                   = 230,
0470         Combining_AboveRight              = 232,
0471 
0472         Combining_DoubleBelow             = 233,
0473         Combining_DoubleAbove             = 234,
0474         Combining_IotaSubscript           = 240
0475     };
0476 
0477     enum UnicodeVersion {
0478         Unicode_Unassigned,
0479         Unicode_1_1,
0480         Unicode_2_0,
0481         Unicode_2_1_2,
0482         Unicode_3_0,
0483         Unicode_3_1,
0484         Unicode_3_2,
0485         Unicode_4_0,
0486         Unicode_4_1,
0487         Unicode_5_0,
0488         Unicode_5_1,
0489         Unicode_5_2,
0490         Unicode_6_0,
0491         Unicode_6_1,
0492         Unicode_6_2,
0493         Unicode_6_3,
0494         Unicode_7_0,
0495         Unicode_8_0,
0496         Unicode_9_0,
0497         Unicode_10_0,
0498         Unicode_11_0,
0499         Unicode_12_0,
0500         Unicode_12_1,
0501         Unicode_13_0,
0502         Unicode_14_0,
0503         Unicode_15_0,
0504         Unicode_15_1,
0505         Unicode_16_0,
0506         Unicode_17_0,
0507     };
0508 
0509     Category category() const noexcept { return QChar::category(char32_t(ucs)); }
0510     Direction direction() const noexcept { return QChar::direction(char32_t(ucs)); }
0511     JoiningType joiningType() const noexcept { return QChar::joiningType(char32_t(ucs)); }
0512     unsigned char combiningClass() const noexcept { return QChar::combiningClass(char32_t(ucs)); }
0513 
0514     QChar mirroredChar() const noexcept { return QChar(QChar::mirroredChar(char32_t(ucs))); }
0515     bool hasMirrored() const noexcept { return QChar::hasMirrored(char32_t(ucs)); }
0516 
0517     QString decomposition() const;
0518     Decomposition decompositionTag() const noexcept { return QChar::decompositionTag(char32_t(ucs)); }
0519 
0520     int digitValue() const noexcept { return QChar::digitValue(char32_t(ucs)); }
0521     QChar toLower() const noexcept { return QChar(QChar::toLower(char32_t(ucs))); }
0522     QChar toUpper() const noexcept { return QChar(QChar::toUpper(char32_t(ucs))); }
0523     QChar toTitleCase() const noexcept { return QChar(QChar::toTitleCase(char32_t(ucs))); }
0524     QChar toCaseFolded() const noexcept { return QChar(QChar::toCaseFolded(char32_t(ucs))); }
0525 
0526     Script script() const noexcept { return QChar::script(char32_t(ucs)); }
0527 
0528     UnicodeVersion unicodeVersion() const noexcept { return QChar::unicodeVersion(char32_t(ucs)); }
0529 
0530     constexpr inline char toLatin1() const noexcept { return ucs > 0xff ? '\0' : char(ucs); }
0531     constexpr inline char16_t unicode() const noexcept { return ucs; }
0532     constexpr inline char16_t &unicode() noexcept { return ucs; }
0533 
0534     static constexpr QChar fromLatin1(char c) noexcept { return QLatin1Char(c); }
0535 
0536     constexpr inline bool isNull() const noexcept { return ucs == 0; }
0537 
0538     bool isPrint() const noexcept { return QChar::isPrint(char32_t(ucs)); }
0539     constexpr bool isSpace() const noexcept { return QChar::isSpace(char32_t(ucs)); }
0540     bool isMark() const noexcept { return QChar::isMark(char32_t(ucs)); }
0541     bool isPunct() const noexcept { return QChar::isPunct(char32_t(ucs)); }
0542     bool isSymbol() const noexcept { return QChar::isSymbol(char32_t(ucs)); }
0543     constexpr bool isLetter() const noexcept { return QChar::isLetter(char32_t(ucs)); }
0544     constexpr bool isNumber() const noexcept { return QChar::isNumber(char32_t(ucs)); }
0545     constexpr bool isLetterOrNumber() const noexcept { return QChar::isLetterOrNumber(char32_t(ucs)); }
0546     constexpr bool isDigit() const noexcept { return QChar::isDigit(char32_t(ucs)); }
0547     constexpr bool isLower() const noexcept { return QChar::isLower(char32_t(ucs)); }
0548     constexpr bool isUpper() const noexcept { return QChar::isUpper(char32_t(ucs)); }
0549     constexpr bool isTitleCase() const noexcept { return QChar::isTitleCase(char32_t(ucs)); }
0550 
0551     constexpr bool isNonCharacter() const noexcept { return QChar::isNonCharacter(char32_t(ucs)); }
0552     constexpr bool isHighSurrogate() const noexcept { return QChar::isHighSurrogate(char32_t(ucs)); }
0553     constexpr bool isLowSurrogate() const noexcept { return QChar::isLowSurrogate(char32_t(ucs)); }
0554     constexpr bool isSurrogate() const noexcept { return QChar::isSurrogate(char32_t(ucs)); }
0555 
0556     constexpr inline uchar cell() const noexcept { return uchar(ucs & 0xff); }
0557     constexpr inline uchar row() const noexcept { return uchar((ucs>>8)&0xff); }
0558     constexpr inline void setCell(uchar acell) noexcept { ucs = char16_t((ucs & 0xff00) + acell); }
0559     constexpr inline void setRow(uchar arow) noexcept { ucs = char16_t((char16_t(arow)<<8) + (ucs&0xff)); }
0560 
0561     static constexpr inline bool isNonCharacter(char32_t ucs4) noexcept
0562     {
0563         return ucs4 >= 0xfdd0 && (ucs4 <= 0xfdef || (ucs4 & 0xfffe) == 0xfffe);
0564     }
0565     static constexpr inline bool isHighSurrogate(char32_t ucs4) noexcept
0566     {
0567         return (ucs4 & 0xfffffc00) == 0xd800; // 0xd800 + up to 1023 (0x3ff)
0568     }
0569     static constexpr inline bool isLowSurrogate(char32_t ucs4) noexcept
0570     {
0571         return (ucs4 & 0xfffffc00) == 0xdc00; // 0xdc00 + up to 1023 (0x3ff)
0572     }
0573     static constexpr inline bool isSurrogate(char32_t ucs4) noexcept
0574     {
0575         return (ucs4 - 0xd800u < 2048u);
0576     }
0577     static constexpr inline bool requiresSurrogates(char32_t ucs4) noexcept
0578     {
0579         return (ucs4 >= 0x10000);
0580     }
0581     static constexpr inline char32_t surrogateToUcs4(char16_t high, char16_t low) noexcept
0582     {
0583         // 0x010000 through 0x10ffff, provided params are actual high, low surrogates.
0584         // 0x010000 + ((high - 0xd800) << 10) + (low - 0xdc00), optimized:
0585         return (char32_t(high)<<10) + low - 0x35fdc00;
0586     }
0587     static constexpr inline char32_t surrogateToUcs4(QChar high, QChar low) noexcept
0588     {
0589         return surrogateToUcs4(high.ucs, low.ucs);
0590     }
0591     static constexpr inline char16_t highSurrogate(char32_t ucs4) noexcept
0592     {
0593         return char16_t((ucs4>>10) + 0xd7c0);
0594     }
0595     static constexpr inline char16_t lowSurrogate(char32_t ucs4) noexcept
0596     {
0597         return char16_t(ucs4%0x400 + 0xdc00);
0598     }
0599 
0600     Q_DECL_CONST_FUNCTION static Category QT_CHAR_FASTCALL category(char32_t ucs4) noexcept;
0601     Q_DECL_CONST_FUNCTION static Direction QT_CHAR_FASTCALL direction(char32_t ucs4) noexcept;
0602     Q_DECL_CONST_FUNCTION static JoiningType QT_CHAR_FASTCALL joiningType(char32_t ucs4) noexcept;
0603     Q_DECL_CONST_FUNCTION static unsigned char QT_CHAR_FASTCALL combiningClass(char32_t ucs4) noexcept;
0604 
0605     Q_DECL_CONST_FUNCTION static char32_t QT_CHAR_FASTCALL mirroredChar(char32_t ucs4) noexcept;
0606     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL hasMirrored(char32_t ucs4) noexcept;
0607 
0608     static QString QT_CHAR_FASTCALL decomposition(char32_t ucs4);
0609     Q_DECL_CONST_FUNCTION static Decomposition QT_CHAR_FASTCALL decompositionTag(char32_t ucs4) noexcept;
0610 
0611     Q_DECL_CONST_FUNCTION static int QT_CHAR_FASTCALL digitValue(char32_t ucs4) noexcept;
0612     Q_DECL_CONST_FUNCTION static char32_t QT_CHAR_FASTCALL toLower(char32_t ucs4) noexcept;
0613     Q_DECL_CONST_FUNCTION static char32_t QT_CHAR_FASTCALL toUpper(char32_t ucs4) noexcept;
0614     Q_DECL_CONST_FUNCTION static char32_t QT_CHAR_FASTCALL toTitleCase(char32_t ucs4) noexcept;
0615     Q_DECL_CONST_FUNCTION static char32_t QT_CHAR_FASTCALL toCaseFolded(char32_t ucs4) noexcept;
0616 
0617     Q_DECL_CONST_FUNCTION static Script QT_CHAR_FASTCALL script(char32_t ucs4) noexcept;
0618 
0619     Q_DECL_CONST_FUNCTION static UnicodeVersion QT_CHAR_FASTCALL unicodeVersion(char32_t ucs4) noexcept;
0620 
0621     Q_DECL_CONST_FUNCTION static UnicodeVersion QT_CHAR_FASTCALL currentUnicodeVersion() noexcept;
0622 
0623     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL isPrint(char32_t ucs4) noexcept;
0624     Q_DECL_CONST_FUNCTION static constexpr inline bool isSpace(char32_t ucs4) noexcept
0625     {
0626         // note that [0x09..0x0d] + 0x85 are exceptional Cc-s and must be handled explicitly
0627         return ucs4 == 0x20 || (ucs4 <= 0x0d && ucs4 >= 0x09)
0628                 || (ucs4 > 127 && (ucs4 == 0x85 || ucs4 == 0xa0 || QChar::isSpace_helper(ucs4)));
0629     }
0630     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL isMark(char32_t ucs4) noexcept;
0631     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL isPunct(char32_t ucs4) noexcept;
0632     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL isSymbol(char32_t ucs4) noexcept;
0633     Q_DECL_CONST_FUNCTION static constexpr inline bool isLetter(char32_t ucs4) noexcept
0634     {
0635         return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
0636                 || (ucs4 > 127 && QChar::isLetter_helper(ucs4));
0637     }
0638     Q_DECL_CONST_FUNCTION static constexpr inline bool isNumber(char32_t ucs4) noexcept
0639     { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::isNumber_helper(ucs4)); }
0640     Q_DECL_CONST_FUNCTION static constexpr inline bool isLetterOrNumber(char32_t ucs4) noexcept
0641     {
0642         return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
0643                 || (ucs4 >= '0' && ucs4 <= '9')
0644                 || (ucs4 > 127 && QChar::isLetterOrNumber_helper(ucs4));
0645     }
0646     Q_DECL_CONST_FUNCTION static constexpr inline bool isDigit(char32_t ucs4) noexcept
0647     { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::category(ucs4) == Number_DecimalDigit); }
0648     Q_DECL_CONST_FUNCTION static constexpr inline bool isLower(char32_t ucs4) noexcept
0649     { return (ucs4 <= 'z' && ucs4 >= 'a') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Lowercase); }
0650     Q_DECL_CONST_FUNCTION static constexpr inline bool isUpper(char32_t ucs4) noexcept
0651     { return (ucs4 <= 'Z' && ucs4 >= 'A') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Uppercase); }
0652     Q_DECL_CONST_FUNCTION static constexpr inline bool isTitleCase(char32_t ucs4) noexcept
0653     { return ucs4 > 127 && QChar::category(ucs4) == Letter_Titlecase; }
0654 
0655     friend constexpr bool comparesEqual(const QChar &lhs, const QChar &rhs) noexcept
0656     { return lhs.ucs == rhs.ucs; }
0657     friend constexpr Qt::strong_ordering
0658     compareThreeWay(const QChar &lhs, const QChar &rhs) noexcept
0659     { return Qt::compareThreeWay(lhs.ucs, rhs.ucs); }
0660     Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QChar)
0661 
0662     friend constexpr bool comparesEqual(const QChar &lhs, std::nullptr_t) noexcept
0663     { return lhs.isNull(); }
0664     friend constexpr Qt::strong_ordering
0665     compareThreeWay(const QChar &lhs, std::nullptr_t) noexcept
0666     { return lhs.isNull() ? Qt::strong_ordering::equivalent : Qt::strong_ordering::greater; }
0667     Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QChar, std::nullptr_t)
0668 
0669 private:
0670     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL isSpace_helper(char32_t ucs4) noexcept;
0671     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL isLetter_helper(char32_t ucs4) noexcept;
0672     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL isNumber_helper(char32_t ucs4) noexcept;
0673     Q_DECL_CONST_FUNCTION static bool QT_CHAR_FASTCALL isLetterOrNumber_helper(char32_t ucs4) noexcept;
0674 
0675     // defined in qstring.cpp, because we need to go via QUtf8StringView
0676     static bool QT_CHAR_FASTCALL
0677     Q_DECL_CONST_FUNCTION equal_helper(QChar lhs, const char *rhs) noexcept;
0678     static int QT_CHAR_FASTCALL
0679     Q_DECL_CONST_FUNCTION compare_helper(QChar lhs, const char *rhs) noexcept;
0680 
0681 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
0682     Q_WEAK_OVERLOAD
0683     friend bool comparesEqual(const QChar &lhs, const char *rhs) noexcept
0684     { return equal_helper(lhs, rhs); }
0685     Q_WEAK_OVERLOAD
0686     friend Qt::strong_ordering compareThreeWay(const QChar &lhs, const char *rhs) noexcept
0687     {
0688         const int res = compare_helper(lhs, rhs);
0689         return Qt::compareThreeWay(res, 0);
0690     }
0691     Q_DECLARE_STRONGLY_ORDERED(QChar, const char *, Q_WEAK_OVERLOAD QT_ASCII_CAST_WARN)
0692 #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
0693 
0694     char16_t ucs;
0695 };
0696 #undef QT_CHAR_FASTCALL
0697 
0698 Q_DECLARE_TYPEINFO(QChar, Q_PRIMITIVE_TYPE);
0699 
0700 namespace Qt {
0701 inline namespace Literals {
0702 inline namespace StringLiterals {
0703 
0704 constexpr inline QLatin1Char operator""_L1(char ch) noexcept
0705 {
0706     return QLatin1Char(ch);
0707 }
0708 
0709 } // StringLiterals
0710 } // Literals
0711 } // Qt
0712 
0713 QT_END_NAMESPACE
0714 
0715 namespace std {
0716 template <>
0717 struct hash<QT_PREPEND_NAMESPACE(QChar)>
0718 {
0719     template <typename = void> // for transparent constexpr tracking
0720     constexpr size_t operator()(QT_PREPEND_NAMESPACE(QChar) c) const
0721         noexcept(noexcept(std::hash<char16_t>{}(u' ')))
0722     {
0723         return std::hash<char16_t>{}(c.unicode());
0724     }
0725 };
0726 } // namespace std
0727 
0728 #endif // QCHAR_H
0729 
0730 #include <QtCore/qstringview.h> // for QChar::fromUcs4() definition