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で動いたのでたぶん大丈夫です。(オイ