<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="">:idprefix: hash_equality_</string>
    <string name="">= Equality Predicates and Hash Functions</string>
    <string name="">While the associative containers use an ordering relation to specify how the elements are stored, the unordered associative containers use an equality predicate and a hash function. For example, `xref:reference/unordered_map.adoc[boost::unordered_map]` is declared as:</string>
    <string name="">```cpp template &lt; class Key, class Mapped, class Hash = boost::hash&lt;Key&gt;, class Pred = std::equal_to&lt;Key&gt;, class Alloc = std::allocator&lt;std::pair&lt;Key const, Mapped&gt; &gt; &gt; class unordered_map; ```</string>
    <string name="">The hash function comes first as you might want to change the hash function but not the equality predicate. For example, if you wanted to use the https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a hash^] you could write:</string>
    <string name="">```cpp boost::unordered_map&lt;std::string, int, hash::fnv_1a&gt; dictionary; ```</string>
    <string name="">There is an link:../../../examples/fnv1.hpp[implementation of FNV-1a^] in the examples directory.</string>
    <string name="">If you wish to use a different equality function, you will also need to use a matching hash function. For example, to implement a case insensitive dictionary you need to define a case insensitive equality predicate and hash function:</string>
    <string name="">```cpp struct iequal_to { bool operator()(std::string const&amp; x, std::string const&amp; y) const { return boost::algorithm::iequals(x, y, std::locale()); } };</string>
    <string name="">struct ihash { std::size_t operator()(std::string const&amp; x) const { std::size_t seed = 0; std::locale locale;</string>
    <string name="">for(std::string::const_iterator it = x.begin(); it != x.end(); ++it) { boost::hash_combine(seed, std::toupper(*it, locale)); }</string>
    <string name="">return seed; } }; ```</string>
    <string name="">Which you can then use in a case insensitive dictionary: ```cpp boost::unordered_map&lt;std::string, int, ihash, iequal_to&gt; idictionary; ```</string>
    <string name="">This is a simplified version of the example at link:../../../examples/case_insensitive.hpp[/libs/unordered/examples/case_insensitive.hpp^] which supports other locales and string types.</string>
    <string name="">Be careful when using the equality (`==`) operator with custom equality</string>
    <string name="">predicates, especially if you\'re using a function pointer. If you compare two containers with different equality predicates then the result is undefined. For most stateless function objects this is impossible - since you can only compare objects with the same equality predicate you know the equality predicates must be equal. But if you\'re using function pointers or a stateful equality predicate (e.g. `boost::function`) then you can get into trouble.</string>
    <string name="">Custom Types</string>
    <string name="">Similarly, a custom hash function can be used for custom types:</string>
    <string name=":83">```cpp struct point { int x; int y; };</string>
    <string name=":89">bool operator==(point const&amp; p1, point const&amp; p2) { return p1.x == p2.x &amp;&amp; p1.y == p2.y; }</string>
    <string name="">struct point_hash { std::size_t operator()(point const&amp; p) const { std::size_t seed = 0; boost::hash_combine(seed, p.x); boost::hash_combine(seed, p.y); return seed; } };</string>
    <string name="">boost::unordered_multiset&lt;point, point_hash&gt; points; ```</string>
    <string name="">Since the default hash function is link:../../../../container_hash/index.html[Boost.Hash^], we can extend it to support the type so that the hash function doesn\'t need to be explicitly given:</string>
    <string name=":111">```cpp struct point { int x; int y; };</string>
    <string name=":117">bool operator==(point const&amp; p1, point const&amp; p2) { return p1.x == p2.x &amp;&amp; p1.y == p2.y; }</string>
    <string name="">std::size_t hash_value(point const&amp; p) { std::size_t seed = 0; boost::hash_combine(seed, p.x); boost::hash_combine(seed, p.y); return seed; }</string>
    <string name="">boost::unordered_multiset&lt;point&gt; points; ```</string>
    <string name="">See the link:../../../../container_hash/index.html[Boost.Hash documentation^] for more detail on how to do this. Remember that it relies on extensions to the standard - so it won\'t work for other implementations of the unordered associative containers, you\'ll need to explicitly use Boost.Hash.</string>
    <string name="">Method</string>
    <string name="">Description</string>
    <string name="">`hasher hash_function() const`</string>
    <string name="">Returns the container\'s hash function.</string>
    <string name="">`key_equal key_eq() const`</string>
    <string name="">Returns the container\'s key equality function..</string>
</resources>
