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