There is this crc32 implementation that I like: CygnusX1 CRC32
It works well at compile time:
ctcrc32("StackOverflow");
But is it possible to use it at runtime:
void myfunction(const std::string& str)
{
uint32_t hash = ctcrc32(str);
// ...
}
So far I had to rewrite another (runtime) function but would prefer to use just one.
EDIT
I did tried with
ctcrc32(str.c_str())
But it doesn't work (** mismatched types ‘const char [len]’ and ‘const char*’ **). It seems to require a compile-time length.
Here is the implementation:
namespace detail {
// CRC32 Table (zlib polynomial)
static constexpr uint32_t crc_table[256] = { 0x00000000L, 0x77073096L, ... }
template<size_t idx>
constexpr uint32_t combine_crc32(const char * str, uint32_t part) {
return (part >> 8) ^ crc_table[(part ^ str[idx]) & 0x000000FF];
}
template<size_t idx>
constexpr uint32_t crc32(const char * str) {
return combine_crc32<idx>(str, crc32<idx - 1>(str));
}
// This is the stop-recursion function
template<>
constexpr uint32_t crc32<size_t(-1)>(const char * str) {
return 0xFFFFFFFF;
}
} //namespace detail
template <size_t len>
constexpr uint32_t ctcrc32(const char (&str)[len]) {
return detail::crc32<len - 2>(str) ^ 0xFFFFFFFF;
}
You cannot use it with a std::string
without rewriting it. If you look at the main function:
template <size_t len>
constexpr uint32_t ctcrc32(const char (&str)[len]) {
return detail::crc32<len - 2>(str) ^ 0xFFFFFFFF;
}
...you see that it needs the length of the string at compile time because it uses it as a template parameter (detail::crc32<len - 2>
).
ctcrc32
will only works with character arrays whose size is known at compile time (they don't have to be const
or constexpr
, but the size must be known).
I wrote an answer based on the original implementation to the linked question that allows both compile-time and runtime strings:
User contributions licensed under CC BY-SA 3.0