-/**
-Computes a 32-bit Fowler-Noll-Vo (FNV-1a) hash. The number of bits can be
-limited to less than 32, in which case XOR-folding is used to reduce the hash
-size.
-*/
-std::uint32_t hash32(const void *, unsigned, unsigned = 32);
+template<unsigned N, unsigned L = 3+(N>8)+(N>16)+(N>32)+(N>64)>
+struct HashTraits;
+
+template<>
+struct HashTraits<64, 6>
+{
+ using HashType = uint64_t;
+ using ResultType = uint64_t;
+ static constexpr HashType prime = 1099511628211ULL;
+ static constexpr HashType offset = 14695981039346656037ULL;
+ static constexpr bool folded = false;
+};
+
+template<>
+struct HashTraits<32, 5>
+{
+ using HashType = uint32_t;
+ using ResultType = uint32_t;
+ static constexpr HashType prime = 16777619;
+ static constexpr HashType offset = 2166136261U;
+ static constexpr bool folded = false;
+};
+
+template<unsigned N>
+struct HashTraits<N, 6>
+{
+ using HashType = uint64_t;
+ using ResultType = uint64_t;
+ static constexpr bool folded = true;
+};
+
+template<unsigned N>
+struct HashTraits<N, 5>
+{
+ using HashType = uint32_t;
+ using ResultType = uint32_t;
+ static constexpr bool folded = true;
+};
+
+template<unsigned N>
+struct HashTraits<N, 4>
+{
+ using HashType = uint32_t;
+ using ResultType = uint16_t;
+ static constexpr bool folded = true;
+};
+
+template<unsigned N>
+struct HashTraits<N, 3>
+{
+ using HashType = uint32_t;
+ using ResultType = uint8_t;
+ static constexpr bool folded = true;
+};
+