remove custom hashing
parent
343c684820
commit
1db7529ad9
|
@ -222,223 +222,6 @@ T from_lil_endian(T x) { return FromLilEndian<T>()(x); }
|
|||
template<typename T>
|
||||
T from_big_endian(T x) { return FromBigEndian<T>()(x); }
|
||||
|
||||
/* hash */
|
||||
|
||||
template<typename T>
|
||||
struct ToHash {
|
||||
using Argument = T;
|
||||
using Result = Size;
|
||||
|
||||
Size operator()(T const &v) const {
|
||||
return v.to_hash();
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct ToHashBase {
|
||||
using Argument = T;
|
||||
using Result = Size;
|
||||
|
||||
Size operator()(T v) const {
|
||||
return Size(v);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define OSTD_HASH_BASIC(T) \
|
||||
template<> \
|
||||
struct ToHash<T>: detail::ToHashBase<T> {};
|
||||
|
||||
OSTD_HASH_BASIC(bool)
|
||||
OSTD_HASH_BASIC(char)
|
||||
OSTD_HASH_BASIC(short)
|
||||
OSTD_HASH_BASIC(int)
|
||||
OSTD_HASH_BASIC(long)
|
||||
|
||||
OSTD_HASH_BASIC(sbyte)
|
||||
OSTD_HASH_BASIC(byte)
|
||||
OSTD_HASH_BASIC(ushort)
|
||||
OSTD_HASH_BASIC(uint)
|
||||
OSTD_HASH_BASIC(ulong)
|
||||
|
||||
#ifndef OSTD_TYPES_CHAR_16_32_NO_BUILTINS
|
||||
OSTD_HASH_BASIC(Char16)
|
||||
OSTD_HASH_BASIC(Char32)
|
||||
#endif
|
||||
OSTD_HASH_BASIC(Wchar)
|
||||
|
||||
#undef OSTD_HASH_BASIC
|
||||
|
||||
namespace detail {
|
||||
template<Size E>
|
||||
struct FnvConstants {
|
||||
static constexpr Size prime = 16777619u;
|
||||
static constexpr Size offset = 2166136261u;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct FnvConstants<8> {
|
||||
/* conversion is necessary here because when compiling on
|
||||
* 32bit, compilers will complain, despite this template
|
||||
* not being instantiated...
|
||||
*/
|
||||
static constexpr Size prime = Size(1099511628211u);
|
||||
static constexpr Size offset = Size(14695981039346656037u);
|
||||
};
|
||||
|
||||
inline Size mem_hash(void const *p, Size l) {
|
||||
using Consts = FnvConstants<sizeof(Size)>;
|
||||
byte const *d = static_cast<byte const *>(p);
|
||||
Size h = Consts::offset;
|
||||
for (byte const *it = d, *end = d + l; it != end; ++it) {
|
||||
h ^= *it;
|
||||
h *= Consts::prime;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
template<typename T, Size = sizeof(T) / sizeof(Size)>
|
||||
struct ScalarHash;
|
||||
|
||||
template<typename T>
|
||||
struct ScalarHash<T, 0> {
|
||||
using Argument = T;
|
||||
using Result = Size;
|
||||
|
||||
Size operator()(T v) const {
|
||||
union { T v; Size h; } u;
|
||||
u.h = 0;
|
||||
u.v = v;
|
||||
return u.h;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ScalarHash<T, 1> {
|
||||
using Argument = T;
|
||||
using Result = Size;
|
||||
|
||||
Size operator()(T v) const {
|
||||
union { T v; Size h; } u;
|
||||
u.v = v;
|
||||
return u.h;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ScalarHash<T, 2> {
|
||||
using Argument = T;
|
||||
using Result = Size;
|
||||
|
||||
Size operator()(T v) const {
|
||||
union { T v; struct { Size h1, h2; }; } u;
|
||||
u.v = v;
|
||||
return mem_hash(static_cast<void const *>(&u), sizeof(u));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ScalarHash<T, 3> {
|
||||
using Argument = T;
|
||||
using Result = Size;
|
||||
|
||||
Size operator()(T v) const {
|
||||
union { T v; struct { Size h1, h2, h3; }; } u;
|
||||
u.v = v;
|
||||
return mem_hash(static_cast<void const *>(&u), sizeof(u));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ScalarHash<T, 4> {
|
||||
using Argument = T;
|
||||
using Result = Size;
|
||||
|
||||
Size operator()(T v) const {
|
||||
union { T v; struct { Size h1, h2, h3, h4; }; } u;
|
||||
u.v = v;
|
||||
return mem_hash(static_cast<void const *>(&u), sizeof(u));
|
||||
}
|
||||
};
|
||||
} /* namespace detail */
|
||||
|
||||
template<>
|
||||
struct ToHash<llong>: detail::ScalarHash<llong> {};
|
||||
template<>
|
||||
struct ToHash<ullong>: detail::ScalarHash<ullong> {};
|
||||
|
||||
template<>
|
||||
struct ToHash<float>: detail::ScalarHash<float> {
|
||||
Size operator()(float v) const {
|
||||
if (v == 0) return 0;
|
||||
return detail::ScalarHash<float>::operator()(v);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ToHash<double>: detail::ScalarHash<double> {
|
||||
Size operator()(double v) const {
|
||||
if (v == 0) return 0;
|
||||
return detail::ScalarHash<double>::operator()(v);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ToHash<ldouble>: detail::ScalarHash<ldouble> {
|
||||
Size operator()(ldouble v) const {
|
||||
if (v == 0) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef __i386__
|
||||
union { ldouble v; struct { Size h1, h2, h3, h4; }; } u;
|
||||
u.h1 = u.h2 = u.h3 = u.h4 = 0;
|
||||
u.v = v;
|
||||
return (u.h1 ^ u.h2 ^ u.h3 ^ u.h4);
|
||||
#else
|
||||
#ifdef __x86_64__
|
||||
union { ldouble v; struct { Size h1, h2; }; } u;
|
||||
u.h1 = u.h2 = 0;
|
||||
u.v = v;
|
||||
return (u.h1 ^ u.h2);
|
||||
#else
|
||||
return detail::ScalarHash<ldouble>::operator()(v);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template<typename T, bool = IsSame<RemoveConst<T>, char>>
|
||||
struct ToHashPtr {
|
||||
using Argument = T *;
|
||||
using Result = Size;
|
||||
Size operator()(T *v) const {
|
||||
union { T *v; Size h; } u;
|
||||
u.v = v;
|
||||
return detail::mem_hash(static_cast<void const *>(&u), sizeof(u));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ToHashPtr<T, true> {
|
||||
using Argument = T *;
|
||||
using Result = Size;
|
||||
Size operator()(T *v) const {
|
||||
return detail::mem_hash(v, strlen(v));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct ToHash<T *>: detail::ToHashPtr<T> {};
|
||||
|
||||
template<typename T>
|
||||
typename ToHash<T>::Result to_hash(T const &v) {
|
||||
return ToHash<T>()(v);
|
||||
}
|
||||
|
||||
} /* namespace ostd */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -184,7 +184,7 @@ namespace detail {
|
|||
|
||||
template<
|
||||
typename T,
|
||||
typename H = ToHash<detail::KeysetKey<T>>,
|
||||
typename H = std::hash<detail::KeysetKey<T>>,
|
||||
typename C = EqualWithCstr<detail::KeysetKey<T>>,
|
||||
typename A = Allocator<T>
|
||||
>
|
||||
|
@ -197,7 +197,7 @@ inline void swap(Keyset<T, H, C, A> &a, Keyset<T, H, C, A> &b) {
|
|||
|
||||
template<
|
||||
typename T,
|
||||
typename H = ToHash<detail::KeysetKey<T>>,
|
||||
typename H = std::hash<detail::KeysetKey<T>>,
|
||||
typename C = EqualWithCstr<detail::KeysetKey<T>>,
|
||||
typename A = Allocator<T>
|
||||
>
|
||||
|
|
|
@ -186,7 +186,7 @@ namespace detail {
|
|||
|
||||
template<
|
||||
typename K, typename T,
|
||||
typename H = ToHash<K>,
|
||||
typename H = std::hash<K>,
|
||||
typename C = EqualWithCstr<K>,
|
||||
typename A = Allocator<std::pair<K const, T>>
|
||||
>
|
||||
|
@ -199,7 +199,7 @@ inline void swap(Map<K, T, H, C, A> &a, Map<K, T, H, C, A> &b) {
|
|||
|
||||
template<
|
||||
typename K, typename T,
|
||||
typename H = ToHash<K>,
|
||||
typename H = std::hash<K>,
|
||||
typename C = EqualWithCstr<K>,
|
||||
typename A = Allocator<std::pair<K const, T>>
|
||||
>
|
||||
|
|
|
@ -301,10 +301,6 @@ public:
|
|||
swap(this->p_engaged, v.p_engaged);
|
||||
}
|
||||
}
|
||||
|
||||
Size to_hash() const {
|
||||
return this->p_engaged ? ostd::ToHash<T>()(this->p_value) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -157,7 +157,7 @@ namespace detail {
|
|||
|
||||
template<
|
||||
typename T,
|
||||
typename H = ToHash<T>,
|
||||
typename H = std::hash<T>,
|
||||
typename C = EqualWithCstr<T>,
|
||||
typename A = Allocator<T>
|
||||
>
|
||||
|
@ -170,7 +170,7 @@ inline void swap(Set<T, H, C, A> &a, Set<T, H, C, A> &b) {
|
|||
|
||||
template<
|
||||
typename T,
|
||||
typename H = ToHash<T>,
|
||||
typename H = std::hash<T>,
|
||||
typename C = EqualWithCstr<T>,
|
||||
typename A = Allocator<T>
|
||||
>
|
||||
|
|
|
@ -167,10 +167,6 @@ public:
|
|||
T *data() { return p_beg; }
|
||||
T const *data() const { return p_beg; }
|
||||
|
||||
Size to_hash() const {
|
||||
return detail::mem_hash(data(), size());
|
||||
}
|
||||
|
||||
/* non-range */
|
||||
int compare(CharRangeBase<T const> s) const {
|
||||
ostd::Size s1 = size(), s2 = s.size();
|
||||
|
@ -681,17 +677,6 @@ inline TempCString<R> to_temp_cstr(
|
|||
return TempCString<R>(input, buf, bufsize);
|
||||
}
|
||||
|
||||
/* temporary */
|
||||
template<>
|
||||
struct ToHash<std::string> {
|
||||
using Argument = std::string;
|
||||
using Result = size_t;
|
||||
|
||||
size_t operator()(std::string const &v) const {
|
||||
return std::hash<std::string>{}(v);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace ostd */
|
||||
|
||||
namespace std {
|
||||
|
|
Loading…
Reference in New Issue