1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QCHAR_H
5#define QCHAR_H
6
7#include <QtCore/qglobal.h>
8#include <QtCore/qcompare.h>
9
10#include <functional> // for std::hash
11
12QT_BEGIN_NAMESPACE
13
14
15class QString;
16
17struct QLatin1Char
18{
19public:
20 constexpr inline explicit QLatin1Char(char c) noexcept : ch(c) {}
21 constexpr inline char toLatin1() const noexcept { return ch; }
22 constexpr inline char16_t unicode() const noexcept { return char16_t(uchar(ch)); }
23
24 friend constexpr bool
25 comparesEqual(const QLatin1Char &lhs, const QLatin1Char &rhs) noexcept
26 { return lhs.ch == rhs.ch; }
27 friend constexpr Qt::strong_ordering
28 compareThreeWay(const QLatin1Char &lhs, const QLatin1Char &rhs) noexcept
29 { return Qt::compareThreeWay(lhs: uchar(lhs.ch), rhs: uchar(rhs.ch)); }
30 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QLatin1Char)
31
32 friend constexpr bool comparesEqual(const QLatin1Char &lhs, char rhs) noexcept
33 { return lhs.toLatin1() == rhs; }
34 friend constexpr Qt::strong_ordering
35 compareThreeWay(const QLatin1Char &lhs, char rhs) noexcept
36 { return Qt::compareThreeWay(lhs: uchar(lhs.toLatin1()), rhs: uchar(rhs)); }
37 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QLatin1Char, char)
38
39private:
40 char ch;
41};
42
43#define QT_CHAR_FASTCALL QT7_ONLY(Q_CORE_EXPORT) QT_FASTCALL
44class QT6_ONLY(Q_CORE_EXPORT) QChar {
45public:
46 enum SpecialCharacter {
47 Null = 0x0000,
48 Tabulation = 0x0009,
49 LineFeed = 0x000a,
50 FormFeed = 0x000c,
51 CarriageReturn = 0x000d,
52 Space = 0x0020,
53 Nbsp = 0x00a0,
54 SoftHyphen = 0x00ad,
55 ReplacementCharacter = 0xfffd,
56 ObjectReplacementCharacter = 0xfffc,
57 ByteOrderMark = 0xfeff,
58 ByteOrderSwapped = 0xfffe,
59 ParagraphSeparator = 0x2029,
60 LineSeparator = 0x2028,
61 VisualTabCharacter = 0x2192,
62 LastValidCodePoint = 0x10ffff
63 };
64
65#ifdef QT_IMPLICIT_QCHAR_CONSTRUCTION
66#error This macro has been removed in Qt 6.8.
67#endif
68
69 constexpr Q_IMPLICIT QChar() noexcept : ucs(0) {}
70 constexpr Q_IMPLICIT QChar(ushort rc) noexcept : ucs(rc) {}
71 constexpr explicit QChar(uchar c, uchar r) noexcept : ucs(char16_t((r << 8) | c)) {}
72 constexpr Q_IMPLICIT QChar(short rc) noexcept : ucs(char16_t(rc)) {}
73 constexpr explicit QChar(uint rc) noexcept : ucs((Q_ASSERT(rc <= 0xffff), char16_t(rc))) {}
74 constexpr explicit QChar(int rc) noexcept : QChar(uint(rc)) {}
75 constexpr Q_IMPLICIT QChar(SpecialCharacter s) noexcept : ucs(char16_t(s)) {}
76 constexpr Q_IMPLICIT QChar(QLatin1Char ch) noexcept : ucs(ch.unicode()) {}
77 constexpr Q_IMPLICIT QChar(char16_t ch) noexcept : ucs(ch) {}
78#if defined(Q_OS_WIN) || defined(Q_QDOC)
79 constexpr Q_IMPLICIT QChar(wchar_t ch) noexcept : ucs(char16_t(ch)) {}
80#endif
81
82#ifndef QT_NO_CAST_FROM_ASCII
83 // Always implicit -- allow for 'x' => QChar conversions
84 QT_ASCII_CAST_WARN constexpr Q_IMPLICIT QChar(char c) noexcept : ucs(uchar(c)) { }
85#ifndef QT_RESTRICTED_CAST_FROM_ASCII
86 QT_ASCII_CAST_WARN constexpr explicit QChar(uchar c) noexcept : ucs(c) { }
87#endif
88#endif
89
90 static constexpr QChar fromUcs2(char16_t c) noexcept { return QChar{c}; }
91 static constexpr inline auto fromUcs4(char32_t c) noexcept;
92
93 // Unicode information
94
95 enum Category
96 {
97 Mark_NonSpacing, // Mn
98 Mark_SpacingCombining, // Mc
99 Mark_Enclosing, // Me
100
101 Number_DecimalDigit, // Nd
102 Number_Letter, // Nl
103 Number_Other, // No
104
105 Separator_Space, // Zs
106 Separator_Line, // Zl
107 Separator_Paragraph, // Zp
108
109 Other_Control, // Cc
110 Other_Format, // Cf
111 Other_Surrogate, // Cs
112 Other_PrivateUse, // Co
113 Other_NotAssigned, // Cn
114
115 Letter_Uppercase, // Lu
116 Letter_Lowercase, // Ll
117 Letter_Titlecase, // Lt
118 Letter_Modifier, // Lm
119 Letter_Other, // Lo
120
121 Punctuation_Connector, // Pc
122 Punctuation_Dash, // Pd
123 Punctuation_Open, // Ps
124 Punctuation_Close, // Pe
125 Punctuation_InitialQuote, // Pi
126 Punctuation_FinalQuote, // Pf
127 Punctuation_Other, // Po
128
129 Symbol_Math, // Sm
130 Symbol_Currency, // Sc
131 Symbol_Modifier, // Sk
132 Symbol_Other // So
133 };
134
135 enum Script
136 {
137 Script_Unknown,
138 Script_Inherited,
139 Script_Common,
140
141 Script_Latin,
142 Script_Greek,
143 Script_Cyrillic,
144 Script_Armenian,
145 Script_Hebrew,
146 Script_Arabic,
147 Script_Syriac,
148 Script_Thaana,
149 Script_Devanagari,
150 Script_Bengali,
151 Script_Gurmukhi,
152 Script_Gujarati,
153 Script_Oriya,
154 Script_Tamil,
155 Script_Telugu,
156 Script_Kannada,
157 Script_Malayalam,
158 Script_Sinhala,
159 Script_Thai,
160 Script_Lao,
161 Script_Tibetan,
162 Script_Myanmar,
163 Script_Georgian,
164 Script_Hangul,
165 Script_Ethiopic,
166 Script_Cherokee,
167 Script_CanadianAboriginal,
168 Script_Ogham,
169 Script_Runic,
170 Script_Khmer,
171 Script_Mongolian,
172 Script_Hiragana,
173 Script_Katakana,
174 Script_Bopomofo,
175 Script_Han,
176 Script_Yi,
177 Script_OldItalic,
178 Script_Gothic,
179 Script_Deseret,
180 Script_Tagalog,
181 Script_Hanunoo,
182 Script_Buhid,
183 Script_Tagbanwa,
184 Script_Coptic,
185
186 // Unicode 4.0 additions
187 Script_Limbu,
188 Script_TaiLe,
189 Script_LinearB,
190 Script_Ugaritic,
191 Script_Shavian,
192 Script_Osmanya,
193 Script_Cypriot,
194 Script_Braille,
195
196 // Unicode 4.1 additions
197 Script_Buginese,
198 Script_NewTaiLue,
199 Script_Glagolitic,
200 Script_Tifinagh,
201 Script_SylotiNagri,
202 Script_OldPersian,
203 Script_Kharoshthi,
204
205 // Unicode 5.0 additions
206 Script_Balinese,
207 Script_Cuneiform,
208 Script_Phoenician,
209 Script_PhagsPa,
210 Script_Nko,
211
212 // Unicode 5.1 additions
213 Script_Sundanese,
214 Script_Lepcha,
215 Script_OlChiki,
216 Script_Vai,
217 Script_Saurashtra,
218 Script_KayahLi,
219 Script_Rejang,
220 Script_Lycian,
221 Script_Carian,
222 Script_Lydian,
223 Script_Cham,
224
225 // Unicode 5.2 additions
226 Script_TaiTham,
227 Script_TaiViet,
228 Script_Avestan,
229 Script_EgyptianHieroglyphs,
230 Script_Samaritan,
231 Script_Lisu,
232 Script_Bamum,
233 Script_Javanese,
234 Script_MeeteiMayek,
235 Script_ImperialAramaic,
236 Script_OldSouthArabian,
237 Script_InscriptionalParthian,
238 Script_InscriptionalPahlavi,
239 Script_OldTurkic,
240 Script_Kaithi,
241
242 // Unicode 6.0 additions
243 Script_Batak,
244 Script_Brahmi,
245 Script_Mandaic,
246
247 // Unicode 6.1 additions
248 Script_Chakma,
249 Script_MeroiticCursive,
250 Script_MeroiticHieroglyphs,
251 Script_Miao,
252 Script_Sharada,
253 Script_SoraSompeng,
254 Script_Takri,
255
256 // Unicode 7.0 additions
257 Script_CaucasianAlbanian,
258 Script_BassaVah,
259 Script_Duployan,
260 Script_Elbasan,
261 Script_Grantha,
262 Script_PahawhHmong,
263 Script_Khojki,
264 Script_LinearA,
265 Script_Mahajani,
266 Script_Manichaean,
267 Script_MendeKikakui,
268 Script_Modi,
269 Script_Mro,
270 Script_OldNorthArabian,
271 Script_Nabataean,
272 Script_Palmyrene,
273 Script_PauCinHau,
274 Script_OldPermic,
275 Script_PsalterPahlavi,
276 Script_Siddham,
277 Script_Khudawadi,
278 Script_Tirhuta,
279 Script_WarangCiti,
280
281 // Unicode 8.0 additions
282 Script_Ahom,
283 Script_AnatolianHieroglyphs,
284 Script_Hatran,
285 Script_Multani,
286 Script_OldHungarian,
287 Script_SignWriting,
288
289 // Unicode 9.0 additions
290 Script_Adlam,
291 Script_Bhaiksuki,
292 Script_Marchen,
293 Script_Newa,
294 Script_Osage,
295 Script_Tangut,
296
297 // Unicode 10.0 additions
298 Script_MasaramGondi,
299 Script_Nushu,
300 Script_Soyombo,
301 Script_ZanabazarSquare,
302
303 // Unicode 12.1 additions
304 Script_Dogra,
305 Script_GunjalaGondi,
306 Script_HanifiRohingya,
307 Script_Makasar,
308 Script_Medefaidrin,
309 Script_OldSogdian,
310 Script_Sogdian,
311 Script_Elymaic,
312 Script_Nandinagari,
313 Script_NyiakengPuachueHmong,
314 Script_Wancho,
315
316 // Unicode 13.0 additions
317 Script_Chorasmian,
318 Script_DivesAkuru,
319 Script_KhitanSmallScript,
320 Script_Yezidi,
321
322 // Unicode 14.0 additions
323 Script_CyproMinoan,
324 Script_OldUyghur,
325 Script_Tangsa,
326 Script_Toto,
327 Script_Vithkuqi,
328
329 // Unicode 15.0 additions
330 Script_Kawi,
331 Script_NagMundari,
332
333 // Unicode 16.0 additions
334 Script_Garay,
335 Script_GurungKhema,
336 Script_KiratRai,
337 Script_OlOnal,
338 Script_Sunuwar,
339 Script_Todhri,
340 Script_TuluTigalari,
341
342 ScriptCount
343 };
344
345 enum Direction
346 {
347 DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
348 DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN,
349 DirLRI, DirRLI, DirFSI, DirPDI
350 };
351
352 enum Decomposition
353 {
354 NoDecomposition,
355 Canonical,
356 Font,
357 NoBreak,
358 Initial,
359 Medial,
360 Final,
361 Isolated,
362 Circle,
363 Super,
364 Sub,
365 Vertical,
366 Wide,
367 Narrow,
368 Small,
369 Square,
370 Compat,
371 Fraction
372 };
373
374 enum JoiningType {
375 Joining_None,
376 Joining_Causing,
377 Joining_Dual,
378 Joining_Right,
379 Joining_Left,
380 Joining_Transparent
381 };
382
383 enum CombiningClass
384 {
385 Combining_BelowLeftAttached = 200,
386 Combining_BelowAttached = 202,
387 Combining_BelowRightAttached = 204,
388 Combining_LeftAttached = 208,
389 Combining_RightAttached = 210,
390 Combining_AboveLeftAttached = 212,
391 Combining_AboveAttached = 214,
392 Combining_AboveRightAttached = 216,
393
394 Combining_BelowLeft = 218,
395 Combining_Below = 220,
396 Combining_BelowRight = 222,
397 Combining_Left = 224,
398 Combining_Right = 226,
399 Combining_AboveLeft = 228,
400 Combining_Above = 230,
401 Combining_AboveRight = 232,
402
403 Combining_DoubleBelow = 233,
404 Combining_DoubleAbove = 234,
405 Combining_IotaSubscript = 240
406 };
407
408 enum UnicodeVersion {
409 Unicode_Unassigned,
410 Unicode_1_1,
411 Unicode_2_0,
412 Unicode_2_1_2,
413 Unicode_3_0,
414 Unicode_3_1,
415 Unicode_3_2,
416 Unicode_4_0,
417 Unicode_4_1,
418 Unicode_5_0,
419 Unicode_5_1,
420 Unicode_5_2,
421 Unicode_6_0,
422 Unicode_6_1,
423 Unicode_6_2,
424 Unicode_6_3,
425 Unicode_7_0,
426 Unicode_8_0,
427 Unicode_9_0,
428 Unicode_10_0,
429 Unicode_11_0,
430 Unicode_12_0,
431 Unicode_12_1,
432 Unicode_13_0,
433 Unicode_14_0,
434 Unicode_15_0,
435 Unicode_15_1,
436 Unicode_16_0,
437 };
438
439 inline Category category() const noexcept { return QChar::category(ucs4: ucs); }
440 inline Direction direction() const noexcept { return QChar::direction(ucs4: ucs); }
441 inline JoiningType joiningType() const noexcept { return QChar::joiningType(ucs4: ucs); }
442 inline unsigned char combiningClass() const noexcept { return QChar::combiningClass(ucs4: ucs); }
443
444 inline QChar mirroredChar() const noexcept { return QChar(QChar::mirroredChar(ucs4: ucs)); }
445 inline bool hasMirrored() const noexcept { return QChar::hasMirrored(ucs4: ucs); }
446
447 QString decomposition() const;
448 inline Decomposition decompositionTag() const noexcept { return QChar::decompositionTag(ucs4: ucs); }
449
450 inline int digitValue() const noexcept { return QChar::digitValue(ucs4: ucs); }
451 inline QChar toLower() const noexcept { return QChar(QChar::toLower(ucs4: ucs)); }
452 inline QChar toUpper() const noexcept { return QChar(QChar::toUpper(ucs4: ucs)); }
453 inline QChar toTitleCase() const noexcept { return QChar(QChar::toTitleCase(ucs4: ucs)); }
454 inline QChar toCaseFolded() const noexcept { return QChar(QChar::toCaseFolded(ucs4: ucs)); }
455
456 inline Script script() const noexcept { return QChar::script(ucs4: ucs); }
457
458 inline UnicodeVersion unicodeVersion() const noexcept { return QChar::unicodeVersion(ucs4: ucs); }
459
460 constexpr inline char toLatin1() const noexcept { return ucs > 0xff ? '\0' : char(ucs); }
461 constexpr inline char16_t unicode() const noexcept { return ucs; }
462 constexpr inline char16_t &unicode() noexcept { return ucs; }
463
464 static constexpr QChar fromLatin1(char c) noexcept { return QLatin1Char(c); }
465
466 constexpr inline bool isNull() const noexcept { return ucs == 0; }
467
468 inline bool isPrint() const noexcept { return QChar::isPrint(ucs4: ucs); }
469 constexpr inline bool isSpace() const noexcept { return QChar::isSpace(ucs4: ucs); }
470 inline bool isMark() const noexcept { return QChar::isMark(ucs4: ucs); }
471 inline bool isPunct() const noexcept { return QChar::isPunct(ucs4: ucs); }
472 inline bool isSymbol() const noexcept { return QChar::isSymbol(ucs4: ucs); }
473 constexpr inline bool isLetter() const noexcept { return QChar::isLetter(ucs4: ucs); }
474 constexpr inline bool isNumber() const noexcept { return QChar::isNumber(ucs4: ucs); }
475 constexpr inline bool isLetterOrNumber() const noexcept { return QChar::isLetterOrNumber(ucs4: ucs); }
476 constexpr inline bool isDigit() const noexcept { return QChar::isDigit(ucs4: ucs); }
477 constexpr inline bool isLower() const noexcept { return QChar::isLower(ucs4: ucs); }
478 constexpr inline bool isUpper() const noexcept { return QChar::isUpper(ucs4: ucs); }
479 constexpr inline bool isTitleCase() const noexcept { return QChar::isTitleCase(ucs4: ucs); }
480
481 constexpr inline bool isNonCharacter() const noexcept { return QChar::isNonCharacter(ucs4: ucs); }
482 constexpr inline bool isHighSurrogate() const noexcept { return QChar::isHighSurrogate(ucs4: ucs); }
483 constexpr inline bool isLowSurrogate() const noexcept { return QChar::isLowSurrogate(ucs4: ucs); }
484 constexpr inline bool isSurrogate() const noexcept { return QChar::isSurrogate(ucs4: ucs); }
485
486 constexpr inline uchar cell() const noexcept { return uchar(ucs & 0xff); }
487 constexpr inline uchar row() const noexcept { return uchar((ucs>>8)&0xff); }
488 constexpr inline void setCell(uchar acell) noexcept { ucs = char16_t((ucs & 0xff00) + acell); }
489 constexpr inline void setRow(uchar arow) noexcept { ucs = char16_t((char16_t(arow)<<8) + (ucs&0xff)); }
490
491 static constexpr inline bool isNonCharacter(char32_t ucs4) noexcept
492 {
493 return ucs4 >= 0xfdd0 && (ucs4 <= 0xfdef || (ucs4 & 0xfffe) == 0xfffe);
494 }
495 static constexpr inline bool isHighSurrogate(char32_t ucs4) noexcept
496 {
497 return (ucs4 & 0xfffffc00) == 0xd800; // 0xd800 + up to 1023 (0x3ff)
498 }
499 static constexpr inline bool isLowSurrogate(char32_t ucs4) noexcept
500 {
501 return (ucs4 & 0xfffffc00) == 0xdc00; // 0xdc00 + up to 1023 (0x3ff)
502 }
503 static constexpr inline bool isSurrogate(char32_t ucs4) noexcept
504 {
505 return (ucs4 - 0xd800u < 2048u);
506 }
507 static constexpr inline bool requiresSurrogates(char32_t ucs4) noexcept
508 {
509 return (ucs4 >= 0x10000);
510 }
511 static constexpr inline char32_t surrogateToUcs4(char16_t high, char16_t low) noexcept
512 {
513 // 0x010000 through 0x10ffff, provided params are actual high, low surrogates.
514 // 0x010000 + ((high - 0xd800) << 10) + (low - 0xdc00), optimized:
515 return (char32_t(high)<<10) + low - 0x35fdc00;
516 }
517 static constexpr inline char32_t surrogateToUcs4(QChar high, QChar low) noexcept
518 {
519 return surrogateToUcs4(high: high.ucs, low: low.ucs);
520 }
521 static constexpr inline char16_t highSurrogate(char32_t ucs4) noexcept
522 {
523 return char16_t((ucs4>>10) + 0xd7c0);
524 }
525 static constexpr inline char16_t lowSurrogate(char32_t ucs4) noexcept
526 {
527 return char16_t(ucs4%0x400 + 0xdc00);
528 }
529
530 static Category QT_CHAR_FASTCALL category(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
531 static Direction QT_CHAR_FASTCALL direction(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
532 static JoiningType QT_CHAR_FASTCALL joiningType(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
533 static unsigned char QT_CHAR_FASTCALL combiningClass(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
534
535 static char32_t QT_CHAR_FASTCALL mirroredChar(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
536 static bool QT_CHAR_FASTCALL hasMirrored(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
537
538 static QString QT_CHAR_FASTCALL decomposition(char32_t ucs4);
539 static Decomposition QT_CHAR_FASTCALL decompositionTag(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
540
541 static int QT_CHAR_FASTCALL digitValue(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
542 static char32_t QT_CHAR_FASTCALL toLower(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
543 static char32_t QT_CHAR_FASTCALL toUpper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
544 static char32_t QT_CHAR_FASTCALL toTitleCase(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
545 static char32_t QT_CHAR_FASTCALL toCaseFolded(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
546
547 static Script QT_CHAR_FASTCALL script(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
548
549 static UnicodeVersion QT_CHAR_FASTCALL unicodeVersion(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
550
551 static UnicodeVersion QT_CHAR_FASTCALL currentUnicodeVersion() noexcept Q_DECL_CONST_FUNCTION;
552
553 static bool QT_CHAR_FASTCALL isPrint(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
554 static constexpr inline bool isSpace(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
555 {
556 // note that [0x09..0x0d] + 0x85 are exceptional Cc-s and must be handled explicitly
557 return ucs4 == 0x20 || (ucs4 <= 0x0d && ucs4 >= 0x09)
558 || (ucs4 > 127 && (ucs4 == 0x85 || ucs4 == 0xa0 || QChar::isSpace_helper(ucs4)));
559 }
560 static bool QT_CHAR_FASTCALL isMark(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
561 static bool QT_CHAR_FASTCALL isPunct(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
562 static bool QT_CHAR_FASTCALL isSymbol(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
563 static constexpr inline bool isLetter(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
564 {
565 return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
566 || (ucs4 > 127 && QChar::isLetter_helper(ucs4));
567 }
568 static constexpr inline bool isNumber(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
569 { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::isNumber_helper(ucs4)); }
570 static constexpr inline bool isLetterOrNumber(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
571 {
572 return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
573 || (ucs4 >= '0' && ucs4 <= '9')
574 || (ucs4 > 127 && QChar::isLetterOrNumber_helper(ucs4));
575 }
576 static constexpr inline bool isDigit(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
577 { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::category(ucs4) == Number_DecimalDigit); }
578 static constexpr inline bool isLower(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
579 { return (ucs4 <= 'z' && ucs4 >= 'a') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Lowercase); }
580 static constexpr inline bool isUpper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
581 { return (ucs4 <= 'Z' && ucs4 >= 'A') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Uppercase); }
582 static constexpr inline bool isTitleCase(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
583 { return ucs4 > 127 && QChar::category(ucs4) == Letter_Titlecase; }
584
585 friend constexpr bool comparesEqual(const QChar &lhs, const QChar &rhs) noexcept
586 { return lhs.ucs == rhs.ucs; }
587 friend constexpr Qt::strong_ordering
588 compareThreeWay(const QChar &lhs, const QChar &rhs) noexcept
589 { return Qt::compareThreeWay(lhs: lhs.ucs, rhs: rhs.ucs); }
590 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QChar)
591
592 friend constexpr bool comparesEqual(const QChar &lhs, std::nullptr_t) noexcept
593 { return lhs.isNull(); }
594 friend constexpr Qt::strong_ordering
595 compareThreeWay(const QChar &lhs, std::nullptr_t) noexcept
596 { return lhs.isNull() ? Qt::strong_ordering::equivalent : Qt::strong_ordering::greater; }
597 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QChar, std::nullptr_t)
598
599private:
600 static bool QT_CHAR_FASTCALL isSpace_helper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
601 static bool QT_CHAR_FASTCALL isLetter_helper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
602 static bool QT_CHAR_FASTCALL isNumber_helper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
603 static bool QT_CHAR_FASTCALL isLetterOrNumber_helper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
604
605 // defined in qstring.cpp, because we need to go via QUtf8StringView
606 static bool QT_CHAR_FASTCALL
607 equal_helper(QChar lhs, const char *rhs) noexcept Q_DECL_CONST_FUNCTION;
608 static int QT_CHAR_FASTCALL
609 compare_helper(QChar lhs, const char *rhs) noexcept Q_DECL_CONST_FUNCTION;
610
611#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
612 Q_WEAK_OVERLOAD
613 friend bool comparesEqual(const QChar &lhs, const char *rhs) noexcept
614 { return equal_helper(lhs, rhs); }
615 Q_WEAK_OVERLOAD
616 friend Qt::strong_ordering compareThreeWay(const QChar &lhs, const char *rhs) noexcept
617 {
618 const int res = compare_helper(lhs, rhs);
619 return Qt::compareThreeWay(lhs: res, rhs: 0);
620 }
621 Q_DECLARE_STRONGLY_ORDERED(QChar, const char *, Q_WEAK_OVERLOAD QT_ASCII_CAST_WARN)
622#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
623
624#ifdef QT_NO_CAST_FROM_ASCII
625 QChar(char c) = delete;
626 QChar(uchar c) = delete;
627#endif
628
629 char16_t ucs;
630};
631#undef QT_CHAR_FASTCALL
632
633Q_DECLARE_TYPEINFO(QChar, Q_PRIMITIVE_TYPE);
634
635#ifndef QT_NO_DATASTREAM
636Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QChar);
637Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QChar &);
638#endif
639
640namespace Qt {
641inline namespace Literals {
642inline namespace StringLiterals {
643
644constexpr inline QLatin1Char operator""_L1(char ch) noexcept
645{
646 return QLatin1Char(ch);
647}
648
649} // StringLiterals
650} // Literals
651} // Qt
652
653QT_END_NAMESPACE
654
655namespace std {
656template <>
657struct hash<QT_PREPEND_NAMESPACE(QChar)>
658{
659 template <typename = void> // for transparent constexpr tracking
660 constexpr size_t operator()(QT_PREPEND_NAMESPACE(QChar) c) const
661 noexcept(noexcept(std::hash<char16_t>{}(u' ')))
662 {
663 return std::hash<char16_t>{}(c.unicode());
664 }
665};
666} // namespace std
667
668#endif // QCHAR_H
669
670#include <QtCore/qstringview.h> // for QChar::fromUcs4() definition
671

source code of qtbase/src/corelib/text/qchar.h