<!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>P3140R0: std::int_least128_t</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/int-least128.html" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="6e39ce8bbfad2b64a991b81b33d49e8aaa5a0103" name="revision">
<style>
@media (prefers-color-scheme: dark) {
  c-[mb], c-[mi], c-[mo], c-[mh] {
    color: #d59393 !important;
  }

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

th, td, table {
    border: 1px solid var(--text);
}
th, td {
    border-left-width: 0;
    border-right-width: 0;
}

.indent {
    margin-left: 2em;
}

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

ins {
    background: rgba(136, 255, 93, 0.2);
    color: inherit;
    text-decoration: underlined;
}
del {
    background: rgba(255, 93, 93, 0.2);
    color: inherit;
    text-decoration: strikethrough;
}
</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">P3140R0<br><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code></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-02-11">2024-02-11</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/int-least128.html">https://eisenwave.github.io/cpp-proposals/int-least128.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&lt;janschultke@gmail.com></a>
     <dt>Audience:
     <dd>SG18, LEWG, SG17, EWG, SG22
     <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/int-least128.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 standardizes mandatory 128-bit integers types with strong library support.</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="#revision-history"><span class="secno">1</span> <span class="content">Revision history</span></a>
    <li>
     <a href="#introduction"><span class="secno">2</span> <span class="content">Introduction</span></a>
     <ol class="toc">
      <li><a href="#lifting-library-restrictions"><span class="secno">2.1</span> <span class="content">Lifting library restrictions</span></a>
     </ol>
    <li>
     <a href="#motivation-and-scope"><span class="secno">3</span> <span class="content">Motivation and scope</span></a>
     <ol class="toc">
      <li>
       <a href="#use-cases"><span class="secno">3.1</span> <span class="content">Use cases</span></a>
       <ol class="toc">
        <li><a href="#cryptography"><span class="secno">3.1.1</span> <span class="content">Cryptography</span></a>
        <li><a href="#random-number-generation"><span class="secno">3.1.2</span> <span class="content">Random number generation</span></a>
        <li>
         <a href="#widening-operations"><span class="secno">3.1.3</span> <span class="content">Widening operations</span></a>
         <ol class="toc">
          <li><a href="#safe-modular-arithmetic"><span class="secno">3.1.3.1</span> <span class="content">64-bit modular arithmetic</span></a>
          <li><a href="#multi-precision-operations"><span class="secno">3.1.3.2</span> <span class="content">Multi-precision operations</span></a>
         </ol>
        <li><a href="#fixed-point-operations"><span class="secno">3.1.4</span> <span class="content">Fixed-point operations</span></a>
        <li><a href="#high-precision-clocks"><span class="secno">3.1.5</span> <span class="content">High-precision time calculations</span></a>
        <li><a href="#floating-point-operations"><span class="secno">3.1.6</span> <span class="content">Floating-point operations</span></a>
        <li><a href="#float-string-conversion"><span class="secno">3.1.7</span> <span class="content">Float-to-string/String-to-float conversion</span></a>
        <li><a href="#financial-systems"><span class="secno">3.1.8</span> <span class="content">Financial systems</span></a>
        <li><a href="#uuid"><span class="secno">3.1.9</span> <span class="content">Universally unique identifiers</span></a>
        <li><a href="#networking"><span class="secno">3.1.10</span> <span class="content">Networking</span></a>
        <li><a href="#bitsets-and-lookup-tables"><span class="secno">3.1.11</span> <span class="content">Bitsets and lookup tables</span></a>
       </ol>
      <li>
       <a href="#utilizing-hardware-support"><span class="secno">3.2</span> <span class="content">Utilizing hardware support</span></a>
       <ol class="toc">
        <li><a href="#future-proofing"><span class="secno">3.2.1</span> <span class="content">Future-proofing for direct 128-bit support</span></a>
        <li><a href="#support-through-128-bit-floating-point"><span class="secno">3.2.2</span> <span class="content">Support through 128-bit floating-point</span></a>
       </ol>
     </ol>
    <li>
     <a href="#impact-on-the-standard"><span class="secno">4</span> <span class="content">Impact on the standard</span></a>
     <ol class="toc">
      <li>
       <a href="#c-compatibility"><span class="secno">4.1</span> <span class="content">C Compatibility</span></a>
       <ol class="toc">
        <li><a href="#intmax-t"><span class="secno">4.1.1</span> <span class="content"><code class="highlight"><c- b>intmax_t</c-></code> and <code class="highlight"><c- b>uintmax_t</c-></code></span></a>
        <li><a href="#int-least128-t-in-c"><span class="secno">4.1.2</span> <span class="content"><code class="highlight"><c- n>int_least128_t</c-></code> in C</span></a>
        <li><a href="#c-library-impact"><span class="secno">4.1.3</span> <span class="content">C library impact</span></a>
       </ol>
      <li>
       <a href="#core-impact"><span class="secno">4.2</span> <span class="content">Impact on the core language</span></a>
       <ol class="toc">
        <li><a href="#note-on-surprising-semantics"><span class="secno">4.2.1</span> <span class="content">Note on surprising semantics</span></a>
       </ol>
      <li>
       <a href="#library-impact"><span class="secno">4.3</span> <span class="content">Impact on the library</span></a>
       <ol class="toc">
        <li><a href="#library-impact-language-support"><span class="secno">4.3.1</span> <span class="content">Language support library</span></a>
        <li><a href="#library-impact-metaprogramming"><span class="secno">4.3.2</span> <span class="content">Metaprogramming library</span></a>
        <li><a href="#library-impact-utilities"><span class="secno">4.3.3</span> <span class="content">General utilities library</span></a>
        <li><a href="#library-impact-containers"><span class="secno">4.3.4</span> <span class="content">Containers library</span></a>
        <li><a href="#library-impact-iterators"><span class="secno">4.3.5</span> <span class="content">Iterators library</span></a>
        <li><a href="#library-impact-ranges"><span class="secno">4.3.6</span> <span class="content">Ranges library</span></a>
        <li><a href="#library-impact-algorithms"><span class="secno">4.3.7</span> <span class="content">Algorithms library</span></a>
        <li><a href="#library-impact-numerics"><span class="secno">4.3.8</span> <span class="content">Numerics library</span></a>
        <li><a href="#library-impact-time"><span class="secno">4.3.9</span> <span class="content">Time library</span></a>
        <li><a href="#library-impact-localization"><span class="secno">4.3.10</span> <span class="content">Localization library</span></a>
        <li><a href="#library-impact-io"><span class="secno">4.3.11</span> <span class="content">Input/output library</span></a>
        <li><a href="#concurrency-support-library"><span class="secno">4.3.12</span> <span class="content">Concurrency support library</span></a>
       </ol>
     </ol>
    <li>
     <a href="#implementation-impact"><span class="secno">5</span> <span class="content">Impact on implementations</span></a>
     <ol class="toc">
      <li><a href="#estimated-implementation-effort"><span class="secno">5.1</span> <span class="content">Estimated implementation effort</span></a>
      <li>
       <a href="#iota-view-abi-break"><span class="secno">5.2</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>iota_view</c-></code> ABI issue</span></a>
       <ol class="toc">
        <li><a href="#abi-break-affected-implementations"><span class="secno">5.2.1</span> <span class="content">Affected implementations</span></a>
        <li><a href="#abi-break-cause"><span class="secno">5.2.2</span> <span class="content">Cause of ABI break</span></a>
        <li><a href="#abi-break-possible-solution"><span class="secno">5.2.3</span> <span class="content">Possible solution</span></a>
        <li><a href="#iota-view-128"><span class="secno">5.2.4</span> <span class="content">What about <code class="highlight"><c- n>iota_view</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-><c- o>></c-></code>?</span></a>
       </ol>
     </ol>
    <li>
     <a href="#impact-on-existing-code"><span class="secno">6</span> <span class="content">Impact on existing code</span></a>
     <ol class="toc">
      <li><a href="#possible-semantic-changes"><span class="secno">6.1</span> <span class="content">Possible semantic changes</span></a>
      <li>
       <a href="#impact-on-overload-sets"><span class="secno">6.2</span> <span class="content">Impact on overload sets</span></a>
       <ol class="toc">
        <li><a href="#proposed-overload-set-extension"><span class="secno">6.2.1</span> <span class="content">Proposed solution</span></a>
       </ol>
      <li><a href="#possible-assumption-violations"><span class="secno">6.3</span> <span class="content">Possible assumption violations</span></a>
      <li>
       <a href="#bitset-constructor"><span class="secno">6.4</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code> constructor semantic changes</span></a>
       <ol class="toc">
        <li><a href="#bitset-constructor-proposed-solution"><span class="secno">6.4.1</span> <span class="content">Proposed solution</span></a>
       </ol>
     </ol>
    <li>
     <a href="#design-considerations"><span class="secno">7</span> <span class="content">Design considerations</span></a>
     <ol class="toc">
      <li><a href="#standard-integers"><span class="secno">7.1</span> <span class="content">Why no standard integer type?</span></a>
      <li><a href="#exact-width-integers"><span class="secno">7.2</span> <span class="content">Why no mandatory <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code> type?</span></a>
      <li><a href="#why-no-256-bit"><span class="secno">7.3</span> <span class="content">Why no <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least256_t</c-></code> type?</span></a>
      <li><a href="#why-not-class-type"><span class="secno">7.4</span> <span class="content">Why no class type?</span></a>
      <li>
       <a href="#bit-precise-integers"><span class="secno">7.5</span> <span class="content">Why no bit-precise integers?</span></a>
       <ol class="toc">
        <li><a href="#bitint-lack-of-work"><span class="secno">7.5.1</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> has no existing C++ work</span></a>
        <li><a href="#bitint-lack-of-motivation"><span class="secno">7.5.2</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> has less motivation in C++</span></a>
        <li><a href="#bitint-should-be-class-type"><span class="secno">7.5.3</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> should be exposed as a class type</span></a>
        <li><a href="#bitint-not-replacement"><span class="secno">7.5.4</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> is not a replacement for standard integers</span></a>
        <li><a href="#bitint-128-bit-support"><span class="secno">7.5.5</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> does not guarantee 128-bit support</span></a>
        <li><a href="#bitint-library-effort"><span class="secno">7.5.6</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> requires more library effort</span></a>
        <li><a href="#bitint-breaking-code"><span class="secno">7.5.7</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> breaks more existing code</span></a>
        <li><a href="#bitint-teachability"><span class="secno">7.5.8</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> has teachability issues</span></a>
        <li><a href="#bitint-too-permissive"><span class="secno">7.5.9</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> in C may be too permissive</span></a>
        <li><a href="#bitint-false-dichotomy"><span class="secno">7.5.10</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-></code> false dichotomy</span></a>
       </ol>
      <li>
       <a href="#why-not-optional"><span class="secno">7.6</span> <span class="content">Why not make it optional?</span></a>
       <ol class="toc">
        <li><a href="#implementation-effort-not-too-high"><span class="secno">7.6.1</span> <span class="content">Implementation effort is not too high</span></a>
        <li><a href="#software-emulation-acceptable"><span class="secno">7.6.2</span> <span class="content">Software emulation is acceptable</span></a>
       </ol>
      <li><a href="#extended-conversion-rank"><span class="secno">7.7</span> <span class="content">Should extended integer semantics be changed?</span></a>
      <li><a href="#user-defined-literals"><span class="secno">7.8</span> <span class="content">Do we need new user-defined literals?</span></a>
      <li><a href="#div"><span class="secno">7.9</span> <span class="content">Why no <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>div</c-></code>?</span></a>
      <li><a href="#ratio-dilemma"><span class="secno">7.10</span> <span class="content">What about the <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ratio</c-></code> dilemma?</span></a>
     </ol>
    <li>
     <a href="#implementation-experience"><span class="secno">8</span> <span class="content">Implementation experience</span></a>
     <ol class="toc">
      <li>
       <a href="#existing-128-bit-integers"><span class="secno">8.1</span> <span class="content">Existing 128-bit integer types</span></a>
       <ol class="toc">
        <li><a href="#existing-int-128"><span class="secno">8.1.1</span> <span class="content"><code class="highlight"><c- b>__int128</c-></code> (GNU-like)</span></a>
        <li><a href="#existing-int-128-cuda"><span class="secno">8.1.2</span> <span class="content"><code class="highlight"><c- b>__int128</c-></code> (CUDA)</span></a>
        <li><a href="#existing-msvc-128"><span class="secno">8.1.3</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>_Signed128</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>_Unsigned128</c-></code></span></a>
        <li><a href="#existing-bit-int"><span class="secno">8.1.4</span> <span class="content"><code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code></span></a>
       </ol>
      <li>
       <a href="#library-implementation-experience"><span class="secno">8.2</span> <span class="content">Library implementation experience</span></a>
       <ol class="toc">
        <li><a href="#to-integer-implementation-experience"><span class="secno">8.2.1</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_integer</c-></code></span></a>
        <li><a href="#type-traits-implementation-experience"><span class="secno">8.2.2</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>type_traits</c-><c- o>></c-></code></span></a>
        <li><a href="#safe-comparison-implementation-experience"><span class="secno">8.2.3</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cmp_xxx</c-></code></span></a>
        <li><a href="#bitset-implementation-experience"><span class="secno">8.2.4</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>bitset</c-><c- o>></c-></code></span></a>
        <li><a href="#charconv-implementation-experience"><span class="secno">8.2.5</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>charconv</c-><c- o>></c-></code></span></a>
        <li><a href="#format-implementation-experience"><span class="secno">8.2.6</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>format</c-><c- o>></c-></code></span></a>
        <li><a href="#bit-implementation-experience"><span class="secno">8.2.7</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code></span></a>
        <li><a href="#to-string-implementation-experience"><span class="secno">8.2.8</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-></code></span></a>
        <li><a href="#gcd-implementation-experience"><span class="secno">8.2.9</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>gcd</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>lcm</c-></code></span></a>
        <li><a href="#random-implementation-experience"><span class="secno">8.2.10</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>random</c-><c- o>></c-></code></span></a>
        <li><a href="#midpoint-implementation-experience"><span class="secno">8.2.11</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>midpoint</c-></code></span></a>
        <li><a href="#saturating-implementation-experience"><span class="secno">8.2.12</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>xxx_sat</c-></code></span></a>
        <li><a href="#abs-implementation-experience"><span class="secno">8.2.13</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>abs</c-></code></span></a>
        <li><a href="#cmath-implementation-experience"><span class="secno">8.2.14</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>cmath</c-><c- o>></c-></code></span></a>
        <li><a href="#valarray-implementation-experience"><span class="secno">8.2.15</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>valarray</c-></code></span></a>
        <li><a href="#linalg-implementation-experience"><span class="secno">8.2.16</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>linalg</c-><c- o>></c-></code></span></a>
        <li><a href="#cstdio-implementation-experience"><span class="secno">8.2.17</span> <span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>cstdio</c-><c- o>></c-></code></span></a>
        <li><a href="#atomic-implementation-experience"><span class="secno">8.2.18</span> <span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-></code></span></a>
       </ol>
     </ol>
    <li>
     <a href="#proposed-wording"><span class="secno">9</span> <span class="content">Proposed wording</span></a>
     <ol class="toc">
      <li><a href="#proposed-version"><span class="secno">9.1</span> <span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>version</c-><c- o>></c-></code></span></a>
      <li><a href="#proposed-cstdint"><span class="secno">9.2</span> <span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>cstdint</c-><c- o>></c-></code></span></a>
      <li><a href="#proposed-inttypes"><span class="secno">9.3</span> <span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code></span></a>
      <li><a href="#proposed-bitset"><span class="secno">9.4</span> <span class="content">Class template <code class="highlight"><c- n>bitset</c-></code></span></a>
      <li><a href="#proposed-numeric-conversions"><span class="secno">9.5</span> <span class="content">Numeric conversions</span></a>
      <li><a href="#proposed-iota"><span class="secno">9.6</span> <span class="content">Iota view</span></a>
      <li><a href="#proposed-abs"><span class="secno">9.7</span> <span class="content">Absolute values</span></a>
      <li><a href="#proposed-cinttypes"><span class="secno">9.8</span> <span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>cinttypes</c-><c- o>></c-></code></span></a>
      <li><a href="#proposed-atomic"><span class="secno">9.9</span> <span class="content">Atomic operations</span></a>
     </ol>
    <li><a href="#acknowledgements"><span class="secno">10</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="revision-history"><span class="secno">1. </span><span class="content">Revision history</span><a class="self-link" href="#revision-history"></a></h2>
   <p>This is the first revision.</p>
   <h2 class="heading settled" data-level="2" id="introduction"><span class="secno">2. </span><span class="content">Introduction</span><a class="self-link" href="#introduction"></a></h2>
   <p>128-bit integers have numerous practical uses, and all major implementations
(MSVC, GCC, LLVM) provide 128-bit integers already.
Among C++ users, there has been great interest in standardizing integers beyond 64 bits for a long time.
With the new wording in the C23 standard for <code class="highlight"><c- b>intmax_t</c-></code> (see <a href="#c-compatibility">§ 4.1 C Compatibility</a>),
one of the last obstacles has been removed.</p>
   <p>The goal of this paper is to obtain a mandatory ≥ 128-bit integer type with no core language changes
and strong support from the C++ standard library.
To accomplish this, the mandatory aliases <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code> are proposed.
Note that any non-malicious implementation would be required to define <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-></code> if possible,
so standardizing the minimum-width types is standardizing exact-width types by proxy.</p>
   <p>While the definition of these aliases is trivial, mandating them also implies
library support from <code class="highlight"><c- o>&lt;</c-><c- n>format</c-><c- o>></c-></code>, <code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code>, <code class="highlight"><c- o>&lt;</c-><c- n>cmath</c-><c- o>></c-></code>, <code class="highlight"><c- o>&lt;</c-><c- n>limits</c-><c- o>></c-></code>, and other facilities.
After extensive investigation, it was determined that the <a href="#impact-on-the-standard">§ 4 Impact on the standard</a> and <a href="#implementation-impact">§ 5 Impact on implementations</a> is relatively low.</p>
   <h3 class="heading settled" data-level="2.1" id="lifting-library-restrictions"><span class="secno">2.1. </span><span class="content">Lifting library restrictions</span><a class="self-link" href="#lifting-library-restrictions"></a></h3>
   <p>The standard library contains a large amount of artificial hurdles
which make it impossible to provide library support for extended integers.
The current standard already permits the implementation to provide additional
extended (fundamental) integer types in addition to the standard integers (<code class="highlight"><c- b>int</c-></code>, <code class="highlight"><c- b>long</c-></code>, etc.).
However, even if there exists an extended 128-bit integer, among other issues:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-><c- p>)</c-></code> cannot exist,</p>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code> cannot be constructed from it (without truncating to <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code>), and</p>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>abs</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-><c- p>)</c-></code> cannot exist.</p>
   </ul>
   <p>It would not be legal for an implementation to provide such additional overloads because it would
change the meaning of well-formed programs.</p>
   <div class="example" id="example-30d55124">
    <a class="self-link" href="#example-30d55124"></a> The following code is a well-defined C++20 program
which uses the optional <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code> type. 
<pre class="language-cpp highlight"><c- cp>#include</c-> &lt;string>
<c- cp>#include</c-> &lt;concepts>

<c- k>struct</c-> <c- nc>S</c-> <c- p>{</c->
    <c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- nc>T</c-><c- o>></c->
      <c- k>requires</c-> <c- n>std</c-><c- o>::</c-><c- n>same_as</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- b>long</c-> <c- b>long</c-><c- o>></c-> <c- o>||</c-> <c- n>std</c-><c- o>::</c-><c- n>same_as</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>int128_t</c-><c- o>></c->
    <c- k>operator</c-> <c- n>T</c-><c- p>()</c-> <c- k>const</c-> <c- p>{</c-> <c- k>return</c-> <c- mi>0</c-><c- p>;</c-> <c- p>}</c->
<c- p>};</c->

<c- b>int</c-> <c- nf>main</c-><c- p>()</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>to_string</c-><c- p>(</c-><c- n>S</c-><c- p>{});</c->
<c- p>}</c->
</pre>
    <p>This code must always call <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-><c- p>)</c-></code>.
If <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code> was not the same type as <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> and the implementation added an overload <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-><c- p>)</c-></code> in spite of the standard, the call to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-></code> would be ambiguous.</p>
   </div>
   <p>The implementation has <em>some</em> ability to add overloads, stated in [global.functions] paragraph 2:</p>
   <blockquote>
    <p>A call to a non-member function signature described in [support] through [thread] and [depr]
shall behave as if the implementation declared no additional non-member function signatures.</p>
   </blockquote>
   <p>This condition is not satisfied.
If a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-><c- p>)</c-></code> overload existed, the behavior would not be <em>as if</em> the implementation declared no additional signature.</p>
   <p class="note" role="note"><span class="marker">Note:</span> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-></code> is not a compiler extension; it’s an optional feature.
C23 <a data-link-type="biblio" href="#biblio-n3047" title="N3047 working draft — August 4, 2022 ISO/IEC 9899:2023 (E)">[N3047]</a> subclause 7.22.1.1 [Exact-width integer types] paragraph 3 requires
implementations to "define the corresponding typedef names" if there exists a
padding-free integer type with 128 bits.</p>
   <p>Even if you don’t find this example convincing, at best, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-></code> and other library support
would be optional.
There are also functions which undeniably cannot exist, like <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-><c- o>::</c-><c- n>to_u128</c-></code> (there are only <code class="highlight"><c- n>to_ulong</c-></code> and to <code class="highlight"><c- n>to_ullong</c-></code>).
It would be highly undesirable to have a 128-bit type but no standard library support which is
documented in the standard, and which is optional on a per-function basis, with no feature-testing macros.
Wording changes should be made to clean up this environment.</p>
   <h2 class="heading settled" data-level="3" id="motivation-and-scope"><span class="secno">3. </span><span class="content">Motivation and scope</span><a class="self-link" href="#motivation-and-scope"></a></h2>
   <p>There are compelling reasons for standardizing a 128-bit integer type:</p>
   <ol>
    <li data-md>
     <p><strong>Utility:</strong> 128-bit integers are extremely useful in a variety of domains.</p>
    <li data-md>
     <p><strong>Uniformity:</strong> Standardization would unify the many uses under a common name
and ideally, common ABI.</p>
    <li data-md>
     <p><strong>Existing practice:</strong> 128-bit integers are already implemented in multiple compilers
(see <a href="#existing-128-bit-integers">§ 8.1 Existing 128-bit integer types</a>).</p>
    <li data-md>
     <p><strong>Performance:</strong> It is difficult, if not impossible to optimize 128-bit operations
in software as well as the compiler could do for a builtin type (see <a href="#utilizing-hardware-support">§ 3.2 Utilizing hardware support</a>).</p>
    <li data-md>
     <p><strong>Low impact:</strong> The <a href="#impact-on-the-standard">§ 4 Impact on the standard</a> and <a href="#implementation-impact">§ 5 Impact on implementations</a> is reasonable.</p>
   </ol>
   <h3 class="heading settled" data-level="3.1" id="use-cases"><span class="secno">3.1. </span><span class="content">Use cases</span><a class="self-link" href="#use-cases"></a></h3>
   <p>A GitHub code search for <a href="/int128|int_128/ language:c++"><code class="highlight"><c- o>/</c-><c- n>int128</c-><c- o>|</c-><c- n>int_128</c-><c- o>/</c-> <c- n>language</c-><c- o>:</c-><c- n>c</c-><c- o>++</c-></code></a> yields 150K files,
and a language-agnostic search for <a href="https://github.com/search?q=%2Fint128%7Cint_128%2F&amp;type=code"><code class="highlight"><c- o>/</c-><c- n>int128</c-><c- o>|</c-><c- n>int_128</c-><c- o>/</c-></code></a> yields more than a million.</p>
   <p>While it is impossible to discuss every one of these,
I will introduce a few use cases of 128-bit integers.</p>
   <h4 class="heading settled" data-level="3.1.1" id="cryptography"><span class="secno">3.1.1. </span><span class="content">Cryptography</span><a class="self-link" href="#cryptography"></a></h4>
   <p>128-bit integers are commonly used in many cryptographic algorithms:</p>
   <ul>
    <li data-md>
     <p>Most notably, AES-128 uses a 128-bit key size.
AES variants with wider key sizes still use a block size of 128 bits.</p>
    <li data-md>
     <p>Various other block ciphers such as Twofish and Serpent also have key and/or block sizes of 128 bits.</p>
    <li data-md>
     <p>MD5 hashes produce 128-bit output.</p>
    <li data-md>
     <p>SHA-2 and SHA-3 produce outputs beyond 128-bit, but outputs can be truncated to 128-bit,
or represented as a pair/array of 128-bit integers.</p>
   </ul>
   <p>For example, the <a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard#The_AddRoundKey"> <code class="highlight"><c- n>AddRoundKey</c-></code> step in AES</a> is simply a 128-bit bitwise XOR.</p>
   <p>To be fair, the utility of 128-bit integers in cryptographic applications is often limited to
providing storage for blocks and keys.</p>
   <h4 class="heading settled" data-level="3.1.2" id="random-number-generation"><span class="secno">3.1.2. </span><span class="content">Random number generation</span><a class="self-link" href="#random-number-generation"></a></h4>
   <p>Some random number generators produce 128-bit numbers.</p>
   <p>For example, the <a href="https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator">CSRPNG</a> (cryptographically secure pseudo-random number generator) <a href="https://en.wikipedia.org/wiki/Fortuna_(PRNG)">Fortuna</a> uses a block cipher to produce random numbers.
