constexprなCRCを実装する
switch case で文字列を使う - とくにあぶなくないRiSKのブログ
ハッシュ関数としてCRC-CCITTを実装してみました。
#include <cstdint> #include <iostream> #include <string> namespace crc_ccitt { constexpr unsigned int process_char(unsigned int acc, int n) { return n > 0 ? process_char(acc & 0x8000 ? (acc << 1) ^ 0x11021 : acc << 1, n - 1) : acc; } constexpr unsigned int process_string(unsigned int acc, char const *s) { return *s ? process_string(process_char(acc ^ (*s << 8), 8), s + 1) : acc; } constexpr std::uint16_t checksum(char const *s) { return process_string(0xFFFF, s); } static_assert(checksum("123456789") == 0x29B1, "crc error"); } // namespace crc_ccitt constexpr auto hash = &crc_ccitt::checksum; int main() { std::string const s = "foo"; switch (hash(s.c_str())) { case hash("foo"): std::cout << "Hello, world!\n"; break; } }
GCC 4.6.0 20110108 (experimental) で動作確認しました。constexprのことは全然知りませんが、GCCで動いたのでたぶん大丈夫です。(オイ