0

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;
}
FloFu
  • 609
  • 1
  • 5
  • 21
  • I did, but maybe I'm missing something: `ctcrc32(str.c_str())` obviously doesn't work (_mismatched types ‘const char [len]’ and ‘const char*’_). It seems to require a compile-time length – FloFu Feb 22 '18 at 09:12
  • should work for `char foo[] = "aasdf"; ctcrc32(foo);`. Please add error messages to your question – 463035818_is_not_an_ai Feb 22 '18 at 09:15
  • 2
    `char foo[] = "aasdf"; ctcrc32(foo);` will be resolved at compile time, I already use the constexpr in this way. I wished to use the same function at runtime (for dynamic string) – FloFu Feb 22 '18 at 09:24
  • I added an answer to the linked question based on @CygnusX11 which allows it to work at compile-time and runtime (with runtime strings), while still being C++11 compliant — I simply moved the template parameter to a function parameter. – Holt Feb 22 '18 at 09:53

1 Answers1

1

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:

https://stackoverflow.com/a/48924267/2666289

Holt
  • 36,600
  • 7
  • 92
  • 139