I was trying to create a compile time hasher that takes a string literal and creates an integer. I'm using Code::Blocks's GCC 4.7.1 compiler (which broke on me earlier). This is how it works:
typedef unsigned long long ull; //less typing
constexpr ull basis = 14695981039346656037ULL; //Don't ask me
constexpr ull prime = 1099511628211ULL; //Someone else invented them
template <size_t I>
constexpr ull myhash(const char* p, ull b) //Recursive function
{
return myhash<I - 1>(p, (b ^ p[I]) * prime);
}
template <>
constexpr ull myhash<size_t(-1)>(const char* p, ull b) //Base case
{
return b;
}
//This macro generates a variable of a given name with a hash of that name
#define CTH_GEN(x) constexpr ull x = myhash<sizeof("x") - 2>("x", basis)
The recursive part of my_hash
will start at the end of the string and constantly change the number b
by a character in the string until it hits the base case, which returns the number. The macro reduces chances for potential bugs by ensuring the variable name and hash always match. CTH_GEN(A)
would evaluate to constexpr unsigned long long A = my_hash<sizeof("A") - 2>("A", basis)
I tested it like this:
CTH_GEN(A);
CTH_GEN(B);
CTH_GEN(C);
int main()
{
cout << ((basis ^ 'A') * prime) << " : " << A << endl;
cout << ((basis ^ 'B') * prime) << " : " << B << endl;
cout << ((basis ^ 'C') * prime) << " : " << C << endl;
}
This is the output of a test run:
12638222384927744748 : 12638214688346347271
12638225683462629381 : 12638214688346347271
12638224583951001170 : 12638214688346347271
The numbers should be identical on each side. The left side is the runtime calculation of the hash, and the right side is the compile time calculation. They both use the exact same math in the same order, but as you can see the compile time version always generates the same number. I would really appreciate an explanation, workaround, or completely new way to approach this. The particular hash method I'm using is totally open for change, but I figure that's a different question entirely.