When a 128-bit block cipher is used, the output is naturally 128-bit as well.
Fortuna is used in the implementation of <code class="highlight"><c- o>/</c-><c- n>dev</c-><c- o>/</c-><c- n>random</c-></code> in FreeBSD 11, and in AppleOSes since 2020.</p>
   <p>Some PRNGs use a 128-bit state, such as <a href="https://en.wikipedia.org/wiki/Xorshift">xorshift128</a>.</p>
   <div class="example" id="example-437c4029">
    <a class="self-link" href="#example-437c4029"></a> The following code is based on <a data-link-type="biblio" href="#biblio-marsaglia" title="Xorshift RNGs">[Marsaglia]</a>, with some changes. 
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- b>uint32_t</c-> <c- nf>xor128</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>uint32_t</c-> <c- n>x</c-><c- p>[</c-><c- mi>4</c-><c- p>])</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- b>uint32_t</c-> <c- n>t</c-> <c- o>=</c-> <c- n>x</c-><c- p>[</c-><c- mi>3</c-><c- p>];</c->
    <c- n>t</c-> <c- o>^=</c-> <c- n>t</c-> <c- o>&lt;&lt;</c-> <c- mi>11</c-><c- p>;</c->
    <c- n>t</c-> <c- o>^=</c-> <c- n>t</c-> <c- o>>></c-> <c- mi>8</c-><c- p>;</c->

    <c- n>x</c-><c- p>[</c-><c- mi>3</c-><c- p>]</c-> <c- o>=</c-> <c- n>x</c-><c- p>[</c-><c- mi>2</c-><c- p>];</c-> <c- n>x</c-><c- p>[</c-><c- mi>2</c-><c- p>]</c-> <c- o>=</c-> <c- n>x</c-><c- p>[</c-><c- mi>1</c-><c- p>];</c-> <c- n>x</c-><c- p>[</c-><c- mi>1</c-><c- p>]</c-> <c- o>=</c-> <c- n>x</c-><c- p>[</c-><c- mi>0</c-><c- p>];</c->

    <c- n>x</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-> <c- o>^=</c-> <c- n>t</c-> <c- o>^</c-> <c- p>(</c-><c- n>x</c-><c- p>[</c-><c- mi>0</c-><c- p>]</c-> <c- o>>></c-> <c- mi>19</c-><c- p>);</c->
    <c- k>return</c-> <c- n>x</c-><c- p>[</c-><c- mi>0</c-><c- p>];</c->
<c- p>}</c->
</pre>
    <p>This can be expressed more elegantly using 128-bit integers:</p>
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- b>uint32_t</c-> <c- nf>xor128</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- b>uint32_t</c-> <c- n>t</c-> <c- o>=</c-> <c- n>x</c-> <c- o>>></c-> <c- mi>96</c-><c- p>;</c->
    <c- n>t</c-> <c- o>^=</c-> <c- n>t</c-> <c- o>&lt;&lt;</c-> <c- mi>11</c-><c- p>;</c->
    <c- n>t</c-> <c- o>^=</c-> <c- n>t</c-> <c- o>>></c-> <c- mi>8</c-><c- p>;</c->

    <c- n>x</c-> <c- o>=</c-> <c- p>(</c-><c- n>x</c-> <c- o>&lt;&lt;</c-> <c- mi>32</c-><c- p>)</c-> <c- o>|</c-> <c- p>(</c-><c- n>t</c-> <c- o>^</c-> <c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>uint32_t</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-> <c- o>^</c-> <c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>uint32_t</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-> <c- o>>></c-> <c- mi>19</c-><c- p>)));</c->
    <c- k>return</c-> <c- n>x</c-><c- p>;</c->
<c- p>}</c->
</pre>
   </div>
   <p>Generally speaking, there is a large amount of code that effectively performs
128-bit operations, but operates on sequences of 32-bit or 64-bit integers.
In the above example, it is not immediately obvious that the <code class="highlight"><c- n>x</c-><c- p>[</c-><c- mi>3</c-><c- p>]</c-> <c- o>=</c-> <c- n>x</c-><c- p>[</c-><c- mi>2</c-><c- p>];</c-> <c- p>...</c-></code> line
is effectively performing a 32-bit shift, whereas <code class="highlight"><c- n>x</c-> <c- o>&lt;&lt;</c-> <c- mi>32</c-></code> is self-documenting.</p>
   <p><a data-link-type="biblio" href="#biblio-p2075r3" title="Philox as an extension of the C++ RNG engines">[P2075R3]</a> proposes counter-based Philox engines for the C++ standard library,
and has been received positively.
The <a data-link-type="biblio" href="#biblio-deshawresearch" title="Random123: a Library of Counter-Based Random Number Generators">[DEShawResearch]</a> reference implementation makes use of 128-bit integers.</p>
   <h4 class="heading settled" data-level="3.1.3" id="widening-operations"><span class="secno">3.1.3. </span><span class="content">Widening operations</span><a class="self-link" href="#widening-operations"></a></h4>
   <p>128-bit arithmetic can produce optimal code for mixed 64/128-bit operations,
for which there is already widespread hardware support.
Among other instructions, this hardware support includes:</p>
   <table>
    <tbody>
     <tr>
      <th>Operation
      <th>x86_64
      <th>ARM
      <th>RISC-V
     <tr>
      <td>64-to-128-bit unsigned multiply
      <td><code class="highlight"><c- n>mul</c-></code>: output to register pair <code class="highlight"><c- nl>rdx</c-><c- p>:</c-><c- n>rax</c-></code>
      <td><code class="highlight"><c- n>umulh</c-></code> for high bits, <code class="highlight"><c- n>mul</c-></code> for low bits
      <td><code class="highlight"><c- n>mulhu</c-></code> for high bits, <code class="highlight"><c- n>mulu</c-></code> for low bits
     <tr>
      <td>64-to-128-bit signed multiply
      <td><code class="highlight"><c- n>imul</c-></code>: output to register pair <code class="highlight"><c- nl>rdx</c-><c- p>:</c-><c- n>rax</c-></code>
      <td><code class="highlight"><c- n>smulh</c-></code> for high bits, <code class="highlight"><c- n>mul</c-></code> for low bits
      <td><code class="highlight"><c- n>mulsu</c-></code> for high bits, <code class="highlight"><c- n>muls</c-></code> for low bits
     <tr>
      <td>128-to-64-bit unsigned divide
      <td><code class="highlight"><c- n>div</c-></code>: <code class="highlight"><c- n>rax</c-></code> = quotient, <code class="highlight"><c- n>rdx</c-></code> = remainder
      <td>❌
      <td><code class="highlight"><c- n>divu</c-></code> (RV128I)
     <tr>
      <td>128-to-64-bit signed divide
      <td><code class="highlight"><c- n>idiv</c-></code>: <code class="highlight"><c- n>rax</c-></code> = quotient, <code class="highlight"><c- n>rdx</c-></code> = remainder
      <td>❌
      <td><code class="highlight"><c- n>divs</c-></code> (RV128I)
     <tr>
      <td>64-to-128-bit <a href="https://en.wikipedia.org/wiki/Carry-less_product">carry-less multiply</a>
      <td><code class="highlight"><c- n>pclmulqdq</c-></code>: output 128 bits to <code class="highlight"><c- n>xmm</c-></code> register
      <td><code class="highlight"><c- n>pmull</c-></code> for low bits, <code class="highlight"><c- n>pmull2</c-></code> for high bits
      <td><code class="highlight"><c- n>clmul</c-></code> for low bits, <code class="highlight"><c- n>clmulh</c-></code> for high bits
   </table>
   <p>Some operating systems also provide 64/128-bit operations.
For example, the Windows API provides a <code class="highlight"><c- n>Multiply128</c-></code> function.</p>
   <p>A more general solution was proposed by <a data-link-type="biblio" href="#biblio-p3018r0" title="Low-Level Integer Arithmetic">[P3018R0]</a>, which supports widening multiplication through a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>mul_wide</c-></code> function, which yields the low and high part of the multiplication as a pair
of integers.
Such utilities would be useful in generic code where integers of any width can be used.
For 64-to-128-bit, it’s obviously more ergonomic to cast operands to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code> prior to an
operation.</p>
   <div class="example" id="example-5312fa0e">
    <a class="self-link" href="#example-5312fa0e"></a> The <a data-link-type="biblio" href="#biblio-stockfish" title="Stockfish">[Stockfish]</a> chess engine has a <a href="https://github.com/official-stockfish/Stockfish/blob/7ccde25baf03e77926644b282fed68ba0b5ddf95/src/misc.h#L158"><code class="highlight"><c- n>mul_hi64</c-></code></a> function which yields the high part
of a 64-bit multiplication: 
<pre class="language-cpp highlight"><c- kr>inline</c-> <c- b>uint64_t</c-> <c- nf>mul_hi64</c-><c- p>(</c-><c- b>uint64_t</c-> <c- n>a</c-><c- p>,</c-> <c- b>uint64_t</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->
<c- cp>#if defined(__GNUC__) &amp;&amp; defined(IS_64BIT)</c->
    <c- n>__extension__</c-> <c- k>using</c-> <c- n>uint128</c-> <c- o>=</c-> <c- b>unsigned</c-> <c- b>__int128</c-><c- p>;</c->
    <c- k>return</c-> <c- p>(</c-><c- n>uint128</c-><c- p>(</c-><c- n>a</c-><c- p>)</c-> <c- o>*</c-> <c- n>uint128</c-><c- p>(</c-><c- n>b</c-><c- p>))</c-> <c- o>>></c-> <c- mi>64</c-><c- p>;</c->
<c- cp>#else</c->
    <c- c1>// ...</c->
<c- p>}</c->
</pre>
   </div>
   <h5 class="heading settled" data-level="3.1.3.1" id="safe-modular-arithmetic"><span class="secno">3.1.3.1. </span><span class="content">64-bit modular arithmetic</span><a class="self-link" href="#safe-modular-arithmetic"></a></h5>
   <p>To perform modular arithmetic with a 64-bit modulo, 128-bit integers are needed.
For example, when computing <code class="highlight"><c- p>(</c-><c- n>a</c-> <c- o>*</c-> <c- n>x</c-><c- p>)</c-> <c- o>%</c-> <c- n>m</c-></code> between 64-bit unsigned integers <code class="highlight"><c- n>a</c-></code>, <code class="highlight"><c- n>x</c-></code>, and <code class="highlight"><c- n>m</c-></code>,
the multiplication between <code class="highlight"><c- n>a</c-></code> and <code class="highlight"><c- n>x</c-></code> is already mod 2<sup>64</sup>,
and the result would be incorrect unless <code class="highlight"><c- n>m</c-></code> was a power of two.</p>
   <p>128-bit operations are used in implementations of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>linear_congruential_engine</c-></code> (see <a href="#random-implementation-experience">§ 8.2.10 &lt;random></a> for implementation experience).
Linear congruential engines use modular arithmetic, and since the user can choose
a modulo arbitrarily, the issue is unavoidable.</p>
   <p class="note" role="note"><span class="marker">Note:</span> A popular workaround for linear congruential generators is to choose the
modulo to be 2<sup>64</sup> or 2<sup>32</sup>.
This means that division is not required at all.</p>
   <h5 class="heading settled" data-level="3.1.3.2" id="multi-precision-operations"><span class="secno">3.1.3.2. </span><span class="content">Multi-precision operations</span><a class="self-link" href="#multi-precision-operations"></a></h5>
   <p>For various applications (cryptography, numerics, etc.) arithmetic with large widths is required.
For example, the RSA (Rivest–Shamir–Adleman) cryptosystem typically uses key sizes of 2048 or 4096.
"Scripting languages" also commonly use an infinite-precision integer type.
For example, the <code class="highlight"><c- b>int</c-></code> type in Python has no size limit.</p>
   <p>Multi-precision operations are implemented through multiple widening operations.
For example, to implement N-bit multiplication,
the number can be split into a sequence of 64-bit "limbs",
and long multiplication is performed.
Since this involves a carry between digits, a 64-to-128-bit widening operation is required.</p>
   <p><a data-link-type="biblio" href="#biblio-boostmultiprecision" title="Boost Multiprecision Library">[BoostMultiPrecision]</a> uses a 128-bit integer as a <code class="highlight"><c- n>double_limb_type</c-></code>.
This type is used extensively in the implementation of multi-precision arithmetic.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The introduction of bit-precise integers (<a href="#bit-precise-integers">§ 7.5 Why no bit-precise integers?</a>) does not
obsolete multi-precision libraries because infinite-precision numbers like
Python’s <code class="highlight"><c- b>int</c-></code> cannot be implement using a constant size.</p>
   <h4 class="heading settled" data-level="3.1.4" id="fixed-point-operations"><span class="secno">3.1.4. </span><span class="content">Fixed-point operations</span><a class="self-link" href="#fixed-point-operations"></a></h4>
   <p>While 64-bit integers are sufficient for many calculations, the amount of available bits
is reduced when the 64 bits are divided into an integral and fractional part.
This may cause issues in <a href="#financial-systems">§ 3.1.8 Financial systems</a>.</p>
   <p>Furthermore, fixed-point arithmetic with a double-wide operand can emulate integer division,
which is a relatively expensive operation, even with hardware support.</p>
   <div class="example" id="example-5318c4f4">
    <a class="self-link" href="#example-5318c4f4"></a> 128-bit integers allow us to implement a division by three without integer division: 
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- b>uint64_t</c-> <c- nf>div3</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>uint64_t</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- c1>// 1 / 3 as a Q63.65 fixed-point number:</c->
    <c- k>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- n>uint_fast128_t</c-> <c- n>reciprocal_3</c-> <c- o>=</c-> <c- mh>0xAAAA'AAAA'AAAA'AAAB</c-><c- p>;</c->
    <c- k>return</c-> <c- p>(</c-><c- n>x</c-> <c- o>*</c-> <c- n>reciprocal_3</c-><c- p>)</c-> <c- o>>></c-> <c- mi>65</c-><c- p>;</c-> <c- c1>// equivalent to return x / 3;</c->
<c- p>}</c->
</pre>
   </div>
   <p>While modern compilers perform this <a href="https://en.wikipedia.org/wiki/Strength_reduction">strength reduction optimization</a> for constant divisors already, they don’t perform it for frequently reused non-constant divisors.</p>
   <p>For such divisors, it can make sense to pre-compute the reciprocal and shift constants
and use them many times for faster division.
Among other libraries, <a data-link-type="biblio" href="#biblio-libdivide" title="libdivide">[libdivide]</a> uses this technique
(using a pair of 64-bit integers, which effectively forms a 128-bit integer).</p>
   <p class="note" role="note"><span class="marker">Note:</span> 3 is a "lucky" case because all nonzero bits fit into a 64-bit integer.
The amount of digits required differs between divisors.</p>
   <h4 class="heading settled" data-level="3.1.5" id="high-precision-clocks"><span class="secno">3.1.5. </span><span class="content">High-precision time calculations</span><a class="self-link" href="#high-precision-clocks"></a></h4>
   <p>64-bit integers are somewhat insufficient for high-precision clocks, if large time spans should
also be covered.
When counting nanoseconds, a maximum value of 2<sup>63</sup>-1 can only represent approximately
9 billion seconds, or 7020 years.
This is enough to keep time for the forseeable future, but is insufficient
for representing historical data long in the past.</p>
   <p>This makes 64-bit integers insufficient for some time calculations, where 128-bit integers
would suffice.
Alternatively, 64-bit floating-point numbers can provide a reasonable trade-off
between resolution and range.</p>
   <p><code class="highlight"><c- n>timespec</c-></code> is effectively a 128-bit type in POSIX (<code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>timespec</c-></code> in C++), since both the
seconds and nanoseconds part of the class are 64-bit integers
(assuming that <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>time_t</c-></code> is 64-bit).</p>
   <p><a data-link-type="biblio" href="#biblio-bloomberg" title="BDE Libraries">[Bloomberg]</a> uses 128-bit integers to safeguard against potential overflow in time
calculations (see <a href="https://github.com/kaidokert/bde/blob/b1c60d6b33e4fa1c596ac6947a7a38fc87286626/groups/bsl/bsls/bsls_timeutil.cpp#L523"><code class="highlight"><c- n>bsls_timeutil</c-><c- p>.</c-><c- n>cpp</c-></code></a>)</p>
   <h4 class="heading settled" data-level="3.1.6" id="floating-point-operations"><span class="secno">3.1.6. </span><span class="content">Floating-point operations</span><a class="self-link" href="#floating-point-operations"></a></h4>
   <p>The implementation of IEEE 754/IEC-559 floating-point operations often involves examining the
bit-representation of the floating-point number through an unsigned integer.</p>
   <p>The C++ standard provides <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>float128_t</c-></code>, but no matching 128-bit integer type,
which makes this more difficult.</p>
   <div class="example" id="example-90d97578">
    <a class="self-link" href="#example-90d97578"></a> Using 128-bit integers, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>signbit</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>float128_t</c-><c- p>)</c-></code> can be implemented as follows: 
<pre class="language-cpp highlight"><c- k>constexpr</c-> <c- b>bool</c-> <c- nf>signbit</c-><c- p>(</c-><c- n>float128_t</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>bit_cast</c-><c- o>&lt;</c-><c- n>uint128_t</c-><c- o>></c-><c- p>(</c-><c- n>x</c-><c- p>)</c-> <c- o>>></c-> <c- mi>127</c-><c- p>;</c->
<c- p>}</c->
</pre>
   </div>
   <div class="example" id="example-e45f1dae">
    <a class="self-link" href="#example-e45f1dae"></a> Using 128-bit integers, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>isinf</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>float128_t</c-><c- p>)</c-></code> can be implemented as follows: 
<pre class="language-cpp highlight"><c- k>constexpr</c-> <c- n>float128_t</c-> <c- nf>abs</c-><c- p>(</c-><c- n>float128_t</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>bit_cast</c-><c- o>&lt;</c-><c- n>float128_t</c-><c- o>></c-><c- p>(</c-><c- n>bit_cast</c-><c- o>&lt;</c-><c- n>uint128_t</c-><c- o>></c-><c- p>(</c-><c- n>x</c-><c- p>)</c-> <c- o>&amp;</c-> <c- p>(</c-><c- n>uint128_t</c-><c- p>(</c-><c- mi>-1</c-><c- p>)</c-> <c- o>>></c-> <c- mi>1</c-><c- p>));</c->
<c- p>}</c->

<c- k>constexpr</c-> <c- b>bool</c-> <c- nf>isinf</c-><c- p>(</c-><c- n>float128_t</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>bit_cast</c-><c- o>&lt;</c-><c- n>uint128_t</c-><c- o>></c-><c- p>(</c-><c- n>abs</c-><c- p>(</c-><c- n>x</c-><c- p>))</c-> <c- o>==</c-> <c- mh>0x7fff'0000'0000'0000'0000'0000'0000'0000</c-><c- p>;</c->
<c- p>}</c->
</pre>
   </div>
   <p class="note" role="note"><span class="marker">Note:</span> Infinity for <a href="https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format"><em>binary128</em></a> numbers is represented as any sign bit, 15 exponent bits all set to <code class="highlight"><c- mi>1</c-></code>,
and 112 mantissa bits all set to <code class="highlight"><c- mi>0</c-></code>.</p>
   <p><a data-link-type="biblio" href="#biblio-bloomberg" title="BDE Libraries">[Bloomberg]</a> uses 128-bit integers as part of a 128-bit decimal floating point
implementation, among other uses.
Decimal floating-point numbers are commonly used in financial applications
and are standard C23 types (e.g. <code class="highlight"><c- n>_Decimal128</c-></code>) since <a data-link-type="biblio" href="#biblio-n2341" title="Floating-point extensions for C - Decimal floating-point arithmetic">[N2341]</a>.
In C++, a software implementation is necessary.</p>
   <h4 class="heading settled" data-level="3.1.7" id="float-string-conversion"><span class="secno">3.1.7. </span><span class="content">Float-to-string/String-to-float conversion</span><a class="self-link" href="#float-string-conversion"></a></h4>
   <p>The <a data-link-type="biblio" href="#biblio-dragonbox" title="Dragonbox: A New FLoating-Point Binary-to-Decimal Conversion Algorithm">[Dragonbox]</a> binary-to-decimal conversion algorithm requires an integer type
that is twice the width of the converted floating-point number.
To convert a floating-point number in <a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format">binary64</a> format, a 128-bit integer type is used.</p>
   <p>Similarly, <a data-link-type="biblio" href="#biblio-fast_float" title="fast_float number parsing library: 4x faster than strtod">[fast_float]</a> uses 128-bit numbers as part of decimal-to-binary conversions.
This library provides an efficient <code class="highlight"><c- n>from_chars</c-></code> implementation.</p>
   <h4 class="heading settled" data-level="3.1.8" id="financial-systems"><span class="secno">3.1.8. </span><span class="content">Financial systems</span><a class="self-link" href="#financial-systems"></a></h4>
   <p>128-bit integers can be used to represent huge monetary values with high accuracy.
When representing cents of a dollar as a 64-bit integer,
a monetary value of up to 184.5 quadrillion dollars can be represented.
However, this value shrinks dramatically when using smaller fractions.</p>
   <p>Since 2005, stock markets are legally required to accept
price increments of $0.0001 when the price of a stock is ≤ $1 (see <a data-link-type="biblio" href="#biblio-sec" title="Division of Market Regulation: Responses to Frequently Asked Questions Concerning Rule 612 (Minimum Pricing Increment) of Regulation NMS">[SEC]</a>).
At this precision, 1.84 quadrillion dollars can be represented.
Using a uniform precision of ten thousandths would prove problematic when
applied to other currencies such as Yen, which forces the complexity of variable precision
on the developer.</p>
   <p>Even more extremely, the smallest fraction of a Bitcoin is a Satoshi, which is a
hundred millionth of a Bitcoin.
2<sup>63</sup> Satoshis equal approximately 92 billion BTC.
In 2009, a Bitcoin was worth less than a penny, so a monetary value of only
920 million USD could be represented in Satoshis.</p>
   <p>In conclusion, simply storing the smallest relevant fraction as a 64-bit integer is
often insufficient, especially when this fraction is very small and exponential
price changes are involved.
Rounding is not always an acceptable solution in financial applications.</p>
   <p><a data-link-type="biblio" href="#biblio-nvidia" title="Implementing High-Precision Decimal Arithmetic with CUDA int128">[NVIDIA]</a> mentions fixed-point accounting calculations as a possible use case of the <code class="highlight"><c- b>__int128</c-></code> type, which is a preview feature of NVIDIA CUDA 11.5.</p>
   <p><a data-link-type="biblio" href="#biblio-tigerbeetle" title="64-Bit Bank Balances ‘Ought to be Enough for Anybody’?">[TigerBeetle]</a> discusses why 64-bit integers have been retired in favor of 128-bit
integers to store financial amounts and balances in the TigerBeetle financial
accounting database.
The aforementioned sub-penny requirement is part of the motivation.</p>
   <h4 class="heading settled" data-level="3.1.9" id="uuid"><span class="secno">3.1.9. </span><span class="content">Universally unique identifiers</span><a class="self-link" href="#uuid"></a></h4>
   <p>A 128-bit integer can be used to represent a <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">UUID</a> (Universally Unique Identifier).
While 64-bit integers are often sufficient as a unique identifier, it is quite likely that two
identical identifiers are chosen by a random number generator over a long period of time,
especially considering the <a href="https://en.wikipedia.org/wiki/Birthday_problem">Birthday Problem</a>.
Therefore, at least 128 bits are typically used for such applications.</p>
   <div class="example" id="example-7d167d1f">
    <a class="self-link" href="#example-7d167d1f"></a> The following code generates a UUIDv4, represented as an unsigned 128-bit integer. 
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-> <c- nf>random_uuid_v4</c-><c- p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>experimental</c-><c- o>::</c-><c- n>randint</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-><c- o>></c-><c- p>(</c-><c- mi>0</c-><c- p>,</c-> <c- mi>-1</c-><c- p>)</c->
         <c- o>&amp;</c-> <c- mh>0x</c-><c- mh><c- mh>ffff</c-></c-><c- mh>'</c-><c- mh><c- mh>ffff</c-></c-><c- mh>'</c-><c- mh><c- mh>ffff</c-></c-><c- mh>'</c-><c- mh><c- mh>003f</c-></c-><c- mh>'</c-><c- mh><c- mh>ff0f</c-></c-><c- mh>'</c-><c- mh><c- mh>ffff</c-></c-><c- mh>'</c-><c- mh><c- mh>ffff</c-></c-><c- mh>'</c-><c- mh><c- mh>ffff</c-></c->  <c- c1>// clear version and variant</c->
         <c- o>|</c-> <c- mh>0x</c-><c- mh><c- mh>0000</c-></c-><c- mh>'</c-><c- mh><c- mh>0000</c-></c-><c- mh>'</c-><c- mh><c- mh>0000</c-></c-><c- mh>'</c-><c- mh><c- mh>0080</c-></c-><c- mh>'</c-><c- mh><c- mh>0040</c-></c-><c- mh>'</c-><c- mh><c- mh>0000</c-></c-><c- mh>'</c-><c- mh><c- mh>0000</c-></c-><c- mh>'</c-><c- mh><c- mh>0000</c-></c-><c- p>;</c-> <c- c1>// set to version 4 and IETF variant</c->
<c- p>}</c->
</pre>
   </div>
   <p>The <a data-link-type="biblio" href="#biblio-clickhouse" title="ClickHouse">[ClickHouse]</a> database management system defines their <code class="highlight"><c- n>UUID</c-></code> type through <a href="https://github.com/ClickHouse/ClickHouse/blob/fc964d6ddd2f854cbff9d036abf424a2f3b7194f/base/base/UUID.h#L8"><code class="highlight"><c- n>StrongTypedef</c-><c- o>&lt;</c-><c- n>UInt128</c-><c- p>,</c-> <c- k>struct</c-> <c- nc>UUIDTag</c-><c- o>></c-></code></a>.</p>
   <h4 class="heading settled" data-level="3.1.10" id="networking"><span class="secno">3.1.10. </span><span class="content">Networking</span><a class="self-link" href="#networking"></a></h4>
   <p>IPv6 addresses can be represented as a 128-bit integer.
This may be a convenient representation because bitwise operations for masking and accessing
individual bits or bit groups may be used.
Implementing these is much easier using a 128-bit integers compared to multi-precision operations
using two 64-bit integers.</p>
   <div class="example" id="example-a484ba65">
    <a class="self-link" href="#example-a484ba65"></a> An IPv6 address in link-local address format can be identified as follows: 
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-> <c- n>ipv6</c-> <c- o>=</c-> <c- d>/* ... */</c-><c- p>;</c->
<c- k>constexpr</c-> <c- k>auto</c-> <c- n>mask10</c-> <c- o>=</c-> <c- mh>0x3ff</c-><c- p>;</c->
<c- k>if</c-> <c- p>((</c-><c- n>ipv6</c-> <c- o>&amp;</c-> <c- n>mask10</c-><c- p>)</c-> <c- o>!=</c-> <c- mb>0b1111111010</c-><c- p>)</c-> <c- d>/* wrong prefix */</c-><c- p>;</c->

<c- k>constexpr</c-> <c- k>auto</c-> <c- n>mask54</c-> <c- o>=</c-> <c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>uint64_t</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-> <c- o>&lt;&lt;</c-> <c- mi>54</c-><c- p>)</c-> <c- o>-</c-> <c- mi>1</c-><c- p>;</c->
<c- k>if</c-> <c- p>((</c-><c- n>ipv6</c-> <c- o>>></c-> <c- mi>10</c-> <c- o>&amp;</c-> <c- n>mask54</c-><c- p>)</c-> <c- o>!=</c-> <c- mi>0</c-><c- p>)</c-> <c- d>/* expected 54 zeros */</c-><c- p>;</c->

