有效实现将小字符串转换为uint64_t

时间:2017-10-28 17:13:34

标签: c++11 char

#include <cstdint>
#include <cstring>

template<typename T>
T oph_(const char *s){
    constexpr std::size_t MAX = sizeof(T);
    const     std::size_t size = strnlen(s, MAX);

    T r = 0;

    for(auto it = s; it - s < size; ++it)
        r = r << 8 | *it;

    return r;
}

inline uint64_t oph(const char *s){
    return oph_<uint64_t>(s);
}

int main(){
    uint64_t const a = oph("New York City");
    uint64_t const b = oph("Boston International");
    return a > b;
}

我想将const char *中的前8个字符转换为uint64_t,以便我可以轻松比较两个字符串是否更大/更小。

我知道等于半工作。

但是我不确定这是否是最有效的实施方式。

我希望实现适用于小端和大端机器。

1 个答案:

答案 0 :(得分:0)

这是一个C实现,应该比你的实现更快,但我仍然需要使用应该成为瓶颈的strncpy

#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <byteswap.h>

union small_str {
    uint64_t v;
    char buf[8];
};

static uint64_t fill_small_str(const char *str)
{
    union small_str ss = { 0 };

    strncpy(ss.buf, str, 8);
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
    return ss.v;
#else
    return bswap_64(ss.v);
#endif
}

int main(void)
{
    uint64_t const a = fill_small_str("Aew York City");
    uint64_t const b = fill_small_str("Boston International");
    printf("%lu ; %lu ; %d\n", a, b, (a < b));
    return 0;
}