Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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_one_of(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_one_of(src[0], '+', L'+'))
return 1;
if (is_one_of(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_one_of(src[0], '0', L'0') &&
is_one_of(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 && internal::is_one_of(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_one_of(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