diff --git a/sprout/functional/hash/hash.hpp b/sprout/functional/hash/hash.hpp index e2ac263a..b62983c2 100644 --- a/sprout/functional/hash/hash.hpp +++ b/sprout/functional/hash/hash.hpp @@ -85,11 +85,11 @@ namespace sprout { ); } - SPROUT_CONSTEXPR inline std::size_t hash_value_pointer_1(std::size_t x) { + inline std::size_t hash_value_pointer_1(std::size_t x) { return x + (x >> 3); } template - SPROUT_CONSTEXPR std::size_t hash_value_pointer(T* v) { + std::size_t hash_value_pointer(T const* v) { return sprout::hash_detail::hash_value_pointer_1(static_cast(reinterpret_cast(v))); } } // namespace hash_detail @@ -145,12 +145,21 @@ namespace sprout { return sprout::hash_range(&v[0], &v[0] + N); } + // + // to_hash + // + template + SPROUT_CONSTEXPR std::size_t to_hash(T const& v) { + using sprout::hash_value; + return hash_value(v); + } + // // hash_combine // template SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v) { - return seed ^ (sprout::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); + return seed ^ (sprout::to_hash(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); } // @@ -178,8 +187,7 @@ namespace sprout { typedef std::size_t result_type; public: SPROUT_CONSTEXPR std::size_t operator()(T const& v) const { - using sprout::hash_value; - return hash_value(v); + return sprout::to_hash(v); } }; @@ -224,16 +232,26 @@ namespace sprout { #undef SPROUT_HASH_SPECIALIZE_REF template - struct hash { + struct hash { public: - typedef T* argument_type; + typedef T argument_type; typedef std::size_t result_type; public: - SPROUT_CONSTEXPR std::size_t operator()(T* v) const { + SPROUT_CONSTEXPR std::size_t operator()(T const& v) const { using sprout::hash_value; return hash_value(v); } }; + template + struct hash { + 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); + } + }; } //namespace sprout #endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_HPP diff --git a/sprout/functional/hash/hash_fwd.hpp b/sprout/functional/hash/hash_fwd.hpp index c442c436..2f54e6a2 100644 --- a/sprout/functional/hash/hash_fwd.hpp +++ b/sprout/functional/hash/hash_fwd.hpp @@ -11,6 +11,12 @@ namespace sprout { template struct hash; + // + // to_hash + // + template + SPROUT_CONSTEXPR std::size_t to_hash(T const& v); + // // hash_combine // diff --git a/sprout/random/unique_seed.hpp b/sprout/random/unique_seed.hpp index b201ab44..5d9956c1 100644 --- a/sprout/random/unique_seed.hpp +++ b/sprout/random/unique_seed.hpp @@ -1,22 +1,56 @@ #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP #define SPROUT_RANDOM_UNIQUE_SEED_HPP -#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR -# include -# include -#endif +#include +#include #include +#include #include #include +namespace sprout { + // + // make_seed + // + template + SPROUT_CONSTEXPR std::size_t make_seed(T const& v) { + return sprout::to_hash(v); + } + + namespace detail { + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) + 1 == N, + sprout::array + >::type make_seed_seq_impl(T const& v, std::size_t seed, Args const&... args) { + return sprout::array{{args..., seed}}; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) + 1 != N, + sprout::array + >::type make_seed_seq_impl(T const& v, std::size_t seed, Args const&... args) { + return sprout::detail::make_seed_seq_impl(v, sprout::hash_combine(seed, v), args..., seed); + } + } // namespace detail + // + // make_seed_seq + // + template + SPROUT_CONSTEXPR sprout::array make_seed_seq(T const& v) { + return sprout::detail::make_seed_seq_impl(v, sprout::to_hash(v)); + } +} // namespace sprout + // // SPROUT_UNIQUE_SEED // -#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR -# define SPROUT_UNIQUE_SEED (::std::integral_constant< ::std::size_t, ::sprout::hash_value(SPROUT_PP_UNIQUE_STRING)>::value) -#else -# define SPROUT_UNIQUE_SEED (::sprout::hash_value(SPROUT_PP_UNIQUE_STRING)) -#endif +#define SPROUT_UNIQUE_SEED (::sprout::make_seed(SPROUT_PP_UNIQUE_STRING)) + +// +// SPROUT_UNIQUE_SEED_SEQ +// +#define SPROUT_UNIQUE_SEED_SEQ(N) (::sprout::make_seed_seq(SPROUT_PP_UNIQUE_STRING)) #endif // #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP