<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P3104R1: Bit permutations</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in § N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *     -> ins/del.c### for candidate and proposed changes (amendments)
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *   - .correction for "candidate corrections"       (div, aside, details, section)
 *   - .addition   for "candidate additions"         (div, aside, details, section)
 *   - .correction.proposed for "proposed corrections" (div, aside, details, section)
 *   - .addition.proposed   for "proposed additions"   (div, aside, details, section)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Outdated warning for old specs
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/* color variables included separately for reliability */

/******************************************************************************/
/*                                    Body                                    */
/******************************************************************************/

	html {
	}

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;			  /* limit line length to 50em for readability   */
		margin: 0 auto;				/* center text within page                    */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag    */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		color: black;
		color: var(--text);
		background: white top left fixed no-repeat;
		background: var(--bg) top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em; }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border: solid var(--logo-bg);
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		background: var(--logo-bg);
		color: white;
		color: var(--logo-text);
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		background: var(--logo-active-bg);
		border-color: #c00;
		border-color: var(--logo-active-bg);
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small; }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 3;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;

			color: #707070;
			color: var(--tocnav-normal-text);
			background: white;
			background: var(--tocnav-normal-bg);
		}
		#toc-nav > a:hover,
		#toc-nav > a:focus {
			color: black;
			color: var(--tocnav-hover-text);
			background: #f8f8f8;
			background: var(--tocnav-hover-bg);
		}
		#toc-nav > a:active {
			color: #c00;
			color: var(--tocnav-active-text);
			background: white;
			background: var(--tocnav-active-bg);
		}

		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			color: black;
			color: var(--tocsidebar-text);
			background: inherit;
			background-color: #f7f8f9;
			background-color: var(--tocsidebar-bg);
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
			color: var(--tocsidebar-heading-text);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;	/* Inherit the font family. */
		line-height: 1.2;		/* Keep wrapped headings compact */
		hyphens: manual;		/* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		color: var(--heading-text);
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#profile-and-date {
		/* #profile-and-date is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > :not(.head) + hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		color: black;
		color: var(--hr-text);
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	border-left: 0.5em solid #DEF;
	border-left: 0.5em solid var(--algo-border);
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	 padding: .5em;
	 border: thin solid #ddd;
	 border: thin solid var(--algo-border);
	 border-radius: .5em;
	 margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	 margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	 margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	margin-left: -2em;
	}
	dl.switch {
	padding-left: 2em;
	}
	dl.switch > dt {
	text-indent: -1.5em;
	margin-top: 1em;
	}
	dl.switch > dt + dt {
	margin-top: 0;
	}
	dl.switch > dt::before {
	content: '\21AA';
	padding: 0 0.5em 0 0;
	display: inline-block;
	width: 1em;
	text-align: right;
	line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: inherit;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del {
		color: #aa0000;
		color: var(--del-text);
		background: transparent;
		background: var(--del-bg);
		text-decoration: line-through;
	}
	ins {
		color: #006100;
		color: var(--ins-text);
		background: transparent;
		background: var(--ins-bg);
		text-decoration: underline;
	}

	/* for amendments (candidate/proposed changes) */

	.amendment ins, .correction ins, .addition ins,
	ins[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment del, .correction del, .addition del,
	del[class^=c] {
		text-decoration-style: dotted;
	}
	.amendment.proposed ins, .correction.proposed ins, .addition.proposed ins,
	ins[class^=c].proposed {
		text-decoration-style: double;
	}
	.amendment.proposed del, .correction.proposed del, .addition.proposed del,
	del[class^=c].proposed {
		text-decoration-style: double;
	}

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		hyphens: none;
		text-transform: none;
		text-align: left;
		text-align: start;
		font-variant: normal;
		orphans: 3;
		widows: 3;
		page-break-before: avoid;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

	/* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		color: var(--a-normal-text);
		text-decoration: underline #707070;
		text-decoration: underline var(--a-normal-underline);
		text-decoration-skip-ink: none;
	}
	a:visited {
		color: #034575;
		color: var(--a-visited-text);
		text-decoration-color: #bbb;
		text-decoration-color: var(--a-visited-underline);
	}

	/* Indicate interaction with the link */
	a[href]:focus,
	a[href]:hover {
		text-decoration-thickness: 2px;
	}
	a[href]:active {
		color: #c00;
		color: var(--a-active-text);
		text-decoration-color: #c00;
		text-decoration-color: var(--a-active-underline);
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	img, svg {
		/* Intentionally not color-scheme aware. */
		background: white;
	}

	/* For autogen numbers, add
	  .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,	.sidefigure img,	figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
		height: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em;
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em; }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote,
	.amendment, .correction, .addition {
		margin: 1em auto;
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	blockquote > :first-child,
	.note  > p:first-child,
	.issue > p:first-child,
	.amendment > p:first-child,
	.correction > p:first-child,
	.addition > p:first-child {
		margin-top: 0;
	}
	blockquote > :last-child,
	.note  > p:last-child,
	.issue > p:last-child,
	.amendment > p:last-child,
	.correction > p:last-child,
	.addition > p:last-child {
		margin-bottom: 0;
	}


	.issue::before, .issue > .marker,
	.example::before, .example > .marker,
	.note::before, .note > .marker,
	details.note > summary > .marker,
	.amendment::before, .amendment > .marker,
	details.amendment > summary > .marker,
	.addition::before, .addition > .marker,
	addition.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	correction.amendment > summary > .marker
	{
		text-transform: uppercase;
		padding-right: 1em;
	}

	.example::before, .example > .marker {
		display: block;
		padding-right: 0em;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
		border-color: var(--blockquote-border);
		background: transparent;
		background: var(--blockquote-bg);
		color: currentcolor;
		color: var(--blockquote-text);
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #e05252;
		border-color: var(--issue-border);
		background: #fbe9e9;
		background: var(--issue-bg);
		color: black;
		color: var(--issue-text);
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		color: #831616;
		color: var(--issueheading-text);
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	  or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #e0cb52;
		border-color: var(--example-border);
		background: #fcfaee;
		background: var(--example-bg);
		color: black;
		color: var(--example-text);
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		color: #574b0f;
		color: var(--exampleheading-text);
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	  or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52e052;
		border-color: var(--note-border);
		background: #e9fbe9;
		background: var(--note-bg);
		color: black;
		color: var(--note-text);
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary {
		color: hsl(120, 70%, 30%);
		color: var(--noteheading-text);
	}
	/* Add .note::before { content: "Note "; } for autogen label,
	  or use class="marker" to mark up the label in source. */

	details.note[open] > summary {
		border-bottom: 1px silver solid;
		border-bottom: 1px var(--notesummary-underline) solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		border-color: var(--assertion-border);
		background: #EEE;
		background: var(--assertion-bg);
		color: black;
		color: var(--assertion-text);
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-color: var(--advisement-border);
		border-style: none solid;
		background: #fec;
		background: var(--advisement-bg);
		color: black;
		color: var(--advisement-text);
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement::before, .advisement > .marker {
		color: #b35f00;
		color: var(--advisementheading-text);
	}

/** Amendment Box *************************************************************/

	.amendment, .correction, .addition {
		border-color: #330099;
		border-color: var(--amendment-border);
		background: #F5F0FF;
		background: var(--amendment-bg);
		color: black;
		color: var(--amendment-text);
	}
	.amendment.proposed, .correction.proposed, .addition.proposed {
		border-style: solid;
		border-block-width: 0.25em;
	}
	.amendment::before, .amendment > .marker,
	details.amendment > summary::before, details.amendment > summary > .marker,
	.correction::before, .correction > .marker,
	details.correction > summary::before, details.correction > summary > .marker,
	.addition::before, .addition > .marker,
	details.addition > summary::before, details.addition > summary > .marker {
		color: #220066;
		color: var(--amendmentheading-text);
	}
	.amendment.proposed::before, .amendment.proposed > .marker,
	details.amendment.proposed > summary::before, details.amendment.proposed > summary > .marker,
	.correction.proposed::before, .correction.proposed > .marker,
	details.correction.proposed > summary::before, details.correction.proposed > summary > .marker,
	.addition.proposed::before, .addition.proposed > .marker,
	details.addition.proposed > summary::before, details.addition.proposed > summary > .marker {
		font-weight: bold;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: hsla(40,100%,50%,0.95);
		background: var(--warning-bg);
		color: black;
		color: var(--warning-text);
		padding: .75em 1em;
		border: red;
		border: var(--warning-border);
		border-style: solid none;
		box-shadow: 0 2px 8px black;
		text-align: center;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 2em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #def;
		background: var(--def-bg);
		margin: 1.2em 0;
		border-left: 0.5em solid #8ccbf2;
		border-left: 0.5em solid var(--def-border);
		color: black;
		color: var(--def-text);
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
		border-bottom: 1px solid var(--defrow-border);
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def td.footnote {
		padding-top: 0.6em;
	}
	table.def td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		<table class="data"> highlights structural relationships in a table
		when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		Use class="complex data" for particularly complicated tables --
		(This will draw more lines: busier, but clearer.)

		Use class="long" on table cells with paragraph-like contents
		(This will adjust text alignment accordingly.)
		Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-color: var(--datacell-border);
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		border-top: 1px solid var(--datacell-border);
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		border: 1px solid var(--datacell-border);
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
		vertical-align: baseline;
		text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding: 0.1rem 1px 0;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Switch to using border-bottom for underlines */
		text-decoration: none;
		border-bottom: 1px solid;
		/* Reverse color scheme */
		color: black;
		color: var(--toclink-text);
		border-color: #3980b5;
		border-color: var(--toclink-underline);
	}
	.toc a:visited {
		color: black;
		color: var(--toclink-visited-text);
		border-color: #054572;
		border-color: var(--toclink-visited-underline);
	}
	.toc a:focus,
	.toc a:hover {
		background: rgba(75%, 75%, 75%, .25);
		background: var(--a-hover-bg);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
	}
	.toc {
		line-height: 1.1em;
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li			{ font-weight: bold;   }
	.toc > li li		 { font-weight: normal; }
	.toc > li li li	  { font-size:   95%;	}
	.toc > li li li li	{ font-size:   90%;	}
	.toc > li li li li li { font-size:   85%;	}

	/* @supports not (display:grid) { */
		.toc > li			{ margin: 1.5rem 0;	}
		.toc > li li		 { margin: 0.3rem 0;	}
		.toc > li li li	  { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}
		.toc > li li li li .secno { font-size: 85%; }
		.toc > li li li li li .secno { font-size: 100%; }

		.toc li {
			clear: both;
		}

		:not(li) > .toc			 { margin-left:  5rem; }
		.toc .secno				 { margin-left: -5rem; }
		.toc > li li li .secno	  { margin-left: -7rem; }
		.toc > li li li li .secno	{ margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc			 { margin-left:  4rem; }
			.toc .secno				 { margin-left: -4rem; }
			.toc > li li li			 { margin-left:  1rem; }
			.toc > li li li .secno	  { margin-left: -5rem; }
			.toc > li li li li .secno	{ margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
		/* Loosen it on wide screens */
		@media screen and (min-width: 78em) {
			body:not(.toc-inline) :not(li) > .toc			 { margin-left:  4rem; }
			body:not(.toc-inline) .toc .secno				 { margin-left: -4rem; }
			body:not(.toc-inline) .toc > li li li			 { margin-left:  1rem; }
			body:not(.toc-inline) .toc > li li li .secno	  { margin-left: -5rem; }
			body:not(.toc-inline) .toc > li li li li .secno	{ margin-left: -6rem; }
			body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	/* } */

	@supports (display:grid) and (display:contents) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			  comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
			border-bottom: 3px solid transparent;
			margin-bottom: -3px;
		}
		#toc .content:hover,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom-color: #054572;
			border-bottom-color: var(--toclink-underline);
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index	  { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li	{ margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em; }
	ul.index dl	{ margin-top: 0; }
	ul.index dt	{ margin: .2em 0 .2em 20px;}
	ul.index dd	{ margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li a + span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
			color: var(--indexinfo-text);
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		color: black;
		color: var(--indextable-hover-text);
		background: #f7f8f9;
		background: var(--indextable-hover-bg);
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/** Outdated warning **********************************************************/

.outdated-spec {
	color: black;
	color: var(--outdatedspec-text);
	background-color: rgba(0,0,0,0.5);
	background-color: var(--outdatedspec-bg);
}

.outdated-warning {
	position: fixed;
	bottom: 50%;
	left: 0;
	right: 0;
	margin: 0 auto;
	width: 50%;
	background: maroon;
	background: var(--outdated-bg);
	color: white;
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	color: var(--outdated-text);
	border-radius: 1em;
	box-shadow: 0 0 1em red;
	box-shadow: 0 0 1em var(--outdated-shadow);
	padding: 2em;
	text-align: center;
	z-index: 2;
}

.outdated-warning a {
	color: currentcolor;
	background: transparent;
}

.edited-rec-warning {
	background: darkorange;
	background: var(--editedrec-bg);
	box-shadow: 0 0 1em;
}

.outdated-warning button {
	position: absolute;
	top: 0;
	right:0;
	margin: 0;
	border: 0;
	padding: 0.25em 0.5em;
	background: transparent;
	color: white;
	color: var(--outdated-text);
	font:1em sans-serif;
	text-align:center;
}

.outdated-warning span {
	display: block;
}

.outdated-collapsed {
	bottom: 0;
	border-radius: 0;
	width: 100%;
	padding: 0;
}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}

		.outdated-warning {
			position: absolute;
			border-style: solid;
			border-color: red;
		}

		.outdated-warning input {
			display: none;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge {
		/* Magic to create good item positioning:
		  "content column" is 50ems wide at max; less on smaller screens.
		  Extra space (after ToC + content) is empty on the right.

		  1. When item < content column, centers item in column.
		  2. When content < item < available, left-aligns.
		  3. When item > available, fills available + scroll bar.
		*/
		display: grid;
		grid-template-columns: minmax(0, 50em);
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			* http://lea.verou.me/2012/04/background-attachment-local/
			*
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
						top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
						top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
						white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style>
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }

    del { background: #fcc; color: #000; text-decoration: line-through; }
    ins { background: #cfc; color: #000; }
    blockquote .highlight:not(.idl) { background: initial; margin: initial; padding: 0.5em }
    blockquote ul { background: inherit; }
    blockquote code.highlight:not(.idl) { padding: initial; }
    blockquote c-[a] { color: inherit; } /* Keyword.Declaration */
    blockquote c-[b] { color: inherit; } /* Keyword.Type */
    blockquote c-[c] { color: inherit; } /* Comment */
    blockquote c-[d] { color: inherit; } /* Comment.Multiline */
    blockquote c-[e] { color: inherit; } /* Name.Attribute */
    blockquote c-[f] { color: inherit; } /* Name.Tag */
    blockquote c-[g] { color: inherit; } /* Name.Variable */
    blockquote c-[k] { color: inherit; } /* Keyword */
    blockquote c-[l] { color: inherit; } /* Literal */
    blockquote c-[m] { color: inherit; } /* Literal.Number */
    blockquote c-[n] { color: inherit; } /* Name */
    blockquote c-[o] { color: inherit; } /* Operator */
    blockquote c-[p] { color: inherit; } /* Punctuation */
    blockquote c-[s] { color: inherit; } /* Literal.String */
    blockquote c-[t] { color: inherit; } /* Literal.String.Single */
    blockquote c-[u] { color: inherit; } /* Literal.String.Double */
    blockquote c-[cp] { color: inherit; } /* Comment.Preproc */
    blockquote c-[c1] { color: inherit; } /* Comment.Single */
    blockquote c-[cs] { color: inherit; } /* Comment.Special */
    blockquote c-[kc] { color: inherit; } /* Keyword.Constant */
    blockquote c-[kn] { color: inherit; } /* Keyword.Namespace */
    blockquote c-[kp] { color: inherit; } /* Keyword.Pseudo */
    blockquote c-[kr] { color: inherit; } /* Keyword.Reserved */
    blockquote c-[ld] { color: inherit; } /* Literal.Date */
    blockquote c-[nc] { color: inherit; } /* Name.Class */
    blockquote c-[no] { color: inherit; } /* Name.Constant */
    blockquote c-[nd] { color: inherit; } /* Name.Decorator */
    blockquote c-[ni] { color: inherit; } /* Name.Entity */
    blockquote c-[ne] { color: inherit; } /* Name.Exception */
    blockquote c-[nf] { color: inherit; } /* Name.Function */
    blockquote c-[nl] { color: inherit; } /* Name.Label */
    blockquote c-[nn] { color: inherit; } /* Name.Namespace */
    blockquote c-[py] { color: inherit; } /* Name.Property */
    blockquote c-[ow] { color: inherit; } /* Operator.Word */
    blockquote c-[mb] { color: inherit; } /* Literal.Number.Bin */
    blockquote c-[mf] { color: inherit; } /* Literal.Number.Float */
    blockquote c-[mh] { color: inherit; } /* Literal.Number.Hex */
    blockquote c-[mi] { color: inherit; } /* Literal.Number.Integer */
    blockquote c-[mo] { color: inherit; } /* Literal.Number.Oct */
    blockquote c-[sb] { color: inherit; } /* Literal.String.Backtick */
    blockquote c-[sc] { color: inherit; } /* Literal.String.Char */
    blockquote c-[sd] { color: inherit; } /* Literal.String.Doc */
    blockquote c-[se] { color: inherit; } /* Literal.String.Escape */
    blockquote c-[sh] { color: inherit; } /* Literal.String.Heredoc */
    blockquote c-[si] { color: inherit; } /* Literal.String.Interpol */
    blockquote c-[sx] { color: inherit; } /* Literal.String.Other */
    blockquote c-[sr] { color: inherit; } /* Literal.String.Regex */
    blockquote c-[ss] { color: inherit; } /* Literal.String.Symbol */
    blockquote c-[vc] { color: inherit; } /* Name.Variable.Class */
    blockquote c-[vg] { color: inherit; } /* Name.Variable.Global */
    blockquote c-[vi] { color: inherit; } /* Name.Variable.Instance */
    blockquote c-[il] { color: inherit; } /* Literal.Number.Integer.Long */
  </style>
  <meta content="Bikeshed version 4416b18d5, updated Tue Jan 2 15:52:39 2024 -0800" name="generator">
  <link href="https://eisenwave.github.io/cpp-proposals/bit-permutations.html" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="b003fa7fde63a38ebda764df6a1ed09227d0a74a" name="revision">
<style>
@media (prefers-color-scheme: dark) {
  c-[mb], c-[mi], c-[mh] {
    color: #d59393 !important;
  }

  blockquote c-[mb], blockquote c-[mi], blockquote c-[mh] {
    color: var(--text) !important;
  }
}

.indent {
    margin-left: 2em;
}

svg {
    background: none;
    vertical-align: middle;
}

ins {
    background: rgba(136, 255, 93, 0.2);
    color: inherit;
    text-decoration: none;
}
del {
    background: rgba(255, 93, 93, 0.2);
    color: inherit;
    text-decoration: strikethrough;
}
</style>
<style>
th, td, table {
    border: 1px solid var(--text);
}
th, td {
    border-left-width: 0;
    border-right-width: 0;
}

table td:nth-child(10n-9), th {
    font-weight: bold;
    background-color: color-mix(in srgb, var(--text) 5%, transparent);
}
</style>
<style>/* Boilerplate: style-autolinks */
.css.css, .property.property, .descriptor.descriptor {
    color: var(--a-normal-text);
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}

@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}
</style>
<style>/* Boilerplate: style-colors */
/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
:root {
    color-scheme: light dark;

    --text: black;
    --bg: white;

    --unofficial-watermark: url(https://www.w3.org/StyleSheets/TR/2016/logos/UD-watermark);

    --logo-bg: #1a5e9a;
    --logo-active-bg: #c00;
    --logo-text: white;

    --tocnav-normal-text: #707070;
    --tocnav-normal-bg: var(--bg);
    --tocnav-hover-text: var(--tocnav-normal-text);
    --tocnav-hover-bg: #f8f8f8;
    --tocnav-active-text: #c00;
    --tocnav-active-bg: var(--tocnav-normal-bg);

    --tocsidebar-text: var(--text);
    --tocsidebar-bg: #f7f8f9;
    --tocsidebar-shadow: rgba(0,0,0,.1);
    --tocsidebar-heading-text: hsla(203,20%,40%,.7);

    --toclink-text: var(--text);
    --toclink-underline: #3980b5;
    --toclink-visited-text: var(--toclink-text);
    --toclink-visited-underline: #054572;

    --heading-text: #005a9c;

    --hr-text: var(--text);

    --algo-border: #def;

    --del-text: red;
    --del-bg: transparent;
    --ins-text: #080;
    --ins-bg: transparent;

    --a-normal-text: #034575;
    --a-normal-underline: #bbb;
    --a-visited-text: var(--a-normal-text);
    --a-visited-underline: #707070;
    --a-hover-bg: rgba(75%, 75%, 75%, .25);
    --a-active-text: #c00;
    --a-active-underline: #c00;

    --blockquote-border: silver;
    --blockquote-bg: transparent;
    --blockquote-text: currentcolor;

    --issue-border: #e05252;
    --issue-bg: #fbe9e9;
    --issue-text: var(--text);
    --issueheading-text: #831616;

    --example-border: #e0cb52;
    --example-bg: #fcfaee;
    --example-text: var(--text);
    --exampleheading-text: #574b0f;

    --note-border: #52e052;
    --note-bg: #e9fbe9;
    --note-text: var(--text);
    --noteheading-text: hsl(120, 70%, 30%);
    --notesummary-underline: silver;

    --assertion-border: #aaa;
    --assertion-bg: #eee;
    --assertion-text: black;

    --advisement-border: orange;
    --advisement-bg: #fec;
    --advisement-text: var(--text);
    --advisementheading-text: #b35f00;

    --warning-border: red;
    --warning-bg: hsla(40,100%,50%,0.95);
    --warning-text: var(--text);

    --amendment-border: #330099;
    --amendment-bg: #F5F0FF;
    --amendment-text: var(--text);
    --amendmentheading-text: #220066;

    --def-border: #8ccbf2;
    --def-bg: #def;
    --def-text: var(--text);
    --defrow-border: #bbd7e9;

    --datacell-border: silver;

    --indexinfo-text: #707070;

    --indextable-hover-text: black;
    --indextable-hover-bg: #f7f8f9;

    --outdatedspec-bg: rgba(0, 0, 0, .5);
    --outdatedspec-text: black;
    --outdated-bg: maroon;
    --outdated-text: white;
    --outdated-shadow: red;

    --editedrec-bg: darkorange;
}

@media (prefers-color-scheme: dark) {
    :root {
        --text: #ddd;
        --bg: black;

        --unofficial-watermark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cg fill='%23100808' transform='translate(200 200) rotate(-45) translate(-200 -200)' stroke='%23100808' stroke-width='3'%3E%3Ctext x='50%25' y='220' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EUNOFFICIAL%3C/text%3E%3Ctext x='50%25' y='305' style='font: bold 70px sans-serif; text-anchor: middle; letter-spacing: 6px;'%3EDRAFT%3C/text%3E%3C/g%3E%3C/svg%3E");

        --logo-bg: #1a5e9a;
        --logo-active-bg: #c00;
        --logo-text: white;

        --tocnav-normal-text: #999;
        --tocnav-normal-bg: var(--bg);
        --tocnav-hover-text: var(--tocnav-normal-text);
        --tocnav-hover-bg: #080808;
        --tocnav-active-text: #f44;
        --tocnav-active-bg: var(--tocnav-normal-bg);

        --tocsidebar-text: var(--text);
        --tocsidebar-bg: #080808;
        --tocsidebar-shadow: rgba(255,255,255,.1);
        --tocsidebar-heading-text: hsla(203,20%,40%,.7);

        --toclink-text: var(--text);
        --toclink-underline: #6af;
        --toclink-visited-text: var(--toclink-text);
        --toclink-visited-underline: #054572;

        --heading-text: #8af;

        --hr-text: var(--text);

        --algo-border: #456;

        --del-text: #f44;
        --del-bg: transparent;
        --ins-text: #4a4;
        --ins-bg: transparent;

        --a-normal-text: #6af;
        --a-normal-underline: #555;
        --a-visited-text: var(--a-normal-text);
        --a-visited-underline: var(--a-normal-underline);
        --a-hover-bg: rgba(25%, 25%, 25%, .2);
        --a-active-text: #f44;
        --a-active-underline: var(--a-active-text);

        --borderedblock-bg: rgba(255, 255, 255, .05);

        --blockquote-border: silver;
        --blockquote-bg: var(--borderedblock-bg);
        --blockquote-text: currentcolor;

        --issue-border: #e05252;
        --issue-bg: var(--borderedblock-bg);
        --issue-text: var(--text);
        --issueheading-text: hsl(0deg, 70%, 70%);

        --example-border: hsl(50deg, 90%, 60%);
        --example-bg: var(--borderedblock-bg);
        --example-text: var(--text);
        --exampleheading-text: hsl(50deg, 70%, 70%);

        --note-border: hsl(120deg, 100%, 35%);
        --note-bg: var(--borderedblock-bg);
        --note-text: var(--text);
        --noteheading-text: hsl(120, 70%, 70%);
        --notesummary-underline: silver;

        --assertion-border: #444;
        --assertion-bg: var(--borderedblock-bg);
        --assertion-text: var(--text);

        --advisement-border: orange;
        --advisement-bg: #222218;
        --advisement-text: var(--text);
        --advisementheading-text: #f84;

        --warning-border: red;
        --warning-bg: hsla(40,100%,20%,0.95);
        --warning-text: var(--text);

        --amendment-border: #330099;
        --amendment-bg: #080010;
        --amendment-text: var(--text);
        --amendmentheading-text: #cc00ff;

        --def-border: #8ccbf2;
        --def-bg: #080818;
        --def-text: var(--text);
        --defrow-border: #136;

        --datacell-border: silver;

        --indexinfo-text: #aaa;

        --indextable-hover-text: var(--text);
        --indextable-hover-bg: #181818;

        --outdatedspec-bg: rgba(255, 255, 255, .5);
        --outdatedspec-text: black;
        --outdated-bg: maroon;
        --outdated-text: white;
        --outdated-shadow: red;

        --editedrec-bg: darkorange;
    }
    /* In case a transparent-bg image doesn't expect to be on a dark bg,
       which is quite common in practice... */
    img { background: white; }
}
</style>
<style>/* Boilerplate: style-counters */
body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}
</style>
<style>/* Boilerplate: style-issues */
a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</style>
<style>/* Boilerplate: style-md-lists */
/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}
</style>
<style>/* Boilerplate: style-selflinks */
:root {
    --selflink-text: white;
    --selflink-bg: gray;
    --selflink-hover-text: black;
}
.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
.example > a.self-link,
.note > a.self-link,
.issue > a.self-link {
    /* These blocks are overflow:auto, so positioning outside
       doesn't work. */
    left: auto;
    right: 0;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: var(--selflink-bg);
    color: var(--selflink-text);
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: var(--selflink-hover-text);
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }
</style>
<style>/* Boilerplate: style-syntax-highlighting */
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }

.highlight:not(.idl) { background: rgba(0, 0, 0, .03); }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */

@media (prefers-color-scheme: dark) {
    .highlight:not(.idl) { background: rgba(255, 255, 255, .05); }

    c-[a] { color: #d33682 } /* Keyword.Declaration */
    c-[b] { color: #d33682 } /* Keyword.Type */
    c-[c] { color: #2aa198 } /* Comment */
    c-[d] { color: #2aa198 } /* Comment.Multiline */
    c-[e] { color: #268bd2 } /* Name.Attribute */
    c-[f] { color: #b58900 } /* Name.Tag */
    c-[g] { color: #cb4b16 } /* Name.Variable */
    c-[k] { color: #d33682 } /* Keyword */
    c-[l] { color: #657b83 } /* Literal */
    c-[m] { color: #657b83 } /* Literal.Number */
    c-[n] { color: #268bd2 } /* Name */
    c-[o] { color: #657b83 } /* Operator */
    c-[p] { color: #657b83 } /* Punctuation */
    c-[s] { color: #6c71c4 } /* Literal.String */
    c-[t] { color: #6c71c4 } /* Literal.String.Single */
    c-[u] { color: #6c71c4 } /* Literal.String.Double */
    c-[ch] { color: #2aa198 } /* Comment.Hashbang */
    c-[cp] { color: #2aa198 } /* Comment.Preproc */
    c-[cpf] { color: #2aa198 } /* Comment.PreprocFile */
    c-[c1] { color: #2aa198 } /* Comment.Single */
    c-[cs] { color: #2aa198 } /* Comment.Special */
    c-[kc] { color: #d33682 } /* Keyword.Constant */
    c-[kn] { color: #d33682 } /* Keyword.Namespace */
    c-[kp] { color: #d33682 } /* Keyword.Pseudo */
    c-[kr] { color: #d33682 } /* Keyword.Reserved */
    c-[ld] { color: #657b83 } /* Literal.Date */
    c-[nc] { color: #268bd2 } /* Name.Class */
    c-[no] { color: #268bd2 } /* Name.Constant */
    c-[nd] { color: #268bd2 } /* Name.Decorator */
    c-[ni] { color: #268bd2 } /* Name.Entity */
    c-[ne] { color: #268bd2 } /* Name.Exception */
    c-[nf] { color: #268bd2 } /* Name.Function */
    c-[nl] { color: #268bd2 } /* Name.Label */
    c-[nn] { color: #268bd2 } /* Name.Namespace */
    c-[py] { color: #268bd2 } /* Name.Property */
    c-[ow] { color: #657b83 } /* Operator.Word */
    c-[mb] { color: #657b83 } /* Literal.Number.Bin */
    c-[mf] { color: #657b83 } /* Literal.Number.Float */
    c-[mh] { color: #657b83 } /* Literal.Number.Hex */
    c-[mi] { color: #657b83 } /* Literal.Number.Integer */
    c-[mo] { color: #657b83 } /* Literal.Number.Oct */
    c-[sa] { color: #6c71c4 } /* Literal.String.Affix */
    c-[sb] { color: #6c71c4 } /* Literal.String.Backtick */
    c-[sc] { color: #6c71c4 } /* Literal.String.Char */
    c-[dl] { color: #6c71c4 } /* Literal.String.Delimiter */
    c-[sd] { color: #6c71c4 } /* Literal.String.Doc */
    c-[se] { color: #6c71c4 } /* Literal.String.Escape */
    c-[sh] { color: #6c71c4 } /* Literal.String.Heredoc */
    c-[si] { color: #6c71c4 } /* Literal.String.Interpol */
    c-[sx] { color: #6c71c4 } /* Literal.String.Other */
    c-[sr] { color: #6c71c4 } /* Literal.String.Regex */
    c-[ss] { color: #6c71c4 } /* Literal.String.Symbol */
    c-[fm] { color: #268bd2 } /* Name.Function.Magic */
    c-[vc] { color: #cb4b16 } /* Name.Variable.Class */
    c-[vg] { color: #cb4b16 } /* Name.Variable.Global */
    c-[vi] { color: #cb4b16 } /* Name.Variable.Instance */
    c-[vm] { color: #cb4b16 } /* Name.Variable.Magic */
    c-[il] { color: #657b83 } /* Literal.Number.Integer.Long */
}
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P3104R1<br>Bit permutations</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="profile-and-date"><span class="content">Published Proposal, <time class="dt-updated" datetime="2024-03-07">2024-03-07</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://eisenwave.github.io/cpp-proposals/bit-permutations.html">https://eisenwave.github.io/cpp-proposals/bit-permutations.html</a>
     <dt class="editor">Author:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:janschultke@gmail.com">Jan Schultke</a>
     <dt>Audience:
     <dd>SG18, LEWG
     <dt>Project:
     <dd>ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21
     <dt>Source:
     <dd><a href="https://github.com/Eisenwave/cpp-proposals/blob/master/src/bit-permutations.bs">eisenwave/cpp-proposals</a>
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>This proposal adds bit permutation functions to the bit manipulation library.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li>
     <a href="#revisions"><span class="secno">1</span> <span class="content">Revision history</span></a>
     <ol class="toc">
      <li><a href="#changes-since-r0"><span class="secno">1.1</span> <span class="content">Changes since R0</span></a>
     </ol>
    <li><a href="#intro"><span class="secno">2</span> <span class="content">Introduction</span></a>
    <li>
     <a href="#proposed-features"><span class="secno">3</span> <span class="content">Proposed features</span></a>
     <ol class="toc">
      <li><a href="#intro-bit-reverse"><span class="secno">3.1</span> <span class="content"><code class="highlight"><c- n>bit_reverse</c-></code></span></a>
      <li><a href="#intro-bit-repeat"><span class="secno">3.2</span> <span class="content"><code class="highlight"><c- n>bit_repeat</c-></code></span></a>
      <li><a href="#intro-bit-permutation"><span class="secno">3.3</span> <span class="content"><code class="highlight"><c- n>next_bit_permutation</c-></code> and <code class="highlight"><c- n>prev_bit_permutation</c-></code></span></a>
      <li><a href="#intro-bit-compress"><span class="secno">3.4</span> <span class="content"><code class="highlight"><c- n>bit_compress</c-></code></span></a>
      <li><a href="#intro-bit-expand"><span class="secno">3.5</span> <span class="content"><code class="highlight"><c- n>bit_expand</c-></code></span></a>
     </ol>
    <li>
     <a href="#motivation-and-scope"><span class="secno">4</span> <span class="content">Motivation and scope</span></a>
     <ol class="toc">
      <li>
       <a href="#applications"><span class="secno">4.1</span> <span class="content">Applications</span></a>
       <ol class="toc">
        <li><a href="#applications-of-bit-reverse"><span class="secno">4.1.1</span> <span class="content">Applications of <code class="highlight"><c- n>bit_reverse</c-></code></span></a>
        <li><a href="#applications-of-bit-repeat"><span class="secno">4.1.2</span> <span class="content">Applications of <code class="highlight"><c- n>bit_repeat</c-></code></span></a>
        <li><a href="#applications-of-bit-compress-and-bit-expand"><span class="secno">4.1.3</span> <span class="content">Applications of <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></span></a>
        <li><a href="#applications-of-next-bit-permutation"><span class="secno">4.1.4</span> <span class="content">Applications of <code class="highlight"><c- n>next_bit_permutation</c-></code></span></a>
       </ol>
      <li>
       <a href="#use-cases"><span class="secno">4.2</span> <span class="content">Motivating examples</span></a>
       <ol class="toc">
        <li><a href="#implementing-countr-zero"><span class="secno">4.2.1</span> <span class="content">Implementing <code class="highlight"><c- n>countr_zero</c-></code> with <code class="highlight"><c- n>bit_repeat</c-></code></span></a>
        <li><a href="#interleaving-bits"><span class="secno">4.2.2</span> <span class="content">Interleaving bits with <code class="highlight"><c- n>bit_expand</c-></code></span></a>
        <li><a href="#input-output"><span class="secno">4.2.3</span> <span class="content">UTF-8 decoding with <code class="highlight"><c- n>bit_compressr</c-></code></span></a>
        <li><a href="#building-operations"><span class="secno">4.2.4</span> <span class="content">Other operations based on <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></span></a>
        <li><a href="#iterating-with-next-bit-permutation"><span class="secno">4.2.5</span> <span class="content">Iterating over subsets using <code class="highlight"><c- n>next_bit_permutation</c-></code></span></a>
       </ol>
      <li>
       <a href="#hardware-support"><span class="secno">4.3</span> <span class="content">Hardware support</span></a>
       <ol class="toc">
        <li><a href="#hardware-support-reverse"><span class="secno">4.3.1</span> <span class="content">Support for <code class="highlight"><c- n>bit_reverse</c-></code></span></a>
        <li><a href="#hardware-support-bit-repeat"><span class="secno">4.3.2</span> <span class="content">Support for <code class="highlight"><c- n>bit_repeat</c-></code></span></a>
        <li><a href="#hardware-support-next-bit-permutation"><span class="secno">4.3.3</span> <span class="content">Support for <code class="highlight"><c- n>next_bit_permutation</c-></code></span></a>
        <li><a href="#hardware-support-compress-expand"><span class="secno">4.3.4</span> <span class="content">Support for <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></span></a>
       </ol>
     </ol>
    <li><a href="#impact-on-existing-code"><span class="secno">5</span> <span class="content">Impact on existing code</span></a>
    <li>
     <a href="#design"><span class="secno">6</span> <span class="content">Design considerations</span></a>
     <ol class="toc">
      <li><a href="#bit-repeat-signature"><span class="secno">6.1</span> <span class="content">Signature of <code class="highlight"><c- n>bit_repeat</c-></code></span></a>
      <li><a href="#naming-compress-expand"><span class="secno">6.2</span> <span class="content">Why the names <em>compress</em> and <em>expand</em>?</span></a>
      <li>
       <a href="#further-generalization"><span class="secno">6.3</span> <span class="content">Why the lack of generalization?</span></a>
       <ol class="toc">
        <li><a href="#generalized-compress-expand"><span class="secno">6.3.1</span> <span class="content">No generalized <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></span></a>
        <li><a href="#generalized-bit-reverse"><span class="secno">6.3.2</span> <span class="content">No generalized <code class="highlight"><c- n>bit_reverse</c-></code></span></a>
       </ol>
      <li><a href="#unusual-signature"><span class="secno">6.4</span> <span class="content">Why does the signature of <code class="highlight"><c- n>bit_compress</c-></code> require two same <code class="highlight"><c- n>T</c-></code>s?</span></a>
     </ol>
    <li>
     <a href="#possible-implementation"><span class="secno">7</span> <span class="content">Possible implementation</span></a>
     <ol class="toc">
      <li><a href="#reference-implementation"><span class="secno">7.1</span> <span class="content">Reference implementation</span></a>
      <li><a href="#contemporary-implementations"><span class="secno">7.2</span> <span class="content">Other implementations</span></a>
     </ol>
    <li>
     <a href="#proposed-wording"><span class="secno">8</span> <span class="content">Proposed wording</span></a>
     <ol class="toc">
      <li><a href="#proposed-feature-testing"><span class="secno">8.1</span> <span class="content">Feature-testing</span></a>
      <li><a href="#proposed-header-synopsis"><span class="secno">8.2</span> <span class="content">Header synopsis</span></a>
      <li><a href="#proposed-new-subclause"><span class="secno">8.3</span> <span class="content">New subclause</span></a>
     </ol>
    <li><a href="#acknowledgements"><span class="secno">9</span> <span class="content">Acknowledgements</span></a>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#normative"><span class="secno"></span> <span class="content">Normative References</span></a>
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="revisions"><span class="secno">1. </span><span class="content">Revision history</span><a class="self-link" href="#revisions"></a></h2>
   <h3 class="heading settled" data-level="1.1" id="changes-since-r0"><span class="secno">1.1. </span><span class="content">Changes since R0</span><a class="self-link" href="#changes-since-r0"></a></h3>
   <ul>
    <li data-md>
     <p>Expand <a href="#hardware-support">§ 4.3 Hardware support</a>, taking more instructions into account, including AVX-512.</p>
    <li data-md>
     <p>Minor editorial fixes.</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="intro"><span class="secno">2. </span><span class="content">Introduction</span><a class="self-link" href="#intro"></a></h2>
   <p>The C++ bit manipulation library in <code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code> is an invaluable abstraction from hardware operations.
Functions like <code class="highlight"><c- n>countl_zero</c-></code> help the programmer avoid use of intrinsic functions or inline
assembly.</p>
   <p>However, there are still a few operations which are non-trivial to implement in software
and have widely available hardware support.
Therefore, I propose to expand the bit manipulation library
with multiple bit permutation functions described below.
Even without hardware support, these functions provide great utility and/or help the developer
write more expressive code.</p>
   <h2 class="heading settled" data-level="3" id="proposed-features"><span class="secno">3. </span><span class="content">Proposed features</span><a class="self-link" href="#proposed-features"></a></h2>
   <p>I propose to add the following functions to the bit manipulation library (<code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code>).</p>
   <p class="note" role="note"><span class="marker">Note:</span> All constraints are exposition-only.
      The function bodies contain a naive implementation that merely illustrates the behavior.</p>
   <p class="note" role="note"><span class="marker">Note:</span> See <a href="#hardware-support">§ 4.3 Hardware support</a> for the corresponding hardware instructions.</p>
   <h3 class="heading settled" data-level="3.1" id="intro-bit-reverse"><span class="secno">3.1. </span><span class="content"><code class="highlight"><c- n>bit_reverse</c-></code></span><a class="self-link" href="#intro-bit-reverse"></a></h3>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c->
<c- p>{</c->
    <c- n>T</c-> <c- n>result</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->
    <c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>numeric_limits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>digits</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
        <c- n>result</c-> <c- o>&lt;&lt;=</c-> <c- mi>1</c-><c- p>;</c->
        <c- n>result</c-> <c- o>|=</c-> <c- n>x</c-> <c- o>&amp;</c-> <c- mi>1</c-><c- p>;</c->
        <c- n>x</c-> <c- o>>>=</c-> <c- mi>1</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>Reverses the bits of <code class="highlight"><c- n>x</c-></code> so that the least significant bit becomes the most significant.</p>
   <div class="example" id="example-349d65a5"><a class="self-link" href="#example-349d65a5"></a> <code class="highlight"><c- n>bit_reverse</c-><c- p>(</c-><c- b>uint32_t</c-><c- p>{</c-><c- mh>0x00001234</c-><c- p>})</c-></code> equals <code class="highlight"><c- mh>0x24c80000</c-></code>. </div>
   <h3 class="heading settled" data-level="3.2" id="intro-bit-repeat"><span class="secno">3.2. </span><span class="content"><code class="highlight"><c- n>bit_repeat</c-></code></span><a class="self-link" href="#intro-bit-repeat"></a></h3>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_repeat</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- b>int</c-> <c- n>length</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c->false<c- p>)</c->
<c- p>{</c->
    <c- n>T</c-> <c- n>result</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->
    <c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>numeric_limits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>digits</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
        <c- n>result</c-> <c- o>|=</c-> <c- p>((</c-><c- n>x</c-> <c- o>>></c-> <c- p>(</c-><c- n>i</c-> <c- o>%</c-> <c- n>length</c-><c- p>))</c-> <c- o>&amp;</c-> <c- mi>1</c-><c- p>)</c-> <c- o>&lt;&lt;</c-> <c- n>i</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>Repeats a pattern stored in the least significant <code class="highlight"><c- n>length</c-></code> bits of <code class="highlight"><c- n>x</c-></code>, as many times as fits into <code class="highlight"><c- n>x</c-></code>.</p>
   <div class="example" id="example-50c3301e"><a class="self-link" href="#example-50c3301e"></a> <code class="highlight"><c- n>bit_repeat</c-><c- p>(</c-><c- b>uint32_t</c-><c- p>{</c-><c- mh>0xc</c-><c- p>},</c-> <c- mi>4</c-><c- p>)</c-></code> equals <code class="highlight"><c- mh>0xcccccccc</c-></code>. </div>
   <h3 class="heading settled" data-level="3.3" id="intro-bit-permutation"><span class="secno">3.3. </span><span class="content"><code class="highlight"><c- n>next_bit_permutation</c-></code> and <code class="highlight"><c- n>prev_bit_permutation</c-></code></span><a class="self-link" href="#intro-bit-permutation"></a></h3>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>next_bit_permutation</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c->
<c- p>{</c->
    <c- k>const</c-> <c- b>int</c-> <c- n>count</c-> <c- o>=</c-> <c- n>popcount</c-><c- p>(</c-><c- n>x</c-><c- p>);</c->
    <c- k>while</c-> <c- p>(</c-><c- n>x</c-> <c- o>!=</c-> <c- mi>0</c-> <c- o>&amp;&amp;</c-> <c- n>popcount</c-><c- p>(</c-><c- o>++</c-><c- n>x</c-><c- p>)</c-> <c- o>!=</c-> <c- n>count</c-><c- p>)</c-> <c- p>{}</c->
    <c- k>return</c-> <c- n>x</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>Returns the lowest number <code class="highlight"><c- n>y</c-></code> in <code class="highlight"><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>numeric_limits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>max</c-><c- p>()]</c-></code> for which <code class="highlight"><c- n>popcount</c-><c- p>(</c-><c- n>y</c-><c- p>)</c-> <c- o>==</c-> <c- n>popcount</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code>, or <code class="highlight"><c- mi>0</c-></code> if none exists.</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>prev_bit_permutation</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c->
<c- p>{</c->
    <c- k>const</c-> <c- b>int</c-> <c- n>count</c-> <c- o>=</c-> <c- n>popcount</c-><c- p>(</c-><c- n>x</c-><c- p>);</c->
    <c- k>while</c-> <c- p>(</c-><c- n>x</c-> <c- o>!=</c-> <c- mi>0</c-> <c- o>&amp;&amp;</c-> <c- n>popcount</c-><c- p>(</c-><c- o>--</c-><c- n>x</c-><c- p>)</c-> <c- o>!=</c-> <c- n>count</c-><c- p>)</c-> <c- p>{}</c->
    <c- k>return</c-> <c- n>x</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>Returns the greatest number <code class="highlight"><c- n>y</c-></code> in <code class="highlight"><c- p>[</c-><c- mi>0</c-><c- p>,</c-> <c- n>x</c-><c- p>)</c-></code> for which <code class="highlight"><c- n>popcount</c-><c- p>(</c-><c- n>y</c-><c- p>)</c-> <c- o>==</c-> <c- n>popcount</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code>, or <code class="highlight"><c- mi>0</c-></code> if none exists.</p>
   <div class="example" id="example-7f810eb1">
    <a class="self-link" href="#example-7f810eb1"></a> The following loop can be used to generate <span title="32 choose 3"> <svg alt="32 choose 3" aria-hidden="true" height="43.424px" viewBox="0 -1449.5 2472 2399" width="44.744px" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><path d="M701 -940Q701 -943 695 -949H664Q662 -947 636 -922T591 -879T537 -818T475 -737T412 -636T350 -511T295 -362T250 -186T221 17T209 251Q209 962 573 1361Q596 1386 616 1405T649 1437T664 1450H695Q701 1444 701 1441Q701 1436 681 1415T629 1356T557 1261T476 1118T400 927T340 675T308 359Q306 321 306 250Q306 -139 400 -430T690 -924Q701 -936 701 -940Z" id="MJX-19-TEX-S3-28"></path><path d="M127 463Q100 463 85 480T69 524Q69 579 117 622T233 665Q268 665 277 664Q351 652 390 611T430 522Q430 470 396 421T302 350L299 348Q299 347 308 345T337 336T375 315Q457 262 457 175Q457 96 395 37T238 -22Q158 -22 100 21T42 130Q42 158 60 175T105 193Q133 193 151 175T169 130Q169 119 166 110T159 94T148 82T136 74T126 70T118 67L114 66Q165 21 238 21Q293 21 321 74Q338 107 338 175V195Q338 290 274 322Q259 328 213 329L171 330L168 332Q166 335 166 348Q166 366 174 366Q202 366 232 371Q266 376 294 413T322 525V533Q322 590 287 612Q265 626 240 626Q208 626 181 615T143 592T132 580H135Q138 579 143 578T153 573T165 566T175 555T183 540T186 520Q186 498 172 481T127 463Z" id="MJX-19-TEX-N-33"></path><path d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z" id="MJX-19-TEX-N-32"></path><path d="M34 1438Q34 1446 37 1448T50 1450H56H71Q73 1448 99 1423T144 1380T198 1319T260 1238T323 1137T385 1013T440 864T485 688T514 485T526 251Q526 134 519 53Q472 -519 162 -860Q139 -885 119 -904T86 -936T71 -949H56Q43 -949 39 -947T34 -937Q88 -883 140 -813Q428 -430 428 251Q428 453 402 628T338 922T245 1146T145 1309T46 1425Q44 1427 42 1429T39 1433T36 1436L34 1438Z" id="MJX-19-TEX-S3-29"></path></defs><g fill="currentColor" stroke="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mrow"><g data-mjx-texclass="OPEN" data-mml-node="TeXAtom"><g data-mml-node="mo" transform="translate(0 -0.5)"><use data-c="28" href="#MJX-19-TEX-S3-28"></use></g></g><g data-mml-node="mfrac" transform="translate(736,0)"><g data-mml-node="mn" transform="translate(0,676)"><use data-c="33" href="#MJX-19-TEX-N-33"></use><use data-c="32" transform="translate(500,0)" href="#MJX-19-TEX-N-32"></use></g><g data-mml-node="mn" transform="translate(250,-686)"><use data-c="33" href="#MJX-19-TEX-N-33"></use></g></g><g data-mjx-texclass="CLOSE" data-mml-node="TeXAtom" transform="translate(1736,0)"><g data-mml-node="mo" transform="translate(0 -0.5)"><use data-c="29" href="#MJX-19-TEX-S3-29"></use></g></g></g></g></g></svg> </span> elements of equal <code class="highlight"><c- n>popcount</c-></code>: 
<pre class="language-cpp highlight"><c- k>for</c-> <c- p>(</c-><c- b>uint32_t</c-> <c- n>x</c-> <c- o>=</c-> <c- mb>0b111</c-><c- p>;</c-> <c- n>x</c-> <c- o>!=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>x</c-> <c- o>=</c-> <c- n>next_bit_permutation</c-><c- p>(</c-><c- n>x</c-><c- p>))</c-> <c- c1>// ...</c->
</pre>
    <p><code class="highlight"><c- n>x</c-></code> will take the values:</p>
<pre class="language-cpp highlight"><c- nl>dec</c-><c- p>:</c->    <c- mi>7</c-><c- p>,</c->   <c- mi>11</c-><c- p>,</c->   <c- mi>13</c-><c- p>,</c->   <c- mi>14</c-><c- p>,</c->    <c- mi>19</c-><c- p>,</c->    <c- mi>21</c-><c- p>,</c-> <c- p>...</c->
<c- nl>bin</c-><c- p>:</c->  <c- mi>111</c-><c- p>,</c-> <c- mi>1011</c-><c- p>,</c-> <c- mi>1101</c-><c- p>,</c-> <c- mi>1110</c-><c- p>,</c-> <c- mi>10011</c-><c- p>,</c-> <c- mi>10101</c-><c- p>,</c-> <c- p>...</c->
</pre>
    <p><code class="highlight"><c- n>prev_bit_permutation</c-></code> can be used to generate this sequence in reverse.</p>
   </div>
   <h3 class="heading settled" data-level="3.4" id="intro-bit-compress"><span class="secno">3.4. </span><span class="content"><code class="highlight"><c- n>bit_compress</c-></code></span><a class="self-link" href="#intro-bit-compress"></a></h3>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c->
<c- p>{</c->
    <c- n>T</c-> <c- n>result</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->
    <c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>,</c-> <c- n>j</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>numeric_limits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>digits</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
        <c- b>bool</c-> <c- n>mask_bit</c-> <c- o>=</c-> <c- p>(</c-><c- n>m</c-> <c- o>>></c-> <c- n>i</c-><c- p>)</c-> <c- o>&amp;</c-> <c- mi>1</c-><c- p>;</c->
        <c- n>result</c-> <c- o>|=</c-> <c- p>(</c-><c- n>mask_bit</c-> <c- o>&amp;</c-> <c- p>(</c-><c- n>x</c-> <c- o>>></c-> <c- n>i</c-><c- p>))</c-> <c- o>&lt;&lt;</c-> <c- n>j</c-><c- p>;</c->
        <c- n>j</c-> <c- o>+=</c-> <c- n>mask_bit</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>For each one-bit in <code class="highlight"><c- n>m</c-></code>, the corresponding bit in <code class="highlight"><c- n>x</c-></code> is taken and packed
contiguously into the result, starting with the least significant result bit.</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_compressl</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c->
<c- p>{</c->
    <c- k>return</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>bit_compressr</c-><c- p>(</c-><c- n>bit_reverse</c-><c- p>(</c-><c- n>x</c-><c- p>)),</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>m</c-><c- p>)));</c->
<c- p>}</c->
</pre>
   <p>For each one-bit in <code class="highlight"><c- n>m</c-></code>, the corresponding bit in <code class="highlight"><c- n>x</c-></code> is taken and packed
contiguously into the result, starting with the most significant result bit.</p>
   <div class="example" id="example-4c76abe3">
    <a class="self-link" href="#example-4c76abe3"></a> 
<pre class="language-text highlight">x:
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
m:    |       |        bit_compressl(x, m):  bit_compressr(x, m):
+---+---+---+---+      +---+---+---+---+      +---+---+---+---+
| 0 | 1 | 0 | 1 |      | b | d | 0 | 0 |      | 0 | 0 | b | d |
+---+---+---+---+      +---+---+---+---+      +---+---+---+---+
</pre>
   </div>
   <p class="note" role="note"><span class="marker">Note:</span> Intuitively, <code class="highlight"><c- n>m</c-></code> is a "mask" that determines which bits of <code class="highlight"><c- n>x</c-></code> are packed.</p>
   <h3 class="heading settled" data-level="3.5" id="intro-bit-expand"><span class="secno">3.5. </span><span class="content"><code class="highlight"><c- n>bit_expand</c-></code></span><a class="self-link" href="#intro-bit-expand"></a></h3>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_expandr</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c->
<c- p>{</c->
    <c- n>T</c-> <c- n>result</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->
    <c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>0</c-><c- p>,</c-> <c- n>j</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>&lt;</c-> <c- n>numeric_limits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>digits</c-><c- p>;</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
        <c- b>bool</c-> <c- n>mask_bit</c-> <c- o>=</c-> <c- p>(</c-><c- n>m</c-> <c- o>>></c-> <c- n>i</c-><c- p>)</c-> <c- o>&amp;</c-> <c- mi>1</c-><c- p>;</c->
        <c- n>result</c-> <c- o>|=</c-> <c- p>(</c-><c- n>mask_bit</c-> <c- o>&amp;</c-> <c- p>(</c-><c- n>x</c-> <c- o>>></c-> <c- n>j</c-><c- p>))</c-> <c- o>&lt;&lt;</c-> <c- n>i</c-><c- p>;</c->
        <c- n>j</c-> <c- o>+=</c-> <c- n>mask_bit</c-><c- p>;</c->
    <c- p>}</c->
    <c- k>return</c-> <c- n>result</c-><c- p>;</c->
<c- p>}</c->
</pre>
   <p>For each one-bit in <code class="highlight"><c- n>m</c-></code>, a bit from <code class="highlight"><c- n>x</c-></code>, starting with the least significant bit
is taken and shifted into the corresponding position of the <code class="highlight"><c- n>m</c-></code> bit.</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_expandl</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c->
<c- p>{</c->
    <c- k>return</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>bit_expandr</c-><c- p>(</c-><c- n>bit_reverse</c-><c- p>(</c-><c- n>x</c-><c- p>)),</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>m</c-><c- p>)));</c->
<c- p>}</c->
</pre>
   <p>For each one-bit in <code class="highlight"><c- n>m</c-></code>, a bit from <code class="highlight"><c- n>x</c-></code>, starting with the most significant bit
is taken and shifted into the corresponding position of the <code class="highlight"><c- n>m</c-></code> bit.</p>
   <div class="example" id="example-37dab458">
    <a class="self-link" href="#example-37dab458"></a> 
<pre class="language-text highlight">x:
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
m:                     bit_expandl(x, m):    bit_expandr(x, m):
+---+---+---+---+      +---+---+---+---+      +---+---+---+---+
| 0 | 1 | 0 | 1 |      | 0 | a | 0 | b |      | 0 | c | 0 | d |
+---+---+---+---+      +---+---+---+---+      +---+---+---+---+
</pre>
   </div>
   <p class="note" role="note"><span class="marker">Note:</span> Intuitively, <code class="highlight"><c- n>m</c-></code> is a "mask" that determines where the bits of <code class="highlight"><c- n>x</c-></code> are unpacked into.</p>
   <h2 class="heading settled" data-level="4" id="motivation-and-scope"><span class="secno">4. </span><span class="content">Motivation and scope</span><a class="self-link" href="#motivation-and-scope"></a></h2>
   <p>Bit-reversal, repetition, compression, and expansion
are fundamental operations that meet multiple criteria
which make them suitable for standardization:</p>
   <ol>
    <li data-md>
     <p>They are common and useful operations.</p>
    <li data-md>
     <p>They can be used to implement numerous other operations.</p>
    <li data-md>
     <p>At least on some architectures, they have direct hardware support.</p>
    <li data-md>
     <p>They are non-trivial to implement efficiently in software.</p>
    <li data-md>
     <p>For known masks, numerous optimization opportunities are available.</p>
   </ol>
   <p><code class="highlight"><c- n>next_bit_permutation</c-></code>, is the most niche of these operations and does not meet all criteria.
However, I believe it is useful enough to be included in this proposal,
and it fits the overall theme well.</p>
   <h3 class="heading settled" data-level="4.1" id="applications"><span class="secno">4.1. </span><span class="content">Applications</span><a class="self-link" href="#applications"></a></h3>
   <h4 class="heading settled" data-level="4.1.1" id="applications-of-bit-reverse"><span class="secno">4.1.1. </span><span class="content">Applications of <code class="highlight"><c- n>bit_reverse</c-></code></span><a class="self-link" href="#applications-of-bit-reverse"></a></h4>
   <p>Bit-reversal is a common operation with uses in:</p>
   <ul>
    <li data-md>
     <p><strong>Cryptography</strong>: scrambling bits</p>
    <li data-md>
     <p><strong>Networking</strong>: as part of <a href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">cyclic redundancy check</a> computation</p>
    <li data-md>
     <p><strong>Graphics</strong>: mirroring of images with one bit per pixel</p>
    <li data-md>
     <p><strong>Random number generation</strong>: reversal can counteract low entropy of low-order bits
such as in the case of <a href="https://en.wikipedia.org/wiki/Linear_congruential_generator">linear congruential generators</a></p>
    <li data-md>
     <p><strong>Digital signal processing</strong>: for radix-2 <a href="https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm">Cooley-Tukey FFT algorithms</a></p>
    <li data-md>
     <p><strong>Code obfuscation</strong>: security by obscurity</p>
   </ul>
   <h4 class="heading settled" data-level="4.1.2" id="applications-of-bit-repeat"><span class="secno">4.1.2. </span><span class="content">Applications of <code class="highlight"><c- n>bit_repeat</c-></code></span><a class="self-link" href="#applications-of-bit-repeat"></a></h4>
   <p>The generation of recurring bit patterns is such a fundamental operation
that it’s hard to tie to any specific domain, but here are some use cases:</p>
   <ul>
    <li data-md>
     <p><strong>Debugging</strong>: using obvious recurring bit pattenrs like <code class="highlight"><c- mh>0xcccc</c-><c- p>...</c-></code> to identify "garbage memory"</p>
    <li data-md>
     <p><strong>Bit manipulation</strong>: generating alternating sequences of <code class="highlight"><c- mi>1</c-></code> and <code class="highlight"><c- mi>0</c-></code> for various algorithms</p>
    <li data-md>
     <p><strong>Eliminating integer divison</strong>: for <code class="highlight"><c- n>x</c-> <c- o>>></c-> <c- p>(</c-><c- n>i</c-> <c- o>%</c-> <c- n>N</c-><c- p>)</c-></code> with very small <code class="highlight"><c- n>N</c-></code>, <code class="highlight"><c- n>bit_repeat</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>N</c-><c- p>)</c-> <c- o>>></c-> <c- n>i</c-></code> can be used instead</p>
    <li data-md>
     <p><strong>Testing</strong>: recurring bit patterns can make for good test cases when implementing numerics</p>
    <li data-md>
     <p><strong>Error detection</strong>: known bit patterns can be introduced to spot failed transmission</p>
   </ul>
   <h4 class="heading settled" data-level="4.1.3" id="applications-of-bit-compress-and-bit-expand"><span class="secno">4.1.3. </span><span class="content">Applications of <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></span><a class="self-link" href="#applications-of-bit-compress-and-bit-expand"></a></h4>
   <p>Compression and expansion are also common, with uses in:</p>
   <ul>
    <li data-md>
     <p><strong>Space-filling curves</strong>: <a href="https://en.wikipedia.org/wiki/Z-order_curve">Morton/Z-Order</a> and <a href="https://en.wikipedia.org/wiki/Hilbert_curve">Hilbert curves</a></p>
    <li data-md>
     <p><strong>Input/output</strong>: especially for variable-length encodings, such as UTF-8 (<a href="#input-output">§ 4.2.3 UTF-8 decoding with bit_compressr</a>)</p>
    <li data-md>
     <p><strong>Chess engines</strong>: for <a href="https://en.wikipedia.org/wiki/Bitboard">bitboards</a>; see <a data-link-type="biblio" href="#biblio-chessprogramming1" title="chessprogramming.org/BMI2, Applications">[ChessProgramming1]</a></p>
    <li data-md>
     <p><strong>Genomics</strong>: according to <a data-link-type="biblio" href="#biblio-arm1" title="Introduction to SVE2, Issue 02, Revision 02">[ARM1]</a></p>
   </ul>
   <p>A GitHub code search for <code class="highlight"><c- o>/</c-><c- p>(</c-><c- n>_pdep_u</c-><c- o>|</c-><c- n>_pext_u</c-><c- p>)(</c-><c- mi>32</c-><c- o>|</c-><c- mi>64</c-><c- p>)</c-><c- o>/</c-> <c- n>AND</c-> <c- n>language</c-><c- o>:</c-><c- n>c</c-><c- o>++</c-></code> reveals ~1300 files which use the intrinsic wrappers for the x86 instructions.</p>
   <h4 class="heading settled" data-level="4.1.4" id="applications-of-next-bit-permutation"><span class="secno">4.1.4. </span><span class="content">Applications of <code class="highlight"><c- n>next_bit_permutation</c-></code></span><a class="self-link" href="#applications-of-next-bit-permutation"></a></h4>
   <p><code class="highlight"><c- n>next_bit_permutation</c-></code> is useful for iterating over all subsets with a fixed amount of elements
(see below for an example).</p>
   <p>Unlike algorithms such as <code class="highlight"><c- n>next_permutation</c-></code>, it can be used with no modification of the
original range.
Together with <code class="highlight"><c- n>prev_bit_permutation</c-></code>, it is possible to create a bidirectional view of all
fixed-size subsets of a range.</p>
   <h3 class="heading settled" data-level="4.2" id="use-cases"><span class="secno">4.2. </span><span class="content">Motivating examples</span><a class="self-link" href="#use-cases"></a></h3>
   <h4 class="heading settled" data-level="4.2.1" id="implementing-countr-zero"><span class="secno">4.2.1. </span><span class="content">Implementing <code class="highlight"><c- n>countr_zero</c-></code> with <code class="highlight"><c- n>bit_repeat</c-></code></span><a class="self-link" href="#implementing-countr-zero"></a></h4>
   <p><a data-link-type="biblio" href="#biblio-anderson1" title="Bit Twiddling Hacks">[Anderson1]</a> contains a vast amount of algorithms,
many of which involve masks of alternating <code class="highlight"><c- mi>0</c-></code>s and <code class="highlight"><c- mi>1</c-></code>s.</p>
   <p>When written as "magic numbers" in code,
these masks can make it quite hard to understand the overall pattern
and to generalize these algorithms. <code class="highlight"><c- n>bit_repeat</c-></code> allows one to be more expressive here:</p>
   <div class="example" id="example-459731b5">
    <a class="self-link" href="#example-459731b5"></a> 
<pre class="highlight"><c- b>unsigned</c-> <c- b>int</c-> <c- n>v</c-><c- p>;</c->      <c- c1>// 32-bit word input to count zero bits on right</c->
<c- b>unsigned</c-> <c- b>int</c-> <c- n>c</c-> <c- o>=</c-> <c- mi>32</c-><c- p>;</c-> <c- c1>// c will be the number of zero bits on the right</c->
<c- n>v</c-> <c- o>&amp;=</c-> <c- o>-</c-><c- n>v</c-><c- p>;</c->
<c- k>if</c-> <c- p>(</c-><c- n>v</c-><c- p>)</c-> <c- n>c</c-><c- o>--</c-><c- p>;</c->
<c- k>if</c-> <c- p>(</c-><c- n>v</c-> <c- o>&amp;</c-> <del><c- mh>0x0000FFFF</c-></del> <ins><c- n>bit_repeat</c-><c- p>((</c-><c- mi>1</c-> <c- o>&lt;&lt;</c-> <c- mi>16</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>,</c-> <c- mi>32</c-><c- p>)</c-></ins><c- p>)</c-> <c- n>c</c-> <c- o>-=</c-> <c- mi>16</c-><c- p>;</c->
<c- k>if</c-> <c- p>(</c-><c- n>v</c-> <c- o>&amp;</c-> <del><c- mh>0x00FF00FF</c-></del> <ins><c- n>bit_repeat</c-><c- p>(</c-> <c- p>(</c-><c- mi>1</c-> <c- o>&lt;&lt;</c-> <c- mi>8</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>,</c-> <c- mi>16</c-><c- p>)</c-></ins><c- p>)</c-> <c- n>c</c-> <c- o>-=</c->  <c- mi>8</c-><c- p>;</c->
<c- k>if</c-> <c- p>(</c-><c- n>v</c-> <c- o>&amp;</c-> <del><c- mh>0x0F0F0F0F</c-></del> <ins><c- n>bit_repeat</c-><c- p>(</c-> <c- p>(</c-><c- mi>1</c-> <c- o>&lt;&lt;</c-> <c- mi>4</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>,</c->  <c- mi>8</c-><c- p>)</c-></ins><c- p>)</c-> <c- n>c</c-> <c- o>-=</c->  <c- mi>4</c-><c- p>;</c->
<c- k>if</c-> <c- p>(</c-><c- n>v</c-> <c- o>&amp;</c-> <del><c- mh>0x33333333</c-></del> <ins><c- n>bit_repeat</c-><c- p>(</c-> <c- p>(</c-><c- mi>1</c-> <c- o>&lt;&lt;</c-> <c- mi>2</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>,</c->  <c- mi>4</c-><c- p>)</c-></ins><c- p>)</c-> <c- n>c</c-> <c- o>-=</c->  <c- mi>2</c-><c- p>;</c->
<c- k>if</c-> <c- p>(</c-><c- n>v</c-> <c- o>&amp;</c-> <del><c- mh>0x55555555</c-></del> <ins><c- n>bit_repeat</c-><c- p>(</c-> <c- p>(</c-><c- mi>1</c-> <c- o>&lt;&lt;</c-> <c- mi>1</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>,</c->  <c- mi>2</c-><c- p>)</c-></ins><c- p>)</c-> <c- n>c</c-> <c- o>-=</c->  <c- mi>1</c-><c- p>;</c->
</pre>
    <p>It is now obvious how this can be expressed in a loop:</p>
<pre class="language-cpp highlight"><c- c1>// ...</c->
<c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-> <c- o>=</c-> <c- mi>16</c-><c- p>;</c-> <c- n>i</c-> <c- o>!=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>i</c-> <c- o>/=</c-> <c- mi>2</c-><c- p>)</c-> <c- p>{</c->
    <c- b>unsigned</c-> <c- n>mask</c-> <c- o>=</c-> <c- n>bit_repeat</c-><c- p>((</c-><c- mi>1u</c-> <c- o>&lt;&lt;</c-> <c- n>i</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>,</c-> <c- n>i</c-> <c- o>*</c-> <c- mi>2</c-><c- p>);</c->
    <c- k>if</c-> <c- p>(</c-><c- n>v</c-> <c- o>&amp;</c-> <c- n>mask</c-><c- p>)</c-> <c- n>c</c-> <c- o>-=</c-> <c- n>i</c-><c- p>;</c->
<c- p>}</c->
</pre>
   </div>
   <p><code class="highlight"><c- n>bit_repeat</c-></code> has been an invaluable asset in the implementation of the remaining functions
in this proposal (see <a data-link-type="biblio" href="#biblio-schultke1" title="C++26 Bit Permutations">[Schultke1]</a> for details).</p>
   <h4 class="heading settled" data-level="4.2.2" id="interleaving-bits"><span class="secno">4.2.2. </span><span class="content">Interleaving bits with <code class="highlight"><c- n>bit_expand</c-></code></span><a class="self-link" href="#interleaving-bits"></a></h4>
   <p>A common use case for expansion is interleaving bits.
This translates Cartesian coordinates to the index on a <a href="https://en.wikipedia.org/wiki/Z-order_curve">Z-order curve</a>.
Space filling curves are a popular technique in compression.</p>
   <div class="example" id="example-daa7eab3">
    <a class="self-link" href="#example-daa7eab3"></a> 
<pre class="language-cpp highlight"><c- b>unsigned</c-> <c- n>x</c-> <c- o>=</c-> <c- mi>3</c-><c- p>;</c-> <c- c1>// 0b011</c->
<c- b>unsigned</c-> <c- n>y</c-> <c- o>=</c-> <c- mi>5</c-><c- p>;</c-> <c- c1>// 0b101</c->
<c- k>const</c-> <c- k>auto</c-> <c- n>i</c-> <c- o>=</c-> <c- n>bit_expandr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>bit_repeat</c-><c- p>(</c-><c- mb>0b10u</c-><c- p>,</c-> <c- mi>2</c-><c- p>))</c-> <c- c1>// i = 0b01'10'11</c->
             <c- o>|</c-> <c- n>bit_expandr</c-><c- p>(</c-><c- n>y</c-><c- p>,</c-> <c- n>bit_repeat</c-><c- p>(</c-><c- mb>0b01u</c-><c- p>,</c-> <c- mi>2</c-><c- p>));</c->
</pre>
   </div>
   <h4 class="heading settled" data-level="4.2.3" id="input-output"><span class="secno">4.2.3. </span><span class="content">UTF-8 decoding with <code class="highlight"><c- n>bit_compressr</c-></code></span><a class="self-link" href="#input-output"></a></h4>
   <p><code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code> are useful in various I/O-related applications.
They are particularly helpful for dealing with variable-length encodings,
where "data bits" are interrupted by bits which signal continuation of the data.</p>
   <div class="example" id="example-aa0416a1">
    <a class="self-link" href="#example-aa0416a1"></a> The following code reads 4 bytes from some source of UTF-8 data and returns the codepoint.
For the sake of simplicity, let’s ignore details like reaching the end of the file, or I/O errors. 
<pre class="language-cpp highlight"><c- b>uint_least32_t</c-> <c- n>x</c-> <c- o>=</c-> <c- n>load32_little_endian</c-><c- p>(</c-><c- n>utf8_data_pointer</c-><c- p>);</c->
<c- k>switch</c-> <c- p>(</c-><c- n>countl_one</c-><c- p>(</c-><c- b>uint8_t</c-><c- p>(</c-><c- n>x</c-><c- p>)))</c-> <c- p>{</c->
<c- k>case</c-> <c- mi>0</c-><c- p>:</c-> <c- k>return</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mb>0b01111111</c-><c- p>);</c->
<c- k>case</c-> <c- mi>1</c-><c- p>:</c-> <c- d>/* error */</c-><c- p>;</c->
<c- k>case</c-> <c- mi>2</c-><c- p>:</c-> <c- k>return</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mb>0b00111111'00011111</c-><c- p>);</c->
<c- k>case</c-> <c- mi>3</c-><c- p>:</c-> <c- k>return</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mb>0b00111111'00111111'00001111</c-><c- p>);</c->
<c- k>case</c-> <c- mi>4</c-><c- p>:</c-> <c- k>return</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mb>0b00111111'00111111'00111111'00000111</c-><c- p>);</c->
<c- p>}</c->
</pre>
   </div>
   <h4 class="heading settled" data-level="4.2.4" id="building-operations"><span class="secno">4.2.4. </span><span class="content">Other operations based on <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></span><a class="self-link" href="#building-operations"></a></h4>
   <p>Many operations can be built on top of <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code>.
However, direct hardware support is often needed for the proposed functions to efficiently
implement them.
Even without such support, they can be canonalized into a faster form.
The point is that <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code> allow you to <em>express</em> these operations.</p>
   <div class="example" id="example-329b75b7">
    <a class="self-link" href="#example-329b75b7"></a> 
<pre class="language-cpp highlight"><c- c1>// x &amp; 0xf</c->
<c- n>bit_expandr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mh>0xf</c-><c- p>)</c->
<c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mh>0xf</c-><c- p>)</c->

<c- c1>// (x &amp; 0xf) &lt;&lt; 4</c->
<c- n>bit_expandr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mh>0xf0</c-><c- p>)</c->
<c- c1>// (x >> 4) &amp; 0xf</c->
<c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mh>0xf0</c-><c- p>)</c->

<c- c1>// Clear the least significant one-bit of x.</c->
<c- n>x</c-> <c- o>^=</c-> <c- n>bit_expandr</c-><c- p>(</c-><c- mi>1</c-><c- p>,</c-> <c- n>x</c-><c- p>)</c->
<c- c1>// Clear the nth least significant one-bit of x.</c->
<c- n>x</c-> <c- o>^=</c-> <c- n>bit_expandr</c-><c- p>(</c-><c- mi>1</c-> <c- o>&lt;&lt;</c-> <c- n>n</c-><c- p>,</c-> <c- n>x</c-><c- p>)</c->
<c- c1>// Clear the n least significant one-bits of x.</c->
<c- n>x</c-> <c- o>^=</c-> <c- n>bit_expandr</c-><c- p>((</c-><c- mi>1</c-> <c- o>&lt;&lt;</c-> <c- n>n</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>,</c-> <c- n>x</c-><c- p>)</c->

<c- c1>// (x >> n) &amp; 1</c->
<c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mi>1</c-> <c- o>&lt;&lt;</c-> <c- n>n</c-><c- p>)</c->
<c- c1>// Get the least significant bit of x.</c->
<c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>x</c-><c- p>)</c-> <c- o>&amp;</c-> <c- mi>1</c->
<c- c1>// Get the nth least significant bit of x.</c->
<c- p>(</c-><c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>x</c-><c- p>)</c-> <c- o>>></c-> <c- n>n</c-><c- p>)</c-> <c- o>&amp;</c-> <c- mi>1</c->

<c- c1>// popcount(x)</c->
<c- n>countr_one</c-><c- p>(</c-><c- n>bit_compressr</c-><c- p>(</c-><c- mi>-1u</c-><c- p>,</c-> <c- n>x</c-><c- p>))</c->
<c- n>countr_one</c-><c- p>(</c-><c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>x</c-><c- p>))</c->
</pre>
   </div>
   <h4 class="heading settled" data-level="4.2.5" id="iterating-with-next-bit-permutation"><span class="secno">4.2.5. </span><span class="content">Iterating over subsets using <code class="highlight"><c- n>next_bit_permutation</c-></code></span><a class="self-link" href="#iterating-with-next-bit-permutation"></a></h4>
   <div class="example" id="example-ee444949">
    <a class="self-link" href="#example-ee444949"></a> 
<pre class="highlight"><c- k>const</c-> <c- b>char</c-> <c- n>set</c-><c- p>[]</c-> <c- p>{</c-><c- sc>'a'</c-><c- p>,</c-> <c- sc>'b'</c-><c- p>,</c-> <c- sc>'c'</c-><c- p>,</c-> <c- sc>'d'</c-><c- p>};</c->

<c- k>for</c-> <c- p>(</c-><c- b>unsigned</c-> <c- n>bits</c-> <c- o>=</c-> <c- mb>0b11</c-><c- p>;</c-> <c- n>bits</c-> <c- o>&lt;</c-> <c- mi>16</c-><c- p>;</c-> <c- n>bits</c-> <c- o>=</c-> <c- n>next_bit_permutation</c-><c- p>(</c-><c- n>bits</c-><c- p>))</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- n>bits</c-> <c- o>&amp;</c-> <c- mi>1</c-><c- p>)</c-> <c- n>std</c-><c- o>::</c-><c- n>print</c-><c- p>(</c-><c- s>"{}"</c-><c- p>,</c-> <c- n>set</c-><c- p>[</c-><c- mi>0</c-><c- p>]);</c->
    <c- k>if</c-> <c- p>(</c-><c- n>bits</c-> <c- o>&amp;</c-> <c- mi>2</c-><c- p>)</c-> <c- n>std</c-><c- o>::</c-><c- n>print</c-><c- p>(</c-><c- s>"{}"</c-><c- p>,</c-> <c- n>set</c-><c- p>[</c-><c- mi>1</c-><c- p>]);</c->
    <c- k>if</c-> <c- p>(</c-><c- n>bits</c-> <c- o>&amp;</c-> <c- mi>4</c-><c- p>)</c-> <c- n>std</c-><c- o>::</c-><c- n>print</c-><c- p>(</c-><c- s>"{}"</c-><c- p>,</c-> <c- n>set</c-><c- p>[</c-><c- mi>2</c-><c- p>]);</c->
    <c- k>if</c-> <c- p>(</c-><c- n>bits</c-> <c- o>&amp;</c-> <c- mi>8</c-><c- p>)</c-> <c- n>std</c-><c- o>::</c-><c- n>print</c-><c- p>(</c-><c- s>"{}"</c-><c- p>,</c-> <c- n>set</c-><c- p>[</c-><c- mi>3</c-><c- p>]);</c->
    <c- n>std</c-><c- o>::</c-><c- n>print</c-><c- p>(</c-><c- s>" "</c-><c- p>);</c->
<c- p>}</c->
</pre>
    <p>This code prints:</p>
<pre class="language-text highlight">ab ac bc ad bd cd
</pre>
   </div>
   <h3 class="heading settled" data-level="4.3" id="hardware-support"><span class="secno">4.3. </span><span class="content">Hardware support</span><a class="self-link" href="#hardware-support"></a></h3>
   <table>
    <tbody>
     <tr>
      <th>Operation
      <th>x86_64
      <th>ARM
      <th>RISC-V
     <tr>
      <td><code class="highlight"><c- n>bit_reverse</c-></code>
      <td><a href="https://www.felixcloutier.com/x86/vpshufbitqmb"><code class="highlight"><c- n>vpshufbitqmb</c-></code></a><sup>AVX512_BITALG</sup>, (<a href="https://www.felixcloutier.com/x86/bswap"><code class="highlight"><c- n>bswap</c-></code></a>)
      <td><a href="https://docsmirror.github.io/A64/2023-06/rbit_z_p_z.html"><code class="highlight"><c- n>rbit</c-></code></a><sup>SVE2</sup>
      <td><a href="https://github.com/riscv/riscv-bitmanip/"><code class="highlight"><c- n>rev8</c-></code></a><sup>Zbb</sup>+<a href="https://drive.google.com/file/d/1Thd010Eh2DqnhDHpDd3SM7Ame7KENkPw/view"><code class="highlight"><c- n>brev8</c-></code></a><sup>Zbkb</sup>,(<a href="https://github.com/riscv/riscv-bitmanip/"><code class="highlight"><c- n>rev8</c-></code></a><sup>Zbb</sup>)
     <tr>
      <td><code class="highlight"><c- n>bit_repeat</c-></code>
      <td><a href="https://www.felixcloutier.com/x86/vpshufbitqmb"><code class="highlight"><c- n>vpshufbitqmb</c-></code></a><sup>AVX512_BITALG</sup>
      <td>
      <td>
     <tr>
      <td><code class="highlight"><c- n>next_bit_permutation</c-></code>
      <td>(<a href="https://www.felixcloutier.com/x86/tzcnt"><code class="highlight"><c- n>tzcnt</c-></code></a><sup>BMI</sup>/<a href="https://www.felixcloutier.com/x86/bsf"><code class="highlight"><c- n>bsf</c-></code></a>)
      <td>(<a href="https://docsmirror.github.io/A64/2023-06/ctz.html"><code class="highlight"><c- n>ctz</c-></code></a>)
      <td>(<a href="https://github.com/riscv/riscv-bitmanip/"><code class="highlight"><c- n>ctz</c-></code></a><sup>Zbb</sup>)
     <tr>
      <td><code class="highlight"><c- n>prev_bit_permutation</c-></code>
      <td>(<a href="https://www.felixcloutier.com/x86/tzcnt"><code class="highlight"><c- n>tzcnt</c-></code></a><sup>BMI</sup>/<a href="https://www.felixcloutier.com/x86/bsf"><code class="highlight"><c- n>bsf</c-></code></a>)
      <td>(<a href="https://docsmirror.github.io/A64/2023-06/ctz.html"><code class="highlight"><c- n>ctz</c-></code></a>)
      <td>(<a href="https://github.com/riscv/riscv-bitmanip/"><code class="highlight"><c- n>ctz</c-></code></a><sup>Zbb</sup>)
     <tr>
      <td><code class="highlight"><c- n>bit_compressr</c-></code>
      <td><a href="https://www.felixcloutier.com/x86/pext"><code class="highlight"><c- n>pext</c-></code></a><sup>BMI2</sup>
      <td><a href="https://dougallj.github.io/asil/doc/bext_z_zz_64.html"><code class="highlight"><c- n>bext</c-></code></a><sup>SVE2</sup>
      <td>(<a href="https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#165-vector-compress-instruction"><code class="highlight"><c- n>vcompress</c-></code></a><sup>V</sup>)
     <tr>
      <td><code class="highlight"><c- n>bit_expandr</c-></code>
      <td><a href="https://www.felixcloutier.com/x86/pdep"><code class="highlight"><c- n>pdep</c-></code></a><sup>BMI2</sup>
      <td><a href="https://dougallj.github.io/asil/doc/bdep_z_zz_64.html"><code class="highlight"><c- n>bdep</c-></code></a><sup>SVE2</sup>
      <td>(<a href="https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#1651-synthesizing-vdecompress"><code class="highlight"><c- n>viota</c-></code>+<code class="highlight"><c- n>vrgather</c-></code></a><sup>V</sup>)
     <tr>
      <td><code class="highlight"><c- n>bit_compressl</c-></code>
      <td>(<a href="https://www.felixcloutier.com/x86/pext"><code class="highlight"><c- n>pext</c-></code></a><sup>BMI2</sup>+<a href="https://www.felixcloutier.com/x86/popcnt"><code class="highlight"><c- n>popcnt</c-></code></a><sup>ABM</sup>)
      <td><a href="https://dougallj.github.io/asil/doc/bgrp_z_zz_64.html"><code class="highlight"><c- n>bgrp</c-></code></a><sup>SVE2</sup>, (<a href="https://dougallj.github.io/asil/doc/bext_z_zz_64.html"><code class="highlight"><c- n>bext</c-></code></a><sup>SVE2</sup>+<a href="https://dougallj.github.io/asil/doc/cnt_z_p_z_64.html"><code class="highlight"><c- n>cnt</c-></code></a><sup>SVE</sup>)
      <td>(<a href="https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#165-vector-compress-instruction"><code class="highlight"><c- n>vcompress</c-></code></a><sup>V</sup>)
     <tr>
      <td><code class="highlight"><c- n>bit_expandl</c-></code>
      <td>(<a href="https://www.felixcloutier.com/x86/pdep"><code class="highlight"><c- n>pdep</c-></code></a><sup>BMI2</sup>+<a href="https://www.felixcloutier.com/x86/popcnt"><code class="highlight"><c- n>popcnt</c-></code></a><sup>ABM</sup>)
      <td>(<a href="https://dougallj.github.io/asil/doc/bdep_z_zz_64.html"><code class="highlight"><c- n>bdep</c-></code></a><sup>SVE2</sup>+<a href="https://dougallj.github.io/asil/doc/cnt_z_p_z_64.html"><code class="highlight"><c- n>cnt</c-></code></a><sup>SVE</sup>)
      <td>(<a href="https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#1651-synthesizing-vdecompress"><code class="highlight"><c- n>viota</c-></code>+<code class="highlight"><c- n>vrgather</c-></code></a><sup>V</sup>)
   </table>
   <p>(Parenthesized) entries signal that the instruction does not directly implement the function,
but greatly assists in its implementation.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The AVX-512 <code class="highlight"><c- n>vpshufbitqmb</c-></code> instruction can implement any bit permutation in the mathematical sense, and more.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The RISC-V <code class="highlight"><c- n>brev8</c-></code> instruction can also be found under the name <code class="highlight"><c- n>rev</c-><c- p>.</c-><c- n>b</c-></code>.
      There appears to have been a name change in 2022.</p>
   <h4 class="heading settled" data-level="4.3.1" id="hardware-support-reverse"><span class="secno">4.3.1. </span><span class="content">Support for <code class="highlight"><c- n>bit_reverse</c-></code></span><a class="self-link" href="#hardware-support-reverse"></a></h4>
   <p>This operation is directly implemented in ARM through <code class="highlight"><c- n>rbit</c-></code>.</p>
   <p>Any architecture with support for <code class="highlight"><c- n>byteswap</c-></code> (such as x86 with <code class="highlight"><c- n>bswap</c-></code>)
also supports bit-reversal in part. <a data-link-type="biblio" href="#biblio-warren1" title="Hacker&apos;s Delight, 2nd Edition">[Warren1]</a> presents an O(log n) algorithm which operates by swapping lower and upper <code class="highlight"><c- n>N</c-> <c- o>/</c-> <c- mi>2</c-></code>, ..., <code class="highlight"><c- mi>16</c-></code>, <code class="highlight"><c- mi>8</c-></code>, <code class="highlight"><c- mi>4</c-></code>, <code class="highlight"><c- mi>2</c-></code>, and <code class="highlight"><c- mi>1</c-></code> bits in parallel.
Byte-swapping implements these individual swaps up to 8 bits, requiring only three more
parallel swaps in software:</p>
<pre class="language-cpp highlight"><c- c1>// assuming a byte is an octet of bits, and assuming the width of x is a power of two</c->
<c- n>x</c-> <c- o>=</c-> <c- n>byteswap</c-><c- p>(</c-><c- n>x</c-><c- p>);</c->
<c- n>x</c-> <c- o>=</c-> <c- p>(</c-><c- n>x</c-> <c- o>&amp;</c-> <c- mh>0x0F0F0F0F</c-><c- p>)</c-> <c- o>&lt;&lt;</c->  <c- mi>4</c-> <c- o>|</c-> <c- p>(</c-><c- n>x</c-> <c- o>&amp;</c-> <c- mh>0xF0F0F0F0</c-><c- p>)</c-> <c- o>>></c->  <c- mi>4</c-><c- p>;</c-> <c- c1>// ... quartets of bits</c->
<c- n>x</c-> <c- o>=</c-> <c- p>(</c-><c- n>x</c-> <c- o>&amp;</c-> <c- mh>0x33333333</c-><c- p>)</c-> <c- o>&lt;&lt;</c->  <c- mi>2</c-> <c- o>|</c-> <c- p>(</c-><c- n>x</c-> <c- o>&amp;</c-> <c- mh>0xCCCCCCCC</c-><c- p>)</c-> <c- o>>></c->  <c- mi>2</c-><c- p>;</c-> <c- c1>// ... pairs of bits</c->
<c- n>x</c-> <c- o>=</c-> <c- p>(</c-><c- n>x</c-> <c- o>&amp;</c-> <c- mh>0x55555555</c-><c- p>)</c-> <c- o>&lt;&lt;</c->  <c- mi>1</c-> <c- o>|</c-> <c- p>(</c-><c- n>x</c-> <c- o>&amp;</c-> <c- mh>0xAAAAAAAA</c-><c- p>)</c-> <c- o>>></c->  <c- mi>1</c-><c- p>;</c-> <c- c1>// ... individual bits</c->
</pre>
   <p>It is worth noting that clang provides a cross-platform family of intrinsics. <a href="https://clang.llvm.org/docs/LanguageExtensions.html#builtin-bitreverse"><code class="highlight"><c- n>__builtin_bitreverse</c-></code></a> uses byte-swapping or bit-reversal instructions if possible.</p>
   <p>Such an intrinsic has been requested from GCC users a number of times in <a data-link-type="biblio" href="#biblio-gnu1" title="Bug 50481 - builtin to reverse the bit order">[GNU1]</a>.</p>
   <h4 class="heading settled" data-level="4.3.2" id="hardware-support-bit-repeat"><span class="secno">4.3.2. </span><span class="content">Support for <code class="highlight"><c- n>bit_repeat</c-></code></span><a class="self-link" href="#hardware-support-bit-repeat"></a></h4>
   <p>Firstly, note that for the pattern length, there are only up to <code class="highlight"><c- n>N</c-></code> relevant cases,
where <code class="highlight"><c- n>N</c-></code> is the operand width in bits.
It is feasible to <code class="highlight"><c- k>switch</c-></code> between these cases, where the length is constant in each case.</p>
   <p>While the AVX-512 instruction <code class="highlight"><c- n>vpshufbitqmb</c-></code> can be used for <em>all</em> cases, this is not the ideal
solution for most cases.
For very low or very great lengths, a naive solution is sufficient (and even optimal),
where we simply use <code class="highlight"><c- o>&lt;&lt;</c-></code> and <code class="highlight"><c- o>|</c-></code> to duplicate the pattern.
What actually matters is how often the pattern is repeated, i.e. <code class="highlight"><c- n>N</c-> <c- o>/</c-> <c- n>length</c-></code>.</p>
   <p>Specific cases like <code class="highlight"><c- n>bit_repeat</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mi>8</c-><c- p>)</c-></code>, <code class="highlight"><c- n>bit_repeat</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mi>16</c-><c- p>)</c-></code> can be implemented using
permutation/duplication/gather/broadcast instructions.</p>
   <p>However, note that the primary use of <code class="highlight"><c- n>bit_repeat</c-></code> is to express repeating bit patterns without magic numbers,
i.e. to improve code quality.
Often, both the pattern and the length are known at compile-time, making hardware support less relevant.
Even without hardware support, the reference implementation <a data-link-type="biblio" href="#biblio-schultke1" title="C++26 Bit Permutations">[Schultke1]</a> requires only O(log N)
fundamental bitwise operations.</p>
   <h4 class="heading settled" data-level="4.3.3" id="hardware-support-next-bit-permutation"><span class="secno">4.3.3. </span><span class="content">Support for <code class="highlight"><c- n>next_bit_permutation</c-></code></span><a class="self-link" href="#hardware-support-next-bit-permutation"></a></h4>
   <p>The next permutation can be efficiently obtained if the platform has a "count trailing zeros"
instruction.
Integer division can also be used as a fallback, although software computation of trailing zeros
may be faster than integer division.</p>
   <p>Both options are shown in <a data-link-type="biblio" href="#biblio-anderson1" title="Bit Twiddling Hacks">[Anderson1]</a>, and one is implemented in <a data-link-type="biblio" href="#biblio-schultke1" title="C++26 Bit Permutations">[Schultke1]</a>.</p>
   <p><code class="highlight"><c- n>prev_bit_permutation</c-></code> can be accelerated using the same operation.</p>
   <h4 class="heading settled" data-level="4.3.4" id="hardware-support-compress-expand"><span class="secno">4.3.4. </span><span class="content">Support for <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></span><a class="self-link" href="#hardware-support-compress-expand"></a></h4>
   <p>Starting with Haswell (2013), Intel CPUs directly implement compression and expansion with
with <code class="highlight"><c- n>pext</c-></code> and <code class="highlight"><c- n>pdep</c-></code> respectively.
AMD CPUs starting with Zen 3 implement <code class="highlight"><c- n>pext</c-></code> and <code class="highlight"><c- n>pdep</c-></code> with 3 cycles
latency, like Intel.
Zen 2 and older implement <code class="highlight"><c- n>pext</c-></code>/<code class="highlight"><c- n>pdep</c-></code> in microcode, with 18 cycles latency.</p>
   <p>ARM also supports these operations directly with <code class="highlight"><c- n>bext</c-></code>, <code class="highlight"><c- n>bdep</c-></code>, and <code class="highlight"><c- n>bgrp</c-></code> in the SVE2 instruction set. <a data-link-type="biblio" href="#biblio-warren1" title="Hacker&apos;s Delight, 2nd Edition">[Warren1]</a> mentions other older architectures with direct support.</p>
   <p>Overall, only recent instruction set extensions offer this functionality directly.
However, when the mask is a constant, many different strategies for hardware acceleration open up.
For example</p>
   <ul>
    <li data-md>
     <p>interleaving bits can be assisted (though not fully implemented) using ARM <code class="highlight"><c- n>zip1</c-></code>/<code class="highlight"><c- n>zip2</c-></code></p>
    <li data-md>
     <p>other permutations can be assisted by ARM <code class="highlight"><c- n>tbl</c-></code> and <code class="highlight"><c- n>tbx</c-></code></p>
   </ul>
   <p>As <a data-link-type="biblio" href="#biblio-warren1" title="Hacker&apos;s Delight, 2nd Edition">[Warren1]</a> explains, the cost of computing <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code> in software is
dramatically lower for a constant mask.
For specific known masks (such as a mask with a single one-bit), the cost is extremely low.</p>
   <p>All in all, there are multiple factors that strongly suggest a standard library implementation:</p>
   <ol>
    <li data-md>
     <p>The strategy for computing <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code> depends greatly on the architecture
and on information about the mask, even if the exact mask isn’t known.</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>tzcnt</c-></code>, <code class="highlight"><c- n>clmul</c-></code> (see <a data-link-type="biblio" href="#biblio-schultke1" title="C++26 Bit Permutations">[Schultke1]</a> or <a data-link-type="biblio" href="#biblio-zp7" title="Zach&apos;s Peppy Parallel-Prefix-Popcountin&apos; PEXT/PDEP Polyfill">[Zp7]</a> for specifics), and <code class="highlight"><c- n>popcnt</c-></code> are helpful.</p>
     </ul>
    <li data-md>
     <p>ISO C++ does not offer a mechanism through which all of this information can be utilized.
Namely, it is not possible to change strategy based on information that only becomes available
during optimization passes.
Compiler extensions such as <code class="highlight"><c- n>__builtin_constant_p</c-></code> offer a workaround.</p>
    <li data-md>
     <p>ISO C++ does not offer a mechanism through which function implementations can be chosen
based on the surrounding context.
In a situation where multiple <code class="highlight"><c- n>bit_compress</c-></code> calls with the same mask <code class="highlight"><c- n>m</c-></code> are performed,
it is significantly faster to pre-compute information based on the mask once,
and utilize it in subsequent calls.
The same technique can be used to accelerate integer division for multiple divisions with the
same divisor.</p>
   </ol>
   <p>Bullets 2. and 3. suggest that <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code> benefit from being
implemented directly in the compiler via intrinsic,
even if hardware does not directly implement these operations.</p>
   <p>Even with a complete lack of hardware support, a software implementation of <code class="highlight"><c- n>compress_bitsr</c-></code> in <a data-link-type="biblio" href="#biblio-schultke1" title="C++26 Bit Permutations">[Schultke1]</a> emits essentially optimal code if the mask is known.</p>
   <div class="example" id="example-f2905923">
    <a class="self-link" href="#example-f2905923"></a> 
<pre class="language-cpp highlight"><c- b>unsigned</c-> <c- nf>bit_compress_known_mask</c-><c- p>(</c-><c- b>unsigned</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>cxx26bp</c-><c- o>::</c-><c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mh>0xf0f0u</c-><c- p>);</c->
<c- p>}</c->
</pre>
    <p>Clang 18 emits the following (and GCC virtually the same); see <a data-link-type="biblio" href="#biblio-compilerexplorer1" title="Compiler Explorer example for bit_compressr">[CompilerExplorer1]</a>:</p>
<pre class="language-asm highlight"><c- nf>bit_compress_known_mask</c-><c- p>(</c-><c- no>unsigned</c-> <c- no>int</c-><c- p>):</c-> <c- c1># bit_compress_known_mask(unsigned int edi)</c->
        <c- nf>mov</c->     <c- no>eax</c-><c- p>,</c-> <c- no>edi</c->               <c- c1># {   unsigned int eax = edi;</c->
        <c- nf>shr</c->     <c- no>eax</c-><c- p>,</c-> <c- mi>4</c->                 <c- c1>#     eax >>= 4;</c->
        <c- nf>and</c->     <c- no>eax</c-><c- p>,</c-> <c- mi>15</c->                <c- c1>#     eax &amp;= 0xf;</c->
        <c- nf>shr</c->     <c- no>edi</c-><c- p>,</c-> <c- mi>8</c->                 <c- c1>#     edi >>= 8;</c->
        <c- nf>and</c->     <c- no>edi</c-><c- p>,</c-> <c- mi>240</c->               <c- c1>#     edi &amp;= 0xf0;</c->
        <c- nf>or</c->      <c- no>eax</c-><c- p>,</c-> <c- no>edi</c->               <c- c1>#     eax |= edi;</c->
        <c- nf>ret</c->                            <c- c1>#     return eax; }</c->
</pre>
    <p>Knowing the implementation of <code class="highlight"><c- n>bit_compressr</c-></code>, this feels like dark magic.
This is an optimizing compiler at its finest hour.</p>
   </div>
   <h2 class="heading settled" data-level="5" id="impact-on-existing-code"><span class="secno">5. </span><span class="content">Impact on existing code</span><a class="self-link" href="#impact-on-existing-code"></a></h2>
   <p>This proposal is purely a standard library expansion.
No existing code is affected.</p>
   <h2 class="heading settled" data-level="6" id="design"><span class="secno">6. </span><span class="content">Design considerations</span><a class="self-link" href="#design"></a></h2>
   <p>The design choices in this paper are based on <a data-link-type="biblio" href="#biblio-p0553r4" title="Bit operations">[P0553R4]</a>, wherever applicable.</p>
   <h3 class="heading settled" data-level="6.1" id="bit-repeat-signature"><span class="secno">6.1. </span><span class="content">Signature of <code class="highlight"><c- n>bit_repeat</c-></code></span><a class="self-link" href="#bit-repeat-signature"></a></h3>
   <p><code class="highlight"><c- n>bit_repeat</c-></code> follows the "use <code class="highlight"><c- b>int</c-></code> if possible" rule mentioned in <a data-link-type="biblio" href="#biblio-p0553r4" title="Bit operations">[P0553R4]</a>.
Other functions such as <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>rotl</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>rotr</c-></code> also accept an <code class="highlight"><c- b>int</c-></code>.</p>
   <p>It is also the only function not marked <code class="highlight"><c- k>noexcept</c-></code>.
It does not throw, but it is not <code class="highlight"><c- k>noexcept</c-></code> due to its narrow contract (Lakos rule).</p>
   <h3 class="heading settled" data-level="6.2" id="naming-compress-expand"><span class="secno">6.2. </span><span class="content">Why the names <em>compress</em> and <em>expand</em>?</span><a class="self-link" href="#naming-compress-expand"></a></h3>
   <p>The use of <code class="highlight"><c- n>compress</c-></code> and <code class="highlight"><c- n>expand</c-></code> is consistent with the mask-based permutations for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>simd</c-></code> proposed in <a data-link-type="biblio" href="#biblio-p2664r6" title="Extend std::simd with permutation API">[P2664R6]</a>.</p>
   <p>Furthermore, there are multiple synonymous sets of terminology:</p>
   <ol>
    <li data-md>
     <p><code class="highlight"><c- n>deposit</c-></code> and <code class="highlight"><c- n>extract</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>compress</c-></code> and <code class="highlight"><c- n>expand</c-></code></p>
    <li data-md>
     <p><code class="highlight"><c- n>gather</c-></code> and <code class="highlight"><c- n>scatter</c-></code></p>
   </ol>
   <p>I have decided against <code class="highlight"><c- n>deposit</c-></code> and <code class="highlight"><c- n>extract</c-></code> because of its ambiguity:</p>
   <p>Taking the input <code class="highlight"><c- mb>0b10101</c-></code> and densely packing it to <code class="highlight"><c- mb>0b111</c-></code> could be described as:</p>
   <blockquote>
    <p>Extract each second bit from <code class="highlight"><c- mb>0b10101</c-></code> and densely deposit it into the result.</p>
   </blockquote>
   <p>Similarly, taking the input <code class="highlight"><c- mb>0b111</c-></code> and expanding it into <code class="highlight"><c- mb>0b10101</c-></code> could be described as:</p>
   <blockquote>
    <p>Extract each bit from <code class="highlight"><c- mb>0b111</c-></code> and sparsely deposit it in the result.</p>
   </blockquote>
   <p>Both operations can be described with <code class="highlight"><c- n>extract</c-></code> and <code class="highlight"><c- n>deposit</c-></code> terminology,
making it virtually useless for keeping the operations apart. <code class="highlight"><c- n>gather</c-></code> and <code class="highlight"><c- n>scatter</c-></code> are simply the least common way to describe these operations, which makes <code class="highlight"><c- n>compress</c-></code> and <code class="highlight"><c- n>expand</c-></code> the best candidates.</p>
   <p>Further design choices are consistent with <a data-link-type="biblio" href="#biblio-p0553r4" title="Bit operations">[P0553R4]</a>.
The abbreviations <code class="highlight"><c- n>l</c-></code> and <code class="highlight"><c- n>r</c-></code> for left/right are consistent with <code class="highlight"><c- n>rotl</c-></code>/<code class="highlight"><c- n>rotr</c-></code>.
The prefix <code class="highlight"><c- n>bit_</c-></code> is consistent with <code class="highlight"><c- n>bit_floor</c-></code> and <code class="highlight"><c- n>bit_ceil</c-></code>.</p>
   <h3 class="heading settled" data-level="6.3" id="further-generalization"><span class="secno">6.3. </span><span class="content">Why the lack of generalization?</span><a class="self-link" href="#further-generalization"></a></h3>
   <h4 class="heading settled" data-level="6.3.1" id="generalized-compress-expand"><span class="secno">6.3.1. </span><span class="content">No generalized <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></span><a class="self-link" href="#generalized-compress-expand"></a></h4>
   <p><a data-link-type="biblio" href="#biblio-n3864" title="A constexpr bitwise operations library for C++">[N3864]</a> originally suggested much more general versions of compression and expansion,
which support:</p>
   <ol>
    <li data-md>
     <p>performing the operation not just on the whole operand, but on "words" of it, in parallel</p>
    <li data-md>
     <p>performing the operation not just on bits, but on arbitrarily sized groups of bits</p>
   </ol>
   <p><strong>I don’t propose this generality</strong> for the following reasons:</p>
   <ol>
    <li data-md>
     <p>The utility functions in <code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code> are not meant to provide a full bitwise manipulation library,
but fundamental operations, especially those that can be accelerated
in hardware while still having reasonable software fallbacks.</p>
    <li data-md>
     <p>These more general form can be built on top of the proposed hardware-oriented versions.
This can be done with relative ease and with little to no overhead.</p>
    <li data-md>
     <p>The generality falsely suggests hardware support for all forms, despite the function only being
accelerated for specific inputs.
This makes the performance characteristics unpredictable.</p>
    <li data-md>
     <p>The proposed functions have wide contracts and can be <code class="highlight"><c- k>noexcept</c-></code> (Lakos rule).
Adding additional parameters would likely require a narrow contract.</p>
    <li data-md>
     <p>Generality adds complexity to the standardization process, to implementation,
and from the perspective of language users.
It is unclear whether this added complexity is worth it in this case.</p>
   </ol>
   <h4 class="heading settled" data-level="6.3.2" id="generalized-bit-reverse"><span class="secno">6.3.2. </span><span class="content">No generalized <code class="highlight"><c- n>bit_reverse</c-></code></span><a class="self-link" href="#generalized-bit-reverse"></a></h4>
   <p>Bit reversal can also be generalized to work with any group size:</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- nc>T</c-><c- o>></c->
<c- n>T</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- b>int</c-> <c- n>group_size</c-> <c- o>=</c-> <c- mi>1</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>(</c->false<c- p>);</c->
</pre>
   <p>With this generalization, <code class="highlight"><c- n>byteswap</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code> on conventional platforms
is equivalent to <code class="highlight"><c- n>bit_reverse</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- mi>8</c-><c- p>)</c-></code>.</p>
   <p>However, this general version is much less used, not as consistently supported in
hardware, and has a narrow contract. <code class="highlight"><c- n>group_size</c-></code> must be a nonzero factor of <code class="highlight"><c- n>x</c-></code> for this operation to be meaningful.</p>
   <p>Therefore, a generalized bit-reversal is not proposed in this paper.</p>
   <h3 class="heading settled" data-level="6.4" id="unusual-signature"><span class="secno">6.4. </span><span class="content">Why does the signature of <code class="highlight"><c- n>bit_compress</c-></code> require two same <code class="highlight"><c- n>T</c-></code>s?</span><a class="self-link" href="#unusual-signature"></a></h3>
   <p>Initially, I went through a number of different signatures.</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- p>,</c-> <c- n>unsigned_integral</c-> <c- n>X</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>X</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   <p>This signature is quite clever because the result never has more bits than the mask <code class="highlight"><c- n>m</c-></code>.
However, it is surprising that the mask plays such a significant role here.</p>
   <p>Furthermore, I’ve realized that while the result never has more bits than <code class="highlight"><c- n>m</c-></code>, <code class="highlight"><c- n>bit_compressl</c-></code> must still deposit bits starting with the most significant bits of the result.
This suggests the following:</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- p>,</c-> <c- n>unsigned_integral</c-> <c- n>X</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>common_type_t</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>X</c-><c- o>></c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>X</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   <p>However, it is not trivial to juggle bits between the left and right versions of <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code>.
The behavior is also not intuitive when a zero-extension occurs.
For wider <code class="highlight"><c- n>x</c-></code>, the mask is always zero-extended to the left, which makes the left and right
versions slightly asymmetrical.</p>
   <p>Since this proposal includes low-level bit operations, it is reasonable and safe to require
the user to be explicit.
A call to <code class="highlight"><c- n>bit_compress</c-></code> or <code class="highlight"><c- n>bit_expand</c-></code> with two different types is likely a design flaw or bug.
Therefore, I have settled on the very simple signature:</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
   <h2 class="heading settled" data-level="7" id="possible-implementation"><span class="secno">7. </span><span class="content">Possible implementation</span><a class="self-link" href="#possible-implementation"></a></h2>
   <h3 class="heading settled" data-level="7.1" id="reference-implementation"><span class="secno">7.1. </span><span class="content">Reference implementation</span><a class="self-link" href="#reference-implementation"></a></h3>
   <p>All proposed functions have been implemented in <a data-link-type="biblio" href="#biblio-schultke1" title="C++26 Bit Permutations">[Schultke1]</a>.
This reference implementation is compatible with all three major compilers,
and leverages hardware support from ARM and x86_64 where possible.</p>
   <h3 class="heading settled" data-level="7.2" id="contemporary-implementations"><span class="secno">7.2. </span><span class="content">Other implementations</span><a class="self-link" href="#contemporary-implementations"></a></h3>
   <p><a data-link-type="biblio" href="#biblio-warren1" title="Hacker&apos;s Delight, 2nd Edition">[Warren1]</a> presents algorithms which are the basis for <a data-link-type="biblio" href="#biblio-schultke1" title="C++26 Bit Permutations">[Schultke1]</a>.</p>
   <ul>
    <li data-md>
     <p>An O(log n) <code class="highlight"><c- n>bit_reverse</c-></code></p>
    <li data-md>
     <p>An O(log<sup>2</sup> n) <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code></p>
     <ul>
      <li data-md>
       <p>can be O(log n) with hardware support for
 carry-less multiplication aka. GF(2) polynomial multiplication</p>
     </ul>
   </ul>
   <p><a data-link-type="biblio" href="#biblio-zp7" title="Zach&apos;s Peppy Parallel-Prefix-Popcountin&apos; PEXT/PDEP Polyfill">[Zp7]</a> offers fast software implementations for <code class="highlight"><c- n>pext</c-></code> and <code class="highlight"><c- n>pdep</c-></code>, optimized for x86_64.</p>
   <p><a data-link-type="biblio" href="#biblio-stackoverflow1" title="What is a fast fallback algorithm which emulates PDEP and PEXT in software?">[StackOverflow1]</a> contains discussion of various possible software implementations
of <code class="highlight"><c- n>bit_compressr</c-></code> and <code class="highlight"><c- n>bit_expandr</c-></code>.</p>
   <h2 class="heading settled" data-level="8" id="proposed-wording"><span class="secno">8. </span><span class="content">Proposed wording</span><a class="self-link" href="#proposed-wording"></a></h2>
   <p>The proposed changes are relative to the working draft of the standard as of <a data-link-type="biblio" href="#biblio-n4917" title="Working Draft, Standard for Programming Language C++">[N4917]</a>.</p>
   <h3 class="heading settled" data-level="8.1" id="proposed-feature-testing"><span class="secno">8.1. </span><span class="content">Feature-testing</span><a class="self-link" href="#proposed-feature-testing"></a></h3>
   <p>In subclause 17.3.2 [version.syn] paragraph 2, update the synopsis as follows:</p>
   <blockquote>
<pre class="highlight"><code><c- cp>#define __cpp_lib_bitops                    </c-><del><c- cp>201907L</c-></del><ins><c- cp>20XXXXL</c-></ins><c- cp> </c-><c- c1>// freestanding, also in &lt;bit></c->
</code></pre>
   </blockquote>
   <h3 class="heading settled" data-level="8.2" id="proposed-header-synopsis"><span class="secno">8.2. </span><span class="content">Header synopsis</span><a class="self-link" href="#proposed-header-synopsis"></a></h3>
   <p>In subclause 22.15.2 [bit.syn], update the synopsis as follows:</p>
   <blockquote>
<pre class="highlight"><code><ins><c- o>+</c-> <c- c1>// 22.15.X, permutations</c->
<c- o>+</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- o>+</c->   <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
<c- o>+</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- o>+</c->   <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_repeat</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- b>int</c-> <c- n>l</c-><c- p>);</c->
<c- o>+</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- o>+</c->   <c- k>constexpr</c-> <c- n>T</c-> <c- n>next_bit_permutation</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
<c- o>+</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- o>+</c->   <c- k>constexpr</c-> <c- n>T</c-> <c- n>prev_bit_permutation</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
<c- o>+</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- o>+</c->   <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
<c- o>+</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- o>+</c->   <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_expandr</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
<c- o>+</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- o>+</c->   <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_compressl</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
<c- o>+</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<c- o>+</c->   <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_expandl</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</ins></code></pre>
   </blockquote>
   <h3 class="heading settled" data-level="8.3" id="proposed-new-subclause"><span class="secno">8.3. </span><span class="content">New subclause</span><a class="self-link" href="#proposed-new-subclause"></a></h3>
   <p>In subclause 22.15 [bit], add the following subclause:</p>
   <blockquote>
    <p> <strong>22.15.X Permutation [bit.permute]</strong> </p>
    <p> 1 In the following descriptions, let <em>N</em> denote <code class="highlight"><c- n>numeric_limits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c->​<c- o>::</c->​<c- n>digits</c-></code>.
    Let α<sub><em>n</em></sub> denote the <em>n</em>-th least significant bit of <code class="highlight"><c- n>α</c-></code>, so that <code class="highlight"><c- n>α</c-></code> equals <span title="\sum_{n=0}^{N-1}{\alpha_n 2^n}"> <svg alt="\sum_{n=0}^{N-1}{\alpha_n 2^n}" aria-hidden="true" height="53.920px" viewBox="0 -1733 3852.8 2978.9" width="69.736px" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><path d="M60 948Q63 950 665 950H1267L1325 815Q1384 677 1388 669H1348L1341 683Q1320 724 1285 761Q1235 809 1174 838T1033 881T882 898T699 902H574H543H251L259 891Q722 258 724 252Q725 250 724 246Q721 243 460 -56L196 -356Q196 -357 407 -357Q459 -357 548 -357T676 -358Q812 -358 896 -353T1063 -332T1204 -283T1307 -196Q1328 -170 1348 -124H1388Q1388 -125 1381 -145T1356 -210T1325 -294L1267 -449L666 -450Q64 -450 61 -448Q55 -446 55 -439Q55 -437 57 -433L590 177Q590 178 557 222T452 366T322 544L56 909L55 924Q55 945 60 948Z" id="MJX-13-TEX-LO-2211"></path><path d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z" id="MJX-13-TEX-I-1D45B"></path><path d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z" id="MJX-13-TEX-N-3D"></path><path d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z" id="MJX-13-TEX-N-30"></path><path d="M234 637Q231 637 226 637Q201 637 196 638T191 649Q191 676 202 682Q204 683 299 683Q376 683 387 683T401 677Q612 181 616 168L670 381Q723 592 723 606Q723 633 659 637Q635 637 635 648Q635 650 637 660Q641 676 643 679T653 683Q656 683 684 682T767 680Q817 680 843 681T873 682Q888 682 888 672Q888 650 880 642Q878 637 858 637Q787 633 769 597L620 7Q618 0 599 0Q585 0 582 2Q579 5 453 305L326 604L261 344Q196 88 196 79Q201 46 268 46H278Q284 41 284 38T282 19Q278 6 272 0H259Q228 2 151 2Q123 2 100 2T63 2T46 1Q31 1 31 10Q31 14 34 26T39 40Q41 46 62 46Q130 49 150 85Q154 91 221 362L289 634Q287 635 234 637Z" id="MJX-13-TEX-I-1D441"></path><path d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z" id="MJX-13-TEX-N-2212"></path><path d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z" id="MJX-13-TEX-N-31"></path><path d="M34 156Q34 270 120 356T309 442Q379 442 421 402T478 304Q484 275 485 237V208Q534 282 560 374Q564 388 566 390T582 393Q603 393 603 385Q603 376 594 346T558 261T497 161L486 147L487 123Q489 67 495 47T514 26Q528 28 540 37T557 60Q559 67 562 68T577 70Q597 70 597 62Q597 56 591 43Q579 19 556 5T512 -10H505Q438 -10 414 62L411 69L400 61Q390 53 370 41T325 18T267 -2T203 -11Q124 -11 79 39T34 156ZM208 26Q257 26 306 47T379 90L403 112Q401 255 396 290Q382 405 304 405Q235 405 183 332Q156 292 139 224T121 120Q121 71 146 49T208 26Z" id="MJX-13-TEX-I-1D6FC"></path><path d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z" id="MJX-13-TEX-N-32"></path></defs><g fill="currentColor" stroke="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="munderover"><g data-mml-node="mo" transform="translate(43.8,0)"><use data-c="2211" href="#MJX-13-TEX-LO-2211"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(101.8,-1087.9) scale(0.707)"><g data-mml-node="mi"><use data-c="1D45B" href="#MJX-13-TEX-I-1D45B"></use></g><g data-mml-node="mo" transform="translate(600,0)"><use data-c="3D" href="#MJX-13-TEX-N-3D"></use></g><g data-mml-node="mn" transform="translate(1378,0)"><use data-c="30" href="#MJX-13-TEX-N-30"></use></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(0,1150) scale(0.707)"><g data-mml-node="mi"><use data-c="1D441" href="#MJX-13-TEX-I-1D441"></use></g><g data-mml-node="mo" transform="translate(888,0)"><use data-c="2212" href="#MJX-13-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(1666,0)"><use data-c="31" href="#MJX-13-TEX-N-31"></use></g></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1698.3,0)"><g data-mml-node="msub"><g data-mml-node="mi"><use data-c="1D6FC" href="#MJX-13-TEX-I-1D6FC"></use></g><g data-mml-node="mi" transform="translate(673,-150) scale(0.707)"><use data-c="1D45B" href="#MJX-13-TEX-I-1D45B"></use></g></g><g data-mml-node="msup" transform="translate(1147.3,0)"><g data-mml-node="mn"><use data-c="32" href="#MJX-13-TEX-N-32"></use></g><g data-mml-node="mi" transform="translate(533,413) scale(0.707)"><use data-c="1D45B" href="#MJX-13-TEX-I-1D45B"></use></g></g></g></g></g></svg> </span> </p>
    <p></p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
    <p></p>
    <p class="indent"> 2 <em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]). </p>
    <p class="indent"> 3 <em>Returns</em>: <span title="\sum_{n=0}^{N-1}{x_n 2^{N-n-1}}"> <svg alt="\sum_{n=0}^{N-1}{x_n 2^{N-n-1}}" aria-hidden="true" height="53.920px" viewBox="0 -1733 5866.5 2978.9" width="106.184px" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><path d="M60 948Q63 950 665 950H1267L1325 815Q1384 677 1388 669H1348L1341 683Q1320 724 1285 761Q1235 809 1174 838T1033 881T882 898T699 902H574H543H251L259 891Q722 258 724 252Q725 250 724 246Q721 243 460 -56L196 -356Q196 -357 407 -357Q459 -357 548 -357T676 -358Q812 -358 896 -353T1063 -332T1204 -283T1307 -196Q1328 -170 1348 -124H1388Q1388 -125 1381 -145T1356 -210T1325 -294L1267 -449L666 -450Q64 -450 61 -448Q55 -446 55 -439Q55 -437 57 -433L590 177Q590 178 557 222T452 366T322 544L56 909L55 924Q55 945 60 948Z" id="MJX-46-TEX-LO-2211"></path><path d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z" id="MJX-46-TEX-I-1D45B"></path><path d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z" id="MJX-46-TEX-N-3D"></path><path d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z" id="MJX-46-TEX-N-30"></path><path d="M234 637Q231 637 226 637Q201 637 196 638T191 649Q191 676 202 682Q204 683 299 683Q376 683 387 683T401 677Q612 181 616 168L670 381Q723 592 723 606Q723 633 659 637Q635 637 635 648Q635 650 637 660Q641 676 643 679T653 683Q656 683 684 682T767 680Q817 680 843 681T873 682Q888 682 888 672Q888 650 880 642Q878 637 858 637Q787 633 769 597L620 7Q618 0 599 0Q585 0 582 2Q579 5 453 305L326 604L261 344Q196 88 196 79Q201 46 268 46H278Q284 41 284 38T282 19Q278 6 272 0H259Q228 2 151 2Q123 2 100 2T63 2T46 1Q31 1 31 10Q31 14 34 26T39 40Q41 46 62 46Q130 49 150 85Q154 91 221 362L289 634Q287 635 234 637Z" id="MJX-46-TEX-I-1D441"></path><path d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z" id="MJX-46-TEX-N-2212"></path><path d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z" id="MJX-46-TEX-N-31"></path><path d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z" id="MJX-46-TEX-I-1D465"></path><path d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z" id="MJX-46-TEX-N-32"></path></defs><g fill="currentColor" stroke="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="munderover"><g data-mml-node="mo" transform="translate(43.8,0)"><use data-c="2211" href="#MJX-46-TEX-LO-2211"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(101.8,-1087.9) scale(0.707)"><g data-mml-node="mi"><use data-c="1D45B" href="#MJX-46-TEX-I-1D45B"></use></g><g data-mml-node="mo" transform="translate(600,0)"><use data-c="3D" href="#MJX-46-TEX-N-3D"></use></g><g data-mml-node="mn" transform="translate(1378,0)"><use data-c="30" href="#MJX-46-TEX-N-30"></use></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(0,1150) scale(0.707)"><g data-mml-node="mi"><use data-c="1D441" href="#MJX-46-TEX-I-1D441"></use></g><g data-mml-node="mo" transform="translate(888,0)"><use data-c="2212" href="#MJX-46-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(1666,0)"><use data-c="31" href="#MJX-46-TEX-N-31"></use></g></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1698.3,0)"><g data-mml-node="msub"><g data-mml-node="mi"><use data-c="1D465" href="#MJX-46-TEX-I-1D465"></use></g><g data-mml-node="mi" transform="translate(605,-150) scale(0.707)"><use data-c="1D45B" href="#MJX-46-TEX-I-1D45B"></use></g></g><g data-mml-node="msup" transform="translate(1079.3,0)"><g data-mml-node="mn"><use data-c="32" href="#MJX-46-TEX-N-32"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(533,413) scale(0.707)"><g data-mml-node="mi"><use data-c="1D441" href="#MJX-46-TEX-I-1D441"></use></g><g data-mml-node="mo" transform="translate(888,0)"><use data-c="2212" href="#MJX-46-TEX-N-2212"></use></g><g data-mml-node="mi" transform="translate(1666,0)"><use data-c="1D45B" href="#MJX-46-TEX-I-1D45B"></use></g><g data-mml-node="mo" transform="translate(2266,0)"><use data-c="2212" href="#MJX-46-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(3044,0)"><use data-c="31" href="#MJX-46-TEX-N-31"></use></g></g></g></g></g></g></svg> </span> <br>[<em>Note</em>: <code class="highlight"><c- n>bit_reverse</c-><c- p>(</c-><c- n>bit_reverse</c-><c- p>(</c-><c- n>x</c-><c- p>))</c-></code> equals <code class="highlight"><c- n>x</c-></code>. — <em>end note</em>] </p>
    <p></p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_repeat</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- b>int</c-> <c- n>l</c-><c- p>);</c->
</pre>
    <p></p>
    <p class="indent"> 4 <em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]). </p>
    <p class="indent"> 5 <em>Preconditions</em>: <code class="highlight"><c- n>l</c-></code> is greater than zero. </p>
    <p class="indent"> 6 <em>Returns</em>: <span title="\sum_{n=0}^{N-1}{x_{(n \mod l)} 2^{N}}"> <svg alt="\sum_{n=0}^{N-1}{x_{(n \mod l)} 2^{N}}" aria-hidden="true" height="53.920px" viewBox="0 -1733 7126.3 2978.9" width="128.984px" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><path d="M60 948Q63 950 665 950H1267L1325 815Q1384 677 1388 669H1348L1341 683Q1320 724 1285 761Q1235 809 1174 838T1033 881T882 898T699 902H574H543H251L259 891Q722 258 724 252Q725 250 724 246Q721 243 460 -56L196 -356Q196 -357 407 -357Q459 -357 548 -357T676 -358Q812 -358 896 -353T1063 -332T1204 -283T1307 -196Q1328 -170 1348 -124H1388Q1388 -125 1381 -145T1356 -210T1325 -294L1267 -449L666 -450Q64 -450 61 -448Q55 -446 55 -439Q55 -437 57 -433L590 177Q590 178 557 222T452 366T322 544L56 909L55 924Q55 945 60 948Z" id="MJX-38-TEX-LO-2211"></path><path d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z" id="MJX-38-TEX-I-1D45B"></path><path d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z" id="MJX-38-TEX-N-3D"></path><path d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z" id="MJX-38-TEX-N-30"></path><path d="M234 637Q231 637 226 637Q201 637 196 638T191 649Q191 676 202 682Q204 683 299 683Q376 683 387 683T401 677Q612 181 616 168L670 381Q723 592 723 606Q723 633 659 637Q635 637 635 648Q635 650 637 660Q641 676 643 679T653 683Q656 683 684 682T767 680Q817 680 843 681T873 682Q888 682 888 672Q888 650 880 642Q878 637 858 637Q787 633 769 597L620 7Q618 0 599 0Q585 0 582 2Q579 5 453 305L326 604L261 344Q196 88 196 79Q201 46 268 46H278Q284 41 284 38T282 19Q278 6 272 0H259Q228 2 151 2Q123 2 100 2T63 2T46 1Q31 1 31 10Q31 14 34 26T39 40Q41 46 62 46Q130 49 150 85Q154 91 221 362L289 634Q287 635 234 637Z" id="MJX-38-TEX-I-1D441"></path><path d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z" id="MJX-38-TEX-N-2212"></path><path d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z" id="MJX-38-TEX-N-31"></path><path d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z" id="MJX-38-TEX-I-1D465"></path><path d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z" id="MJX-38-TEX-N-28"></path><path d="M41 46H55Q94 46 102 60V68Q102 77 102 91T102 122T103 161T103 203Q103 234 103 269T102 328V351Q99 370 88 376T43 385H25V408Q25 431 27 431L37 432Q47 433 65 434T102 436Q119 437 138 438T167 441T178 442H181V402Q181 364 182 364T187 369T199 384T218 402T247 421T285 437Q305 442 336 442Q351 442 364 440T387 434T406 426T421 417T432 406T441 395T448 384T452 374T455 366L457 361L460 365Q463 369 466 373T475 384T488 397T503 410T523 422T546 432T572 439T603 442Q729 442 740 329Q741 322 741 190V104Q741 66 743 59T754 49Q775 46 803 46H819V0H811L788 1Q764 2 737 2T699 3Q596 3 587 0H579V46H595Q656 46 656 62Q657 64 657 200Q656 335 655 343Q649 371 635 385T611 402T585 404Q540 404 506 370Q479 343 472 315T464 232V168V108Q464 78 465 68T468 55T477 49Q498 46 526 46H542V0H534L510 1Q487 2 460 2T422 3Q319 3 310 0H302V46H318Q379 46 379 62Q380 64 380 200Q379 335 378 343Q372 371 358 385T334 402T308 404Q263 404 229 370Q202 343 195 315T187 232V168V108Q187 78 188 68T191 55T200 49Q221 46 249 46H265V0H257L234 1Q210 2 183 2T145 3Q42 3 33 0H25V46H41Z" id="MJX-38-TEX-N-6D"></path><path d="M28 214Q28 309 93 378T250 448Q340 448 405 380T471 215Q471 120 407 55T250 -10Q153 -10 91 57T28 214ZM250 30Q372 30 372 193V225V250Q372 272 371 288T364 326T348 362T317 390T268 410Q263 411 252 411Q222 411 195 399Q152 377 139 338T126 246V226Q126 130 145 91Q177 30 250 30Z" id="MJX-38-TEX-N-6F"></path><path d="M376 495Q376 511 376 535T377 568Q377 613 367 624T316 637H298V660Q298 683 300 683L310 684Q320 685 339 686T376 688Q393 689 413 690T443 693T454 694H457V390Q457 84 458 81Q461 61 472 55T517 46H535V0Q533 0 459 -5T380 -11H373V44L365 37Q307 -11 235 -11Q158 -11 96 50T34 215Q34 315 97 378T244 442Q319 442 376 393V495ZM373 342Q328 405 260 405Q211 405 173 369Q146 341 139 305T131 211Q131 155 138 120T173 59Q203 26 251 26Q322 26 373 103V342Z" id="MJX-38-TEX-N-64"></path><path d="M117 59Q117 26 142 26Q179 26 205 131Q211 151 215 152Q217 153 225 153H229Q238 153 241 153T246 151T248 144Q247 138 245 128T234 90T214 43T183 6T137 -11Q101 -11 70 11T38 85Q38 97 39 102L104 360Q167 615 167 623Q167 626 166 628T162 632T157 634T149 635T141 636T132 637T122 637Q112 637 109 637T101 638T95 641T94 647Q94 649 96 661Q101 680 107 682T179 688Q194 689 213 690T243 693T254 694Q266 694 266 686Q266 675 193 386T118 83Q118 81 118 75T117 65V59Z" id="MJX-38-TEX-I-1D459"></path><path d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z" id="MJX-38-TEX-N-29"></path><path d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z" id="MJX-38-TEX-N-32"></path></defs><g fill="currentColor" stroke="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="munderover"><g data-mml-node="mo" transform="translate(43.8,0)"><use data-c="2211" href="#MJX-38-TEX-LO-2211"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(101.8,-1087.9) scale(0.707)"><g data-mml-node="mi"><use data-c="1D45B" href="#MJX-38-TEX-I-1D45B"></use></g><g data-mml-node="mo" transform="translate(600,0)"><use data-c="3D" href="#MJX-38-TEX-N-3D"></use></g><g data-mml-node="mn" transform="translate(1378,0)"><use data-c="30" href="#MJX-38-TEX-N-30"></use></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(0,1150) scale(0.707)"><g data-mml-node="mi"><use data-c="1D441" href="#MJX-38-TEX-I-1D441"></use></g><g data-mml-node="mo" transform="translate(888,0)"><use data-c="2212" href="#MJX-38-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(1666,0)"><use data-c="31" href="#MJX-38-TEX-N-31"></use></g></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1698.3,0)"><g data-mml-node="msub"><g data-mml-node="mi"><use data-c="1D465" href="#MJX-38-TEX-I-1D465"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(605,-176.7) scale(0.707)"><g data-mml-node="mo"><use data-c="28" href="#MJX-38-TEX-N-28"></use></g><g data-mml-node="mi" transform="translate(389,0)"><use data-c="1D45B" href="#MJX-38-TEX-I-1D45B"></use></g><g data-mml-node="mspace" transform="translate(989,0)"></g><g data-mml-node="mi" transform="translate(1822.7,0)"><use data-c="6D" href="#MJX-38-TEX-N-6D"></use><use data-c="6F" transform="translate(833,0)" href="#MJX-38-TEX-N-6F"></use><use data-c="64" transform="translate(1333,0)" href="#MJX-38-TEX-N-64"></use></g><g data-mml-node="mstyle" transform="translate(3711.7,0) scale(1.414)"><g data-mml-node="mspace"></g></g><g data-mml-node="mstyle" transform="translate(3947.8,0) scale(1.414)"><g data-mml-node="mspace"></g></g><g data-mml-node="mi" transform="translate(4350.7,0)"><use data-c="1D459" href="#MJX-38-TEX-I-1D459"></use></g><g data-mml-node="mo" transform="translate(4648.7,0)"><use data-c="29" href="#MJX-38-TEX-N-29"></use></g></g></g><g data-mml-node="msup" transform="translate(4217.2,0)"><g data-mml-node="mn"><use data-c="32" href="#MJX-38-TEX-N-32"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(533,413) scale(0.707)"><g data-mml-node="mi"><use data-c="1D441" href="#MJX-38-TEX-I-1D441"></use></g></g></g></g></g></g></svg> </span> </p>
    <p class="indent"> 7 <em>Throws</em>: Nothing. </p>
    <p></p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>T</c-> <c- n>next_bit_permutation</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
    <p></p>
    <p class="indent"> 8 <em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]). </p>
    <p class="indent"> 9 <em>Returns</em>: The lowest integer <code class="highlight"><c- n>y</c-></code> in (<code class="highlight"><c- n>x</c-></code>, <code class="highlight"><c- n>numeric_limits</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>max</c-><c- p>()]</c-></code> for which <code class="highlight"><c- n>popcount</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>popcount</c-><c- p>(</c-><c- n>y</c-><c- p>)</c-></code>, or <code class="highlight"><c- mi>0</c-></code> if none exists. <br>[<em>Note</em>: If <code class="highlight"><c- n>x</c-></code> is a power of two or zero, <code class="highlight"><c- n>next_bit_permutation</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-> <c- o>&lt;&lt;</c-> <c- mi>1</c-></code>. — <em>end note</em>] </p>
    <p></p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>T</c-> <c- n>prev_bit_permutation</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
    <p></p>
    <p class="indent"> 10 <em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]). </p>
    <p class="indent"> 11 <em>Returns</em>: The greatest integer <code class="highlight"><c- n>y</c-></code> in [<code class="highlight"><c- mi>0</c-></code>, <code class="highlight"><c- n>x</c-></code>) for which <code class="highlight"><c- n>popcount</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>popcount</c-><c- p>(</c-><c- n>y</c-><c- p>)</c-></code>, or <code class="highlight"><c- mi>0</c-></code> if none exists. <br>[<em>Note</em>: If <code class="highlight"><c- n>x</c-> <c- o>==</c-> <c- mi>0</c-> <c- o>||</c-> <c- n>next_bit_permutation</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-> <c- o>!=</c-> <c- mi>0</c-></code> is <code class="highlight">true</code>, <code class="highlight"><c- n>prev_bit_permutation</c-><c- p>(</c-><c- n>next_bit_permutation</c-><c- p>(</c-><c- n>x</c-><c- p>))</c-></code> equals <code class="highlight"><c- n>x</c-></code>. <em>end note</em>] </p>
    <p></p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_compressr</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
    <p></p>
    <p class="indent"> 12 <em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]). </p>
    <p class="indent"> 13 <em>Returns</em>: <span title="\sum_{n=0}^{N-1}{m_n x_n 2^{(\sum_{k=0}^{n-1}m_k)}}"> <svg alt="\sum_{n=0}^{N-1}{m_n x_n 2^{(\sum_{k=0}^{n-1}m_k)}}" aria-hidden="true" height="53.920px" viewBox="0 -1733 8098.2 2978.9" width="146.576px" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><path d="M60 948Q63 950 665 950H1267L1325 815Q1384 677 1388 669H1348L1341 683Q1320 724 1285 761Q1235 809 1174 838T1033 881T882 898T699 902H574H543H251L259 891Q722 258 724 252Q725 250 724 246Q721 243 460 -56L196 -356Q196 -357 407 -357Q459 -357 548 -357T676 -358Q812 -358 896 -353T1063 -332T1204 -283T1307 -196Q1328 -170 1348 -124H1388Q1388 -125 1381 -145T1356 -210T1325 -294L1267 -449L666 -450Q64 -450 61 -448Q55 -446 55 -439Q55 -437 57 -433L590 177Q590 178 557 222T452 366T322 544L56 909L55 924Q55 945 60 948Z" id="MJX-36-TEX-LO-2211"></path><path d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z" id="MJX-36-TEX-I-1D45B"></path><path d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z" id="MJX-36-TEX-N-3D"></path><path d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z" id="MJX-36-TEX-N-30"></path><path d="M234 637Q231 637 226 637Q201 637 196 638T191 649Q191 676 202 682Q204 683 299 683Q376 683 387 683T401 677Q612 181 616 168L670 381Q723 592 723 606Q723 633 659 637Q635 637 635 648Q635 650 637 660Q641 676 643 679T653 683Q656 683 684 682T767 680Q817 680 843 681T873 682Q888 682 888 672Q888 650 880 642Q878 637 858 637Q787 633 769 597L620 7Q618 0 599 0Q585 0 582 2Q579 5 453 305L326 604L261 344Q196 88 196 79Q201 46 268 46H278Q284 41 284 38T282 19Q278 6 272 0H259Q228 2 151 2Q123 2 100 2T63 2T46 1Q31 1 31 10Q31 14 34 26T39 40Q41 46 62 46Q130 49 150 85Q154 91 221 362L289 634Q287 635 234 637Z" id="MJX-36-TEX-I-1D441"></path><path d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z" id="MJX-36-TEX-N-2212"></path><path d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z" id="MJX-36-TEX-N-31"></path><path d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z" id="MJX-36-TEX-I-1D45A"></path><path d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z" id="MJX-36-TEX-I-1D465"></path><path d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z" id="MJX-36-TEX-N-32"></path><path d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z" id="MJX-36-TEX-N-28"></path><path d="M61 748Q64 750 489 750H913L954 640Q965 609 976 579T993 533T999 516H979L959 517Q936 579 886 621T777 682Q724 700 655 705T436 710H319Q183 710 183 709Q186 706 348 484T511 259Q517 250 513 244L490 216Q466 188 420 134T330 27L149 -187Q149 -188 362 -188Q388 -188 436 -188T506 -189Q679 -189 778 -162T936 -43Q946 -27 959 6H999L913 -249L489 -250Q65 -250 62 -248Q56 -246 56 -239Q56 -234 118 -161Q186 -81 245 -11L428 206Q428 207 242 462L57 717L56 728Q56 744 61 748Z" id="MJX-36-TEX-SO-2211"></path><path d="M121 647Q121 657 125 670T137 683Q138 683 209 688T282 694Q294 694 294 686Q294 679 244 477Q194 279 194 272Q213 282 223 291Q247 309 292 354T362 415Q402 442 438 442Q468 442 485 423T503 369Q503 344 496 327T477 302T456 291T438 288Q418 288 406 299T394 328Q394 353 410 369T442 390L458 393Q446 405 434 405H430Q398 402 367 380T294 316T228 255Q230 254 243 252T267 246T293 238T320 224T342 206T359 180T365 147Q365 130 360 106T354 66Q354 26 381 26Q429 26 459 145Q461 153 479 153H483Q499 153 499 144Q499 139 496 130Q455 -11 378 -11Q333 -11 305 15T277 90Q277 108 280 121T283 145Q283 167 269 183T234 206T200 217T182 220H180Q168 178 159 139T145 81T136 44T129 20T122 7T111 -2Q98 -11 83 -11Q66 -11 57 -1T48 16Q48 26 85 176T158 471L195 616Q196 629 188 632T149 637H144Q134 637 131 637T124 640T121 647Z" id="MJX-36-TEX-I-1D458"></path><path d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z" id="MJX-36-TEX-N-29"></path></defs><g fill="currentColor" stroke="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="munderover"><g data-mml-node="mo" transform="translate(43.8,0)"><use data-c="2211" href="#MJX-36-TEX-LO-2211"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(101.8,-1087.9) scale(0.707)"><g data-mml-node="mi"><use data-c="1D45B" href="#MJX-36-TEX-I-1D45B"></use></g><g data-mml-node="mo" transform="translate(600,0)"><use data-c="3D" href="#MJX-36-TEX-N-3D"></use></g><g data-mml-node="mn" transform="translate(1378,0)"><use data-c="30" href="#MJX-36-TEX-N-30"></use></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(0,1150) scale(0.707)"><g data-mml-node="mi"><use data-c="1D441" href="#MJX-36-TEX-I-1D441"></use></g><g data-mml-node="mo" transform="translate(888,0)"><use data-c="2212" href="#MJX-36-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(1666,0)"><use data-c="31" href="#MJX-36-TEX-N-31"></use></g></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1698.3,0)"><g data-mml-node="msub"><g data-mml-node="mi"><use data-c="1D45A" href="#MJX-36-TEX-I-1D45A"></use></g><g data-mml-node="mi" transform="translate(911,-150) scale(0.707)"><use data-c="1D45B" href="#MJX-36-TEX-I-1D45B"></use></g></g><g data-mml-node="msub" transform="translate(1385.3,0)"><g data-mml-node="mi"><use data-c="1D465" href="#MJX-36-TEX-I-1D465"></use></g><g data-mml-node="mi" transform="translate(605,-150) scale(0.707)"><use data-c="1D45B" href="#MJX-36-TEX-I-1D45B"></use></g></g><g data-mml-node="msup" transform="translate(2464.5,0)"><g data-mml-node="mn"><use data-c="32" href="#MJX-36-TEX-N-32"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(533,413) scale(0.707)"><g data-mml-node="mo"><use data-c="28" href="#MJX-36-TEX-N-28"></use></g><g data-mml-node="munderover" transform="translate(389,0)"><g data-mml-node="mo"><use data-c="2211" href="#MJX-36-TEX-SO-2211"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1089,477.1) scale(0.707)"><g data-mml-node="mi"><use data-c="1D45B" href="#MJX-36-TEX-I-1D45B"></use></g><g data-mml-node="mo" transform="translate(600,0)"><use data-c="2212" href="#MJX-36-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(1378,0)"><use data-c="31" href="#MJX-36-TEX-N-31"></use></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1089,-285.4) scale(0.707)"><g data-mml-node="mi"><use data-c="1D458" href="#MJX-36-TEX-I-1D458"></use></g><g data-mml-node="mo" transform="translate(521,0)"><use data-c="3D" href="#MJX-36-TEX-N-3D"></use></g><g data-mml-node="mn" transform="translate(1299,0)"><use data-c="30" href="#MJX-36-TEX-N-30"></use></g></g></g><g data-mml-node="msub" transform="translate(3022.6,0)"><g data-mml-node="mi"><use data-c="1D45A" href="#MJX-36-TEX-I-1D45A"></use></g><g data-mml-node="mi" transform="translate(911,-150) scale(0.707)"><use data-c="1D458" href="#MJX-36-TEX-I-1D458"></use></g></g><g data-mml-node="mo" transform="translate(4352,0)"><use data-c="29" href="#MJX-36-TEX-N-29"></use></g></g></g></g></g></g></svg> </span> </p>
    <p></p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_expandr</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
    <p></p>
    <p class="indent"> 14 <em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]). </p>
    <p class="indent"> 15 <em>Returns</em>: <span title="\sum_{n=0}^{N-1}{m_n x_{(\sum_{k=0}^{n-1}m_k)} 2^n}"> <svg alt="\sum_{n=0}^{N-1}{m_n x_{(\sum_{k=0}^{n-1}m_k)} 2^n}" aria-hidden="true" height="53.920px" viewBox="0 -1733 8098.2 2978.9" width="146.576px" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><path d="M60 948Q63 950 665 950H1267L1325 815Q1384 677 1388 669H1348L1341 683Q1320 724 1285 761Q1235 809 1174 838T1033 881T882 898T699 902H574H543H251L259 891Q722 258 724 252Q725 250 724 246Q721 243 460 -56L196 -356Q196 -357 407 -357Q459 -357 548 -357T676 -358Q812 -358 896 -353T1063 -332T1204 -283T1307 -196Q1328 -170 1348 -124H1388Q1388 -125 1381 -145T1356 -210T1325 -294L1267 -449L666 -450Q64 -450 61 -448Q55 -446 55 -439Q55 -437 57 -433L590 177Q590 178 557 222T452 366T322 544L56 909L55 924Q55 945 60 948Z" id="MJX-6-TEX-LO-2211"></path><path d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z" id="MJX-6-TEX-I-1D45B"></path><path d="M56 347Q56 360 70 367H707Q722 359 722 347Q722 336 708 328L390 327H72Q56 332 56 347ZM56 153Q56 168 72 173H708Q722 163 722 153Q722 140 707 133H70Q56 140 56 153Z" id="MJX-6-TEX-N-3D"></path><path d="M96 585Q152 666 249 666Q297 666 345 640T423 548Q460 465 460 320Q460 165 417 83Q397 41 362 16T301 -15T250 -22Q224 -22 198 -16T137 16T82 83Q39 165 39 320Q39 494 96 585ZM321 597Q291 629 250 629Q208 629 178 597Q153 571 145 525T137 333Q137 175 145 125T181 46Q209 16 250 16Q290 16 318 46Q347 76 354 130T362 333Q362 478 354 524T321 597Z" id="MJX-6-TEX-N-30"></path><path d="M234 637Q231 637 226 637Q201 637 196 638T191 649Q191 676 202 682Q204 683 299 683Q376 683 387 683T401 677Q612 181 616 168L670 381Q723 592 723 606Q723 633 659 637Q635 637 635 648Q635 650 637 660Q641 676 643 679T653 683Q656 683 684 682T767 680Q817 680 843 681T873 682Q888 682 888 672Q888 650 880 642Q878 637 858 637Q787 633 769 597L620 7Q618 0 599 0Q585 0 582 2Q579 5 453 305L326 604L261 344Q196 88 196 79Q201 46 268 46H278Q284 41 284 38T282 19Q278 6 272 0H259Q228 2 151 2Q123 2 100 2T63 2T46 1Q31 1 31 10Q31 14 34 26T39 40Q41 46 62 46Q130 49 150 85Q154 91 221 362L289 634Q287 635 234 637Z" id="MJX-6-TEX-I-1D441"></path><path d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z" id="MJX-6-TEX-N-2212"></path><path d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z" id="MJX-6-TEX-N-31"></path><path d="M21 287Q22 293 24 303T36 341T56 388T88 425T132 442T175 435T205 417T221 395T229 376L231 369Q231 367 232 367L243 378Q303 442 384 442Q401 442 415 440T441 433T460 423T475 411T485 398T493 385T497 373T500 364T502 357L510 367Q573 442 659 442Q713 442 746 415T780 336Q780 285 742 178T704 50Q705 36 709 31T724 26Q752 26 776 56T815 138Q818 149 821 151T837 153Q857 153 857 145Q857 144 853 130Q845 101 831 73T785 17T716 -10Q669 -10 648 17T627 73Q627 92 663 193T700 345Q700 404 656 404H651Q565 404 506 303L499 291L466 157Q433 26 428 16Q415 -11 385 -11Q372 -11 364 -4T353 8T350 18Q350 29 384 161L420 307Q423 322 423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 181Q151 335 151 342Q154 357 154 369Q154 405 129 405Q107 405 92 377T69 316T57 280Q55 278 41 278H27Q21 284 21 287Z" id="MJX-6-TEX-I-1D45A"></path><path d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z" id="MJX-6-TEX-I-1D465"></path><path d="M94 250Q94 319 104 381T127 488T164 576T202 643T244 695T277 729T302 750H315H319Q333 750 333 741Q333 738 316 720T275 667T226 581T184 443T167 250T184 58T225 -81T274 -167T316 -220T333 -241Q333 -250 318 -250H315H302L274 -226Q180 -141 137 -14T94 250Z" id="MJX-6-TEX-N-28"></path><path d="M61 748Q64 750 489 750H913L954 640Q965 609 976 579T993 533T999 516H979L959 517Q936 579 886 621T777 682Q724 700 655 705T436 710H319Q183 710 183 709Q186 706 348 484T511 259Q517 250 513 244L490 216Q466 188 420 134T330 27L149 -187Q149 -188 362 -188Q388 -188 436 -188T506 -189Q679 -189 778 -162T936 -43Q946 -27 959 6H999L913 -249L489 -250Q65 -250 62 -248Q56 -246 56 -239Q56 -234 118 -161Q186 -81 245 -11L428 206Q428 207 242 462L57 717L56 728Q56 744 61 748Z" id="MJX-6-TEX-SO-2211"></path><path d="M121 647Q121 657 125 670T137 683Q138 683 209 688T282 694Q294 694 294 686Q294 679 244 477Q194 279 194 272Q213 282 223 291Q247 309 292 354T362 415Q402 442 438 442Q468 442 485 423T503 369Q503 344 496 327T477 302T456 291T438 288Q418 288 406 299T394 328Q394 353 410 369T442 390L458 393Q446 405 434 405H430Q398 402 367 380T294 316T228 255Q230 254 243 252T267 246T293 238T320 224T342 206T359 180T365 147Q365 130 360 106T354 66Q354 26 381 26Q429 26 459 145Q461 153 479 153H483Q499 153 499 144Q499 139 496 130Q455 -11 378 -11Q333 -11 305 15T277 90Q277 108 280 121T283 145Q283 167 269 183T234 206T200 217T182 220H180Q168 178 159 139T145 81T136 44T129 20T122 7T111 -2Q98 -11 83 -11Q66 -11 57 -1T48 16Q48 26 85 176T158 471L195 616Q196 629 188 632T149 637H144Q134 637 131 637T124 640T121 647Z" id="MJX-6-TEX-I-1D458"></path><path d="M60 749L64 750Q69 750 74 750H86L114 726Q208 641 251 514T294 250Q294 182 284 119T261 12T224 -76T186 -143T145 -194T113 -227T90 -246Q87 -249 86 -250H74Q66 -250 63 -250T58 -247T55 -238Q56 -237 66 -225Q221 -64 221 250T66 725Q56 737 55 738Q55 746 60 749Z" id="MJX-6-TEX-N-29"></path><path d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z" id="MJX-6-TEX-N-32"></path></defs><g fill="currentColor" stroke="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="munderover"><g data-mml-node="mo" transform="translate(43.8,0)"><use data-c="2211" href="#MJX-6-TEX-LO-2211"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(101.8,-1087.9) scale(0.707)"><g data-mml-node="mi"><use data-c="1D45B" href="#MJX-6-TEX-I-1D45B"></use></g><g data-mml-node="mo" transform="translate(600,0)"><use data-c="3D" href="#MJX-6-TEX-N-3D"></use></g><g data-mml-node="mn" transform="translate(1378,0)"><use data-c="30" href="#MJX-6-TEX-N-30"></use></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(0,1150) scale(0.707)"><g data-mml-node="mi"><use data-c="1D441" href="#MJX-6-TEX-I-1D441"></use></g><g data-mml-node="mo" transform="translate(888,0)"><use data-c="2212" href="#MJX-6-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(1666,0)"><use data-c="31" href="#MJX-6-TEX-N-31"></use></g></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1698.3,0)"><g data-mml-node="msub"><g data-mml-node="mi"><use data-c="1D45A" href="#MJX-6-TEX-I-1D45A"></use></g><g data-mml-node="mi" transform="translate(911,-150) scale(0.707)"><use data-c="1D45B" href="#MJX-6-TEX-I-1D45B"></use></g></g><g data-mml-node="msub" transform="translate(1385.3,0)"><g data-mml-node="mi"><use data-c="1D465" href="#MJX-6-TEX-I-1D465"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(605,-316.7) scale(0.707)"><g data-mml-node="mo"><use data-c="28" href="#MJX-6-TEX-N-28"></use></g><g data-mml-node="munderover" transform="translate(389,0)"><g data-mml-node="mo"><use data-c="2211" href="#MJX-6-TEX-SO-2211"></use></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1089,477.1) scale(0.707)"><g data-mml-node="mi"><use data-c="1D45B" href="#MJX-6-TEX-I-1D45B"></use></g><g data-mml-node="mo" transform="translate(600,0)"><use data-c="2212" href="#MJX-6-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(1378,0)"><use data-c="31" href="#MJX-6-TEX-N-31"></use></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(1089,-285.4) scale(0.707)"><g data-mml-node="mi"><use data-c="1D458" href="#MJX-6-TEX-I-1D458"></use></g><g data-mml-node="mo" transform="translate(521,0)"><use data-c="3D" href="#MJX-6-TEX-N-3D"></use></g><g data-mml-node="mn" transform="translate(1299,0)"><use data-c="30" href="#MJX-6-TEX-N-30"></use></g></g></g><g data-mjx-texclass="ORD" data-mml-node="TeXAtom" transform="translate(3022.6,0)"><g data-mml-node="msub"><g data-mml-node="mi"><use data-c="1D45A" href="#MJX-6-TEX-I-1D45A"></use></g><g data-mml-node="mi" transform="translate(911,-150) scale(0.707)"><use data-c="1D458" href="#MJX-6-TEX-I-1D458"></use></g></g></g><g data-mml-node="mo" transform="translate(4352,0)"><use data-c="29" href="#MJX-6-TEX-N-29"></use></g></g></g></g><g data-mml-node="msup" transform="translate(7090.9,0)"><g data-mml-node="mn"><use data-c="32" href="#MJX-6-TEX-N-32"></use></g><g data-mml-node="mi" transform="translate(533,413) scale(0.707)"><use data-c="1D45B" href="#MJX-6-TEX-I-1D45B"></use></g></g></g></g></svg> </span> <br>[<em>Note</em>:
    If <code class="highlight"><c- n>x</c-> <c- o>&amp;</c-> <c- o>~</c-><c- n>m</c-></code> equals zero, then <code class="highlight"><c- n>bit_expandr</c-><c- p>(</c-><c- n>bit_compressr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>m</c-><c- p>),</c-> <c- n>m</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-></code>.
    If <code class="highlight"><c- n>x</c-> <c- o>>></c-> <c- n>popcount</c-><c- p>(</c-><c- n>m</c-><c- p>)</c-></code> equals zero, then <code class="highlight"><c- n>bit_compressr</c-><c- p>(</c-><c- n>bit_expandr</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>m</c-><c- p>),</c-> <c- n>m</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>x</c-></code>.
    — <em>end note</em>] </p>
    <p></p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_compressl</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
    <p></p>
    <p class="indent"> 16 <em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]). </p>
    <p class="indent"> 17 <em>Returns</em>: <code class="highlight"><c- n>bit_reverse</c-><c- p>(</c-><c- n>bit_compressr</c-><c- p>(</c-><c- n>bit_reverse</c-><c- p>(</c-><c- n>x</c-><c- p>),</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>m</c-><c- p>)))</c-></code>. </p>
    <p></p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
  <c- k>constexpr</c-> <c- n>T</c-> <c- n>bit_expandl</c-><c- p>(</c-><c- n>T</c-> <c- n>x</c-><c- p>,</c-> <c- n>T</c-> <c- n>m</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->
</pre>
    <p></p>
    <p class="indent"> 18 <em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]). </p>
    <p class="indent"> 19 <em>Returns</em>: <code class="highlight"><c- n>bit_reverse</c-><c- p>(</c-><c- n>bit_expandr</c-><c- p>(</c-><c- n>bit_reverse</c-><c- p>(</c-><c- n>x</c-><c- p>),</c-> <c- n>bit_reverse</c-><c- p>(</c-><c- n>m</c-><c- p>)))</c-></code>. </p>
   </blockquote>
   <p class="note" role="note"><span class="marker">Note:</span> I would have preferred a less mathematical approach to defining these functions.
      However, it is too difficult to precisely define <code class="highlight"><c- n>bit_compress</c-></code> and <code class="highlight"><c- n>bit_expand</c-></code> without
      visual aids, pseudo-code, or other crutches.</p>
   <h2 class="heading settled" data-level="9" id="acknowledgements"><span class="secno">9. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h2>
   <p>I greatly appreciate the assistance of Stack Overflow users in assisting me with research for
this proposal. 
I especially thank Peter Cordes for his tireless and selfess dedication to sharing knowledge.</p>
   <p>I also thank various Discord users from <a href="https://discord.com/invite/tccpp">Together C &amp; C++</a> and <a href="https://www.includecpp.org/discord/">#include&lt;C++></a> who have reviewed drafts of
this proposal and shared their thoughts.</p>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don't scroll to compensate for the ToC if we're above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don't know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn't exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn't standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don't have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we're at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can't find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="normative"><span class="content">Normative References</span><a class="self-link" href="#normative"></a></h3>
  <dl>
   <dt id="biblio-n4917">[N4917]
   <dd>Thomas Köppe. <a href="https://wg21.link/n4917"><cite>Working Draft, Standard for Programming Language C++</cite></a>. 5 September 2022. URL: <a href="https://wg21.link/n4917">https://wg21.link/n4917</a>
  </dl>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-anderson1">[Anderson1]
   <dd>Sean Eron Anderson. <a href="https://graphics.stanford.edu/~seander/bithacks.html"><cite>Bit Twiddling Hacks</cite></a>. URL: <a href="https://graphics.stanford.edu/~seander/bithacks.html">https://graphics.stanford.edu/~seander/bithacks.html</a>
   <dt id="biblio-arm1">[ARM1]
   <dd>Arm Developer Community. <a href="https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/102340_0001_02_en_introduction-to-sve2.pdf?revision=b208e56b-6569-4ae2-b6f3-cd7d5d1ecac3"><cite>Introduction to SVE2, Issue 02, Revision 02</cite></a>. URL: <a href="https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/102340_0001_02_en_introduction-to-sve2.pdf?revision=b208e56b-6569-4ae2-b6f3-cd7d5d1ecac3">https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/102340_0001_02_en_introduction-to-sve2.pdf?revision=b208e56b-6569-4ae2-b6f3-cd7d5d1ecac3</a>
   <dt id="biblio-chessprogramming1">[ChessProgramming1]
   <dd>VA. <a href="https://www.chessprogramming.org/BMI2#Applications"><cite>chessprogramming.org/BMI2, Applications</cite></a>. URL: <a href="https://www.chessprogramming.org/BMI2#Applications">https://www.chessprogramming.org/BMI2#Applications</a>
   <dt id="biblio-compilerexplorer1">[CompilerExplorer1]
   <dd>Jan Schultke. <a href="https://godbolt.org/z/5dcTjE5x3"><cite>Compiler Explorer example for bit_compressr</cite></a>. URL: <a href="https://godbolt.org/z/5dcTjE5x3">https://godbolt.org/z/5dcTjE5x3</a>
   <dt id="biblio-gnu1">[GNU1]
   <dd>Marc Glisse et al.. <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50481"><cite>Bug 50481 - builtin to reverse the bit order</cite></a>. URL: <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50481">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50481</a>
   <dt id="biblio-n3864">[N3864]
   <dd>Matthew Fioravante. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3864.html"><cite>A constexpr bitwise operations library for C++</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3864.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3864.html</a>
   <dt id="biblio-p0553r4">[P0553R4]
   <dd>Jens Maurer. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html"><cite>Bit operations</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html</a>
   <dt id="biblio-p2664r6">[P2664R6]
   <dd>Daniel Towner; Ruslan Arutyunyan. <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2664r6.html#permute_by_mask"><cite>Extend std::simd with permutation API</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2664r6.html#permute_by_mask">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2664r6.html#permute_by_mask</a>
   <dt id="biblio-schultke1">[Schultke1]
   <dd>Jan Schultke. <a href="https://github.com/Eisenwave/cxx26-bit-permutations"><cite>C++26 Bit Permutations</cite></a>. URL: <a href="https://github.com/Eisenwave/cxx26-bit-permutations">https://github.com/Eisenwave/cxx26-bit-permutations</a>
   <dt id="biblio-stackoverflow1">[StackOverflow1]
   <dd>Jan Schultke et al.. <a href="https://stackoverflow.com/q/77834169/5740428"><cite>What is a fast fallback algorithm which emulates PDEP and PEXT in software?</cite></a>. URL: <a href="https://stackoverflow.com/q/77834169/5740428">https://stackoverflow.com/q/77834169/5740428</a>
   <dt id="biblio-warren1">[Warren1]
   <dd>Henry S. Warren, Jr.. <cite>Hacker's Delight, 2nd Edition</cite>. 
   <dt id="biblio-zp7">[Zp7]
   <dd>Zach Wegner. <a href="https://github.com/zwegner/zp7"><cite>Zach's Peppy Parallel-Prefix-Popcountin' PEXT/PDEP Polyfill</cite></a>. URL: <a href="https://github.com/zwegner/zp7">https://github.com/zwegner/zp7</a>
  </dl>