1<!DOCTYPE html> 2<html lang="en"> 3<head> 4<meta charset="UTF-8"> 5<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--> 6<meta name="viewport" content="width=device-width, initial-scale=1.0"> 7<meta name="generator" content="Asciidoctor 1.5.8"> 8<meta name="author" content="Beman Dawes"> 9<title>Boost.Endian: The Boost Endian Library</title> 10<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"> 11<style> 12/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */ 13/* Uncomment @import statement below to use as custom stylesheet */ 14/*@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";*/ 15article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block} 16audio,canvas,video{display:inline-block} 17audio:not([controls]){display:none;height:0} 18script{display:none!important} 19html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} 20a{background:transparent} 21a:focus{outline:thin dotted} 22a:active,a:hover{outline:0} 23h1{font-size:2em;margin:.67em 0} 24abbr[title]{border-bottom:1px dotted} 25b,strong{font-weight:bold} 26dfn{font-style:italic} 27hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0} 28mark{background:#ff0;color:#000} 29code,kbd,pre,samp{font-family:monospace;font-size:1em} 30pre{white-space:pre-wrap} 31q{quotes:"\201C" "\201D" "\2018" "\2019"} 32small{font-size:80%} 33sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} 34sup{top:-.5em} 35sub{bottom:-.25em} 36img{border:0} 37svg:not(:root){overflow:hidden} 38figure{margin:0} 39fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} 40legend{border:0;padding:0} 41button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} 42button,input{line-height:normal} 43button,select{text-transform:none} 44button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} 45button[disabled],html input[disabled]{cursor:default} 46input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0} 47button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} 48textarea{overflow:auto;vertical-align:top} 49table{border-collapse:collapse;border-spacing:0} 50*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box} 51html,body{font-size:100%} 52body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased} 53a:hover{cursor:pointer} 54img,object,embed{max-width:100%;height:auto} 55object,embed{height:100%} 56img{-ms-interpolation-mode:bicubic} 57.left{float:left!important} 58.right{float:right!important} 59.text-left{text-align:left!important} 60.text-right{text-align:right!important} 61.text-center{text-align:center!important} 62.text-justify{text-align:justify!important} 63.hide{display:none} 64img,object,svg{display:inline-block;vertical-align:middle} 65textarea{height:auto;min-height:50px} 66select{width:100%} 67.center{margin-left:auto;margin-right:auto} 68.stretch{width:100%} 69.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} 70div,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;direction:ltr} 71a{color:#2156a5;text-decoration:underline;line-height:inherit} 72a:hover,a:focus{color:#1d4b8f} 73a img{border:none} 74p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} 75p aside{font-size:.875em;line-height:1.35;font-style:italic} 76h1,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} 77h1 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} 78h1{font-size:2.125em} 79h2{font-size:1.6875em} 80h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} 81h4,h5{font-size:1.125em} 82h6{font-size:1em} 83hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0} 84em,i{font-style:italic;line-height:inherit} 85strong,b{font-weight:bold;line-height:inherit} 86small{font-size:60%;line-height:inherit} 87code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} 88ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} 89ul,ol{margin-left:1.5em} 90ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em} 91ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit} 92ul.square{list-style-type:square} 93ul.circle{list-style-type:circle} 94ul.disc{list-style-type:disc} 95ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} 96dl dt{margin-bottom:.3125em;font-weight:bold} 97dl dd{margin-bottom:1.25em} 98abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help} 99abbr{text-transform:none} 100blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} 101blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)} 102blockquote cite::before{content:"\2014 \0020"} 103blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)} 104blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} 105@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} 106h1{font-size:2.75em} 107h2{font-size:2.3125em} 108h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} 109h4{font-size:1.4375em}} 110table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede} 111table thead,table tfoot{background:#f7f8f7} 112table 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} 113table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} 114table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7} 115table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6} 116h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} 117h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} 118.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table} 119.clearfix::after,.float-group::after{clear:both} 120*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word} 121*:not(pre)>code.nobreak{word-wrap:normal} 122*:not(pre)>code.nowrap{white-space:nowrap} 123pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed} 124em em{font-style:normal} 125strong strong{font-weight:400} 126.keyseq{color:rgba(51,51,51,.8)} 127kbd{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-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap} 128.keyseq kbd:first-child{margin-left:0} 129.keyseq kbd:last-child{margin-right:0} 130.menuseq,.menuref{color:#000} 131.menuseq b:not(.caret),.menuref{font-weight:inherit} 132.menuseq{word-spacing:-.02em} 133.menuseq b.caret{font-size:1.25em;line-height:.8} 134.menuseq i.caret{font-weight:bold;text-align:center;width:.45em} 135b.button::before,b.button::after{position:relative;top:-1px;font-weight:400} 136b.button::before{content:"[";padding:0 3px 0 2px} 137b.button::after{content:"]";padding:0 2px 0 3px} 138p a>code:hover{color:rgba(0,0,0,.9)} 139#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} 140#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table} 141#header::after,#content::after,#footnotes::after,#footer::after{clear:both} 142#content{margin-top:1.25em} 143#content::before{content:none} 144#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} 145#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf} 146#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} 147#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:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap} 148#header .details span:first-child{margin-left:-.125em} 149#header .details span.email a{color:rgba(0,0,0,.85)} 150#header .details br{display:none} 151#header .details br+span::before{content:"\00a0\2013\00a0"} 152#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} 153#header .details br+span#revremark::before{content:"\00a0|\00a0"} 154#header #revnumber{text-transform:capitalize} 155#header #revnumber::after{content:"\00a0"} 156#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} 157#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em} 158#toc>ul{margin-left:.125em} 159#toc ul.sectlevel0>li>a{font-style:italic} 160#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} 161#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} 162#toc li{line-height:1.3334;margin-top:.3334em} 163#toc a{text-decoration:none} 164#toc a:active{text-decoration:underline} 165#toctitle{color:#7a2518;font-size:1.2em} 166@media screen and (min-width:768px){#toctitle{font-size:1.375em} 167body.toc2{padding-left:15em;padding-right:0} 168#toc.toc2{margin-top:0!important;background-color:#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} 169#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} 170#toc.toc2>ul{font-size:.9em;margin-bottom:0} 171#toc.toc2 ul ul{margin-left:0;padding-left:1em} 172#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} 173body.toc2.toc-right{padding-left:0;padding-right:15em} 174body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}} 175@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} 176#toc.toc2{width:20em} 177#toc.toc2 #toctitle{font-size:1.375em} 178#toc.toc2>ul{font-size:.95em} 179#toc.toc2 ul ul{padding-left:1.25em} 180body.toc2.toc-right{padding-left:0;padding-right:20em}} 181#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} 182#content #toc>:first-child{margin-top:0} 183#content #toc>:last-child{margin-bottom:0} 184#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em} 185#footer-text{color:rgba(255,255,255,.8);line-height:1.44} 186#content{margin-bottom:.625em} 187.sect1{padding-bottom:.625em} 188@media screen and (min-width:768px){#content{margin-bottom:1.25em} 189.sect1{padding-bottom:1.25em}} 190.sect1:last-child{padding-bottom:0} 191.sect1+.sect1{border-top:1px solid #e7e7e9} 192#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} 193#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} 194#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} 195#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} 196#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} 197.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} 198.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} 199table.tableblock.fit-content>caption.title{white-space:nowrap;width:0} 200.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)} 201table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit} 202.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} 203.admonitionblock>table td.icon{text-align:center;width:80px} 204.admonitionblock>table td.icon img{max-width:none} 205.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} 206.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)} 207.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} 208.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px} 209.exampleblock>.content>:first-child{margin-top:0} 210.exampleblock>.content>:last-child{margin-bottom:0} 211.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} 212.sidebarblock>:first-child{margin-top:0} 213.sidebarblock>:last-child{margin-bottom:0} 214.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} 215.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} 216.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8} 217.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1} 218.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em} 219@media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}} 220@media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}} 221.literalblock pre.nowrap,.literalblock pre.nowrap pre,.listingblock pre.nowrap,.listingblock pre.nowrap pre{white-space:pre;word-wrap:normal} 222.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)} 223.listingblock pre.highlightjs{padding:0} 224.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px} 225.listingblock pre.prettyprint{border-width:0} 226.listingblock>.content{position:relative} 227.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:#999} 228.listingblock:hover code[data-lang]::before{display:block} 229.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999} 230.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"} 231table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none} 232table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45} 233table.pyhltable td.code{padding-left:.75em;padding-right:0} 234pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #dddddf} 235pre.pygments .lineno{display:inline-block;margin-right:.25em} 236table.pyhltable .linenodiv{background:none!important;padding-right:0!important} 237.quoteblock{margin:0 1em 1.25em 1.5em;display:table} 238.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em} 239.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} 240.quoteblock blockquote{margin:0;padding:0;border:0} 241.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)} 242.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} 243.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right} 244.verseblock{margin:0 1em 1.25em} 245.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} 246.verseblock pre strong{font-weight:400} 247.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} 248.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} 249.quoteblock .attribution br,.verseblock .attribution br{display:none} 250.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)} 251.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none} 252.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} 253.quoteblock.abstract{margin:0 1em 1.25em;display:block} 254.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center} 255.quoteblock.excerpt,.quoteblock .quoteblock{margin:0 0 1.25em;padding:0 0 .25em 1em;border-left:.25em solid #dddddf} 256.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem} 257.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0} 258table.tableblock{max-width:100%;border-collapse:separate} 259p.tableblock:last-child{margin-bottom:0} 260td.tableblock>.content{margin-bottom:-1.25em} 261table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} 262table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0} 263table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0} 264table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0} 265table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px} 266table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0} 267table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0} 268table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0} 269table.frame-all{border-width:1px} 270table.frame-sides{border-width:0 1px} 271table.frame-topbot,table.frame-ends{border-width:1px 0} 272table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7} 273table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none} 274th.halign-left,td.halign-left{text-align:left} 275th.halign-right,td.halign-right{text-align:right} 276th.halign-center,td.halign-center{text-align:center} 277th.valign-top,td.valign-top{vertical-align:top} 278th.valign-bottom,td.valign-bottom{vertical-align:bottom} 279th.valign-middle,td.valign-middle{vertical-align:middle} 280table thead th,table tfoot th{font-weight:bold} 281tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7} 282tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} 283p.tableblock>code:only-child{background:none;padding:0} 284p.tableblock{font-size:1em} 285td>div.verse{white-space:pre} 286ol{margin-left:1.75em} 287ul li ol{margin-left:1.5em} 288dl dd{margin-left:1.125em} 289dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} 290ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} 291ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none} 292ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em} 293ul.unstyled,ol.unstyled{margin-left:0} 294ul.checklist{margin-left:.625em} 295ul.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} 296ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em} 297ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em} 298ul.inline>li{margin-left:1.25em} 299.unstyled dl dt{font-weight:400;font-style:normal} 300ol.arabic{list-style-type:decimal} 301ol.decimal{list-style-type:decimal-leading-zero} 302ol.loweralpha{list-style-type:lower-alpha} 303ol.upperalpha{list-style-type:upper-alpha} 304ol.lowerroman{list-style-type:lower-roman} 305ol.upperroman{list-style-type:upper-roman} 306ol.lowergreek{list-style-type:lower-greek} 307.hdlist>table,.colist>table{border:0;background:none} 308.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} 309td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em} 310td.hdlist1{font-weight:bold;padding-bottom:1.25em} 311.literalblock+.colist,.listingblock+.colist{margin-top:-.5em} 312.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top} 313.colist td:not([class]):first-child img{max-width:none} 314.colist td:not([class]):last-child{padding:.25em 0} 315.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd} 316.imageblock.left{margin:.25em .625em 1.25em 0} 317.imageblock.right{margin:.25em 0 1.25em .625em} 318.imageblock>.title{margin-bottom:0} 319.imageblock.thumb,.imageblock.th{border-width:6px} 320.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} 321.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} 322.image.left{margin-right:.625em} 323.image.right{margin-left:.625em} 324a.image{text-decoration:none;display:inline-block} 325a.image object{pointer-events:none} 326sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} 327sup.footnote a,sup.footnoteref a{text-decoration:none} 328sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline} 329#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} 330#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} 331#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} 332#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em} 333#footnotes .footnote:last-of-type{margin-bottom:0} 334#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} 335.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0} 336.gist .file-data>table td.line-data{width:99%} 337div.unbreakable{page-break-inside:avoid} 338.big{font-size:larger} 339.small{font-size:smaller} 340.underline{text-decoration:underline} 341.overline{text-decoration:overline} 342.line-through{text-decoration:line-through} 343.aqua{color:#00bfbf} 344.aqua-background{background-color:#00fafa} 345.black{color:#000} 346.black-background{background-color:#000} 347.blue{color:#0000bf} 348.blue-background{background-color:#0000fa} 349.fuchsia{color:#bf00bf} 350.fuchsia-background{background-color:#fa00fa} 351.gray{color:#606060} 352.gray-background{background-color:#7d7d7d} 353.green{color:#006000} 354.green-background{background-color:#007d00} 355.lime{color:#00bf00} 356.lime-background{background-color:#00fa00} 357.maroon{color:#600000} 358.maroon-background{background-color:#7d0000} 359.navy{color:#000060} 360.navy-background{background-color:#00007d} 361.olive{color:#606000} 362.olive-background{background-color:#7d7d00} 363.purple{color:#600060} 364.purple-background{background-color:#7d007d} 365.red{color:#bf0000} 366.red-background{background-color:#fa0000} 367.silver{color:#909090} 368.silver-background{background-color:#bcbcbc} 369.teal{color:#006060} 370.teal-background{background-color:#007d7d} 371.white{color:#bfbfbf} 372.white-background{background-color:#fafafa} 373.yellow{color:#bfbf00} 374.yellow-background{background-color:#fafa00} 375span.icon>.fa{cursor:default} 376a span.icon>.fa{cursor:inherit} 377.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} 378.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c} 379.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} 380.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900} 381.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400} 382.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000} 383.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;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} 384.conum[data-value] *{color:#fff!important} 385.conum[data-value]+b{display:none} 386.conum[data-value]::after{content:attr(data-value)} 387pre .conum[data-value]{position:relative;top:-.125em} 388b.conum *{color:inherit!important} 389.conum:not([data-value]):empty{display:none} 390dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} 391h1,h2,p,td.content,span.alt{letter-spacing:-.01em} 392p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} 393p,blockquote,dt,td.content,span.alt{font-size:1.0625rem} 394p{margin-bottom:1.25rem} 395.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} 396.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc} 397.print-only{display:none!important} 398@page{margin:1.25cm .75cm} 399@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important} 400html{font-size:80%} 401a{color:inherit!important;text-decoration:underline!important} 402a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} 403a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} 404abbr[title]::after{content:" (" attr(title) ")"} 405pre,blockquote,tr,img,object,svg{page-break-inside:avoid} 406thead{display:table-header-group} 407svg{max-width:100%} 408p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} 409h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} 410#toc,.sidebarblock,.exampleblock>.content{background:none!important} 411#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important} 412body.book #header{text-align:center} 413body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em} 414body.book #header .details{border:0!important;display:block;padding:0!important} 415body.book #header .details span:first-child{margin-left:0!important} 416body.book #header .details br{display:block} 417body.book #header .details br+span::before{content:none!important} 418body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} 419body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} 420.listingblock code[data-lang]::before{display:block} 421#footer{padding:0 .9375em} 422.hide-on-print{display:none!important} 423.print-only{display:block!important} 424.hide-for-print{display:none!important} 425.show-for-print{display:inherit!important}} 426@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem} 427.sect1{padding:0!important} 428.sect1+.sect1{border:0} 429#footer{background:none} 430#footer-text{color:rgba(0,0,0,.6);font-size:.9em}} 431@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} 432</style> 433</head> 434<body class="article toc2 toc-left"> 435<div id="header"> 436<h1>Boost.Endian: The Boost Endian Library</h1> 437<div class="details"> 438<span id="author" class="author">Beman Dawes</span><br> 439</div> 440<div id="toc" class="toc2"> 441<div id="toctitle">Table of Contents</div> 442<ul class="sectlevel1"> 443<li><a href="#overview">Overview</a> 444<ul class="sectlevel2"> 445<li><a href="#overview_abstract">Abstract</a></li> 446<li><a href="#overview_endianness">Introduction to endianness</a></li> 447<li><a href="#overview_introduction">Introduction to the Boost.Endian library</a></li> 448<li><a href="#overview_intrinsics">Built-in support for Intrinsics</a></li> 449<li><a href="#overview_performance">Performance</a></li> 450<li><a href="#overview_cpp03_support">C++03 support for C++11 features</a></li> 451<li><a href="#overview_faq">Overall FAQ</a></li> 452</ul> 453</li> 454<li><a href="#changelog">Revision History</a> 455<ul class="sectlevel2"> 456<li><a href="#overview_changes_in_1_74_0">Changes in 1.74.0</a></li> 457<li><a href="#overview_changes_in_1_72_0">Changes in 1.72.0</a></li> 458<li><a href="#overview_changes_in_1_71_0">Changes in 1.71.0</a></li> 459</ul> 460</li> 461<li><a href="#choosing">Choosing between Conversion Functions, Buffer Types, and Arithmetic Types</a> 462<ul class="sectlevel2"> 463<li><a href="#choosing_background">Background</a></li> 464<li><a href="#choosing_characteristics">Characteristics</a></li> 465<li><a href="#choosing_design_patterns">Design patterns</a></li> 466<li><a href="#choosing_use_case_examples">Use case examples</a></li> 467</ul> 468</li> 469<li><a href="#conversion">Endian Conversion Functions</a> 470<ul class="sectlevel2"> 471<li><a href="#conversion_introduction">Introduction</a></li> 472<li><a href="#conversion_reference">Reference</a></li> 473<li><a href="#conversion_faq">FAQ</a></li> 474<li><a href="#conversion_acknowledgements">Acknowledgements</a></li> 475</ul> 476</li> 477<li><a href="#buffers">Endian Buffer Types</a> 478<ul class="sectlevel2"> 479<li><a href="#buffers_introduction">Introduction</a></li> 480<li><a href="#buffers_example">Example</a></li> 481<li><a href="#buffers_limitations">Limitations</a></li> 482<li><a href="#buffers_feature_set">Feature set</a></li> 483<li><a href="#buffers_enums_and_typedefs">Enums and typedefs</a></li> 484<li><a href="#buffers_class_template_endian_buffer">Class template <code>endian_buffer</code></a></li> 485<li><a href="#buffers_faq">FAQ</a></li> 486<li><a href="#buffers_design_considerations_for_boost_endian_buffers">Design considerations for Boost.Endian buffers</a></li> 487<li><a href="#buffers_c11">C++11</a></li> 488<li><a href="#buffers_compilation">Compilation</a></li> 489</ul> 490</li> 491<li><a href="#arithmetic">Endian Arithmetic Types</a> 492<ul class="sectlevel2"> 493<li><a href="#arithmetic_introduction">Introduction</a></li> 494<li><a href="#arithmetic_example">Example</a></li> 495<li><a href="#arithmetic_limitations">Limitations</a></li> 496<li><a href="#arithmetic_feature_set">Feature set</a></li> 497<li><a href="#arithmetic_enums_and_typedefs">Enums and typedefs</a></li> 498<li><a href="#arithmetic_class_template_endian_arithmetic">Class template <code>endian_arithmetic</code></a></li> 499<li><a href="#arithmetic_faq">FAQ</a></li> 500<li><a href="#arithmetic_design_considerations_for_boost_endian_types">Design considerations for Boost.Endian types</a></li> 501<li><a href="#arithmetic_experience">Experience</a></li> 502<li><a href="#arithmetic_motivating_use_cases">Motivating use cases</a></li> 503<li><a href="#arithmetic_c11">C++11</a></li> 504<li><a href="#arithmetic_compilation">Compilation</a></li> 505<li><a href="#arithmetic_acknowledgements">Acknowledgements</a></li> 506</ul> 507</li> 508<li><a href="#appendix_history">Appendix A: History and Acknowledgments</a> 509<ul class="sectlevel2"> 510<li><a href="#apph_history">History</a></li> 511<li><a href="#apph_compatibility_with_interim_releases">Compatibility with interim releases</a></li> 512<li><a href="#apph_future_directions">Future directions</a></li> 513<li><a href="#apph_acknowledgements">Acknowledgements</a></li> 514</ul> 515</li> 516<li><a href="#apph_copyright_and_license">Appendix B: Copyright and License</a></li> 517</ul> 518</div> 519</div> 520<div id="content"> 521<div class="sect1"> 522<h2 id="overview">Overview</h2> 523<div class="sectionbody"> 524<div class="sect2"> 525<h3 id="overview_abstract">Abstract</h3> 526<div class="paragraph"> 527<p>Boost.Endian provides facilities to manipulate the 528<a href="#overview_endianness">endianness</a> of integers and user-defined types.</p> 529</div> 530<div class="ulist"> 531<ul> 532<li> 533<p>Three approaches to endianness are supported. Each has a long history of 534successful use, and each approach has use cases where it is preferred over the 535other approaches.</p> 536</li> 537<li> 538<p>Primary uses:</p> 539<div class="ulist"> 540<ul> 541<li> 542<p>Data portability. The Endian library supports binary data exchange, via 543either external media or network transmission, regardless of platform 544endianness.</p> 545</li> 546<li> 547<p>Program portability. POSIX-based and Windows-based operating systems 548traditionally supply libraries with non-portable functions to perform endian 549conversion. There are at least four incompatible sets of functions in common 550use. The Endian library is portable across all C++ platforms.</p> 551</li> 552</ul> 553</div> 554</li> 555<li> 556<p>Secondary use: Minimizing data size via sizes and/or alignments not supported 557by the standard C++ integer types.</p> 558</li> 559</ul> 560</div> 561</div> 562<div class="sect2"> 563<h3 id="overview_endianness">Introduction to endianness</h3> 564<div class="paragraph"> 565<p>Consider the following code:</p> 566</div> 567<div class="listingblock"> 568<div class="content"> 569<pre class="highlight"><code>int16_t i = 0x0102; 570FILE * file = fopen("test.bin", "wb"); // binary file! 571fwrite(&i, sizeof(int16_t), 1, file); 572fclose(file);</code></pre> 573</div> 574</div> 575<div class="paragraph"> 576<p>On OS X, Linux, or Windows systems with an Intel CPU, a hex dump of the 577"test.bin" output file produces:</p> 578</div> 579<div class="listingblock"> 580<div class="content"> 581<pre class="highlight"><code>0201</code></pre> 582</div> 583</div> 584<div class="paragraph"> 585<p>On OS X systems with a PowerPC CPU, or Solaris systems with a SPARC CPU, a hex 586dump of the "test.bin" output file produces:</p> 587</div> 588<div class="listingblock"> 589<div class="content"> 590<pre class="highlight"><code>0102</code></pre> 591</div> 592</div> 593<div class="paragraph"> 594<p>What’s happening here is that Intel CPUs order the bytes of an integer with the 595least-significant byte first, while SPARC CPUs place the most-significant byte 596first. Some CPUs, such as the PowerPC, allow the operating system to choose 597which ordering applies.</p> 598</div> 599<div class="paragraph"> 600<p>Most-significant-byte-first ordering is traditionally called "big endian" 601ordering and least-significant-byte-first is traditionally called 602"little-endian" ordering. The names are derived from 603<a href="http://en.wikipedia.org/wiki/Jonathan_Swift">Jonathan Swift</a>'s satirical novel 604<em><a href="http://en.wikipedia.org/wiki/Gulliver’s_Travels">Gulliver’s Travels</a></em>, where 605rival kingdoms opened their soft-boiled eggs at different ends.</p> 606</div> 607<div class="paragraph"> 608<p>See Wikipedia’s <a href="http://en.wikipedia.org/wiki/Endianness">Endianness</a> article for 609an extensive discussion of endianness.</p> 610</div> 611<div class="paragraph"> 612<p>Programmers can usually ignore endianness, except when reading a core dump on 613little-endian systems. But programmers have to deal with endianness when 614exchanging binary integers and binary floating point values between computer 615systems with differing endianness, whether by physical file transfer or over a 616network. And programmers may also want to use the library when minimizing either 617internal or external data sizes is advantageous.</p> 618</div> 619</div> 620<div class="sect2"> 621<h3 id="overview_introduction">Introduction to the Boost.Endian library</h3> 622<div class="paragraph"> 623<p>Boost.Endian provides three different approaches to dealing with endianness. All 624three approaches support integers and user-define types (UDTs).</p> 625</div> 626<div class="paragraph"> 627<p>Each approach has a long history of successful use, and each approach has use 628cases where it is preferred to the other approaches. See 629<a href="#choosing">Choosing between Conversion Functions, Buffer Types, and Arithmetic Types</a>.</p> 630</div> 631<div class="dlist"> 632<dl> 633<dt class="hdlist1"><a href="#conversion">Endian conversion functions</a></dt> 634<dd> 635<p>The application uses the built-in integer types to hold values, and calls the 636provided conversion functions to convert byte ordering as needed. Both mutating 637and non-mutating conversions are supplied, and each comes in unconditional and 638conditional variants.</p> 639</dd> 640<dt class="hdlist1"><a href="#buffers">Endian buffer types</a></dt> 641<dd> 642<p>The application uses the provided endian buffer types to hold values, and 643explicitly converts to and from the built-in integer types. Buffer sizes of 8, 64416, 24, 32, 40, 48, 56, and 64 bits (i.e. 1, 2, 3, 4, 5, 6, 7, and 8 bytes) are 645provided. Unaligned integer buffer types are provided for all sizes, and aligned 646buffer types are provided for 16, 32, and 64-bit sizes. The provided specific 647types are typedefs for a generic class template that may be used directly for 648less common use cases.</p> 649</dd> 650<dt class="hdlist1"><a href="#arithmetic">Endian arithmetic types</a></dt> 651<dd> 652<p>The application uses the provided endian arithmetic types, which supply the same 653operations as the built-in C++ arithmetic types. All conversions are implicit. 654Arithmetic sizes of 8, 16, 24, 32, 40, 48, 56, and 64 bits (i.e. 1, 2, 3, 4, 5, 6556, 7, and 8 bytes) are provided. Unaligned integer types are provided for all 656sizes and aligned arithmetic types are provided for 16, 32, and 64-bit sizes. 657The provided specific types are typedefs for a generic class template that may 658be used directly in generic code of for less common use cases.</p> 659</dd> 660</dl> 661</div> 662<div class="paragraph"> 663<p>Boost Endian is a header-only library. C++11 features affecting interfaces, 664such as <code>noexcept</code>, are used only if available. See 665<a href="#overview_cpp03_support">C++03 support for C++11 features</a> for details.</p> 666</div> 667</div> 668<div class="sect2"> 669<h3 id="overview_intrinsics">Built-in support for Intrinsics</h3> 670<div class="paragraph"> 671<p>Most compilers, including GCC, Clang, and Visual C++, supply built-in support 672for byte swapping intrinsics. The Endian library uses these intrinsics when 673available since they may result in smaller and faster generated code, 674particularly for optimized builds.</p> 675</div> 676<div class="paragraph"> 677<p>Defining the macro <code>BOOST_ENDIAN_NO_INTRINSICS</code> will suppress use of the 678intrinsics. This is useful when a compiler has no intrinsic support or fails to 679locate the appropriate header, perhaps because it is an older release or has 680very limited supporting libraries.</p> 681</div> 682<div class="paragraph"> 683<p>The macro <code>BOOST_ENDIAN_INTRINSIC_MSG</code> is defined as either 684<code>"no byte swap intrinsics"</code> or a string describing the particular set of 685intrinsics being used. This is useful for eliminating missing intrinsics as a 686source of performance issues.</p> 687</div> 688</div> 689<div class="sect2"> 690<h3 id="overview_performance">Performance</h3> 691<div class="paragraph"> 692<p>Consider this problem:</p> 693</div> 694<div class="sect3"> 695<h4 id="overview_example_1">Example 1</h4> 696<div class="paragraph"> 697<p>Add 100 to a big endian value in a file, then write the result to a file</p> 698</div> 699<table class="tableblock frame-all grid-all stretch"> 700<colgroup> 701<col style="width: 50%;"> 702<col style="width: 50%;"> 703</colgroup> 704<thead> 705<tr> 706<th class="tableblock halign-left valign-top">Endian arithmetic type approach</th> 707<th class="tableblock halign-left valign-top">Endian conversion function approach</th> 708</tr> 709</thead> 710<tbody> 711<tr> 712<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock"> 713<div class="content"> 714<pre>big_int32_at x; 715 716... read into x from a file ... 717 718 719x += 100; 720 721 722... write x to a file ...</pre> 723</div> 724</div></div></td> 725<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock"> 726<div class="content"> 727<pre>int32_t x; 728 729... read into x from a file ... 730 731big_to_native_inplace(x); 732x += 100; 733native_to_big_inplace(x); 734 735... write x to a file ...</pre> 736</div> 737</div></div></td> 738</tr> 739</tbody> 740</table> 741<div class="paragraph"> 742<p><strong>There will be no performance difference between the two approaches in optimized 743builds, regardless of the native endianness of the machine.</strong> That’s because 744optimizing compilers will generate exactly the same code for each. That 745conclusion was confirmed by studying the generated assembly code for GCC and 746Visual C++. Furthermore, time spent doing I/O will determine the speed of this 747application.</p> 748</div> 749<div class="paragraph"> 750<p>Now consider a slightly different problem:</p> 751</div> 752</div> 753<div class="sect3"> 754<h4 id="overview_example_2">Example 2</h4> 755<div class="paragraph"> 756<p>Add a million values to a big endian value in a file, then write the result to a 757file</p> 758</div> 759<table class="tableblock frame-all grid-all stretch"> 760<colgroup> 761<col style="width: 50%;"> 762<col style="width: 50%;"> 763</colgroup> 764<thead> 765<tr> 766<th class="tableblock halign-left valign-top">Endian arithmetic type approach</th> 767<th class="tableblock halign-left valign-top">Endian conversion function approach</th> 768</tr> 769</thead> 770<tbody> 771<tr> 772<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock"> 773<div class="content"> 774<pre>big_int32_at x; 775 776... read into x from a file ... 777 778 779 780for (int32_t i = 0; i < 1000000; ++i) 781 x += i; 782 783 784 785... write x to a file ...</pre> 786</div> 787</div></div></td> 788<td class="tableblock halign-left valign-top"><div class="content"><div class="listingblock"> 789<div class="content"> 790<pre>int32_t x; 791 792... read into x from a file ... 793 794big_to_native_inplace(x); 795 796for (int32_t i = 0; i < 1000000; ++i) 797 x += i; 798 799native_to_big_inplace(x); 800 801... write x to a file ...</pre> 802</div> 803</div></div></td> 804</tr> 805</tbody> 806</table> 807<div class="paragraph"> 808<p>With the Endian arithmetic approach, on little endian platforms an implicit 809conversion from and then back to big endian is done inside the loop. With the 810Endian conversion function approach, the user has ensured the conversions are 811done outside the loop, so the code may run more quickly on little endian 812platforms.</p> 813</div> 814</div> 815<div class="sect3"> 816<h4 id="overview_timings">Timings</h4> 817<div class="paragraph"> 818<p>These tests were run against release builds on a circa 2012 4-core little endian 819X64 Intel Core i5-3570K CPU @ 3.40GHz under Windows 7.</p> 820</div> 821<div class="admonitionblock caution"> 822<table> 823<tr> 824<td class="icon"> 825<div class="title">Caution</div> 826</td> 827<td class="content"> 828The Windows CPU timer has very high granularity. Repeated runs of the 829same tests often yield considerably different results. 830</td> 831</tr> 832</table> 833</div> 834<div class="paragraph"> 835<p>See <code>test/loop_time_test.cpp</code> for the actual code and <code>benchmark/Jamfile.v2</code> for 836the build setup.</p> 837</div> 838<div class="sect4"> 839<h5 id="overview_gnu_c_version_4_8_2_on_linux_virtual_machine">GNU C++ version 4.8.2 on Linux virtual machine</h5> 840<div class="paragraph"> 841<p>Iterations: 10'000'000'000, Intrinsics: <code>__builtin_bswap16</code>, etc.</p> 842</div> 843<table class="tableblock frame-all grid-all stretch"> 844<colgroup> 845<col style="width: 33.3333%;"> 846<col style="width: 33.3333%;"> 847<col style="width: 33.3334%;"> 848</colgroup> 849<thead> 850<tr> 851<th class="tableblock halign-left valign-top">Test Case</th> 852<th class="tableblock halign-left valign-top">Endian arithmetic type</th> 853<th class="tableblock halign-left valign-top">Endian conversion function</th> 854</tr> 855</thead> 856<tbody> 857<tr> 858<td class="tableblock halign-left valign-top"><p class="tableblock">16-bit aligned big endian</p></td> 859<td class="tableblock halign-left valign-top"><p class="tableblock">8.46 s</p></td> 860<td class="tableblock halign-left valign-top"><p class="tableblock">5.28 s</p></td> 861</tr> 862<tr> 863<td class="tableblock halign-left valign-top"><p class="tableblock">16-bit aligned little endian</p></td> 864<td class="tableblock halign-left valign-top"><p class="tableblock">5.28 s</p></td> 865<td class="tableblock halign-left valign-top"><p class="tableblock">5.22 s</p></td> 866</tr> 867<tr> 868<td class="tableblock halign-left valign-top"><p class="tableblock">32-bit aligned big endian</p></td> 869<td class="tableblock halign-left valign-top"><p class="tableblock">8.40 s</p></td> 870<td class="tableblock halign-left valign-top"><p class="tableblock">2.11 s</p></td> 871</tr> 872<tr> 873<td class="tableblock halign-left valign-top"><p class="tableblock">32-bit aligned little endian</p></td> 874<td class="tableblock halign-left valign-top"><p class="tableblock">2.11 s</p></td> 875<td class="tableblock halign-left valign-top"><p class="tableblock">2.10 s</p></td> 876</tr> 877<tr> 878<td class="tableblock halign-left valign-top"><p class="tableblock">64-bit aligned big endian</p></td> 879<td class="tableblock halign-left valign-top"><p class="tableblock">14.02 s</p></td> 880<td class="tableblock halign-left valign-top"><p class="tableblock">3.10 s</p></td> 881</tr> 882<tr> 883<td class="tableblock halign-left valign-top"><p class="tableblock">64-bit aligned little endian</p></td> 884<td class="tableblock halign-left valign-top"><p class="tableblock">3.00 s</p></td> 885<td class="tableblock halign-left valign-top"><p class="tableblock">3.03 s</p></td> 886</tr> 887</tbody> 888</table> 889</div> 890<div class="sect4"> 891<h5 id="overview_microsoft_visual_c_version_14_0">Microsoft Visual C++ version 14.0</h5> 892<div class="paragraph"> 893<p>Iterations: 10'000'000'000, Intrinsics: <code><cstdlib></code> <code>_byteswap_ushort</code>, etc.</p> 894</div> 895<table class="tableblock frame-all grid-all stretch"> 896<colgroup> 897<col style="width: 33.3333%;"> 898<col style="width: 33.3333%;"> 899<col style="width: 33.3334%;"> 900</colgroup> 901<thead> 902<tr> 903<th class="tableblock halign-left valign-top">Test Case</th> 904<th class="tableblock halign-left valign-top">Endian arithmetic type</th> 905<th class="tableblock halign-left valign-top">Endian conversion function</th> 906</tr> 907</thead> 908<tbody> 909<tr> 910<td class="tableblock halign-left valign-top"><p class="tableblock">16-bit aligned big endian</p></td> 911<td class="tableblock halign-left valign-top"><p class="tableblock">8.27 s</p></td> 912<td class="tableblock halign-left valign-top"><p class="tableblock">5.26 s</p></td> 913</tr> 914<tr> 915<td class="tableblock halign-left valign-top"><p class="tableblock">16-bit aligned little endian</p></td> 916<td class="tableblock halign-left valign-top"><p class="tableblock">5.29 s</p></td> 917<td class="tableblock halign-left valign-top"><p class="tableblock">5.32 s</p></td> 918</tr> 919<tr> 920<td class="tableblock halign-left valign-top"><p class="tableblock">32-bit aligned big endian</p></td> 921<td class="tableblock halign-left valign-top"><p class="tableblock">8.36 s</p></td> 922<td class="tableblock halign-left valign-top"><p class="tableblock">5.24 s</p></td> 923</tr> 924<tr> 925<td class="tableblock halign-left valign-top"><p class="tableblock">32-bit aligned little endian</p></td> 926<td class="tableblock halign-left valign-top"><p class="tableblock">5.24 s</p></td> 927<td class="tableblock halign-left valign-top"><p class="tableblock">5.24 s</p></td> 928</tr> 929<tr> 930<td class="tableblock halign-left valign-top"><p class="tableblock">64-bit aligned big endian</p></td> 931<td class="tableblock halign-left valign-top"><p class="tableblock">13.65 s</p></td> 932<td class="tableblock halign-left valign-top"><p class="tableblock">3.34 s</p></td> 933</tr> 934<tr> 935<td class="tableblock halign-left valign-top"><p class="tableblock">64-bit aligned little endian</p></td> 936<td class="tableblock halign-left valign-top"><p class="tableblock">3.35 s</p></td> 937<td class="tableblock halign-left valign-top"><p class="tableblock">2.73 s</p></td> 938</tr> 939</tbody> 940</table> 941</div> 942</div> 943</div> 944<div class="sect2"> 945<h3 id="overview_cpp03_support">C++03 support for C++11 features</h3> 946<table class="tableblock frame-all grid-all stretch"> 947<colgroup> 948<col style="width: 50%;"> 949<col style="width: 50%;"> 950</colgroup> 951<thead> 952<tr> 953<th class="tableblock halign-left valign-top">C++11 Feature</th> 954<th class="tableblock halign-left valign-top">Action with C++03 Compilers</th> 955</tr> 956</thead> 957<tbody> 958<tr> 959<td class="tableblock halign-left valign-top"><p class="tableblock">Scoped enums</p></td> 960<td class="tableblock halign-left valign-top"><p class="tableblock">Uses header 961<a href="http://www.boost.org/libs/core/doc/html/core/scoped_enum.html">boost/core/scoped_enum.hpp</a> 962to emulate C++11 scoped enums.</p></td> 963</tr> 964<tr> 965<td class="tableblock halign-left valign-top"><p class="tableblock"><code>noexcept</code></p></td> 966<td class="tableblock halign-left valign-top"><p class="tableblock">Uses <code>BOOST_NOEXCEPT</code> macro, which is defined as null for compilers not 967supporting this C++11 feature.</p></td> 968</tr> 969<tr> 970<td class="tableblock halign-left valign-top"><p class="tableblock">C++11 PODs 971(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm">N2342</a>)</p></td> 972<td class="tableblock halign-left valign-top"><p class="tableblock">Takes advantage of C++03 compilers that relax C++03 POD rules, but see 973Limitations <a href="#buffers_limitations">here</a> and <a href="#arithmetic_limitations">here</a>. 974Also see macros for explicit POD control <a href="#buffers_compilation">here</a> and 975<a href="#arithmetic_compilation">here</a></p></td> 976</tr> 977</tbody> 978</table> 979</div> 980<div class="sect2"> 981<h3 id="overview_faq">Overall FAQ</h3> 982<div class="dlist"> 983<dl> 984<dt class="hdlist1">Is the implementation header only?</dt> 985<dd> 986<p>Yes.</p> 987</dd> 988<dt class="hdlist1">Are C++03 compilers supported?</dt> 989<dd> 990<p>Yes.</p> 991</dd> 992<dt class="hdlist1">Does the implementation use compiler intrinsic built-in byte swapping?</dt> 993<dd> 994<p>Yes, if available. See <a href="#overview_intrinsics">Intrinsic built-in support</a>.</p> 995</dd> 996<dt class="hdlist1">Why bother with endianness?</dt> 997<dd> 998<p>Binary data portability is the primary use case.</p> 999</dd> 1000<dt class="hdlist1">Does endianness have any uses outside of portable binary file or network I/O formats?</dt> 1001<dd> 1002<p>Using the unaligned integer types with a size tailored to the application’s 1003needs is a minor secondary use that saves internal or external memory space. For 1004example, using <code>big_int40_buf_t</code> or <code>big_int40_t</code> in a large array saves a lot 1005of space compared to one of the 64-bit types.</p> 1006</dd> 1007<dt class="hdlist1">Why bother with binary I/O? Why not just use C++ Standard Library stream inserters and extractors?</dt> 1008<dd> 1009<div class="ulist"> 1010<ul> 1011<li> 1012<p>Data interchange formats often specify binary integer data. Binary integer 1013data is smaller and therefore I/O is faster and file sizes are smaller. Transfer 1014between systems is less expensive.</p> 1015</li> 1016<li> 1017<p>Furthermore, binary integer data is of fixed size, and so fixed-size disk 1018records are possible without padding, easing sorting and allowing random access.</p> 1019</li> 1020<li> 1021<p>Disadvantages, such as the inability to use text utilities on the resulting 1022files, limit usefulness to applications where the binary I/O advantages are 1023paramount.</p> 1024</li> 1025</ul> 1026</div> 1027</dd> 1028<dt class="hdlist1">Which is better, big-endian or little-endian?</dt> 1029<dd> 1030<p>Big-endian tends to be preferred in a networking environment and is a bit more 1031of an industry standard, but little-endian may be preferred for applications 1032that run primarily on x86, x86-64, and other little-endian CPU’s. The 1033<a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> article gives more pros and cons.</p> 1034</dd> 1035<dt class="hdlist1">Why are only big and little native endianness supported?</dt> 1036<dd> 1037<p>These are the only endian schemes that have any practical value today. PDP-11 1038and the other middle endian approaches are interesting curiosities but have no 1039relevance for today’s C++ developers. The same is true for architectures that 1040allow runtime endianness switching. The 1041<a href="#conversion_native_order_specification">specification for native ordering</a> has 1042been carefully crafted to allow support for such orderings in the future, should 1043the need arise. Thanks to Howard Hinnant for suggesting this.</p> 1044</dd> 1045<dt class="hdlist1">Why do both the buffer and arithmetic types exist?</dt> 1046<dd> 1047<p>Conversions in the buffer types are explicit. Conversions in the arithmetic 1048types are implicit. This fundamental difference is a deliberate design feature 1049that would be lost if the inheritance hierarchy were collapsed. 1050The original design provided only arithmetic types. Buffer types were requested 1051during formal review by those wishing total control over when conversion occurs. 1052They also felt that buffer types would be less likely to be misused by 1053maintenance programmers not familiar with the implications of performing a lot 1054of integer operations on the endian arithmetic integer types.</p> 1055</dd> 1056<dt class="hdlist1">What is gained by using the buffer types rather than always just using the arithmetic types?</dt> 1057<dd> 1058<p>Assurance that hidden conversions are not performed. This is of overriding 1059importance to users concerned about achieving the ultimate in terms of speed. 1060"Always just using the arithmetic types" is fine for other users. When the 1061ultimate in speed needs to be ensured, the arithmetic types can be used in the 1062same design patterns or idioms that would be used for buffer types, resulting in 1063the same code being generated for either types.</p> 1064</dd> 1065<dt class="hdlist1">What are the limitations of integer support?</dt> 1066<dd> 1067<p>Tests have only been performed on machines that use two’s complement 1068arithmetic. The Endian conversion functions only support 8, 16, 32, and 64-bit 1069aligned integers. The endian types only support 8, 16, 24, 32, 40, 48, 56, and 107064-bit unaligned integers, and 8, 16, 32, and 64-bit aligned integers.</p> 1071</dd> 1072<dt class="hdlist1">Is there floating point support?</dt> 1073<dd> 1074<p>An attempt was made to support four-byte <code>float</code>s and eight-byte 1075<code>double</code>s, limited to 1076<a href="http://en.wikipedia.org/wiki/IEEE_floating_point">IEEE 754</a> (also known as 1077ISO/IEC/IEEE 60559) floating point and further limited to systems where floating 1078point endianness does not differ from integer endianness. Even with those 1079limitations, support for floating point types was not reliable and was removed. 1080For example, simply reversing the endianness of a floating point number can 1081result in a signaling-NAN.</p> 1082<div class="paragraph"> 1083<p>Support for <code>float</code> and <code>double</code> has since been reinstated for <code>endian_buffer</code>, 1084<code>endian_arithmetic</code> and the conversion functions that reverse endianness in place. 1085The conversion functions that take and return by value still do not support floating 1086point due to the above issues; reversing the bytes of a floating point number 1087does not necessarily produce another valid floating point number.</p> 1088</div> 1089</dd> 1090</dl> 1091</div> 1092</div> 1093</div> 1094</div> 1095<div class="sect1"> 1096<h2 id="changelog">Revision History</h2> 1097<div class="sectionbody"> 1098<div class="sect2"> 1099<h3 id="overview_changes_in_1_74_0">Changes in 1.74.0</h3> 1100<div class="ulist"> 1101<ul> 1102<li> 1103<p>Enabled scoped enumeration types in <code>endian_reverse</code></p> 1104</li> 1105<li> 1106<p>Enabled <code>bool</code>, <code>enum</code>, <code>float</code>, <code>double</code> in <code>endian_reverse_inplace</code></p> 1107</li> 1108<li> 1109<p>Added an overload of <code>endian_reverse_inplace</code> for arrays</p> 1110</li> 1111</ul> 1112</div> 1113</div> 1114<div class="sect2"> 1115<h3 id="overview_changes_in_1_72_0">Changes in 1.72.0</h3> 1116<div class="ulist"> 1117<ul> 1118<li> 1119<p>Made <code>endian_reverse</code>, <code>conditional_reverse</code> and <code>*_to_*</code> <code>constexpr</code> 1120on GCC and Clang</p> 1121</li> 1122<li> 1123<p>Added convenience load and store functions</p> 1124</li> 1125<li> 1126<p>Added floating point convenience typedefs</p> 1127</li> 1128<li> 1129<p>Added a non-const overload of <code>data()</code>; changed its return type to <code>unsigned char*</code></p> 1130</li> 1131<li> 1132<p>Added <code>__int128</code> support to <code>endian_reverse</code> when available</p> 1133</li> 1134<li> 1135<p>Added a convenience header <code>boost/endian.hpp</code></p> 1136</li> 1137</ul> 1138</div> 1139</div> 1140<div class="sect2"> 1141<h3 id="overview_changes_in_1_71_0">Changes in 1.71.0</h3> 1142<div class="ulist"> 1143<ul> 1144<li> 1145<p>Clarified requirements on the value type template parameter</p> 1146</li> 1147<li> 1148<p>Added support for <code>float</code> and <code>double</code> to <code>endian_buffer</code> and <code>endian_arithmetic</code></p> 1149</li> 1150<li> 1151<p>Added <code>endian_load</code>, <code>endian_store</code></p> 1152</li> 1153<li> 1154<p>Updated <code>endian_reverse</code> to correctly support all non-<code>bool</code> integral types</p> 1155</li> 1156<li> 1157<p>Moved deprecated names to the deprecated header <code>endian.hpp</code></p> 1158</li> 1159</ul> 1160</div> 1161</div> 1162</div> 1163</div> 1164<div class="sect1"> 1165<h2 id="choosing">Choosing between Conversion Functions, Buffer Types, and Arithmetic Types</h2> 1166<div class="sectionbody"> 1167<div class="admonitionblock note"> 1168<table> 1169<tr> 1170<td class="icon"> 1171<div class="title">Note</div> 1172</td> 1173<td class="content"> 1174Deciding which is the best endianness approach (conversion functions, buffer 1175types, or arithmetic types) for a particular application involves complex 1176engineering trade-offs. It is hard to assess those trade-offs without some 1177understanding of the different interfaces, so you might want to read the 1178<a href="#conversion">conversion functions</a>, <a href="#buffers">buffer types</a>, and 1179<a href="#arithmetic">arithmetic types</a> pages before proceeding. 1180</td> 1181</tr> 1182</table> 1183</div> 1184<div class="paragraph"> 1185<p>The best approach to endianness for a particular application depends on the 1186interaction between the application’s needs and the characteristics of each of 1187the three approaches.</p> 1188</div> 1189<div class="paragraph"> 1190<p><strong>Recommendation:</strong> If you are new to endianness, uncertain, or don’t want to 1191invest the time to study engineering trade-offs, use 1192<a href="#arithmetic">endian arithmetic types</a>. They are safe, easy to use, and easy to 1193maintain. Use the <em><a href="#choosing_anticipating_need">anticipating need</a></em> design 1194pattern locally around performance hot spots like lengthy loops, if needed.</p> 1195</div> 1196<div class="sect2"> 1197<h3 id="choosing_background">Background</h3> 1198<div class="paragraph"> 1199<p>A dealing with endianness usually implies a program portability or a data 1200portability requirement, and often both. That means real programs dealing with 1201endianness are usually complex, so the examples shown here would really be 1202written as multiple functions spread across multiple translation units. They 1203would involve interfaces that can not be altered as they are supplied by 1204third-parties or the standard library.</p> 1205</div> 1206</div> 1207<div class="sect2"> 1208<h3 id="choosing_characteristics">Characteristics</h3> 1209<div class="paragraph"> 1210<p>The characteristics that differentiate the three approaches to endianness are 1211the endianness invariants, conversion explicitness, arithmetic operations, sizes 1212available, and alignment requirements.</p> 1213</div> 1214<div class="sect3"> 1215<h4 id="choosing_endianness_invariants">Endianness invariants</h4> 1216<div class="paragraph"> 1217<p><strong>Endian conversion functions</strong> use objects of the ordinary C++ arithmetic types 1218like <code>int</code> or <code>unsigned short</code> to hold values. That breaks the implicit 1219invariant that the C++ language rules apply. The usual language rules only apply 1220if the endianness of the object is currently set to the native endianness for 1221the platform. That can make it very hard to reason about logic flow, and result 1222in difficult to find bugs.</p> 1223</div> 1224<div class="paragraph"> 1225<p>For example:</p> 1226</div> 1227<div class="listingblock"> 1228<div class="content"> 1229<pre class="highlight"><code>struct data_t // big endian 1230{ 1231 int32_t v1; // description ... 1232 int32_t v2; // description ... 1233 ... additional character data members (i.e. non-endian) 1234 int32_t v3; // description ... 1235}; 1236 1237data_t data; 1238 1239read(data); 1240big_to_native_inplace(data.v1); 1241big_to_native_inplace(data.v2); 1242 1243... 1244 1245++v1; 1246third_party::func(data.v2); 1247 1248... 1249 1250native_to_big_inplace(data.v1); 1251native_to_big_inplace(data.v2); 1252write(data);</code></pre> 1253</div> 1254</div> 1255<div class="paragraph"> 1256<p>The programmer didn’t bother to convert <code>data.v3</code> to native endianness because 1257that member isn’t used. A later maintainer needs to pass <code>data.v3</code> to the 1258third-party function, so adds <code>third_party::func(data.v3);</code> somewhere deep in 1259the code. This causes a silent failure because the usual invariant that an 1260object of type <code>int32_t</code> holds a value as described by the C++ core language 1261does not apply.</p> 1262</div> 1263<div class="paragraph"> 1264<p><strong>Endian buffer and arithmetic types</strong> hold values internally as arrays of 1265characters with an invariant that the endianness of the array never changes. 1266That makes these types easier to use and programs easier to maintain.</p> 1267</div> 1268<div class="paragraph"> 1269<p>Here is the same example, using an endian arithmetic type:</p> 1270</div> 1271<div class="listingblock"> 1272<div class="content"> 1273<pre class="highlight"><code>struct data_t 1274{ 1275 big_int32_t v1; // description ... 1276 big_int32_t v2; // description ... 1277 ... additional character data members (i.e. non-endian) 1278 big_int32_t v3; // description ... 1279}; 1280 1281data_t data; 1282 1283read(data); 1284 1285... 1286 1287++v1; 1288third_party::func(data.v2); 1289 1290... 1291 1292write(data);</code></pre> 1293</div> 1294</div> 1295<div class="paragraph"> 1296<p>A later maintainer can add <code>third_party::func(data.v3)</code> and it will just-work.</p> 1297</div> 1298</div> 1299<div class="sect3"> 1300<h4 id="choosing_conversion_explicitness">Conversion explicitness</h4> 1301<div class="paragraph"> 1302<p><strong>Endian conversion functions</strong> and <strong>buffer types</strong> never perform implicit 1303conversions. This gives users explicit control of when conversion occurs, and 1304may help avoid unnecessary conversions.</p> 1305</div> 1306<div class="paragraph"> 1307<p><strong>Endian arithmetic types</strong> perform conversion implicitly. That makes these types 1308very easy to use, but can result in unnecessary conversions. Failure to hoist 1309conversions out of inner loops can bring a performance penalty.</p> 1310</div> 1311</div> 1312<div class="sect3"> 1313<h4 id="choosing_arithmetic_operations">Arithmetic operations</h4> 1314<div class="paragraph"> 1315<p><strong>Endian conversion functions</strong> do not supply arithmetic operations, but this is 1316not a concern since this approach uses ordinary C++ arithmetic types to hold 1317values.</p> 1318</div> 1319<div class="paragraph"> 1320<p><strong>Endian buffer types</strong> do not supply arithmetic operations. Although this 1321approach avoids unnecessary conversions, it can result in the introduction of 1322additional variables and confuse maintenance programmers.</p> 1323</div> 1324<div class="paragraph"> 1325<p><strong>Endian arithmetic types</strong> do supply arithmetic operations. They are very easy to 1326use if lots of arithmetic is involved.</p> 1327</div> 1328</div> 1329<div class="sect3"> 1330<h4 id="choosing_sizes">Sizes</h4> 1331<div class="paragraph"> 1332<p><strong>Endianness conversion functions</strong> only support 1, 2, 4, and 8 byte integers. 1333That’s sufficient for many applications.</p> 1334</div> 1335<div class="paragraph"> 1336<p><strong>Endian buffer and arithmetic types</strong> support 1, 2, 3, 4, 5, 6, 7, and 8 byte 1337integers. For an application where memory use or I/O speed is the limiting 1338factor, using sizes tailored to application needs can be useful.</p> 1339</div> 1340</div> 1341<div class="sect3"> 1342<h4 id="choosing_alignments">Alignments</h4> 1343<div class="paragraph"> 1344<p><strong>Endianness conversion functions</strong> only support aligned integer and 1345floating-point types. That’s sufficient for most applications.</p> 1346</div> 1347<div class="paragraph"> 1348<p><strong>Endian buffer and arithmetic types</strong> support both aligned and unaligned 1349integer and floating-point types. Unaligned types are rarely needed, but when 1350needed they are often very useful and workarounds are painful. For example:</p> 1351</div> 1352<div class="paragraph"> 1353<p>Non-portable code like this:</p> 1354</div> 1355<div class="listingblock"> 1356<div class="content"> 1357<pre class="highlight"><code>struct S { 1358 uint16_t a; // big endian 1359 uint32_t b; // big endian 1360} __attribute__ ((packed));</code></pre> 1361</div> 1362</div> 1363<div class="paragraph"> 1364<p>Can be replaced with portable code like this:</p> 1365</div> 1366<div class="listingblock"> 1367<div class="content"> 1368<pre class="highlight"><code>struct S { 1369 big_uint16_ut a; 1370 big_uint32_ut b; 1371};</code></pre> 1372</div> 1373</div> 1374</div> 1375</div> 1376<div class="sect2"> 1377<h3 id="choosing_design_patterns">Design patterns</h3> 1378<div class="paragraph"> 1379<p>Applications often traffic in endian data as records or packets containing 1380multiple endian data elements. For simplicity, we will just call them records.</p> 1381</div> 1382<div class="paragraph"> 1383<p>If desired endianness differs from native endianness, a conversion has to be 1384performed. When should that conversion occur? Three design patterns have 1385evolved.</p> 1386</div> 1387<div class="sect3"> 1388<h4 id="choosing_convert_only_as_needed_i_e_lazy">Convert only as needed (i.e. lazy)</h4> 1389<div class="paragraph"> 1390<p>This pattern defers conversion to the point in the code where the data 1391element is actually used.</p> 1392</div> 1393<div class="paragraph"> 1394<p>This pattern is appropriate when which endian element is actually used varies 1395greatly according to record content or other circumstances</p> 1396</div> 1397</div> 1398<div class="sect3"> 1399<h4 id="choosing_anticipating_need">Convert in anticipation of need</h4> 1400<div class="paragraph"> 1401<p>This pattern performs conversion to native endianness in anticipation of use, 1402such as immediately after reading records. If needed, conversion to the output 1403endianness is performed after all possible needs have passed, such as just 1404before writing records.</p> 1405</div> 1406<div class="paragraph"> 1407<p>One implementation of this pattern is to create a proxy record with endianness 1408converted to native in a read function, and expose only that proxy to the rest 1409of the implementation. If a write function, if needed, handles the conversion 1410from native to the desired output endianness.</p> 1411</div> 1412<div class="paragraph"> 1413<p>This pattern is appropriate when all endian elements in a record are typically 1414used regardless of record content or other circumstances.</p> 1415</div> 1416</div> 1417<div class="sect3"> 1418<h4 id="choosing_convert_only_as_needed_except_locally_in_anticipation_of_need">Convert only as needed, except locally in anticipation of need</h4> 1419<div class="paragraph"> 1420<p>This pattern in general defers conversion but for specific local needs does 1421anticipatory conversion. Although particularly appropriate when coupled with the 1422endian buffer or arithmetic types, it also works well with the conversion 1423functions.</p> 1424</div> 1425<div class="paragraph"> 1426<p>Example:</p> 1427</div> 1428<div class="listingblock"> 1429<div class="content"> 1430<pre class="highlight"><code>struct data_t 1431{ 1432 big_int32_t v1; 1433 big_int32_t v2; 1434 big_int32_t v3; 1435}; 1436 1437data_t data; 1438 1439read(data); 1440 1441... 1442++v1; 1443... 1444 1445int32_t v3_temp = data.v3; // hoist conversion out of loop 1446 1447for (int32_t i = 0; i < <code>large-number</code>; ++i) 1448{ 1449 ... <code>lengthy computation that accesses v3_temp</code> ... 1450} 1451data.v3 = v3_temp; 1452 1453write(data);</code></pre> 1454</div> 1455</div> 1456<div class="paragraph"> 1457<p>In general the above pseudo-code leaves conversion up to the endian arithmetic 1458type <code>big_int32_t</code>. But to avoid conversion inside the loop, a temporary is 1459created before the loop is entered, and then used to set the new value of 1460<code>data.v3</code> after the loop is complete.</p> 1461</div> 1462<div class="paragraph"> 1463<p>Question: Won’t the compiler’s optimizer hoist the conversion out of the loop 1464anyhow?</p> 1465</div> 1466<div class="paragraph"> 1467<p>Answer: VC++ 2015 Preview, and probably others, does not, even for a toy test 1468program. Although the savings is small (two register <code>bswap</code> instructions), the 1469cost might be significant if the loop is repeated enough times. On the other 1470hand, the program may be so dominated by I/O time that even a lengthy loop will 1471be immaterial.</p> 1472</div> 1473</div> 1474</div> 1475<div class="sect2"> 1476<h3 id="choosing_use_case_examples">Use case examples</h3> 1477<div class="sect3"> 1478<h4 id="choosing_porting_endian_unaware_codebase">Porting endian unaware codebase</h4> 1479<div class="paragraph"> 1480<p>An existing codebase runs on big endian systems. It does not currently deal 1481with endianness. The codebase needs to be modified so it can run on little 1482endian systems under various operating systems. To ease transition and protect 1483value of existing files, external data will continue to be maintained as big 1484endian.</p> 1485</div> 1486<div class="paragraph"> 1487<p>The <a href="#arithmetic">endian arithmetic approach</a> is recommended to meet these 1488needs. A relatively small number of header files dealing with binary I/O layouts 1489need to change types. For example, <code>short</code> or <code>int16_t</code> would change to 1490<code>big_int16_t</code>. No changes are required for <code>.cpp</code> files.</p> 1491</div> 1492</div> 1493<div class="sect3"> 1494<h4 id="choosing_porting_endian_aware_codebase">Porting endian aware codebase</h4> 1495<div class="paragraph"> 1496<p>An existing codebase runs on little-endian Linux systems. It already deals with 1497endianness via 1498<a href="http://man7.org/linux/man-pages/man3/endian.3.html">Linux provided functions</a>. 1499Because of a business merger, the codebase has to be quickly modified for 1500Windows and possibly other operating systems, while still supporting Linux. The 1501codebase is reliable and the programmers are all well-aware of endian issues.</p> 1502</div> 1503<div class="paragraph"> 1504<p>These factors all argue for an <a href="#conversion">endian conversion approach</a> that 1505just mechanically changes the calls to <code>htobe32</code>, etc. to 1506<code>boost::endian::native_to_big</code>, etc. and replaces <code><endian.h></code> with 1507<code><boost/endian/conversion.hpp></code>.</p> 1508</div> 1509</div> 1510<div class="sect3"> 1511<h4 id="choosing_reliability_and_arithmetic_speed">Reliability and arithmetic-speed</h4> 1512<div class="paragraph"> 1513<p>A new, complex, multi-threaded application is to be developed that must run 1514on little endian machines, but do big endian network I/O. The developers believe 1515computational speed for endian variable is critical but have seen numerous bugs 1516result from inability to reason about endian conversion state. They are also 1517worried that future maintenance changes could inadvertently introduce a lot of 1518slow conversions if full-blown endian arithmetic types are used.</p> 1519</div> 1520<div class="paragraph"> 1521<p>The <a href="#buffers">endian buffers</a> approach is made-to-order for this use case.</p> 1522</div> 1523</div> 1524<div class="sect3"> 1525<h4 id="choosing_reliability_and_ease_of_use">Reliability and ease-of-use</h4> 1526<div class="paragraph"> 1527<p>A new, complex, multi-threaded application is to be developed that must run on 1528little endian machines, but do big endian network I/O. The developers believe 1529computational speed for endian variables is <strong>not critical</strong> but have seen 1530numerous bugs result from inability to reason about endian conversion state. 1531They are also concerned about ease-of-use both during development and long-term 1532maintenance.</p> 1533</div> 1534<div class="paragraph"> 1535<p>Removing concern about conversion speed and adding concern about ease-of-use 1536tips the balance strongly in favor the 1537<a href="#arithmetic">endian arithmetic approach</a>.</p> 1538</div> 1539</div> 1540</div> 1541</div> 1542</div> 1543<div class="sect1"> 1544<h2 id="conversion">Endian Conversion Functions</h2> 1545<div class="sectionbody"> 1546<div class="sect2"> 1547<h3 id="conversion_introduction">Introduction</h3> 1548<div class="paragraph"> 1549<p>Header <code>boost/endian/conversion.hpp</code> provides byte order reversal and conversion 1550functions that convert objects of the built-in integer types between native, 1551big, or little endian byte ordering. User defined types are also supported.</p> 1552</div> 1553</div> 1554<div class="sect2"> 1555<h3 id="conversion_reference">Reference</h3> 1556<div class="paragraph"> 1557<p>Functions are implemented <code>inline</code> if appropriate. For C++03 compilers, 1558<code>noexcept</code> is elided. Boost scoped enum emulation is used so that the library 1559still works for compilers that do not support scoped enums.</p> 1560</div> 1561<div class="sect3"> 1562<h4 id="conversion_definitions">Definitions</h4> 1563<div class="paragraph"> 1564<p><strong>Endianness</strong> refers to the ordering of bytes within internal or external 1565integers and other arithmetic data. Most-significant byte first is called 1566<strong>big endian</strong> ordering. Least-significant byte first is called 1567<strong>little endian</strong> ordering. Other orderings are possible and some CPU 1568architectures support both big and little ordering.</p> 1569</div> 1570<div class="admonitionblock note"> 1571<table> 1572<tr> 1573<td class="icon"> 1574<div class="title">Note</div> 1575</td> 1576<td class="content"> 1577The names are derived from 1578<a href="http://en.wikipedia.org/wiki/Jonathan_Swift">Jonathan Swift</a>'s satirical novel 1579<em><a href="http://en.wikipedia.org/wiki/Gulliver’s_Travels">Gulliver’s Travels</a></em>, where 1580rival kingdoms opened their soft-boiled eggs at different ends. Wikipedia has an 1581extensive description of <a href="https://en.wikipedia.org/wiki/Endianness">Endianness</a>. 1582</td> 1583</tr> 1584</table> 1585</div> 1586<div class="paragraph"> 1587<p>The standard integral types (C++std [basic.fundamental]) except <code>bool</code> and 1588the scoped enumeration types (C++std [dcl.enum]) are collectively called the 1589<strong>endian types</strong>. In the absence of padding bits, which is true on the platforms 1590supported by the Boost.Endian library, endian types have the property that all 1591of their bit patterns are valid values, which means that when an object of an 1592endian type has its constituent bytes reversed, the result is another valid value. 1593This allows <code>endian_reverse</code> to take and return by value.</p> 1594</div> 1595<div class="paragraph"> 1596<p>Other built-in types, such as <code>bool</code>, <code>float</code>, or unscoped enumerations, do not 1597have the same property, which means that reversing their constituent bytes may 1598produce an invalid value, leading to undefined behavior. These types are therefore 1599disallowed in <code>endian_reverse</code>, but are still allowed in <code>endian_reverse_inplace</code>. 1600Even if an object becomes invalid as a result of reversing its bytes, as long as 1601its value is never read, there would be no undefined behavior.</p> 1602</div> 1603</div> 1604<div class="sect3"> 1605<h4 id="conversion_header_boostendianconversion_hpp_synopsis">Header <code><boost/endian/conversion.hpp></code> Synopsis</h4> 1606<div class="listingblock"> 1607<div class="content"> 1608<pre class="highlight"><code>#define BOOST_ENDIAN_INTRINSIC_MSG \ 1609 “message describing presence or absence of intrinsics” 1610 1611namespace boost 1612{ 1613namespace endian 1614{ 1615 enum class order 1616 { 1617 native = <code>see below</code>, 1618 big = <code>see below</code>, 1619 little = <code>see below</code>, 1620 }; 1621 1622 // Byte reversal functions 1623 1624 template <class Endian> 1625 Endian endian_reverse(Endian x) noexcept; 1626 1627 template <class EndianReversible> 1628 EndianReversible big_to_native(EndianReversible x) noexcept; 1629 template <class EndianReversible> 1630 EndianReversible native_to_big(EndianReversible x) noexcept; 1631 template <class EndianReversible> 1632 EndianReversible little_to_native(EndianReversible x) noexcept; 1633 template <class EndianReversible> 1634 EndianReversible native_to_little(EndianReversible x) noexcept; 1635 1636 template <order O1, order O2, class EndianReversible> 1637 EndianReversible conditional_reverse(EndianReversible x) noexcept; 1638 template <class EndianReversible> 1639 EndianReversible conditional_reverse(EndianReversible x, 1640 order order1, order order2) noexcept; 1641 1642 // In-place byte reversal functions 1643 1644 template <class EndianReversible> 1645 void endian_reverse_inplace(EndianReversible& x) noexcept; 1646 1647 template<class EndianReversibleInplace, std::size_t N> 1648 void endian_reverse_inplace(EndianReversibleInplace (&x)[N]) noexcept; 1649 1650 template <class EndianReversibleInplace> 1651 void big_to_native_inplace(EndianReversibleInplace& x) noexcept; 1652 template <class EndianReversibleInplace> 1653 void native_to_big_inplace(EndianReversibleInplace& x) noexcept; 1654 template <class EndianReversibleInplace> 1655 void little_to_native_inplace(EndianReversibleInplace& x) noexcept; 1656 template <class EndianReversibleInplace> 1657 void native_to_little_inplace(EndianReversibleInplace& x) noexcept; 1658 1659 template <order O1, order O2, class EndianReversibleInplace> 1660 void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept; 1661 template <class EndianReversibleInplace> 1662 void conditional_reverse_inplace(EndianReversibleInplace& x, 1663 order order1, order order2) noexcept; 1664 1665 // Generic load and store functions 1666 1667 template<class T, std::size_t N, order Order> 1668 T endian_load( unsigned char const * p ) noexcept; 1669 1670 template<class T, std::size_t N, order Order> 1671 void endian_store( unsigned char * p, T const & v ) noexcept; 1672 1673 // Convenience load functions 1674 1675 boost::int16_t load_little_s16( unsigned char const * p ) noexcept; 1676 boost::uint16_t load_little_u16( unsigned char const * p ) noexcept; 1677 boost::int16_t load_big_s16( unsigned char const * p ) noexcept; 1678 boost::uint16_t load_big_u16( unsigned char const * p ) noexcept; 1679 1680 boost::int32_t load_little_s24( unsigned char const * p ) noexcept; 1681 boost::uint32_t load_little_u24( unsigned char const * p ) noexcept; 1682 boost::int32_t load_big_s24( unsigned char const * p ) noexcept; 1683 boost::uint32_t load_big_u24( unsigned char const * p ) noexcept; 1684 1685 boost::int32_t load_little_s32( unsigned char const * p ) noexcept; 1686 boost::uint32_t load_little_u32( unsigned char const * p ) noexcept; 1687 boost::int32_t load_big_s32( unsigned char const * p ) noexcept; 1688 boost::uint32_t load_big_u32( unsigned char const * p ) noexcept; 1689 1690 boost::int64_t load_little_s40( unsigned char const * p ) noexcept; 1691 boost::uint64_t load_little_u40( unsigned char const * p ) noexcept; 1692 boost::int64_t load_big_s40( unsigned char const * p ) noexcept; 1693 boost::uint64_t load_big_u40( unsigned char const * p ) noexcept; 1694 1695 boost::int64_t load_little_s48( unsigned char const * p ) noexcept; 1696 boost::uint64_t load_little_u48( unsigned char const * p ) noexcept; 1697 boost::int64_t load_big_s48( unsigned char const * p ) noexcept; 1698 boost::uint64_t load_big_u48( unsigned char const * p ) noexcept; 1699 1700 boost::int64_t load_little_s56( unsigned char const * p ) noexcept; 1701 boost::uint64_t load_little_u56( unsigned char const * p ) noexcept; 1702 boost::int64_t load_big_s56( unsigned char const * p ) noexcept; 1703 boost::uint64_t load_big_u56( unsigned char const * p ) noexcept; 1704 1705 boost::int64_t load_little_s64( unsigned char const * p ) noexcept; 1706 boost::uint64_t load_little_u64( unsigned char const * p ) noexcept; 1707 boost::int64_t load_big_s64( unsigned char const * p ) noexcept; 1708 boost::uint64_t load_big_u64( unsigned char const * p ) noexcept; 1709 1710 // Convenience store functions 1711 1712 void store_little_s16( unsigned char * p, boost::int16_t v ) noexcept; 1713 void store_little_u16( unsigned char * p, boost::uint16_t v ) noexcept; 1714 void store_big_s16( unsigned char * p, boost::int16_t v ) noexcept; 1715 void store_big_u16( unsigned char * p, boost::uint16_t v ) noexcept; 1716 1717 void store_little_s24( unsigned char * p, boost::int32_t v ) noexcept; 1718 void store_little_u24( unsigned char * p, boost::uint32_t v ) noexcept; 1719 void store_big_s24( unsigned char * p, boost::int32_t v ) noexcept; 1720 void store_big_u24( unsigned char * p, boost::uint32_t v ) noexcept; 1721 1722 void store_little_s32( unsigned char * p, boost::int32_t v ) noexcept; 1723 void store_little_u32( unsigned char * p, boost::uint32_t v ) noexcept; 1724 void store_big_s32( unsigned char * p, boost::int32_t v ) noexcept; 1725 void store_big_u32( unsigned char * p, boost::uint32_t v ) noexcept; 1726 1727 void store_little_s40( unsigned char * p, boost::int64_t v ) noexcept; 1728 void store_little_u40( unsigned char * p, boost::uint64_t v ) noexcept; 1729 void store_big_s40( unsigned char * p, boost::int64_t v ) noexcept; 1730 void store_big_u40( unsigned char * p, boost::uint64_t v ) noexcept; 1731 1732 void store_little_s48( unsigned char * p, boost::int64_t v ) noexcept; 1733 void store_little_u48( unsigned char * p, boost::uint64_t v ) noexcept; 1734 void store_big_s48( unsigned char * p, boost::int64_t v ) noexcept; 1735 void store_big_u48( unsigned char * p, boost::uint64_t v ) noexcept; 1736 1737 void store_little_s56( unsigned char * p, boost::int64_t v ) noexcept; 1738 void store_little_u56( unsigned char * p, boost::uint64_t v ) noexcept; 1739 void store_big_s56( unsigned char * p, boost::int64_t v ) noexcept; 1740 void store_big_u56( unsigned char * p, boost::uint64_t v ) noexcept; 1741 1742 void store_little_s64( unsigned char * p, boost::int64_t v ) noexcept; 1743 void store_little_u64( unsigned char * p, boost::uint64_t v ) noexcept; 1744 void store_big_s64( unsigned char * p, boost::int64_t v ) noexcept; 1745 void store_big_u64( unsigned char * p, boost::uint64_t v ) noexcept; 1746 1747} // namespace endian 1748} // namespace boost</code></pre> 1749</div> 1750</div> 1751<div class="paragraph"> 1752<p>The values of <code>order::little</code> and <code>order::big</code> shall not be equal to one 1753another.</p> 1754</div> 1755<div class="paragraph"> 1756<p>The value of <code>order::native</code> shall be:</p> 1757</div> 1758<div class="ulist"> 1759<ul> 1760<li> 1761<p>equal to <code>order::big</code> if the execution environment is big endian, otherwise</p> 1762</li> 1763<li> 1764<p>equal to <code>order::little</code> if the execution environment is little endian, 1765otherwise</p> 1766</li> 1767<li> 1768<p>unequal to both <code>order::little</code> and <code>order::big</code>.</p> 1769</li> 1770</ul> 1771</div> 1772</div> 1773<div class="sect3"> 1774<h4 id="conversion_requirements">Requirements</h4> 1775<div class="sect4"> 1776<h5 id="conversion_template_argument_requirements">Template argument requirements</h5> 1777<div class="paragraph"> 1778<p>The template definitions in the <code>boost/endian/conversion.hpp</code> header refer to 1779various named requirements whose details are set out in the tables in this 1780subsection. In these tables, <code>T</code> is an object or reference type to be supplied 1781by a C++ program instantiating a template; <code>x</code> is a value of type (possibly 1782<code>const</code>) <code>T</code>; <code>mlx</code> is a modifiable lvalue of type <code>T</code>.</p> 1783</div> 1784<div class="sect5"> 1785<h6 id="conversion_endianreversible">EndianReversible requirements (in addition to <code>CopyConstructible</code>)</h6> 1786<table class="tableblock frame-all grid-all stretch"> 1787<colgroup> 1788<col style="width: 33.3333%;"> 1789<col style="width: 33.3333%;"> 1790<col style="width: 33.3334%;"> 1791</colgroup> 1792<thead> 1793<tr> 1794<th class="tableblock halign-left valign-top">Expression</th> 1795<th class="tableblock halign-left valign-top">Return</th> 1796<th class="tableblock halign-left valign-top">Requirements</th> 1797</tr> 1798</thead> 1799<tbody> 1800<tr> 1801<td class="tableblock halign-left valign-top"><p class="tableblock"><code>endian_reverse(x)</code></p></td> 1802<td class="tableblock halign-left valign-top"><p class="tableblock"><code>T</code></p></td> 1803<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> 1804<p><code>T</code> is an endian type or a class type.</p> 1805</div> 1806<div class="paragraph"> 1807<p>If <code>T</code> is an endian type, returns the value of <code>x</code> with the order of bytes 1808reversed.</p> 1809</div> 1810<div class="paragraph"> 1811<p>If <code>T</code> is a class type, the function:</p> 1812</div> 1813<div class="ulist"> 1814<ul> 1815<li> 1816<p>Is expected to be implemented by the user, as a non-member function in the same 1817namespace as <code>T</code> that can be found by argument dependent lookup (ADL);</p> 1818</li> 1819<li> 1820<p>Should return the value of <code>x</code> with the order of bytes reversed for all data members 1821of types or arrays of types that meet the <code>EndianReversible</code> requirements.</p> 1822</li> 1823</ul> 1824</div></div></td> 1825</tr> 1826</tbody> 1827</table> 1828</div> 1829<div class="sect5"> 1830<h6 id="conversion_endianreversibleinplace">EndianReversibleInplace requirements</h6> 1831<table class="tableblock frame-all grid-all stretch"> 1832<colgroup> 1833<col style="width: 50%;"> 1834<col style="width: 50%;"> 1835</colgroup> 1836<thead> 1837<tr> 1838<th class="tableblock halign-left valign-top">Expression</th> 1839<th class="tableblock halign-left valign-top">Requirements</th> 1840</tr> 1841</thead> 1842<tbody> 1843<tr> 1844<td class="tableblock halign-left valign-top"><p class="tableblock"><code>endian_reverse_inplace(mlx)</code></p></td> 1845<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> 1846<p><code>T</code> is an integral type, an enumeration type, <code>float</code>, <code>double</code>, a class type, 1847or an array type.</p> 1848</div> 1849<div class="paragraph"> 1850<p>If <code>T</code> is not a class type or an array type, reverses the order of bytes in <code>mlx</code>.</p> 1851</div> 1852<div class="paragraph"> 1853<p>If <code>T</code> is a class type, the function:</p> 1854</div> 1855<div class="ulist"> 1856<ul> 1857<li> 1858<p>Is expected to be implemented by the user, as a non-member function in the same 1859namespace as <code>T</code> that can be found by argument dependent lookup (ADL);</p> 1860</li> 1861<li> 1862<p>Should reverse the order of bytes of all data members of <code>mlx</code> that have types or 1863arrays of types that meet the <code>EndianReversible</code> or <code>EndianReversibleInplace</code> 1864requirements.</p> 1865</li> 1866</ul> 1867</div> 1868<div class="paragraph"> 1869<p>If <code>T</code> is an array type, calls <code>endian_reverse_inplace</code> on each element.</p> 1870</div></div></td> 1871</tr> 1872</tbody> 1873</table> 1874<div class="admonitionblock note"> 1875<table> 1876<tr> 1877<td class="icon"> 1878<div class="title">Note</div> 1879</td> 1880<td class="content"> 1881Because there is a function template for <code>endian_reverse_inplace</code> that 1882calls <code>endian_reverse</code> for class types, only <code>endian_reverse</code> is required for a 1883user-defined type to meet the <code>EndianReversibleInplace</code> requirements. Although 1884user-defined types are not required to supply an <code>endian_reverse_inplace</code> function, 1885doing so may improve efficiency. 1886</td> 1887</tr> 1888</table> 1889</div> 1890</div> 1891</div> 1892<div class="sect4"> 1893<h5 id="conversion_customization_points_for_user_defined_types_udts">Customization points for user-defined types (UDTs)</h5> 1894<div class="paragraph"> 1895<p>This subsection describes requirements on the Endian library’s implementation.</p> 1896</div> 1897<div class="paragraph"> 1898<p>The library’s function templates requiring 1899<code><a href="#conversion_endianreversible">EndianReversible</a></code> are required to perform 1900reversal of endianness if needed by making an unqualified call to 1901<code>endian_reverse()</code>.</p> 1902</div> 1903<div class="paragraph"> 1904<p>The library’s function templates requiring 1905<code><a href="#conversion_endianreversibleinplace">EndianReversibleInplace</a></code> are required to 1906perform reversal of endianness if needed by making an unqualified call to 1907<code>endian_reverse_inplace()</code>.</p> 1908</div> 1909<div class="paragraph"> 1910<p>See <code>example/udt_conversion_example.cpp</code> for an example user-defined type.</p> 1911</div> 1912</div> 1913</div> 1914<div class="sect3"> 1915<h4 id="conversion_byte_reversal_functions">Byte Reversal Functions</h4> 1916<div class="listingblock"> 1917<div class="content"> 1918<pre class="highlight"><code>template <class Endian> 1919Endian endian_reverse(Endian x) noexcept;</code></pre> 1920</div> 1921</div> 1922<div class="ulist none"> 1923<ul class="none"> 1924<li> 1925<p></p> 1926<div class="dlist"> 1927<dl> 1928<dt class="hdlist1">Requires</dt> 1929<dd> 1930<p><code>Endian</code> must be a standard integral type that is not <code>bool</code>, 1931or a scoped enumeration type.</p> 1932</dd> 1933<dt class="hdlist1">Returns</dt> 1934<dd> 1935<p><code>x</code>, with the order of its constituent bytes reversed.</p> 1936</dd> 1937</dl> 1938</div> 1939</li> 1940</ul> 1941</div> 1942<div class="listingblock"> 1943<div class="content"> 1944<pre class="highlight"><code>template <class EndianReversible> 1945EndianReversible big_to_native(EndianReversible x) noexcept;</code></pre> 1946</div> 1947</div> 1948<div class="ulist none"> 1949<ul class="none"> 1950<li> 1951<p></p> 1952<div class="dlist"> 1953<dl> 1954<dt class="hdlist1">Returns</dt> 1955<dd> 1956<p><code>conditional_reverse<order::big, order::native>(x)</code>.</p> 1957</dd> 1958</dl> 1959</div> 1960</li> 1961</ul> 1962</div> 1963<div class="listingblock"> 1964<div class="content"> 1965<pre class="highlight"><code>template <class EndianReversible> 1966EndianReversible native_to_big(EndianReversible x) noexcept;</code></pre> 1967</div> 1968</div> 1969<div class="ulist none"> 1970<ul class="none"> 1971<li> 1972<p></p> 1973<div class="dlist"> 1974<dl> 1975<dt class="hdlist1">Returns</dt> 1976<dd> 1977<p><code>conditional_reverse<order::native, order::big>(x)</code>.</p> 1978</dd> 1979</dl> 1980</div> 1981</li> 1982</ul> 1983</div> 1984<div class="listingblock"> 1985<div class="content"> 1986<pre class="highlight"><code>template <class EndianReversible> 1987EndianReversible little_to_native(EndianReversible x) noexcept;</code></pre> 1988</div> 1989</div> 1990<div class="ulist none"> 1991<ul class="none"> 1992<li> 1993<p></p> 1994<div class="dlist"> 1995<dl> 1996<dt class="hdlist1">Returns</dt> 1997<dd> 1998<p><code>conditional_reverse<order::little, order::native>(x)</code>.</p> 1999</dd> 2000</dl> 2001</div> 2002</li> 2003</ul> 2004</div> 2005<div class="listingblock"> 2006<div class="content"> 2007<pre class="highlight"><code>template <class EndianReversible> 2008EndianReversible native_to_little(EndianReversible x) noexcept;</code></pre> 2009</div> 2010</div> 2011<div class="ulist none"> 2012<ul class="none"> 2013<li> 2014<p></p> 2015<div class="dlist"> 2016<dl> 2017<dt class="hdlist1">Returns</dt> 2018<dd> 2019<p><code>conditional_reverse<order::native, order::little>(x)</code>.</p> 2020</dd> 2021</dl> 2022</div> 2023</li> 2024</ul> 2025</div> 2026<div class="listingblock"> 2027<div class="content"> 2028<pre class="highlight"><code>template <order O1, order O2, class EndianReversible> 2029EndianReversible conditional_reverse(EndianReversible x) noexcept;</code></pre> 2030</div> 2031</div> 2032<div class="ulist none"> 2033<ul class="none"> 2034<li> 2035<p></p> 2036<div class="dlist"> 2037<dl> 2038<dt class="hdlist1">Returns</dt> 2039<dd> 2040<p><code>x</code> if <code>O1 == O2,</code> otherwise <code>endian_reverse(x)</code>.</p> 2041</dd> 2042<dt class="hdlist1">Remarks</dt> 2043<dd> 2044<p>Whether <code>x</code> or <code>endian_reverse(x)</code> is to be returned shall be 2045determined at compile time.</p> 2046</dd> 2047</dl> 2048</div> 2049</li> 2050</ul> 2051</div> 2052<div class="listingblock"> 2053<div class="content"> 2054<pre class="highlight"><code>template <class EndianReversible> 2055EndianReversible conditional_reverse(EndianReversible x, 2056 order order1, order order2) noexcept;</code></pre> 2057</div> 2058</div> 2059<div class="ulist none"> 2060<ul class="none"> 2061<li> 2062<p></p> 2063<div class="dlist"> 2064<dl> 2065<dt class="hdlist1">Returns</dt> 2066<dd> 2067<p><code>order1 == order2? x: endian_reverse(x)</code>.</p> 2068</dd> 2069</dl> 2070</div> 2071</li> 2072</ul> 2073</div> 2074</div> 2075<div class="sect3"> 2076<h4 id="conversion_in_place_byte_reversal_functions">In-place Byte Reversal Functions</h4> 2077<div class="listingblock"> 2078<div class="content"> 2079<pre class="highlight"><code>template <class EndianReversible> 2080void endian_reverse_inplace(EndianReversible& x) noexcept;</code></pre> 2081</div> 2082</div> 2083<div class="ulist none"> 2084<ul class="none"> 2085<li> 2086<p></p> 2087<div class="dlist"> 2088<dl> 2089<dt class="hdlist1">Effects</dt> 2090<dd> 2091<p>When <code>EndianReversible</code> is a class type, 2092<code>x = endian_reverse(x);</code>. When <code>EndianReversible</code> is an integral 2093type, an enumeration type, <code>float</code>, or <code>double</code>, reverses the 2094order of the constituent bytes of <code>x</code>. Otherwise, the program is 2095ill-formed.</p> 2096</dd> 2097</dl> 2098</div> 2099</li> 2100</ul> 2101</div> 2102<div class="listingblock"> 2103<div class="content"> 2104<pre class="highlight"><code>template<class EndianReversibleInplace, std::size_t N> 2105void endian_reverse_inplace(EndianReversibleInplace (&x)[N]) noexcept;</code></pre> 2106</div> 2107</div> 2108<div class="ulist none"> 2109<ul class="none"> 2110<li> 2111<p></p> 2112<div class="dlist"> 2113<dl> 2114<dt class="hdlist1">Effects</dt> 2115<dd> 2116<p>Calls <code>endian_reverse_inplace(x[i])</code> for <code>i</code> from <code>0</code> to <code>N-1</code>.</p> 2117</dd> 2118</dl> 2119</div> 2120</li> 2121</ul> 2122</div> 2123<div class="listingblock"> 2124<div class="content"> 2125<pre class="highlight"><code>template <class EndianReversibleInplace> 2126void big_to_native_inplace(EndianReversibleInplace& x) noexcept;</code></pre> 2127</div> 2128</div> 2129<div class="ulist none"> 2130<ul class="none"> 2131<li> 2132<p></p> 2133<div class="dlist"> 2134<dl> 2135<dt class="hdlist1">Effects</dt> 2136<dd> 2137<p><code>conditional_reverse_inplace<order::big, order::native>(x)</code>.</p> 2138</dd> 2139</dl> 2140</div> 2141</li> 2142</ul> 2143</div> 2144<div class="listingblock"> 2145<div class="content"> 2146<pre class="highlight"><code>template <class EndianReversibleInplace> 2147void native_to_big_inplace(EndianReversibleInplace& x) noexcept;</code></pre> 2148</div> 2149</div> 2150<div class="ulist none"> 2151<ul class="none"> 2152<li> 2153<p></p> 2154<div class="dlist"> 2155<dl> 2156<dt class="hdlist1">Effects</dt> 2157<dd> 2158<p><code>conditional_reverse_inplace<order::native, order::big>(x)</code>.</p> 2159</dd> 2160</dl> 2161</div> 2162</li> 2163</ul> 2164</div> 2165<div class="listingblock"> 2166<div class="content"> 2167<pre class="highlight"><code>template <class EndianReversibleInplace> 2168void little_to_native_inplace(EndianReversibleInplace& x) noexcept;</code></pre> 2169</div> 2170</div> 2171<div class="ulist none"> 2172<ul class="none"> 2173<li> 2174<p></p> 2175<div class="dlist"> 2176<dl> 2177<dt class="hdlist1">Effects</dt> 2178<dd> 2179<p><code>conditional_reverse_inplace<order::little, order::native>(x)</code>.</p> 2180</dd> 2181</dl> 2182</div> 2183</li> 2184</ul> 2185</div> 2186<div class="listingblock"> 2187<div class="content"> 2188<pre class="highlight"><code>template <class EndianReversibleInplace> 2189void native_to_little_inplace(EndianReversibleInplace& x) noexcept;</code></pre> 2190</div> 2191</div> 2192<div class="ulist none"> 2193<ul class="none"> 2194<li> 2195<p></p> 2196<div class="dlist"> 2197<dl> 2198<dt class="hdlist1">Effects</dt> 2199<dd> 2200<p><code>conditional_reverse_inplace<order::native, order::little>(x)</code>.</p> 2201</dd> 2202</dl> 2203</div> 2204</li> 2205</ul> 2206</div> 2207<div class="listingblock"> 2208<div class="content"> 2209<pre class="highlight"><code>template <order O1, order O2, class EndianReversibleInplace> 2210void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept;</code></pre> 2211</div> 2212</div> 2213<div class="ulist none"> 2214<ul class="none"> 2215<li> 2216<p></p> 2217<div class="dlist"> 2218<dl> 2219<dt class="hdlist1">Effects</dt> 2220<dd> 2221<p>None if <code>O1 == O2,</code> otherwise <code>endian_reverse_inplace(x)</code>.</p> 2222</dd> 2223<dt class="hdlist1">Remarks</dt> 2224<dd> 2225<p>Which effect applies shall be determined at compile time.</p> 2226</dd> 2227</dl> 2228</div> 2229</li> 2230</ul> 2231</div> 2232<div class="listingblock"> 2233<div class="content"> 2234<pre class="highlight"><code>template <class EndianReversibleInplace> 2235void conditional_reverse_inplace(EndianReversibleInplace& x, 2236 order order1, order order2) noexcept;</code></pre> 2237</div> 2238</div> 2239<div class="ulist none"> 2240<ul class="none"> 2241<li> 2242<p></p> 2243<div class="dlist"> 2244<dl> 2245<dt class="hdlist1">Effects</dt> 2246<dd> 2247<p>If <code>order1 == order2</code> then <code>endian_reverse_inplace(x)</code>.</p> 2248</dd> 2249</dl> 2250</div> 2251</li> 2252</ul> 2253</div> 2254</div> 2255<div class="sect3"> 2256<h4 id="conversion_generic_load_and_store_functions">Generic Load and Store Functions</h4> 2257<div class="listingblock"> 2258<div class="content"> 2259<pre class="highlight"><code>template<class T, std::size_t N, order Order> 2260T endian_load( unsigned char const * p ) noexcept;</code></pre> 2261</div> 2262</div> 2263<div class="ulist none"> 2264<ul class="none"> 2265<li> 2266<p></p> 2267<div class="dlist"> 2268<dl> 2269<dt class="hdlist1">Requires</dt> 2270<dd> 2271<p><code>sizeof(T)</code> must be 1, 2, 4, or 8. <code>N</code> must be between 1 and 2272<code>sizeof(T)</code>, inclusive. <code>T</code> must be trivially copyable. If <code>N</code> is not 2273equal to <code>sizeof(T)</code>, <code>T</code> must be integral or <code>enum</code>.</p> 2274</dd> 2275<dt class="hdlist1">Effects</dt> 2276<dd> 2277<p>Reads <code>N</code> bytes starting from <code>p</code>, in forward or reverse order 2278depending on whether <code>Order</code> matches the native endianness or not, 2279interprets the resulting bit pattern as a value of type <code>T</code>, and returns it. 2280If <code>sizeof(T)</code> is bigger than <code>N</code>, zero-extends when <code>T</code> is unsigned, 2281sign-extends otherwise.</p> 2282</dd> 2283</dl> 2284</div> 2285</li> 2286</ul> 2287</div> 2288<div class="listingblock"> 2289<div class="content"> 2290<pre class="highlight"><code>template<class T, std::size_t N, order Order> 2291void endian_store( unsigned char * p, T const & v ) noexcept;</code></pre> 2292</div> 2293</div> 2294<div class="ulist none"> 2295<ul class="none"> 2296<li> 2297<p></p> 2298<div class="dlist"> 2299<dl> 2300<dt class="hdlist1">Requires</dt> 2301<dd> 2302<p><code>sizeof(T)</code> must be 1, 2, 4, or 8. <code>N</code> must be between 1 and 2303<code>sizeof(T)</code>, inclusive. <code>T</code> must be trivially copyable. If <code>N</code> is not 2304equal to <code>sizeof(T)</code>, <code>T</code> must be integral or <code>enum</code>.</p> 2305</dd> 2306<dt class="hdlist1">Effects</dt> 2307<dd> 2308<p>Writes to <code>p</code> the <code>N</code> least significant bytes from the object 2309representation of <code>v</code>, in forward or reverse order depending on whether 2310<code>Order</code> matches the native endianness or not.</p> 2311</dd> 2312</dl> 2313</div> 2314</li> 2315</ul> 2316</div> 2317</div> 2318<div class="sect3"> 2319<h4 id="conversion_convenience_load_functions">Convenience Load Functions</h4> 2320<div class="listingblock"> 2321<div class="content"> 2322<pre class="highlight"><code>inline boost::intM_t load_little_sN( unsigned char const * p ) noexcept;</code></pre> 2323</div> 2324</div> 2325<div class="ulist none"> 2326<ul class="none"> 2327<li> 2328<p></p> 2329<div class="paragraph"> 2330<p>Reads an N-bit signed little-endian integer from <code>p</code>.</p> 2331</div> 2332<div class="dlist"> 2333<dl> 2334<dt class="hdlist1">Returns</dt> 2335<dd> 2336<p><code>endian_load<boost::intM_t, N/8, order::little>( p )</code>.</p> 2337</dd> 2338</dl> 2339</div> 2340</li> 2341</ul> 2342</div> 2343<div class="listingblock"> 2344<div class="content"> 2345<pre class="highlight"><code>inline boost::uintM_t load_little_uN( unsigned char const * p ) noexcept;</code></pre> 2346</div> 2347</div> 2348<div class="ulist none"> 2349<ul class="none"> 2350<li> 2351<p></p> 2352<div class="paragraph"> 2353<p>Reads an N-bit unsigned little-endian integer from <code>p</code>.</p> 2354</div> 2355<div class="dlist"> 2356<dl> 2357<dt class="hdlist1">Returns</dt> 2358<dd> 2359<p><code>endian_load<boost::uintM_t, N/8, order::little>( p )</code>.</p> 2360</dd> 2361</dl> 2362</div> 2363</li> 2364</ul> 2365</div> 2366<div class="listingblock"> 2367<div class="content"> 2368<pre class="highlight"><code>inline boost::intM_t load_big_sN( unsigned char const * p ) noexcept;</code></pre> 2369</div> 2370</div> 2371<div class="ulist none"> 2372<ul class="none"> 2373<li> 2374<p></p> 2375<div class="paragraph"> 2376<p>Reads an N-bit signed big-endian integer from <code>p</code>.</p> 2377</div> 2378<div class="dlist"> 2379<dl> 2380<dt class="hdlist1">Returns</dt> 2381<dd> 2382<p><code>endian_load<boost::intM_t, N/8, order::big>( p )</code>.</p> 2383</dd> 2384</dl> 2385</div> 2386</li> 2387</ul> 2388</div> 2389<div class="listingblock"> 2390<div class="content"> 2391<pre class="highlight"><code>inline boost::uintM_t load_big_uN( unsigned char const * p ) noexcept;</code></pre> 2392</div> 2393</div> 2394<div class="ulist none"> 2395<ul class="none"> 2396<li> 2397<p></p> 2398<div class="paragraph"> 2399<p>Reads an N-bit unsigned big-endian integer from <code>p</code>.</p> 2400</div> 2401<div class="dlist"> 2402<dl> 2403<dt class="hdlist1">Returns</dt> 2404<dd> 2405<p><code>endian_load<boost::uintM_t, N/8, order::big>( p )</code>.</p> 2406</dd> 2407</dl> 2408</div> 2409</li> 2410</ul> 2411</div> 2412</div> 2413<div class="sect3"> 2414<h4 id="conversion_convenience_store_functions">Convenience Store Functions</h4> 2415<div class="listingblock"> 2416<div class="content"> 2417<pre class="highlight"><code>inline void store_little_sN( unsigned char * p, boost::intM_t v ) noexcept;</code></pre> 2418</div> 2419</div> 2420<div class="ulist none"> 2421<ul class="none"> 2422<li> 2423<p></p> 2424<div class="paragraph"> 2425<p>Writes an N-bit signed little-endian integer to <code>p</code>.</p> 2426</div> 2427<div class="dlist"> 2428<dl> 2429<dt class="hdlist1">Effects</dt> 2430<dd> 2431<p><code>endian_store<boost::intM_t, N/8, order::little>( p, v )</code>.</p> 2432</dd> 2433</dl> 2434</div> 2435</li> 2436</ul> 2437</div> 2438<div class="listingblock"> 2439<div class="content"> 2440<pre class="highlight"><code>inline void store_little_uN( unsigned char * p, boost::uintM_t v ) noexcept;</code></pre> 2441</div> 2442</div> 2443<div class="ulist none"> 2444<ul class="none"> 2445<li> 2446<p></p> 2447<div class="paragraph"> 2448<p>Writes an N-bit unsigned little-endian integer to <code>p</code>.</p> 2449</div> 2450<div class="dlist"> 2451<dl> 2452<dt class="hdlist1">Effects</dt> 2453<dd> 2454<p><code>endian_store<boost::uintM_t, N/8, order::little>( p, v )</code>.</p> 2455</dd> 2456</dl> 2457</div> 2458</li> 2459</ul> 2460</div> 2461<div class="listingblock"> 2462<div class="content"> 2463<pre class="highlight"><code>inline void store_big_sN( unsigned char * p, boost::intM_t v ) noexcept;</code></pre> 2464</div> 2465</div> 2466<div class="ulist none"> 2467<ul class="none"> 2468<li> 2469<p></p> 2470<div class="paragraph"> 2471<p>Writes an N-bit signed big-endian integer to <code>p</code>.</p> 2472</div> 2473<div class="dlist"> 2474<dl> 2475<dt class="hdlist1">Effects</dt> 2476<dd> 2477<p><code>endian_store<boost::intM_t, N/8, order::big>( p, v )</code>.</p> 2478</dd> 2479</dl> 2480</div> 2481</li> 2482</ul> 2483</div> 2484<div class="listingblock"> 2485<div class="content"> 2486<pre class="highlight"><code>inline void store_big_uN( unsigned char * p, boost::uintM_t v ) noexcept;</code></pre> 2487</div> 2488</div> 2489<div class="ulist none"> 2490<ul class="none"> 2491<li> 2492<p></p> 2493<div class="paragraph"> 2494<p>Writes an N-bit unsigned big-endian integer to <code>p</code>.</p> 2495</div> 2496<div class="dlist"> 2497<dl> 2498<dt class="hdlist1">Effects</dt> 2499<dd> 2500<p><code>endian_store<boost::uintM_t, N/8, order::big>( p, v )</code>.</p> 2501</dd> 2502</dl> 2503</div> 2504</li> 2505</ul> 2506</div> 2507</div> 2508</div> 2509<div class="sect2"> 2510<h3 id="conversion_faq">FAQ</h3> 2511<div class="paragraph"> 2512<p>See the <a href="#overview_faq">Overview FAQ</a> for a library-wide FAQ.</p> 2513</div> 2514<div class="dlist"> 2515<dl> 2516<dt class="hdlist1">Why are both value returning and modify-in-place functions provided?</dt> 2517<dd> 2518<p>Returning the result by value is the standard C and C++ idiom for functions 2519that compute a value from an argument. Modify-in-place functions allow cleaner 2520code in many real-world endian use cases and are more efficient for user-defined 2521types that have members such as string data that do not need to be reversed. 2522Thus both forms are provided.</p> 2523</dd> 2524<dt class="hdlist1">Why not use the Linux names (htobe16, htole16, be16toh, le16toh, etc.) ?</dt> 2525<dd> 2526<p>Those names are non-standard and vary even between POSIX-like operating 2527systems. A C++ library TS was going to use those names, but found they were 2528sometimes implemented as macros. Since macros do not respect scoping and 2529namespace rules, to use them would be very error prone.</p> 2530</dd> 2531</dl> 2532</div> 2533</div> 2534<div class="sect2"> 2535<h3 id="conversion_acknowledgements">Acknowledgements</h3> 2536<div class="paragraph"> 2537<p>Tomas Puverle was instrumental in identifying and articulating the need to 2538support endian conversion as separate from endian integer types. Phil Endecott 2539suggested the form of the value returning signatures. Vicente Botet and other 2540reviewers suggested supporting user defined types. General reverse template 2541implementation approach using <code>std::reverse</code> suggested by Mathias Gaunard. 2542Portable implementation approach for 16, 32, and 64-bit integers suggested by 2543tymofey, with avoidance of undefined behavior as suggested by Giovanni Piero 2544Deretta, and a further refinement suggested by Pyry Jahkola. Intrinsic builtins 2545implementation approach for 16, 32, and 64-bit integers suggested by several 2546reviewers, and by David Stone, who provided his Boost licensed macro 2547implementation that became the starting point for 2548<code>boost/endian/detail/intrinsic.hpp</code>. Pierre Talbot provided the 2549<code>int8_t endian_reverse()</code> and templated <code>endian_reverse_inplace()</code> 2550implementations.</p> 2551</div> 2552</div> 2553</div> 2554</div> 2555<div class="sect1"> 2556<h2 id="buffers">Endian Buffer Types</h2> 2557<div class="sectionbody"> 2558<div class="sect2"> 2559<h3 id="buffers_introduction">Introduction</h3> 2560<div class="paragraph"> 2561<p>The internal byte order of arithmetic types is traditionally called 2562<strong>endianness</strong>. See the <a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> for a full 2563exploration of <strong>endianness</strong>, including definitions of <strong>big endian</strong> and <strong>little 2564endian</strong>.</p> 2565</div> 2566<div class="paragraph"> 2567<p>Header <code>boost/endian/buffers.hpp</code> provides <code>endian_buffer</code>, a portable endian 2568integer binary buffer class template with control over byte order, value type, 2569size, and alignment independent of the platform’s native endianness. Typedefs 2570provide easy-to-use names for common configurations.</p> 2571</div> 2572<div class="paragraph"> 2573<p>Use cases primarily involve data portability, either via files or network 2574connections, but these byte-holders may also be used to reduce memory use, file 2575size, or network activity since they provide binary numeric sizes not otherwise 2576available.</p> 2577</div> 2578<div class="paragraph"> 2579<p>Class <code>endian_buffer</code> is aimed at users who wish explicit control over when 2580endianness conversions occur. It also serves as the base class for the 2581<a href="#arithmetic">endian_arithmetic</a> class template, which is aimed at users who 2582wish fully automatic endianness conversion and direct support for all normal 2583arithmetic operations.</p> 2584</div> 2585</div> 2586<div class="sect2"> 2587<h3 id="buffers_example">Example</h3> 2588<div class="paragraph"> 2589<p>The <code>example/endian_example.cpp</code> program writes a binary file containing 2590four-byte, big-endian and little-endian integers:</p> 2591</div> 2592<div class="listingblock"> 2593<div class="content"> 2594<pre class="highlight"><code>#include <iostream> 2595#include <cstdio> 2596#include <boost/endian/buffers.hpp> // see Synopsis below 2597#include <boost/static_assert.hpp> 2598 2599using namespace boost::endian; 2600 2601namespace 2602{ 2603 // This is an extract from a very widely used GIS file format. 2604 // Why the designer decided to mix big and little endians in 2605 // the same file is not known. But this is a real-world format 2606 // and users wishing to write low level code manipulating these 2607 // files have to deal with the mixed endianness. 2608 2609 struct header 2610 { 2611 big_int32_buf_t file_code; 2612 big_int32_buf_t file_length; 2613 little_int32_buf_t version; 2614 little_int32_buf_t shape_type; 2615 }; 2616 2617 const char* filename = "test.dat"; 2618} 2619 2620int main(int, char* []) 2621{ 2622 header h; 2623 2624 BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check 2625 2626 h.file_code = 0x01020304; 2627 h.file_length = sizeof(header); 2628 h.version = 1; 2629 h.shape_type = 0x01020304; 2630 2631 // Low-level I/O such as POSIX read/write or <cstdio> 2632 // fread/fwrite is sometimes used for binary file operations 2633 // when ultimate efficiency is important. Such I/O is often 2634 // performed in some C++ wrapper class, but to drive home the 2635 // point that endian integers are often used in fairly 2636 // low-level code that does bulk I/O operations, <cstdio> 2637 // fopen/fwrite is used for I/O in this example. 2638 2639 std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY 2640 2641 if (!fi) 2642 { 2643 std::cout << "could not open " << filename << '\n'; 2644 return 1; 2645 } 2646 2647 if (std::fwrite(&h, sizeof(header), 1, fi) != 1) 2648 { 2649 std::cout << "write failure for " << filename << '\n'; 2650 return 1; 2651 } 2652 2653 std::fclose(fi); 2654 2655 std::cout << "created file " << filename << '\n'; 2656 2657 return 0; 2658}</code></pre> 2659</div> 2660</div> 2661<div class="paragraph"> 2662<p>After compiling and executing <code>example/endian_example.cpp</code>, a hex dump of 2663<code>test.dat</code> shows:</p> 2664</div> 2665<div class="listingblock"> 2666<div class="content"> 2667<pre class="highlight"><code>01020304 00000010 01000000 04030201</code></pre> 2668</div> 2669</div> 2670<div class="paragraph"> 2671<p>Notice that the first two 32-bit integers are big endian while the second two 2672are little endian, even though the machine this was compiled and run on was 2673little endian.</p> 2674</div> 2675</div> 2676<div class="sect2"> 2677<h3 id="buffers_limitations">Limitations</h3> 2678<div class="paragraph"> 2679<p>Requires <code><climits></code>, <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code> is some other value, 2680compilation will result in an <code>#error</code>. This restriction is in place because the 2681design, implementation, testing, and documentation has only considered issues 2682related to 8-bit bytes, and there have been no real-world use cases presented 2683for other sizes.</p> 2684</div> 2685<div class="paragraph"> 2686<p>In C++03, <code>endian_buffer</code> does not meet the requirements for POD types because 2687it has constructors and a private data member. This means that 2688common use cases are relying on unspecified behavior in that the C++ Standard 2689does not guarantee memory layout for non-POD types. This has not been a problem 2690in practice since all known C++ compilers lay out memory as if <code>endian</code> were 2691a POD type. In C++11, it is possible to specify the default constructor as 2692trivial, and private data members and base classes no longer disqualify a type 2693from being a POD type. Thus under C++11, <code>endian_buffer</code> will no longer be 2694relying on unspecified behavior.</p> 2695</div> 2696</div> 2697<div class="sect2"> 2698<h3 id="buffers_feature_set">Feature set</h3> 2699<div class="ulist"> 2700<ul> 2701<li> 2702<p>Big endian| little endian | native endian byte ordering.</p> 2703</li> 2704<li> 2705<p>Signed | unsigned</p> 2706</li> 2707<li> 2708<p>Unaligned | aligned</p> 2709</li> 2710<li> 2711<p>1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)</p> 2712</li> 2713<li> 2714<p>Choice of value type</p> 2715</li> 2716</ul> 2717</div> 2718</div> 2719<div class="sect2"> 2720<h3 id="buffers_enums_and_typedefs">Enums and typedefs</h3> 2721<div class="paragraph"> 2722<p>Two scoped enums are provided:</p> 2723</div> 2724<div class="listingblock"> 2725<div class="content"> 2726<pre class="highlight"><code>enum class order { big, little, native }; 2727 2728enum class align { no, yes };</code></pre> 2729</div> 2730</div> 2731<div class="paragraph"> 2732<p>One class template is provided:</p> 2733</div> 2734<div class="listingblock"> 2735<div class="content"> 2736<pre class="highlight"><code>template <order Order, typename T, std::size_t Nbits, 2737 align Align = align::no> 2738class endian_buffer;</code></pre> 2739</div> 2740</div> 2741<div class="paragraph"> 2742<p>Typedefs, such as <code>big_int32_buf_t</code>, provide convenient naming conventions for 2743common use cases:</p> 2744</div> 2745<table class="tableblock frame-all grid-all stretch"> 2746<colgroup> 2747<col style="width: 20%;"> 2748<col style="width: 20%;"> 2749<col style="width: 20%;"> 2750<col style="width: 20%;"> 2751<col style="width: 20%;"> 2752</colgroup> 2753<thead> 2754<tr> 2755<th class="tableblock halign-left valign-top">Name</th> 2756<th class="tableblock halign-left valign-top">Alignment</th> 2757<th class="tableblock halign-left valign-top">Endianness</th> 2758<th class="tableblock halign-left valign-top">Sign</th> 2759<th class="tableblock halign-left valign-top">Sizes in bits (n)</th> 2760</tr> 2761</thead> 2762<tbody> 2763<tr> 2764<td class="tableblock halign-left valign-top"><p class="tableblock"><code>big_intN_buf_t</code></p></td> 2765<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 2766<td class="tableblock halign-left valign-top"><p class="tableblock">big</p></td> 2767<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 2768<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 2769</tr> 2770<tr> 2771<td class="tableblock halign-left valign-top"><p class="tableblock"><code>big_uintN_buf_t</code></p></td> 2772<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 2773<td class="tableblock halign-left valign-top"><p class="tableblock">big</p></td> 2774<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 2775<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 2776</tr> 2777<tr> 2778<td class="tableblock halign-left valign-top"><p class="tableblock"><code>little_intN_buf_t</code></p></td> 2779<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 2780<td class="tableblock halign-left valign-top"><p class="tableblock">little</p></td> 2781<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 2782<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 2783</tr> 2784<tr> 2785<td class="tableblock halign-left valign-top"><p class="tableblock"><code>little_uintN_buf_t</code></p></td> 2786<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 2787<td class="tableblock halign-left valign-top"><p class="tableblock">little</p></td> 2788<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 2789<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 2790</tr> 2791<tr> 2792<td class="tableblock halign-left valign-top"><p class="tableblock"><code>native_intN_buf_t</code></p></td> 2793<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 2794<td class="tableblock halign-left valign-top"><p class="tableblock">native</p></td> 2795<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 2796<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 2797</tr> 2798<tr> 2799<td class="tableblock halign-left valign-top"><p class="tableblock"><code>native_uintN_buf_t</code></p></td> 2800<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 2801<td class="tableblock halign-left valign-top"><p class="tableblock">native</p></td> 2802<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 2803<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 2804</tr> 2805<tr> 2806<td class="tableblock halign-left valign-top"><p class="tableblock"><code>big_intN_buf_at</code></p></td> 2807<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> 2808<td class="tableblock halign-left valign-top"><p class="tableblock">big</p></td> 2809<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 2810<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,32,64</p></td> 2811</tr> 2812<tr> 2813<td class="tableblock halign-left valign-top"><p class="tableblock"><code>big_uintN_buf_at</code></p></td> 2814<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> 2815<td class="tableblock halign-left valign-top"><p class="tableblock">big</p></td> 2816<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 2817<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,32,64</p></td> 2818</tr> 2819<tr> 2820<td class="tableblock halign-left valign-top"><p class="tableblock"><code>little_intN_buf_at</code></p></td> 2821<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> 2822<td class="tableblock halign-left valign-top"><p class="tableblock">little</p></td> 2823<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 2824<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,32,64</p></td> 2825</tr> 2826<tr> 2827<td class="tableblock halign-left valign-top"><p class="tableblock"><code>little_uintN_buf_at</code></p></td> 2828<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> 2829<td class="tableblock halign-left valign-top"><p class="tableblock">little</p></td> 2830<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 2831<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,32,64</p></td> 2832</tr> 2833</tbody> 2834</table> 2835<div class="paragraph"> 2836<p>The unaligned types do not cause compilers to insert padding bytes in classes 2837and structs. This is an important characteristic that can be exploited to 2838minimize wasted space in memory, files, and network transmissions.</p> 2839</div> 2840<div class="admonitionblock caution"> 2841<table> 2842<tr> 2843<td class="icon"> 2844<div class="title">Caution</div> 2845</td> 2846<td class="content"> 2847Code that uses aligned types is possibly non-portable because alignment 2848requirements vary between hardware architectures and because alignment may be 2849affected by compiler switches or pragmas. For example, alignment of an 64-bit 2850integer may be to a 32-bit boundary on a 32-bit machine and to a 64-bit boundary 2851on a 64-bit machine. Furthermore, aligned types are only available on 2852architectures with 8, 16, 32, and 64-bit integer types. 2853</td> 2854</tr> 2855</table> 2856</div> 2857<div class="admonitionblock tip"> 2858<table> 2859<tr> 2860<td class="icon"> 2861<div class="title">Tip</div> 2862</td> 2863<td class="content"> 2864Prefer unaligned buffer types. 2865</td> 2866</tr> 2867</table> 2868</div> 2869<div class="admonitionblock tip"> 2870<table> 2871<tr> 2872<td class="icon"> 2873<div class="title">Tip</div> 2874</td> 2875<td class="content"> 2876Protect yourself against alignment ills. For example: 2877</td> 2878</tr> 2879</table> 2880</div> 2881<div class="dlist none"> 2882<dl> 2883<dt></dt> 2884<dd> 2885<div class="listingblock"> 2886<div class="content"> 2887<pre class="highlight"><code>static_assert(sizeof(containing_struct) == 12, "sizeof(containing_struct) is wrong");</code></pre> 2888</div> 2889</div> 2890</dd> 2891</dl> 2892</div> 2893<div class="paragraph"> 2894<p>Note: One-byte big and little buffer types have identical layout on all 2895platforms, so they never actually reverse endianness. They are provided to 2896enable generic code, and to improve code readability and searchability.</p> 2897</div> 2898</div> 2899<div class="sect2"> 2900<h3 id="buffers_class_template_endian_buffer">Class template <code>endian_buffer</code></h3> 2901<div class="paragraph"> 2902<p>An <code>endian_buffer</code> is a byte-holder for arithmetic types with 2903user-specified endianness, value type, size, and alignment.</p> 2904</div> 2905<div class="sect3"> 2906<h4 id="buffers_synopsis">Synopsis</h4> 2907<div class="listingblock"> 2908<div class="content"> 2909<pre class="highlight"><code>namespace boost 2910{ 2911 namespace endian 2912 { 2913 // C++11 features emulated if not available 2914 2915 enum class align { no, yes }; 2916 2917 template <order Order, class T, std::size_t Nbits, 2918 align Align = align::no> 2919 class endian_buffer 2920 { 2921 public: 2922 2923 typedef T value_type; 2924 2925 endian_buffer() noexcept = default; 2926 explicit endian_buffer(T v) noexcept; 2927 2928 endian_buffer& operator=(T v) noexcept; 2929 value_type value() const noexcept; 2930 unsigned char* data() noexcept; 2931 unsigned char const* data() const noexcept; 2932 2933 private: 2934 2935 unsigned char value_[Nbits / CHAR_BIT]; // exposition only 2936 }; 2937 2938 // stream inserter 2939 template <class charT, class traits, order Order, class T, 2940 std::size_t n_bits, align Align> 2941 std::basic_ostream<charT, traits>& 2942 operator<<(std::basic_ostream<charT, traits>& os, 2943 const endian_buffer<Order, T, n_bits, Align>& x); 2944 2945 // stream extractor 2946 template <class charT, class traits, order Order, class T, 2947 std::size_t n_bits, align A> 2948 std::basic_istream<charT, traits>& 2949 operator>>(std::basic_istream<charT, traits>& is, 2950 endian_buffer<Order, T, n_bits, Align>& x); 2951 2952 // typedefs 2953 2954 // unaligned big endian signed integer buffers 2955 typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t; 2956 typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t; 2957 typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t; 2958 typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t; 2959 typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t; 2960 typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t; 2961 typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t; 2962 typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t; 2963 2964 // unaligned big endian unsigned integer buffers 2965 typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t; 2966 typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t; 2967 typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t; 2968 typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t; 2969 typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t; 2970 typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t; 2971 typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t; 2972 typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t; 2973 2974 // unaligned big endian floating point buffers 2975 typedef endian_buffer<order::big, float, 32> big_float32_buf_t; 2976 typedef endian_buffer<order::big, double, 64> big_float64_buf_t; 2977 2978 // unaligned little endian signed integer buffers 2979 typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t; 2980 typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t; 2981 typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t; 2982 typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t; 2983 typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t; 2984 typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t; 2985 typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t; 2986 typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t; 2987 2988 // unaligned little endian unsigned integer buffers 2989 typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t; 2990 typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t; 2991 typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t; 2992 typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t; 2993 typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t; 2994 typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t; 2995 typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t; 2996 typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t; 2997 2998 // unaligned little endian floating point buffers 2999 typedef endian_buffer<order::little, float, 32> little_float32_buf_t; 3000 typedef endian_buffer<order::little, double, 64> little_float64_buf_t; 3001 3002 // unaligned native endian signed integer types 3003 typedef endian_buffer<order::native, int_least8_t, 8> native_int8_buf_t; 3004 typedef endian_buffer<order::native, int_least16_t, 16> native_int16_buf_t; 3005 typedef endian_buffer<order::native, int_least32_t, 24> native_int24_buf_t; 3006 typedef endian_buffer<order::native, int_least32_t, 32> native_int32_buf_t; 3007 typedef endian_buffer<order::native, int_least64_t, 40> native_int40_buf_t; 3008 typedef endian_buffer<order::native, int_least64_t, 48> native_int48_buf_t; 3009 typedef endian_buffer<order::native, int_least64_t, 56> native_int56_buf_t; 3010 typedef endian_buffer<order::native, int_least64_t, 64> native_int64_buf_t; 3011 3012 // unaligned native endian unsigned integer types 3013 typedef endian_buffer<order::native, uint_least8_t, 8> native_uint8_buf_t; 3014 typedef endian_buffer<order::native, uint_least16_t, 16> native_uint16_buf_t; 3015 typedef endian_buffer<order::native, uint_least32_t, 24> native_uint24_buf_t; 3016 typedef endian_buffer<order::native, uint_least32_t, 32> native_uint32_buf_t; 3017 typedef endian_buffer<order::native, uint_least64_t, 40> native_uint40_buf_t; 3018 typedef endian_buffer<order::native, uint_least64_t, 48> native_uint48_buf_t; 3019 typedef endian_buffer<order::native, uint_least64_t, 56> native_uint56_buf_t; 3020 typedef endian_buffer<order::native, uint_least64_t, 64> native_uint64_buf_t; 3021 3022 // unaligned native endian floating point types 3023 typedef endian_buffer<order::native, float, 32> native_float32_buf_t; 3024 typedef endian_buffer<order::native, double, 64> native_float64_buf_t; 3025 3026 // aligned big endian signed integer buffers 3027 typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at; 3028 typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at; 3029 typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at; 3030 typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at; 3031 3032 // aligned big endian unsigned integer buffers 3033 typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at; 3034 typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at; 3035 typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at; 3036 typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at; 3037 3038 // aligned big endian floating point buffers 3039 typedef endian_buffer<order::big, float, 32, align::yes> big_float32_buf_at; 3040 typedef endian_buffer<order::big, double, 64, align::yes> big_float64_buf_at; 3041 3042 // aligned little endian signed integer buffers 3043 typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at; 3044 typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at; 3045 typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at; 3046 typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at; 3047 3048 // aligned little endian unsigned integer buffers 3049 typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at; 3050 typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at; 3051 typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at; 3052 typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at; 3053 3054 // aligned little endian floating point buffers 3055 typedef endian_buffer<order::little, float, 32, align::yes> little_float32_buf_at; 3056 typedef endian_buffer<order::little, double, 64, align::yes> little_float64_buf_at; 3057 3058 // aligned native endian typedefs are not provided because 3059 // <cstdint> types are superior for this use case 3060 3061 } // namespace endian 3062} // namespace boost</code></pre> 3063</div> 3064</div> 3065<div class="paragraph"> 3066<p>The expository data member <code>value_</code> stores the current value of the 3067<code>endian_buffer</code> object as a sequence of bytes ordered as specified by the 3068<code>Order</code> template parameter. The <code>CHAR_BIT</code> macro is defined in <code><climits></code>. 3069The only supported value of <code>CHAR_BIT</code> is 8.</p> 3070</div> 3071<div class="paragraph"> 3072<p>The valid values of <code>Nbits</code> are as follows:</p> 3073</div> 3074<div class="ulist"> 3075<ul> 3076<li> 3077<p>When <code>sizeof(T)</code> is 1, <code>Nbits</code> shall be 8;</p> 3078</li> 3079<li> 3080<p>When <code>sizeof(T)</code> is 2, <code>Nbits</code> shall be 16;</p> 3081</li> 3082<li> 3083<p>When <code>sizeof(T)</code> is 4, <code>Nbits</code> shall be 24 or 32;</p> 3084</li> 3085<li> 3086<p>When <code>sizeof(T)</code> is 8, <code>Nbits</code> shall be 40, 48, 56, or 64.</p> 3087</li> 3088</ul> 3089</div> 3090<div class="paragraph"> 3091<p>Other values of <code>sizeof(T)</code> are not supported.</p> 3092</div> 3093<div class="paragraph"> 3094<p>When <code>Nbits</code> is equal to <code>sizeof(T)*8</code>, <code>T</code> must be a trivially copyable type 3095(such as <code>float</code>) that is assumed to have the same endianness as <code>uintNbits_t</code>.</p> 3096</div> 3097<div class="paragraph"> 3098<p>When <code>Nbits</code> is less than <code>sizeof(T)*8</code>, <code>T</code> must be either a standard integral 3099type (C++std, [basic.fundamental]) or an <code>enum</code>.</p> 3100</div> 3101</div> 3102<div class="sect3"> 3103<h4 id="buffers_members">Members</h4> 3104<div class="listingblock"> 3105<div class="content"> 3106<pre class="highlight"><code>endian_buffer() noexcept = default;</code></pre> 3107</div> 3108</div> 3109<div class="ulist none"> 3110<ul class="none"> 3111<li> 3112<p></p> 3113<div class="dlist"> 3114<dl> 3115<dt class="hdlist1">Effects</dt> 3116<dd> 3117<p>Constructs an uninitialized object.</p> 3118</dd> 3119</dl> 3120</div> 3121</li> 3122</ul> 3123</div> 3124<div class="listingblock"> 3125<div class="content"> 3126<pre class="highlight"><code>explicit endian_buffer(T v) noexcept;</code></pre> 3127</div> 3128</div> 3129<div class="ulist none"> 3130<ul class="none"> 3131<li> 3132<p></p> 3133<div class="dlist"> 3134<dl> 3135<dt class="hdlist1">Effects</dt> 3136<dd> 3137<p><code>endian_store<T, Nbits/8, Order>( value_, v )</code>.</p> 3138</dd> 3139</dl> 3140</div> 3141</li> 3142</ul> 3143</div> 3144<div class="listingblock"> 3145<div class="content"> 3146<pre class="highlight"><code>endian_buffer& operator=(T v) noexcept;</code></pre> 3147</div> 3148</div> 3149<div class="ulist none"> 3150<ul class="none"> 3151<li> 3152<p></p> 3153<div class="dlist"> 3154<dl> 3155<dt class="hdlist1">Effects</dt> 3156<dd> 3157<p><code>endian_store<T, Nbits/8, Order>( value_, v )</code>.</p> 3158</dd> 3159<dt class="hdlist1">Returns</dt> 3160<dd> 3161<p><code>*this</code>.</p> 3162</dd> 3163</dl> 3164</div> 3165</li> 3166</ul> 3167</div> 3168<div class="listingblock"> 3169<div class="content"> 3170<pre class="highlight"><code>value_type value() const noexcept;</code></pre> 3171</div> 3172</div> 3173<div class="ulist none"> 3174<ul class="none"> 3175<li> 3176<p></p> 3177<div class="dlist"> 3178<dl> 3179<dt class="hdlist1">Returns</dt> 3180<dd> 3181<p><code>endian_load<T, Nbits/8, Order>( value_ )</code>.</p> 3182</dd> 3183</dl> 3184</div> 3185</li> 3186</ul> 3187</div> 3188<div class="listingblock"> 3189<div class="content"> 3190<pre class="highlight"><code>unsigned char* data() noexcept;</code></pre> 3191</div> 3192</div> 3193<div class="listingblock"> 3194<div class="content"> 3195<pre class="highlight"><code>unsigned char const* data() const noexcept;</code></pre> 3196</div> 3197</div> 3198<div class="ulist none"> 3199<ul class="none"> 3200<li> 3201<p></p> 3202<div class="dlist"> 3203<dl> 3204<dt class="hdlist1">Returns</dt> 3205<dd> 3206<p>A pointer to the first byte of <code>value_</code>.</p> 3207</dd> 3208</dl> 3209</div> 3210</li> 3211</ul> 3212</div> 3213</div> 3214<div class="sect3"> 3215<h4 id="buffers_non_member_functions">Non-member functions</h4> 3216<div class="listingblock"> 3217<div class="content"> 3218<pre class="highlight"><code>template <class charT, class traits, order Order, class T, 3219 std::size_t n_bits, align Align> 3220std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, 3221 const endian_buffer<Order, T, n_bits, Align>& x);</code></pre> 3222</div> 3223</div> 3224<div class="ulist none"> 3225<ul class="none"> 3226<li> 3227<p></p> 3228<div class="dlist"> 3229<dl> 3230<dt class="hdlist1">Returns</dt> 3231<dd> 3232<p><code>os << x.value()</code>.</p> 3233</dd> 3234</dl> 3235</div> 3236</li> 3237</ul> 3238</div> 3239<div class="listingblock"> 3240<div class="content"> 3241<pre class="highlight"><code>template <class charT, class traits, order Order, class T, 3242 std::size_t n_bits, align A> 3243std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& is, 3244 endian_buffer<Order, T, n_bits, Align>& x);</code></pre> 3245</div> 3246</div> 3247<div class="ulist none"> 3248<ul class="none"> 3249<li> 3250<p></p> 3251<div class="dlist"> 3252<dl> 3253<dt class="hdlist1">Effects</dt> 3254<dd> 3255<p>As if:</p> 3256<div class="listingblock"> 3257<div class="content"> 3258<pre class="highlight"><code>T i; 3259if (is >> i) 3260 x = i;</code></pre> 3261</div> 3262</div> 3263</dd> 3264<dt class="hdlist1">Returns</dt> 3265<dd> 3266<p><code>is</code>.</p> 3267</dd> 3268</dl> 3269</div> 3270</li> 3271</ul> 3272</div> 3273</div> 3274</div> 3275<div class="sect2"> 3276<h3 id="buffers_faq">FAQ</h3> 3277<div class="paragraph"> 3278<p>See the <a href="#overview_faq">Overview FAQ</a> for a library-wide FAQ.</p> 3279</div> 3280<div class="dlist"> 3281<dl> 3282<dt class="hdlist1">Why not just use Boost.Serialization?</dt> 3283<dd> 3284<p>Serialization involves a conversion for every object involved in I/O. Endian 3285integers require no conversion or copying. They are already in the desired 3286format for binary I/O. Thus they can be read or written in bulk.</p> 3287</dd> 3288<dt class="hdlist1">Are endian types PODs?</dt> 3289<dd> 3290<p>Yes for C++11. No for C++03, although several 3291<a href="#buffers_compilation">macros</a> are available to force PODness in all cases.</p> 3292</dd> 3293<dt class="hdlist1">What are the implications of endian integer types not being PODs with C++03 compilers?</dt> 3294<dd> 3295<p>They can’t be used in unions. Also, compilers aren’t required to align or lay 3296out storage in portable ways, although this potential problem hasn’t prevented 3297use of Boost.Endian with real compilers.</p> 3298</dd> 3299<dt class="hdlist1">What good is native endianness?</dt> 3300<dd> 3301<p>It provides alignment and size guarantees not available from the built-in 3302types. It eases generic programming.</p> 3303</dd> 3304<dt class="hdlist1">Why bother with the aligned endian types?</dt> 3305<dd> 3306<p>Aligned integer operations may be faster (as much as 10 to 20 times faster) if 3307the endianness and alignment of the type matches the endianness and alignment 3308requirements of the machine. The code, however, is likely to be somewhat less 3309portable than with the unaligned types.</p> 3310</dd> 3311</dl> 3312</div> 3313</div> 3314<div class="sect2"> 3315<h3 id="buffers_design_considerations_for_boost_endian_buffers">Design considerations for Boost.Endian buffers</h3> 3316<div class="ulist"> 3317<ul> 3318<li> 3319<p>Must be suitable for I/O - in other words, must be memcpyable.</p> 3320</li> 3321<li> 3322<p>Must provide exactly the size and internal byte ordering specified.</p> 3323</li> 3324<li> 3325<p>Must work correctly when the internal integer representation has more bits 3326that the sum of the bits in the external byte representation. Sign extension 3327must work correctly when the internal integer representation type has more 3328bits than the sum of the bits in the external bytes. For example, using 3329a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for 3330both positive and negative values.</p> 3331</li> 3332<li> 3333<p>Must work correctly (including using the same defined external 3334representation) regardless of whether a compiler treats char as signed or 3335unsigned.</p> 3336</li> 3337<li> 3338<p>Unaligned types must not cause compilers to insert padding bytes.</p> 3339</li> 3340<li> 3341<p>The implementation should supply optimizations with great care. Experience 3342has shown that optimizations of endian integers often become pessimizations 3343when changing machines or compilers. Pessimizations can also happen when 3344changing compiler switches, compiler versions, or CPU models of the same 3345architecture.</p> 3346</li> 3347</ul> 3348</div> 3349</div> 3350<div class="sect2"> 3351<h3 id="buffers_c11">C++11</h3> 3352<div class="paragraph"> 3353<p>The availability of the C++11 3354<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">Defaulted 3355Functions</a> feature is detected automatically, and will be used if present to 3356ensure that objects of <code>class endian_buffer</code> are trivial, and thus 3357PODs.</p> 3358</div> 3359</div> 3360<div class="sect2"> 3361<h3 id="buffers_compilation">Compilation</h3> 3362<div class="paragraph"> 3363<p>Boost.Endian is implemented entirely within headers, with no need to link to 3364any Boost object libraries.</p> 3365</div> 3366<div class="paragraph"> 3367<p>Several macros allow user control over features:</p> 3368</div> 3369<div class="ulist"> 3370<ul> 3371<li> 3372<p><code>BOOST_ENDIAN_NO_CTORS</code> causes <code>class endian_buffer</code> to have no 3373constructors. The intended use is for compiling user code that must be 3374portable between compilers regardless of C++11 3375<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">Defaulted 3376Functions</a> support. Use of constructors will always fail,</p> 3377</li> 3378<li> 3379<p><code>BOOST_ENDIAN_FORCE_PODNESS</code> causes <code>BOOST_ENDIAN_NO_CTORS</code> to be defined if 3380the compiler does not support C++11 3381<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">Defaulted 3382Functions</a>. This is ensures that objects of <code>class endian_buffer</code> are PODs, and 3383so can be used in C++03 unions. In C++11, <code>class endian_buffer</code> objects are 3384PODs, even though they have constructors, so can always be used in unions.</p> 3385</li> 3386</ul> 3387</div> 3388</div> 3389</div> 3390</div> 3391<div class="sect1"> 3392<h2 id="arithmetic">Endian Arithmetic Types</h2> 3393<div class="sectionbody"> 3394<div class="sect2"> 3395<h3 id="arithmetic_introduction">Introduction</h3> 3396<div class="paragraph"> 3397<p>Header <code>boost/endian/arithmetic.hpp</code> provides integer binary types with 3398control over byte order, value type, size, and alignment. Typedefs provide 3399easy-to-use names for common configurations.</p> 3400</div> 3401<div class="paragraph"> 3402<p>These types provide portable byte-holders for integer data, independent of 3403particular computer architectures. Use cases almost always involve I/O, either 3404via files or network connections. Although data portability is the primary 3405motivation, these integer byte-holders may also be used to reduce memory use, 3406file size, or network activity since they provide binary integer sizes not 3407otherwise available.</p> 3408</div> 3409<div class="paragraph"> 3410<p>Such integer byte-holder types are traditionally called <strong>endian</strong> types. See the 3411<a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> for a full exploration of 3412<strong>endianness</strong>, including definitions of <strong>big endian</strong> and <strong>little endian</strong>.</p> 3413</div> 3414<div class="paragraph"> 3415<p>Boost endian integers provide the same full set of C++ assignment, arithmetic, 3416and relational operators as C++ standard integral types, with the standard 3417semantics.</p> 3418</div> 3419<div class="paragraph"> 3420<p>Unary arithmetic operators are <code>+</code>, <code>-</code>, <code>~</code>, <code>!</code>, plus both prefix and postfix 3421<code>--</code> and <code>++</code>. Binary arithmetic operators are <code>+</code>, <code>+=</code>, <code>-</code>, <code>-=</code>, <code>*</code>, 3422<code>*=</code>, <code>/</code>, <code>/=</code>, <code>&</code>, <code>&=</code>, <code>|</code>, <code>|=</code>, <code>^</code>, <code>^=</code>, <code><<</code>, <code><<=</code>, <code>>></code>, and 3423<code>>>=</code>. Binary relational operators are <code>==</code>, <code>!=</code>, <code><</code>, <code><=</code>, <code>></code>, and <code>>=</code>.</p> 3424</div> 3425<div class="paragraph"> 3426<p>Implicit conversion to the underlying value type is provided. An implicit 3427constructor converting from the underlying value type is provided.</p> 3428</div> 3429</div> 3430<div class="sect2"> 3431<h3 id="arithmetic_example">Example</h3> 3432<div class="paragraph"> 3433<p>The <code>endian_example.cpp</code> program writes a binary file containing four-byte, 3434big-endian and little-endian integers:</p> 3435</div> 3436<div class="listingblock"> 3437<div class="content"> 3438<pre class="highlight"><code>#include <iostream> 3439#include <cstdio> 3440#include <boost/endian/arithmetic.hpp> 3441#include <boost/static_assert.hpp> 3442 3443using namespace boost::endian; 3444 3445namespace 3446{ 3447 // This is an extract from a very widely used GIS file format. 3448 // Why the designer decided to mix big and little endians in 3449 // the same file is not known. But this is a real-world format 3450 // and users wishing to write low level code manipulating these 3451 // files have to deal with the mixed endianness. 3452 3453 struct header 3454 { 3455 big_int32_t file_code; 3456 big_int32_t file_length; 3457 little_int32_t version; 3458 little_int32_t shape_type; 3459 }; 3460 3461 const char* filename = "test.dat"; 3462} 3463 3464int main(int, char* []) 3465{ 3466 header h; 3467 3468 BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check 3469 3470 h.file_code = 0x01020304; 3471 h.file_length = sizeof(header); 3472 h.version = 1; 3473 h.shape_type = 0x01020304; 3474 3475 // Low-level I/O such as POSIX read/write or <cstdio> 3476 // fread/fwrite is sometimes used for binary file operations 3477 // when ultimate efficiency is important. Such I/O is often 3478 // performed in some C++ wrapper class, but to drive home the 3479 // point that endian integers are often used in fairly 3480 // low-level code that does bulk I/O operations, <cstdio> 3481 // fopen/fwrite is used for I/O in this example. 3482 3483 std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY 3484 3485 if (!fi) 3486 { 3487 std::cout << "could not open " << filename << '\n'; 3488 return 1; 3489 } 3490 3491 if (std::fwrite(&h, sizeof(header), 1, fi) != 1) 3492 { 3493 std::cout << "write failure for " << filename << '\n'; 3494 return 1; 3495 } 3496 3497 std::fclose(fi); 3498 3499 std::cout << "created file " << filename << '\n'; 3500 3501 return 0; 3502}</code></pre> 3503</div> 3504</div> 3505<div class="paragraph"> 3506<p>After compiling and executing <code>endian_example.cpp</code>, a hex dump of <code>test.dat</code> 3507shows:</p> 3508</div> 3509<div class="listingblock"> 3510<div class="content"> 3511<pre class="highlight"><code>01020304 00000010 01000000 04030201</code></pre> 3512</div> 3513</div> 3514<div class="paragraph"> 3515<p>Notice that the first two 32-bit integers are big endian while the second two 3516are little endian, even though the machine this was compiled and run on was 3517little endian.</p> 3518</div> 3519</div> 3520<div class="sect2"> 3521<h3 id="arithmetic_limitations">Limitations</h3> 3522<div class="paragraph"> 3523<p>Requires <code><climits></code>, <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code> is some other value, 3524compilation will result in an <code>#error</code>. This restriction is in place because the 3525design, implementation, testing, and documentation has only considered issues 3526related to 8-bit bytes, and there have been no real-world use cases presented 3527for other sizes.</p> 3528</div> 3529<div class="paragraph"> 3530<p>In C++03, <code>endian_arithmetic</code> does not meet the requirements for POD types 3531because it has constructors, private data members, and a base class. This means 3532that common use cases are relying on unspecified behavior in that the C++ 3533Standard does not guarantee memory layout for non-POD types. This has not been a 3534problem in practice since all known C++ compilers lay out memory as if 3535<code>endian</code> were a POD type. In C++11, it is possible to specify the default 3536constructor as trivial, and private data members and base classes no longer 3537disqualify a type from being a POD type. Thus under C++11, <code>endian_arithmetic</code> 3538will no longer be relying on unspecified behavior.</p> 3539</div> 3540</div> 3541<div class="sect2"> 3542<h3 id="arithmetic_feature_set">Feature set</h3> 3543<div class="ulist"> 3544<ul> 3545<li> 3546<p>Big endian| little endian | native endian byte ordering.</p> 3547</li> 3548<li> 3549<p>Signed | unsigned</p> 3550</li> 3551<li> 3552<p>Unaligned | aligned</p> 3553</li> 3554<li> 3555<p>1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)</p> 3556</li> 3557<li> 3558<p>Choice of value type</p> 3559</li> 3560</ul> 3561</div> 3562</div> 3563<div class="sect2"> 3564<h3 id="arithmetic_enums_and_typedefs">Enums and typedefs</h3> 3565<div class="paragraph"> 3566<p>Two scoped enums are provided:</p> 3567</div> 3568<div class="listingblock"> 3569<div class="content"> 3570<pre class="highlight"><code>enum class order { big, little, native }; 3571 3572enum class align { no, yes };</code></pre> 3573</div> 3574</div> 3575<div class="paragraph"> 3576<p>One class template is provided:</p> 3577</div> 3578<div class="listingblock"> 3579<div class="content"> 3580<pre class="highlight"><code>template <order Order, typename T, std::size_t n_bits, 3581 align Align = align::no> 3582class endian_arithmetic;</code></pre> 3583</div> 3584</div> 3585<div class="paragraph"> 3586<p>Typedefs, such as <code>big_int32_t</code>, provide convenient naming conventions for 3587common use cases:</p> 3588</div> 3589<table class="tableblock frame-all grid-all stretch"> 3590<colgroup> 3591<col style="width: 20%;"> 3592<col style="width: 20%;"> 3593<col style="width: 20%;"> 3594<col style="width: 20%;"> 3595<col style="width: 20%;"> 3596</colgroup> 3597<thead> 3598<tr> 3599<th class="tableblock halign-left valign-top">Name</th> 3600<th class="tableblock halign-left valign-top">Alignment</th> 3601<th class="tableblock halign-left valign-top">Endianness</th> 3602<th class="tableblock halign-left valign-top">Sign</th> 3603<th class="tableblock halign-left valign-top">Sizes in bits (n)</th> 3604</tr> 3605</thead> 3606<tbody> 3607<tr> 3608<td class="tableblock halign-left valign-top"><p class="tableblock"><code>big_intN_t</code></p></td> 3609<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 3610<td class="tableblock halign-left valign-top"><p class="tableblock">big</p></td> 3611<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 3612<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 3613</tr> 3614<tr> 3615<td class="tableblock halign-left valign-top"><p class="tableblock"><code>big_uintN_t</code></p></td> 3616<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 3617<td class="tableblock halign-left valign-top"><p class="tableblock">big</p></td> 3618<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 3619<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 3620</tr> 3621<tr> 3622<td class="tableblock halign-left valign-top"><p class="tableblock"><code>little_intN_t</code></p></td> 3623<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 3624<td class="tableblock halign-left valign-top"><p class="tableblock">little</p></td> 3625<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 3626<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 3627</tr> 3628<tr> 3629<td class="tableblock halign-left valign-top"><p class="tableblock"><code>little_uintN_t</code></p></td> 3630<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 3631<td class="tableblock halign-left valign-top"><p class="tableblock">little</p></td> 3632<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 3633<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 3634</tr> 3635<tr> 3636<td class="tableblock halign-left valign-top"><p class="tableblock"><code>native_intN_t</code></p></td> 3637<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 3638<td class="tableblock halign-left valign-top"><p class="tableblock">native</p></td> 3639<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 3640<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 3641</tr> 3642<tr> 3643<td class="tableblock halign-left valign-top"><p class="tableblock"><code>native_uintN_t</code></p></td> 3644<td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> 3645<td class="tableblock halign-left valign-top"><p class="tableblock">native</p></td> 3646<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 3647<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,24,32,40,48,56,64</p></td> 3648</tr> 3649<tr> 3650<td class="tableblock halign-left valign-top"><p class="tableblock"><code>big_intN_at</code></p></td> 3651<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> 3652<td class="tableblock halign-left valign-top"><p class="tableblock">big</p></td> 3653<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 3654<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,32,64</p></td> 3655</tr> 3656<tr> 3657<td class="tableblock halign-left valign-top"><p class="tableblock"><code>big_uintN_at</code></p></td> 3658<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> 3659<td class="tableblock halign-left valign-top"><p class="tableblock">big</p></td> 3660<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 3661<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,32,64</p></td> 3662</tr> 3663<tr> 3664<td class="tableblock halign-left valign-top"><p class="tableblock"><code>little_intN_at</code></p></td> 3665<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> 3666<td class="tableblock halign-left valign-top"><p class="tableblock">little</p></td> 3667<td class="tableblock halign-left valign-top"><p class="tableblock">signed</p></td> 3668<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,32,64</p></td> 3669</tr> 3670<tr> 3671<td class="tableblock halign-left valign-top"><p class="tableblock"><code>little_uintN_at</code></p></td> 3672<td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> 3673<td class="tableblock halign-left valign-top"><p class="tableblock">little</p></td> 3674<td class="tableblock halign-left valign-top"><p class="tableblock">unsigned</p></td> 3675<td class="tableblock halign-left valign-top"><p class="tableblock">8,16,32,64</p></td> 3676</tr> 3677</tbody> 3678</table> 3679<div class="paragraph"> 3680<p>The unaligned types do not cause compilers to insert padding bytes in classes 3681and structs. This is an important characteristic that can be exploited to 3682minimize wasted space in memory, files, and network transmissions.</p> 3683</div> 3684<div class="admonitionblock caution"> 3685<table> 3686<tr> 3687<td class="icon"> 3688<div class="title">Caution</div> 3689</td> 3690<td class="content"> 3691Code that uses aligned types is possibly non-portable because 3692alignment requirements vary between hardware architectures and because 3693alignment may be affected by compiler switches or pragmas. For example, 3694alignment of an 64-bit integer may be to a 32-bit boundary on a 32-bit machine. 3695Furthermore, aligned types are only available on architectures with 8, 16, 32, 3696and 64-bit integer types. 3697</td> 3698</tr> 3699</table> 3700</div> 3701<div class="admonitionblock tip"> 3702<table> 3703<tr> 3704<td class="icon"> 3705<div class="title">Tip</div> 3706</td> 3707<td class="content"> 3708Prefer unaligned arithmetic types. 3709</td> 3710</tr> 3711</table> 3712</div> 3713<div class="admonitionblock tip"> 3714<table> 3715<tr> 3716<td class="icon"> 3717<div class="title">Tip</div> 3718</td> 3719<td class="content"> 3720Protect yourself against alignment ills. For example: 3721</td> 3722</tr> 3723</table> 3724</div> 3725<div class="dlist none"> 3726<dl> 3727<dt></dt> 3728<dd> 3729<div class="listingblock"> 3730<div class="content"> 3731<pre class="highlight"><code>static_assert(sizeof(containing_struct) == 12, "sizeof(containing_struct) is wrong");</code></pre> 3732</div> 3733</div> 3734</dd> 3735</dl> 3736</div> 3737<div class="admonitionblock note"> 3738<table> 3739<tr> 3740<td class="icon"> 3741<div class="title">Note</div> 3742</td> 3743<td class="content"> 3744One-byte arithmetic types have identical layout on all platforms, so they 3745never actually reverse endianness. They are provided to enable generic code, 3746and to improve code readability and searchability. 3747</td> 3748</tr> 3749</table> 3750</div> 3751</div> 3752<div class="sect2"> 3753<h3 id="arithmetic_class_template_endian_arithmetic">Class template <code>endian_arithmetic</code></h3> 3754<div class="paragraph"> 3755<p><code>endian_arithmetic</code> is an integer byte-holder with user-specified endianness, 3756value type, size, and alignment. The usual operations on arithmetic types are 3757supplied.</p> 3758</div> 3759<div class="sect3"> 3760<h4 id="arithmetic_synopsis">Synopsis</h4> 3761<div class="listingblock"> 3762<div class="content"> 3763<pre class="highlight"><code>#include <boost/endian/buffers.hpp> 3764 3765namespace boost 3766{ 3767 namespace endian 3768 { 3769 // C++11 features emulated if not available 3770 3771 enum class align { no, yes }; 3772 3773 template <order Order, class T, std::size_t n_bits, 3774 align Align = align::no> 3775 class endian_arithmetic 3776 : public endian_buffer<Order, T, n_bits, Align> 3777 { 3778 public: 3779 3780 typedef T value_type; 3781 3782 // if BOOST_ENDIAN_FORCE_PODNESS is defined && C++11 PODs are not 3783 // available then these two constructors will not be present 3784 endian_arithmetic() noexcept = default; 3785 endian_arithmetic(T v) noexcept; 3786 3787 endian_arithmetic& operator=(T v) noexcept; 3788 operator value_type() const noexcept; 3789 value_type value() const noexcept; // for exposition; see endian_buffer 3790 unsigned char* data() noexcept; // for exposition; see endian_buffer 3791 unsigned char const* data() const noexcept; // for exposition; see endian_buffer 3792 3793 // arithmetic operations 3794 // note that additional operations are provided by the value_type 3795 value_type operator+() const noexcept; 3796 endian_arithmetic& operator+=(value_type y) noexcept; 3797 endian_arithmetic& operator-=(value_type y) noexcept; 3798 endian_arithmetic& operator*=(value_type y) noexcept; 3799 endian_arithmetic& operator/=(value_type y) noexcept; 3800 endian_arithmetic& operator%=(value_type y) noexcept; 3801 endian_arithmetic& operator&=(value_type y) noexcept; 3802 endian_arithmetic& operator|=(value_type y) noexcept; 3803 endian_arithmetic& operator^=(value_type y) noexcept; 3804 endian_arithmetic& operator<<=(value_type y) noexcept; 3805 endian_arithmetic& operator>>=(value_type y) noexcept; 3806 endian_arithmetic& operator++() noexcept; 3807 endian_arithmetic& operator--() noexcept; 3808 endian_arithmetic operator++(int) noexcept; 3809 endian_arithmetic operator--(int) noexcept; 3810 3811 // Stream inserter 3812 template <class charT, class traits> 3813 friend std::basic_ostream<charT, traits>& 3814 operator<<(std::basic_ostream<charT, traits>& os, const endian_arithmetic& x); 3815 3816 // Stream extractor 3817 template <class charT, class traits> 3818 friend std::basic_istream<charT, traits>& 3819 operator>>(std::basic_istream<charT, traits>& is, endian_arithmetic& x); 3820 }; 3821 3822 // typedefs 3823 3824 // unaligned big endian signed integer types 3825 typedef endian_arithmetic<order::big, int_least8_t, 8> big_int8_t; 3826 typedef endian_arithmetic<order::big, int_least16_t, 16> big_int16_t; 3827 typedef endian_arithmetic<order::big, int_least32_t, 24> big_int24_t; 3828 typedef endian_arithmetic<order::big, int_least32_t, 32> big_int32_t; 3829 typedef endian_arithmetic<order::big, int_least64_t, 40> big_int40_t; 3830 typedef endian_arithmetic<order::big, int_least64_t, 48> big_int48_t; 3831 typedef endian_arithmetic<order::big, int_least64_t, 56> big_int56_t; 3832 typedef endian_arithmetic<order::big, int_least64_t, 64> big_int64_t; 3833 3834 // unaligned big endian unsigned integer types 3835 typedef endian_arithmetic<order::big, uint_least8_t, 8> big_uint8_t; 3836 typedef endian_arithmetic<order::big, uint_least16_t, 16> big_uint16_t; 3837 typedef endian_arithmetic<order::big, uint_least32_t, 24> big_uint24_t; 3838 typedef endian_arithmetic<order::big, uint_least32_t, 32> big_uint32_t; 3839 typedef endian_arithmetic<order::big, uint_least64_t, 40> big_uint40_t; 3840 typedef endian_arithmetic<order::big, uint_least64_t, 48> big_uint48_t; 3841 typedef endian_arithmetic<order::big, uint_least64_t, 56> big_uint56_t; 3842 typedef endian_arithmetic<order::big, uint_least64_t, 64> big_uint64_t; 3843 3844 // unaligned big endian floating point types 3845 typedef endian_arithmetic<order::big, float, 32> big_float32_t; 3846 typedef endian_arithmetic<order::big, double, 64> big_float64_t; 3847 3848 // unaligned little endian signed integer types 3849 typedef endian_arithmetic<order::little, int_least8_t, 8> little_int8_t; 3850 typedef endian_arithmetic<order::little, int_least16_t, 16> little_int16_t; 3851 typedef endian_arithmetic<order::little, int_least32_t, 24> little_int24_t; 3852 typedef endian_arithmetic<order::little, int_least32_t, 32> little_int32_t; 3853 typedef endian_arithmetic<order::little, int_least64_t, 40> little_int40_t; 3854 typedef endian_arithmetic<order::little, int_least64_t, 48> little_int48_t; 3855 typedef endian_arithmetic<order::little, int_least64_t, 56> little_int56_t; 3856 typedef endian_arithmetic<order::little, int_least64_t, 64> little_int64_t; 3857 3858 // unaligned little endian unsigned integer types 3859 typedef endian_arithmetic<order::little, uint_least8_t, 8> little_uint8_t; 3860 typedef endian_arithmetic<order::little, uint_least16_t, 16> little_uint16_t; 3861 typedef endian_arithmetic<order::little, uint_least32_t, 24> little_uint24_t; 3862 typedef endian_arithmetic<order::little, uint_least32_t, 32> little_uint32_t; 3863 typedef endian_arithmetic<order::little, uint_least64_t, 40> little_uint40_t; 3864 typedef endian_arithmetic<order::little, uint_least64_t, 48> little_uint48_t; 3865 typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_t; 3866 typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_t; 3867 3868 // unaligned little endian floating point types 3869 typedef endian_arithmetic<order::little, float, 32> little_float32_t; 3870 typedef endian_arithmetic<order::little, double, 64> little_float64_t; 3871 3872 // unaligned native endian signed integer types 3873 typedef endian_arithmetic<order::native, int_least8_t, 8> native_int8_t; 3874 typedef endian_arithmetic<order::native, int_least16_t, 16> native_int16_t; 3875 typedef endian_arithmetic<order::native, int_least32_t, 24> native_int24_t; 3876 typedef endian_arithmetic<order::native, int_least32_t, 32> native_int32_t; 3877 typedef endian_arithmetic<order::native, int_least64_t, 40> native_int40_t; 3878 typedef endian_arithmetic<order::native, int_least64_t, 48> native_int48_t; 3879 typedef endian_arithmetic<order::native, int_least64_t, 56> native_int56_t; 3880 typedef endian_arithmetic<order::native, int_least64_t, 64> native_int64_t; 3881 3882 // unaligned native endian unsigned integer types 3883 typedef endian_arithmetic<order::native, uint_least8_t, 8> native_uint8_t; 3884 typedef endian_arithmetic<order::native, uint_least16_t, 16> native_uint16_t; 3885 typedef endian_arithmetic<order::native, uint_least32_t, 24> native_uint24_t; 3886 typedef endian_arithmetic<order::native, uint_least32_t, 32> native_uint32_t; 3887 typedef endian_arithmetic<order::native, uint_least64_t, 40> native_uint40_t; 3888 typedef endian_arithmetic<order::native, uint_least64_t, 48> native_uint48_t; 3889 typedef endian_arithmetic<order::native, uint_least64_t, 56> native_uint56_t; 3890 typedef endian_arithmetic<order::native, uint_least64_t, 64> native_uint64_t; 3891 3892 // unaligned native endian floating point types 3893 typedef endian_arithmetic<order::native, float, 32> native_float32_t; 3894 typedef endian_arithmetic<order::native, double, 64> native_float64_t; 3895 3896 // aligned big endian signed integer types 3897 typedef endian_arithmetic<order::big, int8_t, 8, align::yes> big_int8_at; 3898 typedef endian_arithmetic<order::big, int16_t, 16, align::yes> big_int16_at; 3899 typedef endian_arithmetic<order::big, int32_t, 32, align::yes> big_int32_at; 3900 typedef endian_arithmetic<order::big, int64_t, 64, align::yes> big_int64_at; 3901 3902 // aligned big endian unsigned integer types 3903 typedef endian_arithmetic<order::big, uint8_t, 8, align::yes> big_uint8_at; 3904 typedef endian_arithmetic<order::big, uint16_t, 16, align::yes> big_uint16_at; 3905 typedef endian_arithmetic<order::big, uint32_t, 32, align::yes> big_uint32_at; 3906 typedef endian_arithmetic<order::big, uint64_t, 64, align::yes> big_uint64_at; 3907 3908 // aligned big endian floating point types 3909 typedef endian_arithmetic<order::big, float, 32, align::yes> big_float32_at; 3910 typedef endian_arithmetic<order::big, double, 64, align::yes> big_float64_at; 3911 3912 // aligned little endian signed integer types 3913 typedef endian_arithmetic<order::little, int8_t, 8, align::yes> little_int8_at; 3914 typedef endian_arithmetic<order::little, int16_t, 16, align::yes> little_int16_at; 3915 typedef endian_arithmetic<order::little, int32_t, 32, align::yes> little_int32_at; 3916 typedef endian_arithmetic<order::little, int64_t, 64, align::yes> little_int64_at; 3917 3918 // aligned little endian unsigned integer types 3919 typedef endian_arithmetic<order::little, uint8_t, 8, align::yes> little_uint8_at; 3920 typedef endian_arithmetic<order::little, uint16_t, 16, align::yes> little_uint16_at; 3921 typedef endian_arithmetic<order::little, uint32_t, 32, align::yes> little_uint32_at; 3922 typedef endian_arithmetic<order::little, uint64_t, 64, align::yes> little_uint64_at; 3923 3924 // aligned little endian floating point types 3925 typedef endian_arithmetic<order::little, float, 32, align::yes> little_float32_at; 3926 typedef endian_arithmetic<order::little, double, 64, align::yes> little_float64_at; 3927 3928 // aligned native endian typedefs are not provided because 3929 // <cstdint> types are superior for that use case 3930 3931 } // namespace endian 3932} // namespace boost</code></pre> 3933</div> 3934</div> 3935<div class="paragraph"> 3936<p>The only supported value of <code>CHAR_BIT</code> is 8.</p> 3937</div> 3938<div class="paragraph"> 3939<p>The valid values of <code>Nbits</code> are as follows:</p> 3940</div> 3941<div class="ulist"> 3942<ul> 3943<li> 3944<p>When <code>sizeof(T)</code> is 1, <code>Nbits</code> shall be 8;</p> 3945</li> 3946<li> 3947<p>When <code>sizeof(T)</code> is 2, <code>Nbits</code> shall be 16;</p> 3948</li> 3949<li> 3950<p>When <code>sizeof(T)</code> is 4, <code>Nbits</code> shall be 24 or 32;</p> 3951</li> 3952<li> 3953<p>When <code>sizeof(T)</code> is 8, <code>Nbits</code> shall be 40, 48, 56, or 64.</p> 3954</li> 3955</ul> 3956</div> 3957<div class="paragraph"> 3958<p>Other values of <code>sizeof(T)</code> are not supported.</p> 3959</div> 3960<div class="paragraph"> 3961<p>When <code>Nbits</code> is equal to <code>sizeof(T)*8</code>, <code>T</code> must be a standard arithmetic type.</p> 3962</div> 3963<div class="paragraph"> 3964<p>When <code>Nbits</code> is less than <code>sizeof(T)*8</code>, <code>T</code> must be a standard integral type 3965(C++std, [basic.fundamental]) that is not <code>bool</code>.</p> 3966</div> 3967</div> 3968<div class="sect3"> 3969<h4 id="arithmetic_members">Members</h4> 3970<div class="listingblock"> 3971<div class="content"> 3972<pre class="highlight"><code>endian_arithmetic() noexcept = default; // C++03: endian(){}</code></pre> 3973</div> 3974</div> 3975<div class="ulist none"> 3976<ul class="none"> 3977<li> 3978<p></p> 3979<div class="dlist"> 3980<dl> 3981<dt class="hdlist1">Effects</dt> 3982<dd> 3983<p>Constructs an uninitialized object.</p> 3984</dd> 3985</dl> 3986</div> 3987</li> 3988</ul> 3989</div> 3990<div class="listingblock"> 3991<div class="content"> 3992<pre class="highlight"><code>endian_arithmetic(T v) noexcept;</code></pre> 3993</div> 3994</div> 3995<div class="ulist none"> 3996<ul class="none"> 3997<li> 3998<p></p> 3999<div class="dlist"> 4000<dl> 4001<dt class="hdlist1">Effects</dt> 4002<dd> 4003<p>See <code>endian_buffer::endian_buffer(T)</code>.</p> 4004</dd> 4005</dl> 4006</div> 4007</li> 4008</ul> 4009</div> 4010<div class="listingblock"> 4011<div class="content"> 4012<pre class="highlight"><code>endian_arithmetic& operator=(T v) noexcept;</code></pre> 4013</div> 4014</div> 4015<div class="ulist none"> 4016<ul class="none"> 4017<li> 4018<p></p> 4019<div class="dlist"> 4020<dl> 4021<dt class="hdlist1">Effects</dt> 4022<dd> 4023<p>See <code>endian_buffer::operator=(T)</code>.</p> 4024</dd> 4025<dt class="hdlist1">Returns</dt> 4026<dd> 4027<p><code>*this</code>.</p> 4028</dd> 4029</dl> 4030</div> 4031</li> 4032</ul> 4033</div> 4034<div class="listingblock"> 4035<div class="content"> 4036<pre class="highlight"><code>operator T() const noexcept;</code></pre> 4037</div> 4038</div> 4039<div class="ulist none"> 4040<ul class="none"> 4041<li> 4042<p></p> 4043<div class="dlist"> 4044<dl> 4045<dt class="hdlist1">Returns</dt> 4046<dd> 4047<p><code>value()</code>.</p> 4048</dd> 4049</dl> 4050</div> 4051</li> 4052</ul> 4053</div> 4054</div> 4055<div class="sect3"> 4056<h4 id="arithmetic_other_operators">Other operators</h4> 4057<div class="paragraph"> 4058<p>Other operators on endian objects are forwarded to the equivalent operator on 4059<code>value_type</code>.</p> 4060</div> 4061</div> 4062<div class="sect3"> 4063<h4 id="arithmetic_stream_inserter">Stream inserter</h4> 4064<div class="listingblock"> 4065<div class="content"> 4066<pre class="highlight"><code>template <class charT, class traits> 4067friend std::basic_ostream<charT, traits>& 4068 operator<<(std::basic_ostream<charT, traits>& os, const endian_arithmetic& x);</code></pre> 4069</div> 4070</div> 4071<div class="ulist none"> 4072<ul class="none"> 4073<li> 4074<p></p> 4075<div class="dlist"> 4076<dl> 4077<dt class="hdlist1">Returns</dt> 4078<dd> 4079<p><code>os << +x</code>.</p> 4080</dd> 4081</dl> 4082</div> 4083</li> 4084</ul> 4085</div> 4086</div> 4087<div class="sect3"> 4088<h4 id="arithmetic_stream_extractor">Stream extractor</h4> 4089<div class="listingblock"> 4090<div class="content"> 4091<pre class="highlight"><code>template <class charT, class traits> 4092friend std::basic_istream<charT, traits>& 4093 operator>>(std::basic_istream<charT, traits>& is, endian_arithmetic& x);</code></pre> 4094</div> 4095</div> 4096<div class="ulist none"> 4097<ul class="none"> 4098<li> 4099<p></p> 4100<div class="dlist"> 4101<dl> 4102<dt class="hdlist1">Effects</dt> 4103<dd> 4104<p>As if:</p> 4105<div class="listingblock"> 4106<div class="content"> 4107<pre class="highlight"><code>T i; 4108if (is >> i) 4109 x = i;</code></pre> 4110</div> 4111</div> 4112</dd> 4113<dt class="hdlist1">Returns</dt> 4114<dd> 4115<p><code>is</code>.</p> 4116</dd> 4117</dl> 4118</div> 4119</li> 4120</ul> 4121</div> 4122</div> 4123</div> 4124<div class="sect2"> 4125<h3 id="arithmetic_faq">FAQ</h3> 4126<div class="paragraph"> 4127<p>See the <a href="#overview_faq">Overview FAQ</a> for a library-wide FAQ.</p> 4128</div> 4129<div class="dlist"> 4130<dl> 4131<dt class="hdlist1">Why not just use Boost.Serialization?</dt> 4132<dd> 4133<p>Serialization involves a conversion for every object involved in I/O. Endian 4134integers require no conversion or copying. They are already in the desired 4135format for binary I/O. Thus they can be read or written in bulk.</p> 4136</dd> 4137<dt class="hdlist1">Are endian types PODs?</dt> 4138<dd> 4139<p>Yes for C++11. No for C++03, although several 4140<a href="#arithmetic_compilation">macros</a> are available to force PODness in all cases.</p> 4141</dd> 4142<dt class="hdlist1">What are the implications of endian integer types not being PODs with C++03 compilers?</dt> 4143<dd> 4144<p>They can’t be used in unions. Also, compilers aren’t required to align or lay 4145out storage in portable ways, although this potential problem hasn’t prevented 4146use of Boost.Endian with real compilers.</p> 4147</dd> 4148<dt class="hdlist1">What good is native endianness?</dt> 4149<dd> 4150<p>It provides alignment and size guarantees not available from the built-in 4151types. It eases generic programming.</p> 4152</dd> 4153<dt class="hdlist1">Why bother with the aligned endian types?</dt> 4154<dd> 4155<p>Aligned integer operations may be faster (as much as 10 to 20 times faster) 4156if the endianness and alignment of the type matches the endianness and 4157alignment requirements of the machine. The code, however, will be somewhat less 4158portable than with the unaligned types.</p> 4159</dd> 4160<dt class="hdlist1">Why provide the arithmetic operations?</dt> 4161<dd> 4162<p>Providing a full set of operations reduces program clutter and makes code 4163both easier to write and to read. Consider incrementing a variable in a record. 4164It is very convenient to write:</p> 4165<div class="listingblock"> 4166<div class="content"> 4167<pre class="highlight"><code>++record.foo;</code></pre> 4168</div> 4169</div> 4170<div class="paragraph"> 4171<p>Rather than:</p> 4172</div> 4173<div class="listingblock"> 4174<div class="content"> 4175<pre class="highlight"><code>int temp(record.foo); 4176++temp; 4177record.foo = temp;</code></pre> 4178</div> 4179</div> 4180</dd> 4181</dl> 4182</div> 4183</div> 4184<div class="sect2"> 4185<h3 id="arithmetic_design_considerations_for_boost_endian_types">Design considerations for Boost.Endian types</h3> 4186<div class="ulist"> 4187<ul> 4188<li> 4189<p>Must be suitable for I/O - in other words, must be memcpyable.</p> 4190</li> 4191<li> 4192<p>Must provide exactly the size and internal byte ordering specified.</p> 4193</li> 4194<li> 4195<p>Must work correctly when the internal integer representation has more bits 4196that the sum of the bits in the external byte representation. Sign extension 4197must work correctly when the internal integer representation type has more 4198bits than the sum of the bits in the external bytes. For example, using 4199a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for 4200both positive and negative values.</p> 4201</li> 4202<li> 4203<p>Must work correctly (including using the same defined external 4204representation) regardless of whether a compiler treats char as signed or 4205unsigned.</p> 4206</li> 4207<li> 4208<p>Unaligned types must not cause compilers to insert padding bytes.</p> 4209</li> 4210<li> 4211<p>The implementation should supply optimizations with great care. Experience 4212has shown that optimizations of endian integers often become pessimizations 4213when changing machines or compilers. Pessimizations can also happen when 4214changing compiler switches, compiler versions, or CPU models of the same 4215architecture.</p> 4216</li> 4217</ul> 4218</div> 4219</div> 4220<div class="sect2"> 4221<h3 id="arithmetic_experience">Experience</h3> 4222<div class="paragraph"> 4223<p>Classes with similar functionality have been independently developed by 4224several Boost programmers and used very successful in high-value, high-use 4225applications for many years. These independently developed endian libraries 4226often evolved from C libraries that were also widely used. Endian types have 4227proven widely useful across a wide range of computer architectures and 4228applications.</p> 4229</div> 4230</div> 4231<div class="sect2"> 4232<h3 id="arithmetic_motivating_use_cases">Motivating use cases</h3> 4233<div class="paragraph"> 4234<p>Neil Mayhew writes: "I can also provide a meaningful use-case for this 4235library: reading TrueType font files from disk and processing the contents. The 4236data format has fixed endianness (big) and has unaligned values in various 4237places. Using Boost.Endian simplifies and cleans the code wonderfully."</p> 4238</div> 4239</div> 4240<div class="sect2"> 4241<h3 id="arithmetic_c11">C++11</h3> 4242<div class="paragraph"> 4243<p>The availability of the C++11 4244<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">Defaulted 4245Functions</a> feature is detected automatically, and will be used if present to 4246ensure that objects of <code>class endian_arithmetic</code> are trivial, and thus PODs.</p> 4247</div> 4248</div> 4249<div class="sect2"> 4250<h3 id="arithmetic_compilation">Compilation</h3> 4251<div class="paragraph"> 4252<p>Boost.Endian is implemented entirely within headers, with no need to link to any 4253Boost object libraries.</p> 4254</div> 4255<div class="paragraph"> 4256<p>Several macros allow user control over features:</p> 4257</div> 4258<div class="ulist"> 4259<ul> 4260<li> 4261<p>BOOST_ENDIAN_NO_CTORS causes <code>class endian_arithmetic</code> to have no 4262constructors. The intended use is for compiling user code that must be portable 4263between compilers regardless of C++11 4264<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">Defaulted 4265Functions</a> support. Use of constructors will always fail,</p> 4266</li> 4267<li> 4268<p>BOOST_ENDIAN_FORCE_PODNESS causes BOOST_ENDIAN_NO_CTORS to be defined if 4269the compiler does not support C++11 4270<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">Defaulted 4271Functions</a>. This is ensures that objects of <code>class endian_arithmetic</code> are PODs, 4272and so can be used in C++03 unions. In C++11, <code>class endian_arithmetic</code> 4273objects are PODs, even though they have constructors, so can always be used in 4274unions.</p> 4275</li> 4276</ul> 4277</div> 4278</div> 4279<div class="sect2"> 4280<h3 id="arithmetic_acknowledgements">Acknowledgements</h3> 4281<div class="paragraph"> 4282<p>Original design developed by Darin Adler based on classes developed by Mark 4283Borgerding. Four original class templates combined into a single 4284<code>endian_arithmetic</code> class template by Beman Dawes, who put the library together, 4285provided documentation, added the typedefs, and also added the 4286<code>unrolled_byte_loops</code> sign partial specialization to correctly extend the sign 4287when cover integer size differs from endian representation size.</p> 4288</div> 4289</div> 4290</div> 4291</div> 4292<div class="sect1"> 4293<h2 id="appendix_history">Appendix A: History and Acknowledgments</h2> 4294<div class="sectionbody"> 4295<div class="sect2"> 4296<h3 id="apph_history">History</h3> 4297<div class="sect3"> 4298<h4 id="apph_changes_requested_by_formal_review">Changes requested by formal review</h4> 4299<div class="paragraph"> 4300<p>The library was reworked from top to bottom to accommodate changes requested 4301during the formal review. The issues that were required to be resolved before 4302a mini-review are shown in <strong>bold</strong> below, with the resolution indicated.</p> 4303</div> 4304<div class="dlist"> 4305<dl> 4306<dt class="hdlist1">Common use case scenarios should be developed.</dt> 4307<dd> 4308<p>Done. The documentation have been refactored. A page is now devoted to 4309<a href="#choosing">Choosing the Approach</a> to endianness. See 4310<a href="#choosing_use_cases">Use cases</a> for use case scenarios.</p> 4311</dd> 4312<dt class="hdlist1">Example programs should be developed for the common use case scenarios.</dt> 4313<dd> 4314<p>Done. See <a href="#choosing">Choosing the Approach</a>. Example code has been added 4315throughout.</p> 4316</dd> 4317<dt class="hdlist1">Documentation should illuminate the differences between endian integer/float type and endian conversion approaches to the common use case scenarios, and provide guidelines for choosing the most appropriate approach in user’s applications.</dt> 4318<dd> 4319<p>Done. See <a href="#choosing">Choosing the Approach</a>.</p> 4320</dd> 4321<dt class="hdlist1">Conversion functions supplying results via return should be provided.</dt> 4322<dd> 4323<p>Done. See <a href="#conversion">Conversion Functions</a>.</p> 4324</dd> 4325<dt class="hdlist1">Platform specific performance enhancements such as use of compiler intrinsics or relaxed alignment requirements should be supported.</dt> 4326<dd> 4327<p>Done. Compiler (Clang, GCC, VisualC++, etc.) intrinsics and built-in 4328functions are used in the implementation where appropriate, as requested. See 4329<a href="#overview_intrinsic">Built-in support for Intrinsics</a>. See 4330<a href="#overview_timings">Timings for Example 2</a> to gauge the impact of intrinsics.</p> 4331</dd> 4332<dt class="hdlist1">Endian integer (and floating) types should be implemented via the conversion functions. If that can’t be done efficiently, consideration should be given to expanding the conversion function signatures to resolve the inefficiencies.</dt> 4333<dd> 4334<p>Done. For the endian types, the implementation uses the endian conversion 4335functions, and thus the intrinsics, as requested.</p> 4336</dd> 4337<dt class="hdlist1">Benchmarks that measure performance should be provided. It should be possible to compare platform specific performance enhancements against portable base implementations, and to compare endian integer approaches against endian conversion approaches for the common use case scenarios.</dt> 4338<dd> 4339<p>Done. See <a href="#overview_timings">Timings for Example 2</a>. The <code>endian/test</code> 4340directory also contains several additional benchmark and speed test programs.</p> 4341</dd> 4342<dt class="hdlist1">Float (32-bits) and double (64-bits) should be supported. IEEE 754 is the primary use case.</dt> 4343<dd> 4344<p>Done. The <a href="#buffers">endian buffer types</a>, 4345<a href="#arithmetic">endian arithmetic types</a> and 4346<a href="#conversion">endian conversion functions</a> now support 32-bit <code>(float)</code> 4347and 64-bit <code>(double)</code> floating point, as requested.</p> 4348</dd> 4349</dl> 4350</div> 4351<div class="admonitionblock note"> 4352<table> 4353<tr> 4354<td class="icon"> 4355<div class="title">Note</div> 4356</td> 4357<td class="content"> 4358This answer is outdated. The support for <code>float</code> and <code>double</code> was subsequently found 4359 problematic and has been removed. Recently, support for <code>float</code> and <code>double</code> has 4360 been reinstated for <code>endian_buffer</code> and <code>endian_arithmetic</code>, but not for the 4361 conversion functions. 4362</td> 4363</tr> 4364</table> 4365</div> 4366<div class="dlist"> 4367<dl> 4368<dt class="hdlist1">Support for user defined types (UDTs) is desirable, and should be provided where there would be no conflict with the other concerns.</dt> 4369<dd> 4370<p>Done. See <a href="#conversion_customization">Customization points for user-defined 4371types (UDTs)</a>.</p> 4372</dd> 4373<dt class="hdlist1">There is some concern that endian integer/float arithmetic operations might used inadvertently or inappropriately. The impact of adding an endian_buffer class without arithmetic operations should be investigated.</dt> 4374<dd> 4375<p>Done. The endian types have been decomposed into class template 4376<code><a href="#buffers">endian_buffer</a></code> and class template 4377<code><a href="#arithmetic">endian_arithmetic</a></code>. Class <code>endian_buffer</code> is a public base 4378class for <code>endian_arithmetic</code>, and can also be used by users as a stand-alone 4379class.</p> 4380</dd> 4381<dt class="hdlist1">Stream insertion and extraction of the endian integer/float types should be documented and included in the test coverage.</dt> 4382<dd> 4383<p>Done. See <a href="#buffers_stream_inserter">Stream inserter</a> and 4384<a href="#buffers_stream_extractor">Stream extractor</a>.</p> 4385</dd> 4386<dt class="hdlist1">Binary I/O support that was investigated during development of the Endian library should be put up for mini-review for inclusion in the Boost I/O library.</dt> 4387<dd> 4388<p>Not done yet. Will be handled as a separate min-review soon after the Endian 4389mini-review.</p> 4390</dd> 4391<dt class="hdlist1">Other requested changes.</dt> 4392<dd> 4393<div class="ulist"> 4394<ul> 4395<li> 4396<p>In addition to the named-endianness conversion functions, functions that 4397perform compile-time (via template) and run-time (via function argument) 4398dispatch are now provided.</p> 4399</li> 4400<li> 4401<p><code>order::native</code> is now a synonym for <code>order::big</code> or <code>order::little</code> according 4402to the endianness of the platform. This reduces the number of template 4403specializations required.</p> 4404</li> 4405<li> 4406<p>Headers have been reorganized to make them easier to read, with a synopsis 4407at the front and implementation following.</p> 4408</li> 4409</ul> 4410</div> 4411</dd> 4412</dl> 4413</div> 4414</div> 4415<div class="sect3"> 4416<h4 id="apph_other_changes_since_formal_review">Other changes since formal review</h4> 4417<div class="ulist"> 4418<ul> 4419<li> 4420<p>Header <code>boost/endian/endian.hpp</code> has been renamed to 4421<code>boost/endian/arithmetic.hpp</code>. Headers 4422<code>boost/endian/conversion.hpp</code> and <code>boost/endian/buffers.hpp</code> have been added. 4423Infrastructure file names were changed accordingly.</p> 4424</li> 4425<li> 4426<p>The endian arithmetic type aliases have been renamed, using a naming pattern 4427that is consistent for both integer and floating point, and a consistent set of 4428aliases supplied for the endian buffer types.</p> 4429</li> 4430<li> 4431<p>The unaligned-type alias names still have the <code>_t</code> suffix, but the 4432aligned-type alias names now have an <code>_at</code> suffix.</p> 4433</li> 4434<li> 4435<p><code>endian_reverse()</code> overloads for <code>int8_t</code> and <code>uint8_t</code> have been added for 4436improved generality. (Pierre Talbot)</p> 4437</li> 4438<li> 4439<p>Overloads of <code>endian_reverse_inplace()</code> have been replaced with a single 4440<code>endian_reverse_inplace()</code> template. (Pierre Talbot)</p> 4441</li> 4442<li> 4443<p>For X86 and X64 architectures, which permit unaligned loads and stores, 4444unaligned little endian buffer and arithmetic types use regular loads and 4445stores when the size is exact. This makes unaligned little endian buffer and 4446arithmetic types significantly more efficient on these architectures. (Jeremy 4447Maitin-Shepard)</p> 4448</li> 4449<li> 4450<p>C++11 features affecting interfaces, such as <code>noexcept</code>, are now used. 4451C++03 compilers are still supported.</p> 4452</li> 4453<li> 4454<p>Acknowledgements have been updated.</p> 4455</li> 4456</ul> 4457</div> 4458</div> 4459</div> 4460<div class="sect2"> 4461<h3 id="apph_compatibility_with_interim_releases">Compatibility with interim releases</h3> 4462<div class="paragraph"> 4463<p>Prior to the official Boost release, class template <code>endian_arithmetic</code> has been 4464used for a decade or more with the same functionality but under the name 4465<code>endian</code>. Other names also changed in the official release. If the macro 4466<code>BOOST_ENDIAN_DEPRECATED_NAMES</code> is defined, those old now deprecated names are 4467still supported. However, the class template <code>endian</code> name is only provided for 4468compilers supporting C++11 template aliases. For C++03 compilers, the name 4469will have to be changed to <code>endian_arithmetic</code>.</p> 4470</div> 4471<div class="paragraph"> 4472<p>To support backward header compatibility, deprecated header 4473<code>boost/endian/endian.hpp</code> forwards to <code>boost/endian/arithmetic.hpp</code>. It requires 4474<code>BOOST_ENDIAN_DEPRECATED_NAMES</code> be defined. It should only be used while 4475transitioning to the official Boost release of the library as it will be removed 4476in some future release.</p> 4477</div> 4478</div> 4479<div class="sect2"> 4480<h3 id="apph_future_directions">Future directions</h3> 4481<div class="dlist"> 4482<dl> 4483<dt class="hdlist1">Standardization.</dt> 4484<dd> 4485<p>The plan is to submit Boost.Endian to the C++ standards committee for possible 4486inclusion in a Technical Specification or the C++ standard itself.</p> 4487</dd> 4488<dt class="hdlist1">Specializations for <code>numeric_limits</code>.</dt> 4489<dd> 4490<p>Roger Leigh requested that all <code>boost::endian</code> types provide <code>numeric_limits</code> 4491specializations. 4492See <a href="https://github.com/boostorg/endian/issues/4">GitHub issue 4</a>.</p> 4493</dd> 4494<dt class="hdlist1">Character buffer support.</dt> 4495<dd> 4496<p>Peter Dimov pointed out during the mini-review that getting and setting basic 4497arithmetic types (or <code><cstdint></code> equivalents) from/to an offset into an array of 4498unsigned char is a common need. See 4499<a href="http://lists.boost.org/Archives/boost/2015/01/219574.php">Boost.Endian 4500mini-review posting</a>.</p> 4501</dd> 4502<dt class="hdlist1">Out-of-range detection.</dt> 4503<dd> 4504<p>Peter Dimov pointed suggested during the mini-review that throwing an exception 4505on buffer values being out-of-range might be desirable. See the end of 4506<a href="http://lists.boost.org/Archives/boost/2015/01/219659.php">this posting</a> and 4507subsequent replies.</p> 4508</dd> 4509</dl> 4510</div> 4511</div> 4512<div class="sect2"> 4513<h3 id="apph_acknowledgements">Acknowledgements</h3> 4514<div class="paragraph"> 4515<p>Comments and suggestions were received from Adder, Benaka Moorthi, Christopher 4516Kohlhoff, Cliff Green, Daniel James, Dave Handley, Gennaro Proto, Giovanni Piero 4517Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Howard Hinnant, Jason Newton, 4518Jeff Flinn, Jeremy Maitin-Shepard, John Filo, John Maddock, Kim Barrett, Marsh 4519Ray, Martin Bonner, Mathias Gaunard, Matias Capeletto, Neil Mayhew, Nevin Liber, 4520Olaf van der Spek, Paul Bristow, Peter Dimov, Pierre Talbot, Phil Endecott, 4521Philip Bennefall, Pyry Jahkola, Rene Rivera, Robert Stewart, Roger Leigh, Roland 4522Schwarz, Scott McMurray, Sebastian Redl, Tim Blechmann, Tim Moore, tymofey, 4523Tomas Puverle, Vincente Botet, Yuval Ronen and Vitaly Budovsk. Apologies if 4524anyone has been missed.</p> 4525</div> 4526<div class="paragraph"> 4527<p>The documentation was converted into Asciidoc format by Glen Fernandes.</p> 4528</div> 4529</div> 4530</div> 4531</div> 4532<div class="sect1"> 4533<h2 id="apph_copyright_and_license">Appendix B: Copyright and License</h2> 4534<div class="sectionbody"> 4535<div class="paragraph"> 4536<p>This documentation is</p> 4537</div> 4538<div class="ulist"> 4539<ul> 4540<li> 4541<p>Copyright 2011-2016 Beman Dawes</p> 4542</li> 4543<li> 4544<p>Copyright 2019 Peter Dimov</p> 4545</li> 4546</ul> 4547</div> 4548<div class="paragraph"> 4549<p>and is distributed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</p> 4550</div> 4551</div> 4552</div> 4553</div> 4554<div id="footer"> 4555<div id="footer-text"> 4556Last updated 2020-08-11 14:55:51 UTC 4557</div> 4558</div> 4559<style> 4560 4561*:not(pre)>code { background: none; color: #600000; } 4562:not(pre):not([class^=L])>code { background: none; color: #600000; } 4563table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; } 4564 4565</style> 4566</body> 4567</html>