2021-10-05 21:37:46 +02:00

85 lines
8.7 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hash Function Support</title>
<link rel="stylesheet" href="../../multiprecision.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Chapter 1. Boost.Multiprecision">
<link rel="up" href="../tut.html" title="Tutorial">
<link rel="prev" href="input_output.html" title="Input Output">
<link rel="next" href="eigen.html" title="Eigen Interoperability">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="input_output.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tut.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="eigen.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_multiprecision.tut.hash"></a><a class="link" href="hash.html" title="Hash Function Support">Hash Function Support</a>
</h3></div></div></div>
<p>
All of the types in this library support hashing via boost::hash or std::hash.
That means we can use multiprecision types directly in hashed containers
such as std::unordered_set:
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">;</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">random</span><span class="special">;</span>
<span class="identifier">mt19937</span> <span class="identifier">mt</span><span class="special">;</span>
<span class="identifier">uniform_int_distribution</span><span class="special">&lt;</span><span class="identifier">uint256_t</span><span class="special">&gt;</span> <span class="identifier">ui</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_set</span><span class="special">&lt;</span><span class="identifier">uint256_t</span><span class="special">&gt;</span> <span class="identifier">set</span><span class="special">;</span>
<span class="comment">// Put 1000 random values into the container:</span>
<span class="keyword">for</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">1000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
<span class="identifier">set</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">ui</span><span class="special">(</span><span class="identifier">mt</span><span class="special">));</span>
</pre>
<p>
Or we can define our own hash function, for example in this case based on
Google's CityHash:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">cityhash</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">uint256_t</span><span class="special">&amp;</span> <span class="identifier">val</span><span class="special">)</span><span class="keyword">const</span>
<span class="special">{</span>
<span class="comment">// create a hash from all the limbs of the argument, this function is probably x64 specific,</span>
<span class="comment">// and requires that we access the internals of the data type:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">CityHash64</span><span class="special">(</span><span class="keyword">reinterpret_cast</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">val</span><span class="special">.</span><span class="identifier">backend</span><span class="special">().</span><span class="identifier">limbs</span><span class="special">()),</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">backend</span><span class="special">().</span><span class="identifier">size</span><span class="special">()</span> <span class="special">*</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">val</span><span class="special">.</span><span class="identifier">backend</span><span class="special">().</span><span class="identifier">limbs</span><span class="special">()[</span><span class="number">0</span><span class="special">]));</span>
<span class="comment">// modify the returned hash based on sign:</span>
<span class="keyword">return</span> <span class="identifier">val</span> <span class="special">&lt;</span> <span class="number">0</span> <span class="special">?</span> <span class="special">~</span><span class="identifier">result</span> <span class="special">:</span> <span class="identifier">result</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
As before insert some values into a container, this time using our custom
hasher:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_set</span><span class="special">&lt;</span><span class="identifier">uint256_t</span><span class="special">,</span> <span class="identifier">cityhash</span><span class="special">&gt;</span> <span class="identifier">set2</span><span class="special">;</span>
<span class="keyword">for</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">1000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
<span class="identifier">set2</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">ui</span><span class="special">(</span><span class="identifier">mt</span><span class="special">));</span>
</pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2002-2020 John
Maddock and Christopher Kormanyos<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="input_output.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tut.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="eigen.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>