<c- k>constexpr</c-> <c- k>auto</c-> <c- n>mask64</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- b>uint64_t</c-><c- p>(</c-><c- mi>-1</c-><c- p>);</c->
<c- n>interface_identifier</c-> <c- o>=</c-> <c- p>(</c-><c- n>data</c-> <c- o>>></c-> <c- mi>64</c-><c- p>)</c-> <c- o>&amp;</c-> <c- n>mask64</c-><c- p>;</c->
</pre>
   </div>
   <p>The <a data-link-type="biblio" href="#biblio-clickhouse" title="ClickHouse">[ClickHouse]</a> database management system defines their <code class="highlight"><c- n>IPv6</c-></code> type through <a href="https://github.com/ClickHouse/ClickHouse/blob/0c35492ed33333a2e39f57d8e3c196d1fd22ae22/base/base/IPv4andIPv6.h#L18"><code class="highlight"><c- n>StrongTypedef</c-><c- o>&lt;</c-><c- n>UInt128</c-><c- p>,</c-> <c- k>struct</c-> <c- nc>IPv6Tag</c-><c- o>></c-></code></a>.</p>
   <h4 class="heading settled" data-level="3.1.11" id="bitsets-and-lookup-tables"><span class="secno">3.1.11. </span><span class="content">Bitsets and lookup tables</span><a class="self-link" href="#bitsets-and-lookup-tables"></a></h4>
   <p>A popular technique for optimizing small lookup tables in high-performance applications
is to turn them into a bitset.
128 bits offer additional space over 64 bits.</p>
   <div class="example" id="example-ec05135d">
    <a class="self-link" href="#example-ec05135d"></a> Axis vectors (<code class="highlight"><c- p>(</c-><c- mi>-1</c-><c- p>,</c-> <c- mi>0</c-><c- p>,</c-> <c- mi>0</c-><c- p>)</c-></code>, <code class="highlight"><c- p>(</c-><c- mi>1</c-><c- p>,</c-> <c- mi>0</c-><c- p>,</c-> <c- mi>0</c-><c- p>)</c-></code>, ..., or <code class="highlight"><c- p>(</c-><c- mi>0</c-><c- p>,</c-> <c- mi>0</c-><c- p>,</c-> <c- mi>1</c-><c- p>)</c-></code>)
can be represented as integers in range [0, 6).
This requires three bits of storage, and a lookup table for the cross product of two vectors
requires 3<sup>3</sup> = 81 bits.
The cross product can be computed as follows: 
<pre class="language-cpp highlight"><c- b>unsigned</c-> <c- nf>cross</c-><c- p>(</c-><c- b>unsigned</c-> <c- n>a</c-><c- p>,</c-> <c- b>unsigned</c-> <c- n>b</c-><c- p>)</c-> <c- p>{</c->
    <c- p>[[</c-><c- n>assume</c-><c- p>(</c-><c- n>a</c-> <c- o>&lt;</c-> <c- mi>6</c-> <c- o>&amp;&amp;</c-> <c- n>b</c-> <c- o>&lt;</c-> <c- mi>6</c-><c- p>)]];</c->
    <c- k>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-> <c- n>lookup</c-> <c- o>=</c-> <c- mh>0x201'6812'1320'8941'06c4'ec21'a941</c-><c- p>;</c->
    <c- k>return</c-> <c- p>(</c-><c- n>lookup</c-> <c- o>>></c-> <c- p>(</c-><c- n>a</c-> <c- o>*</c-> <c- mi>6</c-> <c- o>+</c-> <c- n>b</c-> <c- o>*</c-> <c- mi>3</c-><c- p>))</c-> <c- o>&amp;</c-> <c- mb>0b111</c-><c- p>;</c->
<c- p>}</c->
</pre>
    <p>This is significantly faster than computing a cross product between triples of <code class="highlight"><c- b>int</c-></code> or <code class="highlight"><c- b>float</c-></code> using multiplication and subtraction.</p>
   </div>
   <p>Using unsigned integers as lookup tables is a very popular technique in chess engines,
and commonly referred to as <a href="https://en.wikipedia.org/wiki/Bitboard">Bitboard</a>.
The <a data-link-type="biblio" href="#biblio-px0" title="Px0">[px0]</a> chess engine uses a 90-bit board, stored in a 128-bit integer.</p>
   <p class="note" role="note"><span class="marker">Note:</span> Compilers can only perform an "array-to-bitset optimization" to a limited extent at this time.
Clang is the only compiler which performs it, and only for arrays of <code class="highlight"><c- b>bool</c-></code>.</p>
   <p class="note" role="note"><span class="marker">Note:</span> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code> does not offer a way to extract ranges of bits, only individual bits.
Therefore, it would not have been of much help in the example.
Furthermore, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code> has runtime checks and potentially throws exceptions,
which makes it unattractive to some language users.</p>
   <h3 class="heading settled" data-level="3.2" id="utilizing-hardware-support"><span class="secno">3.2. </span><span class="content">Utilizing hardware support</span><a class="self-link" href="#utilizing-hardware-support"></a></h3>
   <h4 class="heading settled" data-level="3.2.1" id="future-proofing"><span class="secno">3.2.1. </span><span class="content">Future-proofing for direct 128-bit support</span><a class="self-link" href="#future-proofing"></a></h4>
   <p>Hardware support for 64/128-bit mixed operations is already common
in x86_64 and ARM.
It is also conceivable that hardware support for 128-bit integer arithmetic will be expanded
in the forseeable future.
The RISC-V instruction set architecture has a 128-bit variant named RV128I,
described in <a data-link-type="biblio" href="#biblio-risc-v" title="The RISC-V Instruction Set Manual - Volume I: Unprivileged ISA">[RISC-V]</a>, although no implementation of it exists yet.</p>
   <p>When hardware support for 128-bit operations is available, but the source code emulates these
in software, the burden of fusing multiple 64-bit operations into a single 128-bit operation
is put on the optimizer.</p>
   <p>For example, multiple 64-bit multiplications may be fused into a single 64-to-128-bit
multiplication.
x86_64 already provides hardware support in this case (see <a href="#widening-operations">§ 3.1.3 Widening operations</a>), however,
the language provides no way of expressing such an operation through integer types.</p>
   <h4 class="heading settled" data-level="3.2.2" id="support-through-128-bit-floating-point"><span class="secno">3.2.2. </span><span class="content">Support through 128-bit floating-point</span><a class="self-link" href="#support-through-128-bit-floating-point"></a></h4>
   <p>On hardware which provides native support for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>float128_t</c-></code> (see <a data-link-type="biblio" href="#biblio-wikipedia" title="Quadruple-precision floating-point format - Hardware support">[Wikipedia]</a> for a list), integer division up to 113
bits can be implemented in terms of floating-point division, and this is possibly the fastest routine.
For such instruction selection, the 113-bit division must be recognized by the compiler.
It is very unlikely that the hundreds of operations
comprising a software integer division could be recognized as such.</p>
   <p>128 bits is obviously more than 113 bits, so not every operation can be performed this way.
However, modern optimizing compilers keep track of range constraints of values.</p>
   <div class="example" id="example-f8cef829">
    <a class="self-link" href="#example-f8cef829"></a> The optimizer may make the following decisions when performing 128-bit integer division: 
    <ol>
     <li data-md>
      <p>If the divisor is zero, mark the operation undefined behavior for the purpose of
compiler optimization, or emit <code class="highlight"><c- n>ud2</c-></code>.</p>
     <li data-md>
      <p>Otherwise, if the divisor and dividend are constant, compute the result.</p>
     <li data-md>
      <p>Otherwise, if the divisor is constant and greater than the dividend, yield zero.</p>
     <li data-md>
      <p>Otherwise, if the divisor is constant, perform strength reduction (<a href="#fixed-point-operations">§ 3.1.4 Fixed-point operations</a>), making the division
a shift and multiplication.</p>
     <li data-md>
      <p>Otherwise, if the divisor is a power of two, count the trailing zeros and perform a right-shift.</p>
     <li data-md>
      <p>Otherwise, if both operands are 2<sup>64</sup>-1 or less, perform 64-bit integer division.</p>
     <li data-md>
      <p>Otherwise, if one of the operands is 2<sup>64</sup>-1 or less, perform 128-to-64-bit (<a href="#widening-operations">§ 3.1.3 Widening operations</a>) division.</p>
     <li data-md>
      <p><b>Otherwise, if both operands are 2<sup>113</sup>-1 or less,
and if there is hardware support for 128-bit floating point numbers, perform floating-point division.</b></p>
     <li data-md>
      <p>Otherwise, use a software implementation of 128-bit division.</p>
    </ol>
   </div>
   <p>ISO C++ does not offer a mechanism through which implementations can be chosen based on
optimizer knowledge.
What is easy for the implementation is difficult for the user,
which makes it very compelling to provide a built-in type.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The pre-computation in bullet 4 must not be done in C++
because the cost of computing the reciprocal is as high as the division itself.
The user must be guaranteed that the entire pre-computation of shift and factor is constant-folded,
and this is generally impossible because optimization passes are finite.</p>
   <p class="note" role="note"><span class="marker">Note:</span> Historically, floating-point division in hardware was used to implement integer division.
The x87 circuitry for dividing 80-bit floating-point numbers could be repurposed for 64-bit
integer division.
This strategy is still many times faster than software division.
Intel desktop processors have received dedicated integer dividers starting with Cannon Lake.</p>
   <h2 class="heading settled" data-level="4" id="impact-on-the-standard"><span class="secno">4. </span><span class="content">Impact on the standard</span><a class="self-link" href="#impact-on-the-standard"></a></h2>
   <p>First and foremost, this proposal mandates the following integer types in <code class="highlight"><c- o>&lt;</c-><c- n>cstdint</c-><c- o>></c-></code>:</p>
<pre class="language-cpp highlight"><c- k>using</c-> <c- n>int_least128_t</c->  <c- o>=</c-> <c- d>/* signed integer type */</c-><c- p>;</c->
<c- k>using</c-> <c- n>uint_least128_t</c-> <c- o>=</c-> <c- d>/* unsigned integer type */</c-><c- p>;</c->

<c- k>using</c-> <c- n>int_fast128_t</c->   <c- o>=</c-> <c- d>/* signed integer type */</c-><c- p>;</c->
<c- k>using</c-> <c- n>uint_fast128_t</c->  <c- o>=</c-> <c- d>/* unsigned integer type */</c-><c- p>;</c->

<c- k>using</c-> <c- n>int128_t</c-> <c- o>=</c-> <c- d>/* signed integer type */</c-><c- p>;</c-> <c- c1>// optional</c->
<c- k>using</c-> <c- n>uint128_t</c-> <c- o>=</c-> <c- d>/* unsigned integer type */</c-><c- p>;</c-> <c- c1>// optional</c->

<c- c1>// TODO: define corresponding macros/specializations in &lt;cinttypes>, &lt;climits>, &lt;limits>, ...</c->
</pre>
   <p>This change in itself is almost no change at all.
The implementation can already provide <code class="highlight"><c- n>int_least128_t</c-></code> while complying with the C++11 standard.
Challenges only arise when considering the impact of these new types on the rest of the
standard library, and possibly C compatibility.</p>
   <p class="note" role="note"><span class="marker">Note:</span> A compliant libstdc++ implementation could define all aliases as <code class="highlight"><c- b>__int128</c-></code>.</p>
   <h3 class="heading settled" data-level="4.1" id="c-compatibility"><span class="secno">4.1. </span><span class="content">C Compatibility</span><a class="self-link" href="#c-compatibility"></a></h3>
   <p>This proposal makes the assumption that C++26 will be based on C23.
Any attempt of standardizing 128-bit integers must also keep possible compatibility with the C
standard in mind.</p>
   <h4 class="heading settled" data-level="4.1.1" id="intmax-t"><span class="secno">4.1.1. </span><span class="content"><code class="highlight"><c- b>intmax_t</c-></code> and <code class="highlight"><c- b>uintmax_t</c-></code></span><a class="self-link" href="#intmax-t"></a></h4>
   <p>In particular, <code class="highlight"><c- b>intmax_t</c-></code> has historically prevented implementations from providing
integer types wider than <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> without breaking ABI compatibility.
A wider integer type would change the width of <code class="highlight"><c- b>intmax_t</c-></code>.</p>
   <p>C23 has relaxed the definition of <code class="highlight"><c- b>intmax_t</c-></code>. <a data-link-type="biblio" href="#biblio-n3047" title="N3047 working draft — August 4, 2022 ISO/IEC 9899:2023 (E)">[N3047]</a>, 7.22.1.5 [Greatest-width integer types] currently defines <code class="highlight"><c- b>intmax_t</c-></code> as follows:</p>
   <blockquote>
     The following type designates a signed integer type, other than a bit-precise integer type, capable of
representing any value of any signed integer type with the possible exceptions of signed bit-precise
integer types and of signed extended integer types that are wider than <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> and that are
referred by the type definition for an exact width integer type: 
<pre class="language-cpp highlight"><c- b>intmax_t</c->
</pre>
   </blockquote>
   <p>For <code class="highlight"><c- b>intmax_t</c-></code> to not be <code class="highlight"><c- n>int_least128_t</c-></code>,
there must exist an <code class="highlight"><c- n>int128_t</c-></code> alias for the same type.
GCC already provides an <code class="highlight"><c- b>__int128</c-></code> type which satisfies the padding-free requirement and could
be exposed as <code class="highlight"><c- n>int128_t</c-></code>.</p>
   <p>In conclusion, it is possible to provide a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> alias with equivalent
semantics in C and C++, and with no ABI break.</p>
   <h4 class="heading settled" data-level="4.1.2" id="int-least128-t-in-c"><span class="secno">4.1.2. </span><span class="content"><code class="highlight"><c- n>int_least128_t</c-></code> in C</span><a class="self-link" href="#int-least128-t-in-c"></a></h4>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> does not force <code class="highlight"><c- n>int_least128_t</c-></code> to exist in C.
In principle, C++ compilers can disable support for the type in C mode, so that there is
effectively no impact.</p>
   <p>However, this would be somewhat undesirable because there would be no mandatory interoperable type.
C users would use <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code> or <code class="highlight"><c- b>__int128</c-></code> and C++ users would use <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code>,
which would only be <code class="highlight"><c- b>__int128</c-></code> by coincidence.
For the sake of QoI, implementations should expose the corresponding alias in C as well
(which they are allowed to).</p>
   <p>To make the type mandatory in both languages, cooperation from WG14 is needed.</p>
   <h4 class="heading settled" data-level="4.1.3" id="c-library-impact"><span class="secno">4.1.3. </span><span class="content">C library impact</span><a class="self-link" href="#c-library-impact"></a></h4>
   <p>A C++ implementation is required to provide compatibility headers as per
[support.c.headers] which have equivalent semantics to the headers in C,
with some details altered.
The affected candidates are those listed in Table 40: C headers [tab:c.headers].</p>
   <table>
    <tbody>
     <tr>
      <th>Header
      <th>Impact of extended integers
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code>
      <td>Define macro constants
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>limits</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code>
      <td>Define macro constants
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>stdatomic</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code>
      <td>Define type aliases
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>stdint</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code>
      <td>Define type aliases
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>stdio</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code>
      <td>Support 128-bit <code class="highlight"><c- n>printf</c-></code>/<code class="highlight"><c- n>scanf</c-></code> optionally 
   </table>
   <p>There is no impact on other C headers.
Most of the issues are trivial and have no runtime C library impact.
The only thing worth noting is that 128-bit support from <code class="highlight"><c- n>printf</c-></code>/<code class="highlight"><c- n>scanf</c-></code> would be
required (<a href="#cstdio-implementation-experience">§ 8.2.17 &lt;cstdio></a> for implementation experience).</p>
   <p class="note" role="note"><span class="marker">Note:</span> This support is made optional, so that C++ implementations are able to keep using
the system’s C library.
Otherwise, the C++ implementation could only guarantee 128-bit <code class="highlight"><c- n>printf</c-></code> support
if it was part of the C++ runtime library.</p>
   <p class="note" role="note"><span class="marker">Note:</span> If additionally, a C implementation wanted to support <code class="highlight"><c- n>int_least128_t</c-></code>,
it would need to add extended integer support in a few other places.
For example, <code class="highlight"><c- n>stdbit</c-><c- p>.</c-><c- n>h</c-></code> requires type-generic functions to support all extended integers.</p>
   <h3 class="heading settled" data-level="4.2" id="core-impact"><span class="secno">4.2. </span><span class="content">Impact on the core language</span><a class="self-link" href="#core-impact"></a></h3>
   <p>The proposal makes no changes to the core language
because existing semantics of extended integers are sufficient
(see <a href="#extended-conversion-rank">§ 7.7 Should extended integer semantics be changed?</a> for discussion).
See also <a href="#user-defined-literals">§ 7.8 Do we need new user-defined literals?</a>.</p>
   <h4 class="heading settled" data-level="4.2.1" id="note-on-surprising-semantics"><span class="secno">4.2.1. </span><span class="content">Note on surprising semantics</span><a class="self-link" href="#note-on-surprising-semantics"></a></h4>
   <p>It is worth noting that the existence of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code> leads to some oddities:</p>
   <ul>
    <li data-md>
     <p>The result of the <code class="highlight"><c- k>sizeof</c-></code> operator can be a 128-bit integer.</p>
    <li data-md>
     <p>The underlying type of enumerations can be a 128-bit integer.</p>
    <li data-md>
     <p>Previously ill-formed integer literals could now be of 128-bit integer type.</p>
    <li data-md>
     <p>The conditions in <code class="highlight"><c- cp>#if</c-></code> preprocessing directives are evaluated as if operands had the same
representation as <code class="highlight"><c- b>intmax_t</c-></code> or <code class="highlight"><c- b>uintmax_t</c-></code>,
which means that 128-bit integers cannot be used in this context, or the values
would be truncated.</p>
   </ul>
   <p>However, none of this is a new issue introduced by this proposal.
Any compliant implementation could already have produced this behavior,
assuming it supported 128-bit integers as an optional extended integer type.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The fact that the preprocessor doesn’t operate on the widest integer type,
but on <code class="highlight"><c- b>intmax_t</c-></code> will need to be addressed.
However, this is a general problem with rebasing on C23 and not within the scope
of this proposal.</p>
   <h3 class="heading settled" data-level="4.3" id="library-impact"><span class="secno">4.3. </span><span class="content">Impact on the library</span><a class="self-link" href="#library-impact"></a></h3>
   <p>Find below a summary of issues that arise from the introduction of 128-bit integers in the
C++ standard library.
One common issue is that aliases such as <code class="highlight"><c- n>size_type</c-></code> and <code class="highlight"><c- n>difference_type</c-></code> within
containers, iterators, and other types can be a 128-bit integer.
The same applies to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>size_t</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>ptrdiff_t</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intmax_t</c-></code>.</p>
   <p>The proposal does not force library maintainers to re-define any of these aliases;
it’s just a possibility.
Whether to define them as such is a QoI issue in general, and won’t be discussed further.</p>
   <h4 class="heading settled" data-level="4.3.1" id="library-impact-language-support"><span class="secno">4.3.1. </span><span class="content">Language support library</span><a class="self-link" href="#library-impact-language-support"></a></h4>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>div</c-></code> may need an overload for 128-bit integers.<br> <strong>Action:</strong> ✔️ None because we don’t support it (see <a href="#div">§ 7.9 Why no std::div?</a>).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_integer</c-></code> may need 128-bit support.<br> <strong>Action:</strong> ✔️ None
