Created
March 16, 2020 23:14
-
-
Save kterhorst/56bb44254d3178d1b63d699abb894b19 to your computer and use it in GitHub Desktop.
C/C++ const(expr) tag functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef __cplusplus | |
#include <cstddef> | |
#include <cstdint> | |
#else | |
#include <stddef.h> | |
#include <stdint.h> | |
#endif | |
/// Fastest, C, non-constexpr way to create a 64bit tag. | |
#define MAKE_TAG8(a, b) ((uint64_t)(a) | ((uint64_t)(b)) << 32ULL) | |
#ifdef __cplusplus | |
/// Unfortunately the C syntax `u32 x = 'abcd'` only works for 32bit literals. | |
/// This function is the equivalent for 64bit literals: `u64 x = makeTag8("abcd1234")`. | |
/// `makeTag8("01234567") <=> MAKE_TAG8('0123', '4567')` | |
/// @str must have a length of exactly 8 characters. | |
template <size_t N> | |
constexpr uint64_t makeTag8(const char(&str)[N]) | |
{ | |
if (N != 9) | |
throw; | |
return ((uint64_t)str[3] << 0ULL) | |
| ((uint64_t)str[2] << 8ULL) | |
| ((uint64_t)str[1] << 16ULL) | |
| ((uint64_t)str[0] << 24ULL) | |
| ((uint64_t)str[7] << 32ULL) | |
| ((uint64_t)str[6] << 40ULL) | |
| ((uint64_t)str[5] << 48ULL) | |
| ((uint64_t)str[4] << 56ULL); | |
} | |
/// Uses the hash function fnv1a. | |
template <size_t N> | |
constexpr uint32_t constStrHash32(const char(&str)[N]) | |
{ | |
// Reference: https://gist.github.com/underscorediscovery/81308642d0325fd386237cfa3b44785c | |
uint32_t hash = 0x811c9dc5; | |
const uint32_t prime = 0x1000193; | |
for (size_t i = 0; i < N; ++i) | |
{ | |
const uint8_t value = str[i]; | |
hash = hash ^ value; | |
hash *= prime; | |
} | |
return hash; | |
} | |
/// Uses the hash function fnv1a. | |
template <size_t N> | |
constexpr uint64_t constStrHash64(const char(&str)[N]) | |
{ | |
// Reference: https://gist.github.com/underscorediscovery/81308642d0325fd386237cfa3b44785c | |
uint64_t hash = 0xcbf29ce484222325ULL; | |
const uint64_t prime = 0x100000001b3ULL; | |
for (size_t i = 0; i < N; ++i) | |
{ | |
const uint8_t value = str[i]; | |
hash = hash ^ value; | |
hash *= prime; | |
} | |
return hash; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment