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 ScriptCount
334 };
335
336 enum Direction
337 {
338 DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
339 DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN,
340 DirLRI, DirRLI, DirFSI, DirPDI
341 };
342
343 enum Decomposition
344 {
345 NoDecomposition,
346 Canonical,
347 Font,
348 NoBreak,
349 Initial,
350 Medial,
351 Final,
352 Isolated,
353 Circle,
354 Super,
355 Sub,
356 Vertical,
357 Wide,
358 Narrow,
359 Small,
360 Square,
361 Compat,
362 Fraction
363 };
364
365 enum JoiningType {
366 Joining_None,
367 Joining_Causing,
368 Joining_Dual,
369 Joining_Right,
370 Joining_Left,
371 Joining_Transparent
372 };
373
374 enum CombiningClass
375 {
376 Combining_BelowLeftAttached = 200,
377 Combining_BelowAttached = 202,
378 Combining_BelowRightAttached = 204,
379 Combining_LeftAttached = 208,
380 Combining_RightAttached = 210,
381 Combining_AboveLeftAttached = 212,
382 Combining_AboveAttached = 214,
383 Combining_AboveRightAttached = 216,
384
385 Combining_BelowLeft = 218,
386 Combining_Below = 220,
387 Combining_BelowRight = 222,
388 Combining_Left = 224,
389 Combining_Right = 226,
390 Combining_AboveLeft = 228,
391 Combining_Above = 230,
392 Combining_AboveRight = 232,
393
394 Combining_DoubleBelow = 233,
395 Combining_DoubleAbove = 234,
396 Combining_IotaSubscript = 240
397 };
398
399 enum UnicodeVersion {
400 Unicode_Unassigned,
401 Unicode_1_1,
402 Unicode_2_0,
403 Unicode_2_1_2,
404 Unicode_3_0,
405 Unicode_3_1,
406 Unicode_3_2,
407 Unicode_4_0,
408 Unicode_4_1,
409 Unicode_5_0,
410 Unicode_5_1,
411 Unicode_5_2,
412 Unicode_6_0,
413 Unicode_6_1,
414 Unicode_6_2,
415 Unicode_6_3,
416 Unicode_7_0,
417 Unicode_8_0,
418 Unicode_9_0,
419 Unicode_10_0,
420 Unicode_11_0,
421 Unicode_12_0,
422 Unicode_12_1,
423 Unicode_13_0,
424 Unicode_14_0,
425 Unicode_15_0,
426 Unicode_15_1,
427 };
428
429 inline Category category() const noexcept { return QChar::category(ucs4: ucs); }
430 inline Direction direction() const noexcept { return QChar::direction(ucs4: ucs); }
431 inline JoiningType joiningType() const noexcept { return QChar::joiningType(ucs4: ucs); }
432 inline unsigned char combiningClass() const noexcept { return QChar::combiningClass(ucs4: ucs); }
433
434 inline QChar mirroredChar() const noexcept { return QChar(QChar::mirroredChar(ucs4: ucs)); }
435 inline bool hasMirrored() const noexcept { return QChar::hasMirrored(ucs4: ucs); }
436
437 QString decomposition() const;
438 inline Decomposition decompositionTag() const noexcept { return QChar::decompositionTag(ucs4: ucs); }
439
440 inline int digitValue() const noexcept { return QChar::digitValue(ucs4: ucs); }
441 inline QChar toLower() const noexcept { return QChar(QChar::toLower(ucs4: ucs)); }
442 inline QChar toUpper() const noexcept { return QChar(QChar::toUpper(ucs4: ucs)); }
443 inline QChar toTitleCase() const noexcept { return QChar(QChar::toTitleCase(ucs4: ucs)); }
444 inline QChar toCaseFolded() const noexcept { return QChar(QChar::toCaseFolded(ucs4: ucs)); }
445
446 inline Script script() const noexcept { return QChar::script(ucs4: ucs); }
447
448 inline UnicodeVersion unicodeVersion() const noexcept { return QChar::unicodeVersion(ucs4: ucs); }
449
450 constexpr inline char toLatin1() const noexcept { return ucs > 0xff ? '\0' : char(ucs); }
451 constexpr inline char16_t unicode() const noexcept { return ucs; }
452 constexpr inline char16_t &unicode() noexcept { return ucs; }
453
454 static constexpr QChar fromLatin1(char c) noexcept { return QLatin1Char(c); }
455
456 constexpr inline bool isNull() const noexcept { return ucs == 0; }
457
458 inline bool isPrint() const noexcept { return QChar::isPrint(ucs4: ucs); }
459 constexpr inline bool isSpace() const noexcept { return QChar::isSpace(ucs4: ucs); }
460 inline bool isMark() const noexcept { return QChar::isMark(ucs4: ucs); }
461 inline bool isPunct() const noexcept { return QChar::isPunct(ucs4: ucs); }
462 inline bool isSymbol() const noexcept { return QChar::isSymbol(ucs4: ucs); }
463 constexpr inline bool isLetter() const noexcept { return QChar::isLetter(ucs4: ucs); }
464 constexpr inline bool isNumber() const noexcept { return QChar::isNumber(ucs4: ucs); }
465 constexpr inline bool isLetterOrNumber() const noexcept { return QChar::isLetterOrNumber(ucs4: ucs); }
466 constexpr inline bool isDigit() const noexcept { return QChar::isDigit(ucs4: ucs); }
467 constexpr inline bool isLower() const noexcept { return QChar::isLower(ucs4: ucs); }
468 constexpr inline bool isUpper() const noexcept { return QChar::isUpper(ucs4: ucs); }
469 constexpr inline bool isTitleCase() const noexcept { return QChar::isTitleCase(ucs4: ucs); }
470
471 constexpr inline bool isNonCharacter() const noexcept { return QChar::isNonCharacter(ucs4: ucs); }
472 constexpr inline bool isHighSurrogate() const noexcept { return QChar::isHighSurrogate(ucs4: ucs); }
473 constexpr inline bool isLowSurrogate() const noexcept { return QChar::isLowSurrogate(ucs4: ucs); }
474 constexpr inline bool isSurrogate() const noexcept { return QChar::isSurrogate(ucs4: ucs); }
475
476 constexpr inline uchar cell() const noexcept { return uchar(ucs & 0xff); }
477 constexpr inline uchar row() const noexcept { return uchar((ucs>>8)&0xff); }
478 constexpr inline void setCell(uchar acell) noexcept { ucs = char16_t((ucs & 0xff00) + acell); }
479 constexpr inline void setRow(uchar arow) noexcept { ucs = char16_t((char16_t(arow)<<8) + (ucs&0xff)); }
480
481 static constexpr inline bool isNonCharacter(char32_t ucs4) noexcept
482 {
483 return ucs4 >= 0xfdd0 && (ucs4 <= 0xfdef || (ucs4 & 0xfffe) == 0xfffe);
484 }
485 static constexpr inline bool isHighSurrogate(char32_t ucs4) noexcept
486 {
487 return (ucs4 & 0xfffffc00) == 0xd800; // 0xd800 + up to 1023 (0x3ff)
488 }
489 static constexpr inline bool isLowSurrogate(char32_t ucs4) noexcept
490 {
491 return (ucs4 & 0xfffffc00) == 0xdc00; // 0xdc00 + up to 1023 (0x3ff)
492 }
493 static constexpr inline bool isSurrogate(char32_t ucs4) noexcept
494 {
495 return (ucs4 - 0xd800u < 2048u);
496 }
497 static constexpr inline bool requiresSurrogates(char32_t ucs4) noexcept
498 {
499 return (ucs4 >= 0x10000);
500 }
501 static constexpr inline char32_t surrogateToUcs4(char16_t high, char16_t low) noexcept
502 {
503 // 0x010000 through 0x10ffff, provided params are actual high, low surrogates.
504 // 0x010000 + ((high - 0xd800) << 10) + (low - 0xdc00), optimized:
505 return (char32_t(high)<<10) + low - 0x35fdc00;
506 }
507 static constexpr inline char32_t surrogateToUcs4(QChar high, QChar low) noexcept
508 {
509 return surrogateToUcs4(high: high.ucs, low: low.ucs);
510 }
511 static constexpr inline char16_t highSurrogate(char32_t ucs4) noexcept
512 {
513 return char16_t((ucs4>>10) + 0xd7c0);
514 }
515 static constexpr inline char16_t lowSurrogate(char32_t ucs4) noexcept
516 {
517 return char16_t(ucs4%0x400 + 0xdc00);
518 }
519
520 static Category QT_CHAR_FASTCALL category(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
521 static Direction QT_CHAR_FASTCALL direction(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
522 static JoiningType QT_CHAR_FASTCALL joiningType(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
523 static unsigned char QT_CHAR_FASTCALL combiningClass(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
524
525 static char32_t QT_CHAR_FASTCALL mirroredChar(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
526 static bool QT_CHAR_FASTCALL hasMirrored(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
527
528 static QString QT_CHAR_FASTCALL decomposition(char32_t ucs4);
529 static Decomposition QT_CHAR_FASTCALL decompositionTag(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
530
531 static int QT_CHAR_FASTCALL digitValue(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
532 static char32_t QT_CHAR_FASTCALL toLower(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
533 static char32_t QT_CHAR_FASTCALL toUpper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
534 static char32_t QT_CHAR_FASTCALL toTitleCase(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
535 static char32_t QT_CHAR_FASTCALL toCaseFolded(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
536
537 static Script QT_CHAR_FASTCALL script(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
538
539 static UnicodeVersion QT_CHAR_FASTCALL unicodeVersion(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
540
541 static UnicodeVersion QT_CHAR_FASTCALL currentUnicodeVersion() noexcept Q_DECL_CONST_FUNCTION;
542
543 static bool QT_CHAR_FASTCALL isPrint(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
544 static constexpr inline bool isSpace(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
545 {
546 // note that [0x09..0x0d] + 0x85 are exceptional Cc-s and must be handled explicitly
547 return ucs4 == 0x20 || (ucs4 <= 0x0d && ucs4 >= 0x09)
548 || (ucs4 > 127 && (ucs4 == 0x85 || ucs4 == 0xa0 || QChar::isSpace_helper(ucs4)));
549 }
550 static bool QT_CHAR_FASTCALL isMark(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
551 static bool QT_CHAR_FASTCALL isPunct(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
552 static bool QT_CHAR_FASTCALL isSymbol(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
553 static constexpr inline bool isLetter(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
554 {
555 return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
556 || (ucs4 > 127 && QChar::isLetter_helper(ucs4));
557 }
558 static constexpr inline bool isNumber(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
559 { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::isNumber_helper(ucs4)); }
560 static constexpr inline bool isLetterOrNumber(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
561 {
562 return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
563 || (ucs4 >= '0' && ucs4 <= '9')
564 || (ucs4 > 127 && QChar::isLetterOrNumber_helper(ucs4));
565 }
566 static constexpr inline bool isDigit(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
567 { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::category(ucs4) == Number_DecimalDigit); }
568 static constexpr inline bool isLower(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
569 { return (ucs4 <= 'z' && ucs4 >= 'a') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Lowercase); }
570 static constexpr inline bool isUpper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
571 { return (ucs4 <= 'Z' && ucs4 >= 'A') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Uppercase); }
572 static constexpr inline bool isTitleCase(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION
573 { return ucs4 > 127 && QChar::category(ucs4) == Letter_Titlecase; }
574
575 friend constexpr bool comparesEqual(const QChar &lhs, const QChar &rhs) noexcept
576 { return lhs.ucs == rhs.ucs; }
577 friend constexpr Qt::strong_ordering
578 compareThreeWay(const QChar &lhs, const QChar &rhs) noexcept
579 { return Qt::compareThreeWay(lhs: lhs.ucs, rhs: rhs.ucs); }
580 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QChar)
581
582 friend constexpr bool comparesEqual(const QChar &lhs, std::nullptr_t) noexcept
583 { return lhs.isNull(); }
584 friend constexpr Qt::strong_ordering
585 compareThreeWay(const QChar &lhs, std::nullptr_t) noexcept
586 { return lhs.isNull() ? Qt::strong_ordering::equivalent : Qt::strong_ordering::greater; }
587 Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QChar, std::nullptr_t)
588
589private:
590 static bool QT_CHAR_FASTCALL isSpace_helper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
591 static bool QT_CHAR_FASTCALL isLetter_helper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
592 static bool QT_CHAR_FASTCALL isNumber_helper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
593 static bool QT_CHAR_FASTCALL isLetterOrNumber_helper(char32_t ucs4) noexcept Q_DECL_CONST_FUNCTION;
594
595 // defined in qstring.cpp, because we need to go via QUtf8StringView
596 static bool QT_CHAR_FASTCALL
597 equal_helper(QChar lhs, const char *rhs) noexcept Q_DECL_CONST_FUNCTION;
598 static int QT_CHAR_FASTCALL
599 compare_helper(QChar lhs, const char *rhs) noexcept Q_DECL_CONST_FUNCTION;
600
601#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
602 Q_WEAK_OVERLOAD
603 friend bool comparesEqual(const QChar &lhs, const char *rhs) noexcept
604 { return equal_helper(lhs, rhs); }
605 Q_WEAK_OVERLOAD
606 friend Qt::strong_ordering compareThreeWay(const QChar &lhs, const char *rhs) noexcept
607 {
608 const int res = compare_helper(lhs, rhs);
609 return Qt::compareThreeWay(lhs: res, rhs: 0);
610 }
611 Q_DECLARE_STRONGLY_ORDERED(QChar, const char *, Q_WEAK_OVERLOAD QT_ASCII_CAST_WARN)
612#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
613
614#ifdef QT_NO_CAST_FROM_ASCII
615 QChar(char c) = delete;
616 QChar(uchar c) = delete;
617#endif
618
619 char16_t ucs;
620};
621#undef QT_CHAR_FASTCALL
622
623Q_DECLARE_TYPEINFO(QChar, Q_PRIMITIVE_TYPE);
624
625#ifndef QT_NO_DATASTREAM
626Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QChar);
627Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QChar &);
628#endif
629
630namespace Qt {
631inline namespace Literals {
632inline namespace StringLiterals {
633
634constexpr inline QLatin1Char operator""_L1(char ch) noexcept
635{
636 return QLatin1Char(ch);
637}
638
639} // StringLiterals
640} // Literals
641} // Qt
642
643QT_END_NAMESPACE
644
645namespace std {
646template <>
647struct hash<QT_PREPEND_NAMESPACE(QChar)>
648{
649 template <typename = void> // for transparent constexpr tracking
650 constexpr size_t operator()(QT_PREPEND_NAMESPACE(QChar) c) const
651 noexcept(noexcept(std::hash<char16_t>{}(u' ')))
652 {
653 return std::hash<char16_t>{}(c.unicode());
654 }
655};
656} // namespace std
657
658#endif // QCHAR_H
659
660#include <QtCore/qstringview.h> // for QChar::fromUcs4() definition
661

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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