Update Reference section

This commit is contained in:
Peter Dimov
2022-09-19 11:56:03 +03:00
parent c01270b0bd
commit 75a37c2616

View File

@@ -172,31 +172,46 @@ where `combine(s, v)` is a mixing function that takes two arguments of
type `std::size_t` and returns `std::size_t`, with the following desirable
properties:
* For a constant `s`, when `v` takes all possible `size_t` values,
. For a constant `s`, when `v` takes all possible `size_t` values,
`combine(s, v)` should also take all possible `size_t` values, producing
a sequence that is close to random; that is, it should be a random
permutation.
+
This guarantees that for a given `seed`, `combine` does not introduce
hash collisions when none were produced by `boost::hash<T>( v )`. It
also implies that `combine(s, v)`, as a function of `v`, has good avalanche
properties; that is, small (e.g. single bit) perturbations in the input `v`
lead to large perturbations in the return value (half of the output bits
changing, on average).
hash collisions when none were produced by `boost::hash<T>(v)`; that is,
it does not lose information from the input. It also implies that
`combine(s, v)`, as a function of `v`, has good avalanche properties;
that is, small (e.g. single bit) perturbations in the input `v` lead to
large perturbations in the return value (half of the output bits changing,
on average).
* For two different seeds `s1` and `s2`, `combine(s1, v)` and
. For two different seeds `s1` and `s2`, `combine(s1, v)` and
`combine(s2, v)`, treated as functions of `v`, should produce two
different random permutations.
* `combine(0, 0)` should not be 0. Since a common initial value of `seed`
. `combine(0, 0)` should not be 0. Since a common initial value of `seed`
is zero, `combine(0, 0) == 0` would imply that applying `hash_combine` on
any sequence of zeroes, regardless of length, will produce zero. This is
undesirable, as it would lead to e.g. `std::vector<int>()` and
`std::vector<int>(4)` to have the same hash value.
The current implementation uses the function `mix(s + 0x9e3779b9 + v)` as
`combine(s, v)`, where `mix` is a high quality random permutation over the
`std::size_t` values (with the property that `mix(0)` is 0).
`combine(s, v)`, where `mix(x)` is a high quality mixing function that is a
bijection over the `std::size_t` values, of the form
[source]
----
x ^= x >> k1;
x *= m1;
x ^= x >> k2;
x *= m2;
x ^= x >> k3;
----
where the constants `k1`, `k2`, `k3`, `m1`, `m2` are suitably chosen.
Note that `mix(0)` is 0. This is why we add the arbitrary constant
`0x9e3779b9` to meet the third requirement above.
--
=== hash_range
@@ -208,14 +223,23 @@ template<class It> void hash_range( std::size_t& seed, It first, It last );
Effects: ::
+
--
When `typename std::iterator_traits<It>::value_type` is not `char`, `signed char`,
`unsigned char`,
[source]
----
for( ; first != last; ++first )
{
hash_combine<typename std::iterator_traits<It>::value_type>( seed, *first );
boost::hash_combine<typename std::iterator_traits<It>::value_type>( seed, *first );
}
----
Otherwise, bytes from `[first, last)` are coalesced in an unspecified manner
and then passed to `hash_combine`, more than one at a time. This is done in
order to improve performance when hashing strings.
--
[source]
----
template<class It> std::size_t hash_range( It first, It last );
@@ -226,7 +250,7 @@ Effects: ::
[source]
----
size_t seed = 0;
hash_range( seed, first, last );
boost::hash_range( seed, first, last );
return seed;
----
@@ -252,7 +276,7 @@ Effects: ::
[source]
----
size_t seed = 0;
hash_unordered_range( seed, first, last );
boost::hash_unordered_range( seed, first, last );
return seed;
----
@@ -315,7 +339,7 @@ template<class T, std::size_t N>
----
Returns: ::
`hash_range( v, v + N )`.
`boost::hash_range( v, v + N )`.
[source]
----
@@ -384,7 +408,7 @@ template<class T>
----
Returns: ::
`hash_range( v.begin(), v.end() )`.
`boost::hash_range( v.begin(), v.end() )`.
Remarks: ::
This overload is only enabled when
@@ -402,7 +426,7 @@ template<class T>
----
Returns: ::
`hash_range( v.data(), v.data() + v.size() )`.
`boost::hash_range( v.data(), v.data() + v.size() )`.
Remarks: ::
This overload handles all standard contiguous containers, such as
@@ -416,7 +440,7 @@ template<class T>
----
Returns: ::
`hash_unordered_range( v.begin(), v.end() )`.
`boost::hash_unordered_range( v.begin(), v.end() )`.
Remarks: ::
This overload handles the standard unordered containers, such as
@@ -432,7 +456,7 @@ template<class T, class D>
----
Returns: ::
`hash<T*>( v.get() )`.
`boost::hash<T*>( v.get() )`.
[source]
----
@@ -468,7 +492,7 @@ template<class T>
Returns: ::
For a disengaged `v`, an unspecified constant value; otherwise,
`hash<T>()( *v )`.
`boost::hash<T>()( *v )`.
[source]
----