diff --git a/sprout/functional/hash.hpp b/sprout/functional/hash.hpp index 2d6de228..d98932d7 100644 --- a/sprout/functional/hash.hpp +++ b/sprout/functional/hash.hpp @@ -7,8 +7,7 @@ #include #include #include -#include -#include #include +#include #endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP diff --git a/sprout/functional/hash/hash_combine.hpp b/sprout/functional/hash/hash_combine.hpp index 0cd8f1f4..36de65de 100644 --- a/sprout/functional/hash/hash_combine.hpp +++ b/sprout/functional/hash/hash_combine.hpp @@ -7,13 +7,30 @@ #include namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR std::size_t + hash_combine_impl(std::size_t seed) { + return seed; + } + template + inline SPROUT_CONSTEXPR std::size_t + hash_combine_impl(std::size_t seed, T const& v) { + return seed ^ (sprout::to_hash(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); + } + template + inline SPROUT_CONSTEXPR std::size_t + hash_combine_impl(std::size_t seed, Head const& head, Tail const&... tail) { + return sprout::detail::hash_combine_impl(sprout::detail::hash_combine_impl(seed, head), tail...); + } + } // namespace detail // // hash_combine // - template + template inline SPROUT_CONSTEXPR std::size_t - hash_combine(std::size_t seed, T const& v) { - return seed ^ (sprout::to_hash(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); + hash_combine(std::size_t seed, Args const&... args) { + return sprout::detail::hash_combine_impl(seed, args...); } } // namespace sprout diff --git a/sprout/functional/hash/hash_fwd.hpp b/sprout/functional/hash/hash_fwd.hpp index 1227a3d9..05dd4f13 100644 --- a/sprout/functional/hash/hash_fwd.hpp +++ b/sprout/functional/hash/hash_fwd.hpp @@ -20,23 +20,9 @@ namespace sprout { // // hash_combine // - template - SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v); - - // - // hash_range - // - template - SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last); - template - SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last); - - // - // hash_values_combine - // template inline SPROUT_CONSTEXPR std::size_t - hash_values_combine(std::size_t seed, Args const&... args); + hash_combine(std::size_t seed, Args const&... args); // // hash_values @@ -44,6 +30,18 @@ namespace sprout { template inline SPROUT_CONSTEXPR std::size_t hash_values(Args const&... args); + + // + // hash_range + // + template + SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last); + template + SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last); + template + SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, InputRange const& rng); + template + SPROUT_CONSTEXPR std::size_t hash_range(InputRange const& rng); } // namespace sprout #endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP diff --git a/sprout/functional/hash/hash_range.hpp b/sprout/functional/hash/hash_range.hpp index 6048d1db..c11e1468 100644 --- a/sprout/functional/hash/hash_range.hpp +++ b/sprout/functional/hash/hash_range.hpp @@ -5,25 +5,49 @@ #include #include #include -#include +#include +#include namespace sprout { + // + // hash_combine_accumulator + // + template + struct hash_combine_accumulator { + public: + typedef T first_argument_type; + typedef T result_type; + public: + template + SPROUT_CONSTEXPR T operator()(T const& seed, U const& v) const { + return sprout::hash_combine(seed, v); + } + }; + // // hash_range // template inline SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, InputIterator first, InputIterator last) { - return first != last - ? sprout::hash_range(sprout::hash_combine(seed, *first), sprout::next(first), last) - : seed - ; + return sprout::accumulate(first, last, seed, sprout::hash_combine_accumulator<>()); } template inline SPROUT_CONSTEXPR std::size_t hash_range(InputIterator first, InputIterator last) { return sprout::hash_range(0, first, last); } + + template + inline SPROUT_CONSTEXPR std::size_t + hash_range(std::size_t seed, InputRange const& rng) { + return sprout::hash_range(seed, sprout::begin(rng), sprout::end(rng)); + } + template + inline SPROUT_CONSTEXPR std::size_t + hash_range(InputRange const& rng) { + return sprout::hash_range(0, rng); + } } // namespace sprout #endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_RANGE_HPP diff --git a/sprout/functional/hash/hash_values.hpp b/sprout/functional/hash/hash_values.hpp index 81bcf1cc..20dac850 100644 --- a/sprout/functional/hash/hash_values.hpp +++ b/sprout/functional/hash/hash_values.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include namespace sprout { // @@ -13,7 +13,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR std::size_t hash_values(Args const&... args) { - return sprout::hash_values_combine(0, args...); + return sprout::hash_combine(0, args...); } } // namespace sprout diff --git a/sprout/functional/hash/hash_values_combine.hpp b/sprout/functional/hash/hash_values_combine.hpp deleted file mode 100644 index 5c6d1c11..00000000 --- a/sprout/functional/hash/hash_values_combine.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_HASH_VALUES_COMBINE_HPP -#define SPROUT_FUNCTIONAL_HASH_HASH_VALUES_COMBINE_HPP - -#include -#include -#include -#include - -namespace sprout { - namespace detail { - template - inline SPROUT_CONSTEXPR std::size_t - hash_values_combine_impl(std::size_t seed, T const& v) { - return sprout::hash_combine(seed, v); - } - template - inline SPROUT_CONSTEXPR std::size_t - hash_values_combine_impl(std::size_t seed, Head const& head, Tail const&... tail) { - return sprout::detail::hash_values_combine_impl(sprout::hash_combine(seed, head), tail...); - } - } // namespace detail - - // - // hash_values_combine - // - template - inline SPROUT_CONSTEXPR std::size_t - hash_values_combine(std::size_t seed, Args const&... args) { - return sprout::detail::hash_values_combine_impl(seed, args...); - } -} // namespace sprout - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_VALUES_COMBINE_HPP