是否有与“ memchr”相似的函数,可以将每个炭与位掩码匹配,而不是确切的平等

Is there a function with similar performance to `memchr` that can match each char with a bit-mask instead of for exact equality?

本文关键字:掩码 memchr 相似 函数 是否      更新时间:2023-10-16

我要解决的实际问题是搜索位模式的出现( 110xxxxx1110xxxx11110xxx),这表明UTF-8中的多比例字符的开始。

我希望找到与memchr()相似的东西,但尚未设法找到任何东西。我自己不能写大会,因为它必须是便携的。

您正在尝试找到第一个UTF-8序列启动字节。测试是:

(c >= 0xC0 && c <= 0xF7)

这可以通过每个字节进行单个测试来有效地完成:

void *memfind_start_byte(const void *p, size_t len) {
    unsigned char *s = (unsigned char *)p;
    while (len-- > 0) {
        if ((unsigned char)(*s++ - 0xC0) <= 0xF7 - 0xC0)
            return (void *)(s - 1);
    }
    return NULL;
}

通过优化编译器,可以自动将此循环自动传输。

您可以使用比特的技巧一次检查多个字节,就像strlen():对齐源指针后,您可以一次检查8个字节:

if (*(uint64_t*)p & 0x8080808080808080) {
    /* one byte might match: write 8 tests */
}

这是未经测试的尝试:

void *memfind_start_byte(const void *p, size_t len) {
    unsigned char *s = (unsigned char *)p;
    while (((uintptr_t)s & 7) && len-- > 0) {
        if ((unsigned char)(*s++ - 0xC0) <= 0xF7 - 0xC0)
            return (void *)(s - 1);
    }
    for (; len >= 8; len -= 8, s += 8) {
        if (*(uint64_t *)s & 0x8080808080808080) {
            if ((unsigned char)(s[0] - 0xC0) <= 0xF7 - 0xC0) return (void *)(s + 0);
            if ((unsigned char)(s[1] - 0xC0) <= 0xF7 - 0xC0) return (void *)(s + 1);
            if ((unsigned char)(s[2] - 0xC0) <= 0xF7 - 0xC0) return (void *)(s + 2);
            if ((unsigned char)(s[3] - 0xC0) <= 0xF7 - 0xC0) return (void *)(s + 3);
            if ((unsigned char)(s[4] - 0xC0) <= 0xF7 - 0xC0) return (void *)(s + 4);
            if ((unsigned char)(s[5] - 0xC0) <= 0xF7 - 0xC0) return (void *)(s + 5);
            if ((unsigned char)(s[6] - 0xC0) <= 0xF7 - 0xC0) return (void *)(s + 6);
            if ((unsigned char)(s[7] - 0xC0) <= 0xF7 - 0xC0) return (void *)(s + 7);
        }
    }
    while (len-- > 0) {
        if ((unsigned char)(*s++ - 0xC0) <= 0xF7 - 0xC0)
            return (void *)(s - 1);
    }
    return NULL;
}