(see <a href="#to-integer-implementation-experience">§ 8.2.1 std::to_integer</a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- o>&lt;</c-><c- n>version</c-><c- o>></c-></code> needs 128-bit integer feature-testing macro.<br> <strong>Action:</strong> ⚠️ Add macros (see <a href="#proposed-version">§ 9.1 Header &lt;version></a> for wording).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- o>&lt;</c-><c- n>numeric_limits</c-><c- o>></c-></code> needs a trait for 128-bit integers.<br> <strong>Action:</strong> ✔️ None.</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- o>&lt;</c-><c- n>climits</c-><c- o>></c-></code> needs additional constants for 128-bit integers.<br> <strong>Action:</strong> ✔️ None.</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- o>&lt;</c-><c- n>cstdint</c-><c- o>></c-></code> needs to explicitly require support for 128-bit integers
in its synopsys.<br> <strong>Action:</strong> ⚠️ Define aliases (see <a href="#proposed-cstdint">§ 9.2 Header &lt;cstdint></a> for wording).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code> needs to support 128-bit only optionally.<br> <strong>Action:</strong> ⚠️ Make support optional (see <a href="#proposed-inttypes">§ 9.3 Header &lt;inttypes.h></a> for wording).</p>
   <h4 class="heading settled" data-level="4.3.2" id="library-impact-metaprogramming"><span class="secno">4.3.2. </span><span class="content">Metaprogramming library</span><a class="self-link" href="#library-impact-metaprogramming"></a></h4>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>is_integral</c-></code> needs to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None
(see <a href="#type-traits-implementation-experience">§ 8.2.2 &lt;type_traits></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>make_signed</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>make_unsigned</c-></code> require 128-bit support.<br> <strong>Action:</strong> ✔️ None
(see <a href="#type-traits-implementation-experience">§ 8.2.2 &lt;type_traits></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ratio</c-></code> currently accepts non-type template arguments of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intmax_t</c-></code>. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intmax_t</c-></code> is no longer the widest integer type and changing the type of NTTP to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code> would be an ABI break because the type of template argument participates
in name mangling.<br> <strong>Action:</strong> ✔️ None
(see <a href="#ratio-dilemma">§ 7.10 What about the std::ratio dilemma?</a> for discussion).</p>
   <h4 class="heading settled" data-level="4.3.3" id="library-impact-utilities"><span class="secno">4.3.3. </span><span class="content">General utilities library</span><a class="self-link" href="#library-impact-utilities"></a></h4>
   <p><strong>Issue:</strong> Integer comparison functions (<code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cmp_equal</c-></code> et al.) require 128-bit support.<br> <strong>Action:</strong> ✔️ None
(see <a href="#safe-comparison-implementation-experience">§ 8.2.3 std::cmp_xxx</a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>integer_sequence</c-></code> needs to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None.</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code> could receive an additional constructor taking <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code>.<br> <strong>Action:</strong> ⚠️ Add such a constructor
(see <a href="#proposed-bitset">§ 9.4 Class template bitset</a> for wording <a href="#bitset-constructor">§ 6.4 std::bitset constructor semantic changes</a> for discussion).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code> could receive an additional <code class="highlight"><c- n>to_u128</c-></code> function, similar to <code class="highlight"><c- n>to_ullong</c-></code>.<br> <strong>Action:</strong> ⚠️ Add such a function
(see <a href="#proposed-bitset">§ 9.4 Class template bitset</a> for wording and <a href="#bitset-implementation-experience">§ 8.2.4 &lt;bitset></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_chars</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>from_chars</c-></code> need to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None
(see <a href="#charconv-implementation-experience">§ 8.2.5 &lt;charconv></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- o>&lt;</c-><c- n>format</c-><c- o>></c-></code> needs to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None
(see <a href="#format-implementation-experience">§ 8.2.6 &lt;format></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>basic_format_parse_context</c-><c- o>::</c-><c- n>check_dynamic_spec</c-></code> might need 128-bit integers support.<br> <strong>Action:</strong> ✔️ None, it doesn’t
(see <a href="#format-implementation-experience">§ 8.2.6 &lt;format></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>basic_format_arg</c-></code> might need support for 128-bit integers.<br> <strong>Action:</strong> ✔️ None, it doesn’t
(see <a href="#format-implementation-experience">§ 8.2.6 &lt;format></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code> needs to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None
(see <a href="#bit-implementation-experience">§ 8.2.7 &lt;bit></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-></code> could support 128-bit types.<br> <strong>Action:</strong> ⚠️ Add overloads
(see <a href="#proposed-numeric-conversions">§ 9.5 Numeric conversions</a> for wording and <a href="#to-string-implementation-experience">§ 8.2.8 std::to_string</a> for implementation experience).</p>
   <h4 class="heading settled" data-level="4.3.4" id="library-impact-containers"><span class="secno">4.3.4. </span><span class="content">Containers library</span><a class="self-link" href="#library-impact-containers"></a></h4>
   <p><strong>Issue:</strong> The extents and index types of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>mdspan</c-></code> could be 128-bit integers.
This is also the case for type aliases of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>strided_slice</c-></code>.
The exposition-only helper <code class="highlight"><i><c- n>integral</c-><c- o>-</c-><c- n>constant</c-><c- o>-</c-><c- n>like</c-></i></code> now also includes
128-bit integers.<br> <strong>Action:</strong> ✔️ None.
All these issues are either QoI or don’t impact existing implementations substantially.</p>
   <h4 class="heading settled" data-level="4.3.5" id="library-impact-iterators"><span class="secno">4.3.5. </span><span class="content">Iterators library</span><a class="self-link" href="#library-impact-iterators"></a></h4>
   <p><strong>Issue:</strong> The exposition-only helper <code class="highlight"><i><c- n>integral</c-><c- o>-</c-><c- n>constant</c-><c- o>-</c-><c- n>like</c-></i></code> now also includes
128-bit integers.
Generally, 128-bit integers would be a valid <code class="highlight"><c- n>difference_type</c-></code> and an implementation needs to
consider this when defining concepts that use integers in any way.<br> <strong>Action:</strong> ✔️ None.</p>
   <p class="note" role="note"><span class="marker">Note:</span> As long as <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>is_integral</c-></code> (and by proxy, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>integral</c-></code>) is correct, the existing wording
should be unaffected.</p>
   <h4 class="heading settled" data-level="4.3.6" id="library-impact-ranges"><span class="secno">4.3.6. </span><span class="content">Ranges library</span><a class="self-link" href="#library-impact-ranges"></a></h4>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>iota_view</c-><c- o>&lt;</c-><c- b>long</c-> <c- b>long</c-><c- o>>::</c-><i><c- n>iterator</c-></i><c- o>::</c-><c- n>difference_type</c-></code> is required to be a 128-bit integer if <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> is not 128-bit, and such a type exists.
This is not the the case in libc++ and MSVC STL at this time,
where <code class="highlight"><c- n>difference_type</c-></code> is <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> and <code class="highlight"><c- k>class</c-> <c- nc>std</c-><c- o>::</c-><c- n>_Signed128</c-></code> respectively.<br> <strong>Action:</strong> ⚠️ Relax wording to prevent breaking ABI
(see <a href="#proposed-iota">§ 9.6 Iota view</a> for wording and <a href="#iota-view-abi-break">§ 5.2 std::ranges::iota_view ABI issue</a> for discussion).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cartesian_product_view</c-><c- o>::</c-><c- n>size</c-></code> may now return a 128-bit integer.
The standard recommends to use a type which is sufficiently wide to store the product
of sizes of underlying ranges.
A similar issue arises for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cartesian_product_view</c-><c- o>::</c-><c- n>iterator</c-></code>.<br> <strong>Action:</strong> ✔️ None.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The choice of integer type used to be (and still is) implementation-defined.</p>
   <h4 class="heading settled" data-level="4.3.7" id="library-impact-algorithms"><span class="secno">4.3.7. </span><span class="content">Algorithms library</span><a class="self-link" href="#library-impact-algorithms"></a></h4>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>gcd</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>lcm</c-></code>, and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>midpoint</c-></code> need to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None
(see <a href="#gcd-implementation-experience">§ 8.2.9 std::gcd, std::lcm</a> for implementation experience).</p>
   <p><strong>Issue:</strong> Saturating arithmetic functions and <code class="highlight"><c- n>saturate_cast</c-></code> need to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None
(see <a href="#saturating-implementation-experience">§ 8.2.12 std::xxx_sat</a> for implementation experience).</p>
   <h4 class="heading settled" data-level="4.3.8" id="library-impact-numerics"><span class="secno">4.3.8. </span><span class="content">Numerics library</span><a class="self-link" href="#library-impact-numerics"></a></h4>
   <p><strong>Issue:</strong> Various random number generators and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uniform_int_distribution</c-></code> need to support
128-bit types.<br> <strong>Action:</strong> ✔️ None
(see <a href="#random-implementation-experience">§ 8.2.10 &lt;random></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>seed_seq</c-></code> needs to support <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-><c- o>></c-></code>.<br> <strong>Action:</strong> ✔️ None
(see <a href="#random-implementation-experience">§ 8.2.10 &lt;random></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>valarray</c-></code> needs to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None (see <a href="#valarray-implementation-experience">§ 8.2.15 std::valarray</a> for implementation experience)</p>
   <p><strong>Issue:</strong> For most <code class="highlight"><c- o>&lt;</c-><c- n>cmath</c-><c- o>></c-></code> functions, an additional overload taking 128-bit integers would
need to be defined.<br> <strong>Action:</strong> ✔️ None
(see <a href="#cmath-implementation-experience">§ 8.2.14 &lt;cmath></a> for implementation experience.)</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>abs</c-></code> could receive an additional 128-bit overload.<br> <strong>Action:</strong> ⚠️ Add an overload
(see <a href="#proposed-abs">§ 9.7 Absolute values</a> for wording and <a href="#abs-implementation-experience">§ 8.2.13 std::abs</a> for implementation experience).</p>
   <p><strong>Issue:</strong> The <code class="highlight"><c- o>&lt;</c-><c- n>linalg</c-><c- o>></c-></code> library needs 128-bit support.<br> <strong>Action:</strong> ✔️ None
(see <a href="#linalg-implementation-experience">§ 8.2.16 &lt;linalg></a> for implementation experience).</p>
   <h4 class="heading settled" data-level="4.3.9" id="library-impact-time"><span class="secno">4.3.9. </span><span class="content">Time library</span><a class="self-link" href="#library-impact-time"></a></h4>
   <p><strong>Issue:</strong> Significant portions of <code class="highlight"><c- o>&lt;</c-><c- n>chrono</c-><c- o>></c-></code> use <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ratio</c-></code>, which has <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intmax_t</c-></code> template
parameters.<br> <strong>Action:</strong> ✔️ None
(see <a href="#ratio-dilemma">§ 7.10 What about the std::ratio dilemma?</a> for discussion).</p>
   <h4 class="heading settled" data-level="4.3.10" id="library-impact-localization"><span class="secno">4.3.10. </span><span class="content">Localization library</span><a class="self-link" href="#library-impact-localization"></a></h4>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>num_get</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>num_put</c-></code> could use <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code> overloads for <code class="highlight"><c- n>do_get</c-></code>.<br> <strong>Action:</strong> ✔️ None.</p>
   <p class="note" role="note"><span class="marker">Note:</span> This would be a an ABI break if changes were made. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>num_get</c-></code> relies on virtual member functions, and modifying the vtable breaks ABI. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>printf</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>scanf</c-></code>cha can be used for locale-dependent formatting without breaking ABI. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>format</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>print</c-></code> provide locale-independent alternatives.</p>
   <h4 class="heading settled" data-level="4.3.11" id="library-impact-io"><span class="secno">4.3.11. </span><span class="content">Input/output library</span><a class="self-link" href="#library-impact-io"></a></h4>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>num_get</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>num_put</c-></code> don’t support 128-bit integers.
By proxy, extraction with <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ostream</c-><c- o>::</c-><c- k>operator</c-><c- o>&lt;&lt;</c-></code> and insertion with <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>istream</c-><c- o>::</c-><c- k>operator</c-><c- o>>></c-></code> would not work.<br> <strong>Action:</strong> ✔️ None.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The standard doesn’t require these to work for all integer types, only for standard integer types.
Any change would be an ABI break, so these facilities could be left untouched.
Unfortunately, the user won’t be able to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cout</c-> <c- o>&lt;&lt;</c-> <c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-><c- p>{...}</c-></code>, however,
the language provides sufficient alternatives
(<code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>printf</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>format</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>printf</c-></code>, <code class="highlight"><c- n>out</c-> <c- o>&lt;&lt;</c-> <c- n>std</c-><c- o>::</c-><c- n>to_string</c-><c- p>(...)</c-></code>).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>printf</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>scanf</c-></code> need to support 128-bit integers.<br> <strong>Action:</strong> ✔️ None
(see <a href="#cstdio-implementation-experience">§ 8.2.17 &lt;cstdio></a> for implementation experience).</p>
   <p><strong>Issue:</strong> <code class="highlight"><c- o>&lt;</c-><c- n>cinttypes</c-><c- o>></c-></code> needs to include the wording changes for <code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code>.<br> <strong>Action:</strong> ⚠️ Include changes
(see <a href="#proposed-cinttypes">§ 9.8 Header &lt;cinttypes></a> for wording).</p>
   <h4 class="heading settled" data-level="4.3.12" id="concurrency-support-library"><span class="secno">4.3.12. </span><span class="content">Concurrency support library</span><a class="self-link" href="#concurrency-support-library"></a></h4>
   <p><strong>Issue:</strong> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-></code> needs to support <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code>.<br> <strong>Action:</strong> ✔️ No impact on the standard
(see <a href="#atomic-implementation-experience">§ 8.2.18 std::atomic</a> for implementation experience).</p>
   <p><strong>Issue:</strong> There should be additional aliases <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic_uint_least128_t</c-></code> et al. aliases.<br> <strong>Action:</strong> ⚠️ Define aliases
(see <a href="#proposed-atomic">§ 9.9 Atomic operations</a> for wording).</p>
   <h2 class="heading settled" data-level="5" id="implementation-impact"><span class="secno">5. </span><span class="content">Impact on implementations</span><a class="self-link" href="#implementation-impact"></a></h2>
   <h3 class="heading settled" data-level="5.1" id="estimated-implementation-effort"><span class="secno">5.1. </span><span class="content">Estimated implementation effort</span><a class="self-link" href="#estimated-implementation-effort"></a></h3>
   <p>The following table summarizes the affected standard library parts and the estimated effort
required to implement the proposed changes.</p>
   <table>
    <tbody>
     <tr>
      <th>Affected library part
      <th>Work definitely required
      <th>Implementation experience
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_integer</c-></code>
      <td>✔️ no
      <td><a href="#to-integer-implementation-experience">§ 8.2.1 std::to_integer</a>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>version</c-><c- o>></c-></code>
      <td><a href="#proposed-version">§ 9.1 Header &lt;version></a>
      <td>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>limits</c-><c- o>></c-></code>
      <td>add specializations
      <td>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>climits</c-><c- o>></c-></code>
      <td>add macro constants
      <td>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>is_integral</c-></code>
      <td>✔️ no
      <td><a href="#type-traits-implementation-experience">§ 8.2.2 &lt;type_traits></a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>make_</c-><c- p>{</c-><c- n>un</c-><c- p>}</c-><c- b>signed</c-></code>
      <td>✔️ no
      <td><a href="#type-traits-implementation-experience">§ 8.2.2 &lt;type_traits></a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cmp_xxx</c-></code>
      <td>✔️ no
      <td><a href="#safe-comparison-implementation-experience">§ 8.2.3 std::cmp_xxx</a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>integer_sequence</c-></code>
      <td>✔️ no
      <td>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>bitset</c-><c- o>></c-></code>
      <td><a href="#proposed-bitset">§ 9.4 Class template bitset</a>
      <td><a href="#bitset-implementation-experience">§ 8.2.4 &lt;bitset></a>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>charconv</c-><c- o>></c-></code>
      <td>✔️ no
      <td><a href="#charconv-implementation-experience">§ 8.2.5 &lt;charconv></a>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>format</c-><c- o>></c-></code>
      <td>✔️ no
      <td><a href="#format-implementation-experience">§ 8.2.6 &lt;format></a>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code>
      <td>support 128-bit
      <td><a href="#bit-implementation-experience">§ 8.2.7 &lt;bit></a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-></code>
      <td><a href="#proposed-numeric-conversions">§ 9.5 Numeric conversions</a>
      <td><a href="#to-string-implementation-experience">§ 8.2.8 std::to_string</a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>iota_view</c-></code>
      <td><a href="#proposed-iota">§ 9.6 Iota view</a>
      <td><a href="#iota-view-abi-break">§ 5.2 std::ranges::iota_view ABI issue</a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>gcd</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>lcm</c-></code>
      <td>✔️ no
      <td><a href="#gcd-implementation-experience">§ 8.2.9 std::gcd, std::lcm</a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>midpoint</c-></code>
      <td>✔️ no
      <td><a href="#midpoint-implementation-experience">§ 8.2.11 std::midpoint</a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>xxx_sat</c-></code>
      <td>✔️ no
      <td><a href="#saturating-implementation-experience">§ 8.2.12 std::xxx_sat</a>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>random</c-><c- o>></c-></code>
      <td>256-bit LCG
      <td><a href="#random-implementation-experience">§ 8.2.10 &lt;random></a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>valarray</c-></code>
      <td>✔️ no
      <td><a href="#valarray-implementation-experience">§ 8.2.15 std::valarray</a>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>cmath</c-><c- o>></c-></code> overloads
      <td>✔️ no
      <td><a href="#cmath-implementation-experience">§ 8.2.14 &lt;cmath></a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>abs</c-></code>
      <td><a href="#proposed-abs">§ 9.7 Absolute values</a>
      <td><a href="#abs-implementation-experience">§ 8.2.13 std::abs</a>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>linalg</c-><c- o>></c-></code>
      <td>✔️ no
      <td><a href="#linalg-implementation-experience">§ 8.2.16 &lt;linalg></a>
     <tr>
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>printf</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>scanf</c-></code>
      <td>✔️ no
      <td><a href="#cstdio-implementation-experience">§ 8.2.17 &lt;cstdio></a>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code>
      <td><a href="#proposed-inttypes">§ 9.3 Header &lt;inttypes.h></a>
      <td>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>cinttypes</c-><c- o>></c-></code>
      <td><a href="#proposed-cinttypes">§ 9.8 Header &lt;cinttypes></a>
      <td>
     <tr>
      <td><code class="highlight"><c- o>&lt;</c-><c- n>atomic</c-><c- o>></c-></code>
      <td><a href="#proposed-atomic">§ 9.9 Atomic operations</a>
      <td><a href="#atomic-implementation-experience">§ 8.2.18 std::atomic</a>
   </table>
   <p>When deciding <em>"Work definitely required"</em>, this paper does not consider menial changes like
relaxing <code class="highlight"><c- k>static_assert</c-><c- p>(</c-><c- n>__is_standard_integer</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>)</c-></code> and such,
which may be present in functions such as <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>gcd</c-></code>.</p>
   <p>Also, if there exists at least one standard library which implements these features,
it is assumed that they can be adapted into other libraries with relative ease.</p>
   <h3 class="heading settled" data-level="5.2" id="iota-view-abi-break"><span class="secno">5.2. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>iota_view</c-></code> ABI issue</span><a class="self-link" href="#iota-view-abi-break"></a></h3>
   <p>libstdc++ defines <code class="highlight"><c- n>difference_type</c-></code> for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>iota_view</c-><c- o>&lt;</c-><c- b>long</c-> <c- b>long</c-><c- o>></c-></code> to be <code class="highlight"><c- b>__int128</c-></code>.
Since a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> alias would likely be defined as <code class="highlight"><c- b>__int128</c-></code>, there is no ABI impact.
Other libraries are not so fortunate.</p>
   <h4 class="heading settled" data-level="5.2.1" id="abi-break-affected-implementations"><span class="secno">5.2.1. </span><span class="content">Affected implementations</span><a class="self-link" href="#abi-break-affected-implementations"></a></h4>
   <p>By contrast, the <code class="highlight"><c- n>difference_type</c-></code> for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>iota_view</c-><c- o>&lt;</c-><c- b>long</c-> <c- b>long</c-><c- o>></c-></code> in libc++
is <code class="highlight"><c- b>long</c-> <c- b>long</c-></code>.</p>
   <p>The MSVC STL uses a class type <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>_Signed128</c-></code>.
Even trivially copyable classes aren’t passed via register in the Microsoft x86_64 ABI,
so this type is passed via the stack.
Re-defining this to be an integer type would break ABI, assuming that a Microsoft <code class="highlight"><c- b>__int128</c-></code> would be passed via registers.</p>
   <h4 class="heading settled" data-level="5.2.2" id="abi-break-cause"><span class="secno">5.2.2. </span><span class="content">Cause of ABI break</span><a class="self-link" href="#abi-break-cause"></a></h4>
   <p>The ABI break stems from the fact that <code class="highlight"><i><c- n>IOTA</c-><c- o>-</c-><c- n>DIFF</c-><c- o>-</c-><c- n>T</c-></i><c- p>(</c-><c- n>W</c-><c- p>)</c-></code> for <code class="highlight"><c- n>W</c-> <c- o>=</c-> <c- b>long</c-> <c- b>long</c-></code> is defined to be:</p>
   <blockquote>
    <p>a signed integer type of width greater than the width of <code class="highlight"><c- n>W</c-></code> if such a type exists.</p>
   </blockquote>
   <p>Currently, no such type exists, but if <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> did exist, it would no longer be valid
to use a class type or <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> as a <code class="highlight"><c- n>difference_type</c-></code>.</p>
   <h4 class="heading settled" data-level="5.2.3" id="abi-break-possible-solution"><span class="secno">5.2.3. </span><span class="content">Possible solution</span><a class="self-link" href="#abi-break-possible-solution"></a></h4>
   <p>See <a href="#proposed-iota">§ 9.6 Iota view</a> for a proposed solution which resolves this issue without requiring
action from implementors.</p>
   <h4 class="heading settled" data-level="5.2.4" id="iota-view-128"><span class="secno">5.2.4. </span><span class="content">What about <code class="highlight"><c- n>iota_view</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-><c- o>></c-></code>?</span><a class="self-link" href="#iota-view-128"></a></h4>
   <p>Besides the option to provide a ≥ 129-bit <code class="highlight"><c- n>difference_type</c-></code>,
implementations can also define <code class="highlight"><c- n>difference_type</c-></code> to be a 128-bit integer.</p>
   <p>Neither the <em>Cpp17RandomAccessIterator</em> requirement nor the <code class="highlight"><c- n>random_access_iterator</c-></code> concept
require the difference between two iterators to be representable using their <code class="highlight"><c- n>difference_type</c-></code>.
Therefore, this is a reasonable strategy which is easy to implement.
Of course, it has the adverse affect that <code class="highlight"><c- n>a</c-> <c- o>-</c-> <c- n>b</c-></code> is possibly undefined behavior for two iterators.</p>
   <p>In practice, will the user ever need a 128-bit <code class="highlight"><c- n>iota_view</c-></code>, and if so, do they need to represent
such extreme differences?
These are quality-of-implementation issues which maintainers will need to consider.
libstdc++ already supports <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>iota_view</c-><c- o>&lt;</c-><c- b>__int128</c-><c- o>></c-></code>, where the <code class="highlight"><c- n>difference_type</c-></code> is <code class="highlight"><c- b>__int128</c-></code>.
Besides QoI questions, this proposal does not introduce any new issues.</p>
   <h2 class="heading settled" data-level="6" id="impact-on-existing-code"><span class="secno">6. </span><span class="content">Impact on existing code</span><a class="self-link" href="#impact-on-existing-code"></a></h2>
   <p>With no core language changes and only additional standard library features,
the impact on existing code should be minimal.</p>
   <h3 class="heading settled" data-level="6.1" id="possible-semantic-changes"><span class="secno">6.1. </span><span class="content">Possible semantic changes</span><a class="self-link" href="#possible-semantic-changes"></a></h3>
   <p>However, this idea is put into question when it comes to integer literals.</p>
   <div class="example" id="example-68d97e7f">
    <a class="self-link" href="#example-68d97e7f"></a> 
<pre class="highlight"><c- k>auto</c-> <c- n>x</c-> <c- o>=</c-> <c- mi>18446744073709551615</c-><c- p>;</c-> <c- c1>// 2</c-><sup><c- c1>64</c-></sup><c- c1>-1</c->
</pre>
    <p>If the widest signed integer type is a 64-bit type, this code is ill-formed.
Every compiler handles this differently:</p>
    <ul>
     <li data-md>
      <p>clang declares <code class="highlight"><c- n>x</c-></code> as <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code> and emits a warning (✔️ compliant).</p>
     <li data-md>
      <p>GCC declares <code class="highlight"><c- n>x</c-></code> as <code class="highlight"><c- b>__int128</c-></code> and emits a misleading warning (✔️ compliant).</p>
     <li data-md>
      <p>MSVC declares <code class="highlight"><c- n>x</c-></code> as <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code> and emits no warning (❌ non-compliant).</p>
    </ul>
   </div>
   <p>The example demonstrates that in practice, introducing a 128-bit integer may
impact some existing code.
To comply with the C++ standard, the type of <code class="highlight"><c- mi>18446744073709551615</c-></code> would have to be <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> assuming that <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> cannot represent the value.</p>
   <p>Hexadecimal literals are not affected in the same way because they
are required to be of type <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code> if <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> cannot represent the value.
The introduction of a 128-bit integer type would not alter the signedness of existing literals.</p>
   <h3 class="heading settled" data-level="6.2" id="impact-on-overload-sets"><span class="secno">6.2. </span><span class="content">Impact on overload sets</span><a class="self-link" href="#impact-on-overload-sets"></a></h3>
   <p>Besides templates, a popular technique for covering multiple integer types is to create an
"exhaustive" overload sets like:</p>
<pre class="language-cpp highlight"><c- c1>// support "all" signed integers (anything less than int is promoted)</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>int</c-><c- p>);</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>long</c-><c- p>);</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-><c- p>);</c->
</pre>
   <p>I’m putting "exhaustive" in quotes because such code does not cover extended integer types,
which can exist.
Only the implementation knows the whole set of integer types and can ensure completeness.</p>
   <p class="note" role="note"><span class="marker">Note:</span> Creating an overload set from <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>int8_t</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>int16_t</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>int32_t</c-></code>,
and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>int64_t</c-></code> is not possible because it only covers four out of five standard integer types,
making some calls ambiguous.</p>
   <p>While creating sets like these outside of language implementations is not ideal,
the proposal can minimize the impact by making <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> a distinct type from
standard integer types.</p>
   <div class="example" id="example-5f5b1274">
    <a class="self-link" href="#example-5f5b1274"></a> If <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> is <code class="highlight"><c- b>long</c-> <c- b>long</c-></code>, the following code is ill-formed: 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>long</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-><c- p>)</c-> <c- p>{</c-> <c- p>}</c-> <c- c1>// re-definition of foo(long long)</c->
</pre>
   </div>
    There exists no implementation where <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> is 128-bit, so no code is really affected. 
   <p class="note" role="note"><span class="marker">Note:</span> A workaround is to write <code class="highlight"><c- b>void</c-> <c- n>foo</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>same_as</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-><c- o>></c-> <c- k>auto</c-><c- p>)</c-></code>.
However, this solution is not obvious, and should not be necessary.</p>
   <h4 class="heading settled" data-level="6.2.1" id="proposed-overload-set-extension"><span class="secno">6.2.1. </span><span class="content">Proposed solution</span><a class="self-link" href="#proposed-overload-set-extension"></a></h4>
   <p>There should exist a natural and universally correct way to extend such overload sets,
so that the effort of "upgrading" to 128-bit is minimal.
Therefore <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> should be distinct.</p>
   <p>Guaranteeing that <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> is distinct means that even if <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> is a 128-bit type, it won’t be chosen by this alias.
This breaks the conventions of <code class="highlight"><c- o>&lt;</c-><c- n>cstdint</c-><c- o>></c-></code> and may be surprising,
but no implementation with <code class="highlight"><c- o>&lt;</c-><c- n>cstdint</c-><c- o>></c-></code> aliases beyond <code class="highlight"><c- mi>64</c-></code> exists,
and no implementation where <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> is 128-bit exists.
No existing code is affected; this is a purely academic problem.</p>
   <h3 class="heading settled" data-level="6.3" id="possible-assumption-violations"><span class="secno">6.3. </span><span class="content">Possible assumption violations</span><a class="self-link" href="#possible-assumption-violations"></a></h3>
   <p>There is obviously a substantial amount of code which assumes that integers are no wider
than 64 bits.
There is also a substantial amount of code which assumes that <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intmax_t</c-></code> is
the widest integer type, and this assumption would be broken by introducing <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code>.</p>
   <p>The exact impact is investigated in this proposal.
Assumptions about hardware or integer width limitations cannot hold back language development.
C would be stuck with 32-bit types if that had ever been a convincing rationale.
Also, the introduction of a 128-bit type does not break existing code unless the user chooses
to use it.</p>
   <h3 class="heading settled" data-level="6.4" id="bitset-constructor"><span class="secno">6.4. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code> constructor semantic changes</span><a class="self-link" href="#bitset-constructor"></a></h3>
   <p>The only overload which accepts integers is <code class="highlight"><c- n>bitset</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-><c- p>)</c-></code>.
Ideally, we would like to construct bitsets from wider integer types, if available. <strong>My proposed solution changes the semantics of this constructor</strong> (see <a href="#proposed-bitset">§ 9.4 Class template bitset</a> for wording).</p>
   <p>The existing constructor is problematic for multiple reasons:</p>
   <ol>
    <li data-md>
     <p>If extended by a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> overload, a call <code class="highlight"><c- n>bitset</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> would become ambiguous.</p>
    <li data-md>
     <p>When called with negative numbers, a sign extension only takes place up to
the width of <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code>.
Beyond that, the bits are zero-filled.</p>
   </ol>
   <div class="example" id="example-fe74c2f2">
    <a class="self-link" href="#example-fe74c2f2"></a> The following assertion passes: 
<pre class="language-cpp highlight"><c- cp>#include</c-> &lt;bitset>
<c- k>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- n>bitset</c-><c- o>&lt;</c-><c- mi>128</c-><c- o>></c-> <c- n>bits</c-><c- p>(</c-><c- mi>-1</c-><c- p>);</c->
<c- k>static_assert</c-><c- p>(</c-><c- n>bits</c-><c- p>.</c-><c- n>count</c-><c- p>()</c-> <c- o>==</c-> <c- mi>64</c-><c- p>);</c->
</pre>
   </div>
   <p>The original behavior is very difficult to preserve if we add more overloads.
If we added an <code class="highlight"><c- n>int_least128_t</c-></code> overload, then <code class="highlight"><c- n>bitset</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> would be ambiguous.
Therefore, we must at least have an overload for all integers with a conversion rank
of <code class="highlight"><c- b>int</c-></code> or greater.</p>
   <p>However, if so, <code class="highlight"><c- mi>-1</c-></code> under the current definition would result int a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-><c- o>&lt;</c-><c- mi>128</c-><c- o>></c-></code> that has only 32 one-bits (assuming 32-bit <code class="highlight"><c- b>int</c-></code>).
We could preserve the current behavior exactly if sign-extension occurred up to the width
of <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code>; beyond that, zero-extension would be used.
This is not proposed because the design makes no sense outside of its historical context.</p>
   <h4 class="heading settled" data-level="6.4.1" id="bitset-constructor-proposed-solution"><span class="secno">6.4.1. </span><span class="content">Proposed solution</span><a class="self-link" href="#bitset-constructor-proposed-solution"></a></h4>
   <p>Therefore, I propose to perform sign-extension for the full size of the <code class="highlight"><c- n>bitset</c-></code>.
In other words, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-><c- p>(</c-><c- mi>-1</c-><c- p>)</c-></code> would always be a bitset where every bit is set.
This almost certainly matches the intent of the user.</p>
   <p>A GitHub code search for <a href="https://github.com/search?type=code&amp;q=%2Fbitset%3C.*%3E%5C%28-%5B0-9%5D%2B%5C%29%2F+language%3Ac%2B%2B"><code class="highlight"><c- o>/</c-><c- n>bitset</c-><c- o>&lt;</c-><c- p>.</c-><c- o>*></c->\<c- p>(</c-><c- o>-</c-><c- p>[</c-><c- mi>0-9</c-><c- p>]</c-><c- o>+</c->\<c- p>)</c-><c- o>/</c-> <c- n>language</c-><c- o>:</c-><c- n>c</c-><c- o>++</c-></code></a> finds 30 uses of constructing a bitset from a negative literal.
Of the ones which use <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code>, all uses are of the form</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-><c- p>(</c-><c- mi>-1</c-><c- p>)</c-></code> where <code class="highlight"><c- n>N</c-></code> is less than 64, or</p>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-><c- p>(</c-><c- k>static_cast</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(</c-><c- mi>-1</c-><c- p>))</c-></code>.</p>
   </ul>
   <p>None of these existing uses would be affected.</p>
   <p class="note" role="note"><span class="marker">Note:</span> See <a href="#proposed-bitset">§ 9.4 Class template bitset</a> for wording.</p>
   <h2 class="heading settled" data-level="7" id="design-considerations"><span class="secno">7. </span><span class="content">Design considerations</span><a class="self-link" href="#design-considerations"></a></h2>
   <p>The goal of this proposal is to obtain a mandatory 128-bit type with strong library support.
A <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>least_uint128_t</c-></code> alias is the only option that does not involve any changes
to the core language.
Therefore, it is the obvious design choice for this proposal.</p>
   <p class="note" role="note"><span class="marker">Note:</span> Unlike the existing <code class="highlight"><c- n>int_leastN_t</c-></code> and <code class="highlight"><c- n>int_fastN_t</c-></code> aliases, this type is distinct.
See <a href="#impact-on-overload-sets">§ 6.2 Impact on overload sets</a> for rationale, and <a href="#proposed-cstdint">§ 9.2 Header &lt;cstdint></a> for wording.</p>
   <p>Besides the current approach, there are a few alternatives which have been considered:</p>
   <h3 class="heading settled" data-level="7.1" id="standard-integers"><span class="secno">7.1. </span><span class="content">Why no standard integer type?</span><a class="self-link" href="#standard-integers"></a></h3>
   <blockquote>
    <p>Why standardize a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code> type alias but no standard integer type?
Essentially, why no <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <c- b>long</c-></code>?</p>
   </blockquote>
   <p>Firstly, naming is a problem here.
A standard integer type would likely warrant the ability to name it by keyword, and an
ever-increasing sequence of <code class="highlight"><c- b>long</c-></code>s isn’t an attractive solution.
Even with a concise keyword such as <code class="highlight"><c- n>_Uint128</c-></code>, it is unclear what advantage such a keyword
would have over a type alias, other than saving one <code class="highlight"><c- cp>#include</c-> &lt;cstdint></code> directive.</p>
   <p>Secondly, it is useful to keep <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint_least128_t</c-></code> a second-class citizen by not making it a
standard integer type.
For example, in the formatting library, a format string can
specify a dynamic <em>width</em> for an argument, which must be a standard integer.
A <em>width</em> that cannot be represented by a 64-bit number is unreasonable,
so it makes sense to limit support to standard integers.</p>
   <p>Thirdly, as already stated in <a href="#c-compatibility">§ 4.1 C Compatibility</a>, C23’s <code class="highlight"><c- b>intmax_t</c-></code> must be the
widest standard integer type.
To not break ABI and be C23-compatible, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> must be
an extended integer type.</p>
   <h3 class="heading settled" data-level="7.2" id="exact-width-integers"><span class="secno">7.2. </span><span class="content">Why no mandatory <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code> type?</span><a class="self-link" href="#exact-width-integers"></a></h3>
   <p>Mandating any exact <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>intN_t</c-></code> inadvertently restricts the byte width
because exact-width types cannot have any padding. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code> implies that the width of a byte is a power of two ≤ 128,
and historically, C++ has not restricted implementations to a specific byte size.</p>
   <p>This decrease in portability also has no good rationale.
If <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> is mandatory and an implementation is able to define it without padding,
then <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code> is effectively mandatory.</p>
   <p>Hypothetically, a malicious implementation could define <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> to be a 1000-bit
integer with 872 padding bits, even if it was able to define a padding-free 128-bit integer.
However, malicious implementations have never been a strong argument to guide design.</p>
   <h3 class="heading settled" data-level="7.3" id="why-no-256-bit"><span class="secno">7.3. </span><span class="content">Why no <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least256_t</c-></code> type?</span><a class="self-link" href="#why-no-256-bit"></a></h3>
   <p>256-bit integers are also useful and one could use many of the arguments
in favor of 128-bit integers to also propose them.
However, there are are a few strong reasons against including them in this proposal:</p>
   <ol>
    <li data-md>
     <p>The wider the bit sizes, the fewer the use cases are.
For example, 128 bits are sufficient for high-precision clocks and most financial
applications.</p>
    <li data-md>
     <p>There is tremendously less hardware support for 256-bit integers.
x86 has instructions to perform a 64-to-128-bit multiplication, but no such
128-to-256-bit instruction exists.</p>
    <li data-md>
     <p>There are fewer existing implementations of 256-bit integers.</p>
    <li data-md>
     <p>Many use cases of 256-bit integers are simply bit manipulation.
The wider the type, the less common arithmetic becomes.
Bitwise operations (<code class="highlight"><c- o>&amp;</c-></code>, <code class="highlight"><c- o>|</c-></code>, <code class="highlight"><c- o>~</c-></code>) are best done through vector registers,
but the ABI for <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>256</c-><c- p>)</c-></code> is to use general purpose registers or the stack,
and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least256_t</c-></code> would likely be the same.
Since there is strong hardware support for <a href="#widening-operations">§ 3.1.3 Widening operations</a> which is based
on general purpose registers, the choice for 128-bit is easy; not so much for 256-bit.</p>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-></code> is a "support type" for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>float128_t</c-></code> which simplifies the
implementation of many <code class="highlight"><c- o>&lt;</c-><c- n>cmath</c-><c- o>></c-></code> functions.
There exists no hardware with <em>binary256</em> support to motivate a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint256_t</c-></code> support type.</p>
    <li data-md>
     <p>Longer integer literals are a major reason to get a fundamental type.
256-bit hexadecimal literals are up to 64 digits long, which degrades code quality
too much.
With indentation and digit separators, using the full width can exceed the auto-formatter’s column limit.</p>
   </ol>
   <p>It is also unclear whether there should ever be a mandatory 256-bit extended integer type,
or if support should be provided through 256-bit bit-precise integers.
Overall, this proposal is more focused if it includes only 128-bit.</p>
   <p>Nevertheless, many of the changes in <a href="#proposed-wording">§ 9 Proposed wording</a> pave the way for a future <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least256_t</c-></code> or even <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least512_t</c-></code>.
There would be no wording impact other than defining the necessary aliases and macros.</p>
   <h3 class="heading settled" data-level="7.4" id="why-not-class-type"><span class="secno">7.4. </span><span class="content">Why no class type?</span><a class="self-link" href="#why-not-class-type"></a></h3>
   <p>Instead of an extended integer type, it would also be possible to provide the user with a
128-bit class type.
This could even be done through a general <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>big_int</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-></code> class.
However, there are compelling reasons against doing so:</p>
   <ol>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> is sufficiently common to where the added cost of class type
(overload resolution for operators, function call evaluation in constant expressions, etc.)
would be a burden to the user. <code class="highlight"><c- b>__int128</c-></code> is the "work horse" of any multi-precision library which uses 64-to-128-bit
widening operations (see <a href="#multi-precision-operations">§ 3.1.3.2 Multi-precision operations</a>).
This cost could add up quickly.</p>
    <li data-md>
     <p>A fundamental type also comes with integer literals, and up to 128-bit, there are still
reasonable use cases for integer literals. <a href="#motivation-and-scope">§ 3 Motivation and scope</a> shows multiple examples where 128-bit literals were used.
Besides these use cases, it would be nice to represent an IPv6 address using a
hexadecimal literal (which is the typical representation of these addresses).</p>
    <li data-md>
     <p>There are 128-bit architectures where the general purpose register size is 128-bit.
For example, the RV128I variant of RISC-V is such an architecture.
To be fair, there exists no implementation of RV128I yet.
Still, it would be unusual not to have a fundamental type that represents the
general purpose register.</p>
   </ol>
   <p>In essence, 128-bit is still "special" enough to deserve a fundamental type.
Beyond 128-bit, even hexadecimal literals become hard to read due to their sheer length,
and we are unlikely to find any ISA with a 256-bit register size,
even counting theoretical ISAs like RV128I.</p>
   <h3 class="heading settled" data-level="7.5" id="bit-precise-integers"><span class="secno">7.5. </span><span class="content">Why no bit-precise integers?</span><a class="self-link" href="#bit-precise-integers"></a></h3>
   <p>Instead of putting work into 128-bit integers, it would also be possible to integrate
bit-precise integers (C’s <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> type, proposed in <a data-link-type="biblio" href="#biblio-n2763" title="Adding a Fundamental Type for N-bit integers">[N2763]</a>) into the C++ standard.</p>
   <p>This would be a sufficient alternative if <code class="highlight"><c- b>_BitInt</c-></code> was a fundamental type,
had integer literal support, and had strong library support.
However, there are numerous reasons why <code class="highlight"><c- b>_BitInt</c-></code> is not the right path for this proposal, described below.
In short, this proposal argues that <code class="highlight"><c- b>_BitInt</c-></code> does not bring sufficient value to C++ relative to its
impact, and would better be exposed via a class type <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>big_int</c-></code> than a fundamental type.</p>
   <h4 class="heading settled" data-level="7.5.1" id="bitint-lack-of-work"><span class="secno">7.5.1. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> has no existing C++ work</span><a class="self-link" href="#bitint-lack-of-work"></a></h4>
   <p>After enquiry in the std-proposals mailing list, no one has expressed that they are working on <code class="highlight"><c- b>_BitInt</c-></code>, nor has anyone expressed interest on beginning work on this.
Right now, <code class="highlight"><c- b>_BitInt</c-></code> is a purely hypothetical feature.</p>
   <h4 class="heading settled" data-level="7.5.2" id="bitint-lack-of-motivation"><span class="secno">7.5.2. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> has less motivation in C++</span><a class="self-link" href="#bitint-lack-of-motivation"></a></h4>
   <p>A significant part of the rationale for <a data-link-type="biblio" href="#biblio-n2709" title="Packaging Tasks for Asynchronous Execution">[N2709]</a> was that only <code class="highlight"><c- b>_BitInt</c-></code> can utilize hardware
resources optimally on hardware such as FPGAs that have a native 2031-bit type.
C++ is much less ambitious in its goal of supporting <em>all</em> hardware,
with changes such as C++20 effectively mandating two’s complement signed integers.
C23 supporting <code class="highlight"><c- b>_BitInt</c-></code> is not rationale for a C++ fundamental type in itself.</p>
   <p>Therefore, a limited solution as focusing on 128-bit is not unreasonable.</p>
   <h4 class="heading settled" data-level="7.5.3" id="bitint-should-be-class-type"><span class="secno">7.5.3. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> should be exposed as a class type</span><a class="self-link" href="#bitint-should-be-class-type"></a></h4>
   <p>By default, all new language features are library features.
If it’s possible to express N-bit integers through a class, then this is the go-to solution.</p>
   <p>In C++, it is possible to expose the compiler’s <code class="highlight"><c- b>_BitInt</c-></code> functionality as follows:</p>
<pre class="language-cpp highlight"><c- kr>inline</c-> <c- k>constexpr</c-> <c- b>size_t</c-> <c- n>big_int_max_width</c-> <c- o>=</c-> <c- n>BITINT_MAXWIDTH</c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- b>size_t</c-> <c- n>N</c-><c- o>></c->
  <c- k>requires</c-> <c- p>(</c-><c- n>N</c-> <c- o>&lt;=</c-> <c- n>BITINT_MAXWIDTH</c-><c- p>)</c->
<c- k>struct</c-> <c- nc>big_int</c-> <c- p>{</c->
    <c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-> <c- n>_M_value</c-><c- p>;</c->

    <c- c1>// TODO: constructors, operator overloads, etc.</c->
<c- p>};</c->

<c- c1>// TODO: define big_uint similarly</c->

<c- c1>// compatibility macros:</c->
<c- cp>#ifdef __cplusplus</c->
<c- cp>#define _BigInt(...) ::std::big_int&lt;__VA_ARGS__></c->
<c- cp>#define _BigUint(...) ::std::big_uint&lt;__VA_ARGS__></c->
<c- cp>#else</c->
<c- cp>#define _BigInt(...) _BitInt(__VA_ARGS__)</c->
<c- cp>#define _BIgUint(...) unsigned _BitInt(__VA_ARGS__)</c->
<c- cp>#endif</c->
</pre>
   <p>There is precedent for this design:</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>complex</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> is compatible with C’s <code class="highlight"><c- n>_Complex</c-> <c- n>T</c-></code>.</p>
    <li data-md>
     <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> is compatible with C’s <code class="highlight"><c- n>_Atomic</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-></code>.</p>
   </ul>
   <p>Unless an extremely strong case for a new category of integer types in the core language can be
made, this is the obvious solution.</p>
   <p>Of course, a class type is more costly in terms of compilation slowdown as well as
performance on debug builds and in constant evaluations.
This is acceptable because <code class="highlight"><c- b>_BitInt</c-></code> is not a replacement for the existing integers,
but an infrequently used special-purpose type which only comes into play when no other size
would suffice.</p>
   <h4 class="heading settled" data-level="7.5.4" id="bitint-not-replacement"><span class="secno">7.5.4. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> is not a replacement for standard integers</span><a class="self-link" href="#bitint-not-replacement"></a></h4>
   <p>In C, <code class="highlight"><c- b>_BitInt</c-></code> is a second-class citizen.
The overwhelming majority of library functions take <code class="highlight"><c- b>int</c-></code>, <code class="highlight"><c- b>long</c-></code>, and other standard integer types.
Conversion rules are also biased in favor of standard integers.
For example, <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>)</c-> <c- p>{</c-><c- mi>0</c-><c- p>}</c-> <c- o>+</c-> <c- p>(</c-><c- b>int</c-><c- p>)</c-> <c- p>{</c-><c- mi>0</c-><c- p>}</c-></code> is of type <code class="highlight"><c- b>int</c-></code> in C, if <code class="highlight"><c- b>int</c-></code> is 32-bit.</p>
   <p>Standard integers are essentially engraved into the language and have special status, both in C
and in C++.
Billions of lines of code use these integers, and this is never going to change.
Virtually all learning resources in existence teach standard integers or <code class="highlight"><c- o>&lt;</c-><c- n>cstdint</c-><c- o>></c-></code> aliases,
which are standard integers in all implementations.</p>
   <p>Even if <code class="highlight"><c- b>_BitInt</c-></code> was a replacement for the existing integers, the transition process would take a century.
It is better to think of it as an extension of the existing integers.</p>
   <h4 class="heading settled" data-level="7.5.5" id="bitint-128-bit-support"><span class="secno">7.5.5. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> does not guarantee 128-bit support</span><a class="self-link" href="#bitint-128-bit-support"></a></h4>
   <p>The whole point of this proposal is to guarantee developers a 128-bit type.
However, <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> is only valid for <code class="highlight"><c- n>N</c-> <c- o>&lt;=</c-> <c- n>BITINT_MAXWIDTH</c-></code>, where <code class="highlight"><c- n>BITINT_MAXWIDTH</c-></code> is guaranteed to be no more than the width of <code class="highlight"><c- b>long</c-> <c- b>long</c-></code>.</p>
   <h4 class="heading settled" data-level="7.5.6" id="bitint-library-effort"><span class="secno">7.5.6. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> requires more library effort</span><a class="self-link" href="#bitint-library-effort"></a></h4>
   <p>This proposal only mandates <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code>, not any specific width.
Therefore, implementers have the luxury of relying on all integers being padding-free
and all integers having a width which is 2<sup>N</sup> times the platform’s byte size.</p>
   <p>These assumptions greatly simplify the implementation of various algorithms.
From personal experience, implementing any functions in <code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code> is tremendously easier
when it is guaranteed that integers have a 2<sup>N</sup> width.</p>
   <p>Full <code class="highlight"><c- b>_BitInt</c-></code> library support requires tremendously greater library effort.
It is unclear what parts of the standard library can be burdened.</p>
   <h4 class="heading settled" data-level="7.5.7" id="bitint-breaking-code"><span class="secno">7.5.7. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> breaks more existing code</span><a class="self-link" href="#bitint-breaking-code"></a></h4>
   <p><code class="highlight"><c- b>_BitInt</c-></code> also breaks assumptions in existing, generic code.
C++ users have enjoyed the luxury of padding-free integers on conventional implementations
for a very long time, and some code depends on it.</p>
   <p>It may depend through anti-patterns like using <code class="highlight"><c- n>memcmp</c-></code> for comparison of <code class="highlight"><c- k>struct</c-></code>s storing integers,
or more justified uses like <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bit_cast</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(</c-><c- n>integer</c-><c- p>)</c-></code>. <code class="highlight"><c- b>_BitInt</c-></code> inevitably breaks assumptions about padding and size, which is a great challenge
to both the implementation and C++ users.</p>
   <div class="example" id="example-d9708717">
    <a class="self-link" href="#example-d9708717"></a> The following pseudo-code has undefined behavior if <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>30</c-><c- p>)</c-></code> has padding bits. 
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>integral</c-> <c- n>T</c-><c- o>></c->
<c- k>auto</c-> <c- n>to_byte_array</c-><c- p>(</c-><c- k>const</c-> <c- n>T</c-><c- o>&amp;</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>bit_cast</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>byte</c-><c- p>,</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>T</c-><c- p>)</c-><c- o>>></c-><c- p>(</c-><c- n>x</c-><c- p>);</c->
<c- p>}</c->

<c- b>int</c-> <c- n>main</c-><c- p>()</c-> <c- p>{</c->
    <c- b>_BitInt</c-><c- p>(</c-><c- mi>30</c-><c- p>)</c-> <c- n>x</c-> <c- o>=</c-> <c- p>...;</c->
    <c- n>write_buffer_to_file</c-><c- p>(</c-><c- n>file</c-><c- p>,</c-> <c- n>to_byte_array</c-><c- p>(</c-><c- n>x</c-><c- p>));</c->
<c- p>}</c->
</pre>
    <p>Assuming a 4-byte array is returned, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bit_cast</c-></code> one of these bytes would have indeterminate
value because the corresponding byte in <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>30</c-><c- p>)</c-></code> has padding bits.
Reading this indeterminate value to store it in a file is undefined behavior.</p>
   </div>
   <p>While the assumption that all integers are padding-free is not universally correct,
C++ users have enjoyed this guarantee for decades, and an unknown amount of code depends on it.
If <code class="highlight"><c- b>_BitInt</c-></code> was just another integral type, it could silently break existing code like in the example,
despite a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>integral</c-></code> constraint.</p>
   <p class="note" role="note"><span class="marker">Note:</span> <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> does not have the same problem because the implementation can define
it as a type with more than 128 bits which has no padding, if need be.</p>
   <h4 class="heading settled" data-level="7.5.8" id="bitint-teachability"><span class="secno">7.5.8. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> has teachability issues</span><a class="self-link" href="#bitint-teachability"></a></h4>
   <p><code class="highlight"><c- b>_BitInt</c-></code> has different promotion and conversion rules.
These rules are not necessarily obvious, especially when bit-precise integers interact with
other types.</p>
   <p>For example, <code class="highlight"><c- n>x</c-> <c- o>+</c-> <c- mi>1</c-></code> is of type <code class="highlight"><c- b>int</c-></code> if <code class="highlight"><c- n>x</c-></code> is of type <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>)</c-></code> or narrower, and <code class="highlight"><c- b>int</c-></code> is 32-bit.
Not only does the user have to learn the existing integer conversion and promotion rules,
the user also has to learn this new <code class="highlight"><c- b>_BitInt</c-></code> system and how it interacts with the old system.
This also complicates overload resolution:</p>
   <div class="example" id="example-6c127adc">
    <a class="self-link" href="#example-6c127adc"></a> 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>int</c-><c- p>);</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>));</c->

