85 lines
1.5 KiB
C++
85 lines
1.5 KiB
C++
![]() |
#pragma once
|
||
|
#include <cstddef>
|
||
|
#include <cstdint>
|
||
|
#include <string_view>
|
||
|
#include <type_traits>
|
||
|
|
||
|
namespace rage
|
||
|
{
|
||
|
using joaat_t = std::uint32_t;
|
||
|
|
||
|
inline constexpr char joaat_to_lower(char c)
|
||
|
{
|
||
|
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
|
||
|
}
|
||
|
|
||
|
template <std::size_t CharCount>
|
||
|
struct constexpr_joaat
|
||
|
{
|
||
|
char data[CharCount];
|
||
|
|
||
|
template <std::size_t... Indices>
|
||
|
constexpr constexpr_joaat(const char *str, std::index_sequence<Indices...>) :
|
||
|
data{ (str[Indices])... }
|
||
|
{
|
||
|
}
|
||
|
|
||
|
constexpr joaat_t operator()()
|
||
|
{
|
||
|
joaat_t hash = 0;
|
||
|
|
||
|
for (std::size_t i = 0; i < CharCount; ++i)
|
||
|
{
|
||
|
hash += joaat_to_lower(data[i]);
|
||
|
hash += (hash << 10);
|
||
|
hash ^= (hash >> 6);
|
||
|
}
|
||
|
|
||
|
hash += (hash << 3);
|
||
|
hash ^= (hash >> 11);
|
||
|
hash += (hash << 15);
|
||
|
|
||
|
return hash;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
inline joaat_t joaat(std::string_view str)
|
||
|
{
|
||
|
joaat_t hash = 0;
|
||
|
|
||
|
for (char c : str)
|
||
|
{
|
||
|
hash += joaat_to_lower(c);
|
||
|
hash += (hash << 10);
|
||
|
hash ^= (hash >> 6);
|
||
|
}
|
||
|
|
||
|
hash += (hash << 3);
|
||
|
hash ^= (hash >> 11);
|
||
|
hash += (hash << 15);
|
||
|
|
||
|
return hash;
|
||
|
}
|
||
|
|
||
|
inline joaat_t joaat(const char *str)
|
||
|
{
|
||
|
joaat_t hash = 0;
|
||
|
|
||
|
while (*str)
|
||
|
{
|
||
|
hash += joaat_to_lower(*(str++));
|
||
|
hash += (hash << 10);
|
||
|
hash ^= (hash >> 6);
|
||
|
}
|
||
|
|
||
|
hash += (hash << 3);
|
||
|
hash ^= (hash >> 11);
|
||
|
hash += (hash << 15);
|
||
|
|
||
|
return hash;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define RAGE_JOAAT_IMPL(str) (::rage::constexpr_joaat<sizeof(str) - 1>((str), std::make_index_sequence<sizeof(str) - 1>())())
|
||
|
#define RAGE_JOAAT(str) (std::integral_constant<rage::joaat_t, RAGE_JOAAT_IMPL(str)>::value)
|