[clang] [llvm] [Support] Optimise Unicode.cpp (PR #233945)

Harald van Dijk via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 21 04:32:50 PDT 2026


https://github.com/hvdijk updated https://github.com/llvm/llvm-project/pull/233945

>From 4e918ac01eb9bb9b115f78fc10ed6b2dc1d1b6f9 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Tue, 20 Oct 2026 19:29:06 +0100
Subject: [PATCH 1/6] [Support] Optimise Unicode.cpp

We were generating range tables in the two UnicodeCharSetsGenerated.cpp
files in order to perform a binary search on them, but the tables for
characters and printables were large enough that this search was slower
than needed. This commit replaces the individual tables with a character
property lookup function.

Aside from a performance boost, this also reduces the total data size
from 25,104 to 16,668 bytes, although results will vary across programs
as the table can only be included in full, whereas previously the linker
could discard individual range tables even when including others.
---
 clang/lib/Lex/CMakeLists.txt                  |    1 -
 clang/lib/Lex/Lexer.cpp                       |   41 +-
 clang/lib/Lex/UnicodeCharSets.h               |    9 -
 clang/lib/Lex/UnicodeCharSetsGenerated.cpp    |  423 ----
 llvm/include/llvm/Support/Unicode.h           |   93 +-
 llvm/lib/Support/Unicode.cpp                  |   66 +-
 llvm/lib/Support/UnicodeCharSetsGenerated.cpp | 1706 ++++++++++-------
 llvm/lib/Support/UnicodeCharSetsGenerated.h   |   30 +
 llvm/utils/UnicodeData/CMakeLists.txt         |   27 -
 .../UnicodeData/UnicodeCharSetsGenerator.cpp  |  265 ---
 llvm/utils/generate-unicode-charsetdata.py    |  103 +
 11 files changed, 1258 insertions(+), 1506 deletions(-)
 delete mode 100644 clang/lib/Lex/UnicodeCharSetsGenerated.cpp
 create mode 100644 llvm/lib/Support/UnicodeCharSetsGenerated.h
 delete mode 100644 llvm/utils/UnicodeData/UnicodeCharSetsGenerator.cpp
 create mode 100644 llvm/utils/generate-unicode-charsetdata.py

diff --git a/clang/lib/Lex/CMakeLists.txt b/clang/lib/Lex/CMakeLists.txt
index f333605668abce..7b0be7249cd99a 100644
--- a/clang/lib/Lex/CMakeLists.txt
+++ b/clang/lib/Lex/CMakeLists.txt
@@ -32,7 +32,6 @@ add_clang_library(clangLex
   TextEncoding.cpp
   TokenConcatenation.cpp
   TokenLexer.cpp
-  UnicodeCharSetsGenerated.cpp
 
   LINK_LIBS
   clangBasic
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index b659780bac593a..2202acc4f7f759 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -1613,12 +1613,9 @@ static bool isUnicodeWhitespace(uint32_t Codepoint) {
 // https://www.unicode.org/reports/tr31/#Mathematical_Compatibility_Notation
 static bool isMathematicalExtensionID(uint32_t C, const LangOptions &LangOpts,
                                       bool IsStart, bool &IsExtension) {
-  static const llvm::sys::UnicodeCharSet MathStartChars(
-      GeneratedMathematicalNotationProfileIDStartRanges);
-  static const llvm::sys::UnicodeCharSet MathContinueChars(
-      GeneratedMathematicalNotationProfileIDContinueRanges);
-  if (MathStartChars.contains(C) ||
-      (!IsStart && MathContinueChars.contains(C))) {
+  const llvm::sys::unicode::CharProperties P =
+      llvm::sys::unicode::charProperties(C);
+  if (P.MathStart || (!IsStart && P.MathContinue)) {
     IsExtension = true;
     return true;
   }
@@ -1632,15 +1629,11 @@ static bool isAllowedIDChar(uint32_t C, const LangOptions &LangOpts,
   } else if (LangOpts.DollarIdents && '$' == C) {
     return true;
   } else if (LangOpts.CPlusPlus || LangOpts.C23) {
-    // A non-leading codepoint must have the XID_Continue property.
-    // GeneratedXIDContinueRanges doesn't contain characters also in
-    // GeneratedXIDStartRanges, so we need to check both tables.
-    // '_' doesn't have the XID_Continue property but is allowed in C and C++.
-    static const llvm::sys::UnicodeCharSet XIDStartChars(
-        GeneratedXIDStartRanges);
-    static const llvm::sys::UnicodeCharSet XIDContinueChars(
-        GeneratedXIDContinueRanges);
-    if (C == '_' || XIDStartChars.contains(C) || XIDContinueChars.contains(C))
+    // A non-leading codepoint must have the XID_Start or XID_Continue property.
+    // '_' doesn't have either property but is allowed in C and C++.
+    llvm::sys::unicode::CharProperties P =
+        llvm::sys::unicode::charProperties(C);
+    if (C == '_' || P.XIDStart || P.XIDContinue)
       return true;
     return isMathematicalExtensionID(C, LangOpts, /*IsStart=*/false,
                                      IsExtension);
@@ -1663,9 +1656,11 @@ static bool isAllowedInitiallyIDChar(uint32_t C, const LangOptions &LangOpts,
     return false;
   }
   if (LangOpts.CPlusPlus || LangOpts.C23) {
-    static const llvm::sys::UnicodeCharSet XIDStartChars(
-        GeneratedXIDStartRanges);
-    if (XIDStartChars.contains(C))
+    // A leading codepoint must have the XID_Start property.
+    // '_' doesn't have the property but is allowed in C and C++.
+    llvm::sys::unicode::CharProperties P =
+        llvm::sys::unicode::charProperties(C);
+    if (C == '_' || P.XIDStart)
       return true;
     return isMathematicalExtensionID(C, LangOpts, /*IsStart=*/true,
                                      IsExtension);
@@ -1687,14 +1682,8 @@ diagnoseMathematicalNotationInIdentifier(DiagnosticsEngine &Diags,
                                          const LangOptions &LangOpts,
                                          uint32_t C, CharSourceRange Range) {
 
-  static const llvm::sys::UnicodeCharSet MathStartChars(
-      GeneratedMathematicalNotationProfileIDStartRanges);
-  static const llvm::sys::UnicodeCharSet MathContinueChars(
-      GeneratedMathematicalNotationProfileIDContinueRanges);
-
-  (void)MathStartChars;
-  (void)MathContinueChars;
-  assert((MathStartChars.contains(C) || MathContinueChars.contains(C)) &&
+  assert((llvm::sys::unicode::charProperties(C).MathStart ||
+          llvm::sys::unicode::charProperties(C).MathContinue) &&
          "Unexpected mathematical notation codepoint");
   unsigned DiagID = LangOpts.CPlusPlus
                         ? DiagnosticIDs::getCompatDiagId(
diff --git a/clang/lib/Lex/UnicodeCharSets.h b/clang/lib/Lex/UnicodeCharSets.h
index 186c983e2f6a56..5efae65df8611a 100644
--- a/clang/lib/Lex/UnicodeCharSets.h
+++ b/clang/lib/Lex/UnicodeCharSets.h
@@ -10,15 +10,6 @@
 
 #include "llvm/Support/UnicodeCharRanges.h"
 
-namespace clang {
-extern const llvm::sys::UnicodeCharSet::CharRanges GeneratedXIDStartRanges;
-extern const llvm::sys::UnicodeCharSet::CharRanges GeneratedXIDContinueRanges;
-extern const llvm::sys::UnicodeCharSet::CharRanges
-    GeneratedMathematicalNotationProfileIDStartRanges;
-extern const llvm::sys::UnicodeCharSet::CharRanges
-    GeneratedMathematicalNotationProfileIDContinueRanges;
-} // namespace clang
-
 // C11 D.1, C++11 [charname.allowed]
 static const llvm::sys::UnicodeCharRange C11AllowedIDCharRanges[] = {
   // 1
diff --git a/clang/lib/Lex/UnicodeCharSetsGenerated.cpp b/clang/lib/Lex/UnicodeCharSetsGenerated.cpp
deleted file mode 100644
index f1967d496d9da6..00000000000000
--- a/clang/lib/Lex/UnicodeCharSetsGenerated.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file was generated by llvm/utils/UnicodeData/UnicodeCharSetsGenerator
-// from the Unicode 18.0 Character Database. Do not edit manually.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/UnicodeCharRanges.h"
-
-using llvm::sys::UnicodeCharRange;
-using CharRanges = llvm::sys::UnicodeCharSet::CharRanges;
-
-namespace clang {
-
-// XID_Start
-static constexpr UnicodeCharRange GeneratedXIDStartRangesData[] = {
-    {0x0041, 0x005A},   {0x0061, 0x007A},   {0x00AA, 0x00AA},
-    {0x00B5, 0x00B5},   {0x00BA, 0x00BA},   {0x00C0, 0x00D6},
-    {0x00D8, 0x00F6},   {0x00F8, 0x02C1},   {0x02C6, 0x02D1},
-    {0x02E0, 0x02E4},   {0x02EC, 0x02EC},   {0x02EE, 0x02EE},
-    {0x0370, 0x0374},   {0x0376, 0x0377},   {0x037B, 0x037D},
-    {0x037F, 0x037F},   {0x0386, 0x0386},   {0x0388, 0x038A},
-    {0x038C, 0x038C},   {0x038E, 0x03A1},   {0x03A3, 0x03F5},
-    {0x03F7, 0x0481},   {0x048A, 0x052F},   {0x0531, 0x0556},
-    {0x0558, 0x0559},   {0x0560, 0x0588},   {0x058B, 0x058C},
-    {0x05D0, 0x05EA},   {0x05EF, 0x05F2},   {0x0620, 0x064A},
-    {0x066E, 0x066F},   {0x0671, 0x06D3},   {0x06D5, 0x06D5},
-    {0x06E5, 0x06E6},   {0x06EE, 0x06EF},   {0x06FA, 0x06FC},
-    {0x06FF, 0x06FF},   {0x0710, 0x0710},   {0x0712, 0x072F},
-    {0x074D, 0x07A5},   {0x07B1, 0x07B1},   {0x07CA, 0x07EA},
-    {0x07F4, 0x07F5},   {0x07FA, 0x07FA},   {0x0800, 0x0815},
-    {0x081A, 0x081A},   {0x0824, 0x0824},   {0x0828, 0x0828},
-    {0x0840, 0x0858},   {0x0860, 0x086A},   {0x0870, 0x0887},
-    {0x0889, 0x088F},   {0x08A0, 0x08C9},   {0x0904, 0x0939},
-    {0x093D, 0x093D},   {0x0950, 0x0950},   {0x0958, 0x0961},
-    {0x0971, 0x0980},   {0x0985, 0x098C},   {0x098F, 0x0990},
-    {0x0993, 0x09A8},   {0x09AA, 0x09B0},   {0x09B2, 0x09B2},
-    {0x09B6, 0x09B9},   {0x09BD, 0x09BD},   {0x09CE, 0x09CE},
-    {0x09DC, 0x09DD},   {0x09DF, 0x09E1},   {0x09F0, 0x09F1},
-    {0x09FC, 0x09FC},   {0x0A05, 0x0A0A},   {0x0A0F, 0x0A10},
-    {0x0A13, 0x0A28},   {0x0A2A, 0x0A30},   {0x0A32, 0x0A33},
-    {0x0A35, 0x0A36},   {0x0A38, 0x0A39},   {0x0A59, 0x0A5C},
-    {0x0A5E, 0x0A5E},   {0x0A72, 0x0A74},   {0x0A85, 0x0A8D},
-    {0x0A8F, 0x0A91},   {0x0A93, 0x0AA8},   {0x0AAA, 0x0AB0},
-    {0x0AB2, 0x0AB3},   {0x0AB5, 0x0AB9},   {0x0ABD, 0x0ABD},
-    {0x0AD0, 0x0AD0},   {0x0AE0, 0x0AE1},   {0x0AF9, 0x0AF9},
-    {0x0B05, 0x0B0C},   {0x0B0F, 0x0B10},   {0x0B13, 0x0B28},
-    {0x0B2A, 0x0B30},   {0x0B32, 0x0B33},   {0x0B35, 0x0B39},
-    {0x0B3D, 0x0B3D},   {0x0B5C, 0x0B5D},   {0x0B5F, 0x0B61},
-    {0x0B71, 0x0B71},   {0x0B83, 0x0B83},   {0x0B85, 0x0B8A},
-    {0x0B8E, 0x0B90},   {0x0B92, 0x0B95},   {0x0B99, 0x0B9A},
-    {0x0B9C, 0x0B9C},   {0x0B9E, 0x0B9F},   {0x0BA3, 0x0BA4},
-    {0x0BA8, 0x0BAA},   {0x0BAE, 0x0BB9},   {0x0BD0, 0x0BD0},
-    {0x0C05, 0x0C0C},   {0x0C0E, 0x0C10},   {0x0C12, 0x0C28},
-    {0x0C2A, 0x0C39},   {0x0C3D, 0x0C3D},   {0x0C58, 0x0C5A},
-    {0x0C5C, 0x0C5D},   {0x0C60, 0x0C61},   {0x0C80, 0x0C80},
-    {0x0C85, 0x0C8C},   {0x0C8E, 0x0C90},   {0x0C92, 0x0CA8},
-    {0x0CAA, 0x0CB3},   {0x0CB5, 0x0CB9},   {0x0CBD, 0x0CBD},
-    {0x0CDC, 0x0CDE},   {0x0CE0, 0x0CE1},   {0x0CF1, 0x0CF2},
-    {0x0D04, 0x0D0C},   {0x0D0E, 0x0D10},   {0x0D12, 0x0D3A},
-    {0x0D3D, 0x0D3D},   {0x0D4E, 0x0D4E},   {0x0D54, 0x0D56},
-    {0x0D5F, 0x0D61},   {0x0D7A, 0x0D7F},   {0x0D85, 0x0D96},
-    {0x0D9A, 0x0DB1},   {0x0DB3, 0x0DBB},   {0x0DBD, 0x0DBD},
-    {0x0DC0, 0x0DC6},   {0x0E01, 0x0E30},   {0x0E32, 0x0E32},
-    {0x0E40, 0x0E46},   {0x0E81, 0x0E82},   {0x0E84, 0x0E84},
-    {0x0E86, 0x0E8A},   {0x0E8C, 0x0EA3},   {0x0EA5, 0x0EA5},
-    {0x0EA7, 0x0EB0},   {0x0EB2, 0x0EB2},   {0x0EBD, 0x0EBD},
-    {0x0EC0, 0x0EC4},   {0x0EC6, 0x0EC6},   {0x0EDC, 0x0EDF},
-    {0x0F00, 0x0F00},   {0x0F40, 0x0F47},   {0x0F49, 0x0F6C},
-    {0x0F88, 0x0F8C},   {0x1000, 0x102A},   {0x103F, 0x103F},
-    {0x1050, 0x1055},   {0x105A, 0x105D},   {0x1061, 0x1061},
-    {0x1065, 0x1066},   {0x106E, 0x1070},   {0x1075, 0x1081},
-    {0x108E, 0x108E},   {0x10A0, 0x10C5},   {0x10C7, 0x10C7},
-    {0x10CD, 0x10CD},   {0x10D0, 0x10FA},   {0x10FC, 0x1248},
-    {0x124A, 0x124D},   {0x1250, 0x1256},   {0x1258, 0x1258},
-    {0x125A, 0x125D},   {0x1260, 0x1288},   {0x128A, 0x128D},
-    {0x1290, 0x12B0},   {0x12B2, 0x12B5},   {0x12B8, 0x12BE},
-    {0x12C0, 0x12C0},   {0x12C2, 0x12C5},   {0x12C8, 0x12D6},
-    {0x12D8, 0x1310},   {0x1312, 0x1315},   {0x1318, 0x135A},
-    {0x1380, 0x138F},   {0x13A0, 0x13F5},   {0x13F8, 0x13FD},
-    {0x1401, 0x166C},   {0x166F, 0x167F},   {0x1681, 0x169A},
-    {0x16A0, 0x16EA},   {0x16EE, 0x16F8},   {0x1700, 0x1711},
-    {0x171F, 0x1731},   {0x1740, 0x1751},   {0x1760, 0x176C},
-    {0x176E, 0x1770},   {0x1780, 0x17B3},   {0x17D7, 0x17D7},
-    {0x17DC, 0x17DC},   {0x1820, 0x1878},   {0x1880, 0x18A8},
-    {0x18AA, 0x18AA},   {0x18B0, 0x18F5},   {0x1900, 0x191E},
-    {0x1950, 0x196D},   {0x1970, 0x1974},   {0x1980, 0x19AB},
-    {0x19B0, 0x19C9},   {0x1A00, 0x1A16},   {0x1A20, 0x1A54},
-    {0x1AA7, 0x1AA7},   {0x1B05, 0x1B33},   {0x1B45, 0x1B4C},
-    {0x1B83, 0x1BA0},   {0x1BAE, 0x1BAF},   {0x1BBA, 0x1BE5},
-    {0x1C00, 0x1C23},   {0x1C4D, 0x1C4F},   {0x1C5A, 0x1C7D},
-    {0x1C80, 0x1C8A},   {0x1C90, 0x1CBA},   {0x1CBD, 0x1CBF},
-    {0x1CE9, 0x1CEC},   {0x1CEE, 0x1CF3},   {0x1CF5, 0x1CF6},
-    {0x1CFA, 0x1CFA},   {0x1D00, 0x1DBF},   {0x1E00, 0x1F15},
-    {0x1F18, 0x1F1D},   {0x1F20, 0x1F45},   {0x1F48, 0x1F4D},
-    {0x1F50, 0x1F57},   {0x1F59, 0x1F59},   {0x1F5B, 0x1F5B},
-    {0x1F5D, 0x1F5D},   {0x1F5F, 0x1F7D},   {0x1F80, 0x1FB4},
-    {0x1FB6, 0x1FBC},   {0x1FBE, 0x1FBE},   {0x1FC2, 0x1FC4},
-    {0x1FC6, 0x1FCC},   {0x1FD0, 0x1FD3},   {0x1FD6, 0x1FDB},
-    {0x1FE0, 0x1FEC},   {0x1FF2, 0x1FF4},   {0x1FF6, 0x1FFC},
-    {0x2071, 0x2071},   {0x207F, 0x207F},   {0x208F, 0x209F},
-    {0x2102, 0x2102},   {0x2107, 0x2107},   {0x210A, 0x2113},
-    {0x2115, 0x2115},   {0x2118, 0x211D},   {0x2124, 0x2124},
-    {0x2126, 0x2126},   {0x2128, 0x2128},   {0x212A, 0x2139},
-    {0x213C, 0x213F},   {0x2145, 0x2149},   {0x214E, 0x214E},
-    {0x2160, 0x2188},   {0x2C00, 0x2CE4},   {0x2CEB, 0x2CEE},
-    {0x2CF2, 0x2CF3},   {0x2D00, 0x2D25},   {0x2D27, 0x2D27},
-    {0x2D2D, 0x2D2D},   {0x2D30, 0x2D67},   {0x2D6F, 0x2D6F},
-    {0x2D80, 0x2D96},   {0x2DA0, 0x2DA6},   {0x2DA8, 0x2DAE},
-    {0x2DB0, 0x2DB6},   {0x2DB8, 0x2DBE},   {0x2DC0, 0x2DC6},
-    {0x2DC8, 0x2DCE},   {0x2DD0, 0x2DD6},   {0x2DD8, 0x2DDE},
-    {0x3005, 0x3007},   {0x3021, 0x3029},   {0x3031, 0x3035},
-    {0x3038, 0x303C},   {0x3041, 0x3096},   {0x309D, 0x309F},
-    {0x30A1, 0x30FA},   {0x30FC, 0x30FF},   {0x3105, 0x312F},
-    {0x3131, 0x318E},   {0x31A0, 0x31BF},   {0x31F0, 0x31FF},
-    {0x3400, 0x4DBF},   {0x4E00, 0xA48C},   {0xA4D0, 0xA4FD},
-    {0xA500, 0xA60C},   {0xA610, 0xA61F},   {0xA62A, 0xA62B},
-    {0xA640, 0xA66E},   {0xA67F, 0xA69D},   {0xA6A0, 0xA6EF},
-    {0xA717, 0xA71F},   {0xA722, 0xA788},   {0xA78B, 0xA7DD},
-    {0xA7E2, 0xA7E2},   {0xA7F1, 0xA801},   {0xA803, 0xA805},
-    {0xA807, 0xA80A},   {0xA80C, 0xA822},   {0xA840, 0xA873},
-    {0xA882, 0xA8B3},   {0xA8F2, 0xA8F7},   {0xA8FB, 0xA8FB},
-    {0xA8FD, 0xA8FE},   {0xA90A, 0xA925},   {0xA930, 0xA946},
-    {0xA960, 0xA97C},   {0xA984, 0xA9B2},   {0xA9CF, 0xA9CF},
-    {0xA9E0, 0xA9E4},   {0xA9E6, 0xA9EF},   {0xA9FA, 0xA9FE},
-    {0xAA00, 0xAA28},   {0xAA40, 0xAA42},   {0xAA44, 0xAA4B},
-    {0xAA60, 0xAA76},   {0xAA7A, 0xAA7A},   {0xAA7E, 0xAAAF},
-    {0xAAB1, 0xAAB1},   {0xAAB5, 0xAAB6},   {0xAAB9, 0xAABD},
-    {0xAAC0, 0xAAC0},   {0xAAC2, 0xAAC2},   {0xAADB, 0xAADD},
-    {0xAAE0, 0xAAEA},   {0xAAF2, 0xAAF4},   {0xAB01, 0xAB06},
-    {0xAB09, 0xAB0E},   {0xAB11, 0xAB16},   {0xAB20, 0xAB26},
-    {0xAB28, 0xAB2E},   {0xAB30, 0xAB5A},   {0xAB5C, 0xAB69},
-    {0xAB6C, 0xAB6D},   {0xAB70, 0xABE2},   {0xAC00, 0xD7A3},
-    {0xD7B0, 0xD7C6},   {0xD7CB, 0xD7FB},   {0xF900, 0xFA6D},
-    {0xFA70, 0xFAD9},   {0xFB00, 0xFB06},   {0xFB13, 0xFB17},
-    {0xFB1D, 0xFB1D},   {0xFB1F, 0xFB28},   {0xFB2A, 0xFB36},
-    {0xFB38, 0xFB3C},   {0xFB3E, 0xFB3E},   {0xFB40, 0xFB41},
-    {0xFB43, 0xFB44},   {0xFB46, 0xFBB1},   {0xFBD3, 0xFC5D},
-    {0xFC64, 0xFD3D},   {0xFD50, 0xFD8F},   {0xFD92, 0xFDC7},
-    {0xFDF0, 0xFDF9},   {0xFE71, 0xFE71},   {0xFE73, 0xFE73},
-    {0xFE77, 0xFE77},   {0xFE79, 0xFE79},   {0xFE7B, 0xFE7B},
-    {0xFE7D, 0xFE7D},   {0xFE7F, 0xFEFC},   {0xFF21, 0xFF3A},
-    {0xFF41, 0xFF5A},   {0xFF66, 0xFF9D},   {0xFFA0, 0xFFBE},
-    {0xFFC2, 0xFFC7},   {0xFFCA, 0xFFCF},   {0xFFD2, 0xFFD7},
-    {0xFFDA, 0xFFDC},   {0x10000, 0x1000B}, {0x1000D, 0x10026},
-    {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D},
-    {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10140, 0x10174},
-    {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x10300, 0x1031F},
-    {0x1032D, 0x1034A}, {0x10350, 0x10375}, {0x10380, 0x1039D},
-    {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D1, 0x103D5},
-    {0x10400, 0x1049D}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB},
-    {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10570, 0x1057A},
-    {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595},
-    {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9},
-    {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736},
-    {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785},
-    {0x10787, 0x107B0}, {0x107B2, 0x107BF}, {0x10800, 0x10805},
-    {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838},
-    {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10860, 0x10876},
-    {0x10880, 0x1089E}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5},
-    {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10940, 0x10959},
-    {0x10980, 0x109B7}, {0x109BE, 0x109BF}, {0x10A00, 0x10A00},
-    {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35},
-    {0x10A60, 0x10A7C}, {0x10A80, 0x10A9C}, {0x10AC0, 0x10AC7},
-    {0x10AC9, 0x10AE4}, {0x10B00, 0x10B35}, {0x10B40, 0x10B55},
-    {0x10B60, 0x10B72}, {0x10B80, 0x10B91}, {0x10C00, 0x10C48},
-    {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D00, 0x10D23},
-    {0x10D4A, 0x10D65}, {0x10D6F, 0x10D85}, {0x10E80, 0x10EA9},
-    {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10ED9, 0x10EEE},
-    {0x10F00, 0x10F1C}, {0x10F27, 0x10F27}, {0x10F30, 0x10F45},
-    {0x10F70, 0x10F81}, {0x10FB0, 0x10FC4}, {0x10FE0, 0x10FF6},
-    {0x11003, 0x11037}, {0x11071, 0x11072}, {0x11075, 0x11075},
-    {0x11083, 0x110AF}, {0x110D0, 0x110E8}, {0x11103, 0x11126},
-    {0x11144, 0x11144}, {0x11147, 0x11147}, {0x11150, 0x11172},
-    {0x11176, 0x11176}, {0x11183, 0x111B2}, {0x111C1, 0x111C4},
-    {0x111DA, 0x111DA}, {0x111DC, 0x111DC}, {0x11200, 0x11211},
-    {0x11213, 0x1122B}, {0x1123F, 0x11240}, {0x11280, 0x11286},
-    {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D},
-    {0x1129F, 0x112A8}, {0x112B0, 0x112DE}, {0x11305, 0x1130C},
-    {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330},
-    {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133D, 0x1133D},
-    {0x11350, 0x11350}, {0x1135D, 0x11361}, {0x11380, 0x11389},
-    {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5},
-    {0x113B7, 0x113B7}, {0x113D1, 0x113D1}, {0x113D3, 0x113D3},
-    {0x11400, 0x11434}, {0x11447, 0x1144A}, {0x1145F, 0x11461},
-    {0x11480, 0x114AF}, {0x114C4, 0x114C5}, {0x114C7, 0x114C7},
-    {0x11580, 0x115AE}, {0x115D8, 0x115DB}, {0x11600, 0x1162F},
-    {0x11644, 0x11644}, {0x11680, 0x116AA}, {0x116B8, 0x116B8},
-    {0x11700, 0x1171A}, {0x11740, 0x11746}, {0x11800, 0x1182B},
-    {0x118A0, 0x118DF}, {0x118FF, 0x11906}, {0x11909, 0x11909},
-    {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x1192F},
-    {0x1193F, 0x1193F}, {0x11941, 0x11941}, {0x119A0, 0x119A7},
-    {0x119AA, 0x119D0}, {0x119E1, 0x119E1}, {0x119E3, 0x119E3},
-    {0x11A00, 0x11A00}, {0x11A0B, 0x11A32}, {0x11A3A, 0x11A3A},
-    {0x11A50, 0x11A50}, {0x11A5C, 0x11A89}, {0x11A9D, 0x11A9D},
-    {0x11AB0, 0x11AF8}, {0x11B0A, 0x11B0A}, {0x11BC0, 0x11BE0},
-    {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C40, 0x11C40},
-    {0x11C72, 0x11C8F}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09},
-    {0x11D0B, 0x11D30}, {0x11D46, 0x11D46}, {0x11D60, 0x11D65},
-    {0x11D67, 0x11D68}, {0x11D6A, 0x11D89}, {0x11D98, 0x11D98},
-    {0x11DB0, 0x11DDB}, {0x11DF1, 0x11DF1}, {0x11EE0, 0x11EF2},
-    {0x11F02, 0x11F02}, {0x11F04, 0x11F10}, {0x11F12, 0x11F33},
-    {0x11FB0, 0x11FB0}, {0x12000, 0x12399}, {0x12400, 0x1246F},
-    {0x12475, 0x12543}, {0x12550, 0x12686}, {0x12F90, 0x12FF0},
-    {0x13000, 0x1342F}, {0x13441, 0x13446}, {0x13460, 0x143FA},
-    {0x14400, 0x14646}, {0x16100, 0x1611D}, {0x16800, 0x16A38},
-    {0x16A40, 0x16A5E}, {0x16A70, 0x16ABE}, {0x16AD0, 0x16AED},
-    {0x16B00, 0x16B2F}, {0x16B40, 0x16B43}, {0x16B63, 0x16B77},
-    {0x16B7D, 0x16B8F}, {0x16D40, 0x16D6C}, {0x16E40, 0x16E7F},
-    {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A},
-    {0x16F50, 0x16F50}, {0x16F93, 0x16F9F}, {0x16FE0, 0x16FE1},
-    {0x16FE3, 0x16FE3}, {0x16FF2, 0x16FF6}, {0x17000, 0x18CDA},
-    {0x18CFF, 0x18D20}, {0x18D80, 0x18DF2}, {0x18E00, 0x19191},
-    {0x191A0, 0x191D2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB},
-    {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B128}, {0x1B132, 0x1B132},
-    {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B168},
-    {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
-    {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1D400, 0x1D454},
-    {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2},
-    {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9},
-    {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505},
-    {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C},
-    {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544},
-    {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A6},
-    {0x1D6A8, 0x1D6C0}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA},
-    {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, {0x1D736, 0x1D74E},
-    {0x1D750, 0x1D76E}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8},
-    {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, {0x1DF00, 0x1DF81},
-    {0x1DF90, 0x1DF96}, {0x1DFCD, 0x1DFFF}, {0x1E030, 0x1E06D},
-    {0x1E100, 0x1E12C}, {0x1E137, 0x1E13D}, {0x1E14E, 0x1E14E},
-    {0x1E290, 0x1E2AD}, {0x1E2C0, 0x1E2EB}, {0x1E4D0, 0x1E4EB},
-    {0x1E5D0, 0x1E5ED}, {0x1E5F0, 0x1E5F0}, {0x1E6C0, 0x1E6DE},
-    {0x1E6E0, 0x1E6E2}, {0x1E6E4, 0x1E6E5}, {0x1E6E7, 0x1E6ED},
-    {0x1E6F0, 0x1E6F4}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6},
-    {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE},
-    {0x1E800, 0x1E8C4}, {0x1E900, 0x1E943}, {0x1E94B, 0x1E94B},
-    {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22},
-    {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32},
-    {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B},
-    {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49},
-    {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52},
-    {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59},
-    {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F},
-    {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A},
-    {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C},
-    {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B},
-    {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB},
-    {0x20000, 0x2A6DF}, {0x2A700, 0x2B81E}, {0x2B820, 0x2CEAD},
-    {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D},
-    {0x30000, 0x3134A}, {0x31350, 0x33479}, {0x3D000, 0x3FC3F},
-};
-extern const CharRanges GeneratedXIDStartRanges = GeneratedXIDStartRangesData;
-
-// XID_Continue, excluding XID_Start
-static constexpr UnicodeCharRange GeneratedXIDContinueRangesData[] = {
-    {0x0030, 0x0039},   {0x005F, 0x005F},   {0x00B7, 0x00B7},
-    {0x0300, 0x036F},   {0x0387, 0x0387},   {0x0483, 0x0487},
-    {0x0591, 0x05BD},   {0x05BF, 0x05BF},   {0x05C1, 0x05C2},
-    {0x05C4, 0x05C5},   {0x05C7, 0x05C9},   {0x0610, 0x061A},
-    {0x064B, 0x0669},   {0x0670, 0x0670},   {0x06D6, 0x06DC},
-    {0x06DF, 0x06E4},   {0x06E7, 0x06E8},   {0x06EA, 0x06ED},
-    {0x06F0, 0x06F9},   {0x0711, 0x0711},   {0x0730, 0x074A},
-    {0x07A6, 0x07B0},   {0x07C0, 0x07C9},   {0x07EB, 0x07F3},
-    {0x07FD, 0x07FD},   {0x0816, 0x0819},   {0x081B, 0x0823},
-    {0x0825, 0x0827},   {0x0829, 0x082D},   {0x0859, 0x085B},
-    {0x0897, 0x089F},   {0x08CA, 0x08E1},   {0x08E3, 0x0903},
-    {0x093A, 0x093C},   {0x093E, 0x094F},   {0x0951, 0x0957},
-    {0x0962, 0x0963},   {0x0966, 0x096F},   {0x0981, 0x0983},
-    {0x09BC, 0x09BC},   {0x09BE, 0x09C4},   {0x09C7, 0x09C8},
-    {0x09CB, 0x09CD},   {0x09D7, 0x09D7},   {0x09E2, 0x09E3},
-    {0x09E6, 0x09EF},   {0x09FE, 0x09FE},   {0x0A01, 0x0A03},
-    {0x0A3C, 0x0A3C},   {0x0A3E, 0x0A42},   {0x0A47, 0x0A48},
-    {0x0A4B, 0x0A4D},   {0x0A51, 0x0A51},   {0x0A66, 0x0A71},
-    {0x0A75, 0x0A75},   {0x0A81, 0x0A83},   {0x0ABC, 0x0ABC},
-    {0x0ABE, 0x0AC5},   {0x0AC7, 0x0AC9},   {0x0ACB, 0x0ACD},
-    {0x0AE2, 0x0AE3},   {0x0AE6, 0x0AEF},   {0x0AFA, 0x0AFF},
-    {0x0B01, 0x0B03},   {0x0B3C, 0x0B3C},   {0x0B3E, 0x0B44},
-    {0x0B47, 0x0B48},   {0x0B4B, 0x0B4D},   {0x0B53, 0x0B57},
-    {0x0B62, 0x0B63},   {0x0B66, 0x0B6F},   {0x0B82, 0x0B82},
-    {0x0BBE, 0x0BC2},   {0x0BC6, 0x0BC8},   {0x0BCA, 0x0BCD},
-    {0x0BD7, 0x0BD7},   {0x0BE6, 0x0BEF},   {0x0C00, 0x0C04},
-    {0x0C3C, 0x0C3C},   {0x0C3E, 0x0C44},   {0x0C46, 0x0C48},
-    {0x0C4A, 0x0C4D},   {0x0C55, 0x0C56},   {0x0C62, 0x0C63},
-    {0x0C66, 0x0C6F},   {0x0C81, 0x0C83},   {0x0CBC, 0x0CBC},
-    {0x0CBE, 0x0CC4},   {0x0CC6, 0x0CC8},   {0x0CCA, 0x0CCD},
-    {0x0CD5, 0x0CD6},   {0x0CE2, 0x0CE3},   {0x0CE6, 0x0CEF},
-    {0x0CF3, 0x0CF3},   {0x0D00, 0x0D03},   {0x0D3B, 0x0D3C},
-    {0x0D3E, 0x0D44},   {0x0D46, 0x0D48},   {0x0D4A, 0x0D4D},
-    {0x0D57, 0x0D57},   {0x0D62, 0x0D63},   {0x0D66, 0x0D6F},
-    {0x0D81, 0x0D83},   {0x0DCA, 0x0DCA},   {0x0DCF, 0x0DD4},
-    {0x0DD6, 0x0DD6},   {0x0DD8, 0x0DDF},   {0x0DE6, 0x0DEF},
-    {0x0DF2, 0x0DF3},   {0x0E31, 0x0E31},   {0x0E33, 0x0E3A},
-    {0x0E47, 0x0E4E},   {0x0E50, 0x0E59},   {0x0EB1, 0x0EB1},
-    {0x0EB3, 0x0EBC},   {0x0EC8, 0x0ECE},   {0x0ED0, 0x0ED9},
-    {0x0F18, 0x0F19},   {0x0F20, 0x0F29},   {0x0F35, 0x0F35},
-    {0x0F37, 0x0F37},   {0x0F39, 0x0F39},   {0x0F3E, 0x0F3F},
-    {0x0F71, 0x0F84},   {0x0F86, 0x0F87},   {0x0F8D, 0x0F97},
-    {0x0F99, 0x0FBC},   {0x0FC6, 0x0FC6},   {0x102B, 0x103E},
-    {0x1040, 0x1049},   {0x1056, 0x1059},   {0x105E, 0x1060},
-    {0x1062, 0x1064},   {0x1067, 0x106D},   {0x1071, 0x1074},
-    {0x1082, 0x108D},   {0x108F, 0x109D},   {0x135D, 0x135F},
-    {0x1369, 0x1371},   {0x1712, 0x1715},   {0x1732, 0x1734},
-    {0x1752, 0x1753},   {0x1772, 0x1773},   {0x17B4, 0x17D3},
-    {0x17DD, 0x17DD},   {0x17E0, 0x17E9},   {0x180B, 0x180D},
-    {0x180F, 0x1819},   {0x18A9, 0x18A9},   {0x1920, 0x192B},
-    {0x1930, 0x193B},   {0x1946, 0x194F},   {0x19D0, 0x19DA},
-    {0x1A17, 0x1A1B},   {0x1A55, 0x1A5E},   {0x1A60, 0x1A7C},
-    {0x1A7F, 0x1A89},   {0x1A90, 0x1A99},   {0x1AB0, 0x1ABD},
-    {0x1ABF, 0x1AF0},   {0x1B00, 0x1B04},   {0x1B34, 0x1B44},
-    {0x1B50, 0x1B59},   {0x1B6B, 0x1B73},   {0x1B80, 0x1B82},
-    {0x1BA1, 0x1BAD},   {0x1BB0, 0x1BB9},   {0x1BE6, 0x1BF3},
-    {0x1C24, 0x1C37},   {0x1C40, 0x1C49},   {0x1C50, 0x1C59},
-    {0x1CD0, 0x1CD2},   {0x1CD4, 0x1CE8},   {0x1CED, 0x1CED},
-    {0x1CF4, 0x1CF4},   {0x1CF7, 0x1CF9},   {0x1DC0, 0x1DFF},
-    {0x200C, 0x200D},   {0x203F, 0x2040},   {0x2054, 0x2054},
-    {0x20D0, 0x20DC},   {0x20E1, 0x20E1},   {0x20E5, 0x20F0},
-    {0x2CEF, 0x2CF1},   {0x2D7F, 0x2D7F},   {0x2DE0, 0x2DFF},
-    {0x302A, 0x302F},   {0x3099, 0x309A},   {0x30FB, 0x30FB},
-    {0xA620, 0xA629},   {0xA66F, 0xA66F},   {0xA674, 0xA67D},
-    {0xA69E, 0xA69F},   {0xA6F0, 0xA6F1},   {0xA802, 0xA802},
-    {0xA806, 0xA806},   {0xA80B, 0xA80B},   {0xA823, 0xA827},
-    {0xA82C, 0xA82C},   {0xA880, 0xA881},   {0xA8B4, 0xA8C5},
-    {0xA8D0, 0xA8D9},   {0xA8E0, 0xA8F1},   {0xA8FF, 0xA909},
-    {0xA926, 0xA92D},   {0xA947, 0xA953},   {0xA980, 0xA983},
-    {0xA9B3, 0xA9C0},   {0xA9D0, 0xA9D9},   {0xA9E5, 0xA9E5},
-    {0xA9F0, 0xA9F9},   {0xAA29, 0xAA36},   {0xAA43, 0xAA43},
-    {0xAA4C, 0xAA4D},   {0xAA50, 0xAA59},   {0xAA7B, 0xAA7D},
-    {0xAAB0, 0xAAB0},   {0xAAB2, 0xAAB4},   {0xAAB7, 0xAAB8},
-    {0xAABE, 0xAABF},   {0xAAC1, 0xAAC1},   {0xAAEB, 0xAAEF},
-    {0xAAF5, 0xAAF6},   {0xABE3, 0xABEA},   {0xABEC, 0xABED},
-    {0xABF0, 0xABF9},   {0xFB1E, 0xFB1E},   {0xFE00, 0xFE0F},
-    {0xFE20, 0xFE2F},   {0xFE33, 0xFE34},   {0xFE4D, 0xFE4F},
-    {0xFF10, 0xFF19},   {0xFF3F, 0xFF3F},   {0xFF65, 0xFF65},
-    {0xFF9E, 0xFF9F},   {0x101FD, 0x101FD}, {0x102E0, 0x102E0},
-    {0x10376, 0x1037A}, {0x104A0, 0x104A9}, {0x10A01, 0x10A03},
-    {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A},
-    {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x10D24, 0x10D27},
-    {0x10D30, 0x10D39}, {0x10D40, 0x10D49}, {0x10D69, 0x10D6D},
-    {0x10EAB, 0x10EAC}, {0x10ECB, 0x10ECF}, {0x10EF0, 0x10EFF},
-    {0x10F46, 0x10F50}, {0x10F82, 0x10F85}, {0x11000, 0x11002},
-    {0x11038, 0x11046}, {0x11066, 0x11070}, {0x11073, 0x11074},
-    {0x1107F, 0x11082}, {0x110B0, 0x110BA}, {0x110C2, 0x110C2},
-    {0x110F0, 0x110F9}, {0x11100, 0x11102}, {0x11127, 0x11134},
-    {0x11136, 0x1113F}, {0x11145, 0x11146}, {0x11173, 0x11173},
-    {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111C9, 0x111CC},
-    {0x111CE, 0x111D9}, {0x1122C, 0x11237}, {0x1123E, 0x1123E},
-    {0x11241, 0x11241}, {0x112DF, 0x112EA}, {0x112F0, 0x112F9},
-    {0x11300, 0x11303}, {0x1133B, 0x1133C}, {0x1133E, 0x11344},
-    {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357},
-    {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374},
-    {0x113B8, 0x113C0}, {0x113C2, 0x113C2}, {0x113C5, 0x113C5},
-    {0x113C7, 0x113CA}, {0x113CC, 0x113D0}, {0x113D2, 0x113D2},
-    {0x113E1, 0x113E2}, {0x11435, 0x11446}, {0x11450, 0x11459},
-    {0x1145E, 0x1145E}, {0x114B0, 0x114C3}, {0x114D0, 0x114D9},
-    {0x115AF, 0x115B5}, {0x115B8, 0x115C0}, {0x115DC, 0x115DD},
-    {0x11630, 0x11640}, {0x11650, 0x11659}, {0x116AB, 0x116B7},
-    {0x116C0, 0x116C9}, {0x116D0, 0x116E3}, {0x1171D, 0x1172B},
-    {0x11730, 0x11739}, {0x1182C, 0x1183A}, {0x118E0, 0x118E9},
-    {0x11930, 0x11935}, {0x11937, 0x11938}, {0x1193B, 0x1193E},
-    {0x11940, 0x11940}, {0x11942, 0x11943}, {0x11950, 0x11959},
-    {0x119D1, 0x119D7}, {0x119DA, 0x119E0}, {0x119E4, 0x119E4},
-    {0x11A01, 0x11A0A}, {0x11A33, 0x11A39}, {0x11A3B, 0x11A3E},
-    {0x11A47, 0x11A47}, {0x11A51, 0x11A5B}, {0x11A8A, 0x11A99},
-    {0x11B60, 0x11B67}, {0x11BF0, 0x11BF9}, {0x11C2F, 0x11C36},
-    {0x11C38, 0x11C3F}, {0x11C50, 0x11C59}, {0x11C92, 0x11CA7},
-    {0x11CA9, 0x11CB6}, {0x11D31, 0x11D36}, {0x11D3A, 0x11D3A},
-    {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D45}, {0x11D47, 0x11D47},
-    {0x11D50, 0x11D59}, {0x11D8A, 0x11D8E}, {0x11D90, 0x11D91},
-    {0x11D93, 0x11D97}, {0x11DA0, 0x11DA9}, {0x11DE0, 0x11DE9},
-    {0x11DF0, 0x11DF0}, {0x11EF3, 0x11EF6}, {0x11F00, 0x11F01},
-    {0x11F03, 0x11F03}, {0x11F34, 0x11F3A}, {0x11F3E, 0x11F42},
-    {0x11F50, 0x11F5A}, {0x13440, 0x13440}, {0x13447, 0x13455},
-    {0x1611E, 0x16139}, {0x16A60, 0x16A69}, {0x16AC0, 0x16AC9},
-    {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16B50, 0x16B59},
-    {0x16D70, 0x16D79}, {0x16F4F, 0x16F4F}, {0x16F51, 0x16F87},
-    {0x16F8F, 0x16F92}, {0x16FE4, 0x16FE4}, {0x16FF0, 0x16FF1},
-    {0x1BC9D, 0x1BC9E}, {0x1CCF0, 0x1CCF9}, {0x1CF00, 0x1CF2D},
-    {0x1CF30, 0x1CF46}, {0x1D127, 0x1D128}, {0x1D165, 0x1D169},
-    {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B},
-    {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1D250, 0x1D252},
-    {0x1D25B, 0x1D25C}, {0x1D25F, 0x1D25F}, {0x1D280, 0x1D281},
-    {0x1D7CE, 0x1D7FF}, {0x1DA00, 0x1DA36}, {0x1DA3B, 0x1DA6C},
-    {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, {0x1DA9B, 0x1DA9F},
-    {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018},
-    {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A},
-    {0x1E08F, 0x1E08F}, {0x1E130, 0x1E136}, {0x1E140, 0x1E149},
-    {0x1E2AE, 0x1E2AE}, {0x1E2EC, 0x1E2F9}, {0x1E4EC, 0x1E4F9},
-    {0x1E5EE, 0x1E5EF}, {0x1E5F1, 0x1E5FA}, {0x1E6E3, 0x1E6E3},
-    {0x1E6E6, 0x1E6E6}, {0x1E6EE, 0x1E6EF}, {0x1E6F5, 0x1E6F5},
-    {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, {0x1E950, 0x1E959},
-    {0x1FBF0, 0x1FBF9}, {0xE0100, 0xE01EF},
-};
-extern const CharRanges GeneratedXIDContinueRanges =
-    GeneratedXIDContinueRangesData;
-
-// ID_Compat_Math_Start
-static constexpr UnicodeCharRange
-    GeneratedMathematicalNotationProfileIDStartRangesData[] = {
-        {0x2202, 0x2202},   {0x2207, 0x2207},   {0x221E, 0x221E},
-        {0x1D6C1, 0x1D6C1}, {0x1D6DB, 0x1D6DB}, {0x1D6FB, 0x1D6FB},
-        {0x1D715, 0x1D715}, {0x1D735, 0x1D735}, {0x1D74F, 0x1D74F},
-        {0x1D76F, 0x1D76F}, {0x1D789, 0x1D789}, {0x1D7A9, 0x1D7A9},
-        {0x1D7C3, 0x1D7C3},
-};
-extern const CharRanges GeneratedMathematicalNotationProfileIDStartRanges =
-    GeneratedMathematicalNotationProfileIDStartRangesData;
-
-// ID_Compat_Math_Continue, excluding ID_Compat_Math_Start
-static constexpr UnicodeCharRange
-    GeneratedMathematicalNotationProfileIDContinueRangesData[] = {
-        {0x00B2, 0x00B3}, {0x00B9, 0x00B9}, {0x2070, 0x2070},
-        {0x2074, 0x207E}, {0x2080, 0x208E},
-};
-extern const CharRanges GeneratedMathematicalNotationProfileIDContinueRanges =
-    GeneratedMathematicalNotationProfileIDContinueRangesData;
-
-} // namespace clang
diff --git a/llvm/include/llvm/Support/Unicode.h b/llvm/include/llvm/Support/Unicode.h
index 73beed93c7bf02..05d2c209f1cc64 100644
--- a/llvm/include/llvm/Support/Unicode.h
+++ b/llvm/include/llvm/Support/Unicode.h
@@ -25,31 +25,114 @@ class StringRef;
 namespace sys {
 namespace unicode {
 
+enum class CharCategory : unsigned {
+  Lu, // Letter, Uppercase
+  Ll, // Letter, Lowercase
+  Lt, // Letter, Titlecase
+  Lm, // Letter, Modifier
+  Lo, // Letter, Other
+  Mn, // Mark, Non-Spacing
+  Mc, // Mark, Spacing Combining
+  Me, // Mark, Enclosing
+  Nd, // Number, Decimal Digit
+  Nl, // Number, Letter
+  No, // Number, Other
+  Pc, // Punctuation, Connector
+  Pd, // Punctuation, Dash
+  Ps, // Punctuation, Open
+  Pe, // Punctuation, Close
+  Pi, // Punctuation, Initial Quote
+  Pf, // Punctuation, Final Quote
+  Po, // Punctuation, Other
+  Sm, // Symbol, Math
+  Sc, // Symbol, Currency
+  Sk, // Symbol, Modifier
+  So, // Symbol, Other
+  Zs, // Separator, Space
+  Zl, // Separator, Line
+  Zp, // Separator, Paragraph
+  Co, // Other, Private Use
+  Cf, // Other, Format
+  Cc, // Other, Control
+  Cs, // Other, Surrogate
+  Cn, // Other, Not Assigned
+};
+
+enum class EastAsianWidth : unsigned {
+  N,  // Neutral
+  Na, // East Asian Narrow
+  H,  // East Asian Halfwidth
+  A,  // East Asian Ambiguous
+  F,  // East Asian Fullwidth
+  W,  // East Asian Wide
+};
+
+struct CharProperties {
+  CharCategory Gc : 5;
+  EastAsianWidth Ea : 3;
+  unsigned XIDStart : 1;
+  unsigned XIDContinue : 1;
+  unsigned MathStart : 1;
+  unsigned MathContinue : 1;
+
+  bool isCharacter() const { return Gc <= CharCategory::Cc; }
+
+  bool isCombining() const {
+    return Gc == CharCategory::Me || Gc == CharCategory::Mn;
+  }
+
+  bool isControl() const { return Gc == CharCategory::Cc; }
+
+  bool isDoubleWidth() const { return Ea >= EastAsianWidth::F; }
+
+  bool isFormatting() const { return Gc == CharCategory::Cf; }
+
+  bool isPrintable(int UCS) const {
+    return Gc <= CharCategory::Zs || UCS == 0x00AD;
+  }
+};
+
 enum ColumnWidthErrors {
   ErrorInvalidUTF8 = -2,
   ErrorNonPrintableCharacter = -1
 };
 
+/// Return the character properties of the given Unicode code point. If UCS is
+/// out of range, the character properties will match that of any in-range
+/// non-character code point.
+LLVM_ABI LLVM_READONLY const CharProperties &charProperties(int UCS);
+
 /// Unicode code points that are considered characters. This function
 /// returns true for any code point defined by Unicode as a character, false for
 /// any code point defined as a non-character, as reserved, as a surrogate code
 /// point, or not defined at all.
-LLVM_ABI bool isCharacter(int UCS);
+LLVM_ABI inline bool isCharacter(int UCS) {
+  return charProperties(UCS).isCharacter();
+}
 
 /// Determines if a character is likely to be displayed correctly on the
 /// terminal. Exact implementation would have to depend on the specific
 /// terminal, so we define the semantic that should be suitable for generic case
 /// of a terminal capable to output Unicode characters.
 ///
-/// Printable codepoints are those in the categories L, M, N, P, S and Zs
+/// Printable codepoints are those in the categories L, M, N, P, S and Zs. In
+/// addition, U+00AD SOFT HYPHEN is also considered printable, as it's actually
+/// displayed on most terminals.
+///
 /// \return true if the character is considered printable.
-LLVM_ABI bool isPrintable(int UCS);
+LLVM_ABI inline bool isPrintable(int UCS) {
+  return charProperties(UCS).isPrintable(UCS);
+}
 
 // Control codepoints are codepoints in the Cc category.
-LLVM_ABI bool isControl(int UCS);
+LLVM_ABI inline bool isControl(int UCS) {
+  return charProperties(UCS).isControl();
+}
 
 // Formatting codepoints are codepoints in the Cf category.
-LLVM_ABI bool isFormatting(int UCS);
+LLVM_ABI inline bool isFormatting(int UCS) {
+  return charProperties(UCS).isFormatting();
+}
 
 /// Gets the number of positions the UTF8-encoded \p Text is likely to occupy
 /// when output on a terminal ("character width"). This depends on the
diff --git a/llvm/lib/Support/Unicode.cpp b/llvm/lib/Support/Unicode.cpp
index b91e1724424e8e..bc4a64a26b1ef2 100644
--- a/llvm/lib/Support/Unicode.cpp
+++ b/llvm/lib/Support/Unicode.cpp
@@ -12,53 +12,25 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Unicode.h"
+#include "UnicodeCharSetsGenerated.h"
 #include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/UnicodeCharRanges.h"
 
 namespace llvm {
 namespace sys {
 namespace unicode {
 
-extern const UnicodeCharSet::CharRanges GeneratedCharacterRanges;
-extern const UnicodeCharSet::CharRanges GeneratedPrintableRanges;
-extern const UnicodeCharSet::CharRanges GeneratedControlCharacterRanges;
-extern const UnicodeCharSet::CharRanges GeneratedFormatCharacterRanges;
-extern const UnicodeCharSet::CharRanges GeneratedCombiningCharacterRanges;
-extern const UnicodeCharSet::CharRanges GeneratedDoubleWidthCharacterRanges;
-
-/// Unicode code points that are considered characters. This function
-/// returns true for any code point defined by Unicode as a character, false for
-/// any code point defined as a non-character, as reserved, as a surrogate code
-/// point, or not defined at all.
-bool isCharacter(int UCS) {
-  static const UnicodeCharSet Character(GeneratedCharacterRanges);
-  return Character.contains(UCS);
-}
-
-/// Unicode code points of the categories L, M, N, P, S and Zs are considered
-/// printable.
-/// In addition, U+00AD SOFT HYPHEN is also considered printable, as
-/// it's actually displayed on most terminals. \return true if the character is
-/// considered printable.
-bool isPrintable(int UCS) {
-  static const UnicodeCharSet Printables(GeneratedPrintableRanges);
-  // Clang special cases 0x00AD (SOFT HYPHEN) which is rendered as an actual
-  // hyphen in most terminals.
-  return UCS == 0x00AD || Printables.contains(UCS);
-}
-
-/// Unicode code points of the Cc category are considered
-/// control characters.
-bool isControl(int UCS) {
-  static const UnicodeCharSet Control(GeneratedControlCharacterRanges);
-  return Control.contains(UCS);
-}
-
-/// Unicode code points of the Cf category are considered
-/// formatting characters.
-bool isFormatting(int UCS) {
-  static const UnicodeCharSet Format(GeneratedFormatCharacterRanges);
-  return Format.contains(UCS);
+const CharProperties &charProperties(int UCS) {
+  // We know 0x10FFFF is a non-character and treat any out-of-range code point
+  // the same.
+  UCS = std::min<unsigned>(UCS, 0x10FFFF);
+
+  namespace T = CharPropertyTables;
+  auto A = T::Lookup1[UCS >> 12];
+  auto B = T::Lookup2[A][(UCS >> 10) & 0x3];
+  auto C = T::Lookup3[B][(UCS >> 8) & 0xf];
+  auto D = T::Lookup4[C][(UCS >> 4) & 0xf];
+  auto E = T::Lookup5[D][UCS & 0xf];
+  return T::Lookup6[E];
 }
 
 /// Gets the number of positions a character is likely to occupy when output
@@ -76,17 +48,13 @@ static inline int charWidth(int UCS) {
   if (!isPrintable(UCS))
     return ErrorNonPrintableCharacter;
 
-  static const UnicodeCharSet CombiningCharacters(
-      GeneratedCombiningCharacterRanges);
-
-  if (CombiningCharacters.contains(UCS))
+  const CharProperties &P = charProperties(UCS);
+  if (P.isCombining())
     return 0;
 
-  static const UnicodeCharSet DoubleWidthCharacters(
-      GeneratedDoubleWidthCharacterRanges);
-
-  if (DoubleWidthCharacters.contains(UCS))
+  if (P.isDoubleWidth())
     return 2;
+
   return 1;
 }
 
diff --git a/llvm/lib/Support/UnicodeCharSetsGenerated.cpp b/llvm/lib/Support/UnicodeCharSetsGenerated.cpp
index cba25f21eacb93..3049bf0feea265 100644
--- a/llvm/lib/Support/UnicodeCharSetsGenerated.cpp
+++ b/llvm/lib/Support/UnicodeCharSetsGenerated.cpp
@@ -6,715 +6,1019 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file was generated by llvm/utils/UnicodeData/UnicodeCharSetsGenerator
-// from the Unicode 18.0 Character Database. Do not edit manually.
+// This file was generated by llvm/utils/gen_unicode_charsetdata.py
+// from the Unicode 18.0.0 Character Database. Do not edit manually.
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Support/UnicodeCharRanges.h"
+#include "UnicodeCharSetsGenerated.h"
+#include "llvm/Support/Unicode.h"
 
-using llvm::sys::UnicodeCharRange;
-using CharRanges = llvm::sys::UnicodeCharSet::CharRanges;
+namespace llvm::sys::unicode::CharPropertyTables {
 
-namespace llvm::sys::unicode {
+extern const std::uint8_t Lookup1[272] = {
+    0,  1,  2,  3,  4,  5,  5,  5,  5,  5,  6,  5,  5,  7,  8,  9,  10, 11, 12,
+    13, 14, 15, 16, 5,  17, 18, 19, 20, 21, 22, 23, 24, 5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  25, 26, 27, 5,  28, 29, 5,  30, 5,  31, 32, 32, 32, 32, 32,
+    32, 32, 32, 32, 5,  5,  33, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 34, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 8,  8,  8,  8,  8,  8,  8,
+    8,  8,  8,  8,  8,  8,  8,  8,  35, 8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+    8,  8,  8,  8,  8,  35};
 
-// Characters
-static constexpr UnicodeCharRange GeneratedCharacterRangesData[] = {
-    {0x0000, 0x0377},   {0x037A, 0x037F},   {0x0384, 0x038A},
-    {0x038C, 0x038C},   {0x038E, 0x03A1},   {0x03A3, 0x052F},
-    {0x0531, 0x0556},   {0x0558, 0x058F},   {0x0591, 0x05C9},
-    {0x05D0, 0x05EA},   {0x05EF, 0x05F4},   {0x0600, 0x070D},
-    {0x070F, 0x074A},   {0x074D, 0x07B1},   {0x07C0, 0x07FA},
-    {0x07FD, 0x082D},   {0x0830, 0x083E},   {0x0840, 0x085B},
-    {0x085E, 0x085E},   {0x0860, 0x086A},   {0x0870, 0x0891},
-    {0x0897, 0x0983},   {0x0985, 0x098C},   {0x098F, 0x0990},
-    {0x0993, 0x09A8},   {0x09AA, 0x09B0},   {0x09B2, 0x09B2},
-    {0x09B6, 0x09B9},   {0x09BC, 0x09C4},   {0x09C7, 0x09C8},
-    {0x09CB, 0x09CE},   {0x09D7, 0x09D7},   {0x09DC, 0x09DD},
-    {0x09DF, 0x09E3},   {0x09E6, 0x09FE},   {0x0A01, 0x0A03},
-    {0x0A05, 0x0A0A},   {0x0A0F, 0x0A10},   {0x0A13, 0x0A28},
-    {0x0A2A, 0x0A30},   {0x0A32, 0x0A33},   {0x0A35, 0x0A36},
-    {0x0A38, 0x0A39},   {0x0A3C, 0x0A3C},   {0x0A3E, 0x0A42},
-    {0x0A47, 0x0A48},   {0x0A4B, 0x0A4D},   {0x0A51, 0x0A51},
-    {0x0A59, 0x0A5C},   {0x0A5E, 0x0A5E},   {0x0A66, 0x0A76},
-    {0x0A81, 0x0A83},   {0x0A85, 0x0A8D},   {0x0A8F, 0x0A91},
-    {0x0A93, 0x0AA8},   {0x0AAA, 0x0AB0},   {0x0AB2, 0x0AB3},
-    {0x0AB5, 0x0AB9},   {0x0ABC, 0x0AC5},   {0x0AC7, 0x0AC9},
-    {0x0ACB, 0x0ACD},   {0x0AD0, 0x0AD0},   {0x0AE0, 0x0AE3},
-    {0x0AE6, 0x0AF1},   {0x0AF9, 0x0AFF},   {0x0B01, 0x0B03},
-    {0x0B05, 0x0B0C},   {0x0B0F, 0x0B10},   {0x0B13, 0x0B28},
-    {0x0B2A, 0x0B30},   {0x0B32, 0x0B33},   {0x0B35, 0x0B39},
-    {0x0B3C, 0x0B44},   {0x0B47, 0x0B48},   {0x0B4B, 0x0B4D},
-    {0x0B53, 0x0B57},   {0x0B5C, 0x0B5D},   {0x0B5F, 0x0B63},
-    {0x0B66, 0x0B77},   {0x0B82, 0x0B83},   {0x0B85, 0x0B8A},
-    {0x0B8E, 0x0B90},   {0x0B92, 0x0B95},   {0x0B99, 0x0B9A},
-    {0x0B9C, 0x0B9C},   {0x0B9E, 0x0B9F},   {0x0BA3, 0x0BA4},
-    {0x0BA8, 0x0BAA},   {0x0BAE, 0x0BB9},   {0x0BBE, 0x0BC2},
-    {0x0BC6, 0x0BC8},   {0x0BCA, 0x0BCD},   {0x0BD0, 0x0BD0},
-    {0x0BD7, 0x0BD7},   {0x0BE6, 0x0BFA},   {0x0C00, 0x0C0C},
-    {0x0C0E, 0x0C10},   {0x0C12, 0x0C28},   {0x0C2A, 0x0C39},
-    {0x0C3C, 0x0C44},   {0x0C46, 0x0C48},   {0x0C4A, 0x0C4D},
-    {0x0C55, 0x0C56},   {0x0C58, 0x0C5A},   {0x0C5C, 0x0C5D},
-    {0x0C60, 0x0C63},   {0x0C66, 0x0C6F},   {0x0C77, 0x0C8C},
-    {0x0C8E, 0x0C90},   {0x0C92, 0x0CA8},   {0x0CAA, 0x0CB3},
-    {0x0CB5, 0x0CB9},   {0x0CBC, 0x0CC4},   {0x0CC6, 0x0CC8},
-    {0x0CCA, 0x0CCD},   {0x0CD5, 0x0CD6},   {0x0CDC, 0x0CDE},
-    {0x0CE0, 0x0CE3},   {0x0CE6, 0x0CEF},   {0x0CF1, 0x0CF3},
-    {0x0D00, 0x0D0C},   {0x0D0E, 0x0D10},   {0x0D12, 0x0D44},
-    {0x0D46, 0x0D48},   {0x0D4A, 0x0D4F},   {0x0D54, 0x0D63},
-    {0x0D66, 0x0D7F},   {0x0D81, 0x0D83},   {0x0D85, 0x0D96},
-    {0x0D9A, 0x0DB1},   {0x0DB3, 0x0DBB},   {0x0DBD, 0x0DBD},
-    {0x0DC0, 0x0DC6},   {0x0DCA, 0x0DCA},   {0x0DCF, 0x0DD4},
-    {0x0DD6, 0x0DD6},   {0x0DD8, 0x0DDF},   {0x0DE6, 0x0DEF},
-    {0x0DF2, 0x0DF4},   {0x0E01, 0x0E3A},   {0x0E3F, 0x0E5B},
-    {0x0E81, 0x0E82},   {0x0E84, 0x0E84},   {0x0E86, 0x0E8A},
-    {0x0E8C, 0x0EA3},   {0x0EA5, 0x0EA5},   {0x0EA7, 0x0EBD},
-    {0x0EC0, 0x0EC4},   {0x0EC6, 0x0EC6},   {0x0EC8, 0x0ECE},
-    {0x0ED0, 0x0ED9},   {0x0EDC, 0x0EDF},   {0x0F00, 0x0F47},
-    {0x0F49, 0x0F6C},   {0x0F71, 0x0F97},   {0x0F99, 0x0FBC},
-    {0x0FBE, 0x0FCC},   {0x0FCE, 0x0FDA},   {0x1000, 0x10C5},
-    {0x10C7, 0x10C7},   {0x10CD, 0x10CD},   {0x10D0, 0x1248},
-    {0x124A, 0x124D},   {0x1250, 0x1256},   {0x1258, 0x1258},
-    {0x125A, 0x125D},   {0x1260, 0x1288},   {0x128A, 0x128D},
-    {0x1290, 0x12B0},   {0x12B2, 0x12B5},   {0x12B8, 0x12BE},
-    {0x12C0, 0x12C0},   {0x12C2, 0x12C5},   {0x12C8, 0x12D6},
-    {0x12D8, 0x1310},   {0x1312, 0x1315},   {0x1318, 0x135A},
-    {0x135D, 0x137C},   {0x1380, 0x1399},   {0x13A0, 0x13F5},
-    {0x13F8, 0x13FD},   {0x1400, 0x169C},   {0x16A0, 0x16F8},
-    {0x1700, 0x1715},   {0x171F, 0x1736},   {0x1740, 0x1753},
-    {0x1760, 0x176C},   {0x176E, 0x1770},   {0x1772, 0x1773},
-    {0x1780, 0x17DD},   {0x17E0, 0x17E9},   {0x17F0, 0x17F9},
-    {0x1800, 0x1819},   {0x1820, 0x1878},   {0x1880, 0x18AA},
-    {0x18B0, 0x18F5},   {0x1900, 0x191E},   {0x1920, 0x192B},
-    {0x1930, 0x193B},   {0x1940, 0x1940},   {0x1944, 0x196D},
-    {0x1970, 0x1974},   {0x1980, 0x19AB},   {0x19B0, 0x19C9},
-    {0x19D0, 0x19DA},   {0x19DE, 0x1A1B},   {0x1A1E, 0x1A5E},
-    {0x1A60, 0x1A7C},   {0x1A7F, 0x1A89},   {0x1A90, 0x1A99},
-    {0x1AA0, 0x1AAD},   {0x1AB0, 0x1AF0},   {0x1B00, 0x1B4C},
-    {0x1B4E, 0x1BF3},   {0x1BFC, 0x1C37},   {0x1C3B, 0x1C49},
-    {0x1C4D, 0x1C8A},   {0x1C90, 0x1CBA},   {0x1CBD, 0x1CC7},
-    {0x1CD0, 0x1CFA},   {0x1D00, 0x1F15},   {0x1F18, 0x1F1D},
-    {0x1F20, 0x1F45},   {0x1F48, 0x1F4D},   {0x1F50, 0x1F57},
-    {0x1F59, 0x1F59},   {0x1F5B, 0x1F5B},   {0x1F5D, 0x1F5D},
-    {0x1F5F, 0x1F7D},   {0x1F80, 0x1FB4},   {0x1FB6, 0x1FC4},
-    {0x1FC6, 0x1FD3},   {0x1FD6, 0x1FDB},   {0x1FDD, 0x1FEF},
-    {0x1FF2, 0x1FF4},   {0x1FF6, 0x1FFE},   {0x2000, 0x2064},
-    {0x2066, 0x2071},   {0x2074, 0x20C4},   {0x20D0, 0x20F0},
-    {0x2100, 0x218B},   {0x2190, 0x2429},   {0x2440, 0x244A},
-    {0x2460, 0x2B73},   {0x2B76, 0x2CF3},   {0x2CF9, 0x2D25},
-    {0x2D27, 0x2D27},   {0x2D2D, 0x2D2D},   {0x2D30, 0x2D67},
-    {0x2D6F, 0x2D70},   {0x2D7F, 0x2D96},   {0x2DA0, 0x2DA6},
-    {0x2DA8, 0x2DAE},   {0x2DB0, 0x2DB6},   {0x2DB8, 0x2DBE},
-    {0x2DC0, 0x2DC6},   {0x2DC8, 0x2DCE},   {0x2DD0, 0x2DD6},
-    {0x2DD8, 0x2DDE},   {0x2DE0, 0x2E5D},   {0x2E60, 0x2E63},
-    {0x2E80, 0x2E99},   {0x2E9B, 0x2EF3},   {0x2F00, 0x2FD5},
-    {0x2FF0, 0x303F},   {0x3041, 0x3096},   {0x3099, 0x30FF},
-    {0x3105, 0x312F},   {0x3131, 0x318E},   {0x3190, 0x31E5},
-    {0x31EF, 0x321E},   {0x3220, 0xA48C},   {0xA490, 0xA4C6},
-    {0xA4D0, 0xA62B},   {0xA640, 0xA6F7},   {0xA700, 0xA7DD},
-    {0xA7E2, 0xA7E2},   {0xA7F1, 0xA82C},   {0xA830, 0xA839},
-    {0xA840, 0xA877},   {0xA880, 0xA8C5},   {0xA8CE, 0xA8D9},
-    {0xA8E0, 0xA953},   {0xA95F, 0xA97C},   {0xA980, 0xA9CD},
-    {0xA9CF, 0xA9D9},   {0xA9DE, 0xA9FE},   {0xAA00, 0xAA36},
-    {0xAA40, 0xAA4D},   {0xAA50, 0xAA59},   {0xAA5C, 0xAAC2},
-    {0xAADB, 0xAAF6},   {0xAB01, 0xAB06},   {0xAB09, 0xAB0E},
-    {0xAB11, 0xAB16},   {0xAB20, 0xAB26},   {0xAB28, 0xAB2E},
-    {0xAB30, 0xAB6D},   {0xAB70, 0xABED},   {0xABF0, 0xABF9},
-    {0xAC00, 0xD7A3},   {0xD7B0, 0xD7C6},   {0xD7CB, 0xD7FB},
-    {0xE000, 0xFA6D},   {0xFA70, 0xFAD9},   {0xFB00, 0xFB06},
-    {0xFB13, 0xFB17},   {0xFB1D, 0xFB36},   {0xFB38, 0xFB3C},
-    {0xFB3E, 0xFB3E},   {0xFB40, 0xFB41},   {0xFB43, 0xFB44},
-    {0xFB46, 0xFDCF},   {0xFDF0, 0xFE19},   {0xFE20, 0xFE52},
-    {0xFE54, 0xFE66},   {0xFE68, 0xFE6B},   {0xFE70, 0xFE74},
-    {0xFE76, 0xFEFC},   {0xFEFF, 0xFEFF},   {0xFF01, 0xFFBE},
-    {0xFFC2, 0xFFC7},   {0xFFCA, 0xFFCF},   {0xFFD2, 0xFFD7},
-    {0xFFDA, 0xFFDC},   {0xFFE0, 0xFFE6},   {0xFFE8, 0xFFEE},
-    {0xFFF9, 0xFFFD},   {0x10000, 0x1000B}, {0x1000D, 0x10026},
-    {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D},
-    {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10100, 0x10102},
-    {0x10107, 0x10133}, {0x10137, 0x1018E}, {0x10190, 0x1019C},
-    {0x101A0, 0x101A0}, {0x101D0, 0x101FD}, {0x10280, 0x1029C},
-    {0x102A0, 0x102D0}, {0x102E0, 0x102FB}, {0x10300, 0x10323},
-    {0x1032D, 0x1034A}, {0x10350, 0x1037A}, {0x10380, 0x1039D},
-    {0x1039F, 0x103C3}, {0x103C8, 0x103D5}, {0x10400, 0x1049D},
-    {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB},
-    {0x10500, 0x10527}, {0x10530, 0x10563}, {0x1056F, 0x1057A},
-    {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595},
-    {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9},
-    {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736},
-    {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785},
-    {0x10787, 0x107B0}, {0x107B2, 0x107BF}, {0x10800, 0x10805},
-    {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838},
-    {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10857, 0x1089E},
-    {0x108A7, 0x108AF}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5},
-    {0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x1093F, 0x10959},
-    {0x10980, 0x109B7}, {0x109BC, 0x109CF}, {0x109D2, 0x10A03},
-    {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17},
-    {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48},
-    {0x10A50, 0x10A58}, {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6},
-    {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, {0x10B39, 0x10B55},
-    {0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C},
-    {0x10BA9, 0x10BAF}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2},
-    {0x10CC0, 0x10CF2}, {0x10CFA, 0x10D27}, {0x10D30, 0x10D39},
-    {0x10D40, 0x10D65}, {0x10D69, 0x10D85}, {0x10D8E, 0x10D8F},
-    {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD},
-    {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10EC9, 0x10EEE},
-    {0x10EF0, 0x10F27}, {0x10F30, 0x10F59}, {0x10F70, 0x10F89},
-    {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6}, {0x11000, 0x1104D},
-    {0x11052, 0x11075}, {0x1107F, 0x110C2}, {0x110CD, 0x110CD},
-    {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11134},
-    {0x11136, 0x11147}, {0x11150, 0x11176}, {0x11180, 0x111DF},
-    {0x111E1, 0x111F4}, {0x11200, 0x11211}, {0x11213, 0x11241},
-    {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D},
-    {0x1128F, 0x1129D}, {0x1129F, 0x112A9}, {0x112B0, 0x112EA},
-    {0x112F0, 0x112F9}, {0x11300, 0x11303}, {0x11305, 0x1130C},
-    {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330},
-    {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133B, 0x11344},
-    {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350},
-    {0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11366, 0x1136C},
-    {0x11370, 0x11374}, {0x11380, 0x11389}, {0x1138B, 0x1138B},
-    {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113C0},
-    {0x113C2, 0x113C2}, {0x113C5, 0x113C5}, {0x113C7, 0x113CA},
-    {0x113CC, 0x113D5}, {0x113D7, 0x113D8}, {0x113E1, 0x113E2},
-    {0x11400, 0x1145B}, {0x1145D, 0x11461}, {0x11480, 0x114C7},
-    {0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD},
-    {0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C},
-    {0x11680, 0x116B9}, {0x116C0, 0x116C9}, {0x116D0, 0x116E3},
-    {0x11700, 0x1171A}, {0x1171D, 0x1172B}, {0x11730, 0x11746},
-    {0x11800, 0x1183B}, {0x118A0, 0x118F2}, {0x118FF, 0x11906},
-    {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916},
-    {0x11918, 0x11935}, {0x11937, 0x11938}, {0x1193B, 0x11946},
-    {0x11950, 0x11959}, {0x119A0, 0x119A7}, {0x119AA, 0x119D7},
-    {0x119DA, 0x119E4}, {0x11A00, 0x11A47}, {0x11A50, 0x11AA2},
-    {0x11AB0, 0x11AF8}, {0x11B00, 0x11B0A}, {0x11B60, 0x11B67},
-    {0x11BC0, 0x11BE1}, {0x11BF0, 0x11BF9}, {0x11C00, 0x11C08},
-    {0x11C0A, 0x11C36}, {0x11C38, 0x11C45}, {0x11C50, 0x11C6C},
-    {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6},
-    {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D36},
-    {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D47},
-    {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68},
-    {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, {0x11D93, 0x11D98},
-    {0x11DA0, 0x11DA9}, {0x11DB0, 0x11DDB}, {0x11DE0, 0x11DE9},
-    {0x11DF0, 0x11DF1}, {0x11EE0, 0x11EF8}, {0x11F00, 0x11F10},
-    {0x11F12, 0x11F3A}, {0x11F3E, 0x11F5A}, {0x11FB0, 0x11FB0},
-    {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399}, {0x12400, 0x12543},
-    {0x12550, 0x12686}, {0x12F90, 0x12FF2}, {0x13000, 0x13455},
-    {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x16139},
-    {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69},
-    {0x16A6E, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED},
-    {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, {0x16B50, 0x16B59},
-    {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F},
-    {0x16D40, 0x16D79}, {0x16E40, 0x16E9A}, {0x16EA0, 0x16EB8},
-    {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87},
-    {0x16F8F, 0x16F9F}, {0x16FE0, 0x16FE4}, {0x16FF0, 0x16FF6},
-    {0x17000, 0x18CDA}, {0x18CFF, 0x18D20}, {0x18D80, 0x18DF2},
-    {0x18E00, 0x19191}, {0x191A0, 0x191D2}, {0x1AFF0, 0x1AFF3},
-    {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B128},
-    {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1B155, 0x1B155},
-    {0x1B164, 0x1B168}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A},
-    {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99},
-    {0x1BC9C, 0x1BCA3}, {0x1CC00, 0x1CCFC}, {0x1CD00, 0x1CEB3},
-    {0x1CEBA, 0x1CED0}, {0x1CED2, 0x1CED4}, {0x1CEDD, 0x1CEFD},
-    {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1CF50, 0x1CFC3},
-    {0x1D000, 0x1D0F5}, {0x1D100, 0x1D245}, {0x1D250, 0x1D281},
-    {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356},
-    {0x1D360, 0x1D378}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C},
-    {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6},
-    {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB},
-    {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A},
-    {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539},
-    {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546},
-    {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A6}, {0x1D6A8, 0x1D7CB},
-    {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF},
-    {0x1DB00, 0x1DB1C}, {0x1DF00, 0x1DF81}, {0x1DF90, 0x1DF96},
-    {0x1DFCD, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021},
-    {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D},
-    {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},
-    {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AE},
-    {0x1E2C0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4F9},
-    {0x1E5D0, 0x1E5FA}, {0x1E5FF, 0x1E5FF}, {0x1E6C0, 0x1E6DE},
-    {0x1E6E0, 0x1E6F5}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6},
-    {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE},
-    {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, {0x1E900, 0x1E94B},
-    {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, {0x1EC71, 0x1ECB4},
-    {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F},
-    {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27},
-    {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39},
-    {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47},
-    {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F},
-    {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57},
-    {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D},
-    {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64},
-    {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77},
-    {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89},
-    {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9},
-    {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F02B},
-    {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF},
-    {0x1F0C1, 0x1F0CF}, {0x1F0D1, 0x1F0F5}, {0x1F100, 0x1F1AE},
-    {0x1F1E6, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248},
-    {0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F6D9},
-    {0x1F6DC, 0x1F6EC}, {0x1F6F0, 0x1F6FC}, {0x1F700, 0x1F7DB},
-    {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F80B}, {0x1F810, 0x1F847},
-    {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD},
-    {0x1F8B0, 0x1F8BB}, {0x1F8C0, 0x1F8C1}, {0x1F8D0, 0x1F8D8},
-    {0x1F900, 0x1FA57}, {0x1FA60, 0x1FA6D}, {0x1FA70, 0x1FA7C},
-    {0x1FA80, 0x1FAC6}, {0x1FAC8, 0x1FAC8}, {0x1FACC, 0x1FADD},
-    {0x1FADF, 0x1FAEB}, {0x1FAEF, 0x1FAFA}, {0x1FB00, 0x1FB92},
-    {0x1FB94, 0x1FBFA}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81E},
-    {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D},
-    {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479},
-    {0x3D000, 0x3FC3F}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F},
-    {0xE0100, 0xE01EF}, {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},
-};
-extern const CharRanges GeneratedCharacterRanges = GeneratedCharacterRangesData;
+extern const std::uint8_t Lookup2[36][16] = {
+    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+    {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
+    {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47},
+    {48, 49, 50, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52},
+    {52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 52, 52},
+    {52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52},
+    {54, 52, 52, 52, 55, 21, 56, 57, 58, 59, 60, 61, 52, 52, 52, 52},
+    {52, 52, 52, 52, 52, 52, 52, 62, 63, 63, 63, 63, 63, 63, 63, 63},
+    {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
+    {64, 64, 64, 64, 64, 64, 64, 64, 64, 52, 65, 66, 67, 68, 69, 70},
+    {71, 72, 73, 74, 75, 76, 21, 77, 78, 79, 80, 81, 82, 83, 84, 85},
+    {86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101},
+    {21, 21, 21, 102, 103, 104, 105, 106, 106, 106, 106, 106, 106, 106, 106,
+     107},
+    {21, 21, 21, 21, 108, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21},
+    {21, 21, 21, 109, 21, 21, 110, 106, 106, 106, 106, 106, 106, 106, 106, 106},
+    {106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+     106},
+    {106, 111, 106, 106, 106, 106, 106, 106, 21, 21, 112, 113, 106, 114, 115,
+     116},
+    {52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 117, 118, 52, 52},
+    {52, 119, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+     106},
+    {106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+     120},
+    {52, 121, 122, 106, 106, 106, 106, 106, 106, 106, 106, 106, 123, 106, 106,
+     106},
+    {106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 124, 40, 125,
+     126},
+    {127, 128, 129, 130, 131, 132, 133, 134, 40, 40, 135, 136, 106, 106, 106,
+     137},
+    {138, 139, 140, 106, 141, 142, 143, 144, 145, 146, 106, 106, 147, 148, 149,
+     106},
+    {150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 106, 106, 106,
+     106},
+    {52, 52, 52, 52, 52, 52, 162, 52, 52, 52, 52, 52, 52, 52, 52, 52},
+    {52, 52, 52, 52, 52, 52, 52, 52, 163, 52, 52, 52, 52, 52, 52, 52},
+    {52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 164, 52},
+    {52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 165, 52, 52, 166, 167},
+    {167, 167, 167, 167, 167, 167, 167, 167, 52, 52, 168, 167, 167, 167, 167,
+     169},
+    {52, 52, 52, 170, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52},
+    {52, 52, 52, 52, 171, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
+     167},
+    {167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
+     167},
+    {52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 172, 167, 167, 169},
+    {173, 174, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+     106},
+    {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 175}};
 
-// General_Category=L|M|N|P|S|Zs
-static constexpr UnicodeCharRange GeneratedPrintableRangesData[] = {
-    {0x0020, 0x007E},   {0x00A0, 0x00AC},   {0x00AE, 0x0377},
-    {0x037A, 0x037F},   {0x0384, 0x038A},   {0x038C, 0x038C},
-    {0x038E, 0x03A1},   {0x03A3, 0x052F},   {0x0531, 0x0556},
-    {0x0558, 0x058F},   {0x0591, 0x05C9},   {0x05D0, 0x05EA},
-    {0x05EF, 0x05F4},   {0x0606, 0x061B},   {0x061D, 0x06DC},
-    {0x06DE, 0x070D},   {0x0710, 0x074A},   {0x074D, 0x07B1},
-    {0x07C0, 0x07FA},   {0x07FD, 0x082D},   {0x0830, 0x083E},
-    {0x0840, 0x085B},   {0x085E, 0x085E},   {0x0860, 0x086A},
-    {0x0870, 0x088F},   {0x0897, 0x08E1},   {0x08E3, 0x0983},
-    {0x0985, 0x098C},   {0x098F, 0x0990},   {0x0993, 0x09A8},
-    {0x09AA, 0x09B0},   {0x09B2, 0x09B2},   {0x09B6, 0x09B9},
-    {0x09BC, 0x09C4},   {0x09C7, 0x09C8},   {0x09CB, 0x09CE},
-    {0x09D7, 0x09D7},   {0x09DC, 0x09DD},   {0x09DF, 0x09E3},
-    {0x09E6, 0x09FE},   {0x0A01, 0x0A03},   {0x0A05, 0x0A0A},
-    {0x0A0F, 0x0A10},   {0x0A13, 0x0A28},   {0x0A2A, 0x0A30},
-    {0x0A32, 0x0A33},   {0x0A35, 0x0A36},   {0x0A38, 0x0A39},
-    {0x0A3C, 0x0A3C},   {0x0A3E, 0x0A42},   {0x0A47, 0x0A48},
-    {0x0A4B, 0x0A4D},   {0x0A51, 0x0A51},   {0x0A59, 0x0A5C},
-    {0x0A5E, 0x0A5E},   {0x0A66, 0x0A76},   {0x0A81, 0x0A83},
-    {0x0A85, 0x0A8D},   {0x0A8F, 0x0A91},   {0x0A93, 0x0AA8},
-    {0x0AAA, 0x0AB0},   {0x0AB2, 0x0AB3},   {0x0AB5, 0x0AB9},
-    {0x0ABC, 0x0AC5},   {0x0AC7, 0x0AC9},   {0x0ACB, 0x0ACD},
-    {0x0AD0, 0x0AD0},   {0x0AE0, 0x0AE3},   {0x0AE6, 0x0AF1},
-    {0x0AF9, 0x0AFF},   {0x0B01, 0x0B03},   {0x0B05, 0x0B0C},
-    {0x0B0F, 0x0B10},   {0x0B13, 0x0B28},   {0x0B2A, 0x0B30},
-    {0x0B32, 0x0B33},   {0x0B35, 0x0B39},   {0x0B3C, 0x0B44},
-    {0x0B47, 0x0B48},   {0x0B4B, 0x0B4D},   {0x0B53, 0x0B57},
-    {0x0B5C, 0x0B5D},   {0x0B5F, 0x0B63},   {0x0B66, 0x0B77},
-    {0x0B82, 0x0B83},   {0x0B85, 0x0B8A},   {0x0B8E, 0x0B90},
-    {0x0B92, 0x0B95},   {0x0B99, 0x0B9A},   {0x0B9C, 0x0B9C},
-    {0x0B9E, 0x0B9F},   {0x0BA3, 0x0BA4},   {0x0BA8, 0x0BAA},
-    {0x0BAE, 0x0BB9},   {0x0BBE, 0x0BC2},   {0x0BC6, 0x0BC8},
-    {0x0BCA, 0x0BCD},   {0x0BD0, 0x0BD0},   {0x0BD7, 0x0BD7},
-    {0x0BE6, 0x0BFA},   {0x0C00, 0x0C0C},   {0x0C0E, 0x0C10},
-    {0x0C12, 0x0C28},   {0x0C2A, 0x0C39},   {0x0C3C, 0x0C44},
-    {0x0C46, 0x0C48},   {0x0C4A, 0x0C4D},   {0x0C55, 0x0C56},
-    {0x0C58, 0x0C5A},   {0x0C5C, 0x0C5D},   {0x0C60, 0x0C63},
-    {0x0C66, 0x0C6F},   {0x0C77, 0x0C8C},   {0x0C8E, 0x0C90},
-    {0x0C92, 0x0CA8},   {0x0CAA, 0x0CB3},   {0x0CB5, 0x0CB9},
-    {0x0CBC, 0x0CC4},   {0x0CC6, 0x0CC8},   {0x0CCA, 0x0CCD},
-    {0x0CD5, 0x0CD6},   {0x0CDC, 0x0CDE},   {0x0CE0, 0x0CE3},
-    {0x0CE6, 0x0CEF},   {0x0CF1, 0x0CF3},   {0x0D00, 0x0D0C},
-    {0x0D0E, 0x0D10},   {0x0D12, 0x0D44},   {0x0D46, 0x0D48},
-    {0x0D4A, 0x0D4F},   {0x0D54, 0x0D63},   {0x0D66, 0x0D7F},
-    {0x0D81, 0x0D83},   {0x0D85, 0x0D96},   {0x0D9A, 0x0DB1},
-    {0x0DB3, 0x0DBB},   {0x0DBD, 0x0DBD},   {0x0DC0, 0x0DC6},
-    {0x0DCA, 0x0DCA},   {0x0DCF, 0x0DD4},   {0x0DD6, 0x0DD6},
-    {0x0DD8, 0x0DDF},   {0x0DE6, 0x0DEF},   {0x0DF2, 0x0DF4},
-    {0x0E01, 0x0E3A},   {0x0E3F, 0x0E5B},   {0x0E81, 0x0E82},
-    {0x0E84, 0x0E84},   {0x0E86, 0x0E8A},   {0x0E8C, 0x0EA3},
-    {0x0EA5, 0x0EA5},   {0x0EA7, 0x0EBD},   {0x0EC0, 0x0EC4},
-    {0x0EC6, 0x0EC6},   {0x0EC8, 0x0ECE},   {0x0ED0, 0x0ED9},
-    {0x0EDC, 0x0EDF},   {0x0F00, 0x0F47},   {0x0F49, 0x0F6C},
-    {0x0F71, 0x0F97},   {0x0F99, 0x0FBC},   {0x0FBE, 0x0FCC},
-    {0x0FCE, 0x0FDA},   {0x1000, 0x10C5},   {0x10C7, 0x10C7},
-    {0x10CD, 0x10CD},   {0x10D0, 0x1248},   {0x124A, 0x124D},
-    {0x1250, 0x1256},   {0x1258, 0x1258},   {0x125A, 0x125D},
-    {0x1260, 0x1288},   {0x128A, 0x128D},   {0x1290, 0x12B0},
-    {0x12B2, 0x12B5},   {0x12B8, 0x12BE},   {0x12C0, 0x12C0},
-    {0x12C2, 0x12C5},   {0x12C8, 0x12D6},   {0x12D8, 0x1310},
-    {0x1312, 0x1315},   {0x1318, 0x135A},   {0x135D, 0x137C},
-    {0x1380, 0x1399},   {0x13A0, 0x13F5},   {0x13F8, 0x13FD},
-    {0x1400, 0x169C},   {0x16A0, 0x16F8},   {0x1700, 0x1715},
-    {0x171F, 0x1736},   {0x1740, 0x1753},   {0x1760, 0x176C},
-    {0x176E, 0x1770},   {0x1772, 0x1773},   {0x1780, 0x17DD},
-    {0x17E0, 0x17E9},   {0x17F0, 0x17F9},   {0x1800, 0x180D},
-    {0x180F, 0x1819},   {0x1820, 0x1878},   {0x1880, 0x18AA},
-    {0x18B0, 0x18F5},   {0x1900, 0x191E},   {0x1920, 0x192B},
-    {0x1930, 0x193B},   {0x1940, 0x1940},   {0x1944, 0x196D},
-    {0x1970, 0x1974},   {0x1980, 0x19AB},   {0x19B0, 0x19C9},
-    {0x19D0, 0x19DA},   {0x19DE, 0x1A1B},   {0x1A1E, 0x1A5E},
-    {0x1A60, 0x1A7C},   {0x1A7F, 0x1A89},   {0x1A90, 0x1A99},
-    {0x1AA0, 0x1AAD},   {0x1AB0, 0x1AF0},   {0x1B00, 0x1B4C},
-    {0x1B4E, 0x1BF3},   {0x1BFC, 0x1C37},   {0x1C3B, 0x1C49},
-    {0x1C4D, 0x1C8A},   {0x1C90, 0x1CBA},   {0x1CBD, 0x1CC7},
-    {0x1CD0, 0x1CFA},   {0x1D00, 0x1F15},   {0x1F18, 0x1F1D},
-    {0x1F20, 0x1F45},   {0x1F48, 0x1F4D},   {0x1F50, 0x1F57},
-    {0x1F59, 0x1F59},   {0x1F5B, 0x1F5B},   {0x1F5D, 0x1F5D},
-    {0x1F5F, 0x1F7D},   {0x1F80, 0x1FB4},   {0x1FB6, 0x1FC4},
-    {0x1FC6, 0x1FD3},   {0x1FD6, 0x1FDB},   {0x1FDD, 0x1FEF},
-    {0x1FF2, 0x1FF4},   {0x1FF6, 0x1FFE},   {0x2000, 0x200A},
-    {0x2010, 0x2027},   {0x202F, 0x205F},   {0x2070, 0x2071},
-    {0x2074, 0x20C4},   {0x20D0, 0x20F0},   {0x2100, 0x218B},
-    {0x2190, 0x2429},   {0x2440, 0x244A},   {0x2460, 0x2B73},
-    {0x2B76, 0x2CF3},   {0x2CF9, 0x2D25},   {0x2D27, 0x2D27},
-    {0x2D2D, 0x2D2D},   {0x2D30, 0x2D67},   {0x2D6F, 0x2D70},
-    {0x2D7F, 0x2D96},   {0x2DA0, 0x2DA6},   {0x2DA8, 0x2DAE},
-    {0x2DB0, 0x2DB6},   {0x2DB8, 0x2DBE},   {0x2DC0, 0x2DC6},
-    {0x2DC8, 0x2DCE},   {0x2DD0, 0x2DD6},   {0x2DD8, 0x2DDE},
-    {0x2DE0, 0x2E5D},   {0x2E60, 0x2E63},   {0x2E80, 0x2E99},
-    {0x2E9B, 0x2EF3},   {0x2F00, 0x2FD5},   {0x2FF0, 0x303F},
-    {0x3041, 0x3096},   {0x3099, 0x30FF},   {0x3105, 0x312F},
-    {0x3131, 0x318E},   {0x3190, 0x31E5},   {0x31EF, 0x321E},
-    {0x3220, 0xA48C},   {0xA490, 0xA4C6},   {0xA4D0, 0xA62B},
-    {0xA640, 0xA6F7},   {0xA700, 0xA7DD},   {0xA7E2, 0xA7E2},
-    {0xA7F1, 0xA82C},   {0xA830, 0xA839},   {0xA840, 0xA877},
-    {0xA880, 0xA8C5},   {0xA8CE, 0xA8D9},   {0xA8E0, 0xA953},
-    {0xA95F, 0xA97C},   {0xA980, 0xA9CD},   {0xA9CF, 0xA9D9},
-    {0xA9DE, 0xA9FE},   {0xAA00, 0xAA36},   {0xAA40, 0xAA4D},
-    {0xAA50, 0xAA59},   {0xAA5C, 0xAAC2},   {0xAADB, 0xAAF6},
-    {0xAB01, 0xAB06},   {0xAB09, 0xAB0E},   {0xAB11, 0xAB16},
-    {0xAB20, 0xAB26},   {0xAB28, 0xAB2E},   {0xAB30, 0xAB6D},
-    {0xAB70, 0xABED},   {0xABF0, 0xABF9},   {0xAC00, 0xD7A3},
-    {0xD7B0, 0xD7C6},   {0xD7CB, 0xD7FB},   {0xF900, 0xFA6D},
-    {0xFA70, 0xFAD9},   {0xFB00, 0xFB06},   {0xFB13, 0xFB17},
-    {0xFB1D, 0xFB36},   {0xFB38, 0xFB3C},   {0xFB3E, 0xFB3E},
-    {0xFB40, 0xFB41},   {0xFB43, 0xFB44},   {0xFB46, 0xFDCF},
-    {0xFDF0, 0xFE19},   {0xFE20, 0xFE52},   {0xFE54, 0xFE66},
-    {0xFE68, 0xFE6B},   {0xFE70, 0xFE74},   {0xFE76, 0xFEFC},
-    {0xFF01, 0xFFBE},   {0xFFC2, 0xFFC7},   {0xFFCA, 0xFFCF},
-    {0xFFD2, 0xFFD7},   {0xFFDA, 0xFFDC},   {0xFFE0, 0xFFE6},
-    {0xFFE8, 0xFFEE},   {0xFFFC, 0xFFFD},   {0x10000, 0x1000B},
-    {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},
-    {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA},
-    {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E},
-    {0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD},
-    {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB},
-    {0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A},
-    {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},
-    {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
-    {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
-    {0x1056F, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592},
-    {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1},
-    {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x105C0, 0x105F3},
-    {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767},
-    {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BF},
-    {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835},
-    {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x10855},
-    {0x10857, 0x1089E}, {0x108A7, 0x108AF}, {0x108E0, 0x108F2},
-    {0x108F4, 0x108F5}, {0x108FB, 0x1091B}, {0x1091F, 0x10939},
-    {0x1093F, 0x10959}, {0x10980, 0x109B7}, {0x109BC, 0x109CF},
-    {0x109D2, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A13},
-    {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A38, 0x10A3A},
-    {0x10A3F, 0x10A48}, {0x10A50, 0x10A58}, {0x10A60, 0x10A9F},
-    {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35},
-    {0x10B39, 0x10B55}, {0x10B58, 0x10B72}, {0x10B78, 0x10B91},
-    {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, {0x10C00, 0x10C48},
-    {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10CFA, 0x10D27},
-    {0x10D30, 0x10D39}, {0x10D40, 0x10D65}, {0x10D69, 0x10D85},
-    {0x10D8E, 0x10D8F}, {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9},
-    {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7},
-    {0x10EC9, 0x10EEE}, {0x10EF0, 0x10F27}, {0x10F30, 0x10F59},
-    {0x10F70, 0x10F89}, {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6},
-    {0x11000, 0x1104D}, {0x11052, 0x11075}, {0x1107F, 0x110BC},
-    {0x110BE, 0x110C2}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9},
-    {0x11100, 0x11134}, {0x11136, 0x11147}, {0x11150, 0x11176},
-    {0x11180, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211},
-    {0x11213, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288},
-    {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A9},
-    {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303},
-    {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328},
-    {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339},
-    {0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D},
-    {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363},
-    {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11380, 0x11389},
-    {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5},
-    {0x113B7, 0x113C0}, {0x113C2, 0x113C2}, {0x113C5, 0x113C5},
-    {0x113C7, 0x113CA}, {0x113CC, 0x113D5}, {0x113D7, 0x113D8},
-    {0x113E1, 0x113E2}, {0x11400, 0x1145B}, {0x1145D, 0x11461},
-    {0x11480, 0x114C7}, {0x114D0, 0x114D9}, {0x11580, 0x115B5},
-    {0x115B8, 0x115DD}, {0x11600, 0x11644}, {0x11650, 0x11659},
-    {0x11660, 0x1166C}, {0x11680, 0x116B9}, {0x116C0, 0x116C9},
-    {0x116D0, 0x116E3}, {0x11700, 0x1171A}, {0x1171D, 0x1172B},
-    {0x11730, 0x11746}, {0x11800, 0x1183B}, {0x118A0, 0x118F2},
-    {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913},
-    {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938},
-    {0x1193B, 0x11946}, {0x11950, 0x11959}, {0x119A0, 0x119A7},
-    {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, {0x11A00, 0x11A47},
-    {0x11A50, 0x11AA2}, {0x11AB0, 0x11AF8}, {0x11B00, 0x11B0A},
-    {0x11B60, 0x11B67}, {0x11BC0, 0x11BE1}, {0x11BF0, 0x11BF9},
-    {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45},
-    {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7},
-    {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09},
-    {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D},
-    {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65},
-    {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91},
-    {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11DB0, 0x11DDB},
-    {0x11DE0, 0x11DE9}, {0x11DF0, 0x11DF1}, {0x11EE0, 0x11EF8},
-    {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F5A},
-    {0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399},
-    {0x12400, 0x12543}, {0x12550, 0x12686}, {0x12F90, 0x12FF2},
-    {0x13000, 0x1342F}, {0x13440, 0x13455}, {0x13460, 0x143FA},
-    {0x14400, 0x14646}, {0x16100, 0x16139}, {0x16800, 0x16A38},
-    {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16ABE},
-    {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5},
-    {0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61},
-    {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D79},
-    {0x16E40, 0x16E9A}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3},
-    {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F},
-    {0x16FE0, 0x16FE4}, {0x16FF0, 0x16FF6}, {0x17000, 0x18CDA},
-    {0x18CFF, 0x18D20}, {0x18D80, 0x18DF2}, {0x18E00, 0x19191},
-    {0x191A0, 0x191D2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB},
-    {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B128}, {0x1B132, 0x1B132},
-    {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B168},
-    {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
-    {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9F},
-    {0x1CC00, 0x1CCFC}, {0x1CD00, 0x1CEB3}, {0x1CEBA, 0x1CED0},
-    {0x1CED2, 0x1CED4}, {0x1CEDD, 0x1CEFD}, {0x1CF00, 0x1CF2D},
-    {0x1CF30, 0x1CF46}, {0x1CF50, 0x1CFC3}, {0x1D000, 0x1D0F5},
-    {0x1D100, 0x1D172}, {0x1D17B, 0x1D245}, {0x1D250, 0x1D281},
-    {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356},
-    {0x1D360, 0x1D378}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C},
-    {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6},
-    {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB},
-    {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A},
-    {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539},
-    {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546},
-    {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A6}, {0x1D6A8, 0x1D7CB},
-    {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF},
-    {0x1DB00, 0x1DB1C}, {0x1DF00, 0x1DF81}, {0x1DF90, 0x1DF96},
-    {0x1DFCD, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021},
-    {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D},
-    {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},
-    {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AE},
-    {0x1E2C0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4F9},
-    {0x1E5D0, 0x1E5FA}, {0x1E5FF, 0x1E5FF}, {0x1E6C0, 0x1E6DE},
-    {0x1E6E0, 0x1E6F5}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6},
-    {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE},
-    {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, {0x1E900, 0x1E94B},
-    {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, {0x1EC71, 0x1ECB4},
-    {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F},
-    {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27},
-    {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39},
-    {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47},
-    {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F},
-    {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57},
-    {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D},
-    {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64},
-    {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77},
-    {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89},
-    {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9},
-    {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F02B},
-    {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF},
-    {0x1F0C1, 0x1F0CF}, {0x1F0D1, 0x1F0F5}, {0x1F100, 0x1F1AE},
-    {0x1F1E6, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248},
-    {0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F6D9},
-    {0x1F6DC, 0x1F6EC}, {0x1F6F0, 0x1F6FC}, {0x1F700, 0x1F7DB},
-    {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F80B}, {0x1F810, 0x1F847},
-    {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD},
-    {0x1F8B0, 0x1F8BB}, {0x1F8C0, 0x1F8C1}, {0x1F8D0, 0x1F8D8},
-    {0x1F900, 0x1FA57}, {0x1FA60, 0x1FA6D}, {0x1FA70, 0x1FA7C},
-    {0x1FA80, 0x1FAC6}, {0x1FAC8, 0x1FAC8}, {0x1FACC, 0x1FADD},
-    {0x1FADF, 0x1FAEB}, {0x1FAEF, 0x1FAFA}, {0x1FB00, 0x1FB92},
-    {0x1FB94, 0x1FBFA}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81E},
-    {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D},
-    {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479},
-    {0x3D000, 0x3FC3F}, {0xE0100, 0xE01EF},
-};
-extern const CharRanges GeneratedPrintableRanges = GeneratedPrintableRangesData;
+extern const std::uint16_t Lookup3[176][16] = {
+    {0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12},
+    {13, 14, 15, 16, 17, 18, 15, 19, 20, 21, 22, 23, 24, 25, 26, 27},
+    {26, 26, 26, 28, 29, 30, 30, 31, 31, 32, 31, 33, 34, 35, 36, 37},
+    {38, 38, 38, 38, 38, 38, 38, 39, 40, 41, 42, 43, 44, 45, 26, 46},
+    {47, 48, 48, 49, 49, 30, 26, 26, 50, 26, 26, 26, 51, 26, 26, 26},
+    {26, 26, 26, 52, 53, 54, 31, 31, 55, 56, 57, 58, 59, 60, 61, 62},
+    {63, 64, 60, 60, 65, 57, 66, 67, 60, 60, 60, 60, 60, 68, 69, 70},
+    {71, 72, 60, 57, 73, 60, 60, 60, 60, 60, 74, 75, 76, 60, 77, 78},
+    {60, 79, 80, 81, 60, 82, 83, 60, 84, 85, 60, 60, 86, 57, 87, 57},
+    {88, 60, 60, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101},
+    {102, 95, 96, 103, 104, 105, 106, 107, 108, 109, 96, 110, 111, 112, 100,
+     113},
+    {114, 95, 96, 115, 116, 117, 100, 118, 119, 120, 121, 122, 123, 124, 106,
+     125},
+    {126, 127, 96, 128, 129, 130, 100, 131, 132, 127, 96, 133, 134, 135, 100,
+     136},
+    {137, 127, 60, 138, 139, 140, 100, 141, 142, 143, 60, 144, 145, 146, 106,
+     147},
+    {148, 60, 60, 149, 150, 151, 152, 152, 153, 60, 154, 155, 156, 157, 152,
+     152},
+    {158, 159, 160, 161, 162, 60, 163, 164, 165, 166, 57, 167, 168, 169, 152,
+     152},
+    {60, 60, 170, 171, 172, 173, 174, 175, 176, 177, 53, 53, 178, 31, 31, 179},
+    {180, 180, 180, 180, 180, 180, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60},
+    {60, 60, 60, 60, 181, 182, 60, 60, 181, 60, 60, 183, 184, 185, 60, 60},
+    {60, 184, 60, 60, 60, 186, 187, 188, 60, 189, 53, 53, 53, 53, 53, 190},
+    {191, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60},
+    {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60},
+    {60, 60, 60, 60, 60, 60, 192, 60, 193, 194, 60, 60, 60, 60, 195, 196},
+    {60, 197, 60, 198, 60, 199, 200, 201, 60, 60, 60, 202, 203, 204, 205, 206},
+    {207, 205, 60, 60, 208, 60, 60, 209, 210, 60, 211, 60, 60, 60, 60, 212},
+    {60, 213, 214, 215, 216, 60, 217, 218, 60, 60, 219, 60, 220, 221, 222, 222},
+    {60, 223, 60, 60, 60, 224, 225, 226, 205, 205, 227, 228, 57, 57, 57, 229},
+    {230, 60, 60, 231, 232, 172, 233, 234, 235, 60, 236, 76, 60, 60, 237, 238},
+    {60, 60, 239, 240, 241, 76, 60, 242, 243, 53, 53, 244, 245, 246, 247, 248},
+    {31, 31, 249, 33, 33, 33, 250, 251, 31, 252, 33, 33, 57, 57, 57, 57},
+    {26, 26, 26, 26, 26, 26, 26, 26, 26, 253, 26, 26, 26, 26, 26, 26},
+    {254, 255, 254, 254, 255, 256, 254, 257, 258, 258, 258, 259, 260, 261, 262,
+     263},
+    {264, 265, 266, 267, 268, 269, 270, 271, 272, 33, 273, 274, 275, 276, 277,
+     229},
+    {278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,
+     293},
+    {294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 301, 301, 301,
+     301},
+    {306, 307, 308, 222, 222, 222, 222, 309, 222, 310, 301, 311, 222, 312, 313,
+     314},
+    {222, 222, 189, 152, 315, 152, 316, 316, 316, 317, 318, 318, 318, 318, 319,
+     316},
+    {318, 318, 318, 318, 320, 318, 318, 321, 318, 322, 323, 324, 325, 326, 327,
+     328},
+    {329, 330, 222, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+     343},
+    {344, 222, 345, 346, 347, 348, 349, 350, 351, 352, 222, 353, 354, 301, 355,
+     301},
+    {222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222,
+     222},
+    {301, 301, 301, 301, 301, 301, 301, 301, 356, 357, 301, 301, 301, 358, 301,
+     359},
+    {301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, 301,
+     301},
+    {222, 360, 222, 301, 361, 362, 222, 363, 222, 222, 222, 222, 222, 222, 222,
+     222},
+    {53, 53, 53, 31, 31, 31, 364, 365, 26, 26, 26, 26, 26, 26, 366, 367},
+    {31, 31, 368, 60, 60, 60, 369, 370, 60, 371, 372, 372, 372, 372, 57, 57},
+    {373, 374, 375, 376, 377, 378, 379, 152, 380, 381, 380, 380, 380, 380, 380,
+     382},
+    {380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 383, 152,
+     380},
+    {384, 385, 386, 387, 388, 180, 180, 180, 180, 389, 390, 180, 180, 180, 180,
+     391},
+    {392, 180, 180, 388, 180, 180, 180, 180, 393, 394, 180, 180, 380, 380, 395,
+     180},
+    {380, 396, 397, 380, 398, 399, 380, 380, 397, 380, 380, 399, 380, 380, 380,
+     380},
+    {380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380,
+     380},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+     180},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 380, 380, 380,
+     380},
+    {180, 400, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+     180},
+    {180, 180, 180, 180, 180, 180, 180, 180, 401, 380, 380, 380, 402, 60, 60,
+     242},
+    {403, 60, 404, 152, 26, 26, 405, 406, 26, 407, 60, 60, 60, 60, 408, 409},
+    {37, 410, 411, 412, 26, 26, 26, 413, 414, 415, 416, 417, 418, 419, 420,
+     421},
+    {422, 60, 423, 424, 60, 60, 60, 425, 426, 60, 60, 427, 428, 205, 57, 429},
+    {76, 60, 430, 60, 431, 432, 180, 401, 88, 60, 60, 433, 434, 435, 436, 437},
+    {60, 60, 438, 439, 440, 441, 60, 442, 60, 60, 60, 443, 444, 445, 446, 447},
+    {448, 449, 372, 31, 31, 450, 451, 31, 31, 31, 31, 31, 60, 60, 452, 205},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 453, 60, 454, 60, 60,
+     219},
+    {455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455,
+     455},
+    {456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
+     456},
+    {180, 180, 180, 180, 180, 180, 457, 180, 180, 180, 180, 180, 180, 458, 459,
+     459},
+    {460, 461, 462, 463, 464, 60, 60, 60, 60, 60, 60, 465, 466, 467, 60, 60},
+    {60, 60, 60, 60, 60, 468, 469, 60, 60, 60, 60, 60, 60, 60, 60, 60},
+    {60, 60, 60, 470, 222, 60, 60, 60, 60, 471, 60, 60, 472, 152, 152, 473},
+    {38, 474, 57, 475, 476, 477, 478, 479, 60, 60, 60, 60, 60, 60, 60, 480},
+    {481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 489, 491, 492, 493, 494,
+     495},
+    {496, 60, 185, 497, 217, 217, 152, 152, 60, 60, 60, 60, 60, 60, 60, 83},
+    {498, 351, 351, 499, 500, 500, 500, 501, 502, 503, 504, 152, 152, 222, 222,
+     505},
+    {152, 152, 152, 152, 152, 152, 152, 152, 60, 163, 60, 60, 60, 112, 506,
+     507},
+    {60, 60, 508, 60, 509, 60, 60, 510, 60, 511, 60, 60, 512, 513, 152, 152},
+    {53, 53, 514, 31, 31, 60, 60, 60, 60, 217, 205, 53, 53, 515, 31, 516},
+    {60, 60, 517, 60, 60, 60, 518, 519, 519, 520, 521, 522, 60, 60, 60, 523},
+    {60, 60, 60, 371, 60, 212, 517, 152, 524, 33, 33, 525, 152, 152, 152, 152},
+    {526, 60, 60, 527, 60, 528, 60, 529, 60, 213, 530, 152, 152, 152, 60, 531},
+    {60, 532, 60, 533, 60, 220, 152, 152, 60, 60, 60, 534, 351, 535, 351, 351},
+    {536, 537, 60, 538, 539, 540, 60, 541, 60, 542, 152, 152, 543, 60, 544,
+     545},
+    {60, 60, 60, 546, 60, 547, 60, 548, 60, 549, 550, 152, 152, 152, 152, 152},
+    {60, 60, 60, 60, 209, 152, 152, 152, 53, 53, 53, 551, 31, 31, 31, 552},
+    {60, 60, 553, 205, 554, 53, 555, 31, 556, 152, 152, 152, 152, 152, 152,
+     152},
+    {152, 152, 152, 152, 152, 152, 351, 557, 60, 60, 558, 559, 560, 561, 213,
+     57},
+    {60, 542, 562, 60, 74, 563, 152, 60, 564, 152, 152, 60, 565, 152, 60, 371},
+    {566, 60, 60, 567, 568, 535, 569, 570, 235, 60, 60, 571, 572, 60, 209, 205},
+    {573, 60, 574, 575, 576, 60, 60, 577, 235, 60, 60, 578, 579, 580, 581, 582},
+    {60, 109, 583, 584, 585, 152, 152, 152, 586, 587, 588, 60, 60, 589, 590,
+     205},
+    {591, 95, 96, 592, 593, 594, 595, 596, 597, 60, 60, 598, 599, 600, 601,
+     152},
+    {60, 60, 60, 602, 603, 604, 559, 152, 60, 60, 60, 605, 606, 205, 152, 152},
+    {152, 152, 152, 152, 152, 152, 152, 152, 60, 60, 607, 608, 609, 610, 152,
+     152},
+    {60, 60, 60, 611, 612, 205, 613, 152, 60, 60, 614, 615, 205, 616, 617, 152},
+    {60, 618, 619, 620, 371, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {60, 60, 583, 621, 152, 152, 152, 152, 152, 152, 53, 53, 31, 31, 160, 622},
+    {623, 624, 60, 625, 626, 205, 152, 152, 152, 152, 627, 60, 60, 628, 629,
+     152},
+    {630, 60, 60, 631, 632, 633, 60, 60, 634, 635, 636, 60, 60, 60, 60, 209},
+    {637, 152, 152, 152, 152, 152, 638, 152, 152, 152, 152, 152, 60, 60, 639,
+     205},
+    {96, 60, 607, 640, 641, 160, 642, 643, 60, 644, 645, 646, 152, 152, 152,
+     152},
+    {647, 60, 60, 648, 649, 205, 650, 60, 651, 652, 205, 60, 60, 653, 205, 75},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 60,
+     654},
+    {655, 127, 60, 656, 657, 658, 152, 152, 152, 152, 152, 112, 351, 659, 660,
+     661},
+    {60, 60, 60, 60, 60, 60, 60, 60, 60, 220, 152, 152, 152, 152, 152, 152},
+    {500, 500, 500, 500, 500, 500, 500, 662, 60, 60, 60, 60, 60, 60, 60, 60},
+    {60, 60, 60, 60, 523, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500,
+     500},
+    {500, 500, 500, 500, 500, 500, 500, 500, 663, 152, 152, 152, 152, 152, 152,
+     152},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 60, 60, 60, 60, 60, 60, 664},
+    {60, 60, 60, 665, 666, 667, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60},
+    {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 83},
+    {60, 60, 60, 60, 371, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {60, 668, 669, 205, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {60, 60, 60, 209, 60, 213, 435, 60, 60, 60, 60, 213, 205, 60, 217, 670},
+    {60, 60, 60, 671, 672, 673, 674, 675, 60, 152, 152, 152, 152, 152, 152,
+     152},
+    {152, 152, 152, 152, 676, 60, 677, 205, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {152, 152, 152, 152, 53, 53, 31, 31, 351, 678, 53, 679, 31, 680, 152, 152},
+    {60, 60, 60, 60, 681, 682, 683, 683, 684, 685, 152, 152, 152, 152, 686,
+     687},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 688, 152,
+     689},
+    {180, 180, 690, 152, 152, 152, 152, 152, 180, 180, 180, 180, 180, 180, 180,
+     691},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 692, 180, 180, 180, 691, 152,
+     152},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     693},
+    {180, 180, 694, 695, 152, 696, 697, 180, 180, 180, 180, 180, 180, 180, 180,
+     180},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+     698},
+    {60, 60, 60, 60, 60, 60, 83, 163, 209, 699, 700, 152, 152, 152, 152, 152},
+    {222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222,
+     701},
+    {222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 702, 222, 703, 222,
+     704},
+    {57, 57, 705, 57, 706, 222, 222, 222, 222, 222, 222, 222, 707, 152, 152,
+     152},
+    {222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222,
+     708},
+    {222, 222, 709, 222, 222, 222, 710, 711, 712, 222, 713, 222, 222, 222, 222,
+     222},
+    {222, 222, 222, 222, 714, 715, 222, 222, 716, 152, 152, 152, 351, 717, 351,
+     717},
+    {380, 380, 380, 380, 380, 402, 718, 719, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {53, 720, 31, 721, 722, 723, 254, 53, 724, 725, 726, 727, 728, 53, 720, 31},
+    {729, 730, 31, 731, 732, 733, 734, 53, 735, 31, 53, 720, 31, 721, 722, 31},
+    {254, 53, 724, 734, 53, 735, 31, 53, 720, 31, 736, 53, 737, 738, 739, 740},
+    {31, 741, 53, 742, 743, 744, 745, 31, 746, 53, 747, 31, 748, 616, 616, 616},
+    {57, 57, 57, 749, 57, 57, 750, 751, 752, 753, 56, 152, 152, 152, 152, 152},
+    {301, 754, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {755, 31, 31, 31, 756, 757, 758, 412, 559, 460, 152, 152, 759, 33, 33, 33},
+    {760, 761, 762, 33, 33, 33, 763, 152, 764, 152, 152, 152, 152, 152, 152,
+     152},
+    {60, 60, 163, 765, 766, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 60, 767, 152, 60, 60, 768,
+     769},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 60, 770,
+     205},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 60, 668,
+     771},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 60, 213, 772,
+     773},
+    {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 774,
+     213},
+    {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 775, 706, 152, 152},
+    {53, 53, 724, 31, 776, 435, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {152, 152, 152, 152, 152, 152, 152, 581, 351, 351, 777, 778, 152, 152, 152,
+     152},
+    {581, 351, 779, 780, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {781, 60, 782, 783, 784, 785, 786, 787, 788, 219, 789, 219, 152, 152, 152,
+     790},
+    {791, 222, 792, 222, 222, 222, 222, 222, 222, 707, 793, 794, 795, 794, 222,
+     708},
+    {796, 318, 797, 318, 318, 318, 798, 318, 799, 800, 801, 152, 152, 152, 802,
+     222},
+    {803, 380, 380, 804, 805, 806, 383, 152, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {380, 380, 807, 808, 380, 380, 380, 809, 380, 333, 380, 380, 810, 333, 380,
+     811},
+    {380, 380, 380, 812, 813, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380,
+     814},
+    {380, 380, 380, 815, 816, 380, 331, 817, 222, 818, 791, 222, 222, 222, 222,
+     819},
+    {380, 380, 380, 380, 380, 222, 222, 222, 380, 380, 380, 380, 820, 821, 822,
+     823},
+    {222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 824, 804,
+     825},
+    {792, 222, 222, 222, 826, 189, 222, 222, 826, 222, 827, 792, 828, 829, 152,
+     152},
+    {830, 380, 380, 831, 808, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380,
+     380},
+    {222, 222, 222, 222, 222, 826, 827, 832, 380, 380, 380, 380, 833, 834, 835,
+     836},
+    {222, 222, 222, 222, 222, 222, 222, 222, 222, 837, 222, 222, 222, 222, 222,
+     838},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 459,
+     459},
+    {180, 839, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+     180},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 457, 180, 180, 180, 180,
+     180},
+    {180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 840,
+     180},
+    {180, 180, 180, 180, 180, 457, 459, 459, 459, 459, 459, 459, 459, 459, 459,
+     459},
+    {459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
+     459},
+    {180, 457, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
+     459},
+    {459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
+     841},
+    {180, 180, 180, 180, 842, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+     180},
+    {180, 180, 180, 180, 180, 180, 180, 458, 459, 459, 459, 459, 459, 459, 459,
+     459},
+    {180, 180, 180, 180, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
+     459},
+    {843, 152, 665, 665, 665, 665, 665, 665, 152, 152, 152, 152, 152, 152, 152,
+     152},
+    {38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 152},
+    {456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
+     844}};
 
-// General_Category=Cc
-static constexpr UnicodeCharRange GeneratedControlCharacterRangesData[] = {
-    {0x0000, 0x001F},
-    {0x007F, 0x009F},
-};
-extern const CharRanges GeneratedControlCharacterRanges =
-    GeneratedControlCharacterRangesData;
+extern const std::uint16_t Lookup4[845][4] = {
+    {0, 0, 0, 0},         {1, 2, 3, 4},         {5, 5, 6, 7},
+    {8, 9, 9, 9},         {9, 9, 10, 11},       {12, 13, 13, 13},
+    {13, 13, 14, 15},     {16, 17, 18, 19},     {20, 21, 22, 23},
+    {24, 25, 24, 24},     {26, 27, 26, 28},     {29, 30, 31, 29},
+    {32, 33, 31, 34},     {35, 36, 36, 36},     {37, 36, 38, 36},
+    {36, 39, 38, 36},     {40, 36, 41, 42},     {43, 41, 44, 35},
+    {39, 36, 36, 36},     {36, 36, 45, 46},     {47, 48, 49, 50},
+    {45, 48, 51, 45},     {36, 48, 46, 48},     {49, 52, 53, 51},
+    {54, 55, 56, 57},     {58, 58, 58, 59},     {36, 36, 36, 36},
+    {60, 48, 36, 36},     {36, 61, 50, 47},     {52, 62, 36, 36},
+    {63, 61, 61, 61},     {61, 61, 61, 61},     {61, 64, 61, 61},
+    {65, 65, 65, 65},     {66, 67, 68, 69},     {70, 71, 72, 73},
+    {65, 74, 71, 75},     {71, 71, 71, 71},     {76, 76, 76, 76},
+    {36, 77, 78, 79},     {80, 81, 82, 83},     {84, 85, 85, 85},
+    {86, 85, 87, 61},     {88, 89, 89, 89},     {90, 89, 29, 91},
+    {50, 51, 36, 36},     {61, 92, 47, 49},     {93, 24, 24, 24},
+    {85, 85, 85, 85},     {89, 89, 89, 89},     {94, 95, 96, 36},
+    {45, 52, 52, 46},     {97, 24, 24, 24},     {24, 24, 24, 24},
+    {24, 82, 98, 99},     {61, 61, 100, 101},   {102, 95, 95, 95},
+    {95, 95, 95, 95},     {95, 95, 95, 103},    {104, 105, 106, 80},
+    {54, 54, 54, 54},     {54, 54, 107, 108},   {109, 110, 80, 80},
+    {111, 112, 113, 114}, {95, 95, 115, 116},   {117, 54, 118, 95},
+    {119, 119, 120, 121}, {122, 54, 54, 54},    {54, 123, 95, 124},
+    {95, 125, 126, 127},  {119, 119, 128, 129}, {99, 99, 99, 130},
+    {131, 54, 54, 54},    {95, 95, 132, 133},   {54, 134, 95, 95},
+    {135, 80, 80, 80},    {119, 119, 128, 54},  {54, 54, 118, 95},
+    {95, 136, 137, 138},  {54, 134, 139, 95},   {95, 140, 140, 106},
+    {99, 99, 99, 141},    {54, 54, 142, 143},   {54, 54, 107, 80},
+    {54, 54, 144, 54},    {145, 146, 95, 95},   {54, 54, 147, 95},
+    {148, 95, 95, 95},    {149, 54, 54, 54},    {54, 54, 150, 151},
+    {152, 95, 153, 154},  {142, 95, 54, 54},    {134, 155, 119, 119},
+    {156, 54, 54, 54},    {157, 133, 54, 158},  {158, 54, 54, 54},
+    {54, 54, 159, 54},    {160, 161, 162, 151}, {152, 163, 164, 165},
+    {80, 166, 80, 167},   {134, 168, 119, 119}, {169, 170, 171, 172},
+    {173, 133, 107, 108}, {159, 174, 162, 175}, {176, 146, 177, 106},
+    {178, 80, 133, 160},  {80, 168, 119, 119},  {127, 179, 80, 80},
+    {173, 133, 54, 167},  {167, 54, 54, 54},    {159, 133, 162, 151},
+    {152, 180, 181, 182}, {183, 80, 80, 80},    {184, 80, 185, 95},
+    {186, 133, 54, 158},  {159, 133, 162, 187}, {152, 163, 164, 182},
+    {146, 149, 80, 167},  {188, 170, 80, 80},   {189, 133, 107, 161},
+    {159, 162, 174, 159}, {108, 183, 107, 161}, {54, 54, 162, 190},
+    {191, 190, 192, 182}, {183, 166, 80, 80},   {193, 194, 195, 80},
+    {153, 122, 54, 159},  {159, 54, 54, 54},    {54, 54, 162, 196},
+    {153, 197, 198, 106}, {80, 199, 107, 162},  {80, 200, 170, 193},
+    {157, 201, 54, 159},  {54, 133, 162, 187},  {202, 203, 192, 106},
+    {80, 204, 80, 107},   {205, 80, 80, 80},    {206, 54, 54, 159},
+    {54, 54, 118, 151},   {152, 175, 192, 207}, {80, 208, 170, 209},
+    {170, 170, 210, 54},  {186, 133, 54, 54},   {54, 107, 161, 54},
+    {167, 54, 54, 211},   {54, 107, 212, 166},  {213, 214, 202, 202},
+    {190, 110, 80, 80},   {133, 54, 54, 54},    {215, 95, 132, 216},
+    {54, 217, 95, 115},   {119, 119, 120, 80},  {80, 80, 80, 80},
+    {174, 159, 107, 54},  {54, 218, 54, 54},    {215, 95, 95, 135},
+    {54, 219, 95, 132},   {119, 119, 220, 54},  {221, 99, 99, 99},
+    {222, 223, 224, 194}, {119, 119, 225, 170}, {170, 226, 227, 228},
+    {54, 54, 133, 54},    {54, 54, 54, 183},    {102, 95, 95, 149},
+    {95, 229, 54, 142},   {95, 95, 102, 95},    {95, 95, 95, 230},
+    {194, 231, 194, 232}, {99, 223, 233, 80},   {54, 54, 208, 152},
+    {234, 95, 235, 236},  {119, 119, 120, 99},  {54, 237, 127, 134},
+    {151, 238, 202, 239}, {142, 122, 54, 54},   {150, 235, 202, 240},
+    {119, 119, 241, 242}, {24, 243, 80, 244},   {61, 61, 245, 246},
+    {247, 247, 247, 247}, {54, 54, 159, 162},   {54, 107, 159, 162},
+    {159, 162, 54, 107},  {159, 162, 54, 54},   {54, 107, 54, 54},
+    {54, 54, 107, 102},   {99, 99, 248, 249},   {250, 170, 170, 251},
+    {194, 194, 252, 80},  {24, 253, 61, 254},   {255, 54, 54, 54},
+    {54, 54, 54, 256},    {257, 54, 54, 54},    {54, 54, 258, 259},
+    {54, 54, 109, 260},   {261, 54, 183, 80},   {134, 262, 80, 108},
+    {134, 263, 80, 80},   {134, 80, 80, 80},    {54, 54, 54, 159},
+    {264, 80, 80, 80},    {54, 265, 95, 206},   {202, 266, 152, 95},
+    {95, 267, 268, 269},  {119, 119, 220, 80},  {170, 170, 270, 80},
+    {99, 271, 272, 148},  {273, 54, 54, 54},    {54, 54, 183, 80},
+    {54, 274, 54, 54},    {54, 54, 275, 80},    {54, 162, 80, 80},
+    {54, 54, 54, 107},    {149, 276, 153, 80},  {266, 202, 152, 80},
+    {277, 155, 119, 119}, {54, 54, 54, 162},    {54, 183, 80, 80},
+    {54, 54, 54, 80},     {54, 54, 162, 80},    {119, 119, 278, 279},
+    {194, 194, 194, 194}, {54, 118, 280, 281},  {54, 282, 95, 132},
+    {283, 152, 95, 153},  {276, 95, 95, 177},   {99, 267, 99, 284},
+    {95, 95, 95, 285},    {286, 80, 80, 80},    {95, 287, 54, 54},
+    {54, 234, 149, 153},  {266, 287, 54, 288},  {223, 194, 289, 95},
+    {95, 194, 194, 290},  {291, 54, 54, 54},    {292, 206, 265, 127},
+    {54, 150, 206, 293},  {206, 80, 80, 99},    {54, 202, 202, 95},
+    {95, 213, 200, 99},   {119, 119, 220, 133}, {54, 54, 65, 98},
+    {61, 61, 294, 80},    {24, 24, 82, 97},     {99, 99, 80, 80},
+    {115, 95, 95, 95},    {234, 95, 122, 131},  {54, 295, 296, 80},
+    {61, 61, 61, 65},     {65, 65, 297, 61},    {61, 61, 246, 61},
+    {61, 61, 298, 65},    {36, 51, 61, 299},    {61, 61, 24, 24},
+    {61, 254, 24, 253},   {61, 61, 300, 300},   {61, 61, 61, 254},
+    {61, 61, 301, 301},   {61, 302, 24, 303},   {304, 302, 24, 305},
+    {61, 306, 24, 307},   {61, 61, 24, 308},    {306, 302, 24, 309},
+    {310, 310, 311, 312}, {313, 314, 315, 315}, {316, 317, 318, 319},
+    {320, 321, 322, 323}, {324, 325, 99, 99},   {326, 324, 99, 327},
+    {111, 328, 111, 111}, {329, 330, 331, 332}, {333, 330, 331, 334},
+    {335, 335, 336, 337}, {335, 335, 335, 335}, {335, 338, 80, 80},
+    {95, 95, 95, 339},    {340, 341, 95, 95},   {342, 343, 344, 345},
+    {346, 347, 348, 349}, {350, 351, 352, 353}, {24, 354, 355, 50},
+    {356, 357, 358, 359}, {360, 361, 360, 362}, {363, 363, 363, 364},
+    {363, 363, 365, 364}, {366, 367, 368, 80},  {369, 370, 371, 194},
+    {372, 373, 194, 373}, {194, 194, 374, 194}, {194, 194, 194, 375},
+    {376, 377, 194, 194}, {194, 378, 194, 194}, {194, 356, 356, 356},
+    {379, 380, 381, 382}, {383, 383, 384, 385}, {381, 386, 369, 387},
+    {356, 369, 356, 388}, {356, 356, 389, 389}, {384, 356, 356, 356},
+    {388, 369, 390, 390}, {356, 356, 356, 356}, {390, 390, 356, 356},
+    {356, 383, 383, 356}, {356, 383, 356, 356}, {356, 356, 356, 382},
+    {194, 194, 391, 194}, {392, 194, 393, 194}, {394, 194, 395, 194},
+    {194, 194, 194, 396}, {194, 194, 397, 356}, {356, 194, 194, 194},
+    {194, 194, 194, 356}, {394, 194, 398, 399}, {400, 194, 194, 194},
+    {194, 194, 401, 80},  {402, 402, 402, 402}, {402, 402, 402, 403},
+    {403, 403, 403, 403}, {403, 403, 404, 402}, {403, 403, 403, 194},
+    {403, 194, 194, 194}, {405, 374, 194, 194}, {406, 403, 374, 194},
+    {405, 407, 194, 374}, {408, 405, 409, 405}, {374, 194, 194, 194},
+    {405, 374, 194, 378}, {194, 194, 356, 410}, {194, 350, 411, 405},
+    {194, 412, 194, 413}, {414, 414, 194, 194}, {413, 194, 414, 414},
+    {414, 194, 194, 194}, {406, 406, 415, 416}, {194, 194, 194, 417},
+    {194, 194, 393, 414}, {417, 194, 194, 405}, {418, 194, 393, 194},
+    {194, 194, 194, 419}, {194, 420, 403, 421}, {403, 422, 403, 403},
+    {406, 194, 421, 403}, {423, 424, 421, 424}, {194, 418, 393, 194},
+    {194, 194, 399, 194}, {194, 194, 194, 411}, {194, 194, 194, 425},
+    {417, 426, 194, 194}, {194, 194, 391, 391}, {391, 427, 402, 402},
+    {170, 170, 170, 170}, {170, 398, 194, 194}, {399, 194, 194, 417},
+    {356, 428, 356, 356}, {356, 429, 430, 431}, {432, 433, 434, 434},
+    {434, 434, 435, 356}, {356, 356, 391, 356}, {356, 356, 356, 436},
+    {194, 194, 417, 399}, {356, 372, 356, 396}, {399, 437, 374, 194},
+    {194, 279, 194, 194}, {48, 438, 52, 49},    {36, 46, 61, 439},
+    {36, 440, 441, 442},  {443, 80, 444, 445},  {61, 446, 80, 447},
+    {54, 54, 80, 448},    {110, 80, 80, 146},   {54, 107, 80, 80},
+    {54, 107, 54, 107},   {449, 450, 451, 450}, {99, 452, 271, 450},
+    {453, 391, 454, 455}, {99, 99, 456, 99},    {457, 99, 99, 99},
+    {458, 459, 434, 460}, {461, 80, 80, 80},    {414, 414, 414, 414},
+    {414, 414, 462, 414}, {414, 80, 80, 80},    {414, 463, 80, 80},
+    {464, 465, 466, 466}, {467, 466, 466, 468}, {469, 470, 471, 472},
+    {473, 474, 475, 476}, {477, 247, 247, 247}, {247, 478, 479, 480},
+    {481, 247, 247, 247}, {247, 247, 482, 483}, {80, 477, 247, 247},
+    {247, 247, 247, 478}, {484, 485, 414, 414}, {414, 463, 80, 486},
+    {414, 414, 414, 487}, {488, 488, 485, 414}, {414, 414, 402, 402},
+    {489, 488, 488, 488}, {247, 490, 247, 247}, {247, 247, 247, 491},
+    {414, 487, 80, 80},   {54, 54, 54, 492},    {119, 119, 128, 80},
+    {36, 36, 36, 493},    {494, 95, 95, 495},   {36, 36, 36, 496},
+    {54, 497, 364, 364},  {498, 99, 80, 80},    {71, 499, 65, 65},
+    {500, 36, 36, 36},    {299, 36, 36, 36},    {246, 61, 52, 47},
+    {36, 36, 501, 502},   {36, 299, 36, 36},    {36, 36, 48, 62},
+    {24, 36, 36, 36},     {36, 24, 52, 36},     {36, 36, 36, 253},
+    {503, 80, 80, 80},    {504, 505, 506, 54},  {507, 507, 118, 54},
+    {208, 235, 194, 286}, {170, 508, 509, 80},  {54, 99, 80, 80},
+    {239, 54, 54, 54},    {54, 202, 202, 202},  {202, 106, 80, 281},
+    {127, 54, 510, 511},  {54, 134, 95, 498},   {54, 118, 95, 95},
+    {206, 80, 80, 200},   {118, 213, 206, 206}, {512, 99, 99, 513},
+    {119, 119, 220, 281}, {54, 514, 54, 54},    {119, 119, 128, 107},
+    {54, 54, 142, 149},   {235, 176, 80, 80},   {118, 54, 54, 262},
+    {119, 119, 220, 99},  {117, 515, 516, 517}, {196, 518, 122, 134},
+    {275, 80, 80, 80},    {80, 80, 108, 519},   {54, 54, 208, 206},
+    {520, 521, 80, 80},   {133, 107, 133, 107}, {133, 107, 80, 80},
+    {61, 61, 522, 65},    {61, 61, 523, 253},   {208, 154, 524, 182},
+    {247, 80, 80, 80},    {54, 107, 108, 54},   {525, 525, 525, 525},
+    {526, 526, 526, 526}, {247, 247, 247, 527}, {247, 247, 527, 528},
+    {528, 528, 528, 528}, {61, 529, 80, 80},    {530, 61, 80, 531},
+    {54, 54, 532, 54},    {54, 107, 54, 160},   {167, 159, 54, 54},
+    {533, 71, 71, 71},    {534, 194, 194, 194}, {535, 54, 54, 54},
+    {54, 54, 54, 536},    {537, 54, 54, 54},    {54, 54, 54, 538},
+    {539, 54, 54, 54},    {54, 54, 194, 194},   {54, 54, 536, 540},
+    {541, 542, 543, 80},  {544, 545, 546, 546}, {546, 547, 548, 549},
+    {550, 541, 551, 552}, {553, 554, 555, 80},  {556, 557, 556, 556},
+    {54, 54, 54, 558},    {559, 560, 561, 562}, {563, 563, 564, 565},
+    {566, 567, 567, 567}, {567, 567, 568, 569}, {570, 571, 571, 571},
+    {571, 571, 572, 573}, {574, 575, 576, 576}, {577, 576, 576, 576},
+    {576, 576, 576, 576}, {576, 576, 576, 578}, {576, 576, 576, 579},
+    {580, 576, 580, 576}, {580, 576, 580, 581}, {582, 583, 584, 585},
+    {80, 80, 586, 587},   {54, 54, 54, 133},    {54, 54, 107, 167},
+    {141, 588, 170, 170}, {170, 589, 194, 194}, {364, 364, 364, 364},
+    {364, 590, 591, 194}, {194, 194, 592, 401}, {194, 194, 194, 277},
+    {277, 80, 80, 80},    {194, 194, 194, 593}, {594, 170, 170, 170},
+    {170, 170, 170, 80},  {170, 80, 80, 133},   {595, 54, 596, 80},
+    {54, 134, 132, 80},   {54, 54, 54, 597},    {54, 80, 54, 54},
+    {598, 599, 80, 80},   {24, 24, 61, 61},     {24, 80, 61, 61},
+    {61, 61, 61, 80},     {54, 54, 80, 80},     {54, 80, 80, 200},
+    {24, 24, 82, 24},     {82, 600, 61, 61},    {446, 61, 61, 61},
+    {446, 61, 446, 601},  {54, 80, 80, 80},     {65, 602, 65, 65},
+    {603, 65, 65, 65},    {54, 162, 159, 54},   {54, 167, 183, 158},
+    {54, 597, 170, 170},  {54, 515, 604, 170},  {80, 588, 170, 170},
+    {107, 162, 588, 170}, {54, 605, 170, 200},  {54, 54, 162, 200},
+    {54, 54, 80, 606},    {607, 170, 170, 170}, {142, 199, 80, 95},
+    {54, 133, 133, 54},   {54, 162, 132, 146},  {170, 170, 251, 80},
+    {99, 99, 110, 80},    {54, 54, 54, 608},    {54, 54, 54, 609},
+    {54, 54, 610, 54},    {54, 611, 588, 170},  {99, 141, 80, 80},
+    {54, 162, 444, 99},   {54, 162, 170, 170},  {107, 80, 170, 170},
+    {162, 80, 444, 110},  {80, 80, 612, 170},   {82, 80, 80, 80},
+    {529, 80, 607, 170},  {54, 95, 80, 80},     {119, 119, 128, 613},
+    {24, 253, 102, 614},  {61, 254, 80, 615},   {170, 170, 170, 616},
+    {54, 54, 617, 618},   {162, 80, 80, 80},    {161, 619, 620, 95},
+    {223, 194, 610, 54},  {170, 209, 80, 80},   {594, 621, 284, 80},
+    {134, 498, 284, 80},  {54, 609, 170, 80},   {622, 54, 54, 54},
+    {54, 54, 95, 95},     {95, 115, 99, 284},   {170, 623, 119, 119},
+    {518, 135, 80, 146},  {276, 149, 624, 625}, {626, 80, 80, 627},
+    {628, 54, 54, 54},    {54, 118, 95, 152},   {95, 629, 119, 119},
+    {99, 630, 80, 80},    {118, 631, 80, 80},   {208, 213, 95, 149},
+    {287, 632, 633, 634}, {119, 119, 635, 632}, {612, 170, 170, 170},
+    {170, 251, 80, 80},   {54, 54, 54, 276},    {206, 234, 99, 636},
+    {269, 80, 80, 80},    {54, 107, 159, 167},  {54, 54, 54, 167},
+    {54, 54, 637, 80},    {54, 54, 54, 118},    {276, 95, 132, 80},
+    {206, 133, 54, 158},  {159, 133, 617, 151}, {153, 164, 164, 638},
+    {183, 166, 80, 133},  {237, 639, 95, 286},  {95, 286, 80, 80},
+    {54, 54, 167, 640},   {54, 167, 276, 95},   {641, 642, 643, 266},
+    {644, 645, 110, 80},  {199, 80, 80, 80},    {54, 646, 95, 95},
+    {213, 647, 109, 99},  {119, 119, 120, 648}, {276, 95, 283, 276},
+    {234, 649, 80, 80},   {54, 54, 54, 208},    {213, 106, 202, 265},
+    {650, 99, 99, 99},    {99, 99, 54, 106},    {276, 95, 149, 293},
+    {650, 183, 80, 80},   {99, 99, 99, 110},    {54, 54, 118, 154},
+    {95, 265, 637, 80},   {119, 119, 119, 119}, {119, 80, 80, 80},
+    {54, 54, 107, 651},   {213, 265, 95, 80},   {119, 119, 225, 222},
+    {95, 95, 624, 80},    {616, 80, 80, 108},   {54, 107, 211, 54},
+    {54, 174, 54, 54},    {202, 652, 653, 647}, {654, 141, 80, 80},
+    {54, 54, 161, 54},    {646, 95, 639, 202},  {655, 656, 80, 80},
+    {142, 95, 628, 54},   {118, 95, 657, 115},  {99, 272, 80, 80},
+    {142, 149, 152, 54},  {54, 54, 134, 95},    {95, 149, 498, 658},
+    {141, 80, 80, 80},    {99, 99, 631, 80},    {234, 283, 80, 80},
+    {637, 80, 80, 80},    {95, 132, 95, 265},   {632, 284, 80, 80},
+    {170, 170, 170, 251}, {121, 54, 54, 54},    {639, 95, 95, 95},
+    {95, 95, 659, 95},    {234, 176, 80, 80},   {54, 107, 167, 54},
+    {142, 132, 212, 180}, {95, 660, 80, 80},    {54, 167, 159, 54},
+    {54, 54, 237, 643},   {661, 293, 183, 80},  {54, 54, 619, 80},
+    {118, 524, 110, 80},  {662, 54, 54, 54},    {54, 213, 132, 190},
+    {663, 99, 99, 99},    {119, 119, 664, 80},  {170, 591, 194, 665},
+    {540, 194, 194, 194}, {252, 80, 80, 200},   {99, 598, 364, 364},
+    {364, 666, 80, 80},   {667, 80, 80, 80},    {111, 111, 111, 111},
+    {122, 118, 95, 95},   {95, 106, 80, 80},    {54, 54, 54, 134},
+    {95, 95, 206, 152},   {95, 668, 80, 80},    {95, 115, 99, 194},
+    {65, 669, 80, 80},    {119, 119, 670, 170}, {671, 54, 54, 54},
+    {54, 54, 80, 133},    {672, 54, 54, 54},    {54, 54, 273, 492},
+    {170, 673, 141, 80},  {24, 24, 674, 61},    {61, 80, 80, 80},
+    {54, 54, 107, 146},   {646, 202, 202, 202}, {202, 202, 202, 202},
+    {202, 202, 80, 146},  {675, 65, 65, 65},    {676, 677, 80, 80},
+    {678, 679, 80, 80},   {247, 247, 478, 80},  {80, 80, 80, 680},
+    {491, 80, 80, 80},    {478, 80, 80, 80},    {681, 80, 80, 80},
+    {682, 683, 682, 684}, {247, 247, 491, 80},  {685, 80, 80, 80},
+    {478, 686, 80, 80},   {80, 247, 491, 80},   {247, 247, 247, 80},
+    {54, 54, 162, 687},   {111, 80, 80, 80},    {119, 119, 688, 277},
+    {194, 80, 279, 194},  {232, 277, 80, 689},  {356, 356, 356, 690},
+    {95, 95, 95, 106},    {95, 132, 80, 80},    {194, 80, 80, 80},
+    {194, 252, 80, 80},   {194, 289, 691, 194}, {194, 692, 224, 693},
+    {694, 111, 695, 95},  {696, 697, 95, 194},  {194, 194, 698, 224},
+    {698, 699, 80, 80},   {700, 194, 289, 701}, {638, 80, 80, 80},
+    {170, 80, 80, 80},    {488, 488, 488, 488}, {488, 702, 251, 80},
+    {24, 24, 345, 61},    {61, 24, 24, 24},     {24, 24, 24, 345},
+    {61, 302, 61, 61},    {345, 61, 61, 61},    {61, 61, 61, 83},
+    {503, 703, 97, 83},   {24, 345, 446, 704},  {61, 704, 61, 61},
+    {61, 243, 82, 97},    {24, 83, 24, 705},    {61, 61, 243, 82},
+    {24, 706, 707, 24},   {705, 61, 61, 61},    {61, 61, 61, 24},
+    {24, 345, 61, 61},    {61, 529, 24, 24},    {708, 61, 61, 61},
+    {61, 61, 709, 61},    {50, 24, 24, 24},     {24, 24, 710, 61},
+    {61, 711, 61, 24},    {24, 708, 61, 61},    {61, 61, 61, 709},
+    {61, 50, 24, 24},     {24, 24, 24, 710},    {61, 61, 711, 61},
+    {24, 24, 708, 61},    {709, 61, 299, 168},  {95, 696, 289, 95},
+    {95, 95, 95, 691},    {194, 712, 194, 194}, {194, 713, 99, 80},
+    {80, 80, 146, 95},    {356, 356, 356, 714}, {61, 61, 715, 61},
+    {51, 61, 36, 46},     {46, 61, 61, 61},     {61, 61, 36, 36},
+    {80, 80, 80, 504},    {95, 132, 95, 95},    {95, 95, 177, 95},
+    {180, 198, 132, 80},  {65, 65, 65, 716},    {80, 80, 80, 146},
+    {95, 675, 65, 716},   {119, 119, 220, 717}, {54, 54, 54, 718},
+    {54, 54, 54, 95},     {119, 119, 220, 216}, {54, 54, 273, 95},
+    {719, 119, 720, 200}, {118, 507, 54, 134},  {54, 269, 80, 721},
+    {54, 107, 54, 174},   {54, 722, 170, 170},  {61, 95, 675, 80},
+    {170, 170, 170, 604}, {723, 251, 80, 80},   {170, 170, 170, 724},
+    {170, 170, 170, 270}, {54, 133, 54, 54},    {174, 158, 133, 54},
+    {107, 54, 218, 80},   {640, 108, 218, 133}, {174, 158, 218, 218},
+    {174, 158, 107, 54},  {107, 54, 133, 160},  {54, 54, 167, 54},
+    {133, 133, 167, 54},  {690, 80, 80, 80},    {194, 399, 194, 194},
+    {194, 194, 194, 80},  {194, 194, 194, 401}, {725, 194, 194, 194},
+    {725, 194, 194, 417}, {402, 402, 362, 591}, {403, 403, 403, 374},
+    {403, 403, 374, 194}, {403, 403, 403, 421}, {726, 414, 727, 403},
+    {403, 403, 403, 728}, {80, 279, 194, 194},  {487, 80, 80, 80},
+    {414, 414, 414, 80},  {414, 414, 729, 80},  {463, 80, 80, 80},
+    {399, 194, 194, 398}, {414, 426, 414, 414}, {414, 414, 414, 730},
+    {414, 414, 731, 417}, {399, 399, 732, 733}, {414, 414, 414, 731},
+    {730, 414, 414, 414}, {414, 414, 414, 400}, {414, 414, 414, 412},
+    {194, 194, 417, 731}, {194, 194, 734, 194}, {194, 735, 194, 194},
+    {194, 194, 417, 414}, {414, 412, 194, 399}, {731, 398, 463, 414},
+    {194, 194, 417, 729}, {194, 414, 414, 729}, {194, 194, 734, 80},
+    {399, 194, 194, 194}, {194, 194, 80, 80},   {194, 194, 194, 252},
+    {252, 80, 80, 80},    {356, 356, 714, 80},  {194, 194, 194, 414},
+    {414, 414, 731, 414}, {414, 414, 414, 729}, {414, 487, 729, 414},
+    {414, 414, 414, 462}, {414, 414, 414, 486}, {414, 414, 487, 80},
+    {401, 194, 194, 194}, {119, 119, 736, 80},  {247, 247, 247, 737},
+    {738, 528, 528, 528}, {528, 528, 528, 739}, {247, 247, 737, 528},
+    {627, 80, 80, 80},    {526, 526, 526, 740}};
 
-// General_Category=Cf
-static constexpr UnicodeCharRange GeneratedFormatCharacterRangesData[] = {
-    {0x00AD, 0x00AD},   {0x0600, 0x0605},   {0x061C, 0x061C},
-    {0x06DD, 0x06DD},   {0x070F, 0x070F},   {0x0890, 0x0891},
-    {0x08E2, 0x08E2},   {0x180E, 0x180E},   {0x200B, 0x200F},
-    {0x202A, 0x202E},   {0x2060, 0x2064},   {0x2066, 0x206F},
-    {0xFEFF, 0xFEFF},   {0xFFF9, 0xFFFB},   {0x110BD, 0x110BD},
-    {0x110CD, 0x110CD}, {0x13430, 0x1343F}, {0x1BCA0, 0x1BCA3},
-    {0x1D173, 0x1D17A}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F},
-};
-extern const CharRanges GeneratedFormatCharacterRanges =
-    GeneratedFormatCharacterRangesData;
+extern const std::uint8_t Lookup5[741][4] = {
+    {0, 0, 0, 0},         {1, 2, 2, 2},         {3, 2, 2, 2},
+    {4, 5, 2, 6},         {2, 7, 2, 2},         {8, 8, 8, 8},
+    {8, 8, 2, 2},         {6, 6, 6, 2},         {2, 9, 9, 9},
+    {9, 9, 9, 9},         {9, 9, 9, 4},         {2, 5, 10, 11},
+    {10, 12, 12, 12},     {12, 12, 12, 12},     {12, 12, 12, 4},
+    {6, 5, 6, 0},         {13, 14, 3, 3},       {15, 3, 16, 14},
+    {17, 18, 19, 20},     {6, 21, 22, 10},      {22, 23, 24, 24},
+    {17, 25, 14, 26},     {17, 24, 19, 27},     {28, 28, 28, 14},
+    {29, 29, 29, 29},     {29, 29, 30, 29},     {30, 29, 29, 29},
+    {29, 29, 29, 23},     {29, 29, 30, 31},     {31, 31, 25, 25},
+    {25, 25, 31, 25},     {31, 31, 31, 25},     {31, 25, 31, 31},
+    {25, 25, 25, 23},     {31, 25, 31, 25},     {29, 31, 29, 25},
+    {29, 25, 29, 25},     {29, 31, 29, 31},     {29, 25, 29, 31},
+    {29, 25, 30, 31},     {29, 31, 30, 31},     {31, 29, 25, 29},
+    {25, 29, 25, 30},     {31, 30, 31, 29},     {31, 31, 30, 31},
+    {29, 29, 25, 29},     {25, 29, 25, 25},     {25, 29, 29, 25},
+    {29, 25, 29, 29},     {25, 29, 29, 29},     {25, 25, 29, 29},
+    {29, 25, 25, 25},     {25, 29, 25, 29},     {29, 25, 25, 32},
+    {32, 32, 32, 32},     {29, 33, 25, 29},     {33, 25, 29, 33},
+    {25, 29, 31, 29},     {31, 29, 31, 29},     {31, 25, 29, 25},
+    {25, 29, 33, 25},     {25, 25, 25, 25},     {29, 29, 29, 25},
+    {25, 31, 25, 25},     {32, 32, 25, 25},     {34, 34, 34, 34},
+    {34, 34, 35, 35},     {17, 35, 34, 36},     {34, 36, 36, 36},
+    {34, 36, 34, 34},     {36, 34, 35, 35},     {35, 35, 35, 35},
+    {17, 17, 17, 17},     {35, 17, 35, 17},     {34, 35, 35, 35},
+    {34, 35, 34, 35},     {37, 37, 37, 37},     {34, 35, 29, 25},
+    {38, 38, 39, 25},     {25, 25, 40, 29},     {38, 38, 38, 38},
+    {35, 35, 29, 41},     {29, 29, 29, 38},     {29, 38, 29, 29},
+    {25, 30, 30, 30},     {30, 30, 30, 30},     {30, 30, 38, 30},
+    {30, 30, 29, 29},     {25, 31, 31, 31},     {31, 31, 31, 31},
+    {31, 31, 25, 31},     {25, 25, 25, 29},     {29, 25, 42, 29},
+    {29, 30, 29, 29},     {29, 25, 18, 43},     {43, 43, 43, 43},
+    {44, 44, 29, 25},     {38, 29, 29, 29},     {34, 34, 40, 40},
+    {40, 40, 40, 40},     {25, 40, 45, 34},     {34, 18, 18, 46},
+    {38, 43, 43, 43},     {43, 43, 45, 43},     {40, 43, 43, 40},
+    {43, 43, 40, 43},     {43, 43, 38, 38},     {32, 32, 32, 38},
+    {38, 38, 38, 32},     {32, 32, 32, 40},     {40, 38, 38, 38},
+    {47, 47, 47, 47},     {47, 47, 42, 42},     {42, 40, 40, 46},
+    {40, 40, 18, 18},     {43, 43, 43, 40},     {47, 40, 40, 40},
+    {34, 32, 32, 32},     {32, 32, 32, 43},     {48, 48, 48, 48},
+    {48, 48, 40, 40},     {40, 40, 32, 32},     {43, 32, 32, 32},
+    {40, 32, 43, 43},     {43, 47, 18, 43},     {43, 34, 34, 43},
+    {43, 18, 43, 43},     {43, 43, 32, 32},     {48, 48, 32, 32},
+    {32, 18, 18, 32},     {40, 40, 38, 47},     {32, 43, 32, 32},
+    {43, 43, 43, 38},     {38, 32, 32, 32},     {32, 32, 43, 43},
+    {43, 32, 38, 38},     {34, 34, 18, 40},     {40, 40, 34, 38},
+    {38, 43, 46, 46},     {43, 43, 34, 43},     {34, 43, 43, 43},
+    {40, 40, 40, 38},     {32, 43, 43, 43},     {38, 38, 40, 38},
+    {35, 32, 32, 32},     {47, 47, 38, 38},     {38, 38, 38, 43},
+    {32, 34, 43, 43},     {43, 43, 47, 43},     {43, 43, 43, 49},
+    {32, 32, 43, 49},     {43, 32, 49, 49},     {49, 43, 43, 43},
+    {43, 49, 49, 49},     {49, 43, 49, 49},     {40, 40, 48, 48},
+    {40, 34, 32, 32},     {32, 43, 49, 49},     {32, 38, 38, 32},
+    {32, 38, 32, 32},     {32, 38, 32, 38},     {38, 38, 32, 32},
+    {32, 32, 38, 38},     {43, 38, 38, 49},     {49, 38, 38, 49},
+    {49, 43, 32, 38},     {38, 38, 38, 49},     {32, 32, 38, 32},
+    {38, 38, 48, 48},     {32, 32, 46, 46},     {50, 50, 50, 50},
+    {50, 50, 18, 46},     {32, 40, 43, 38},     {38, 43, 43, 49},
+    {38, 32, 32, 38},     {43, 38, 49, 49},     {49, 43, 43, 38},
+    {43, 38, 38, 43},     {38, 43, 38, 38},     {32, 43, 40, 38},
+    {43, 43, 38, 43},     {43, 49, 38, 49},     {49, 43, 38, 38},
+    {32, 38, 38, 38},     {40, 46, 38, 38},     {38, 32, 43, 43},
+    {38, 43, 49, 49},     {43, 32, 49, 43},     {18, 32, 50, 50},
+    {38, 38, 43, 32},     {38, 38, 49, 49},     {43, 49, 49, 38},
+    {49, 38, 49, 49},     {50, 50, 50, 18},     {18, 18, 18, 18},
+    {18, 46, 18, 38},     {43, 32, 43, 43},     {49, 38, 43, 43},
+    {43, 38, 43, 43},     {38, 43, 43, 38},     {38, 38, 38, 40},
+    {40, 32, 32, 32},     {49, 49, 49, 49},     {49, 38, 43, 49},
+    {38, 49, 49, 38},     {38, 32, 32, 49},     {43, 43, 49, 49},
+    {49, 43, 32, 18},     {32, 32, 32, 49},     {50, 50, 50, 32},
+    {50, 18, 32, 32},     {38, 32, 38, 38},     {38, 38, 43, 38},
+    {49, 49, 43, 43},     {43, 38, 43, 38},     {32, 43, 32, 51},
+    {38, 38, 38, 46},     {32, 32, 34, 43},     {38, 32, 38, 32},
+    {32, 38, 34, 38},     {48, 48, 38, 38},     {32, 18, 18, 18},
+    {40, 40, 40, 18},     {40, 18, 18, 18},     {43, 43, 18, 18},
+    {48, 48, 50, 50},     {18, 43, 18, 43},     {18, 43, 52, 53},
+    {52, 53, 49, 49},     {43, 40, 43, 43},     {43, 38, 18, 18},
+    {18, 18, 43, 18},     {18, 38, 18, 18},     {18, 40, 40, 38},
+    {43, 49, 43, 43},     {49, 43, 43, 49},     {49, 43, 43, 32},
+    {32, 32, 49, 49},     {49, 32, 32, 49},     {49, 49, 32, 32},
+    {49, 43, 32, 49},     {48, 48, 49, 49},     {49, 43, 18, 18},
+    {29, 29, 38, 29},     {38, 29, 38, 38},     {25, 25, 25, 40},
+    {34, 25, 25, 25},     {54, 54, 54, 54},     {40, 55, 55, 55},
+    {55, 55, 55, 55},     {55, 55, 50, 50},     {50, 38, 38, 38},
+    {18, 18, 38, 38},     {29, 29, 38, 38},     {25, 25, 38, 38},
+    {45, 32, 32, 32},     {32, 18, 40, 32},     {13, 32, 32, 32},
+    {32, 32, 32, 52},     {53, 38, 38, 38},     {40, 40, 56, 56},
+    {56, 32, 32, 32},     {43, 49, 38, 38},     {49, 40, 40, 38},
+    {32, 38, 43, 43},     {43, 43, 49, 43},     {49, 49, 43, 49},
+    {40, 40, 40, 34},     {40, 40, 40, 46},     {32, 43, 38, 38},
+    {50, 50, 38, 38},     {40, 40, 45, 40},     {40, 40, 40, 43},
+    {32, 32, 32, 34},     {32, 57, 57, 32},     {32, 43, 32, 38},
+    {49, 49, 49, 43},     {18, 38, 38, 38},     {48, 48, 55, 38},
+    {38, 38, 18, 18},     {43, 49, 49, 43},     {38, 38, 40, 40},
+    {32, 49, 43, 49},     {43, 49, 43, 49},     {40, 40, 38, 38},
+    {43, 43, 44, 43},     {43, 38, 38, 38},     {49, 32, 32, 32},
+    {32, 38, 40, 40},     {18, 18, 18, 43},     {18, 40, 40, 40},
+    {43, 43, 49, 32},     {32, 49, 43, 43},     {49, 43, 49, 43},
+    {25, 29, 25, 38},     {43, 32, 32, 49},     {43, 43, 32, 38},
+    {34, 34, 34, 25},     {25, 25, 25, 34},     {25, 25, 29, 25},
+    {38, 29, 38, 29},     {33, 33, 33, 33},     {25, 38, 25, 25},
+    {33, 35, 25, 35},     {35, 35, 25, 25},     {33, 35, 35, 35},
+    {38, 38, 25, 25},     {38, 35, 35, 35},     {29, 35, 35, 35},
+    {33, 35, 35, 38},     {13, 13, 13, 13},     {13, 13, 13, 47},
+    {58, 58, 47, 47},     {59, 45, 45, 59},     {59, 59, 14, 40},
+    {60, 61, 52, 20},     {14, 14, 14, 40},     {14, 14, 14, 14},
+    {62, 63, 47, 47},     {47, 47, 47, 13},     {14, 40, 14, 14},
+    {40, 14, 40, 40},     {40, 20, 27, 14},     {40, 40, 14, 64},
+    {64, 40, 40, 40},     {42, 52, 53, 40},     {40, 40, 42, 40},
+    {40, 40, 40, 13},     {47, 38, 47, 47},     {65, 34, 38, 38},
+    {24, 65, 65, 65},     {65, 65, 66, 66},     {66, 67, 68, 36},
+    {65, 24, 24, 24},     {66, 67, 68, 34},     {46, 46, 46, 46},
+    {46, 69, 46, 46},     {15, 46, 46, 46},     {46, 38, 38, 38},
+    {43, 44, 44, 44},     {44, 43, 44, 44},     {44, 43, 43, 43},
+    {18, 18, 29, 22},     {18, 22, 18, 29},     {18, 22, 25, 29},
+    {29, 29, 25, 25},     {29, 29, 29, 31},     {18, 29, 22, 18},
+    {70, 29, 29, 29},     {29, 29, 18, 18},     {18, 22, 22, 18},
+    {29, 18, 30, 18},     {29, 18, 29, 30},     {29, 29, 71, 25},
+    {25, 32, 32, 32},     {32, 25, 18, 18},     {42, 42, 42, 42},
+    {42, 29, 25, 25},     {25, 25, 18, 42},     {18, 18, 25, 18},
+    {50, 50, 50, 28},     {28, 50, 50, 50},     {28, 28, 28, 50},
+    {72, 72, 72, 72},     {56, 56, 56, 56},     {72, 72, 56, 56},
+    {56, 56, 56, 29},     {25, 56, 56, 56},     {56, 28, 18, 18},
+    {23, 23, 23, 23},     {23, 22, 22, 22},     {22, 22, 42, 42},
+    {42, 18, 18, 42},     {18, 18, 42, 18},     {22, 22, 18, 18},
+    {18, 18, 42, 42},     {18, 18, 23, 18},     {23, 18, 18, 18},
+    {18, 18, 18, 22},     {23, 42, 73, 23},     {42, 42, 42, 73},
+    {23, 42, 42, 23},     {42, 42, 42, 23},     {42, 23, 42, 42},
+    {42, 42, 23, 42},     {42, 23, 73, 23},     {42, 23, 42, 23},
+    {23, 42, 23, 42},     {23, 23, 42, 42},     {23, 42, 42, 42},
+    {42, 42, 23, 23},     {52, 53, 52, 53},     {18, 18, 22, 18},
+    {18, 18, 74, 74},     {42, 42, 18, 18},     {18, 75, 76, 18},
+    {42, 18, 18, 18},     {18, 18, 18, 42},     {18, 74, 74, 74},
+    {74, 18, 18, 18},     {74, 18, 18, 74},     {18, 18, 18, 38},
+    {28, 28, 28, 28},     {22, 22, 22, 22},     {22, 22, 50, 28},
+    {18, 18, 22, 22},     {22, 22, 18, 22},     {18, 18, 22, 23},
+    {22, 23, 18, 18},     {22, 18, 18, 22},     {42, 77, 77, 42},
+    {18, 22, 18, 18},     {74, 74, 18, 18},     {22, 18, 22, 18},
+    {74, 74, 74, 74},     {22, 22, 22, 18},     {22, 22, 18, 23},
+    {18, 18, 18, 74},     {18, 74, 18, 18},     {18, 74, 74, 22},
+    {74, 74, 22, 22},     {22, 22, 74, 22},     {74, 22, 22, 22},
+    {22, 22, 74, 74},     {22, 74, 22, 22},     {74, 18, 74, 18},
+    {74, 74, 18, 74},     {52, 53, 28, 28},     {42, 52, 53, 42},
+    {42, 42, 4, 5},       {4, 5, 4, 5},         {4, 5, 52, 53},
+    {42, 42, 42, 52},     {53, 4, 5, 52},       {53, 52, 53, 52},
+    {53, 42, 42, 42},     {52, 53, 42, 42},     {18, 74, 22, 22},
+    {29, 25, 25, 29},     {34, 34, 29, 29},     {25, 18, 18, 18},
+    {18, 18, 18, 29},     {25, 29, 25, 43},     {43, 43, 29, 25},
+    {38, 40, 40, 40},     {40, 50, 40, 40},     {25, 25, 38, 25},
+    {38, 25, 38, 38},     {38, 38, 38, 34},     {40, 40, 20, 27},
+    {20, 27, 40, 40},     {40, 20, 27, 40},     {40, 40, 40, 45},
+    {20, 27, 52, 53},     {52, 53, 40, 40},     {40, 40, 40, 39},
+    {40, 40, 45, 45},     {45, 40, 52, 40},     {18, 18, 40, 40},
+    {40, 52, 53, 52},     {53, 45, 38, 38},     {40, 40, 52, 53},
+    {74, 74, 38, 74},     {74, 74, 38, 38},     {78, 79, 79, 79},
+    {74, 80, 54, 81},     {75, 76, 75, 76},     {75, 76, 74, 74},
+    {82, 75, 76, 76},     {74, 81, 81, 81},     {81, 81, 81, 81},
+    {81, 81, 83, 83},     {83, 83, 84, 84},     {82, 80, 80, 80},
+    {80, 80, 74, 74},     {81, 81, 81, 80},     {54, 79, 74, 18},
+    {38, 54, 54, 54},     {54, 54, 54, 38},     {38, 83, 83, 85},
+    {85, 80, 80, 54},     {82, 54, 54, 54},     {54, 54, 54, 86},
+    {80, 80, 80, 54},     {74, 74, 87, 87},     {87, 87, 74, 74},
+    {38, 38, 38, 74},     {74, 74, 74, 38},     {87, 87, 87, 87},
+    {74, 87, 87, 87},     {54, 80, 54, 54},     {54, 38, 38, 38},
+    {34, 40, 40, 40},     {29, 25, 32, 43},     {44, 44, 44, 40},
+    {43, 43, 40, 34},     {34, 34, 43, 43},     {32, 32, 56, 56},
+    {43, 43, 40, 40},     {35, 35, 35, 34},     {35, 35, 29, 25},
+    {34, 35, 35, 29},     {25, 29, 25, 32},     {38, 38, 29, 38},
+    {38, 34, 34, 34},     {34, 29, 25, 32},     {34, 34, 25, 32},
+    {32, 32, 43, 32},     {50, 50, 18, 18},     {46, 18, 38, 38},
+    {40, 40, 40, 32},     {40, 32, 32, 43},     {49, 40, 40, 40},
+    {40, 40, 38, 34},     {32, 43, 34, 32},     {32, 32, 32, 18},
+    {18, 18, 32, 49},     {43, 49, 32, 32},     {43, 32, 32, 43},
+    {32, 34, 40, 40},     {40, 40, 32, 34},     {34, 49, 43, 38},
+    {25, 25, 25, 35},     {25, 34, 35, 35},     {43, 49, 49, 40},
+    {88, 88, 88, 88},     {89, 89, 89, 89},     {54, 54, 90, 90},
+    {90, 90, 90, 90},     {25, 25, 25, 38},     {38, 38, 38, 25},
+    {38, 32, 43, 32},     {32, 42, 32, 32},     {32, 32, 35, 35},
+    {35, 35, 35, 18},     {18, 18, 18, 32},     {32, 32, 91, 91},
+    {91, 91, 91, 91},     {32, 32, 53, 52},     {18, 18, 32, 32},
+    {46, 18, 18, 18},     {79, 79, 79, 79},     {79, 79, 79, 75},
+    {76, 79, 38, 38},     {79, 82, 82, 92},     {92, 75, 76, 75},
+    {76, 75, 76, 75},     {76, 79, 79, 75},     {76, 79, 79, 79},
+    {79, 92, 92, 92},     {79, 79, 79, 38},     {82, 75, 76, 75},
+    {76, 75, 76, 79},     {79, 79, 77, 82},     {77, 77, 77, 38},
+    {79, 93, 79, 79},     {91, 32, 91, 32},     {91, 38, 91, 32},
+    {32, 38, 38, 47},     {38, 94, 94, 94},     {95, 94, 94, 94},
+    {96, 97, 94, 98},     {94, 99, 94, 94},     {100, 100, 100, 100},
+    {100, 100, 94, 94},   {98, 98, 98, 94},     {94, 101, 101, 101},
+    {101, 101, 101, 101}, {101, 101, 101, 96},  {94, 97, 102, 103},
+    {102, 104, 104, 104}, {104, 104, 104, 104}, {104, 104, 104, 96},
+    {98, 97, 98, 96},     {97, 105, 106, 107},  {105, 108, 109, 109},
+    {109, 109, 109, 109}, {110, 109, 109, 109}, {109, 109, 111, 111},
+    {109, 109, 109, 38},  {38, 38, 109, 109},   {109, 38, 38, 38},
+    {95, 95, 98, 102},    {112, 95, 95, 38},    {113, 114, 114, 114},
+    {114, 113, 113, 38},  {38, 47, 47, 47},     {18, 22, 38, 38},
+    {38, 38, 38, 50},     {38, 38, 38, 18},     {56, 50, 50, 50},
+    {50, 18, 18, 18},     {18, 18, 50, 50},     {18, 43, 38, 38},
+    {43, 50, 50, 50},     {32, 56, 32, 32},     {32, 32, 56, 38},
+    {32, 32, 38, 40},     {40, 56, 56, 56},     {56, 56, 38, 38},
+    {29, 29, 38, 25},     {25, 38, 38, 38},     {34, 34, 38, 34},
+    {34, 38, 34, 34},     {18, 50, 50, 50},     {32, 32, 50, 50},
+    {50, 50, 32, 32},     {38, 38, 50, 50},     {32, 50, 50, 40},
+    {32, 50, 50, 50},     {18, 32, 32, 32},     {32, 43, 43, 38},
+    {38, 50, 50, 50},     {32, 32, 34, 32},     {43, 43, 45, 34},
+    {38, 38, 42, 42},     {50, 50, 50, 38},     {32, 32, 38, 43},
+    {43, 45, 38, 38},     {32, 34, 32, 32},     {38, 35, 35, 43},
+    {50, 40, 40, 40},     {49, 43, 49, 32},     {50, 50, 48, 48},
+    {49, 43, 43, 40},     {40, 47, 40, 40},     {40, 40, 43, 38},
+    {38, 47, 38, 38},     {43, 43, 43, 32},     {43, 38, 48, 48},
+    {32, 49, 49, 32},     {40, 40, 32, 38},     {32, 40, 40, 40},
+    {40, 43, 43, 43},     {43, 40, 49, 43},     {48, 48, 32, 40},
+    {40, 40, 43, 32},     {32, 40, 38, 38},     {49, 49, 38, 38},
+    {38, 38, 43, 43},     {38, 38, 32, 38},     {43, 38, 49, 38},
+    {38, 49, 38, 49},     {49, 49, 49, 38},     {43, 32, 43, 32},
+    {40, 40, 38, 40},     {32, 49, 49, 49},     {43, 49, 43, 32},
+    {38, 40, 43, 32},     {32, 32, 40, 32},     {43, 40, 40, 40},
+    {38, 43, 49, 43},     {49, 49, 38, 49},     {49, 38, 38, 43},
+    {49, 32, 49, 43},     {43, 32, 40, 32},     {49, 38, 38, 38},
+    {43, 49, 32, 43},     {40, 32, 40, 40},     {38, 49, 43, 43},
+    {43, 43, 32, 43},     {43, 43, 38, 49},     {43, 43, 32, 49},
+    {43, 49, 43, 40},     {48, 48, 43, 38},     {18, 46, 46, 46},
+    {56, 56, 56, 38},     {32, 40, 40, 38},     {43, 40, 38, 38},
+    {40, 18, 38, 38},     {48, 48, 38, 50},     {50, 50, 38, 32},
+    {34, 34, 34, 32},     {50, 50, 50, 40},     {29, 38, 38, 25},
+    {43, 43, 43, 34},     {80, 80, 79, 80},     {83, 38, 38, 38},
+    {84, 84, 80, 80},     {81, 81, 81, 38},     {38, 38, 38, 54},
+    {54, 54, 38, 38},     {80, 80, 80, 80},     {38, 80, 80, 80},
+    {38, 80, 80, 38},     {38, 38, 54, 38},     {38, 54, 38, 38},
+    {18, 43, 43, 40},     {48, 48, 18, 18},     {38, 42, 42, 42},
+    {42, 42, 38, 38},     {43, 18, 18, 18},     {18, 49, 49, 43},
+    {18, 49, 49, 49},     {49, 49, 49, 47},     {47, 47, 47, 43},
+    {43, 43, 43, 18},     {18, 43, 43, 43},     {18, 18, 43, 43},
+    {43, 18, 38, 38},     {49, 49, 49, 18},     {43, 18, 18, 49},
+    {87, 87, 87, 50},     {38, 29, 29, 38},     {38, 25, 25, 25},
+    {29, 38, 25, 25},     {29, 38, 29, 38},     {38, 38, 29, 29},
+    {29, 115, 25, 25},    {25, 25, 25, 115},    {29, 29, 29, 115},
+    {25, 115, 25, 25},    {18, 43, 18, 18},     {43, 18, 18, 40},
+    {42, 38, 38, 38},     {25, 25, 32, 25},     {34, 34, 38, 38},
+    {38, 38, 32, 18},     {32, 32, 43, 38},     {32, 48, 48, 48},
+    {48, 48, 48, 38},     {38, 38, 32, 34},     {32, 38, 38, 50},
+    {46, 50, 50, 50},     {50, 50, 18, 50},     {38, 18, 18, 18},
+    {22, 74, 74, 74},     {74, 74, 74, 22},     {22, 18, 74, 38},
+    {74, 38, 38, 38},     {74, 18, 74, 74},     {74, 74, 74, 18},
+    {74, 74, 74, 85},     {85, 85, 85, 85},     {18, 18, 74, 18},
+    {18, 74, 74, 18},     {48, 48, 18, 38},     {54, 54, 54, 90},
+    {54, 90, 90, 90},     {90, 90, 38, 38},     {89, 89, 38, 38}};
 
-// General_Category=Mn|Me
-static constexpr UnicodeCharRange GeneratedCombiningCharacterRangesData[] = {
-    {0x0300, 0x036F},   {0x0483, 0x0489},   {0x0591, 0x05BD},
-    {0x05BF, 0x05BF},   {0x05C1, 0x05C2},   {0x05C4, 0x05C5},
-    {0x05C7, 0x05C9},   {0x0610, 0x061A},   {0x064B, 0x065F},
-    {0x0670, 0x0670},   {0x06D6, 0x06DC},   {0x06DF, 0x06E4},
-    {0x06E7, 0x06E8},   {0x06EA, 0x06ED},   {0x0711, 0x0711},
-    {0x0730, 0x074A},   {0x07A6, 0x07B0},   {0x07EB, 0x07F3},
-    {0x07FD, 0x07FD},   {0x0816, 0x0819},   {0x081B, 0x0823},
-    {0x0825, 0x0827},   {0x0829, 0x082D},   {0x0859, 0x085B},
-    {0x0897, 0x089F},   {0x08CA, 0x08E1},   {0x08E3, 0x0902},
-    {0x093A, 0x093A},   {0x093C, 0x093C},   {0x0941, 0x0948},
-    {0x094D, 0x094D},   {0x0951, 0x0957},   {0x0962, 0x0963},
-    {0x0981, 0x0981},   {0x09BC, 0x09BC},   {0x09C1, 0x09C4},
-    {0x09CD, 0x09CD},   {0x09E2, 0x09E3},   {0x09FE, 0x09FE},
-    {0x0A01, 0x0A02},   {0x0A3C, 0x0A3C},   {0x0A41, 0x0A42},
-    {0x0A47, 0x0A48},   {0x0A4B, 0x0A4D},   {0x0A51, 0x0A51},
-    {0x0A70, 0x0A71},   {0x0A75, 0x0A75},   {0x0A81, 0x0A82},
-    {0x0ABC, 0x0ABC},   {0x0AC1, 0x0AC5},   {0x0AC7, 0x0AC8},
-    {0x0ACD, 0x0ACD},   {0x0AE2, 0x0AE3},   {0x0AFA, 0x0AFF},
-    {0x0B01, 0x0B01},   {0x0B3C, 0x0B3C},   {0x0B3F, 0x0B3F},
-    {0x0B41, 0x0B44},   {0x0B4D, 0x0B4D},   {0x0B53, 0x0B56},
-    {0x0B62, 0x0B63},   {0x0B82, 0x0B82},   {0x0BC0, 0x0BC0},
-    {0x0BCD, 0x0BCD},   {0x0C00, 0x0C00},   {0x0C04, 0x0C04},
-    {0x0C3C, 0x0C3C},   {0x0C3E, 0x0C40},   {0x0C46, 0x0C48},
-    {0x0C4A, 0x0C4D},   {0x0C55, 0x0C56},   {0x0C62, 0x0C63},
-    {0x0C81, 0x0C81},   {0x0CBC, 0x0CBC},   {0x0CBF, 0x0CBF},
-    {0x0CC6, 0x0CC6},   {0x0CCC, 0x0CCD},   {0x0CE2, 0x0CE3},
-    {0x0D00, 0x0D01},   {0x0D3B, 0x0D3C},   {0x0D41, 0x0D44},
-    {0x0D4D, 0x0D4D},   {0x0D62, 0x0D63},   {0x0D81, 0x0D81},
-    {0x0DCA, 0x0DCA},   {0x0DD2, 0x0DD4},   {0x0DD6, 0x0DD6},
-    {0x0E31, 0x0E31},   {0x0E34, 0x0E3A},   {0x0E47, 0x0E4E},
-    {0x0EB1, 0x0EB1},   {0x0EB4, 0x0EBC},   {0x0EC8, 0x0ECE},
-    {0x0F18, 0x0F19},   {0x0F35, 0x0F35},   {0x0F37, 0x0F37},
-    {0x0F39, 0x0F39},   {0x0F71, 0x0F7E},   {0x0F80, 0x0F84},
-    {0x0F86, 0x0F87},   {0x0F8D, 0x0F97},   {0x0F99, 0x0FBC},
-    {0x0FC6, 0x0FC6},   {0x102D, 0x1030},   {0x1032, 0x1037},
-    {0x1039, 0x103A},   {0x103D, 0x103E},   {0x1058, 0x1059},
-    {0x105E, 0x1060},   {0x1071, 0x1074},   {0x1082, 0x1082},
-    {0x1085, 0x1086},   {0x108D, 0x108D},   {0x109D, 0x109D},
-    {0x135D, 0x135F},   {0x1712, 0x1714},   {0x1732, 0x1733},
-    {0x1752, 0x1753},   {0x1772, 0x1773},   {0x17B4, 0x17B5},
-    {0x17B7, 0x17BD},   {0x17C6, 0x17C6},   {0x17C9, 0x17D3},
-    {0x17DD, 0x17DD},   {0x180B, 0x180D},   {0x180F, 0x180F},
-    {0x1885, 0x1886},   {0x18A9, 0x18A9},   {0x1920, 0x1922},
-    {0x1927, 0x1928},   {0x1932, 0x1932},   {0x1939, 0x193B},
-    {0x1A17, 0x1A18},   {0x1A1B, 0x1A1B},   {0x1A56, 0x1A56},
-    {0x1A58, 0x1A5E},   {0x1A60, 0x1A60},   {0x1A62, 0x1A62},
-    {0x1A65, 0x1A6C},   {0x1A73, 0x1A7C},   {0x1A7F, 0x1A7F},
-    {0x1AB0, 0x1AF0},   {0x1B00, 0x1B03},   {0x1B34, 0x1B34},
-    {0x1B36, 0x1B3A},   {0x1B3C, 0x1B3C},   {0x1B42, 0x1B42},
-    {0x1B6B, 0x1B73},   {0x1B80, 0x1B81},   {0x1BA2, 0x1BA5},
-    {0x1BA8, 0x1BA9},   {0x1BAB, 0x1BAD},   {0x1BE6, 0x1BE6},
-    {0x1BE8, 0x1BE9},   {0x1BED, 0x1BED},   {0x1BEF, 0x1BF1},
-    {0x1C2C, 0x1C33},   {0x1C36, 0x1C37},   {0x1CD0, 0x1CD2},
-    {0x1CD4, 0x1CE0},   {0x1CE2, 0x1CE8},   {0x1CED, 0x1CED},
-    {0x1CF4, 0x1CF4},   {0x1CF8, 0x1CF9},   {0x1DC0, 0x1DFF},
-    {0x20D0, 0x20F0},   {0x2CEF, 0x2CF1},   {0x2D7F, 0x2D7F},
-    {0x2DE0, 0x2DFF},   {0x302A, 0x302D},   {0x3099, 0x309A},
-    {0xA66F, 0xA672},   {0xA674, 0xA67D},   {0xA69E, 0xA69F},
-    {0xA6F0, 0xA6F1},   {0xA802, 0xA802},   {0xA806, 0xA806},
-    {0xA80B, 0xA80B},   {0xA825, 0xA826},   {0xA82C, 0xA82C},
-    {0xA8C4, 0xA8C5},   {0xA8E0, 0xA8F1},   {0xA8FF, 0xA8FF},
-    {0xA926, 0xA92D},   {0xA947, 0xA951},   {0xA980, 0xA982},
-    {0xA9B3, 0xA9B3},   {0xA9B6, 0xA9B9},   {0xA9BC, 0xA9BD},
-    {0xA9E5, 0xA9E5},   {0xAA29, 0xAA2E},   {0xAA31, 0xAA32},
-    {0xAA35, 0xAA36},   {0xAA43, 0xAA43},   {0xAA4C, 0xAA4C},
-    {0xAA7C, 0xAA7C},   {0xAAB0, 0xAAB0},   {0xAAB2, 0xAAB4},
-    {0xAAB7, 0xAAB8},   {0xAABE, 0xAABF},   {0xAAC1, 0xAAC1},
-    {0xAAEC, 0xAAED},   {0xAAF6, 0xAAF6},   {0xABE5, 0xABE5},
-    {0xABE8, 0xABE8},   {0xABED, 0xABED},   {0xFB1E, 0xFB1E},
-    {0xFE00, 0xFE0F},   {0xFE20, 0xFE2F},   {0x101FD, 0x101FD},
-    {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03},
-    {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A},
-    {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x10D24, 0x10D27},
-    {0x10D69, 0x10D6D}, {0x10EAB, 0x10EAC}, {0x10ECB, 0x10ECF},
-    {0x10EF0, 0x10EFF}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85},
-    {0x11001, 0x11001}, {0x11038, 0x11046}, {0x11070, 0x11070},
-    {0x11073, 0x11074}, {0x1107F, 0x11081}, {0x110B3, 0x110B6},
-    {0x110B9, 0x110BA}, {0x110C2, 0x110C2}, {0x11100, 0x11102},
-    {0x11127, 0x1112B}, {0x1112D, 0x11134}, {0x11173, 0x11173},
-    {0x11180, 0x11181}, {0x111B6, 0x111BE}, {0x111C9, 0x111CC},
-    {0x111CF, 0x111CF}, {0x1122F, 0x11231}, {0x11234, 0x11234},
-    {0x11236, 0x11237}, {0x1123E, 0x1123E}, {0x11241, 0x11241},
-    {0x112DF, 0x112DF}, {0x112E3, 0x112EA}, {0x11300, 0x11301},
-    {0x1133B, 0x1133C}, {0x11340, 0x11340}, {0x11366, 0x1136C},
-    {0x11370, 0x11374}, {0x113BB, 0x113C0}, {0x113CE, 0x113CE},
-    {0x113D0, 0x113D0}, {0x113D2, 0x113D2}, {0x113E1, 0x113E2},
-    {0x11438, 0x1143F}, {0x11442, 0x11444}, {0x11446, 0x11446},
-    {0x1145E, 0x1145E}, {0x114B3, 0x114B8}, {0x114BA, 0x114BA},
-    {0x114BF, 0x114C0}, {0x114C2, 0x114C3}, {0x115B2, 0x115B5},
-    {0x115BC, 0x115BD}, {0x115BF, 0x115C0}, {0x115DC, 0x115DD},
-    {0x11633, 0x1163A}, {0x1163D, 0x1163D}, {0x1163F, 0x11640},
-    {0x116AB, 0x116AB}, {0x116AD, 0x116AD}, {0x116B0, 0x116B5},
-    {0x116B7, 0x116B7}, {0x1171D, 0x1171D}, {0x1171F, 0x1171F},
-    {0x11722, 0x11725}, {0x11727, 0x1172B}, {0x1182F, 0x11837},
-    {0x11839, 0x1183A}, {0x1193B, 0x1193C}, {0x1193E, 0x1193E},
-    {0x11943, 0x11943}, {0x119D4, 0x119D7}, {0x119DA, 0x119DB},
-    {0x119E0, 0x119E0}, {0x11A01, 0x11A0A}, {0x11A33, 0x11A38},
-    {0x11A3B, 0x11A3E}, {0x11A47, 0x11A47}, {0x11A51, 0x11A56},
-    {0x11A59, 0x11A5B}, {0x11A8A, 0x11A96}, {0x11A98, 0x11A99},
-    {0x11B60, 0x11B60}, {0x11B62, 0x11B64}, {0x11B66, 0x11B66},
-    {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3F, 0x11C3F},
-    {0x11C92, 0x11CA7}, {0x11CAA, 0x11CB0}, {0x11CB2, 0x11CB3},
-    {0x11CB5, 0x11CB6}, {0x11D31, 0x11D36}, {0x11D3A, 0x11D3A},
-    {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D45}, {0x11D47, 0x11D47},
-    {0x11D90, 0x11D91}, {0x11D95, 0x11D95}, {0x11D97, 0x11D97},
-    {0x11DF0, 0x11DF0}, {0x11EF3, 0x11EF4}, {0x11F00, 0x11F01},
-    {0x11F36, 0x11F3A}, {0x11F40, 0x11F40}, {0x11F42, 0x11F42},
-    {0x11F5A, 0x11F5A}, {0x13440, 0x13440}, {0x13447, 0x13455},
-    {0x1611E, 0x16129}, {0x1612D, 0x1612F}, {0x16AF0, 0x16AF4},
-    {0x16B30, 0x16B36}, {0x16F4F, 0x16F4F}, {0x16F8F, 0x16F92},
-    {0x16FE4, 0x16FE4}, {0x1BC9D, 0x1BC9E}, {0x1CF00, 0x1CF2D},
-    {0x1CF30, 0x1CF46}, {0x1D127, 0x1D128}, {0x1D167, 0x1D169},
-    {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD},
-    {0x1D242, 0x1D244}, {0x1D25B, 0x1D25C}, {0x1DA00, 0x1DA36},
-    {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84},
-    {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},
-    {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
-    {0x1E026, 0x1E02A}, {0x1E08F, 0x1E08F}, {0x1E130, 0x1E136},
-    {0x1E2AE, 0x1E2AE}, {0x1E2EC, 0x1E2EF}, {0x1E4EC, 0x1E4EF},
-    {0x1E5EE, 0x1E5EF}, {0x1E6E3, 0x1E6E3}, {0x1E6E6, 0x1E6E6},
-    {0x1E6EE, 0x1E6EF}, {0x1E6F5, 0x1E6F5}, {0x1E8D0, 0x1E8D6},
-    {0x1E944, 0x1E94A}, {0xE0100, 0xE01EF},
-};
-extern const CharRanges GeneratedCombiningCharacterRanges =
-    GeneratedCombiningCharacterRangesData;
+extern const CharProperties Lookup6[116] = {
+    {CharCategory::Cc, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Zs, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Po, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Sc, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Ps, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Pe, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Sm, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Pd, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Nd, EastAsianWidth::Na, false, true, false, false},
+    {CharCategory::Lu, EastAsianWidth::Na, true, true, false, false},
+    {CharCategory::Sk, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Pc, EastAsianWidth::Na, false, true, false, false},
+    {CharCategory::Ll, EastAsianWidth::Na, true, true, false, false},
+    {CharCategory::Zs, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Po, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::Sc, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::So, EastAsianWidth::Na, false, false, false, false},
+    {CharCategory::Sk, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::So, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Lo, EastAsianWidth::A, true, true, false, false},
+    {CharCategory::Pi, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Cf, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::So, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::Sm, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::No, EastAsianWidth::A, false, false, false, true},
+    {CharCategory::Ll, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::Po, EastAsianWidth::A, false, true, false, false},
+    {CharCategory::Pf, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::No, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::Lu, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::Lu, EastAsianWidth::A, true, true, false, false},
+    {CharCategory::Ll, EastAsianWidth::A, true, true, false, false},
+    {CharCategory::Lo, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::Lt, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::Lm, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::Sk, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Lm, EastAsianWidth::A, true, true, false, false},
+    {CharCategory::Mn, EastAsianWidth::A, false, true, false, false},
+    {CharCategory::Cn, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Lm, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Po, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Po, EastAsianWidth::N, false, true, false, false},
+    {CharCategory::Sm, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Mn, EastAsianWidth::N, false, true, false, false},
+    {CharCategory::Me, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Pd, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Sc, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Cf, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Nd, EastAsianWidth::N, false, true, false, false},
+    {CharCategory::Mc, EastAsianWidth::N, false, true, false, false},
+    {CharCategory::No, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Lo, EastAsianWidth::N, false, true, false, false},
+    {CharCategory::Ps, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Pe, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Lo, EastAsianWidth::W, true, true, false, false},
+    {CharCategory::No, EastAsianWidth::N, false, true, false, false},
+    {CharCategory::Nl, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::Mn, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::Cf, EastAsianWidth::N, false, true, false, false},
+    {CharCategory::Pd, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::Pi, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::Pf, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::Zl, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Zp, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Pc, EastAsianWidth::N, false, true, false, false},
+    {CharCategory::No, EastAsianWidth::N, false, false, false, true},
+    {CharCategory::Sm, EastAsianWidth::N, false, false, false, true},
+    {CharCategory::Ps, EastAsianWidth::N, false, false, false, true},
+    {CharCategory::Pe, EastAsianWidth::N, false, false, false, true},
+    {CharCategory::Sc, EastAsianWidth::H, false, false, false, false},
+    {CharCategory::Sm, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::So, EastAsianWidth::N, true, true, false, false},
+    {CharCategory::Nl, EastAsianWidth::A, true, true, false, false},
+    {CharCategory::Sm, EastAsianWidth::A, false, false, true, true},
+    {CharCategory::So, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Ps, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Pe, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Sm, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Zs, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::Po, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Lm, EastAsianWidth::W, true, true, false, false},
+    {CharCategory::Nl, EastAsianWidth::W, true, true, false, false},
+    {CharCategory::Pd, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Mn, EastAsianWidth::W, false, true, false, false},
+    {CharCategory::Mc, EastAsianWidth::W, false, true, false, false},
+    {CharCategory::Sk, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Po, EastAsianWidth::W, false, true, false, false},
+    {CharCategory::No, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Cs, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Co, EastAsianWidth::A, false, false, false, false},
+    {CharCategory::Cn, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Lo, EastAsianWidth::N, false, false, false, false},
+    {CharCategory::Pc, EastAsianWidth::W, false, true, false, false},
+    {CharCategory::Sc, EastAsianWidth::W, false, false, false, false},
+    {CharCategory::Po, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::Sc, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::Ps, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::Pe, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::Sm, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::Pd, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::Nd, EastAsianWidth::F, false, true, false, false},
+    {CharCategory::Lu, EastAsianWidth::F, true, true, false, false},
+    {CharCategory::Sk, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::Pc, EastAsianWidth::F, false, true, false, false},
+    {CharCategory::Ll, EastAsianWidth::F, true, true, false, false},
+    {CharCategory::Po, EastAsianWidth::H, false, false, false, false},
+    {CharCategory::Ps, EastAsianWidth::H, false, false, false, false},
+    {CharCategory::Pe, EastAsianWidth::H, false, false, false, false},
+    {CharCategory::Po, EastAsianWidth::H, false, true, false, false},
+    {CharCategory::Lo, EastAsianWidth::H, true, true, false, false},
+    {CharCategory::Lm, EastAsianWidth::H, true, true, false, false},
+    {CharCategory::Lm, EastAsianWidth::H, false, true, false, false},
+    {CharCategory::So, EastAsianWidth::F, false, false, false, false},
+    {CharCategory::So, EastAsianWidth::H, false, false, false, false},
+    {CharCategory::Sm, EastAsianWidth::H, false, false, false, false},
+    {CharCategory::Sm, EastAsianWidth::N, false, false, true, true}};
 
-// East_Asian_Width=F|W
-static constexpr UnicodeCharRange GeneratedDoubleWidthCharacterRangesData[] = {
-    {0x1100, 0x115F},   {0x231A, 0x231B},   {0x2329, 0x232A},
-    {0x23E9, 0x23EC},   {0x23F0, 0x23F0},   {0x23F3, 0x23F3},
-    {0x25FD, 0x25FE},   {0x2614, 0x2615},   {0x2630, 0x2637},
-    {0x2648, 0x2653},   {0x267F, 0x267F},   {0x268A, 0x268F},
-    {0x2693, 0x2693},   {0x26A1, 0x26A1},   {0x26AA, 0x26AB},
-    {0x26BD, 0x26BE},   {0x26C4, 0x26C5},   {0x26CE, 0x26CE},
-    {0x26D4, 0x26D4},   {0x26EA, 0x26EA},   {0x26F2, 0x26F3},
-    {0x26F5, 0x26F5},   {0x26FA, 0x26FA},   {0x26FD, 0x26FD},
-    {0x2705, 0x2705},   {0x270A, 0x270B},   {0x2728, 0x2728},
-    {0x274C, 0x274C},   {0x274E, 0x274E},   {0x2753, 0x2755},
-    {0x2757, 0x2757},   {0x2795, 0x2797},   {0x27B0, 0x27B0},
-    {0x27BF, 0x27BF},   {0x2B1B, 0x2B1C},   {0x2B50, 0x2B50},
-    {0x2B55, 0x2B55},   {0x2E80, 0x2E99},   {0x2E9B, 0x2EF3},
-    {0x2F00, 0x2FD5},   {0x2FF0, 0x303E},   {0x3041, 0x3096},
-    {0x3099, 0x30FF},   {0x3105, 0x312F},   {0x3131, 0x318E},
-    {0x3190, 0x31E5},   {0x31EF, 0x321E},   {0x3220, 0x3247},
-    {0x3250, 0xA48C},   {0xA490, 0xA4C6},   {0xA960, 0xA97C},
-    {0xAC00, 0xD7A3},   {0xF900, 0xFAFF},   {0xFE10, 0xFE19},
-    {0xFE30, 0xFE52},   {0xFE54, 0xFE66},   {0xFE68, 0xFE6B},
-    {0xFF01, 0xFF60},   {0xFFE0, 0xFFE6},   {0x16FE0, 0x16FE4},
-    {0x16FF0, 0x16FF6}, {0x17000, 0x18CDA}, {0x18CFF, 0x18D20},
-    {0x18D80, 0x18DF2}, {0x18E00, 0x19191}, {0x191A0, 0x191D2},
-    {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE},
-    {0x1B000, 0x1B128}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152},
-    {0x1B155, 0x1B155}, {0x1B164, 0x1B168}, {0x1B170, 0x1B2FB},
-    {0x1D300, 0x1D356}, {0x1D360, 0x1D376}, {0x1F004, 0x1F004},
-    {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
-    {0x1F1AE, 0x1F1AE}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23B},
-    {0x1F240, 0x1F248}, {0x1F250, 0x1F251}, {0x1F260, 0x1F265},
-    {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, {0x1F337, 0x1F37C},
-    {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3},
-    {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E},
-    {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D},
-    {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, {0x1F57A, 0x1F57A},
-    {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F},
-    {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2},
-    {0x1F6D5, 0x1F6D9}, {0x1F6DC, 0x1F6DF}, {0x1F6EB, 0x1F6EC},
-    {0x1F6F4, 0x1F6FC}, {0x1F7DA, 0x1F7DA}, {0x1F7E0, 0x1F7EB},
-    {0x1F7F0, 0x1F7F0}, {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945},
-    {0x1F947, 0x1F9FF}, {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FAC6},
-    {0x1FAC8, 0x1FAC8}, {0x1FACC, 0x1FADD}, {0x1FADF, 0x1FAEB},
-    {0x1FAEF, 0x1FAFA}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
-};
-extern const CharRanges GeneratedDoubleWidthCharacterRanges =
-    GeneratedDoubleWidthCharacterRangesData;
-
-} // namespace llvm::sys::unicode
+} // namespace llvm::sys::unicode::CharPropertyTables
diff --git a/llvm/lib/Support/UnicodeCharSetsGenerated.h b/llvm/lib/Support/UnicodeCharSetsGenerated.h
new file mode 100644
index 00000000000000..df9d6f56714437
--- /dev/null
+++ b/llvm/lib/Support/UnicodeCharSetsGenerated.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//  
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information. 
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//  
+//===----------------------------------------------------------------------===//
+//  
+// This file was generated by llvm/utils/gen_unicode_charsetdata.py
+// from the Unicode 18.0.0 Character Database. Do not edit manually.
+//  
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Unicode.h"
+
+namespace llvm::sys::unicode::CharPropertyTables {
+
+extern const std::uint8_t Lookup1[272];
+
+extern const std::uint8_t Lookup2[36][16];
+
+extern const std::uint16_t Lookup3[176][16];
+
+extern const std::uint16_t Lookup4[845][4];
+
+extern const std::uint8_t Lookup5[741][4];
+
+extern const CharProperties Lookup6[116];
+
+} // namespace llvm::sys::unicode::CharPropertyTables
diff --git a/llvm/utils/UnicodeData/CMakeLists.txt b/llvm/utils/UnicodeData/CMakeLists.txt
index 2cda951ff96673..6fbc0b9311cc46 100644
--- a/llvm/utils/UnicodeData/CMakeLists.txt
+++ b/llvm/utils/UnicodeData/CMakeLists.txt
@@ -7,30 +7,3 @@ add_llvm_utility(UnicodeNameMappingGenerator
     UnicodeNameMappingGenerator.cpp
     PARTIAL_SOURCES_INTENDED
 )
-
-if (NOT LLVM_ENABLE_LIBXML2)
-  message(STATUS "Not building UnicodeCharSetsGenerator because libxml2 is not available")
-  return()
-endif ()
-
-if (LLVM_USE_STATIC_LIBXML2)
-  set(libxml2_library LibXml2::LibXml2Static)
-else()
-  set(libxml2_library LibXml2::LibXml2)
-endif()
-
-cmake_push_check_state()
-list(APPEND CMAKE_REQUIRED_LIBRARIES ${libxml2_library})
-check_cxx_symbol_exists(LIBXML_READER_ENABLED libxml/xmlversion.h HAVE_LIBXML_READER)
-cmake_pop_check_state()
-
-if (NOT HAVE_LIBXML_READER)
-  message(STATUS "Not building UnicodeCharSetsGenerator because libxml2 reader is not enabled")
-  return()
-endif ()
-
-add_llvm_utility(UnicodeCharSetsGenerator
-    UnicodeCharSetsGenerator.cpp
-    PARTIAL_SOURCES_INTENDED
-)
-target_link_libraries(UnicodeCharSetsGenerator PRIVATE ${libxml2_library})
diff --git a/llvm/utils/UnicodeData/UnicodeCharSetsGenerator.cpp b/llvm/utils/UnicodeData/UnicodeCharSetsGenerator.cpp
deleted file mode 100644
index 58b305a4fa32ad..00000000000000
--- a/llvm/utils/UnicodeData/UnicodeCharSetsGenerator.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-//===--- UnicodeCharSetsGenerator.cpp - Unicode character sets generator --===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is used to generate clang/lib/Lex/UnicodeCharSetsGenerated.cpp and
-// llvm/lib/Support/UnicodeCharSetsGenerated.cpp from the XML representation of
-// the Unicode Character Database available at
-// https://www.unicode.org/Public/UCD/latest/ucdxml/
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/InitLLVM.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/UnicodeCharRanges.h"
-#include "llvm/Support/WithColor.h"
-
-#include <libxml/xmlreader.h>
-#include <vector>
-
-using namespace llvm;
-
-static cl::opt<std::string> UCDFile(cl::Positional, cl::Required,
-                                    cl::desc("<UCD XML file>"));
-static cl::opt<std::string> ClangOutput(cl::Positional, cl::Required,
-                                        cl::desc("<clang output file>"));
-static cl::opt<std::string> LLVMOutput(cl::Positional, cl::Required,
-                                       cl::desc("<LLVM output file>"));
-
-static constexpr unsigned CodePointCount = 0x110000;
-
-static constexpr StringLiteral FileHeader = R"(
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file was generated by llvm/utils/UnicodeData/UnicodeCharSetsGenerator
-// from the Unicode {0} Character Database. Do not edit manually.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/UnicodeCharRanges.h"
-
-using llvm::sys::UnicodeCharRange;
-using CharRanges = llvm::sys::UnicodeCharSet::CharRanges;
-
-namespace {1} {{
-)";
-
-[[noreturn]] static void error(const Twine &Message) {
-  WithColor::error() << Message << '\n';
-  exit(EXIT_FAILURE);
-}
-
-namespace {
-struct Properties {
-  unsigned XIDStart : 1;
-  unsigned XIDContinue : 1;
-  unsigned MathStart : 1;
-  unsigned MathContinue : 1;
-  unsigned Char : 1;
-  unsigned Printable : 1;
-  unsigned Control : 1;
-  unsigned Format : 1;
-  unsigned Combining : 1;
-  unsigned DoubleWidth : 1;
-};
-
-struct CharacterDatabase {
-  std::string Version;
-  std::vector<Properties> Chars;
-};
-
-struct XmlDeleter {
-  void operator()(xmlTextReader *Reader) { xmlFreeTextReader(Reader); }
-  void operator()(xmlChar *Ptr) { xmlFree(Ptr); }
-};
-} // namespace
-
-static StringRef fromXmlChar(const xmlChar *S) {
-  return S ? StringRef(reinterpret_cast<const char *>(S)) : StringRef();
-}
-
-static bool isPrintableGC(StringRef GC) {
-  return GC == "Zs" || (!GC.empty() && StringRef("LMNPS").contains(GC.front()));
-}
-
-// Loads the properties we care about from the flat XML representation of the
-// UCD, which describes each code point, or range of code points, with all of
-// its properties, e.g.
-//   <char cp="0041" age="1.1" na="LATIN CAPITAL LETTER A" gc="Lu" ... />
-static CharacterDatabase loadDatabase(StringRef Path) {
-  std::unique_ptr<xmlTextReader, XmlDeleter> Reader(xmlReaderForFile(
-      Path.str().c_str(), /*encoding=*/nullptr, XML_PARSE_NONET));
-  if (!Reader)
-    error(Path + ": cannot open file");
-
-  CharacterDatabase Database;
-  Database.Chars.resize(CodePointCount);
-  int Status;
-  while ((Status = xmlTextReaderRead(Reader.get())) == 1) {
-    if (xmlTextReaderNodeType(Reader.get()) != XML_READER_TYPE_ELEMENT)
-      continue;
-    StringRef Element = fromXmlChar(xmlTextReaderConstLocalName(Reader.get()));
-    if (Element == "description") {
-      // <description>Unicode 18.0.0</description>
-      std::unique_ptr<xmlChar, XmlDeleter> Description(
-          xmlTextReaderReadString(Reader.get()));
-      if (Description)
-        Database.Version = fromXmlChar(Description.get())
-                               .rsplit(' ')
-                               .second.rsplit('.')
-                               .first.str();
-      continue;
-    }
-    if (!is_contained({"char", "reserved", "noncharacter", "surrogate"},
-                      Element))
-      continue;
-
-    unsigned First = 0, Last = 0;
-    bool HasRange = false;
-    unsigned Found = 0;
-    Properties P = {};
-    while (xmlTextReaderMoveToNextAttribute(Reader.get()) == 1) {
-      StringRef Name = fromXmlChar(xmlTextReaderConstLocalName(Reader.get()));
-      StringRef Value = fromXmlChar(xmlTextReaderConstValue(Reader.get()));
-      P.Char = Element == "char";
-      if (Name == "cp" || Name == "first-cp") {
-        if (Value.getAsInteger(16, First))
-          break;
-        if (Name == "cp")
-          Last = First;
-        HasRange = true;
-      } else if (Name == "last-cp") {
-        if (Value.getAsInteger(16, Last))
-          HasRange = false;
-      } else if (Name == "XIDS") {
-        P.XIDStart = Value == "Y";
-        ++Found;
-      } else if (Name == "XIDC") {
-        P.XIDContinue = Value == "Y";
-        ++Found;
-      } else if (Name == "ID_Compat_Math_Start") {
-        P.MathStart = Value == "Y";
-        ++Found;
-      } else if (Name == "ID_Compat_Math_Continue") {
-        P.MathContinue = Value == "Y";
-        ++Found;
-      } else if (Name == "gc") {
-        P.Printable = isPrintableGC(Value);
-        P.Control = Value == "Cc";
-        P.Format = Value == "Cf";
-        P.Combining = Value == "Mn" || Value == "Me";
-        ++Found;
-      } else if (Name == "ea") {
-        P.DoubleWidth = Value == "F" || Value == "W";
-        ++Found;
-      }
-    }
-
-    if (!HasRange || First > Last || Last >= CodePointCount || Found != 6)
-      error(Path + ":" + Twine(xmlTextReaderGetParserLineNumber(Reader.get())) +
-            ": invalid <" + Element + "> element");
-    llvm::fill(MutableArrayRef(Database.Chars).slice(First, Last - First + 1),
-               P);
-  }
-  if (Status != 0)
-    error(Path + ": failed to parse XML");
-  if (Database.Version.empty())
-    error(Path + ": missing Unicode version");
-  return Database;
-}
-
-template <typename Predicate>
-static void emitTable(raw_ostream &OS, StringRef Name, StringRef Description,
-                      ArrayRef<Properties> Chars, Predicate Pred) {
-  SmallVector<sys::UnicodeCharRange> Ranges;
-  for (unsigned CodePoint = 0, E = Chars.size(); CodePoint != E; ++CodePoint) {
-    if (!Pred(Chars[CodePoint]))
-      continue;
-    if (!Ranges.empty() && Ranges.back().Upper + 1 == CodePoint)
-      Ranges.back().Upper = CodePoint;
-    else
-      Ranges.push_back({CodePoint, CodePoint});
-  }
-
-  OS << "\n// " << Description << "\nstatic constexpr UnicodeCharRange " << Name
-     << "Data[] = {\n";
-  for (sys::UnicodeCharRange Range : Ranges)
-    OS << formatv("    {{{0:X4}, {1:X4}},\n", Range.Lower, Range.Upper);
-  OS << "};\nextern const CharRanges " << Name << " = " << Name << "Data;\n";
-}
-
-static void writeFile(StringRef Path, StringRef Namespace, StringRef Version,
-                      function_ref<void(raw_ostream &)> EmitTables) {
-  std::error_code EC;
-  ToolOutputFile Out(Path, EC, sys::fs::OF_Text);
-  if (EC)
-    error(Path + ": " + EC.message());
-
-  Out.os() << formatv(FileHeader.drop_front().data(), Version, Namespace);
-  EmitTables(Out.os());
-  Out.os() << "\n} // namespace " << Namespace << '\n';
-  Out.keep();
-}
-
-int main(int argc, char **argv) {
-  InitLLVM X(argc, argv);
-  cl::ParseCommandLineOptions(
-      argc, argv,
-      "Unicode character sets generator\n\n"
-      "  Generates clang/lib/Lex/UnicodeCharSetsGenerated.cpp and\n"
-      "  llvm/lib/Support/UnicodeCharSetsGenerated.cpp from the flat XML\n"
-      "  representation of the Unicode Character Database, which can be\n"
-      "  downloaded from https://www.unicode.org/Public/UCD/latest/ucdxml/\n"
-      "  The generated files must then be formatted with clang-format.\n");
-
-  CharacterDatabase UCD = loadDatabase(UCDFile);
-  ArrayRef<Properties> Chars = UCD.Chars;
-
-  writeFile(ClangOutput, "clang", UCD.Version, [&](raw_ostream &OS) {
-    emitTable(OS, "GeneratedXIDStartRanges", "XID_Start", Chars,
-              [](Properties P) { return P.XIDStart; });
-    emitTable(OS, "GeneratedXIDContinueRanges",
-              "XID_Continue, excluding XID_Start", Chars,
-              [](Properties P) { return P.XIDContinue && !P.XIDStart; });
-    emitTable(OS, "GeneratedMathematicalNotationProfileIDStartRanges",
-              "ID_Compat_Math_Start", Chars,
-              [](Properties P) { return P.MathStart; });
-    emitTable(OS, "GeneratedMathematicalNotationProfileIDContinueRanges",
-              "ID_Compat_Math_Continue, excluding ID_Compat_Math_Start", Chars,
-              [](Properties P) { return P.MathContinue && !P.MathStart; });
-  });
-  writeFile(
-      LLVMOutput, "llvm::sys::unicode", UCD.Version, [&](raw_ostream &OS) {
-        emitTable(OS, "GeneratedCharacterRanges", "Characters", Chars,
-                  [](Properties P) { return P.Char; });
-        emitTable(OS, "GeneratedPrintableRanges",
-                  "General_Category=L|M|N|P|S|Zs", Chars,
-                  [](Properties P) { return P.Printable; });
-        emitTable(OS, "GeneratedControlCharacterRanges", "General_Category=Cc",
-                  Chars, [](Properties P) { return P.Control; });
-        emitTable(OS, "GeneratedFormatCharacterRanges", "General_Category=Cf",
-                  Chars, [](Properties P) { return P.Format; });
-        emitTable(OS, "GeneratedCombiningCharacterRanges",
-                  "General_Category=Mn|Me", Chars,
-                  [](Properties P) { return P.Combining; });
-        emitTable(OS, "GeneratedDoubleWidthCharacterRanges",
-                  "East_Asian_Width=F|W", Chars,
-                  [](Properties P) { return P.DoubleWidth; });
-      });
-}
diff --git a/llvm/utils/generate-unicode-charsetdata.py b/llvm/utils/generate-unicode-charsetdata.py
new file mode 100644
index 00000000000000..e1acc8b56e013e
--- /dev/null
+++ b/llvm/utils/generate-unicode-charsetdata.py
@@ -0,0 +1,103 @@
+'''Generates the UnicodeCharSetsGenerated.cpp/.h files.
+
+Given the Unicode character database in xml form (ucd.all.flat.xml), this
+script generates the UnicodeCharSetsGenerated.cpp/.h files from it.'''
+
+import argparse
+import os
+import xml.etree.ElementTree as ET
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument('--database', default='ucd.all.flat.xml', help='the database to convert (default ucd.all.flat.xml)')
+    config = parser.parse_args()
+
+    tree = ET.parse(config.database)
+    root = tree.getroot()
+    description = root.find('{http://www.unicode.org/ns/2003/ucd/1.0}description').text
+    repertoire = [None] * 0x110000
+    for elem in root.find('{http://www.unicode.org/ns/2003/ucd/1.0}repertoire').findall('*'):
+        attrib = elem.attrib
+        props = (
+            attrib['gc'],
+            attrib['ea'],
+            attrib['XIDS'] == 'Y',
+            attrib['XIDC'] == 'Y',
+            attrib['ID_Compat_Math_Start'] == 'Y',
+            attrib['ID_Compat_Math_Continue'] == 'Y',
+        )
+        if 'cp' in attrib:
+            repertoire[int(attrib['cp'], 16)] = props
+        else:
+            for cp in range(int(attrib['first-cp'], 16), int(attrib['last-cp'], 16) + 1):
+                repertoire[cp] = props
+
+    def make_lookup_table(table, n):
+        lookup_table = ([], {})
+        for i in range(0, len(table), n):
+            lookup_table[0].append(lookup_table[1].setdefault(tuple(table[i:i+n]), len(lookup_table[1])))
+        return (lookup_table[0], list(lookup_table[1].keys()))
+
+    (n1, n2, n3, n4) = (4, 4, 16, 16)
+    lookup_table_1 = make_lookup_table(repertoire, 1)
+    lookup_table_2 = make_lookup_table(lookup_table_1[0], n1)
+    lookup_table_3 = make_lookup_table(lookup_table_2[0], n2)
+    lookup_table_4 = make_lookup_table(lookup_table_3[0], n3)
+    lookup_table_5 = make_lookup_table(lookup_table_4[0], n4)
+
+    dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib', 'Support')
+    for (header, file) in ((False, 'UnicodeCharSetsGenerated.cpp'), (True, 'UnicodeCharSetsGenerated.h')):
+        with open(os.path.join(dir, file), 'w') as f:
+            b = ("false", "true")
+            f.write(f'''\
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file was generated by llvm/utils/gen_unicode_charsetdata.py
+// from the {description} Character Database. Do not edit manually.
+//
+//===----------------------------------------------------------------------===//
+
+{'' if header else '''#include "UnicodeCharSetsGenerated.h"
+'''}#include "llvm/Support/Unicode.h"
+
+namespace llvm::sys::unicode::CharPropertyTables {{
+
+extern const std::uint8_t Lookup1[{len(lookup_table_5[0])}]{'' if header else f''' =
+{{{
+    ",\n ".join(str(x) for x in lookup_table_5[0])
+}}}'''};
+
+extern const std::uint8_t Lookup2[{len(lookup_table_5[1])}][{n4}]{'' if header else f''' =
+{{{{{
+    "},\n {".join(", ".join(str(x) for x in y) for y in lookup_table_5[1])
+}}}}}'''};
+
+extern const std::uint16_t Lookup3[{len(lookup_table_4[1])}][{n3}]{'' if header else f''' =
+{{{{{
+    "},\n {".join(", ".join(str(x) for x in y) for y in lookup_table_4[1])
+}}}}}'''};
+
+extern const std::uint16_t Lookup4[{len(lookup_table_3[1])}][{n2}]{"" if header else f''' =
+{{{{{
+    "},\n {".join(", ".join(str(x) for x in y) for y in lookup_table_3[1])
+}}}}}'''};
+
+extern const std::uint8_t Lookup5[{len(lookup_table_2[1])}][{n1}]{"" if header else f''' =
+{{{{{
+    '},\n {'.join(', '.join(str(x) for x in y) for y in lookup_table_2[1])
+}}}}}'''};
+
+extern const CharProperties Lookup6[{len(lookup_table_1[1])}]{'' if header else f''' =
+{{{{{'},\n {'.join(f'CharCategory::{x[0]}, EastAsianWidth::{x[1]}, {b[x[2]]}, {b[x[3]]}, {b[x[4]]}, {b[x[5]]}' for y in lookup_table_1[1] for x in y)}}}}}'''};
+
+}} // namespace llvm::sys::unicode::CharPropertyTables
+''')
+
+if __name__ == '__main__':
+    main()

>From d2442c871ca621b0226cf7c5a7005225a5441b98 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Tue, 20 Oct 2026 19:34:18 +0100
Subject: [PATCH 2/6] clang-format

---
 llvm/lib/Support/UnicodeCharSetsGenerated.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Support/UnicodeCharSetsGenerated.h b/llvm/lib/Support/UnicodeCharSetsGenerated.h
index df9d6f56714437..44f283f44bb630 100644
--- a/llvm/lib/Support/UnicodeCharSetsGenerated.h
+++ b/llvm/lib/Support/UnicodeCharSetsGenerated.h
@@ -1,14 +1,14 @@
 //===----------------------------------------------------------------------===//
-//  
+//
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information. 
+// See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//  
+//
 //===----------------------------------------------------------------------===//
-//  
+//
 // This file was generated by llvm/utils/gen_unicode_charsetdata.py
 // from the Unicode 18.0.0 Character Database. Do not edit manually.
-//  
+//
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Unicode.h"

>From b2bff0b1e0e28574b1d92d5789358c25159f2762 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Tue, 20 Oct 2026 19:39:44 +0100
Subject: [PATCH 3/6] Remove LLVM_ABI from now-inline functions

---
 llvm/include/llvm/Support/Unicode.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Support/Unicode.h b/llvm/include/llvm/Support/Unicode.h
index 05d2c209f1cc64..b17fe441f2e11a 100644
--- a/llvm/include/llvm/Support/Unicode.h
+++ b/llvm/include/llvm/Support/Unicode.h
@@ -106,7 +106,7 @@ LLVM_ABI LLVM_READONLY const CharProperties &charProperties(int UCS);
 /// returns true for any code point defined by Unicode as a character, false for
 /// any code point defined as a non-character, as reserved, as a surrogate code
 /// point, or not defined at all.
-LLVM_ABI inline bool isCharacter(int UCS) {
+inline bool isCharacter(int UCS) {
   return charProperties(UCS).isCharacter();
 }
 
@@ -120,17 +120,17 @@ LLVM_ABI inline bool isCharacter(int UCS) {
 /// displayed on most terminals.
 ///
 /// \return true if the character is considered printable.
-LLVM_ABI inline bool isPrintable(int UCS) {
+inline bool isPrintable(int UCS) {
   return charProperties(UCS).isPrintable(UCS);
 }
 
 // Control codepoints are codepoints in the Cc category.
-LLVM_ABI inline bool isControl(int UCS) {
+inline bool isControl(int UCS) {
   return charProperties(UCS).isControl();
 }
 
 // Formatting codepoints are codepoints in the Cf category.
-LLVM_ABI inline bool isFormatting(int UCS) {
+inline bool isFormatting(int UCS) {
   return charProperties(UCS).isFormatting();
 }
 

>From 672dd21bb51cce2297fc8609a314c92c7ef425b8 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Tue, 20 Oct 2026 20:11:12 +0100
Subject: [PATCH 4/6] More clang-format

---
 llvm/include/llvm/Support/Unicode.h | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/Support/Unicode.h b/llvm/include/llvm/Support/Unicode.h
index b17fe441f2e11a..2abe61ed9edcdd 100644
--- a/llvm/include/llvm/Support/Unicode.h
+++ b/llvm/include/llvm/Support/Unicode.h
@@ -106,9 +106,7 @@ LLVM_ABI LLVM_READONLY const CharProperties &charProperties(int UCS);
 /// returns true for any code point defined by Unicode as a character, false for
 /// any code point defined as a non-character, as reserved, as a surrogate code
 /// point, or not defined at all.
-inline bool isCharacter(int UCS) {
-  return charProperties(UCS).isCharacter();
-}
+inline bool isCharacter(int UCS) { return charProperties(UCS).isCharacter(); }
 
 /// Determines if a character is likely to be displayed correctly on the
 /// terminal. Exact implementation would have to depend on the specific
@@ -125,14 +123,10 @@ inline bool isPrintable(int UCS) {
 }
 
 // Control codepoints are codepoints in the Cc category.
-inline bool isControl(int UCS) {
-  return charProperties(UCS).isControl();
-}
+inline bool isControl(int UCS) { return charProperties(UCS).isControl(); }
 
 // Formatting codepoints are codepoints in the Cf category.
-inline bool isFormatting(int UCS) {
-  return charProperties(UCS).isFormatting();
-}
+inline bool isFormatting(int UCS) { return charProperties(UCS).isFormatting(); }
 
 /// Gets the number of positions the UTF8-encoded \p Text is likely to occupy
 /// when output on a terminal ("character width"). This depends on the

>From cdbfa85a07f9bb9c75dc260504eeaa17953b7ed3 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Tue, 20 Oct 2026 20:19:56 +0100
Subject: [PATCH 5/6] Also format Python script

---
 llvm/utils/generate-unicode-charsetdata.py | 57 ++++++++++++++--------
 1 file changed, 37 insertions(+), 20 deletions(-)

diff --git a/llvm/utils/generate-unicode-charsetdata.py b/llvm/utils/generate-unicode-charsetdata.py
index e1acc8b56e013e..4d877d73393ba0 100644
--- a/llvm/utils/generate-unicode-charsetdata.py
+++ b/llvm/utils/generate-unicode-charsetdata.py
@@ -1,53 +1,69 @@
-'''Generates the UnicodeCharSetsGenerated.cpp/.h files.
+"""Generates the UnicodeCharSetsGenerated.cpp/.h files.
 
 Given the Unicode character database in xml form (ucd.all.flat.xml), this
-script generates the UnicodeCharSetsGenerated.cpp/.h files from it.'''
+script generates the UnicodeCharSetsGenerated.cpp/.h files from it."""
 
 import argparse
 import os
 import xml.etree.ElementTree as ET
 
+
 def main():
     parser = argparse.ArgumentParser(description=__doc__)
-    parser.add_argument('--database', default='ucd.all.flat.xml', help='the database to convert (default ucd.all.flat.xml)')
+    parser.add_argument(
+        "--database",
+        default="ucd.all.flat.xml",
+        help="the database to convert (default ucd.all.flat.xml)",
+    )
     config = parser.parse_args()
 
     tree = ET.parse(config.database)
     root = tree.getroot()
-    description = root.find('{http://www.unicode.org/ns/2003/ucd/1.0}description').text
+    description = root.find("{http://www.unicode.org/ns/2003/ucd/1.0}description").text
     repertoire = [None] * 0x110000
-    for elem in root.find('{http://www.unicode.org/ns/2003/ucd/1.0}repertoire').findall('*'):
+    for elem in root.find("{http://www.unicode.org/ns/2003/ucd/1.0}repertoire").findall(
+        "*"
+    ):
         attrib = elem.attrib
         props = (
-            attrib['gc'],
-            attrib['ea'],
-            attrib['XIDS'] == 'Y',
-            attrib['XIDC'] == 'Y',
-            attrib['ID_Compat_Math_Start'] == 'Y',
-            attrib['ID_Compat_Math_Continue'] == 'Y',
+            attrib["gc"],
+            attrib["ea"],
+            attrib["XIDS"] == "Y",
+            attrib["XIDC"] == "Y",
+            attrib["ID_Compat_Math_Start"] == "Y",
+            attrib["ID_Compat_Math_Continue"] == "Y",
         )
-        if 'cp' in attrib:
-            repertoire[int(attrib['cp'], 16)] = props
+        if "cp" in attrib:
+            repertoire[int(attrib["cp"], 16)] = props
         else:
-            for cp in range(int(attrib['first-cp'], 16), int(attrib['last-cp'], 16) + 1):
+            for cp in range(
+                int(attrib["first-cp"], 16), int(attrib["last-cp"], 16) + 1
+            ):
                 repertoire[cp] = props
 
     def make_lookup_table(table, n):
         lookup_table = ([], {})
         for i in range(0, len(table), n):
-            lookup_table[0].append(lookup_table[1].setdefault(tuple(table[i:i+n]), len(lookup_table[1])))
+            lookup_table[0].append(
+                lookup_table[1].setdefault(
+                    tuple(table[i : i + n]), len(lookup_table[1])
+                )
+            )
         return (lookup_table[0], list(lookup_table[1].keys()))
 
-    (n1, n2, n3, n4) = (4, 4, 16, 16)
+    n1, n2, n3, n4 = (4, 4, 16, 16)
     lookup_table_1 = make_lookup_table(repertoire, 1)
     lookup_table_2 = make_lookup_table(lookup_table_1[0], n1)
     lookup_table_3 = make_lookup_table(lookup_table_2[0], n2)
     lookup_table_4 = make_lookup_table(lookup_table_3[0], n3)
     lookup_table_5 = make_lookup_table(lookup_table_4[0], n4)
 
-    dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib', 'Support')
-    for (header, file) in ((False, 'UnicodeCharSetsGenerated.cpp'), (True, 'UnicodeCharSetsGenerated.h')):
-        with open(os.path.join(dir, file), 'w') as f:
+    dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "lib", "Support")
+    for header, file in (
+        (False, "UnicodeCharSetsGenerated.cpp"),
+        (True, "UnicodeCharSetsGenerated.h"),
+    ):
+        with open(os.path.join(dir, file), "w") as f:
             b = ("false", "true")
             f.write(f'''\
 //===----------------------------------------------------------------------===//
@@ -99,5 +115,6 @@ def make_lookup_table(table, n):
 }} // namespace llvm::sys::unicode::CharPropertyTables
 ''')
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     main()

>From 4c135af48c7d42be84ed48367f88637ffe940f33 Mon Sep 17 00:00:00 2001
From: Harald van Dijk <hdijk at accesssoftek.com>
Date: Wed, 21 Oct 2026 12:32:32 +0100
Subject: [PATCH 6/6] Fix errors introduced in cleanup

---
 llvm/lib/Support/Unicode.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Support/Unicode.cpp b/llvm/lib/Support/Unicode.cpp
index bc4a64a26b1ef2..985defe83506b6 100644
--- a/llvm/lib/Support/Unicode.cpp
+++ b/llvm/lib/Support/Unicode.cpp
@@ -26,10 +26,10 @@ const CharProperties &charProperties(int UCS) {
 
   namespace T = CharPropertyTables;
   auto A = T::Lookup1[UCS >> 12];
-  auto B = T::Lookup2[A][(UCS >> 10) & 0x3];
-  auto C = T::Lookup3[B][(UCS >> 8) & 0xf];
-  auto D = T::Lookup4[C][(UCS >> 4) & 0xf];
-  auto E = T::Lookup5[D][UCS & 0xf];
+  auto B = T::Lookup2[A][(UCS >> 8) & 0xf];
+  auto C = T::Lookup3[B][(UCS >> 4) & 0xf];
+  auto D = T::Lookup4[C][(UCS >> 2) & 0x3];
+  auto E = T::Lookup5[D][UCS & 0x3];
   return T::Lookup6[E];
 }
 



More information about the cfe-commits mailing list