LibC: optimize strpbrk, str{,c}spn, strtok{,_r}
These matches are now detected with bitmasks instead of looping over the second string
This commit is contained in:
parent
418678466c
commit
006a196e4a
|
@ -282,37 +282,39 @@ char* strstr(const char* haystack, const char* needle)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t strcspn(const char* s1, const char* s2)
|
#define CHAR_UCHAR(ch) \
|
||||||
{
|
static_cast<unsigned char>(ch)
|
||||||
size_t i = 0;
|
|
||||||
for (; s1[i]; i++)
|
#define CHAR_BITMASK(str) \
|
||||||
for (size_t j = 0; s2[j]; j++)
|
uint32_t bitmask[0x100 / 32] {}; \
|
||||||
if (s1[i] == s2[j])
|
for (size_t i = 0; str[i]; i++) \
|
||||||
return i;
|
bitmask[CHAR_UCHAR(str[i]) / 32] |= (1 << (CHAR_UCHAR(str[i]) % 32))
|
||||||
return i;
|
|
||||||
}
|
#define CHAR_BITMASK_TEST(ch) \
|
||||||
|
(bitmask[CHAR_UCHAR(ch) / 32] & (1 << (CHAR_UCHAR(ch) % 32)))
|
||||||
|
|
||||||
char* strpbrk(const char* s1, const char* s2)
|
char* strpbrk(const char* s1, const char* s2)
|
||||||
{
|
{
|
||||||
|
CHAR_BITMASK(s2);
|
||||||
for (size_t i = 0; s1[i]; i++)
|
for (size_t i = 0; s1[i]; i++)
|
||||||
for (size_t j = 0; s2[j]; j++)
|
if (CHAR_BITMASK_TEST(s1[i]))
|
||||||
if (s1[i] == s2[j])
|
return const_cast<char*>(&s1[i]);
|
||||||
return const_cast<char*>(s1 + i);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t strspn(const char* s1, const char* s2)
|
size_t strspn(const char* s1, const char* s2)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
CHAR_BITMASK(s2);
|
||||||
for (; s1[i]; i++)
|
for (size_t i = 0;; i++)
|
||||||
{
|
if (s1[i] == '\0' || !CHAR_BITMASK_TEST(s1[i]))
|
||||||
bool found = false;
|
return i;
|
||||||
for (size_t j = 0; s2[j] && !found; j++)
|
}
|
||||||
if (s1[i] == s2[j])
|
|
||||||
found = true;
|
size_t strcspn(const char* s1, const char* s2)
|
||||||
if (!found)
|
{
|
||||||
break;
|
CHAR_BITMASK(s2);
|
||||||
}
|
for (size_t i = 0;; i++)
|
||||||
|
if (s1[i] == '\0' || CHAR_BITMASK_TEST(s1[i]))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,49 +326,43 @@ char* strtok(char* __restrict s, const char* __restrict sep)
|
||||||
|
|
||||||
char* strtok_r(char* __restrict str, const char* __restrict sep, char** __restrict state)
|
char* strtok_r(char* __restrict str, const char* __restrict sep, char** __restrict state)
|
||||||
{
|
{
|
||||||
if (str)
|
CHAR_BITMASK(sep);
|
||||||
{
|
|
||||||
while (*str)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
for (size_t i = 0; sep[i] && !found; i++)
|
|
||||||
if (*str == sep[i])
|
|
||||||
found = true;
|
|
||||||
if (!found)
|
|
||||||
break;
|
|
||||||
str++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*str)
|
if (str)
|
||||||
|
*state = str;
|
||||||
|
|
||||||
|
if (*state == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
str = *state;
|
||||||
|
|
||||||
|
for (; *str; str++)
|
||||||
|
if (!CHAR_BITMASK_TEST(*str))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (*str == '\0')
|
||||||
{
|
{
|
||||||
*state = nullptr;
|
*state = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
*state = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*state)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
str = *state;
|
|
||||||
for (size_t i = 0; str[i]; i++)
|
for (size_t i = 0; str[i]; i++)
|
||||||
{
|
{
|
||||||
for (size_t j = 0; sep[j]; j++)
|
if (!CHAR_BITMASK_TEST(str[i]))
|
||||||
{
|
continue;
|
||||||
if (str[i] == sep[j])
|
|
||||||
{
|
|
||||||
str[i] = '\0';
|
str[i] = '\0';
|
||||||
*state = str + i + 1;
|
*state = str + i + 1;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*state = nullptr;
|
*state = nullptr;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef CHAR_UCHAR
|
||||||
|
#undef CHAR_BITMASK
|
||||||
|
#undef CHAR_BITMASK_TEST
|
||||||
|
|
||||||
char* strsignal(int signum)
|
char* strsignal(int signum)
|
||||||
{
|
{
|
||||||
static char buffer[128];
|
static char buffer[128];
|
||||||
|
|
Loading…
Reference in New Issue