<c- b>int</c-> <c- nf>main</c-><c- p>()</c-> <c- p>{</c->
    <c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>)</c-> <c- n>x</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c->
    <c- n>foo</c-><c- p>(</c-><c- n>x</c-><c- p>);</c-> <c- c1>// calls which?</c->
<c- p>}</c->
</pre>
    <p>If <code class="highlight"><c- b>int</c-></code> dominates in implicit conversions, should it also dominate in overload resolution so that <code class="highlight"><c- n>foo</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-></code> is selected?
The answer is not entirely clear.</p>
   </div>
   <div class="example" id="example-f02573b7">
    <a class="self-link" href="#example-f02573b7"></a> 
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>int</c-><c- p>);</c->
<c- b>void</c-> <c- nf>foo</c-><c- p>(</c-><c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>));</c->

<c- b>int</c-> <c- nf>main</c-><c- p>()</c-> <c- p>{</c->
    <c- n>foo</c-><c- p>(</c-><c- mi>1'000'000'000</c-><c- p>);</c-> <c- c1>// calls which?</c->
<c- p>}</c->
</pre>
    <p>On a target where <code class="highlight"><c- b>int</c-></code> is 16-bit, the integer literal is of type <code class="highlight"><c- b>long</c-></code>.
It is possible to convert it to <code class="highlight"><c- b>int</c-></code> in a narrowing conversion, and possible
to convert it to <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>)</c-></code> losslessly.</p>
    <ul>
     <li data-md>
      <p>Should overload resolution prefer the lossless conversion to <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>32</c-><c- p>)</c-></code>?
After all, lossless is better.</p>
     <li data-md>
      <p>Should the call be ambiguous?
After all, that’s what normally happens when there are two viable candidates with equally long
conversion sequences.</p>
     <li data-md>
      <p>Should <code class="highlight"><c- n>foo</c-><c- p>(</c-><c- b>int</c-><c- p>)</c-></code> be called?
After all, standard integers are normally dominant, and <code class="highlight"><c- mi>1</c->’<c- mo>000</c->’<c- mo>000</c->’<c- mo>000</c-></code> could be of type <code class="highlight"><c- b>int</c-></code> if only <code class="highlight"><c- b>int</c-></code> was 32-bit.</p>
    </ul>
    <p>There is a compelling case for each of these options, and no matter what design choice is made,
the complexity of the language increases significantly.</p>
   </div>
   <h4 class="heading settled" data-level="7.5.9" id="bitint-too-permissive"><span class="secno">7.5.9. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> in C may be too permissive</span><a class="self-link" href="#bitint-too-permissive"></a></h4>
   <p>Many C++ users have lamented that integers are too permissive.
As is tradition, C has not restricted the behavior of <code class="highlight"><c- b>_BitInt</c-></code> substantially:</p>
   <ul>
    <li data-md>
     <p>Signed/unsigned mixed comparison are permitted.</p>
    <li data-md>
     <p>Signed/unsigned mixed arithmetic is permitted.</p>
    <li data-md>
     <p>Implicit truncating conversion is permitted.</p>
    <li data-md>
     <p>Implicit signed/unsigned conversion is permitted.</p>
   </ul>
   <p>One substantial difference is that <code class="highlight"><c- b>_BitInt</c-></code> is not promoted to <code class="highlight"><c- b>int</c-></code>, other than that,
the semantics are the same as the old integers.
If <code class="highlight"><c- b>_BitInt</c-></code> behaves almost the same as standard integers and brings all of this bug-prone
behavior with it, how can one justify adding it as a new fundamental type?</p>
   <p>Of course, C++ could decide to make these semantics more restrictive for its <code class="highlight"><c- b>_BitInt</c-></code> type,
similar to how implicit casts from <code class="highlight"><c- b>void</c-><c- o>*</c-></code> are only permitted in C, but not in C++.
However, this would complicate writing C/C++ interoperable code
and make the language even less teachable because <code class="highlight"><c- b>_BitInt</c-></code> semantics would become language-specific.</p>
   <p>Furthermore, the more distinct the <code class="highlight"><c- b>_BitInt</c-></code> semantics become, the less of a drop-in replacement for <code class="highlight"><c- b>__int128</c-></code> it becomes:</p>
   <div class="example" id="example-fc4111ed">
    <a class="self-link" href="#example-fc4111ed"></a> The following function yields the high 64 bits of a multiplication.
Similar code can be found in <a data-link-type="biblio" href="#biblio-stockfish" title="Stockfish">[Stockfish]</a> (see also <a href="#widening-operations">§ 3.1.3 Widening operations</a>). 
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- b>uint64_t</c-> <c- nf>mul_hi</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- b>uint64_t</c-> <c- n>x</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>uint64_t</c-> <c- n>y</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>u128</c-><c- p>(</c-><c- n>x</c-><c- p>)</c-> <c- o>*</c-> <c- n>u128</c-><c- p>(</c-><c- n>y</c-><c- p>)</c-> <c- o>>></c-> <c- mi>64</c-><c- p>;</c->
<c- p>}</c->
</pre>
    <p>If <code class="highlight"><c- n>u128</c-></code> is extended integer type, this code is well-formed.
If <code class="highlight"><c- n>u128</c-></code> is a C-style <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code>, this code is well-formed.
If <code class="highlight"><c- n>u128</c-></code> is a more restrictive C++ <code class="highlight"><c- b>unsigned</c-> <c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code> which forbids narrowing,
this code is ill-formed.</p>
   </div>
   <p>In short, the dilemma is as follows:</p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- b>_BitInt</c-></code> is as permissive as existing integers, it is harder to justify its addition
to the language because it innovates too little.</p>
    <li data-md>
     <p>If <code class="highlight"><c- b>_BitInt</c-></code> is more restrictive, its impact on existing code and on language
teachability is greater.</p>
   </ul>
   <p>There is no obvious path here, only a bottomless potential for discussion.
By comparison, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> has exactly the same rules as existing integers,
which <code class="highlight"><c- b>__int128</c-></code> follows.
The user can use it as a drop-in replacement:</p>
   <blockquote>
<pre class="highlight"><del><c- cp>#ifdef __SIZEOF_INT128__</c-></del>
<c- k>using</c-> <c- n>i128</c-> <c- o>=</c-> <del><c- n>__int128</c-></del><ins><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></ins><c- p>;</c->
<del><c- cp>#else</c->
<c- c1>// struct i128 { /* ... */ };</c->
<c- cp>#endif</c-></del>
</pre>
   </blockquote>
   <h4 class="heading settled" data-level="7.5.10" id="bitint-false-dichotomy"><span class="secno">7.5.10. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-></code> false dichotomy</span><a class="self-link" href="#bitint-false-dichotomy"></a></h4>
   <p>The <code class="highlight"><c- b>_BitInt</c-></code> vs. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> argument is a false dichotomy.
Bit-precise integers essentially create a parallel, alternative type system with
different rules for promotion, implicit conversion, and possibly overload resolution.</p>
   <p>Defining any <code class="highlight"><c- o>&lt;</c-><c- n>cstdint</c-><c- o>></c-></code>/<code class="highlight"><c- n>stdint</c-><c- p>.</c-><c- n>h</c-></code> type alias as a bit-precise integer would be hugely surprising
to language users, who have certain expectations towards aliases in these headers.
These expectations have been formed over the past 30 years.</p>
   <p>Therefore, even if all issues regarding <code class="highlight"><c- b>_BitInt</c-></code> mentioned in this paper were resolved
and <code class="highlight"><c- b>_BitInt</c-></code> becomes a fundamental type,
it would be reasonable to maintain the "legacy" type system in parallel.</p>
   <h3 class="heading settled" data-level="7.6" id="why-not-optional"><span class="secno">7.6. </span><span class="content">Why not make it optional?</span><a class="self-link" href="#why-not-optional"></a></h3>
   <p>Instead of making <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> entirely mandatory, it would also be possible to
make it an optional type, or to make it mandatory only on hosted implementations.</p>
   <p>First and foremost, making the type optional has severe consequences.
