2
0
mirror of https://github.com/boostorg/hash2.git synced 2026-02-01 08:32:11 +00:00
Files
hash2/doc/html/hash2.html
2024-11-05 18:20:42 +02:00

2566 lines
91 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.18">
<meta name="author" content="Peter Dimov">
<title>Hash2: An Extensible Hashing Framework</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.square{list-style-type:square}
ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
details>summary::-webkit-details-marker{display:none}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
pre.pygments span.linenos{display:inline-block;margin-right:.75em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
li>p:empty:only-child::before{content:"";display:inline-block}
ul.checklist>li>p:first-child{margin-left:-1em}
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>Hash2: An Extensible Hashing Framework</h1>
<div class="details">
<span id="author" class="author">Peter Dimov</span><br>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#overview">Overview</a></li>
<li><a href="#hashing_bytes">Hashing Byte Sequences</a>
<ul class="sectlevel2">
<li><a href="#hashing_bytes_hash_algorithm_requirements">Hash Algorithm Requirements</a>
<ul class="sectlevel3">
<li><a href="#hashing_bytes_result_type">result_type</a></li>
<li><a href="#hashing_bytes_block_size">block_size</a></li>
<li><a href="#hashing_bytes_default_constructor">Default Constructor</a></li>
<li><a href="#hashing_bytes_constructor_taking_an_integer_seed">Constructor Taking an Integer Seed</a></li>
<li><a href="#hashing_bytes_constructor_taking_a_byte_sequence_seed">Constructor Taking a Byte Sequence Seed</a></li>
<li><a href="#hashing_bytes_copy_constructor_copy_assignment">Copy Constructor, Copy Assignment</a></li>
<li><a href="#hashing_bytes_update">update</a></li>
<li><a href="#hashing_bytes_result">result</a></li>
</ul>
</li>
<li><a href="#hashing_bytes_compile_time_hashing">Compile Time Hashing</a></li>
<li><a href="#hashing_bytes_provided_hash_algorithms">Provided Hash Algorithms</a>
<ul class="sectlevel3">
<li><a href="#hashing_bytes_fnv_1a">FNV-1a</a></li>
<li><a href="#hashing_bytes_xxhash">xxHash</a></li>
<li><a href="#hashing_bytes_siphash">SipHash</a></li>
<li><a href="#hashing_bytes_md5">MD5</a></li>
<li><a href="#hashing_bytes_sha_1">SHA-1</a></li>
<li><a href="#hashing_bytes_sha_2">SHA-2</a></li>
<li><a href="#hashing_bytes_ripemd_160">RIPEMD-160</a></li>
</ul>
</li>
<li><a href="#hashing_bytes_choosing_a_hash_algorithm">Choosing a Hash Algorithm</a></li>
</ul>
</li>
<li><a href="#hashing_objects">Hashing C&#43;&#43; Objects</a></li>
<li><a href="#examples">Usage Examples</a>
<ul class="sectlevel2">
<li><a href="#example_md5sum">md5sum</a></li>
<li><a href="#example_hash2sum">hash2sum</a></li>
</ul>
</li>
<li><a href="#implementation">Implementation Features</a>
<ul class="sectlevel2">
<li><a href="#implementation_supported_compilers">Supported Compilers</a></li>
</ul>
</li>
<li><a href="#reference">Reference</a>
<ul class="sectlevel2">
<li><a href="#ref_hash_algorithms">Hash Algorithms</a>
<ul class="sectlevel3">
<li><a href="#ref_fnv1a">&lt;boost/hash2/fnv1a.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_fnv1a_fnv1a_32">fnv1a_32</a></li>
<li><a href="#ref_fnv1a_fnv1a_64">fnv1a_64</a></li>
</ul>
</li>
<li><a href="#ref_xxhash">&lt;boost/hash2/xxhash.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_xxhash_xxhash_32">xxhash_32</a></li>
<li><a href="#ref_xxhash_xxhash_64">xxhash_64</a></li>
</ul>
</li>
<li><a href="#ref_siphash">&lt;boost/hash2/siphash.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_siphash_siphash_32">siphash_32</a></li>
<li><a href="#ref_siphash_siphash_64">siphash_64</a></li>
</ul>
</li>
<li><a href="#ref_hmac">&lt;boost/hash2/hmac.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_hmac_hmac">hmac</a></li>
</ul>
</li>
<li><a href="#ref_md5">&lt;boost/hash2/md5.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_md5_md5_128">md5_128</a></li>
</ul>
</li>
<li><a href="#ref_sha1">&lt;boost/hash2/sha1.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_sha1_sha1_160">sha1_160</a></li>
</ul>
</li>
<li><a href="#ref_sha2">&lt;boost/hash2/sha2.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_sha2_sha2_256">sha2_256</a></li>
<li><a href="#ref_sha2_sha2_224">sha2_224</a></li>
<li><a href="#ref_sha2_sha2_512">sha2_512</a></li>
<li><a href="#ref_sha2_sha2_384">sha2_384</a></li>
<li><a href="#ref_sha2_sha2_512_224">sha2_512_224</a></li>
<li><a href="#ref_sha2_sha2_512_256">sha2_512_256</a></li>
</ul>
</li>
<li><a href="#ref_ripemd">&lt;boost/hash2/ripemd.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_ripemd_ripemd_160">ripemd_160</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#ref_ripemd_utilities_and_traits">Utilities and Traits</a>
<ul class="sectlevel3">
<li><a href="#ref_digest">&lt;boost/hash2/digest.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_digest_digest">digest</a></li>
</ul>
</li>
<li><a href="#ref_endian">&lt;boost/hash2/endian.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_endian_endian">endian</a></li>
</ul>
</li>
<li><a href="#ref_flavor">&lt;boost/hash2/flavor.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_flavor_default_flavor">default_flavor</a></li>
<li><a href="#ref_flavor_little_endian_flavor">little_endian_flavor</a></li>
<li><a href="#ref_flavor_big_endian_flavor">big_endian_flavor</a></li>
</ul>
</li>
<li><a href="#ref_get_integral_result">&lt;boost/hash2/get_integral_result.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_get_integral_result_get_integral_result">get_integral_result</a></li>
</ul>
</li>
<li><a href="#ref_is_trivially_equality_comparable">&lt;boost/hash2/is_trivially_equality_comparable.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_is_trivially_equality_comparable_is_trivially_equality_comparable">is_trivially_equality_comparable</a></li>
</ul>
</li>
<li><a href="#ref_is_endian_independent">&lt;boost/hash2/is_endian_independent.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_is_endian_independent_is_endian_independent">is_endian_independent</a></li>
</ul>
</li>
<li><a href="#ref_is_contiguously_hashable">&lt;boost/hash2/is_contiguously_hashable.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_is_contiguously_hashable_is_contiguously_hashable">is_contiguously_hashable</a></li>
</ul>
</li>
<li><a href="#ref_has_constant_size">&lt;boost/hash2/has_constant_size.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_has_constant_size_has_constant_size">has_constant_size</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#ref_has_constant_size_hash_append">hash_append</a>
<ul class="sectlevel3">
<li><a href="#ref_hash_append_fwd">&lt;boost/hash2/hash_append_fwd.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_hash_append_fwd_synopsis">Synopsis</a></li>
</ul>
</li>
<li><a href="#ref_hash_append">&lt;boost/hash2/hash_append.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_hash_append_hash_append">hash_append</a></li>
<li><a href="#ref_hash_append_hash_append_range">hash_append_range</a></li>
<li><a href="#ref_hash_append_hash_append_size">hash_append_size</a></li>
<li><a href="#ref_hash_append_hash_append_sized_range">hash_append_sized_range</a></li>
<li><a href="#ref_hash_append_hash_append_unordered_range">hash_append_unordered_range</a></li>
<li><a href="#ref_hash_append_hash_append_tag">hash_append_tag</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#copyright">Copyright and License</a></li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="overview">Overview</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This library implements an extensible framework for implementing
hashing algorithms that can support user-defined types. Its structure
is largely based on the paper <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3980.html">"Types don&#8217;t know #"</a>
by Howard Hinnant, Vinnie Falco and John Bytheway.</p>
</div>
<div class="paragraph">
<p>The key feature of the design is the clean separation between the <em>hash
algorithm</em>, which takes an untyped stream of bytes (a <em>message</em>) and produces
a hash value (a <em>message digest</em>), and the <code>hash_append</code> function, which takes
a type and is responsible for turning the value of this type into a
sequence of bytes and feeding them to a <em>hash algorithm</em>.</p>
</div>
<div class="paragraph">
<p>This allows hashing support for user-defined types to be written once,
and then automatically being usable with any hash algorithms, even such
that weren&#8217;t yet available at the time the type was defined.</p>
</div>
<div class="paragraph">
<p>The following popular hashing algorithms are provided:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">FNV-1a</a></p>
</li>
<li>
<p><a href="https://cyan4973.github.io/xxHash/">xxHash</a></p>
</li>
<li>
<p><a href="https://en.wikipedia.org/wiki/SipHash">SipHash</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc1321">MD5</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc3174">SHA-1</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc6234">SHA-2</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc2104">HMAC-MD5, HMAC-SHA1, HMAC-SHA2</a></p>
</li>
<li>
<p><a href="https://homes.esat.kuleuven.be/%7Ebosselae/ripemd160.html">RIPEMD-160 and HMAC-RIPEMD-160</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>but it&#8217;s also possible for users to write their own; as long as the
hash algorithm conforms to the concept, <code>hash_append</code> will work with it,
and so will all user-defined types that support <code>hash_append</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hashing_bytes">Hashing Byte Sequences</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This library addresses two major use cases: hashing an untyped sequence
of bytes, and hashing C&#43;&#43; objects.</p>
</div>
<div class="paragraph">
<p>Untyped byte sequences (also called <em>messages</em>) are hashed by passing
them to a <em>hash algorithm</em>, which then produces a hash value (or a
<em>message digest</em>).</p>
</div>
<div class="paragraph">
<p>The same <em>hash algorithm</em>, when passed the same <em>message</em>, will always
produce the same <em>digest</em>. (Published algorithms provide <em>message</em> and
corresponding <em>digest</em> pairs, called <em>test vectors</em>, to enable
verification of independent implementations.)</p>
</div>
<div class="paragraph">
<p>(To hash a C&#43;&#43; object, it&#8217;s first converted (serialized) to a sequence
of bytes, then passed to a <em>hash algorithm</em>.)</p>
</div>
<div class="sect2">
<h3 id="hashing_bytes_hash_algorithm_requirements">Hash Algorithm Requirements</h3>
<div class="paragraph">
<p>A <em>hash algorithm</em> must have the following structure, and meet the
following minimum requirements:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>struct HashAlgorithm
{
using result_type = /*integral or array-like*/;
static constexpr int block_size = /*...*/; // optional
HashAlgorithm();
explicit HashAlgorithm( std::uint64_t seed );
HashAlgorithm( unsigned char const* seed, std::size_t n );
HashAlgorithm( HashAlgorithm const&amp; r );
HashAlgorithm&amp; operator=( HashAlgorithm const&amp; r );
void update( void const* data, std::size_t n );
result_type result();
};</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_result_type">result_type</h4>
<div class="paragraph">
<p>The nested type <code>result_type</code> is the type of the produced hash value. It
can be an unsigned integer type (that is not <code>bool</code>), typically
<code>std::uint32_t</code> or <code>std::uint64_t</code>, or a <code>std::array</code>-like type with a
value type of <code>unsigned char</code>.</p>
</div>
<div class="paragraph">
<p>Normally, non-cryptographic hash functions have an integer <code>result_type</code>,
and cryptographic hash functions have an array-like <code>result_type</code>, but
that&#8217;s not required.</p>
</div>
<div class="paragraph">
<p>The provided utility function <code>get_integral_result_type</code> can be used to
obtain an integer hash value from any valid <code>result_type</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_block_size">block_size</h4>
<div class="paragraph">
<p>Cryptographic hash functions provide a <code>block_size</code> value, which is their
block size (e.g. 64 for MD5, 128 for SHA2-512) and is required in order
to implement the corresponding <a href="https://en.wikipedia.org/wiki/HMAC">HMAC</a>.</p>
</div>
<div class="paragraph">
<p><code>block_size</code> is an optional requirement.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_default_constructor">Default Constructor</h4>
<div class="paragraph">
<p>All <em>hash algorithms</em> must be default constructible. The default
constructor initializes the internal state of the hash algorithm to its
initial values, as published in its specification.</p>
</div>
<div class="paragraph">
<p>For example, the default constructor of <code>md5_128</code> corresponds to calling
the function <code>MD5_Init</code> of the reference implementation.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_constructor_taking_an_integer_seed">Constructor Taking an Integer Seed</h4>
<div class="paragraph">
<p>All <em>hash algorithms</em> must be constructible from a value of type
<code>std::uint64_t</code>, which serves as a seed.</p>
</div>
<div class="paragraph">
<p>Using a seed value of 0 is equivalent to default construction.</p>
</div>
<div class="paragraph">
<p>Distinct seed values cause the internal state to be initialized differently,
and therefore, instances of the hash algorithm initialized by different seeds
produce different hash values when passed the same message.</p>
</div>
<div class="paragraph">
<p>Seeding using random (unobservable from the outside) values is useful for
preventing <a href="https://en.wikipedia.org/wiki/Collision_attack#Hash_flooding">hash flooding attacks</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_constructor_taking_a_byte_sequence_seed">Constructor Taking a Byte Sequence Seed</h4>
<div class="paragraph">
<p>All <em>hash algorithms</em> can be constructed from a seed sequence of
<code>unsigned char</code> values (this makes all hash algorithms
<a href="https://en.wikipedia.org/wiki/Keyed_hash_function">keyed hash functions</a>.)</p>
</div>
<div class="paragraph">
<p>A null sequence (one with length 0) produces a default-constructed instance.</p>
</div>
<div class="paragraph">
<p>Different seed sequences produce differently initialized instances.</p>
</div>
<div class="paragraph">
<p>While this requirement makes all hash algorithms usable as MACs
(<a href="https://en.wikipedia.org/wiki/Message_authentication_code">Message Authentication Codes</a>),
you should as a general rule prefer an established MAC algorithm, such as
<a href="https://en.wikipedia.org/wiki/HMAC">HMAC</a>. (A HMAC implementation is provided.)</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_copy_constructor_copy_assignment">Copy Constructor, Copy Assignment</h4>
<div class="paragraph">
<p>Hash algorithms are copy constructible and copy assignable, providing the
usual guarantees for these operations. That is, a copy is equivalent to the
original.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_update">update</h4>
<div class="paragraph">
<p>The function <code>update</code> is the mechanism by which the input message is provided
to the hash algorithm.</p>
</div>
<div class="paragraph">
<p>Calling <code>update</code> several times is equivalent to calling it once with the
concatenated byte sequences from the individual calls. That is, the input
message may be provided in parts, and the way it&#8217;s split into parts does
not matter and does not affect the final hash value.</p>
</div>
<div class="paragraph">
<p>Given</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>Hash hash; // some hash algorithm
unsigned char message[6] = { /*...*/ }; // some input message</code></pre>
</div>
</div>
<div class="paragraph">
<p>the following <code>update</code> call</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>hash.update( message, 6 );</code></pre>
</div>
</div>
<div class="paragraph">
<p>is equivalent to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>hash.update( message, 4 );
hash.update( message + 4, 2 );</code></pre>
</div>
</div>
<div class="paragraph">
<p>and to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>for( int i = 0; i &lt; 6; ++i ) hash.update( &amp;message[i], 1 );</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_result">result</h4>
<div class="paragraph">
<p>After the entire input message has been provided via calls to <code>update</code>, the
final hash value can be obtained by calling <code>result</code>.</p>
</div>
<div class="paragraph">
<p>The call to <code>result</code> finalizes the internal state, by padding the message as
per the concrete algorithm specification, by optionally incorporating the
length of the message into the state, and by performing finalization
operations on the state, again as specified by the concrete algorithm.</p>
</div>
<div class="paragraph">
<p>A final hash value is then obtained by transforming the internal state, and
returned.</p>
</div>
<div class="paragraph">
<p>Note that <code>result</code> is non-const, because it changes the internal state. It&#8217;s
allowed for <code>result</code> to be called more than once; subsequent calls perform
the state finalization again and as a result produce a pseudorandom sequence
of <code>result_type</code> values. This can be used to effectively extend the output of
the hash function. For example, a 256 bit result can be obtained from a hash
algorithm whose <code>result_type</code> is 64 bit, by calling <code>result</code> four times.</p>
</div>
<div class="paragraph">
<p>As a toy example, <em>not intended for production use</em>, this is how one could
write a random number generator on top of the FNV-1a implementation provided
by the library:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>std::uint64_t random()
{
static boost::hash2::fnv1a_64 hash;
return hash.result();
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="hashing_bytes_compile_time_hashing">Compile Time Hashing</h3>
<div class="paragraph">
<p>Under C&#43;&#43;14, it&#8217;s possible to invoke some hash algorithms at compile time.
These algorithms provide the following interface:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>struct HashAlgorithm
{
using result_type = /*integral or array-like*/;
static constexpr int block_size = /*...*/; // optional
constexpr HashAlgorithm();
explicit constexpr HashAlgorithm( std::uint64_t seed );
constexpr HashAlgorithm( unsigned char const* seed, std::size_t n );
constexpr HashAlgorithm( HashAlgorithm const&amp; r );
constexpr HashAlgorithm&amp; operator=( HashAlgorithm const&amp; r );
void update( void const* data, std::size_t n );
constexpr void update( unsigned char const* data, std::size_t n );
constexpr result_type result();
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>Apart from the added <code>constexpr</code> qualifiers, the only difference is that
<code>update</code> has a second overload that takes <code>unsigned char const*</code> instead
of <code>void const*</code>. (Pointers to <code>void</code> cannot be used in <code>constexpr</code> functions
before C&#43;&#43;26.)</p>
</div>
</div>
<div class="sect2">
<h3 id="hashing_bytes_provided_hash_algorithms">Provided Hash Algorithms</h3>
<div class="sect3">
<h4 id="hashing_bytes_fnv_1a">FNV-1a</h4>
</div>
<div class="sect3">
<h4 id="hashing_bytes_xxhash">xxHash</h4>
</div>
<div class="sect3">
<h4 id="hashing_bytes_siphash">SipHash</h4>
</div>
<div class="sect3">
<h4 id="hashing_bytes_md5">MD5</h4>
</div>
<div class="sect3">
<h4 id="hashing_bytes_sha_1">SHA-1</h4>
</div>
<div class="sect3">
<h4 id="hashing_bytes_sha_2">SHA-2</h4>
</div>
<div class="sect3">
<h4 id="hashing_bytes_ripemd_160">RIPEMD-160</h4>
</div>
</div>
<div class="sect2">
<h3 id="hashing_bytes_choosing_a_hash_algorithm">Choosing a Hash Algorithm</h3>
<div class="paragraph">
<p>&#8230;&#8203;</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hashing_objects">Hashing C&#43;&#43; Objects</h2>
<div class="sectionbody">
<div class="paragraph">
<p>&#8230;&#8203;</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="examples">Usage Examples</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="example_md5sum">md5sum</h3>
<div class="paragraph">
<p>A command line utility that prints the MD5 digests
of a list of files passed as arguments.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/md5.hpp&gt;
#include &lt;array&gt;
#include &lt;string&gt;
#include &lt;cerrno&gt;
#include &lt;cstdio&gt;
static void md5sum( std::FILE* f, char const* fn )
{
boost::hash2::md5_128 hash;
int const N = 4096;
unsigned char buffer[ N ];
for( ;; )
{
std::size_t n = std::fread( buffer, 1, N, f );
if( std::ferror( f ) )
{
std::fprintf( stderr, "'%s': read error: %s\n", fn, std::strerror( errno ) );
return;
}
if( n == 0 ) break;
hash.update( buffer, n );
}
std::string digest = to_string( hash.result() );
std::printf( "%s *%s\n", digest.c_str(), fn );
}
int main( int argc, char const* argv[] )
{
for( int i = 1; i &lt; argc; ++i )
{
std::FILE* f = std::fopen( argv[i], "rb" );
if( f == 0 )
{
std::fprintf( stderr, "'%s': open error: %s\n", argv[i], std::strerror( errno ) );
continue;
}
md5sum( f, argv[i] );
std::fclose( f );
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Sample command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>md5sum apache_builds.json canada.json citm_catalog.json twitter.json</pre>
</div>
</div>
<div class="paragraph">
<p>Sample output:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>7dc25b5fd9eb2217ed648dad23b311da *apache_builds.json
8767d618bff99552b4946078d3a90c0c *canada.json
b4391581160654374bee934a3b91255e *citm_catalog.json
bf7d37451840af4e8873b65763315cbf *twitter.json</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_hash2sum">hash2sum</h3>
<div class="paragraph">
<p>A command line utility that prints the digests
of a list of files, using a specified hash algorithm.</p>
</div>
<div class="paragraph">
<p>The hash algorithm is passed as the first command
line argument.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/md5.hpp&gt;
#include &lt;boost/hash2/sha1.hpp&gt;
#include &lt;boost/hash2/sha2.hpp&gt;
#include &lt;boost/hash2/ripemd.hpp&gt;
#include &lt;boost/mp11.hpp&gt;
#include &lt;array&gt;
#include &lt;string&gt;
#include &lt;cerrno&gt;
#include &lt;cstdio&gt;
template&lt;std::size_t N&gt; std::string to_string( std::array&lt;unsigned char, N&gt; const &amp; v )
{
std::string r;
for( std::size_t i = 0; i &lt; N; ++i )
{
char buffer[ 8 ];
std::snprintf( buffer, sizeof( buffer ), "%02x", static_cast&lt;int&gt;( v[ i ] ) );
r += buffer;
}
return r;
}
template&lt;class Hash&gt; void hash2sum( std::FILE* f, char const* fn )
{
Hash hash;
int const N = 4096;
unsigned char buffer[ N ];
for( ;; )
{
std::size_t n = std::fread( buffer, 1, N, f );
if( std::ferror( f ) )
{
std::fprintf( stderr, "'%s': read error: %s\n", fn, std::strerror( errno ) );
return;
}
if( n == 0 ) break;
hash.update( buffer, n );
}
std::string digest = to_string( hash.result() );
std::printf( "%s *%s\n", digest.c_str(), fn );
}
template&lt;class Hash&gt; void hash2sum( char const* fn )
{
std::FILE* f = std::fopen( fn, "rb" );
if( f == 0 )
{
std::fprintf( stderr, "'%s': open error: %s\n", fn, std::strerror( errno ) );
}
else
{
hash2sum&lt;Hash&gt;( f, fn );
std::fclose( f );
}
}
using namespace boost::mp11;
using namespace boost::hash2;
using hashes = mp_list&lt;
md5_128,
sha1_160,
sha2_256,
sha2_224,
sha2_512,
sha2_384,
sha2_512_256,
sha2_512_224,
ripemd_160
&gt;;
constexpr char const* names[] = {
"md5_128",
"sha1_160",
"sha2_256",
"sha2_224",
"sha2_512",
"sha2_384",
"sha2_512_256",
"sha2_512_224",
"ripemd_160"
};
int main( int argc, char const* argv[] )
{
if( argc &lt; 2 )
{
std::fputs( "usage: hash2sum &lt;hash&gt; &lt;files...&gt;\n", stderr );
return 2;
}
std::string hash( argv[1] );
bool found = false;
mp_for_each&lt; mp_iota&lt;mp_size&lt;hashes&gt;&gt; &gt;([&amp;](auto I){
if( hash == names[I] )
{
using Hash = mp_at_c&lt;hashes, I&gt;;
for( int i = 2; i &lt; argc; ++i )
{
hash2sum&lt;Hash&gt;( argv[i] );
}
found = true;
}
});
if( !found )
{
std::fprintf( stderr, "hash2sum: unknown hash name '%s'\n", hash.c_str() );
return 1;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Sample command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>hash2sum sha2_512_224 apache_builds.json canada.json citm_catalog.json twitter.json</pre>
</div>
</div>
<div class="paragraph">
<p>Sample output:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>a95d7fde785fe24f9507fd1709014567bbc595867f1abaad96f50dbc *apache_builds.json
b07e42587d10ec323a25fd8fc3eef2213fb0997beb7950350f4e8a4b *canada.json
4ceee5a83ad320fedb0dfddfb6f80af50b99677e87158e2d039aa168 *citm_catalog.json
854ebe0da98cadd426ea0fa3218d60bb52cf6494e435d2f385a37d48 *twitter.json</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="implementation">Implementation Features</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="implementation_supported_compilers">Supported Compilers</h3>
<div class="paragraph">
<p>The library requires C&#43;&#43;11. The following compilers:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>g++ 4.8 or later</p>
</li>
<li>
<p>clang++ 3.9 or later</p>
</li>
<li>
<p>Visual Studio 2015 and above</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>are being tested on <a href="https://github.com/pdimov/hash2/actions/">Github Actions</a>
and <a href="https://ci.appveyor.com/project/pdimov/hash2/">Appveyor</a>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reference">Reference</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="ref_hash_algorithms">Hash Algorithms</h3>
<div class="sect3">
<h4 id="ref_fnv1a">&lt;boost/hash2/fnv1a.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
class fnv1a_32;
class fnv1a_64;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">FNV-1a algorithm</a>, in 32 and 64 bit variants.</p>
</div>
<div class="sect4">
<h5 id="ref_fnv1a_fnv1a_32">fnv1a_32</h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>class fnv1a_32
{
private:
std::uint32_t state_; // exposition only
public:
using result_type = std::uint32_t;
constexpr fnv1a_32();
explicit constexpr fnv1a_32( std::uint64_t seed );
constexpr fnv1a_32( unsigned char const* p, std::size_t n );
void update( void const* p, std::size_t n );
constexpr void update( unsigned char const* p, std::size_t n );
constexpr result_type result();
};</code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr fnv1a_32();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes <code>state_</code> to <code>0x811c9dc5</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>explicit constexpr fnv1a_32( std::uint64_t seed );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integral seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8)</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr fnv1a_32( unsigned char const* p, std::size_t n );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, and then, if <code>n</code> is not zero, performs <code>update(p, n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>void update( void const* p, std::size_t n );
constexpr void update( unsigned char const* p, std::size_t n );</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>For each <code>unsigned char</code> value <code>ch</code> in the range <code>[p, p+n)</code> performs <code>state_ = (state_ ^ ch) * 0x01000193</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr result_type result();</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates <code>state_</code> to <code>(state_ ^ 0xFF) * 0x01000193</code>.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The value of <code>state_</code> before the update.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>The state is updated to allow repeated calls to <code>result()</code> to return
a pseudorandom sequence of <code>result_type</code> values, effectively extending
the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_fnv1a_fnv1a_64">fnv1a_64</h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>class fnv1a_64
{
private:
std::uint64_t state_; // exposition only
public:
using result_type = std::uint64_t;
constexpr fnv1a_64();
explicit constexpr fnv1a_64( std::uint64_t seed );
constexpr fnv1a_64( unsigned char const* p, std::size_t n );
void update( void const* p, std::size_t n );
constexpr void update( unsigned char const* p, std::size_t n );
constexpr result_type result();
};</code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_constructors_2">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr fnv1a_64();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes <code>state_</code> to <code>0xcbf29ce484222325</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>explicit constexpr fnv1a_64( std::uint64_t seed );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integral seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8)</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr fnv1a_64( unsigned char const* p, std::size_t n );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, and then, if <code>n</code> is not zero, performs <code>update(p, n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_update_2">update</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>void update( void const* p, std::size_t n );
constexpr void update( unsigned char const* p, std::size_t n );</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>For each <code>unsigned char</code> value <code>ch</code> in the range <code>[p, p+n)</code> performs <code>state_ = (state_ ^ ch) * 0x100000001b3</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_result_2">result</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr result_type result();</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates <code>state_</code> to <code>(state_ ^ 0xFF) * 0x100000001b3</code>.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The value of <code>state_</code> before the update.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>The state is updated to allow repeated calls to <code>result()</code> to return
a pseudorandom sequence of <code>result_type</code> values, effectively extending
the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_xxhash">&lt;boost/hash2/xxhash.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
class xxhash_32;
class xxhash_64;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_xxhash_xxhash_32">xxhash_32</h5>
</div>
<div class="sect4">
<h5 id="ref_xxhash_xxhash_64">xxhash_64</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_siphash">&lt;boost/hash2/siphash.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
class siphash_32;
class siphash_64;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_siphash_siphash_32">siphash_32</h5>
</div>
<div class="sect4">
<h5 id="ref_siphash_siphash_64">siphash_64</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_hmac">&lt;boost/hash2/hmac.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
template&lt;class H&gt; class hmac;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_hmac_hmac">hmac</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_md5">&lt;boost/hash2/md5.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/hmac.hpp&gt;
#include &lt;boost/hash2/digest.hpp&gt;
namespace boost {
namespace hash2 {
class md5_128;
using hmac_md5_128 = hmac&lt;md5_128&gt;;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://tools.ietf.org/html/rfc1321">MD5 algorithm</a>.</p>
</div>
<div class="sect4">
<h5 id="ref_md5_md5_128">md5_128</h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>class md5_128
{
public:
using result_type = digest&lt;16&gt;;
static constexpr int block_size = 64;
constexpr md5_128();
explicit constexpr md5_128( std::uint64_t seed );
constexpr md5_128( unsigned char const* p, std::size_t n );
void update( void const* p, std::size_t n );
constexpr void update( unsigned char const* p, std::size_t n );
constexpr result_type result();
};</code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_md5_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr md5_128();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the MD5 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>explicit constexpr md5_128( std::uint64_t seed );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integral seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>md5_128( unsigned char const* p, std::size_t n );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_md5_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>void update( void const* p, std::size_t n );
constexpr void update( unsigned char const* p, std::size_t n );</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the MD5 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_md5_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr result_type result();</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the MD5 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The MD5 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_sha1">&lt;boost/hash2/sha1.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/hmac.hpp&gt;
#include &lt;boost/hash2/digest.hpp&gt;
namespace boost {
namespace hash2 {
class sha1_160;
using hmac_sha1_160 = hmac&lt;sha1_160&gt;;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://tools.ietf.org/html/rfc3174">SHA-1 algorithm</a>.</p>
</div>
<div class="sect4">
<h5 id="ref_sha1_sha1_160">sha1_160</h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>class sha1_160
{
public:
using result_type = digest&lt;20&gt;;
static constexpr int block_size = 64;
constexpr sha1_160();
explicit constexpr sha1_160( std::uint64_t seed );
constexpr sha1_160( unsigned char const* p, std::size_t n );
void update( void const* p, std::size_t n );
constexpr void update( unsigned char const* p, std::size_t n );
constexpr result_type result();
};</code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha1_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr sha1_160();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the SHA-1 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>explicit constexpr sha1_160( std::uint64_t seed );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integral seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr sha1_160( unsigned char const* p, std::size_t n );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha1_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>void update( void const* p, std::size_t n );
constexpr void update( unsigned char const* p, std::size_t n );</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the SHA-1 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha1_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>constexpr result_type result();</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the SHA-1 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The SHA-1 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_sha2">&lt;boost/hash2/sha2.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/hmac.hpp&gt;
namespace boost {
namespace hash2 {
class sha2_256;
class sha2_224;
class sha2_512;
class sha2_384;
class sha2_512_256;
class sha2_512_224;
using hmac_sha2_256 = hmac&lt;sha2_256&gt;;
using hmac_sha2_224 = hmac&lt;sha2_224&gt;;
using hmac_sha2_512 = hmac&lt;sha2_512&gt;;
using hmac_sha2_384 = hmac&lt;sha2_384&gt;;
using hmac_sha2_512_256 = hmac&lt;sha2_512_256&gt;;
using hmac_sha2_512_224 = hmac&lt;sha2_512_224&gt;;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://csrc.nist.gov/pubs/fips/180-4/upd1/final">SHA-2</a> family of functions.</p>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_256">sha2_256</h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>class sha2_256
{
using result_type = std::array&lt;unsigned char, 32&gt;;
static constexpr int block_size = 64;
sha2_256();
explicit sha2_256( std::uint64_t seed );
sha2_256( unsigned char const * p, std::size_t n );
void update( void const * p, std::size_t n );
result_type result();
};</code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>sha2_256();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the SHA-256 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>explicit sha2_256( std::uint64_t seed );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integral seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>sha2_256( unsigned char const * p, std::size_t n );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>void update( void const * p, std::size_t n );</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the SHA-256 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>result_type result();</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the SHA-256 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The SHA-256 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_224">sha2_224</h5>
<div class="paragraph">
<p>The SHA-224 algorithm is identical to the SHA-256 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the internal state&#8217;s initial values and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>using result_type = std::array&lt;unsigned char, 28&gt;;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
<div class="paragraph">
<p>The message digest is obtained by truncating the final results of the SHA-256 algorithm to its leftmost 224 bits.</p>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_512">sha2_512</h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>class sha2_512
{
using result_type = std::array&lt;unsigned char, 64&gt;;
static constexpr int block_size = 128;
sha2_512();
explicit sha2_512( std::uint64_t seed );
sha2_512( unsigned char const * p, std::size_t n );
void update( void const * p, std::size_t n );
result_type result();
};</code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_constructors_2">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>sha2_512();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the SHA-512 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>explicit sha2_512( std::uint64_t seed );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integral seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>sha2_512( unsigned char const * p, std::size_t n );</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_update_2">update</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>void update( void const * p, std::size_t n );</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the SHA-512 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_result_2">result</h6>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>result_type result();</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the SHA-512 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The SHA-512 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_384">sha2_384</h5>
<div class="paragraph">
<p>The SHA-384 algorithm is identical to the SHA-512 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the internal state&#8217;s initial values and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>using result_type = std::array&lt;unsigned char, 48&gt;;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
<div class="paragraph">
<p>The message digest is obtained by truncating the final results of the SHA-512 algorithm to its leftmost 384 bits.</p>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_512_224">sha2_512_224</h5>
<div class="paragraph">
<p>The SHA-512/224 algorithm is identical to the SHA-512 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the internal state&#8217;s initial values and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>using result_type = std::array&lt;unsigned char, 28&gt;;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
<div class="paragraph">
<p>The message digest is obtained by truncating the final results of the SHA-512 algorithm to its leftmost 224 bits.</p>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_512_256">sha2_512_256</h5>
<div class="paragraph">
<p>The SHA-512/256 algorithm is identical to the SHA-512 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the internal state&#8217;s initial values and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>using result_type = std::array&lt;unsigned char, 32&gt;;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
<div class="paragraph">
<p>The message digest is obtained by truncating the final results of the SHA-512 algorithm to its leftmost 256 bits.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_ripemd">&lt;boost/hash2/ripemd.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/hmac.hpp&gt;
namespace boost {
namespace hash2 {
class ripemd_160;
using hmac_ripemd_160 = hmac&lt;ripemd_160&gt;;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_ripemd_ripemd_160">ripemd_160</h5>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_ripemd_utilities_and_traits">Utilities and Traits</h3>
<div class="sect3">
<h4 id="ref_digest">&lt;boost/hash2/digest.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
class digest;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_digest_digest">digest</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_endian">&lt;boost/hash2/endian.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
enum class endian;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_endian_endian">endian</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_flavor">&lt;boost/hash2/flavor.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/endian.hpp&gt;
namespace boost {
namespace hash2 {
struct default_flavor;
struct little_endian_flavor;
struct big_endian_flavor;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_flavor_default_flavor">default_flavor</h5>
</div>
<div class="sect4">
<h5 id="ref_flavor_little_endian_flavor">little_endian_flavor</h5>
</div>
<div class="sect4">
<h5 id="ref_flavor_big_endian_flavor">big_endian_flavor</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_get_integral_result">&lt;boost/hash2/get_integral_result.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
template&lt;class T, class R&gt; constexpr T get_integral_result( R const&amp; r );
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_get_integral_result_get_integral_result">get_integral_result</h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>template&lt;class T, class R&gt; constexpr T get_integral_result( R const&amp; r );</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_is_trivially_equality_comparable">&lt;boost/hash2/is_trivially_equality_comparable.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
template&lt;class T&gt; struct is_trivially_equality_comparable;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_is_trivially_equality_comparable_is_trivially_equality_comparable">is_trivially_equality_comparable</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_is_endian_independent">&lt;boost/hash2/is_endian_independent.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
template&lt;class T&gt; struct is_endian_independent;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_is_endian_independent_is_endian_independent">is_endian_independent</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_is_contiguously_hashable">&lt;boost/hash2/is_contiguously_hashable.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/endian.hpp&gt;
#include &lt;boost/hash2/is_trivially_equality_comparable.hpp&gt;
#include &lt;boost/hash2/is_endian_independent.hpp&gt;
namespace boost {
namespace hash2 {
template&lt;class T, endian E&gt; struct is_contiguously_hashable;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_is_contiguously_hashable_is_contiguously_hashable">is_contiguously_hashable</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_has_constant_size">&lt;boost/hash2/has_constant_size.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
template&lt;class T&gt; struct has_constant_size;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_has_constant_size_has_constant_size">has_constant_size</h5>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_has_constant_size_hash_append">hash_append</h3>
<div class="sect3">
<h4 id="ref_hash_append_fwd">&lt;boost/hash2/hash_append_fwd.hpp&gt;</h4>
<div class="sect4">
<h5 id="ref_hash_append_fwd_synopsis">Synopsis</h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>namespace boost {
namespace hash2 {
template&lt;class Hash, class Flavor, class T&gt;
constexpr void hash_append( Hash&amp; h, Flavor const&amp; f, T const&amp; v );
template&lt;class Hash, class Flavor, class It&gt;
constexpr void hash_append_range( Hash&amp; h, Flavor const&amp; f, It first, It last );
template&lt;class Hash, class Flavor, class T&gt;
constexpr void hash_append_size( Hash&amp; h, Flavor const&amp; f, T const&amp; v );
template&lt;class Hash, class Flavor, class It&gt;
constexpr void hash_append_sized_range( Hash&amp; h, Flavor const&amp; f, It first, It last );
template&lt;class Hash, class Flavor, class It&gt;
constexpr void hash_append_unordered_range( Hash&amp; h, Flavor const&amp; f, It first, It last );
struct hash_append_tag;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_hash_append">&lt;boost/hash2/hash_append.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>#include &lt;boost/hash2/flavor.hpp&gt;
namespace boost {
namespace hash2 {
template&lt;class Hash, class Flavor = default_flavor, class T&gt;
constexpr void hash_append( Hash&amp; h, Flavor const&amp; f, T const&amp; v );
template&lt;class Hash, class Flavor = default_flavor, class It&gt;
constexpr void hash_append_range( Hash&amp; h, Flavor const&amp; f, It first, It last );
template&lt;class Hash, class Flavor = default_flavor, class T&gt;
constexpr void hash_append_size( Hash&amp; h, Flavor const&amp; f, T const&amp; v );
template&lt;class Hash, class Flavor = default_flavor, class It&gt;
constexpr void hash_append_sized_range( Hash&amp; h, Flavor const&amp; f, It first, It last );
template&lt;class Hash, class Flavor = default_flavor, class It&gt;
constexpr void hash_append_unordered_range( Hash&amp; h, Flavor const&amp; f, It first, It last );
struct hash_append_tag;
} // namespace hash2
} // namespace boost</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append">hash_append</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_range">hash_append_range</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_size">hash_append_size</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_sized_range">hash_append_sized_range</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_unordered_range">hash_append_unordered_range</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_tag">hash_append_tag</h5>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="copyright">Copyright and License</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This documentation is copyright 2020, 2024 Peter Dimov and is distributed under
the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2024-11-05 18:20:03 +0200
</div>
</div>
<style>
*:not(pre)>code { background: none; color: #600000; }
:not(pre):not([class^=L])>code { background: none; color: #600000; }
</style>
</body>
</html>