fix hash implementation

This commit is contained in:
bolero-MURAKAMI 2012-06-21 00:57:27 +09:00
parent 635145eda5
commit 1f041c0edc

View file

@ -3,9 +3,11 @@
#include <cstddef> #include <cstddef>
#include <limits> #include <limits>
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/functional/hash/hash_fwd.hpp> #include <sprout/functional/hash/hash_fwd.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
// //
@ -29,8 +31,11 @@ namespace sprout {
//inline SPROUT_CONSTEXPR std::size_t hash_value(float v); //inline SPROUT_CONSTEXPR std::size_t hash_value(float v);
//inline SPROUT_CONSTEXPR std::size_t hash_value(double v); //inline SPROUT_CONSTEXPR std::size_t hash_value(double v);
//inline SPROUT_CONSTEXPR std::size_t hash_value(long double v); //inline SPROUT_CONSTEXPR std::size_t hash_value(long double v);
template<typename T> template<
SPROUT_CONSTEXPR std::size_t hash_value(T*); typename T,
typename sprout::enabler_if<std::is_pointer<typename std::remove_reference<T>::type>::value>::type
>
SPROUT_CONSTEXPR std::size_t hash_value(T&& v);
template<typename T, std::size_t N> template<typename T, std::size_t N>
SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]); SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]);
@ -144,15 +149,17 @@ namespace sprout {
inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned long long v) { inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned long long v) {
return sprout::hash_detail::hash_value_unsigned(v); return sprout::hash_detail::hash_value_unsigned(v);
} }
template<typename T> template<
SPROUT_CONSTEXPR std::size_t hash_value(T* v) { typename T,
typename sprout::enabler_if<std::is_pointer<typename std::remove_reference<T>::type>::value>::type = sprout::enabler
>
SPROUT_CONSTEXPR std::size_t hash_value(T&& v) {
return sprout::hash_detail::hash_value_pointer(v); return sprout::hash_detail::hash_value_pointer(v);
} }
// !!! template<typename T, std::size_t N>
// template<typename T, std::size_t N> SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]) {
// SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]) { return sprout::hash_range(&v[0], &v[0] + N);
// return sprout::hash_range(&v[0], &v[0] + N); }
// }
// //
// to_hash // to_hash
@ -162,10 +169,6 @@ namespace sprout {
using sprout::hash_value; using sprout::hash_value;
return hash_value(v); return hash_value(v);
} }
template<typename T, std::size_t N>
SPROUT_CONSTEXPR std::size_t to_hash(T const (&v)[N]) {
return sprout::hash_range(&v[0], &v[0] + N);
}
// //
// hash_combine // hash_combine
@ -203,6 +206,18 @@ namespace sprout {
return sprout::to_hash(v); return sprout::to_hash(v);
} }
}; };
template<typename T>
struct hash<T const>
: public sprout::hash<T>
{};
template<typename T>
struct hash<T volatile>
: public sprout::hash<T>
{};
template<typename T>
struct hash<T const volatile>
: public sprout::hash<T>
{};
#define SPROUT_HASH_SPECIALIZE(type) \ #define SPROUT_HASH_SPECIALIZE(type) \
template<> \ template<> \
@ -212,7 +227,7 @@ namespace sprout {
typedef std::size_t result_type; \ typedef std::size_t result_type; \
public: \ public: \
SPROUT_CONSTEXPR std::size_t operator()(type v) const { \ SPROUT_CONSTEXPR std::size_t operator()(type v) const { \
return sprout::hash_value(v); \ return sprout::to_hash(v); \
} \ } \
} }
#define SPROUT_HASH_SPECIALIZE_REF(type) \ #define SPROUT_HASH_SPECIALIZE_REF(type) \
@ -223,7 +238,7 @@ namespace sprout {
typedef std::size_t result_type; \ typedef std::size_t result_type; \
public: \ public: \
SPROUT_CONSTEXPR std::size_t operator()(type const& v) const { \ SPROUT_CONSTEXPR std::size_t operator()(type const& v) const { \
return sprout::hash_value(v); \ return sprout::to_hash(v); \
} \ } \
} }
@ -247,23 +262,12 @@ namespace sprout {
#undef SPROUT_HASH_SPECIALIZE_REF #undef SPROUT_HASH_SPECIALIZE_REF
template<typename T> template<typename T>
struct hash<T const> { struct hash<T*> {
public: public:
typedef T argument_type; typedef T* argument_type;
typedef std::size_t result_type; typedef std::size_t result_type;
public: public:
SPROUT_CONSTEXPR std::size_t operator()(T const& v) const { std::size_t operator()(T* v) const {
using sprout::hash_value;
return hash_value(v);
}
};
template<typename T>
struct hash<T const*> {
public:
typedef T const* argument_type;
typedef std::size_t result_type;
public:
std::size_t operator()(T const* v) const {
return sprout::to_hash(v); return sprout::to_hash(v);
} }
}; };