Library authors still have to write twice the code:
one version with 128-bit support, one version without.
To C++ users, the ability to write portable code is more valuable
than the underlying implementation effort, or potential performance issues.
I will go into these two issues more:</p>
   <h4 class="heading settled" data-level="7.6.1" id="implementation-effort-not-too-high"><span class="secno">7.6.1. </span><span class="content">Implementation effort is not too high</span><a class="self-link" href="#implementation-effort-not-too-high"></a></h4>
   <p>The criticism is:</p>
   <blockquote>
    <p>On freestanding/embedded platforms, the implementation effort of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> is too great.</p>
   </blockquote>
   <p>While this concern is valid, C23 requires arbitrary-precision arithmetic through <code class="highlight"><c- b>_BitInt</c-></code> anyway
and GCC and clang support <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code> already (see <a href="#existing-bit-int">§ 8.1.4 _BitInt(128)</a> for support).
Assuming that vendors care about C-compatibility,
this proposal merely requires vendors to provide <code class="highlight"><c- n>int_least128_t</c-> <c- o>=</c-> <c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code>.</p>
   <p class="note" role="note"><span class="marker">Note:</span> Bit-precise integers have slightly different semantics than extended integers.
However, these differences don’t matter if <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code> is the widest integer,
making it valid to use as <code class="highlight"><c- n>int_least128_t</c-></code>.</p>
   <p>The remaining impact is limited to the standard library.
For the most part, it is simple to generalize library algorithms to an arbitrary bit size.
It is especially easy when the implementation can ensure that all integers are padding-free
and have a size that is a 2<sup>N</sup> multiple of the byte size.
Only <code class="highlight"><c- n>int_leastN_t</c-></code> is mandatory (not the exact-width types),
so the implementation can ensure it.</p>
   <h4 class="heading settled" data-level="7.6.2" id="software-emulation-acceptable"><span class="secno">7.6.2. </span><span class="content">Software emulation is acceptable</span><a class="self-link" href="#software-emulation-acceptable"></a></h4>
   <p>The criticism is:</p>
   <blockquote>
    <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code> should not be mandatory if software emulation degrades performance.</p>
   </blockquote>
   <p>There is also merit to this concern.
A mandatory type may give the user a false sense of hardware support which simply
doesn’t exist, especially on 32-bit or even 8-bit hardware.</p>
   <p>However, this problem is innate to standard integers as well.
If a user is compiling for a 32-bit architecture, a 64-bit <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> will have to be
software-emulated, and 64-bit integer division can have dramatic cost.
Why should a 64-bit <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> be mandatory on an 8-bit architecture?
The answer is: because it’s useful to rely on <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> so we can write portable code,
even if we try to avoid the type for the sake of performance.</p>
   <p>In the end, it’s the responsibility of the user to be vaguely aware of hardware capabilities
and not use integer types that are poorly supported.
If the user wants to perform a 128-bit integer division on an 8-bit machine,
the language shouldn’t artificially restrict them from doing so.
The same principle applies to <code class="highlight"><c- b>long</c-> <c- b>long</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-></code>, C23’s <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>1024</c-><c- p>)</c-></code>, etc.</p>
   <h3 class="heading settled" data-level="7.7" id="extended-conversion-rank"><span class="secno">7.7. </span><span class="content">Should extended integer semantics be changed?</span><a class="self-link" href="#extended-conversion-rank"></a></h3>
   <p>An interesting question is whether extended integer semantics make sense in the first place,
or require some form of changes.
The relevant standard section is 6.8.6 [conv.rank].</p>
   <p>In summary:</p>
   <table>
    <tbody>
     <tr>
      <th>Relevant Rule
      <th>Example
     <tr>
      <td>Unsigned integers have the same rank as signed integers of equal width.
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-> <c- o>==</c-> <c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code>
     <tr>
      <td>Wider integers have greater rank.
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-> <c- o>==</c-> <c- n>std</c-><c- o>::</c-><c- b>int64_t</c-></code>
     <tr>
      <td>Standard integers of equal width have greater rank.
      <td><code class="highlight"><c- b>long</c-> <c- b>long</c-> <c- o>></c-> <c- n>std</c-><c- o>::</c-><c- n>int128_t</c-></code><br>if <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> is 128-bit
     <tr>
      <td>Extended integers with the same width are ranked <em>implementation-defined</em>.
      <td><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-> <c- o>??</c-> <c- n>std</c-><c- o>::</c-><c- n>int_fast128_t</c-></code><br>if these types are distinct
   </table>
   <p>7.4 [expr.arith.conv] decides that for integers of equal rank, the common type is unsigned.
For example, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>int128_t</c-><c- p>{}</c-> <c- o>+</c-> <c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-><c- p>{}</c-></code> is of type <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>uint128_t</c-><c- p>{}</c-></code>.</p>
   <p>I believe these semantics to be sufficiently clear; they don’t require any change.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The rules for determining the better overload are based on implicit conversion sequences.
If the rules for conversions are unchanged, by proxy, overload resolution remains unchanged.</p>
   <h3 class="heading settled" data-level="7.8" id="user-defined-literals"><span class="secno">7.8. </span><span class="content">Do we need new user-defined literals?</span><a class="self-link" href="#user-defined-literals"></a></h3>
   <p>No, not necessarily.
If the user desperately wants to define a user-defined literal which accepts
128-bit numeric values and beyond, they can write:</p>
   <div class="example" id="example-32654a40">
    <a class="self-link" href="#example-32654a40"></a> 
<pre class="language-cpp highlight"><c- k>constexpr</c-> <c- b>int</c-> <c- k>operator</c-><c- s>""</c-><c- n>_zero</c-><c- p>(</c-><c- k>const</c-> <c- b>char</c-><c- o>*</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- mi>0</c-><c- p>;</c->
<c- p>}</c->

<c- b>int</c-> <c- n>x</c-> <c- o>=</c-> <c- mi>100000000000000000000000000000000000000000000000000000000000000000</c-><c- n>_zero</c-><c- p>;</c->
</pre>
   </div>
   <p>Obviously, this forces the user into parsing the input string at compile-time if they want
to obtain a numeric value.
A literal operator of the form <code class="highlight"><c- k>operator</c-><c- s>""</c-><c- n>_zero</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-><c- p>)</c-></code> circumvents this problem,
but <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> is typically not 128-bit.
Therefore, it could be argued that these rules should be expanded to save the user the trouble
of parsing.</p>
   <p>However, this is not proposed because it lacks motivation.
User-defined literals have diminishing returns the longer they are:</p>
   <ul>
    <li data-md>
     <p>The difference between <code class="highlight"><c- mi>0</c-><c- n>s</c-></code> and <code class="highlight"><c- n>chrono</c-><c- o>::</c-><c- n>seconds</c-><c- p>{</c-><c- mi>0</c-><c- p>}</c-></code> is huge: 800%.</p>
    <li data-md>
     <p>The difference between <code class="highlight"><c- mi>1000000000</c-><c- n>s</c-></code> and <code class="highlight"><c- n>chrono</c-><c- o>::</c-><c- n>seconds</c-><c- p>{</c-><c- mi>1000000000</c-><c- p>}</c-></code> is not: ~150%.</p>
   </ul>
   <p>The shortest user-defined literal that does not fit into <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code> is <code class="highlight"><c- mh>0xfffffffffffffffff</c-><c- n>s</c-></code>, which is 20 characters long.
At this length, user-defined literals never provide overwhelming utility.</p>
   <p>However, if WG21 favors new forms of <code class="highlight"><c- k>operator</c-><c- s>""</c-></code> for
integer types wider than <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code>, I am open to working on this.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The standard currently does not allow <code class="highlight"><c- k>operator</c-><c- s>""</c-><c- n>_zero</c-><c- p>(</c-><i><c- n>integer</c-></i><c- p>)</c-></code> for any <code class="highlight"><i><c- n>integer</c-></i></code> except <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code>.</p>
   <h3 class="heading settled" data-level="7.9" id="div"><span class="secno">7.9. </span><span class="content">Why no <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>div</c-></code>?</span><a class="self-link" href="#div"></a></h3>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>div</c-></code> is a function which returns the quotient and remainder of an integer division in one
operation.
This proposal intentionally doesn’t extend support to 128-bit types because each overload of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>div</c-></code> returns a different type.
Namely, the current overloads for <code class="highlight"><c- b>int</c-></code>, <code class="highlight"><c- b>long</c-></code>, and <code class="highlight"><c- b>long</c-> <c- b>long</c-></code> return <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>div_t</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>ldiv_t</c-></code>, and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>lldiv_t</c-></code> respectively.</p>
   <p>This scheme isn’t easy to generalize to 128-bit integers or other extended integer types.
A possibly approach would be to define a class template <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>div_result</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> and re-define
the concrete types to be aliases for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>div_result</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-></code> etc.
However, this is arguably a breaking change because it alters what template argument deduction
is possible from these types.</p>
   <p>Furthermore, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>div</c-></code> is arguably useless.
Optimizing compilers recognize separate uses of <code class="highlight"><c- n>x</c-> <c- o>/</c-> <c- n>y</c-></code> and <code class="highlight"><c- n>x</c-> <c- o>%</c-> <c- n>y</c-></code> and fuse them into a single
division which yields both quotient and remainder, at least on platforms where this is possible.</p>
   <p class="note" role="note"><span class="marker">Note:</span> In C89, <code class="highlight"><c- n>div</c-></code> was useful because it had a well specified rounding mode,
whereas the division operator had implementation-defined rounding.</p>
   <h3 class="heading settled" data-level="7.10" id="ratio-dilemma"><span class="secno">7.10. </span><span class="content">What about the <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ratio</c-></code> dilemma?</span><a class="self-link" href="#ratio-dilemma"></a></h3>
   <p>Assuming that C++26 is based on C23, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ratio</c-></code> will be problematic
because it is defined as:</p>
<pre class="language-cpp highlight"><c- k>template</c-><c- o>&lt;</c-><c- b>intmax_t</c-> <c- n>Num</c-><c- p>,</c-> <c- b>intmax_t</c-> <c- n>Denom</c-> <c- o>=</c-> <c- mi>1</c-><c- o>></c->
<c- k>class</c-> <c- nc>ratio</c-> <c- p>{</c-> <c- d>/* ... */</c-> <c- p>};</c->
</pre>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- b>intmax_t</c-></code> would no longer be the widest integer type, and certain extreme ratios
would become unrepresentable.
It is not possible to redefine it to have other types for template parameters
because the types of template arguments participate in name mangling.</p>
   <p>This issue is not caused by this proposal, but the introduction of a 128-bit integer
first manifests it.</p>
   <p>This proposal does not attempt to resolve it.
However, a possible path forward is to make <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>duration</c-></code> less dependent on <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ratio</c-></code> and allow <em>ratio-like</em> types instead.</p>
   <h2 class="heading settled" data-level="8" id="implementation-experience"><span class="secno">8. </span><span class="content">Implementation experience</span><a class="self-link" href="#implementation-experience"></a></h2>
   <h3 class="heading settled" data-level="8.1" id="existing-128-bit-integers"><span class="secno">8.1. </span><span class="content">Existing 128-bit integer types</span><a class="self-link" href="#existing-128-bit-integers"></a></h3>
   <h4 class="heading settled" data-level="8.1.1" id="existing-int-128"><span class="secno">8.1.1. </span><span class="content"><code class="highlight"><c- b>__int128</c-></code> (GNU-like)</span><a class="self-link" href="#existing-int-128"></a></h4>
   <p>GCC and clang already provide the 128-bit integer types in the form of <code class="highlight"><c- b>__int128</c-></code> and <code class="highlight"><c- b>unsigned</c-> <c- b>__int128</c-></code>.
However, this type is not available when compiling for 32-bit targets.
Clang provides the same support.</p>
   <h4 class="heading settled" data-level="8.1.2" id="existing-int-128-cuda"><span class="secno">8.1.2. </span><span class="content"><code class="highlight"><c- b>__int128</c-></code> (CUDA)</span><a class="self-link" href="#existing-int-128-cuda"></a></h4>
   <p>In NVIDIA CUDA 11.5, the NVCC compiler has added preview support for the
signed and unsigned <code class="highlight"><c- b>__int128</c-></code> data types on platforms where the host compiler supports it.
See <a data-link-type="biblio" href="#biblio-nvidia" title="Implementing High-Precision Decimal Arithmetic with CUDA int128">[NVIDIA]</a>.</p>
   <h4 class="heading settled" data-level="8.1.3" id="existing-msvc-128"><span class="secno">8.1.3. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>_Signed128</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>_Unsigned128</c-></code></span><a class="self-link" href="#existing-msvc-128"></a></h4>
   <p>The MSVC STL provides the class types <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>_Signed128</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>_Unsigned128</c-></code> defined in <a href="https://github.com/microsoft/STL/blob/main/stl/inc/__msvc_int128.hpp"><code class="highlight"><c- o>&lt;</c-><c- n>__msvc_int128</c-><c- p>.</c-><c- n>hpp</c-><c- o>></c-></code></a>.
These types implement all arithmetic operations and integer comparisons.</p>
   <p>They satisfy the <em>integer-like</em> constraint and have been added to implement <a data-link-type="biblio" href="#biblio-p1522r1" title="Iterator Difference Type and Integer Overflow">[P1522R1]</a>. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>iota_view</c-><c- o>::</c-><c- n>difference_type</c-></code> is possibly defined as <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>_Signed128</c-></code>.</p>
   <h4 class="heading settled" data-level="8.1.4" id="existing-bit-int"><span class="secno">8.1.4. </span><span class="content"><code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code></span><a class="self-link" href="#existing-bit-int"></a></h4>
   <p>The C23 standard requires support for bit-precise integers <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-> <c- o>&lt;=</c-> <c- n>BITINT_MAXWIDTH</c-><c- p>)</c-></code> where <code class="highlight"><c- n>BITINT_MAXWIDTH</c-> <c- o>>=</c-> <c- n>ULLONG_WIDTH</c-></code>.
While this doesn’t strictly force support for 128-bit integers,
GNU-family implementations support more than 128 bits already.</p>
   <p>As of February 2024, the support is as follows:</p>
   <table>
    <tbody>
     <tr>
      <th>Compiler
      <th><code class="highlight"><c- n>BITINT_MAXWIDTH</c-></code>
      <th>Targets
      <th>Languages
     <tr>
      <td>clang 14
      <td><code class="highlight"><c- mi>128</c-></code>
      <td>all
      <td>C &amp; C++
     <tr>
     <tr>
      <td>clang 16
      <td><code class="highlight"><c- mi>8388608</c-></code>
      <td>all
      <td>C &amp; C++
     <tr>
     <tr>
      <td>GCC 14
      <td><code class="highlight"><c- mi>65535</c-></code>
      <td>64-bit only
      <td>C
     <tr>
     <tr>
      <td>MSVC 19.38
      <td>❌
      <td>❌
      <td>❌
   </table>
   <p class="note" role="note"><span class="marker">Note:</span> clang has supported <code class="highlight"><c- b>_BitInt</c-></code> as an <code class="highlight"><c- n>_ExtInt</c-></code> compiler extension prior to C standardization.</p>
   <p>It is possible that given enough time, <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- mi>128</c-><c- p>)</c-></code> will be
supported by Microsoft as well.</p>
   <p class="note" role="note"><span class="marker">Note:</span> Microsoft Developer Community users have requested support for a 128-bit type
at <a data-link-type="biblio" href="#biblio-msdn" title="Support for 128-bit integer type">[MSDN]</a>.</p>
   <h3 class="heading settled" data-level="8.2" id="library-implementation-experience"><span class="secno">8.2. </span><span class="content">Library implementation experience</span><a class="self-link" href="#library-implementation-experience"></a></h3>
   <h4 class="heading settled" data-level="8.2.1" id="to-integer-implementation-experience"><span class="secno">8.2.1. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_integer</c-></code></span><a class="self-link" href="#to-integer-implementation-experience"></a></h4>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_integer</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(...)</c-></code> is equivalent to <code class="highlight"><c- k>static_cast</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(...)</c-></code> with constraints.</p>
   <h4 class="heading settled" data-level="8.2.2" id="type-traits-implementation-experience"><span class="secno">8.2.2. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>type_traits</c-><c- o>></c-></code></span><a class="self-link" href="#type-traits-implementation-experience"></a></h4>
   <p>Assuming that <code class="highlight"><c- n>is_integral</c-></code> and <code class="highlight"><c- n>make_</c-><c- p>{</c-><c- n>un</c-><c- p>}</c-><c- b>signed</c-></code> don’t simply delegate to a compiler intrinsic,
implementing these traits merely requires adding two specializations such as <code class="highlight"><c- n>is_integral</c-><c- o>&lt;</c-><c- n>int_least128_t</c-><c- o>></c-> <c- o>:</c-> <c- n>false_type</c-></code>.</p>
   <p>See libstdc++'s <a href="https://github.com/gcc-mirror/gcc/blob/93e1559bea434a681208e5e7a21513d7da2844d6/libstdc%2B%2B-v3/include/std/type_traits"><code class="highlight"><c- o>&lt;</c-><c- n>type_traits</c-><c- o>></c-></code></a>.</p>
   <h4 class="heading settled" data-level="8.2.3" id="safe-comparison-implementation-experience"><span class="secno">8.2.3. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cmp_xxx</c-></code></span><a class="self-link" href="#safe-comparison-implementation-experience"></a></h4>
   <p>Libstdc++ provides a width-agnostic implementation of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cmp_equal</c-></code> and other safe comparison functions in <a href="https://github.com/gcc-mirror/gcc/blob/93e1559bea434a681208e5e7a21513d7da2844d6/libstdc%2B%2B-v3/include/std/utility#L127"><code class="highlight"><c- o>&lt;</c-><c- n>utility</c-><c- o>></c-></code></a>.</p>
   <p>Being able to extend to a wider type is helpful in principle (e.g. implementing <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>cmp_equal</c-><c- p>(</c-><c- b>int</c-><c- p>,</c-> <c- b>int</c-><c- p>)</c-></code> in terms of a comparison between <code class="highlight"><c- b>long</c-></code>s),
however, the current implementations don’t make use of this opportunity anyway.</p>
   <h4 class="heading settled" data-level="8.2.4" id="bitset-implementation-experience"><span class="secno">8.2.4. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>bitset</c-><c- o>></c-></code></span><a class="self-link" href="#bitset-implementation-experience"></a></h4>
   <p class="note" role="note"><span class="marker">Note:</span> See <a href="#proposed-bitset">§ 9.4 Class template bitset</a> for proposed changes.</p>
   <p>To implement these changes, a constructor and member function template can be defined:</p>
<pre class="language-cpp highlight"><c- n>bitset</c-><c- p>(</c-><c- n>integral</c-> <c- k>auto</c-><c- p>);</c->

<c- k>template</c-> <c- o>&lt;</c-><c- n>unsigned_integral</c-> <c- n>T</c-><c- o>></c->
<c- n>T</c-> <c- n>to</c-><c- p>();</c->
</pre>
   <p>These are functionally equivalent to the existing <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code> constructor
and <code class="highlight"><c- n>to_ullong</c-></code> function respectively, just generalized.</p>
   <h4 class="heading settled" data-level="8.2.5" id="charconv-implementation-experience"><span class="secno">8.2.5. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>charconv</c-><c- o>></c-></code></span><a class="self-link" href="#charconv-implementation-experience"></a></h4>
   <p>libstdc++ already provides a width-agnostic implementation
of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_chars</c-></code> in <a href="https://github.com/gcc-mirror/gcc/blob/cff174fabd6c980c09aee95db1d9d5c22421761f/libstdc%2B%2B-v3/include/bits/charconv.h"><code class="highlight"><c- o>&lt;</c-><c- n>bits</c-><c- o>/</c-><c- n>charconv</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code></a>,
and a width-agnostic implementation of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>from_chars</c-></code> in <a href="https://github.com/gcc-mirror/gcc/blob/cff174fabd6c980c09aee95db1d9d5c22421761f/libstdc%2B%2B-v3/include/std/charconv"><code class="highlight"><c- o>&lt;</c-><c- n>charconv</c-><c- o>></c-></code></a>.</p>
   <p>In general, it is not difficult to generalize <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_chars</c-></code> for any width.
Stringification uses integer division, which may be a problem.
However, the divisor is constant.
Due to strength reduction optimization (see <a href="#fixed-point-operations">§ 3.1.4 Fixed-point operations</a> for an example),
no extreme cost is incurred no matter the width.</p>
   <h4 class="heading settled" data-level="8.2.6" id="format-implementation-experience"><span class="secno">8.2.6. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>format</c-><c- o>></c-></code></span><a class="self-link" href="#format-implementation-experience"></a></h4>
   <p>libstdc++ already supports <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>format</c-></code> for <code class="highlight"><c- b>__int128</c-></code>.</p>
   <p>The locale-independent forms are simply implemented in terms of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_chars</c-></code> and are not
affected by the introduction of 128-bit integers.
As explained above, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_chars</c-></code> implementations typically already support 128-bit integers.</p>
   <p>The new <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_format_parse_context</c-><c- o>::</c-><c- n>check_dynamic_spec</c-></code> function is not affected.
This function only checks for the type of a dynamic <em>width</em> or <em>precision</em>, and the arguments are required to be of standard integer type.
Realistically the user will never need a 128-bit <em>width</em> or <em>precision</em>,
which is why no changes are proposed.</p>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_format_arg</c-></code> also requires no changes because <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_format_arg</c-><c- o>::</c-><c- n>handle</c-></code> already covers extended integer and floating-point types.
Also, modifying the <code class="highlight"><c- n>value</c-></code> <code class="highlight"><c- n>variant</c-></code> within a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_format_arg</c-></code> would be an avoidable ABI-break.</p>
   <h4 class="heading settled" data-level="8.2.7" id="bit-implementation-experience"><span class="secno">8.2.7. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>bit</c-><c- o>></c-></code></span><a class="self-link" href="#bit-implementation-experience"></a></h4>
   <p>In <a data-link-type="biblio" href="#biblio-bitpermutations" title="C++26 Bit Permutations">[BitPermutations]</a>, I have implemented the majority of C++ bit manipulation functions
for <em>any</em> width, i.e. in a way that is compatible with <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> for any <code class="highlight"><c- n>N</c-></code>.</p>
   <p>Such an extremely generalized implementation is challenging, however, merely extending support
to 128-bit given a 64-bit implementation is simple.</p>
   <div class="example" id="example-28ecfb3d">
    <a class="self-link" href="#example-28ecfb3d"></a> Given a 64-bit <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>popcount</c-></code>, a 128-bit implementation looks as follows: 
<pre class="language-cpp highlight"><c- b>int</c-> <c- nf>popcount</c-><c- p>(</c-><c- n>uint128_t</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>popcount</c-><c- p>(</c-><c- b>uint64_t</c-><c- p>(</c-><c- n>x</c-> <c- o>>></c-> <c- mi>64</c-><c- p>))</c-> <c- o>+</c-> <c- n>popcount</c-><c- p>(</c-><c- b>uint64_t</c-><c- p>(</c-><c- n>x</c-><c- p>));</c->
<c- p>}</c->
</pre>
   </div>
   <div class="example" id="example-5392957a">
    <a class="self-link" href="#example-5392957a"></a> Given a 64-bit <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>countr_zero</c-></code>, a 128-bit implementation looks as follows: 
<pre class="language-cpp highlight"><c- b>int</c-> <c- nf>countr_zero</c-><c- p>(</c-><c- n>uint128_t</c-> <c- n>x</c-><c- p>)</c-> <c- p>{</c->
    <c- b>int</c-> <c- n>result</c-> <c- o>=</c-> <c- n>countr_zero</c-><c- p>(</c-><c- b>uint64_t</c-><c- p>(</c-><c- n>x</c-><c- p>));</c->
    <c- k>return</c-> <c- n>result</c-> <c- o>&lt;</c-> <c- mi>64</c-> <c- o>?</c-> <c- n>result</c-> <c- o>:</c-> <c- mi>64</c-> <c- o>+</c-> <c- n>countr_zero</c-><c- p>(</c-><c- b>uint64_t</c-><c- p>(</c-><c- n>x</c-> <c- o>>></c-> <c- mi>64</c-><c- p>));</c->
<c- p>}</c->
</pre>
   </div>
   <p>All bit manipulation functions are easily constructed this way.</p>
   <h4 class="heading settled" data-level="8.2.8" id="to-string-implementation-experience"><span class="secno">8.2.8. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-></code></span><a class="self-link" href="#to-string-implementation-experience"></a></h4>
   <p class="note" role="note"><span class="marker">Note:</span> See <a href="#proposed-numeric-conversions">§ 9.5 Numeric conversions</a> for proposed changes.</p>
   <p>libstdc++ already implements <a href="https://github.com/gcc-mirror/gcc/blob/f1412546ac8999b7f6eeeee8cf967ce3f31794c2/libstdc%2B%2B-v3/include/bits/basic_string.h#L4240"><code class="highlight"><c- n>to_string</c-></code></a> as an inline function which forwards to <a href="https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/charconv.h#L81"> <code class="highlight"><c- n>detail</c-><c- o>::</c-><c- n>__to_chars_10_impl</c-></code> </a>.</p>
   <p>In general, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_string</c-></code> simply needs to forward to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_chars</c-></code> or a similar function,
and this is easily generalized.</p>
   <h4 class="heading settled" data-level="8.2.9" id="gcd-implementation-experience"><span class="secno">8.2.9. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>gcd</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>lcm</c-></code></span><a class="self-link" href="#gcd-implementation-experience"></a></h4>
   <p>libstdc++ provides a <a href="https://github.com/gcc-mirror/gcc/blob/cff174fabd6c980c09aee95db1d9d5c22421761f/libstdc%2B%2B-v3/include/std/numeric#L134"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>gcd</c-></code></a> implementation which uses the <a href="https://en.wikipedia.org/wiki/Binary_GCD_algorithm">Binary GCD algorithm</a>.
The MSVC STL has a similar implementation.
This algorithm is easily generalized to any width.
It requires <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>countr_zero</c-></code> for an efficient implementation, which is easy to implement
for 128-bit integers (see <a href="#bit-implementation-experience">§ 8.2.7 &lt;bit></a>).</p>
   <p>libc++ uses a naive <a href="https://github.com/llvm/llvm-project/blob/b17348c3b541d7fc7ec441c98db75c18d8959910/libcxx/include/__numeric/gcd_lcm.h#L53"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>gcd</c-></code></a> implementation based on the Euclidean Algorithm, which relies on integer division.
Due to the immense cost of integer division for 128-bit integers,
such an implementation may need revision.</p>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>lcm</c-></code> requires no work because mathematically, <code class="highlight"><c- n>gcd</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>)</c-> <c- o>*</c-> <c- n>lcm</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>)</c-> <c- o>==</c-> <c- n>x</c-> <c- o>*</c-> <c- n>y</c-></code>.
When solving for <code class="highlight"><c- n>lcm</c-></code>, <code class="highlight"><c- n>lcm</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>)</c-> <c- o>=</c-> <c- n>x</c-> <c- o>/</c-> <c- n>gcd</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>)</c-> <c- o>*</c-> <c- n>y</c-></code>.
The implementation effort (if any) is limited to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>gcd</c-></code>.</p>
   <p class="note" role="note"><span class="marker">Note:</span> By dividing by <code class="highlight"><c- n>gcd</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>)</c-></code> prior to multiplication, overflow in <code class="highlight"><c- n>x</c-> <c- o>*</c-> <c- n>y</c-></code> is avoided.
