remove custom hashing

master
Daniel Kolesa 2017-01-30 18:56:38 +01:00
parent 343c684820
commit 1db7529ad9
6 changed files with 6 additions and 242 deletions

View File

@ -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

View File

@ -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>
>

View File

@ -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>>
>

View File

@ -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>

View File

@ -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>
>

View File

@ -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 {