Implement boost::hash_unordered_range

This commit is contained in:
Peter Dimov
2022-09-15 18:00:04 +03:00
parent e387d14d36
commit ce734b435e
4 changed files with 74 additions and 7 deletions

View File

@@ -637,22 +637,54 @@ namespace boost
// //
template <class It> template <class It>
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<typename std::iterator_traits<It>::value_type>( seed, *first );
}
}
template <class It>
inline std::size_t hash_range( It first, It last )
{ {
std::size_t seed = 0; std::size_t seed = 0;
hash_range(seed, first, last); hash_range( seed, first, last );
return seed; return seed;
} }
//
// boost::hash_unordered_range
//
template <class It> template <class It>
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<typename std::iterator_traits<It>::value_type>(seed, *first); std::size_t s3( s2 );
hash_combine<typename std::iterator_traits<It>::value_type>( s3, *first );
r += s3;
} }
seed += r;
}
template <class It>
inline std::size_t hash_unordered_range( It first, It last )
{
std::size_t seed = 0;
hash_unordered_range( seed, first, last );
return seed;
} }
// //

View File

@@ -24,11 +24,11 @@ template<class T> struct hash;
template<class T> void hash_combine( std::size_t& seed, T const& v ); template<class T> void hash_combine( std::size_t& seed, T const& v );
template<class It> std::size_t hash_range( It, It );
template<class It> void hash_range( std::size_t&, It, It ); template<class It> void hash_range( std::size_t&, It, It );
template<class It> std::size_t hash_range( It, It );
template<class It> std::size_t hash_unordered_range( It, It );
template<class It> void hash_unordered_range( std::size_t&, It, It ); template<class It> void hash_unordered_range( std::size_t&, It, It );
template<class It> std::size_t hash_unordered_range( It, It );
} // namespace boost } // namespace boost

View File

@@ -89,3 +89,5 @@ run hash_string_test4.cpp ;
run hash_multiset_test.cpp ; run hash_multiset_test.cpp ;
run hash_multimap_test.cpp ; run hash_multimap_test.cpp ;
run hash_unordered_range_test.cpp ;

View File

@@ -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 <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <algorithm>
#include <vector>
int main()
{
int const N = 16;
std::vector<int> 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();
}