Overflow can only occur if <code class="highlight"><c- n>lcm</c-><c- p>(</c-><c- n>x</c-><c- p>,</c-> <c- n>y</c-><c- p>)</c-></code> is not representable by the result type.</p>
   <h4 class="heading settled" data-level="8.2.10" id="random-implementation-experience"><span class="secno">8.2.10. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>random</c-><c- o>></c-></code></span><a class="self-link" href="#random-implementation-experience"></a></h4>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>linear_congruential_engine</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>a</c-><c- p>,</c-> <c- n>c</c-><c- p>,</c-> <c- n>m</c-><c- o>></c-></code> requires at least double-wide integers
to safely perform the operation <code class="highlight"><c- p>(</c-><c- n>a</c-> <c- o>*</c-> <c- n>x</c-> <c- o>+</c-> <c- n>c</c-><c- p>)</c-> <c- n>mod</c-> <c- n>m</c-></code>, where <code class="highlight"><c- n>x</c-></code> is the LCG state.
Otherwise, the multiplication and addition could overflow.</p>
   <p>libstdc++ solves this issue by performing all operations using <code class="highlight"><c- b>__int128</c-></code> if available
(see <a href="https://github.com/gcc-mirror/gcc/blob/67d5b10e659c3f4c02b8af507c84d5e764e264b4/libstdc%2B%2B-v3/include/bits/random.h#L83"><code class="highlight"><c- o>&lt;</c-><c- n>bits</c-><c- o>/</c-><c- n>random</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code></a>),
and otherwise:</p>
<pre class="language-cpp highlight"><c- k>static_assert</c-><c- p>(</c-><c- n>__which</c-> <c- o>&lt;</c-> <c- mi>0</c-><c- p>,</c-> <c- d>/* needs to be dependent */</c->
    <c- s>"sorry, would be too much trouble for a slow result"</c-><c- p>);</c->
</pre>
   <p>Introducing 128-bit integers would force implementations to also provide 256-bit operations
solely for the purpose of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>linear_congruential_engine</c-></code>.
This can be considered reasonable because C23 requires implementations to provide
arbitrary-precision arithmetic anyway, and both GCC and clang already implement <code class="highlight"><c- b>_BitInt</c-><c- p>(</c-><c- n>N</c-><c- p>)</c-></code> for <code class="highlight"><c- n>N</c-> <c- o>>=</c-> <c- mi>256</c-></code> (see <a href="#existing-bit-int">§ 8.1.4 _BitInt(128)</a> for details on support).</p>
   <h4 class="heading settled" data-level="8.2.11" id="midpoint-implementation-experience"><span class="secno">8.2.11. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>midpoint</c-></code></span><a class="self-link" href="#midpoint-implementation-experience"></a></h4>
   <p>Libstdc++ has a <a href="https://github.com/gcc-mirror/gcc/blob/1e94648ab7b370c5867e146c7f59603e2e6ba2e6/libstdc%2B%2B-v3/include/std/numeric#L221"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>midpoint</c-></code></a> implementation which is width-agnostic.</p>
   <h4 class="heading settled" data-level="8.2.12" id="saturating-implementation-experience"><span class="secno">8.2.12. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>xxx_sat</c-></code></span><a class="self-link" href="#saturating-implementation-experience"></a></h4>
   <p>libstdc++ provides a width-agnostic implementation for all saturating arithmetic functions in <a href="https://github.com/gcc-mirror/gcc/blob/cff174fabd6c980c09aee95db1d9d5c22421761f/libstdc%2B%2B-v3/include/bits/sat_arith.h"><code class="highlight"><c- o>&lt;</c-><c- n>bits</c-><c- o>/</c-><c- n>sat_arith</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code></a>.</p>
   <p>Saturating arithmetic is generally done through compiler intrinsics such as <code class="highlight"><c- n>__builtin_mul_overflow</c-></code>.
These are already supported by GCC and Clang.
A software implementation of overflow detection may be very tedious as explained in <a data-link-type="biblio" href="#biblio-p0543r3" title="Saturation arithmetic">[P0543R3]</a>, but that isn’t the chosen implementation anyway.</p>
   <h4 class="heading settled" data-level="8.2.13" id="abs-implementation-experience"><span class="secno">8.2.13. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>abs</c-></code></span><a class="self-link" href="#abs-implementation-experience"></a></h4>
   <p class="note" role="note"><span class="marker">Note:</span> See <a href="#proposed-abs">§ 9.7 Absolute values</a> for proposed changes.</p>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>abs</c-></code> can be easily implemented width-agnostically as <code class="highlight"><c- n>x</c-> <c- o>>=</c-> <c- mi>0</c-> <c- o>?</c-> <c- n>x</c-> <c- o>:</c-> <c- o>-</c-><c- n>x</c-></code> for any integer <code class="highlight"><c- n>x</c-></code>.</p>
   <p>Note that an overload must exist for every integer type to avoid calling <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>abs</c-></code> for
floating-point types.
Such an overload is proposed in <a href="#proposed-abs">§ 9.7 Absolute values</a>.</p>
   <h4 class="heading settled" data-level="8.2.14" id="cmath-implementation-experience"><span class="secno">8.2.14. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>cmath</c-><c- o>></c-></code></span><a class="self-link" href="#cmath-implementation-experience"></a></h4>
   <p>libstdc++, libc++, and the MSVC STL implement the integral math overloads using SFINAE.
Effectively, they define function templates using <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>enable_if_t</c-><c- o>&lt;</c-><c- n>std</c-><c- o>::</c-><c- n>is_integral_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>></c-></code>.
Therefore, no changes are required.</p>
   <h4 class="heading settled" data-level="8.2.15" id="valarray-implementation-experience"><span class="secno">8.2.15. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>valarray</c-></code></span><a class="self-link" href="#valarray-implementation-experience"></a></h4>
   <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>valarray</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-></code> does not rely on any specific bit-size, or on <code class="highlight"><c- n>T</c-></code> being any
type in general.
While it is possible to provide specializations for specific types that make
more optimal use of hardware, it is also possible to rely on the
optimizers auto-vectorization capabilities alone.</p>
   <h4 class="heading settled" data-level="8.2.16" id="linalg-implementation-experience"><span class="secno">8.2.16. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>linalg</c-><c- o>></c-></code></span><a class="self-link" href="#linalg-implementation-experience"></a></h4>
   <p>The linear algebra library introduced by <a data-link-type="biblio" href="#biblio-p1673r13" title="A free function linear algebra interface based on the BLAS">[P1673R13]</a> does not rely on any specific widths and
is generalized by default.
The corresponding <a href="https://github.com/kokkos/stdBLAS">reference implementation</a> can operate on <code class="highlight"><c- b>__int128</c-></code>.</p>
   <p>Providing specializations for specific widths is a quality-of-implementation issue.</p>
   <h4 class="heading settled" data-level="8.2.17" id="cstdio-implementation-experience"><span class="secno">8.2.17. </span><span class="content"><code class="highlight"><c- o>&lt;</c-><c- n>cstdio</c-><c- o>></c-></code></span><a class="self-link" href="#cstdio-implementation-experience"></a></h4>
   <p class="note" role="note"><span class="marker">Note:</span> This proposal makes 128-bit <code class="highlight"><c- n>printf</c-></code>/<code class="highlight"><c- n>scanf</c-></code> support entirely optional
(see <a href="#proposed-inttypes">§ 9.3 Header &lt;inttypes.h></a> for wording).</p>
   <p>Similar to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>to_chars</c-></code>, extending support to 128-bit integers for printing and parsing
requires only moderate effort because the underlying algorithm easily generalizes to any bit size.
The <code class="highlight"><c- n>PRI</c-><c- o>*</c-><c- n>LEAST128</c-></code> et al. macros in <code class="highlight"><c- o>&lt;</c-><c- n>cinttypes</c-><c- o>></c-></code> would also need to be defined,
and would expand to an implementation-defined format constant.</p>
   <p>LLVM libc currently uses a <a href="https://github.com/llvm/llvm-project/blob/8373ceef8f2ee377d6daf884e2f3ea11408a7fe2/libc/src/stdio/printf_core/int_converter.h#L50"><code class="highlight"><c- n>num_to_strview</c-><c- p>(</c-><c- b>uintmax_t</c-><c- p>,</c-> <c- p>...)</c-></code></a> function for stringification.
This would require replacement, possibly with a function template.
Other standard libraries may be impacted more significantly.</p>
   <div class="note" role="note">
     <span class="marker">Note:</span> With the changes from <a data-link-type="biblio" href="#biblio-n2680" title="Specific width length modifier">[N2680]</a> included, an alternative C23 way of printing 128-bit
integers is: 
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- n>printf</c-><c- p>(</c-><c- s>"%w128d</c-><c- se>\n</c-><c- s>"</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>int_least128_t</c-><c- p>{</c-><c- mi>123</c-><c- p>});</c->
</pre>
   </div>
   <h4 class="heading settled" data-level="8.2.18" id="atomic-implementation-experience"><span class="secno">8.2.18. </span><span class="content"><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-></code></span><a class="self-link" href="#atomic-implementation-experience"></a></h4>
   <p>Libc++ already provides support for fetch-operations for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-><c- o>&lt;</c-><c- b>__int128</c-><c- o>></c-></code>.
For example, <code class="highlight"><c- p>.</c-><c- n>fetch_add</c-></code> delegates to <code class="highlight"><c- n>__atomic_fetch_add_16</c-></code> in libatomic.</p>
   <p>In general, the <code class="highlight"><c- n>fetch</c-></code> operations that <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>atomic</c-><c- o>&lt;</c-><c- b>long</c-> <c- b>long</c-><c- o>></c-></code> provides
must already have a software fallback for 32-bit hardware, where no 64-bit
atomic <code class="highlight"><c- n>add</c-></code> instruction exists.
Such a software fallback may be implemented as a <a href="https://en.wikipedia.org/wiki/Compare-and-swap">CAS-and-retry</a> loop.
The introduction of 128-bit integers adds no new challenges.</p>
   <h2 class="heading settled" data-level="9" id="proposed-wording"><span class="secno">9. </span><span class="content">Proposed wording</span><a class="self-link" href="#proposed-wording"></a></h2>
   <p>The proposed wording is relative to <a data-link-type="biblio" href="#biblio-cxxdraft" title="C++ Standard Draft">[CxxDraft]</a>, accessed 2024-02-10.</p>
   <h3 class="heading settled" data-level="9.1" id="proposed-version"><span class="secno">9.1. </span><span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>version</c-><c- o>></c-></code></span><a class="self-link" href="#proposed-version"></a></h3>
   <p>In subclause 17.3.2 [version.syn], update the feature-testing macros as follows:</p>
   <blockquote>
<pre class="highlight"><ins><c- cp>#define __cpp_lib_atomic_int128    20XXXX</c-></ins>
<c- cp>#define __cpp_lib_bitset    </c-><del><c- cp>202306L</c-></del><ins><c- cp>20XXXX</c-></ins>
<ins><c- cp>#define __cpp_lib_bitset_int128    20XXXX</c-></ins>
<ins><c- cp>#define __cpp_lib_int128           20XXXX</c-></ins>
<c- cp>#define __cpp_lib_to_string </c-><del><c- cp>202306L</c-></del><ins><c- cp>20XXXX</c-></ins>
<ins><c- cp>#define __cpp_lib_to_string_int128 20XXXX</c-></ins>
</pre>
   </blockquote>
   <p class="note" role="note"><span class="marker">Note:</span> Feature-detection for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>printf</c-></code> and <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>scanf</c-></code> is intentionally omitted
because the user can detect whether <code class="highlight"><c- n>PRI</c-><c- o>*</c-><c- n>LEAST128</c-></code>, <code class="highlight"><c- n>SCN</c-><c- o>*</c-><c- n>FAST128</c-></code> etc. are defined.</p>
   <h3 class="heading settled" data-level="9.2" id="proposed-cstdint"><span class="secno">9.2. </span><span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>cstdint</c-><c- o>></c-></code></span><a class="self-link" href="#proposed-cstdint"></a></h3>
   <p>In subclause 17.4.1 [cstdint.syn], update the synopsis as follows:</p>
   <blockquote>
<pre class="highlight"><c- c1>// all freestanding</c->
<c- k>namespace</c-> <c- nn>std</c-> <c- p>{</c->
  <c- k>using</c-> <c- b>int8_t</c->          <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->    <c- c1>// optional</c->
  <c- k>using</c-> <c- b>int16_t</c->         <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->    <c- c1>// optional</c->
  <c- k>using</c-> <c- b>int32_t</c->         <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->    <c- c1>// optional</c->
  <c- k>using</c-> <c- b>int64_t</c->         <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->    <c- c1>// optional</c->
  <ins><c- k>using</c-> <c- n>int128_t</c->        <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->    <c- c1>// optional</c-></ins>
  <c- k>using</c-> <c- n>intN_t</c->          <c- o>=</c-> <i><c- n>see</c-> <c- n>below</c-></i><c- p>;</c->              <c- c1>// optional</c->

  <c- k>using</c-> <c- b>int_fast8_t</c->     <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>int_fast16_t</c->    <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>int_fast32_t</c->    <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>int_fast64_t</c->    <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <ins><c- k>using</c-> <c- n>int_fast128_t</c->   <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c-></ins>
  <c- k>using</c-> <c- n>int_fastN_t</c->     <c- o>=</c-> <i><c- n>see</c-> <c- n>below</c-></i><c- p>;</c->              <c- c1>// optional</c->

  <c- k>using</c-> <c- b>int_least8_t</c->    <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>int_least16_t</c->   <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>int_least32_t</c->   <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>int_least64_t</c->   <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <ins><c- k>using</c-> <c- n>int_least128_t</c->  <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c-></ins>
  <c- k>using</c-> <c- n>int_leastN_t</c->    <c- o>=</c-> <i><c- n>see</c-> <c- n>below</c-></i><c- p>;</c->              <c- c1>// optional</c->

  <c- k>using</c-> <c- b>intmax_t</c->        <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>intptr_t</c->        <c- o>=</c-> <i><c- b>signed</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->    <c- c1>// optional</c->

  <c- k>using</c-> <c- b>uint8_t</c->         <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->  <c- c1>// optional</c->
  <c- k>using</c-> <c- b>uint16_t</c->        <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->  <c- c1>// optional</c->
  <c- k>using</c-> <c- b>uint32_t</c->        <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->  <c- c1>// optional</c->
  <c- k>using</c-> <c- b>uint64_t</c->        <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->  <c- c1>// optional</c->
  <ins><c- k>using</c-> <c- n>uint128_t</c->       <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->  <c- c1>// optional</c-></ins>
  <c- k>using</c-> <c- n>uintN_t</c->         <c- o>=</c-> <i><c- n>see</c-> <c- n>below</c-></i><c- p>;</c->              <c- c1>// optional</c->

  <c- k>using</c-> <c- b>uint_fast8_t</c->    <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>uint_fast16_t</c->   <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>uint_fast32_t</c->   <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>uint_fast64_t</c->   <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <ins><c- k>using</c-> <c- n>uint_fast128_t</c->  <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c-></ins>
  <c- k>using</c-> <c- n>uint_fastN_t</c->    <c- o>=</c-> <i><c- n>see</c-> <c- n>below</c-></i><c- p>;</c->              <c- c1>// optional</c->

  <c- k>using</c-> <c- b>uint_least8_t</c->   <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>uint_least16_t</c->  <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>uint_least32_t</c->  <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>uint_least64_t</c->  <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <ins><c- k>using</c-> <c- n>uint_least128_t</c-> <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c-></ins>
  <c- k>using</c-> <c- n>uint_leastN_t</c->   <c- o>=</c-> <i><c- n>see</c-> <c- n>below</c-></i><c- p>;</c->              <c- c1>// optional</c->

  <c- k>using</c-> <c- b>uintmax_t</c->       <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->
  <c- k>using</c-> <c- b>uintptr_t</c->       <c- o>=</c-> <i><c- b>unsigned</c-> <c- n>integer</c-> <c- n>type</c-></i><c- p>;</c->  <c- c1>// optional</c->
<c- p>}</c->
</pre>
   </blockquote>
   <p>In subclause 17.4.1 [cstdint.syn], update paragraph 3 as follows:</p>
   <blockquote>
     All types that use the placeholder <em>N</em> are optional when <em>N</em> is not <code class="highlight"><c- mi>8</c-></code>, <code class="highlight"><c- mi>16</c-></code>, <code class="highlight"><c- mi>32</c-></code>, 
    <del>or</del>
     <code class="highlight"><c- mi>64</c-></code>
    <ins>, or <code class="highlight"><c- mi>128</c-></code></ins>
    .
The exact-width types <code class="highlight"><c- n>intN_t</c-></code> and <code class="highlight"><c- n>uintN_t</c-></code> for <em>N</em> = <code class="highlight"><c- mi>8</c-></code>, <code class="highlight"><c- mi>16</c-></code>, <code class="highlight"><c- mi>32</c-></code>, 
    <del>and</del>
     <code class="highlight"><c- mi>64</c-></code>
    <ins>, and <code class="highlight"><c- mi>128</c-></code></ins>
     are also optional;
however, if an implementation defines integer types with the corresponding width and no padding bits,
it defines the corresponding <em>typedef-name</em>s.
Each of the macros listed in this subclause is defined
if and only if the implementation defines the corresponding <em>typedef-name</em>. 
   </blockquote>
   <p>In subclause 17.4.1 [cstdint.syn], add the following paragraph:</p>
   <blockquote>
    <ins>None of the types that use the placeholder <em>N</em> are standard integers types ([basic.fundamental])
if <em>N</em> is greater than 64. <br>[<em>Example</em>: <code class="highlight"><c- n>int_least128_t</c-></code> is an extended integer type. <code class="highlight"><c- b>int_least64_t</c-></code> is an extended integer type or a standard integer type whose width is at least 64.  — <em>end example</em>] </ins>
   </blockquote>
   <p class="note" role="note"><span class="marker">Note:</span> This restriction is intended to address <a href="#impact-on-overload-sets">§ 6.2 Impact on overload sets</a>.</p>
   <h3 class="heading settled" data-level="9.3" id="proposed-inttypes"><span class="secno">9.3. </span><span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code></span><a class="self-link" href="#proposed-inttypes"></a></h3>
   <p>In subclause 17.14 [support.c.headers], add the following subclause:</p>
   <blockquote>
     <b><ins>17.14.X Header <code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code></ins></b> 
    <p>
     <ins> The contents of the C++ header <code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code> are the same as the C standard library
header <code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code> with the following exception:
The definition of the <code class="highlight"><c- n>fprintf</c-></code> and <code class="highlight"><c- n>fscanf</c-></code> macros for the corresponding
integers in the header <code class="highlight"><c- o>&lt;</c-><c- n>stdint</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code> is optional for any integer with a width greater
than 64.
However, if any macro for an integer with width <em>N</em> is defined,
all macros corresponding to integers with the same or lower width as <em>N</em> shall be defined. <br><br> See also: ISO/IEC 9899:2018, 7.8.1 </ins>
    </p>
   </blockquote>
   <p class="note" role="note"><span class="marker">Note:</span> This effectively makes <code class="highlight"><c- n>printf</c-></code>/<code class="highlight"><c- n>scanf</c-></code> 128-bit support optional because without any <code class="highlight"><c- n>PRI</c-></code>/<code class="highlight"><c- n>SCN</c-></code> macros, the user has no standard way of using these functions with 128-bit integers.</p>
   <p class="note" role="note"><span class="marker">Note:</span> After rebasing on C23, additional restrictions to <code class="highlight"><c- n>stdio</c-><c- p>.</c-><c- n>h</c-></code> must be applied
so that <code class="highlight"><c- o>%</c-><c- n>w128d</c-></code> (see <a data-link-type="biblio" href="#biblio-n2680" title="Specific width length modifier">[N2680]</a>) is not mandatory in C++.</p>
   <h3 class="heading settled" data-level="9.4" id="proposed-bitset"><span class="secno">9.4. </span><span class="content">Class template <code class="highlight"><c- n>bitset</c-></code></span><a class="self-link" href="#proposed-bitset"></a></h3>
   <p>In subclause 22.9.2.1 [template.bitset.general], update the synopsis as follows:</p>
   <blockquote>
<pre class="highlight">    <c- c1>// [bitset.cons], constructors</c->
    <c- k>constexpr</c-> <c- n>bitset</c-><c- p>()</c-> <c- k>noexcept</c-><c- p>;</c->
<del>    <c- k>constexpr</c-> <c- n>bitset</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></del>
<ins>    <c- k>constexpr</c-> <c- n>bitset</c-><c- p>(</c-><i><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>val</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></ins>
<c- p>[...]</c->
    <c- k>constexpr</c-> <c- b>unsigned</c-> <c- b>long</c->        <c- n>to_ulong</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
    <c- k>constexpr</c-> <c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c->   <c- nf>to_ullong</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
<ins>    <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>to</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c-></ins>
</pre>
   </blockquote>
   <p>In subclause 22.9.2.1 [template.bitset.general], add a paragraph:</p>
   <blockquote>
    <p class="indent">
     <ins>For each function with a parameter of type <em>integer-least-int</em>,
the implementation provides an overload for each cv-unqualified
integer type ([basic.fundamental]) whose conversion rank is that of <code class="highlight"><c- b>int</c-></code> or greater,
where <i>integer-least-int</i> in the function signature is replaced with that
integer type.</ins>
    </p>
   </blockquote>
   <p class="note" role="note"><span class="marker">Note:</span> See <a href="#bitset-constructor">§ 6.4 std::bitset constructor semantic changes</a> for discussion.</p>
   <p>In subclause 22.9.2.2 [template.bitset.const], update the constructors as follows:</p>
   <blockquote>
<pre class="highlight"><del><c- k>constexpr</c-> <c- n>bitset</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></del>
<ins><c- k>constexpr</c-> <c- n>bitset</c-><c- p>(</c-><i><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>val</c-><c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></ins>
</pre>
    <p class="indent">
      <em>Effects</em>: Initializes the first <code class="highlight"><c- n>M</c-></code> bit positions to the corresponding bit values in val. <code class="highlight"><c- n>M</c-></code> is the smaller of <code class="highlight"><c- n>N</c-></code> and the 
     <del>number of bits in the value representation</del>
     <ins>width</ins>
      ([basic.types.general]) of 
     <del><code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code></del>
     <ins><i>integer-least-int</i></ins>
     .
If <code class="highlight"><c- n>M</c-> <c- o>&lt;</c-> <c- n>N</c-></code>, the remaining bit positions are initialized to 
     <del>zero</del>
     <ins>one if <code class="highlight"><c- n>val</c-></code> is negative, otherwise to zero</ins>
     . 
    </p>
   </blockquote>
   <p>In subclause 22.9.2.3 [bitset.members], make the following changes:</p>
   <blockquote>
<pre class="highlight"><c- k>constexpr</c-> <c- b>unsigned</c-> <c- b>long</c-> <c- nf>to_ulong</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
</pre>
    <p class="indent">
     <del><em>Returns</em>: <code class="highlight"><c- n>x</c-></code>.</del>
    </p>
    <p class="indent">
     <del><em>Throws</em>: <code class="highlight"><c- n>overflow_error</c-></code> if the integral value <code class="highlight"><c- n>x</c-></code> corresponding to the bits in <code class="highlight"><c- o>*</c-><c- k>this</c-></code> cannot be represented as type <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-></code>.</del>
    </p>
<pre class="highlight"><c- k>constexpr</c-> <c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <c- nf>to_ullong</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c->
<ins><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- o>></c->
<ins>  <c- k>constexpr</c-> <c- n>T</c-> <c- n>to</c-><c- p>()</c-> <c- k>const</c-><c- p>;</c-></ins>
</ins></pre>
    <p class="indent">
     <ins><em>Constraints</em>: <code class="highlight"><c- n>T</c-></code> is an unsigned integer type ([basic.fundamental]).</ins>
    </p>
    <p class="indent"> <em>Returns</em>: <code class="highlight"><c- n>x</c-></code>. </p>
    <p class="indent">
      <em>Throws</em>: <code class="highlight"><c- n>overflow_error</c-></code> if the integral value <code class="highlight"><c- n>x</c-></code> corresponding to the bits in <code class="highlight"><c- o>*</c-><c- k>this</c-></code> cannot be represented as 
     <del>type <code class="highlight"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></code></del>
     <ins>the return type of this function</ins>
     . 
    </p>
   </blockquote>
   <h3 class="heading settled" data-level="9.5" id="proposed-numeric-conversions"><span class="secno">9.5. </span><span class="content">Numeric conversions</span><a class="self-link" href="#proposed-numeric-conversions"></a></h3>
   <p>Update subclause 23.4.2 [string.syn] as follows:</p>
   <blockquote>
<pre class="highlight"><del>  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>int</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>unsigned</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- n>int_least128_t</c-><c- p>);</c-></del>
<ins>  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><i><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>val</c-><c- p>);</c-></ins>
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>float</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>double</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>long</c-> <c- b>double</c-> <c- n>val</c-><c- p>);</c->
<c- p>[...]</c->
<del>  <c- n>wstring</c-> <c- n>to_wstring</c-><c- p>(</c-><c- b>int</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>unsigned</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c-></del>
<ins>  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><i><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>val</c-><c- p>);</c-></ins>
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>float</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>double</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>long</c-> <c- b>double</c-> <c- n>val</c-><c- p>);</c->
</pre>
   </blockquote>
   <p>In subclause 23.4.2 [string.syn], add a paragraph:</p>
   <blockquote>
    <ins>For each function with a parameter of type <em>integer-least-int</em>,
the implementation provides an overload for each cv-unqualified
integer type ([basic.fundamental]) whose conversion rank is that of <code class="highlight"><c- b>int</c-></code> or greater,
where <em>integer-least-int</em> in the function signature is replaced with that integer type.</ins>
   </blockquote>
   <p>In subclause 23.4.5 [string.conversions], update <code class="highlight"><c- n>to_string</c-></code>:</p>
   <blockquote>
<pre class="highlight"><del>  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>int</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>unsigned</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c-></del>
<ins>  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><i><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>val</c-><c- p>);</c-></ins>
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>float</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>double</c-> <c- n>val</c-><c- p>);</c->
  <c- n>string</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>long</c-> <c- b>double</c-> <c- n>val</c-><c- p>);</c->
