Skip to content

Instantly share code, notes, and snippets.

@kterhorst
Created March 16, 2020 23:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kterhorst/56bb44254d3178d1b63d699abb894b19 to your computer and use it in GitHub Desktop.
Save kterhorst/56bb44254d3178d1b63d699abb894b19 to your computer and use it in GitHub Desktop.
C/C++ const(expr) tag functions
#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