Skip to content

Instantly share code, notes, and snippets.

@pdlan
Created January 19, 2022 17:51
Show Gist options
  • Save pdlan/08190dbbf56a652b1cabdda53b310990 to your computer and use it in GitHub Desktop.
Save pdlan/08190dbbf56a652b1cabdda53b310990 to your computer and use it in GitHub Desktop.
compile time type hash
template <typename T>
constexpr uint64_t type_hash() {
const char *name = __PRETTY_FUNCTION__;
size_t len;
for (len = 0; name[len]; len++);
const uint64_t m = 0xc6a4a7935bd1e995ull;
const int r = 47;
const uint64_t seed = 0;
uint64_t h = seed ^ (len * m);
for (size_t j = 0; j < len / 8; ++j) {
size_t i = j * 8;
uint64_t k = ((uint64_t)(uint8_t)name[i]) | ((uint64_t)(uint8_t)name[i+1] << 8) |
((uint64_t)(uint8_t)name[i+2] << 16) | ((uint64_t)(uint8_t)name[i+3] << 24) |
((uint64_t)(uint8_t)name[i+4] << 32) | ((uint64_t)(uint8_t)name[i+5] << 40) |
((uint64_t)(uint8_t)name[i+6] << 48) | ((uint64_t)(uint8_t)name[i+7] << 56);
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
}
size_t i = len / 8 * 8;
switch (len & 7) {
case 7: h ^= ((uint64_t)(uint8_t)name[i+6]) << 48;
case 6: h ^= ((uint64_t)(uint8_t)name[i+5]) << 40;
case 5: h ^= ((uint64_t)(uint8_t)name[i+4]) << 32;
case 4: h ^= ((uint64_t)(uint8_t)name[i+3]) << 24;
case 3: h ^= ((uint64_t)(uint8_t)name[i+2]) << 16;
case 2: h ^= ((uint64_t)(uint8_t)name[i+1]) << 8;
case 1: h ^= ((uint64_t)(uint8_t)name[i+0]);
h *= m;
}
h ^= h >> r;
h *= m;
h ^= h >> r;
return h;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment