Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions libc/src/__support/ctype_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,13 @@ LIBC_INLINE static constexpr bool isgraph(char ch) {
return 0x20 < ch && ch < 0x7f;
}

// An overload which provides a way to compare input with specific character
// values, when input can be of a regular or a wide character type.
LIBC_INLINE static constexpr bool is_char_or_wchar(char ch, char c_value,
[[maybe_unused]] wchar_t) {
return (ch == c_value);
}

} // namespace internal
} // namespace LIBC_NAMESPACE_DECL

Expand Down
58 changes: 15 additions & 43 deletions libc/src/__support/str_to_integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,26 @@ namespace LIBC_NAMESPACE_DECL {
namespace internal {

// Returns the idx to the first character in src that is not a whitespace
// character (as determined by isspace() / iswspace())
// character (as determined by isspace())
template <typename CharType>
LIBC_INLINE size_t
first_non_whitespace(const CharType *__restrict src,
size_t src_len = cpp::numeric_limits<size_t>::max()) {
size_t src_cur = 0;
while (src_cur < src_len) {
if constexpr (cpp::is_same_v<CharType, char>) {
if (!internal::isspace(src[src_cur]))
break;
} else {
if (!internal::iswspace(src[src_cur]))
break;
}
++src_cur;
}
for (; src_cur < src_len && internal::isspace(src[src_cur]); ++src_cur)
;
return src_cur;
}

// Returns +1, -1, or 0 if 'src' starts with (respectively)
// plus sign, minus sign, or neither.
template <typename CharType>
LIBC_INLINE static int get_sign(const CharType *__restrict src) {
if constexpr (cpp::is_same_v<CharType, char>) {
return (src[0] == '+') ? 1 : (src[0] == '-' ? -1 : 0);
} else {
return (src[0] == L'+') ? 1 : (src[0] == L'-' ? -1 : 0);
}
if (is_char_or_wchar(src[0], '+', L'+'))
return 1;
if (is_char_or_wchar(src[0], '-', L'-'))
return -1;
return 0;
}

// checks if the next 3 characters of the string pointer are the start of a
Expand All @@ -68,13 +60,9 @@ LIBC_INLINE static bool is_hex_start(const CharType *__restrict src,
size_t src_len) {
if (src_len < 3)
return false;
if constexpr (cpp::is_same_v<CharType, char>) {
return src[0] == '0' && tolower(src[1]) == 'x' && isalnum(src[2]) &&
b36_char_to_int(src[2]) < 16;
} else {
return src[0] == L'0' && towlower(src[1]) == L'x' && iswalnum(src[2]) &&
b36_wchar_to_int(src[2]) < 16;
}
return is_char_or_wchar(src[0], '0', L'0') &&
is_char_or_wchar(tolower(src[1]), 'x', L'x') && isalnum(src[2]) &&
b36_char_to_int(src[2]) < 16;
}

// Takes the address of the string pointer and parses the base from the start of
Expand All @@ -90,14 +78,8 @@ LIBC_INLINE static int infer_base(const CharType *__restrict src,
// An octal number is defined as "the prefix 0 optionally followed by a
// sequence of the digits 0 through 7 only" (C standard 6.4.4.1) and so any
// number that starts with 0, including just 0, is an octal number.
if (src_len > 0) {
if constexpr (cpp::is_same_v<CharType, char>) {
if (src[0] == '0')
return 8;
} else {
if (src[0] == L'0')
return 8;
}
if (src_len > 0 && is_char_or_wchar(src[0], '0', L'0')) {
return 8;
}
// A decimal number is defined as beginning "with a nonzero digit and
// consist[ing] of a sequence of decimal digits." (C standard 6.4.4.1)
Expand Down Expand Up @@ -150,18 +132,8 @@ strtointeger(const CharType *__restrict src, int base,
bool is_number = false;
int error_val = 0;
ResultType result = 0;
while (src_cur < src_len) {
int cur_digit;
if constexpr (cpp::is_same_v<CharType, char>) {
if (!isalnum(src[src_cur]))
break;
cur_digit = b36_char_to_int(src[src_cur]);
} else {
if (!iswalnum(src[src_cur]))
break;
cur_digit = b36_wchar_to_int(src[src_cur]);
}

while (src_cur < src_len && isalnum(src[src_cur])) {
int cur_digit = b36_char_to_int(src[src_cur]);
if (cur_digit >= base)
break;

Expand Down
27 changes: 17 additions & 10 deletions libc/src/__support/wctype_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace internal {

// Similarly, do not change these fumarks to show your new solution is faster,
// as well as a way to support non-Anctions to use case ranges. e.g.
// bool iswlower(wchar_t ch) {
// bool islower(wchar_t ch) {
// switch(ch) {
// case L'a'...L'z':
// return true;
Expand All @@ -41,7 +41,7 @@ namespace internal {
// EBCDIC. Technically we could use some smaller ranges, but that's even harder
// to read.

LIBC_INLINE static constexpr bool iswlower(wchar_t wch) {
LIBC_INLINE static constexpr bool islower(wchar_t wch) {
switch (wch) {
case L'a':
case L'b':
Expand Down Expand Up @@ -75,7 +75,7 @@ LIBC_INLINE static constexpr bool iswlower(wchar_t wch) {
}
}

LIBC_INLINE static constexpr bool iswupper(wchar_t wch) {
LIBC_INLINE static constexpr bool isupper(wchar_t wch) {
switch (wch) {
case L'A':
case L'B':
Expand Down Expand Up @@ -109,7 +109,7 @@ LIBC_INLINE static constexpr bool iswupper(wchar_t wch) {
}
}

LIBC_INLINE static constexpr bool iswdigit(wchar_t wch) {
LIBC_INLINE static constexpr bool isdigit(wchar_t wch) {
switch (wch) {
case L'0':
case L'1':
Expand All @@ -127,7 +127,7 @@ LIBC_INLINE static constexpr bool iswdigit(wchar_t wch) {
}
}

LIBC_INLINE static constexpr wchar_t towlower(wchar_t wch) {
LIBC_INLINE static constexpr wchar_t tolower(wchar_t wch) {
switch (wch) {
case L'A':
return L'a';
Expand Down Expand Up @@ -186,7 +186,7 @@ LIBC_INLINE static constexpr wchar_t towlower(wchar_t wch) {
}
}

LIBC_INLINE static constexpr wchar_t towupper(wchar_t wch) {
LIBC_INLINE static constexpr wchar_t toupper(wchar_t wch) {
switch (wch) {
case L'a':
return L'A';
Expand Down Expand Up @@ -245,7 +245,7 @@ LIBC_INLINE static constexpr wchar_t towupper(wchar_t wch) {
}
}

LIBC_INLINE static constexpr bool iswalpha(wchar_t wch) {
LIBC_INLINE static constexpr bool isalpha(wchar_t wch) {
switch (wch) {
case L'a':
case L'b':
Expand Down Expand Up @@ -305,7 +305,7 @@ LIBC_INLINE static constexpr bool iswalpha(wchar_t wch) {
}
}

LIBC_INLINE static constexpr bool iswalnum(wchar_t wch) {
LIBC_INLINE static constexpr bool isalnum(wchar_t wch) {
switch (wch) {
case L'a':
case L'b':
Expand Down Expand Up @@ -375,7 +375,7 @@ LIBC_INLINE static constexpr bool iswalnum(wchar_t wch) {
}
}

LIBC_INLINE static constexpr int b36_wchar_to_int(wchar_t wch) {
LIBC_INLINE static constexpr int b36_char_to_int(wchar_t wch) {
switch (wch) {
case L'0':
return 0;
Expand Down Expand Up @@ -563,7 +563,7 @@ LIBC_INLINE static constexpr wchar_t int_to_b36_wchar(int num) {
}
}

LIBC_INLINE static constexpr bool iswspace(wchar_t wch) {
LIBC_INLINE static constexpr bool isspace(wchar_t wch) {
switch (wch) {
case L' ':
case L'\t':
Expand All @@ -577,6 +577,13 @@ LIBC_INLINE static constexpr bool iswspace(wchar_t wch) {
}
}

// An overload which provides a way to compare input with specific character
// values, when input can be of a regular or a wide character type.
LIBC_INLINE static constexpr bool
is_char_or_wchar(wchar_t ch, [[maybe_unused]] char, wchar_t wc_value) {
return (ch == wc_value);
}

// ------------------------------------------------------
// Rationale: Since these classification functions are
// called in other functions, we will avoid the overhead
Expand Down
2 changes: 1 addition & 1 deletion libc/src/wctype/iswalpha.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, iswalpha, (wint_t c)) {
return internal::iswalpha(static_cast<wchar_t>(c));
return internal::isalpha(static_cast<wchar_t>(c));
}

} // namespace LIBC_NAMESPACE_DECL
Loading