diff --git a/include/boost/container_hash/hash.hpp b/include/boost/container_hash/hash.hpp index 4012fc9..733d934 100644 --- a/include/boost/container_hash/hash.hpp +++ b/include/boost/container_hash/hash.hpp @@ -637,22 +637,54 @@ namespace boost // template - inline std::size_t hash_range(It first, It last) + inline void hash_range( std::size_t& seed, It first, It last ) + { + for( ; first != last; ++first ) + { + hash_combine::value_type>( seed, *first ); + } + } + + template + inline std::size_t hash_range( It first, It last ) { std::size_t seed = 0; - hash_range(seed, first, last); + hash_range( seed, first, last ); return seed; } + // + // boost::hash_unordered_range + // + template - inline void hash_range(std::size_t& seed, It first, It last) + inline void hash_unordered_range( std::size_t& seed, It first, It last ) { - for(; first != last; ++first) + std::size_t r = 0; + std::size_t const s2( seed ); + + for( ; first != last; ++first ) { - hash_combine::value_type>(seed, *first); + std::size_t s3( s2 ); + + hash_combine::value_type>( s3, *first ); + + r += s3; } + + seed += r; + } + + template + inline std::size_t hash_unordered_range( It first, It last ) + { + std::size_t seed = 0; + + hash_unordered_range( seed, first, last ); + + return seed; } // diff --git a/include/boost/container_hash/hash_fwd.hpp b/include/boost/container_hash/hash_fwd.hpp index 6311d12..f3a30e5 100644 --- a/include/boost/container_hash/hash_fwd.hpp +++ b/include/boost/container_hash/hash_fwd.hpp @@ -24,11 +24,11 @@ template struct hash; template void hash_combine( std::size_t& seed, T const& v ); -template std::size_t hash_range( It, It ); template void hash_range( std::size_t&, It, It ); +template std::size_t hash_range( It, It ); -template std::size_t hash_unordered_range( It, It ); template void hash_unordered_range( std::size_t&, It, It ); +template std::size_t hash_unordered_range( It, It ); } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 924529b..c9fbcae 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -89,3 +89,5 @@ run hash_string_test4.cpp ; run hash_multiset_test.cpp ; run hash_multimap_test.cpp ; + +run hash_unordered_range_test.cpp ; diff --git a/test/hash_unordered_range_test.cpp b/test/hash_unordered_range_test.cpp new file mode 100644 index 0000000..5b8de86 --- /dev/null +++ b/test/hash_unordered_range_test.cpp @@ -0,0 +1,33 @@ +// Copyright 2021, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +int main() +{ + int const N = 16; + + std::vector v; + + for( int i = 0; i < N; ++i ) + { + v.push_back( i ); + } + + std::size_t h0 = boost::hash_unordered_range( v.begin(), v.end() ); + + int const M = 256; + + for( int i = 0; i < M; ++i ) + { + std::next_permutation( v.begin(), v.end() ); + std::size_t h1 = boost::hash_unordered_range( v.begin(), v.end() ); + BOOST_TEST_EQ( h0, h1 ); + } + + return boost::report_errors(); +}