diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2014-12-16 18:57:19 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2014-12-16 18:57:19 +0000 |
| commit | ebecd60eb810246cfa682a1fbd72270aa9861f0b (patch) | |
| tree | 0c5c707b68cb08fc93ace2433291deb8a52db5bc /src/hash.hh | |
| parent | dbd7bd41bbf39d1fd5736997122a4652c78ddc50 (diff) | |
Rework hashing, use a more extensible framework similar to n3876 proposal
std::hash specialization is a pain to work with, stop using that, and
just specialize a 'size_t hash_value(const T&)' free function.
Diffstat (limited to 'src/hash.hh')
| -rw-r--r-- | src/hash.hh | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/hash.hh b/src/hash.hh new file mode 100644 index 00000000..838fdffa --- /dev/null +++ b/src/hash.hh @@ -0,0 +1,57 @@ +#ifndef hash_hh_INCLUDED +#define hash_hh_INCLUDED + +#include <type_traits> +#include <functional> + +namespace Kakoune +{ + +size_t hash_data(const char* data, size_t len); + +template<typename Type> +typename std::enable_if<not std::is_enum<Type>::value, size_t>::type +hash_value(const Type& val) +{ + return std::hash<Type>()(val); +} + +template<typename Type> +typename std::enable_if<std::is_enum<Type>::value, size_t>::type +hash_value(const Type& val) +{ + return hash_value((typename std::underlying_type<Type>::type)val); +} + +template<typename Type> +size_t hash_values(Type&& t) +{ + return hash_value(std::forward<Type>(t)); +} + +template<typename Type, typename... RemainingTypes> +size_t hash_values(Type&& t, RemainingTypes&&... rt) +{ + size_t seed = hash_values(std::forward<RemainingTypes>(rt)...); + return seed ^ (hash_value(std::forward<Type>(t)) + 0x9e3779b9 + + (seed << 6) + (seed >> 2)); +} + +template<typename T1, typename T2> +size_t hash_value(const std::pair<T1, T2>& val) +{ + return hash_values(val.first, val.second); +} + +template<typename Type> +struct Hash +{ + size_t operator()(const Type& val) const + { + return hash_value(val); + } +}; + +} + +#endif // hash_hh_INCLUDED |