</pre>
    <p class="indent"> <em>Returns</em>: <code class="highlight"><c- n>format</c-><c- p>(</c-><c- s>"{}"</c-><c- p>,</c-> <c- n>val</c-><c- p>)</c-></code>. </p>
   </blockquote>
   <p>In subclause 23.4.5 [string.conversions], update <code class="highlight"><c- n>to_wstring</c-></code>:</p>
   <blockquote>
<pre class="highlight"><del>  <c- n>wstring</c-> <c- nf>to_string</c-><c- p>(</c-><c- b>int</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>unsigned</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <c- n>val</c-><c- p>);</c-></del>
<ins>  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><i><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>val</c-><c- p>);</c-></ins>
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>float</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>double</c-> <c- n>val</c-><c- p>);</c->
  <c- n>wstring</c-> <c- nf>to_wstring</c-><c- p>(</c-><c- b>long</c-> <c- b>double</c-> <c- n>val</c-><c- p>);</c->
</pre>
    <p class="indent"> <em>Returns</em>: <code class="highlight"><c- n>format</c-><c- p>(</c->L<c- s>"{}"</c-><c- p>,</c-> <c- n>val</c-><c- p>)</c-></code>. </p>
   </blockquote>
   <h3 class="heading settled" data-level="9.6" id="proposed-iota"><span class="secno">9.6. </span><span class="content">Iota view</span><a class="self-link" href="#proposed-iota"></a></h3>
   <p>In subclause 26.6.4.2 [ranges.iota.view], update paragraph 1 as follows:</p>
   <blockquote>
     Let <code class="highlight"><i><c- n>IOTA</c-><c- o>-</c-><c- n>DIFF</c-><c- o>-</c-><c- n>T</c-><c- p>(</c-><c- n>W</c-><c- p>)</c-></i></code> be defined as follows: 
    <ul>
     <li data-md>
      <p>If <code class="highlight"><c- n>W</c-></code> is not an integral type, or if it is an integral type and <code class="highlight"><c- k>sizeof</c-><c- p>(</c-><c- n>iter_difference_t</c-><c- o>&lt;</c-><c- n>W</c-><c- o>></c-><c- p>)</c-></code> is greater than <code class="highlight"><c- k>sizeof</c-><c- p>(</c-><c- n>W</c-><c- p>)</c-></code>, then <code class="highlight"><i><c- n>IOTA</c-><c- o>-</c-><c- n>DIFF</c-><c- o>-</c-><c- n>T</c-><c- p>(</c-><c- n>W</c-><c- p>)</c-></i></code> denotes <code class="highlight"><c- n>iter_difference_t</c-><c- o>&lt;</c-><c- n>W</c-><c- o>></c-></code>.</p>
     <li data-md>
      <p>
       Otherwise, <code class="highlight"><i><c- n>IOTA</c-><c- o>-</c-><c- n>DIFF</c-><c- o>-</c-><c- n>T</c-><c- p>(</c-><c- n>W</c-><c- p>)</c-></i></code> is a signed 
       <ins>standard</ins>
        integer type of width greater than the width of <code class="highlight"><c- n>W</c-></code> if such a type exists.
      </p>
     <li data-md>
      <p>Otherwise, <code class="highlight"><i><c- n>IOTA</c-><c- o>-</c-><c- n>DIFF</c-><c- o>-</c-><c- n>T</c-><c- p>(</c-><c- n>W</c-><c- p>)</c-></i></code> is an unspecified signed-integer-like type ([iterator.concept.winc]) of width not less than the width of <code class="highlight"><c- n>W</c-></code>. <br>[<em>Note</em> 1: It is unspecified whether this type satisfies <code class="highlight"><c- n>weakly_incrementable</c-></code>.
— <em>end note</em>]</p>
    </ul>
   </blockquote>
   <p class="note" role="note"><span class="marker">Note:</span> This change resolves the potential ABI break explained in <a href="#iota-view-abi-break">§ 5.2 std::ranges::iota_view ABI issue</a>.
This change purely increases implementor freedom.
An extended integer type still models signed-integer-like, so GCC’s existing implementation
using <code class="highlight"><c- b>__int128</c-></code> remains valid.
However, a wider extended integer type is no longer the mandatory difference type (if it exists)
as per the second bullet.</p>
   <h3 class="heading settled" data-level="9.7" id="proposed-abs"><span class="secno">9.7. </span><span class="content">Absolute values</span><a class="self-link" href="#proposed-abs"></a></h3>
   <p>In subclause 28.7.1 [cmath.syn], update the synopsis as follows:</p>
   <blockquote>
<pre class="highlight">  <c- c1>// [c.math.abs], absolute values</c->
<del>  <c- k>constexpr</c-> <c- b>int</c-> <c- nf>abs</c-><c- p>(</c-><c- b>int</c-> <c- n>j</c-><c- p>);</c->                                         <c- c1>// freestanding</c->
  <c- k>constexpr</c-> <c- b>long</c-> <c- b>int</c-> <c- nf>abs</c-><c- p>(</c-><c- b>long</c-> <c- b>int</c-> <c- n>j</c-><c- p>);</c->                               <c- c1>// freestanding</c->
  <c- k>constexpr</c-> <c- b>long</c-> <c- b>long</c-> <c- b>int</c-> <c- nf>abs</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-> <c- b>int</c-> <c- n>j</c-><c- p>);</c->                     <c- c1>// freestanding</c-></del>
<ins>  <c- k>constexpr</c-> <i><c- b>signed</c-><c- o>-</c-><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>abs</c-><c- p>(</c-><i><c- b>signed</c-><c- o>-</c-><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>j</c-><c- p>);</c-> <c- c1>// freestanding</c-></ins>
  <c- k>constexpr</c-> <i><c- n>floating</c-><c- o>-</c-><c- n>point</c-><c- o>-</c-><c- n>type</c-></i> <c- n>abs</c-><c- p>(</c-><i><c- n>floating</c-><c- o>-</c-><c- n>point</c-><c- o>-</c-><c- n>type</c-></i> <c- n>j</c-><c- p>);</c->           <c- c1>// freestanding-deleted</c->
</pre>
   </blockquote>
   <p>In subclause 28.7.1 [cmath.syn], add a paragraph after paragraph 2:</p>
   <blockquote>
    <ins>For each function with a parameter of type <em>signed-integer-least-int</em>,
the implementation provides an overload for each cv-unqualified
signed integer type ([basic.fundamental]) whose conversion rank is that of <code class="highlight"><c- b>int</c-></code> or greater,
where all uses of <em>signed-integer-least-int</em> in the function signature are replaced with that
signed integer type.</ins>
   </blockquote>
   <p>In subclause 28.7.2 [c.math.abs], make the following changes:</p>
   <blockquote>
<pre class="highlight"><del><c- k>constexpr</c-> <c- b>int</c-> <c- nf>abs</c-><c- p>(</c-><c- b>int</c-> <c- n>j</c-><c- p>);</c->
<c- k>constexpr</c-> <c- b>long</c-> <c- b>int</c-> <c- nf>abs</c-><c- p>(</c-><c- b>long</c-> <c- b>int</c-> <c- n>j</c-><c- p>);</c->
<c- k>constexpr</c-> <c- b>long</c-> <c- b>long</c-> <c- b>int</c-> <c- nf>abs</c-><c- p>(</c-><c- b>long</c-> <c- b>long</c-> <c- b>int</c-> <c- n>j</c-><c- p>);</c-></del>
<ins><c- k>constexpr</c-> <i><c- b>signed</c-><c- o>-</c-><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>abs</c-><c- p>(</c-><i><c- b>signed</c-><c- o>-</c-><c- n>integer</c-><c- o>-</c-><c- n>least</c-><c- o>-</c-><c- b>int</c-></i> <c- n>j</c-><c- p>);</c-></ins>
</pre>
    <p class="indent">
     <del><em>Effects</em>: These functions have the semantics specified in the C standard library for the functions <code class="highlight"><c- n>abs</c-></code>, <code class="highlight"><c- n>labs</c-></code>, and <code class="highlight"><c- n>llabs</c-></code>, respectively.</del>
     <ins><em>Returns</em>: <code class="highlight"><c- n>j</c-> <c- o>>=</c-> <c- mi>0</c-> <c- o>?</c-> <c- n>j</c-> <c- o>:</c-> <c- o>-</c-><c- n>j</c-><c- p>;</c-></code>. </ins>
    </p>
   </blockquote>
   <p class="note" role="note"><span class="marker">Note:</span> <code class="highlight"><c- n>j</c-> <c- o>>=</c-> <c- mi>0</c-> <c- o>?</c-> <c- n>j</c-> <c- o>:</c-> <c- o>-</c-><c- n>j</c-><c- p>;</c-></code> matches the semantics of the C functions exactly,
even in undefined cases like <code class="highlight"><c- n>abs</c-><c- p>(</c-><c- n>INT_MAX</c-><c- p>)</c-></code>.</p>
   <p class="note" role="note"><span class="marker">Note:</span> The floating-point overload set is intentionally not re-defined to return <code class="highlight"><c- n>j</c-> <c- o>>=</c-> <c- mi>0</c-> <c- o>?</c-> <c- n>j</c-> <c- o>:</c-> <c- o>-</c-><c- n>j</c-></code>.
This expression is not equivalent to clearing the sign bit.</p>
   <h3 class="heading settled" data-level="9.8" id="proposed-cinttypes"><span class="secno">9.8. </span><span class="content">Header <code class="highlight"><c- o>&lt;</c-><c- n>cinttypes</c-><c- o>></c-></code></span><a class="self-link" href="#proposed-cinttypes"></a></h3>
   <p>In subclause 31.13.2 [cinttypes.syn], update paragraph 1 as follows:</p>
   <blockquote>
     The contents and meaning of the header <code class="highlight"><c- o>&lt;</c-><c- n>cinttypes</c-><c- o>></c-></code> are the same as the 
    <del>C standard library</del>
    <ins>C++</ins>
     header <code class="highlight"><c- o>&lt;</c-><c- n>inttypes</c-><c- p>.</c-><c- n>h</c-><c- o>></c-></code>, with the following changes: 
   </blockquote>
   <p class="note" role="note"><span class="marker">Note:</span> Unlike the C standard library header, the <em>C++ header</em> has the changes described in <a href="#proposed-inttypes">§ 9.3 Header &lt;inttypes.h></a> applied.</p>
   <h3 class="heading settled" data-level="9.9" id="proposed-atomic"><span class="secno">9.9. </span><span class="content">Atomic operations</span><a class="self-link" href="#proposed-atomic"></a></h3>
   <p>In subclause 33.5.2 [atomics.syn], update the synopsis as follows:</p>
   <blockquote>
<pre class="highlight"><c- c1>// all freestanding</c->
<c- k>namespace</c-> <c- nn>std</c-> <c- p>{</c->
  <c- p>[...]</c->

  <c- k>using</c-> <c- n>atomic_int8_t</c->          <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int8_t</c-><c- o>></c-><c- p>;</c->           <c- c1>// freestanding</c->
  <c- k>using</c-> <c- n>atomic_uint8_t</c->         <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint8_t</c-><c- o>></c-><c- p>;</c->          <c- c1>// freestanding</c->
  <c- k>using</c-> <c- n>atomic_int16_t</c->         <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int16_t</c-><c- o>></c-><c- p>;</c->          <c- c1>// freestanding</c->
  <c- k>using</c-> <c- n>atomic_uint16_t</c->        <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint16_t</c-><c- o>></c-><c- p>;</c->         <c- c1>// freestanding</c->
  <c- k>using</c-> <c- n>atomic_int32_t</c->         <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int32_t</c-><c- o>></c-><c- p>;</c->          <c- c1>// freestanding</c->
  <c- k>using</c-> <c- n>atomic_uint32_t</c->        <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint32_t</c-><c- o>></c-><c- p>;</c->         <c- c1>// freestanding</c->
  <c- k>using</c-> <c- n>atomic_int64_t</c->         <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int64_t</c-><c- o>></c-><c- p>;</c->          <c- c1>// freestanding</c->
  <c- k>using</c-> <c- n>atomic_uint64_t</c->        <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint64_t</c-><c- o>></c-><c- p>;</c->         <c- c1>// freestanding</c->
<ins>  <c- k>using</c-> <c- n>atomic_int128_t</c->        <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- n>int128_t</c-><c- o>></c-><c- p>;</c->         <c- c1>// freestanding</c-></ins>
<ins>  <c- k>using</c-> <c- n>atomic_uint128_t</c->       <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- n>uint128_t</c-><c- o>></c-><c- p>;</c->        <c- c1>// freestanding</c-></ins>

  <c- k>using</c-> <c- b>atomic_int_least8_t</c->    <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int_least8_t</c-><c- o>></c-><c- p>;</c->     <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_uint_least8_t</c->   <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_least8_t</c-><c- o>></c-><c- p>;</c->    <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_int_least16_t</c->   <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int_least16_t</c-><c- o>></c-><c- p>;</c->    <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_uint_least16_t</c->  <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_least16_t</c-><c- o>></c-><c- p>;</c->   <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_int_least32_t</c->   <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int_least32_t</c-><c- o>></c-><c- p>;</c->    <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_uint_least32_t</c->  <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_least32_t</c-><c- o>></c-><c- p>;</c->   <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_int_least64_t</c->   <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int_least64_t</c-><c- o>></c-><c- p>;</c->    <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_uint_least64_t</c->  <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_least64_t</c-><c- o>></c-><c- p>;</c->   <c- c1>// freestanding</c->
<ins>  <c- k>using</c-> <c- n>atomic_int_least128_t</c->  <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- n>int_least128_t</c-><c- o>></c-><c- p>;</c->   <c- c1>// freestanding</c-></ins>
<ins>  <c- k>using</c-> <c- n>atomic_uint_least128_t</c-> <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- n>uint_least128_t</c-><c- o>></c-><c- p>;</c->  <c- c1>// freestanding</c-></ins>

  <c- k>using</c-> <c- b>atomic_int_fast8_t</c->     <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int_fast8_t</c-><c- o>></c-><c- p>;</c->      <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_uint_fast8_t</c->    <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_fast8_t</c-><c- o>></c-><c- p>;</c->     <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_int_fast16_t</c->    <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int_fast16_t</c-><c- o>></c-><c- p>;</c->     <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_uint_fast16_t</c->   <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_fast16_t</c-><c- o>></c-><c- p>;</c->    <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_int_fast32_t</c->    <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int_fast32_t</c-><c- o>></c-><c- p>;</c->     <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_uint_fast32_t</c->   <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_fast32_t</c-><c- o>></c-><c- p>;</c->    <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_int_fast64_t</c->    <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>int_fast64_t</c-><c- o>></c-><c- p>;</c->     <c- c1>// freestanding</c->
  <c- k>using</c-> <c- b>atomic_uint_fast64_t</c->   <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- b>uint_fast64_t</c-><c- o>></c-><c- p>;</c->    <c- c1>// freestanding</c->
<ins>  <c- k>using</c-> <c- n>atomic_int_fast128_t</c->   <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- n>int_fast128_t</c-><c- o>></c-><c- p>;</c->    <c- c1>// freestanding</c-></ins>
<ins>  <c- k>using</c-> <c- n>atomic_uint_fast128_t</c->  <c- o>=</c-> <c- n>atomic</c-><c- o>&lt;</c-><c- n>uint_fast128_t</c-><c- o>></c-><c- p>;</c->   <c- c1>// freestanding</c-></ins>

  <c- p>[...]</c->
<c- p>}</c->
</pre>
   </blockquote>
   <h2 class="heading settled" data-level="10" id="acknowledgements"><span class="secno">10. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h2>
   <p>I thank Jonathan Wakely and other participants in the std-proposals mailing list whose feedback
has helped me improve the quality of this proposal substantially.</p>
   <p>I also thank Lénárd Szolnoki for contributing the example in <a href="#lifting-library-restrictions">§ 2.1 Lifting library restrictions</a>.</p>
   <p class="note" role="note"><span class="marker">Note:</span> See <a data-link-type="biblio" href="#biblio-std-proposals" title="[std-proposals] 128-bit integers">[std-proposals]</a> for discussion of this proposal.</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-cxxdraft">[CxxDraft]
   <dd>VA. <a href="https://github.com/cplusplus/draft/commit/8238252bcec14f76e97133db32721beaec5c749b"><cite>C++ Standard Draft</cite></a>. URL: <a href="https://github.com/cplusplus/draft/commit/8238252bcec14f76e97133db32721beaec5c749b">https://github.com/cplusplus/draft/commit/8238252bcec14f76e97133db32721beaec5c749b</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-bitpermutations">[BitPermutations]
   <dd>Jan Schultke et al.. <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-bloomberg">[Bloomberg]
   <dd>Bloomberg Finance L.P. et al.. <a href="https://github.com/bloomberg/bde"><cite>BDE Libraries</cite></a>. URL: <a href="https://github.com/bloomberg/bde">https://github.com/bloomberg/bde</a>
   <dt id="biblio-boostmultiprecision">[BoostMultiPrecision]
   <dd>Boost Org. <a href="https://github.com/boostorg/multiprecision"><cite>Boost Multiprecision Library</cite></a>. URL: <a href="https://github.com/boostorg/multiprecision">https://github.com/boostorg/multiprecision</a>
   <dt id="biblio-clickhouse">[ClickHouse]
   <dd>ClickHouse et al.. <a href="https://github.com/ClickHouse/ClickHouse"><cite>ClickHouse</cite></a>. URL: <a href="https://github.com/ClickHouse/ClickHouse">https://github.com/ClickHouse/ClickHouse</a>
   <dt id="biblio-deshawresearch">[DEShawResearch]
   <dd>John Salmon et al.. <a href="https://github.com/DEShawResearch/random123"><cite>Random123: a Library of Counter-Based Random Number Generators</cite></a>. URL: <a href="https://github.com/DEShawResearch/random123">https://github.com/DEShawResearch/random123</a>
   <dt id="biblio-dragonbox">[Dragonbox]
   <dd>Junekey Jeon. <a href="https://github.com/jk-jeon/dragonbox/blob/master/other_files/Dragonbox.pdf"><cite>Dragonbox: A New FLoating-Point Binary-to-Decimal Conversion Algorithm</cite></a>. URL: <a href="https://github.com/jk-jeon/dragonbox/blob/master/other_files/Dragonbox.pdf">https://github.com/jk-jeon/dragonbox/blob/master/other_files/Dragonbox.pdf</a>
   <dt id="biblio-fast_float">[FAST_FLOAT]
   <dd>Daniel Lemire et al.. <a href="https://github.com/fastfloat/fast_float"><cite>fast_float number parsing library: 4x faster than strtod</cite></a>. URL: <a href="https://github.com/fastfloat/fast_float">https://github.com/fastfloat/fast_float</a>
   <dt id="biblio-libdivide">[LIBDIVIDE]
   <dd>Kim Walisch et al.. <a href="https://github.com/ridiculousfish/libdivide"><cite>libdivide</cite></a>. URL: <a href="https://github.com/ridiculousfish/libdivide">https://github.com/ridiculousfish/libdivide</a>
   <dt id="biblio-marsaglia">[Marsaglia]
   <dd>George Marsaglia. <a href="https://www.jstatsoft.org/article/download/v008i14/916"><cite>Xorshift RNGs</cite></a>. URL: <a href="https://www.jstatsoft.org/article/download/v008i14/916">https://www.jstatsoft.org/article/download/v008i14/916</a>
   <dt id="biblio-msdn">[MSDN]
   <dd>Colen Garoutte-Carson et al.. <a href="https://developercommunity.microsoft.com/t/Support-for-128-bit-integer-type/879048"><cite>Support for 128-bit integer type</cite></a>. URL: <a href="https://developercommunity.microsoft.com/t/Support-for-128-bit-integer-type/879048">https://developercommunity.microsoft.com/t/Support-for-128-bit-integer-type/879048</a>
   <dt id="biblio-n2341">[N2341]
   <dd>ISO/IEC. <a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2341.pdf"><cite>Floating-point extensions for C - Decimal floating-point arithmetic</cite></a>. URL: <a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2341.pdf">https://open-std.org/JTC1/SC22/WG14/www/docs/n2341.pdf</a>
   <dt id="biblio-n2680">[N2680]
   <dd>Robert C. Seacord. <a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2680.pdf"><cite>Specific width length modifier</cite></a>. URL: <a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2680.pdf">https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2680.pdf</a>
   <dt id="biblio-n2709">[N2709]
   <dd>Anthony Williams. <a href="https://wg21.link/n2709"><cite>Packaging Tasks for Asynchronous Execution</cite></a>. 28 July 2008. URL: <a href="https://wg21.link/n2709">https://wg21.link/n2709</a>
   <dt id="biblio-n2763">[N2763]
   <dd>Aaron Ballman; et al. <a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf"><cite>Adding a Fundamental Type for N-bit integers</cite></a>. URL: <a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf">https://open-std.org/JTC1/SC22/WG14/www/docs/n2763.pdf</a>
   <dt id="biblio-n3047">[N3047]
   <dd>ISO. <a href="https://www.iso-9899.info/n3047.html"><cite>N3047 working draft — August 4, 2022 ISO/IEC 9899:2023 (E)</cite></a>. URL: <a href="https://www.iso-9899.info/n3047.html">https://www.iso-9899.info/n3047.html</a>
   <dt id="biblio-nvidia">[NVIDIA]
   <dd>Conor Hoekstra; Kuhu Shukla; Mark Harris. <a href="https://developer.nvidia.com/blog/implementing-high-precision-decimal-arithmetic-with-cuda-int128/"><cite>Implementing High-Precision Decimal Arithmetic with CUDA int128</cite></a>. URL: <a href="https://developer.nvidia.com/blog/implementing-high-precision-decimal-arithmetic-with-cuda-int128/">https://developer.nvidia.com/blog/implementing-high-precision-decimal-arithmetic-with-cuda-int128/</a>
   <dt id="biblio-p0543r3">[P0543R3]
   <dd>Jens Maurer. <a href="https://wg21.link/p0543r3"><cite>Saturation arithmetic</cite></a>. 19 July 2023. URL: <a href="https://wg21.link/p0543r3">https://wg21.link/p0543r3</a>
   <dt id="biblio-p1522r1">[P1522R1]
   <dd>Eric Niebler. <a href="https://wg21.link/p1522r1"><cite>Iterator Difference Type and Integer Overflow</cite></a>. 28 July 2019. URL: <a href="https://wg21.link/p1522r1">https://wg21.link/p1522r1</a>
   <dt id="biblio-p1673r13">[P1673R13]
   <dd>Mark Hoemmen, Daisy Hollman,Christian Trott,Daniel Sunderland,Nevin Liber,Alicia KlinvexLi-Ta Lo,Damien Lebrun-Grandie,Graham Lopez,Peter Caday,Sarah Knepper,Piotr Luszczek,Timothy Costa. <a href="https://wg21.link/p1673r13"><cite>A free function linear algebra interface based on the BLAS</cite></a>. 18 December 2023. URL: <a href="https://wg21.link/p1673r13">https://wg21.link/p1673r13</a>
   <dt id="biblio-p2075r3">[P2075R3]
   <dd>Ilya Burylov, Ruslan Arutyunyan; Andrey Nikolaev; Alina Elizarova; Pavel Dyakov; John Salmon. <a href="https://wg21.link/p2075r3"><cite>Philox as an extension of the C++ RNG engines</cite></a>. 13 October 2023. URL: <a href="https://wg21.link/p2075r3">https://wg21.link/p2075r3</a>
   <dt id="biblio-p3018r0">[P3018R0]
   <dd>Andreas Weis. <a href="https://wg21.link/p3018r0"><cite>Low-Level Integer Arithmetic</cite></a>. 15 October 2023. URL: <a href="https://wg21.link/p3018r0">https://wg21.link/p3018r0</a>
   <dt id="biblio-px0">[PX0]
   <dd>PikaCat. <a href="https://github.com/official-pikafish/px0"><cite>Px0</cite></a>. URL: <a href="https://github.com/official-pikafish/px0">https://github.com/official-pikafish/px0</a>
   <dt id="biblio-risc-v">[RISC-V]
   <dd>VA. <a href="https://drive.google.com/file/d/1s0lZxUZaa7eV_O0_WsZzaurFLLww7ou5/view"><cite>The RISC-V Instruction Set Manual - Volume I: Unprivileged ISA</cite></a>. URL: <a href="https://drive.google.com/file/d/1s0lZxUZaa7eV_O0_WsZzaurFLLww7ou5/view">https://drive.google.com/file/d/1s0lZxUZaa7eV_O0_WsZzaurFLLww7ou5/view</a>
   <dt id="biblio-sec">[SEC]
   <dd>U.S. Securities and Exchange Commission. <a href="https://www.sec.gov/divisions/marketreg/subpenny612faq.htm"><cite>Division of Market Regulation: Responses to Frequently Asked Questions Concerning Rule 612 (Minimum Pricing Increment) of Regulation NMS</cite></a>. URL: <a href="https://www.sec.gov/divisions/marketreg/subpenny612faq.htm">https://www.sec.gov/divisions/marketreg/subpenny612faq.htm</a>
   <dt id="biblio-std-proposals">[STD-PROPOSALS]
   <dd>VA. <a href="https://lists.isocpp.org/std-proposals/2024/02/8972.php"><cite>[std-proposals] 128-bit integers</cite></a>. URL: <a href="https://lists.isocpp.org/std-proposals/2024/02/8972.php">https://lists.isocpp.org/std-proposals/2024/02/8972.php</a>
   <dt id="biblio-stockfish">[Stockfish]
   <dd>Marco Costalba et al.. <a href="https://github.com/official-stockfish/Stockfish"><cite>Stockfish</cite></a>. URL: <a href="https://github.com/official-stockfish/Stockfish">https://github.com/official-stockfish/Stockfish</a>
   <dt id="biblio-tigerbeetle">[TigerBeetle]
   <dd>Rafael Batiati. <a href="https://tigerbeetle.com/blog/2023-09-19-64-bit-bank-balances-ought-to-be-enough-for-anybody/"><cite>64-Bit Bank Balances ‘Ought to be Enough for Anybody’?</cite></a>. URL: <a href="https://tigerbeetle.com/blog/2023-09-19-64-bit-bank-balances-ought-to-be-enough-for-anybody/">https://tigerbeetle.com/blog/2023-09-19-64-bit-bank-balances-ought-to-be-enough-for-anybody/</a>
   <dt id="biblio-wikipedia">[Wikipedia]
   <dd>VA. <a href="https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Hardware_support"><cite>Quadruple-precision floating-point format - Hardware support</cite></a>. URL: <a href="https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Hardware_support">https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Hardware_support</a>
  </dl>