[libc-commits] [libc] [libc][wctype] Implement internal UTF8 wctype classification functions (PR #174607)
Marcell Leleszi via libc-commits
libc-commits at lists.llvm.org
Fri Feb 6 01:53:03 PST 2026
================
@@ -125,255 +132,473 @@ LIBC_INLINE static constexpr bool isdigit(wchar_t wch) {
}
}
-LIBC_INLINE static constexpr wchar_t tolower(wchar_t wch) {
+LIBC_INLINE constexpr bool isalpha(wchar_t wch) {
switch (wch) {
+ case L'a':
+ case L'b':
+ case L'c':
+ case L'd':
+ case L'e':
+ case L'f':
+ case L'g':
+ case L'h':
+ case L'i':
+ case L'j':
+ case L'k':
+ case L'l':
+ case L'm':
+ case L'n':
+ case L'o':
+ case L'p':
+ case L'q':
+ case L'r':
+ case L's':
+ case L't':
+ case L'u':
+ case L'v':
+ case L'w':
+ case L'x':
+ case L'y':
+ case L'z':
case L'A':
- return L'a';
case L'B':
- return L'b';
case L'C':
- return L'c';
case L'D':
- return L'd';
case L'E':
- return L'e';
case L'F':
- return L'f';
case L'G':
- return L'g';
case L'H':
- return L'h';
case L'I':
- return L'i';
case L'J':
- return L'j';
case L'K':
- return L'k';
case L'L':
- return L'l';
case L'M':
- return L'm';
case L'N':
- return L'n';
case L'O':
- return L'o';
case L'P':
- return L'p';
case L'Q':
- return L'q';
case L'R':
- return L'r';
case L'S':
- return L's';
case L'T':
- return L't';
case L'U':
- return L'u';
case L'V':
- return L'v';
case L'W':
- return L'w';
case L'X':
- return L'x';
case L'Y':
- return L'y';
case L'Z':
- return L'z';
+ return true;
default:
- return wch;
+ return false;
}
}
-LIBC_INLINE static constexpr wchar_t toupper(wchar_t wch) {
+LIBC_INLINE constexpr bool isalnum(wchar_t wch) {
switch (wch) {
case L'a':
- return L'A';
case L'b':
- return L'B';
case L'c':
- return L'C';
case L'd':
- return L'D';
case L'e':
- return L'E';
case L'f':
- return L'F';
case L'g':
- return L'G';
case L'h':
- return L'H';
case L'i':
- return L'I';
case L'j':
- return L'J';
case L'k':
- return L'K';
case L'l':
- return L'L';
case L'm':
- return L'M';
case L'n':
- return L'N';
case L'o':
- return L'O';
case L'p':
- return L'P';
case L'q':
- return L'Q';
case L'r':
- return L'R';
case L's':
- return L'S';
case L't':
- return L'T';
case L'u':
- return L'U';
case L'v':
- return L'V';
case L'w':
- return L'W';
case L'x':
- return L'X';
case L'y':
- return L'Y';
case L'z':
- return L'Z';
+ case L'A':
+ case L'B':
+ case L'C':
+ case L'D':
+ case L'E':
+ case L'F':
+ case L'G':
+ case L'H':
+ case L'I':
+ case L'J':
+ case L'K':
+ case L'L':
+ case L'M':
+ case L'N':
+ case L'O':
+ case L'P':
+ case L'Q':
+ case L'R':
+ case L'S':
+ case L'T':
+ case L'U':
+ case L'V':
+ case L'W':
+ case L'X':
+ case L'Y':
+ case L'Z':
+ case L'0':
+ case L'1':
+ case L'2':
+ case L'3':
+ case L'4':
+ case L'5':
+ case L'6':
+ case L'7':
+ case L'8':
+ case L'9':
+ return true;
default:
- return wch;
+ return false;
+ }
+}
+
+LIBC_INLINE constexpr bool isspace(wchar_t wch) {
+ switch (wch) {
+ case L' ':
+ case L'\t':
+ case L'\n':
+ case L'\v':
+ case L'\f':
+ case L'\r':
+ return true;
+ default:
+ return false;
+ }
+}
+
+LIBC_INLINE constexpr bool isblank(wchar_t wch) {
+ switch (wch) {
+ case L' ':
+ case L'\t':
+ return true;
+ default:
+ return false;
}
}
-LIBC_INLINE static constexpr bool isalpha(wchar_t wch) {
+LIBC_INLINE constexpr bool isgraph(wchar_t wch) {
+ return 0x20 < wch && wch < 0x7f;
+}
+
+LIBC_INLINE constexpr bool isprint(wchar_t wch) {
+ return (static_cast<unsigned>(wch) - ' ') < 95;
+}
+
+LIBC_INLINE constexpr bool isxdigit(wchar_t wch) {
switch (wch) {
case L'a':
case L'b':
case L'c':
case L'd':
case L'e':
case L'f':
- case L'g':
- case L'h':
- case L'i':
- case L'j':
- case L'k':
- case L'l':
- case L'm':
- case L'n':
- case L'o':
- case L'p':
- case L'q':
- case L'r':
- case L's':
- case L't':
- case L'u':
- case L'v':
- case L'w':
- case L'x':
- case L'y':
- case L'z':
case L'A':
case L'B':
case L'C':
case L'D':
case L'E':
case L'F':
+ case L'0':
+ case L'1':
+ case L'2':
+ case L'3':
+ case L'4':
+ case L'5':
+ case L'6':
+ case L'7':
+ case L'8':
+ case L'9':
+ return true;
+ default:
+ return false;
+ }
+}
+
+LIBC_INLINE constexpr bool iscntrl(wchar_t wch) {
+ return (wch < 0x20 || wch == 0x7f);
+}
+
+LIBC_INLINE constexpr bool ispunct(wchar_t wch) {
+ return !isalnum(wch) && isgraph(wch);
+}
+
+LIBC_INLINE constexpr wchar_t tolower(wchar_t wch) {
+ switch (wch) {
+ case L'A':
+ return L'a';
+ case L'B':
+ return L'b';
+ case L'C':
+ return L'c';
+ case L'D':
+ return L'd';
+ case L'E':
+ return L'e';
+ case L'F':
+ return L'f';
case L'G':
+ return L'g';
case L'H':
+ return L'h';
case L'I':
+ return L'i';
case L'J':
+ return L'j';
case L'K':
+ return L'k';
case L'L':
+ return L'l';
case L'M':
+ return L'm';
case L'N':
+ return L'n';
case L'O':
+ return L'o';
case L'P':
+ return L'p';
case L'Q':
+ return L'q';
case L'R':
+ return L'r';
case L'S':
+ return L's';
case L'T':
+ return L't';
case L'U':
+ return L'u';
case L'V':
+ return L'v';
case L'W':
+ return L'w';
case L'X':
+ return L'x';
case L'Y':
+ return L'y';
case L'Z':
- return true;
+ return L'z';
default:
- return false;
+ return wch;
}
}
-LIBC_INLINE static constexpr bool isalnum(wchar_t wch) {
+LIBC_INLINE constexpr wchar_t toupper(wchar_t wch) {
switch (wch) {
case L'a':
+ return L'A';
case L'b':
+ return L'B';
case L'c':
+ return L'C';
case L'd':
+ return L'D';
case L'e':
+ return L'E';
case L'f':
+ return L'F';
case L'g':
+ return L'G';
case L'h':
+ return L'H';
case L'i':
+ return L'I';
case L'j':
+ return L'J';
case L'k':
+ return L'K';
case L'l':
+ return L'L';
case L'm':
+ return L'M';
case L'n':
+ return L'N';
case L'o':
+ return L'O';
case L'p':
+ return L'P';
case L'q':
+ return L'Q';
case L'r':
+ return L'R';
case L's':
+ return L'S';
case L't':
+ return L'T';
case L'u':
+ return L'U';
case L'v':
+ return L'V';
case L'w':
+ return L'W';
case L'x':
+ return L'X';
case L'y':
+ return L'Y';
case L'z':
- case L'A':
- case L'B':
- case L'C':
- case L'D':
- case L'E':
- case L'F':
- case L'G':
- case L'H':
- case L'I':
- case L'J':
- case L'K':
- case L'L':
- case L'M':
- case L'N':
- case L'O':
- case L'P':
- case L'Q':
- case L'R':
- case L'S':
- case L'T':
- case L'U':
- case L'V':
- case L'W':
- case L'X':
- case L'Y':
- case L'Z':
- case L'0':
- case L'1':
- case L'2':
- case L'3':
- case L'4':
- case L'5':
- case L'6':
- case L'7':
- case L'8':
- case L'9':
- return true;
+ return L'Z';
default:
- return false;
+ return wch;
+ }
+}
+
+} // namespace ascii
+
+LIBC_INLINE constexpr bool islower(wchar_t wch) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::islower(wch);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::islower(wch);
+ }
+ return lookup_properties(wch) & PropertyFlag::LOWER;
+#endif
+}
+
+LIBC_INLINE constexpr bool isupper(wchar_t wch) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::isupper(wch);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::isupper(wch);
+ }
+ return lookup_properties(wch) & PropertyFlag::UPPER;
+#endif
+}
+
+LIBC_INLINE constexpr bool isdigit(wchar_t wch) {
+ // In C.UT8, only ASCII digits are considered digits
+ return ascii::isdigit(wch);
+}
+
+LIBC_INLINE constexpr bool isalpha(wchar_t wch) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::isalpha(wch);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::isalpha(wch);
+ }
+ return lookup_properties(wch) & PropertyFlag::ALPHA;
+#endif
+}
+
+LIBC_INLINE constexpr bool isalnum(wchar_t wch) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::isalnum(wch);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::isalnum(wch);
+ }
+ // Only need to check ALPHA, digit cases are covered by ASCII path
+ return lookup_properties(wch) & PropertyFlag::ALPHA;
+#endif
+}
+
+LIBC_INLINE constexpr bool isspace(wchar_t wch) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::isspace(wch);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::isspace(wch);
+ }
+ return lookup_properties(wch) & PropertyFlag::SPACE;
+#endif
+}
+
+LIBC_INLINE constexpr bool isblank(wchar_t wch) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::isblank(wch);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::isblank(wch);
+ }
+ return lookup_properties(wch) & PropertyFlag::BLANK;
+#endif
+}
+
+LIBC_INLINE constexpr bool isgraph(wchar_t wch) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::isgraph(wch);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::isgraph(wch);
+ }
+ // print && !space
+ return (lookup_properties(wch) &
+ (PropertyFlag::PRINT | PropertyFlag::SPACE)) == PropertyFlag::PRINT;
+#endif
+}
+
+LIBC_INLINE constexpr bool isprint(wchar_t wch) {
+#if LIBC_CONF_WCTYPE_MODE != LIBC_WCTYPE_MODE_UTF8
+ return ascii::isprint(wch);
+#else
+ if (static_cast<uint32_t>(wch) < 128) {
+ return ascii::isprint(wch);
}
+ return lookup_properties(wch) & PropertyFlag::PRINT;
+#endif
}
-LIBC_INLINE static constexpr int b36_char_to_int(wchar_t wch) {
+LIBC_INLINE constexpr bool isxdigit(wchar_t wch) {
----------------
mleleszi wrote:
Done
https://github.com/llvm/llvm-project/pull/174607
More information about the libc-commits
mailing list