MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
hash.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_FUNCTIONAL_HASH_HPP__
2#define MSTL_CORE_FUNCTIONAL_HASH_HPP__
3
11
14
20
30template <typename Key, typename Dummy = void>
31struct hash;
32
37template <typename T>
38struct hash<T*> {
44 MSTL_NODISCARD MSTL_CONSTEXPR20 size_t operator ()(const T* ptr) const noexcept {
45 return static_cast<size_t>(reinterpret_cast<uintptr_t>(ptr));
46 }
47};
48 // HashPrimary
50
56
59
65MSTL_INLINE17 constexpr size_t FNV_OFFSET_BASIS =
66#ifdef MSTL_DATA_BUS_WIDTH_64__
67 14695981039346656037ULL;
68#else
69 2166136261U
70#endif
71
77MSTL_INLINE17 constexpr size_t FNV_PRIME
78#ifdef MSTL_DATA_BUS_WIDTH_64__
79 = 1099511628211ULL;
80#else
81 = 16777619U;
82#endif
83
86
100MSTL_CONSTEXPR14 size_t FNV_hash(const byte_t* first, const size_t count) noexcept {
101 size_t result = _CONSTANTS FNV_OFFSET_BASIS;
102 for (size_t i = 0; i < count; i++) {
103 result ^= static_cast<size_t>(first[i]);
104 result *= _CONSTANTS FNV_PRIME;
105 }
106 return result;
107}
108
109
112
119template <typename T>
120MSTL_CONSTEXPR14 size_t FNV_hash_integer(const T& value) noexcept {
121 static_assert(is_integral<T>::value, "T must be integral");
122
123 size_t result = _CONSTANTS FNV_OFFSET_BASIS;
124 for (size_t i = 0; i < sizeof(T); ++i) {
125 const byte_t byte_val = static_cast<byte_t>((value >> (i * 8)) & 0xFF);
126 result ^= static_cast<size_t>(byte_val);
127 result *= _CONSTANTS FNV_PRIME;
128 }
129 return result;
130}
131
139template <typename CharT>
140MSTL_CONSTEXPR14 size_t FNV_hash_string(const CharT* str, const size_t len) noexcept {
141 static_assert(is_character<CharT>::value, "CharT must be character types");
142
143 size_t result = _CONSTANTS FNV_OFFSET_BASIS;
144 for (size_t i = 0; i < len; ++i) {
145 result ^= static_cast<size_t>(static_cast<byte_t>(str[i]));
146 result *= _CONSTANTS FNV_PRIME;
147 }
148 return result;
149}
150
153 // FNVHash
155
157
158template <>
159struct hash<bool> {
160 MSTL_NODISCARD constexpr size_t operator ()(const bool x) const noexcept {
161 return x ? 0x9e3779b9 : 0x7f4a7c15;
162 }
163};
164
165#define __MSTL_BUILD_INTEGER_HASH_STRUCT(OPT) \
166template <> struct hash<OPT> { \
167 MSTL_NODISCARD constexpr size_t operator ()(const OPT& x) const noexcept { \
168 return x == 0.0f ? 0 : _INNER FNV_hash_integer(x); \
169 } \
170};
171
172MSTL_MACRO_RANGE_CHARS(__MSTL_BUILD_INTEGER_HASH_STRUCT)
173MSTL_MACRO_RANGE_INT(__MSTL_BUILD_INTEGER_HASH_STRUCT)
174#undef FLOAT_HASH_STRUCT__
175
177template <typename T>
178union __float_converter { T f; uint64_t i; };
180
181#define __MSTL_BUILD_FLOAT_HASH_STRUCT(OPT) \
182template <> \
183struct hash<OPT> { \
184 MSTL_NODISCARD MSTL_CONSTEXPR14 size_t operator ()(const OPT x) const noexcept { \
185 if (x == 0.0f) return 0; \
186 _INNER __float_converter<OPT> converter{}; \
187 converter.f = x; \
188 return _INNER FNV_hash_integer(converter.i); \
189 } \
190};
191
192MSTL_MACRO_RANGE_FLOAT(__MSTL_BUILD_FLOAT_HASH_STRUCT)
193#undef __MSTL_BUILD_FLOAT_HASH_STRUCT
194
196
202
216MSTL_CONSTEXPR14 size_t DJB2_hash(const char* str, const size_t len) noexcept {
217 size_t hash = 5381;
218 for (size_t i = 0; i < len; ++i) {
219 hash = (hash << 5) + hash + static_cast<byte_t>(str[i]);
220 }
221 return hash;
222}
223 // DJB2Hash
225
231
232#ifdef MSTL_DATA_BUS_WIDTH_64__
233
240struct murmur_hash {
241 size_t low = 0;
242 size_t high = 0;
243
244 murmur_hash() noexcept = default;
245 ~murmur_hash() noexcept = default;
246
252 murmur_hash(const size_t l, const size_t h) noexcept
253 : low(l), high(h) {}
254};
255
272murmur_hash MurmurHash_x64(const void* key, size_t len, uint32_t seed) noexcept;
273#endif
274
285uint32_t MurmurHash_x32(const void* key, size_t len, uint32_t seed) noexcept;
286 // MurmurHash
288
294
301template <typename Key, typename Dummy = void>
303
305template <typename Key>
306struct is_nothrow_hashable<Key, void_t<decltype(_MSTL hash<Key>{}(_MSTL declval<const Key&>()))>>
307 : bool_constant<noexcept(_MSTL hash<Key>{}(_MSTL declval<const Key&>()))> {};
309
310#ifdef MSTL_STANDARD_14__
315template <typename Key>
316MSTL_INLINE17 constexpr bool is_nothrow_hashable_v = is_nothrow_hashable<Key>::value;
317#endif
318
319
329template <typename Func, typename Arg, typename Dummy = void>
330struct is_hash : false_type {};
331
333template <typename Func, typename Arg>
334struct is_hash<Func, Arg, enable_if_t<
335 is_convertible<decltype(_MSTL declval<Func>()(_MSTL declval<Arg>())), size_t>::value
336>> : true_type {};
338
339#ifdef MSTL_STANDARD_14__
344template <typename Func, typename Arg>
345constexpr bool is_hash_v = is_hash<Func, Arg>::value;
346#endif
347 // HashTraits
349
351#endif // MSTL_CORE_FUNCTIONAL_HASH_HPP__
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned long long uint64_t
64位无符号整数类型
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
MSTL_CONSTEXPR14 size_t DJB2_hash(const char *str, const size_t len) noexcept
DJB2哈希算法
add_rvalue_reference_t< T > declval() noexcept
获取类型的右值引用,仅用于非求值上下文
MSTL_CONSTEXPR14 size_t FNV_hash(const byte_t *first, const size_t count) noexcept
FNV-1a哈希算法
uint32_t MurmurHash_x32(const void *key, size_t len, uint32_t seed) noexcept
MurmurHash3_x86_32算法
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_CONSTANTS__
结束constants命名空间
#define MSTL_END_INNER__
结束inner命名空间
#define _CONSTANTS
constants命名空间前缀
#define MSTL_BEGIN_CONSTANTS__
开始constants命名空间
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
uint64_t size_t
无符号大小类型
uint64_t uintptr_t
可容纳指针的无符号整数类型
bool_constant< true > true_type
表示true的类型
void void_t
将任意类型映射为void
bool_constant< false > false_type
表示false的类型
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
哈希函数的主模板
判断类型From是否可以隐式转换为类型To
判断类型是否为有效的哈希函数
判断类型是否可无异常哈希
MSTL类型萃取