<!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>P3299R2: Proposal to extend &lt;code>std::simd&lt;/code> with range constructors</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 74068a90b, updated Wed Mar 22 17:34:51 2023 -0700" name="generator">
  <link href="https://isocpp.org/files/papers/P2876R2.html" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
  <meta content="efe475a08ff98bd1caf8e2f266a7d6b9ca7e377e" name="document-revision">
<style>
.ins, ins, ins * {
    background-color: rgb(200, 250, 200);
    color: rgb(0, 136, 0);
    text-decoration: none;
}
.span, span, span * {
    white-space: pre
}
</style>
<style>
.remove, remove, remove * {
    background-color: rgb(250, 200, 200);
    color: rgb(136, 0, 0);
    text-decoration: none;
}
.span, span, span * {
    white-space: pre
}
</style>
<style>/* 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;
}
</style>
<style>/* 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;
}
</style>
<style>/* 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>/* style-issues */
a[href].issue-return {
    float: right;
    float: inline-end;
    color: var(--issueheading-text);
    font-weight: bold;
    text-decoration: none;
}
</style>
<style>/* 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>/* 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>/* 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 */
</style>
<style>/* style-darkmode */

@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; }
}

@media (prefers-color-scheme: dark) {
    :root {
        --selflink-text: black;
        --selflink-bg: silver;
        --selflink-hover-text: white;
    }
}

@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">P3299R2<br>Proposal to extend <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>simd</c-></code> with range constructors</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-10-16">2024-10-16</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://isocpp.org/files/papers/P2876R2.html">https://isocpp.org/files/papers/P2876R2.html</a>
     <dt class="editor">Authors:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:daniel.towner@intel.com">Daniel Towner</a> (<span class="p-org org">Intel</span>)
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:m.kretz@gsi.de">Matthias Kretz</a> (<span class="p-org org">GSI</span>)
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:ruslan.arutyunyan@intel.com">Ruslan Arutyunyan</a> (<span class="p-org org">Intel</span>)
     <dt>Audience:
     <dd>LEWG
     <dt>Project:
     <dd>ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21
    </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>Proposal to extend <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>simd</c-></code> with range constructors to address issues raised in LEWG and documented in <a data-link-type="biblio" href="#biblio-p3024r0" title="Interface Directions for std::simd">[P3024R0]</a>.</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="#intro"><span class="secno">2</span> <span class="content">Motivation</span></a>
    <li><a href="#memory_accessor_ctors"><span class="secno">3</span> <span class="content">Existing functions for memory accesses</span></a>
    <li><a href="#general_access_guidelines"><span class="secno">4</span> <span class="content">Generic guidelines for safe memory accesses</span></a>
    <li><a href="#compile_time_extent"><span class="secno">5</span> <span class="content">Accessing a source of compile-time extent</span></a>
    <li>
     <a href="#dynamic_extent"><span class="secno">6</span> <span class="content">Accessing a source of bounded but unknown extent</span></a>
     <ol class="toc">
      <li><a href="#undefined_behaviour"><span class="secno">6.1</span> <span class="content">Undefined behaviour</span></a>
      <li><a href="#defined_behaviour"><span class="secno">6.2</span> <span class="content">Defined behaviour</span></a>
      <li><a href="#erroneous_behaviour"><span class="secno">6.3</span> <span class="content">Erroneous behaviour</span></a>
      <li><a href="#exception_behaviour"><span class="secno">6.4</span> <span class="content">Exception</span></a>
      <li><a href="#choosing_default_load_behaviour"><span class="secno">6.5</span> <span class="content">Choosing the default behaviour</span></a>
      <li><a href="#examples"><span class="secno">6.6</span> <span class="content">Examples</span></a>
     </ol>
    <li><a href="#range_overloads"><span class="secno">7</span> <span class="content">Overloads for different range specifications</span></a>
    <li><a href="#contiguous_source_or_not"><span class="secno">8</span> <span class="content">Contiguous or non-contiguous sources</span></a>
    <li><a href="#simd_mask_ranges"><span class="secno">9</span> <span class="content">Range operations for <code class="highlight"><c- n>simd_mask</c-></code></span></a>
    <li>
     <a href="#function_type_choice"><span class="secno">10</span> <span class="content">Constructor, member function or free function</span></a>
     <ol class="toc">
      <li><a href="#range_to"><span class="secno">10.1</span> <span class="content">Design alternative replacing <code class="highlight"><c- n>load_from</c-></code> by <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code></span></a>
      <li><a href="#combine_load_gather_store_scatter"><span class="secno">10.2</span> <span class="content">Design alternative combining load and gather / store and scatter</span></a>
     </ol>
    <li><a href="#data_parallel_execution_policy"><span class="secno">11</span> <span class="content">Data parallel execution policy</span></a>
    <li>
     <a href="#wording"><span class="secno">12</span> <span class="content">Wording</span></a>
     <ol class="toc">
      <li><a href="#wording_simd_flags"><span class="secno">12.1</span> <span class="content">Modify [<strong>simd.flags</strong>]</span></a>
      <li><a href="#word_simd_syn"><span class="secno">12.2</span> <span class="content">Modify [<strong>simd.synopsis</strong>]</span></a>
      <li><a href="#word_simd_overview"><span class="secno">12.3</span> <span class="content">Modify [<strong>simd.overview</strong>]</span></a>
      <li><a href="#word_simd_mask_overview"><span class="secno">12.4</span> <span class="content">Modify [<strong>simd.mask.overview</strong>]</span></a>
      <li><a href="#word_simd_ctor"><span class="secno">12.5</span> <span class="content">Modify [<strong>simd.ctor</strong>] <code class="highlight"><c- n>basic_simd</c-></code> constructors</span></a>
      <li><a href="#word_simd_from_range"><span class="secno">12.6</span> <span class="content">Add [<strong>simd.from_range</strong>] <code class="highlight"><c- n>basic_simd</c-></code> load from range</span></a>
      <li><a href="#wording_ctad"><span class="secno">12.7</span> <span class="content">Add [<strong>simd.overview</strong>]</span></a>
      <li><a href="#word_simd_ctad"><span class="secno">12.8</span> <span class="content">Add [<strong>simd.ctad</strong>] <code class="highlight"><c- n>basic_simd</c-></code> class template argument deduction</span></a>
     </ol>
    <li>
     <a href="#polls"><span class="secno">13</span> <span class="content">Polls</span></a>
     <ol class="toc">
      <li><a href="#poll_st_louis"><span class="secno">13.1</span> <span class="content">St Louis 2024</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <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>R1 => R2</p>
   <ul>
    <li data-md>
     <p>Added poll from St Louis '24 meeting.</p>
    <li data-md>
     <p>Added wording</p>
    <li data-md>
     <p>Added note on <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges_to</c-></code>.</p>
    <li data-md>
     <p>Added numerous extra notes, clarifications and examples.</p>
   </ul>
   <p>R0 => R1</p>
   <ul>
    <li data-md>
     <p>Added description of erroneous behaviour</p>
    <li data-md>
     <p>Added examples</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="intro"><span class="secno">2. </span><span class="content">Motivation</span><a class="self-link" href="#intro"></a></h2>
   <p>The <span>[P1928R12]</span> proposal outlines a number of constructors and accessors which
can be used to move blocks of memory data in and out of a <code class="highlight"><c- n>simd</c-></code> object, and
these are supplemented in <a data-link-type="biblio" href="#biblio-p2664r6" title="Proposal to extend std::simd with permutation API">[P2664R6]</a> with functions for permuting data to and
from memory. However, these functions are potentially unsafe since they rely on
representing memory regions using only an iterator to the start of the memory
region, and relying on the <code class="highlight"><c- n>simd</c-></code> objects own size to determine the extent. In <a data-link-type="biblio" href="#biblio-p3024r0" title="Interface Directions for std::simd">[P3024R0]</a> it was suggested that <code class="highlight"><c- n>simd</c-></code> should include memory safe operations
and LEWG asked for an exploration of what such features might look like, what
their cost would be, and what trade-offs might have to be made. This paper
 discusses that exploration.</p>
   <p>This paper primarily discusses moving data from memory into a <code class="highlight"><c- n>simd</c-></code> using a
constructor which accepts a range. Exploration of this problem covers all of the
main issues that might arise in safe interactions between memory and a <code class="highlight"><c- n>simd</c-></code> value. Once a direction has been set we will extend this paper to cover the
movement of data from a <code class="highlight"><c- n>simd</c-></code> back into memory.</p>
   <h2 class="heading settled" data-level="3" id="memory_accessor_ctors"><span class="secno">3. </span><span class="content">Existing functions for memory accesses</span><a class="self-link" href="#memory_accessor_ctors"></a></h2>
   <p>Being able to load the contents of a region of memory into a <code class="highlight"><c- n>simd</c-></code> is common
practice, and essential for many types of algorithm which are written in a
data-parallel style. However, <span>[1928R8]</span> may have some issues related to memory
safety, and in this section we discuss some of the options to avoid or mitigate
these issues.</p>
   <p>There are two constructors which allow a memory load, and two related member functions:</p>
<pre class="highlight"><c- n>simd</c-><c- o>::</c-><c- n>simd</c-><c- p>(</c-><c- n>contiguous_iterator</c-><c- p>,</c-> <c- n>flags</c-><c- p>)</c->

<c- n>simd</c-><c- o>::</c-><c- n>simd</c-><c- p>(</c-><c- n>contiguous_iterator</c-><c- p>,</c-> <c- n>mask</c-><c- p>,</c-> <c- n>flags</c-><c- p>)</c->

<c- n>simd</c-><c- o>::</c-><c- n>copy_from</c-><c- p>(</c-><c- n>contiguous_iterator</c-><c- p>,</c-> <c- n>flags</c-><c- p>)</c->

<c- n>simd</c-><c- o>::</c-><c- n>copy_from</c-><c- p>(</c-><c- n>contiguous_iterator</c-><c- p>,</c-> <c- n>mask</c-><c- p>,</c-> <c- n>flags</c-><c- p>)</c-></pre>
   <p>We will only discuss the unmasked constructor in this proposal since the other
forms can be readily derived from it. There is one exception which we note in
its own section below.</p>
   <p>The issue with these memory load constructors and members is that they lack
memory safety. They will attempt to load a block of memory into a <code class="highlight"><c- n>simd</c-></code> value
without checking the legality of reading from that memory region, potentially
allowing access to data which it should not be able to use, or generating a
hardware exception (e.g,. page fault). In this section we shall discuss possible
ways to improve this behaviour, along with the costs in doing so.</p>
   <p>The constructors are not the only place in <code class="highlight"><c- n>simd</c-></code> which needs to take care of
memory safety. The <code class="highlight"><c- n>gather_from</c-></code> and <code class="highlight"><c- n>scatter_to</c-></code> functions described in <a data-link-type="biblio" href="#biblio-p2664r6" title="Proposal to extend std::simd with permutation API">[P2664R6]</a> also suffered from similar access issues, but they have been updated
to avoid these issues by replacing single iterators with ranges, and using
runtime-checks. However, gather and scatter instructions are relatively rare
compared to normal loads, and are expensive instructions anyway, so the cost of
adding runtime checks to them has negligible cost. In contrast, a plain memory
load is a work-horse instruction, frequently used, and much more sensitive to
the imposition of the costs of runtime checks, so we have to be more careful in
what we propose for them.</p>
   <h2 class="heading settled" data-level="4" id="general_access_guidelines"><span class="secno">4. </span><span class="content">Generic guidelines for safe memory accesses</span><a class="self-link" href="#general_access_guidelines"></a></h2>
   <p>There is one glaring problem with the basic memory access as it is currently
defined in <code class="highlight"><c- n>simd</c-></code>, which is that it provides only an iterator to the start of
the source:</p>
<pre class="highlight"><c- k>template</c-><c- o>&amp;</c-><c- n>lt</c-><c- p>;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c-></pre>
   <p>The absence of information about the extent of the memory source makes it
impossible for the implementation to (optionally) check its preconditions.
Fundamentally, the fix for this is to
provide information about the extent of the source which could be done in a few
different ways, such as:</p>
<pre class="highlight"><c- c1>// Use a pair of iterators to mark the limits</c->
<c- k>constexpr</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>It</c-> <c- n>begin</c-><c- p>,</c-> <c- n>It</c-> <c- n>end</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->

<c- c1>// Iterator and size</c->
<c- k>constexpr</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>It</c-> <c- n>begin</c-><c- p>,</c-> <c- n>size_type</c-> <c- n>count</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->

<c- c1>// Span with fixed size</c->
<c- k>constexpr</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>span</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>N</c-><c- o>></c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->

<c- c1>// Range with dynamic size (possibly unbounded)</c->
<c- k>constexpr</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>Range</c-> <c- n>r</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c-></pre>
   <p>Once we have information about the extent of the memory region then we can add
either static compile-time checks, or dynamic run-time checks to use that
information to determine correctness and safety. We can then act on that
information in a number of ways including throwing an exception on error,
defaulting to some safe state, or even choosing to ignore the issue entirely
when the programmer knows it is safe to do so or prefers speed over safety.</p>
   <h2 class="heading settled" data-level="5" id="compile_time_extent"><span class="secno">5. </span><span class="content">Accessing a source of compile-time extent</span><a class="self-link" href="#compile_time_extent"></a></h2>
   <p>In the following examples the elements of the destination <code class="highlight"><c- n>simd</c-></code> will be filled
with the contents of a memory source with compile-time extent:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- mi>6</c-><c- o>></c-> <c- n>ad</c-><c- p>;</c->
<c- n>simd</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- mi>6</c-><c- o>></c-> <c- n>simdA</c-><c- p>(</c-><c- n>ad</c-><c- p>);</c->

<c- n>std</c-><c- o>::</c-><c- n>span</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>8</c-><c- o>></c-> <c- n>sd</c-><c- p>(</c-><c- n>d</c-><c- p>.</c-><c- n>begin</c-><c- p>(),</c-> <c- mi>8</c-><c- p>);</c->
<c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>8</c-><c- o>></c-> <c- n>simdB</c-><c- p>(</c-><c- n>sd</c-><c- p>);</c-></pre>
   <p>This is the ideal scenario; we have the maximum amount of information possible
about the data being moved, and since it is known at compile-time we can enforce
whatever our desired behaviour is. In our proposal we think that under these
conditions all data from the source should be copied into the destination. There
should be no silent loss of data through truncation, nor should there be silent
addition of new values. If the programmer desires either of those behaviour they
should make that explicit:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- mi>6</c-><c- o>></c-> <c- n>ad</c-><c- p>;</c->
<c- n>simd</c-><c- o>&lt;</c-><c- b>float</c-> <c- mi>8</c-><c- o>></c-> <c- n>simdA</c-><c- p>(</c-><c- n>ad</c-><c- p>);</c-> <c- c1>// No! There is a mismatch in size causing extra data to be added.</c->

<c- c1>// Alternative making the resize explicit.</c->
<c- n>simd</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- mi>6</c-><c- o>></c-> <c- n>simdA</c-><c- p>(</c-><c- n>ad</c-><c- p>);</c->
<c- k>auto</c-> <c- n>simdA8</c-> <c- o>=</c-> <c- n>resize</c-><c- o>&lt;</c-><c- mi>8</c-><c- o>></c-><c- p>(</c-><c- n>simdA</c-><c- p>);</c-></pre>
   <p>Our intention would be to allow construction from anything which has
compile-time extent including C-array, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>span</c-></code>, and so on. We
will either spell these out in the wording, or find a way to generically
construct from anything which has compile-time constant size found using <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>extent_v</c-></code>, <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>tuple_size_v</c-></code>, and so on. Example implementation:</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- k>typename</c-> <c- nc>Rg</c-><c- o>></c->
  <c- k>constexpr</c-> <c- kr>inline</c-> <c- b>size_t</c->
  <c- n>static_range_size</c-> <c- o>=</c-> <c- p>[]</c-> <c- o>-></c-> <c- b>size_t</c-> <c- p>{</c->
    <c- k>using</c-> <c- n>T</c-> <c- o>=</c-> <c- n>remove_cvref_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>;</c->
    <c- k>if</c-> <c- k>constexpr</c-> <c- p>(</c-><c- k>requires</c-> <c- p>{</c-> <c- k>typename</c-> <c- nc>integral_constant</c-><c- o>&lt;</c-><c- b>size_t</c-><c- p>,</c-> <c- n>T</c-><c- o>::</c-><c- n>size</c-><c- p>()</c-><c- o>></c-><c- p>;</c-> <c- p>})</c->
      <c- k>return</c-> <c- n>T</c-><c- o>::</c-><c- n>size</c-><c- p>();</c->
    <c- k>else</c-> <c- k>if</c-> <c- k>constexpr</c-> <c- p>(</c-><c- k>requires</c-> <c- p>{</c-> <c- k>typename</c-> <c- nc>integral_constant</c-><c- o>&lt;</c-><c- b>size_t</c-><c- p>,</c-> <c- n>T</c-><c- o>::</c-><c- n>extent</c-><c- o>></c-><c- p>;</c-> <c- p>})</c->
      <c- k>return</c-> <c- n>T</c-><c- o>::</c-><c- n>extent</c-><c- p>;</c->
    <c- k>else</c-> <c- k>if</c-> <c- k>constexpr</c-> <c- p>(</c-><c- n>extent_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- o>></c-> <c- mi>0</c-><c- p>)</c->
      <c- k>return</c-> <c- n>extent_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>;</c->
    <c- k>else</c-> <c- k>if</c-> <c- k>constexpr</c-> <c- p>(</c-><c- k>requires</c-> <c- p>{</c->
                         <c- k>typename</c-> <c- nc>integral_constant</c-><c- o>&lt;</c-><c- b>size_t</c-><c- p>,</c-> <c- n>tuple_size</c-><c- o>&lt;</c-><c- n>T</c-><c- o>>::</c-><c- n>value</c-><c- o>></c-><c- p>;</c->
                         <c- k>typename</c-> <c- nc>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>;</c->
                       <c- p>})</c->
      <c- p>{</c->
        <c- k>if</c-> <c- k>constexpr</c-> <c- p>(</c-><c- n>tuple_size_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-> <c- o>>=</c-> <c- mi>1</c->
                        <c- o>&amp;&amp;</c-> <c- n>same_as</c-><c- o>&lt;</c-><c- n>tuple_element_t</c-><c- o>&lt;</c-><c- mi>0</c-><c- p>,</c-> <c- n>T</c-><c- o>></c-><c- p>,</c->
                                        <c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>>></c-><c- p>)</c->
          <c- k>return</c-> <c- n>tuple_size_v</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>;</c->
      <c- p>}</c->
    <c- k>return</c-> <c- n>dynamic_extent</c-><c- p>;</c->
  <c- p>}();</c-></pre>
   <p>We propose that the span constructor is explicit. Our basis for this is to note
that <a data-link-type="biblio" href="#biblio-p3116r0" title="Policy for explicit">[P3116R0]</a> recommends that implicit conversions should only be provided if
the types are fundamentally the same. A <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>span</c-></code> and a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>simd</c-></code> may share
similarities in storage (both contain a set of element values), but a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>simd</c-></code> also allows an extensive range of parallel operations. It isn’t clear cut
whether the types are fundamentally the same and so we prefer to be conservative
and require the constructor to be explicit. This decision can be revisited if
compelling cases are found to make this conversion implicit.</p>
   <p>Finally, we can provide deduction guides too, since we know what the size of the
output <code class="highlight"><c- n>simd</c-></code> should be:</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- n>contiguous</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>with</c-><c- o>-</c-><c- k>static</c-><c- o>-</c-><c- n>extent</c-> <c- n>Rg</c-><c- o>></c->
<c- n>basic_simd</c-><c- p>(</c-><c- n>Rg</c-><c- o>&amp;&amp;</c-><c- p>)</c->
  <c- o>-></c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c->
                <c- n>deduce</c-><c- o>-</c-><c- n>t</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c-> <c- k>static</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>size</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>>>></c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- n>contiguous</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>with</c-><c- o>-</c-><c- k>static</c-><c- o>-</c-><c- n>extent</c-> <c- n>Rg</c-><c- p>,</c-> <c- k>typename</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- n>basic_simd</c-><c- p>(</c-><c- n>Rg</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-><c- p>)</c->
  <c- o>-></c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c->
                <c- n>deduce</c-><c- o>-</c-><c- n>t</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c-> <c- k>static</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>size</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>>>></c-><c- p>;</c-></pre>
   <p>Recall that we cannot define the necessary deduction guides for the <code class="highlight"><c- n>simd</c-></code> alias template. Thus, users that want to use CTAD need to use <code class="highlight"><c- n>basic_simd</c-></code>:</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- mi>4</c-><c- o>></c-> <c- n>data</c-><c- p>;</c->
<c- n>std</c-><c- o>::</c-><c- n>simd</c-> <c- n>v</c-> <c- o>=</c-> <c- n>data</c-><c- p>;</c-> <c- c1>// compiles only if simd&lt;float>::size() happens to be 4</c->
<c- n>std</c-><c- o>::</c-><c- n>basic_simd</c-> <c- n>w</c-> <c- o>=</c-> <c- n>data</c-><c- p>;</c-> <c- c1>// deduces Abi correctly</c-></pre>
   <h2 class="heading settled" data-level="6" id="dynamic_extent"><span class="secno">6. </span><span class="content">Accessing a source of bounded but unknown extent</span><a class="self-link" href="#dynamic_extent"></a></h2>
   <p>When the source has an unknown extent there may be a mismatch between the size
of the <code class="highlight"><c- n>simd</c-></code> and the source’s size. We could handle this in one of three ways,
from least expensive to most expensive:</p>
   <ol>
    <li data-md>
     <p>Make this undefined behaviour</p>
    <li data-md>
     <p>Make this defined behaviour which is gracefully handled</p>
    <li data-md>
     <p>Make this erroneous behaviour</p>
    <li data-md>
     <p>Make this an exception</p>
   </ol>
   <p>We look at each of these in turn. We also look at which of these should be the default behaviour.</p>
   <h3 class="heading settled" data-level="6.1" id="undefined_behaviour"><span class="secno">6.1. </span><span class="content">Undefined behaviour</span><a class="self-link" href="#undefined_behaviour"></a></h3>
   <p>This option is equivalent to leaving the status quo of <span>[P1928R12]</span> unchanged,
and putting the onus entirely on the user to check that the range is valid. If
the source range is too small, the load will go beyond the end of the valid
data. If the source range is too big, the data will be truncated to the size of
the <code class="highlight"><c- n>simd</c-></code>.</p>
   <p>Even if the range is not used explicitly for bounds checking, the extra
information could still be used in debug modes by the compiler to help aid
correctness checking, or by static analysis tools, or by mechanisms for contract
checking.</p>
   <h3 class="heading settled" data-level="6.2" id="defined_behaviour"><span class="secno">6.2. </span><span class="content">Defined behaviour</span><a class="self-link" href="#defined_behaviour"></a></h3>
   <p>With this option the behaviour of the <code class="highlight"><c- n>simd</c-></code> load will always generate valid
data and will always ensure that out-of-bounds reads (or writes for stores)
cannot occur.</p>
   <p>When the <code class="highlight"><c- n>simd</c-></code> is too small to hold all the data in the source range, the data
will be truncated to what can fit in the <code class="highlight"><c- n>simd</c-></code> itself.</p>
   <p>When the <code class="highlight"><c- n>simd</c-></code> is bigger than the source range then the extra elements are
filled with value initialized data. The memory beyond the end of the smaller
source range will not be accessed. This particular behaviour is useful for
handling loop remainders/epilogues.</p>
   <p>The major costs of this option are the extra instructions to implement the
runtime check, and the need to do a partial copy from memory into the simd
register. The latter of these might be particular expensive if, for example, the
target has to do element-by-element copy from memory to satisfy the need to
avoid touching the memory entirely. Also, the introduction of a checked load
could introduce a branch into critical load routines where we really don’t want
branches. Even on modern Intel machines which have masked memory operations, the cost of
setting up and acting on the mask for every call is still something we’d prefer to avoid.</p>
   <p>We could explicitly opt-in to this behaviour by passing in <code class="highlight"><c- n>simd_flag_partial_loadstore</c-></code> as a flag.</p>
   <h3 class="heading settled" data-level="6.3" id="erroneous_behaviour"><span class="secno">6.3. </span><span class="content">Erroneous behaviour</span><a class="self-link" href="#erroneous_behaviour"></a></h3>
   <p>With a minor change in implementation, compared to "defined behaviour" above,
the implementation could also support EB on out-of-bounds access. The runtime
cost of checking the range size and copying only the valid elements is exactly
the same. The only difference is that the default-initialized simd elements must
exhibit EB on usage.</p>
   <p>The default-initialization feature above is a valid use-case for implementing a
remainder step after a loop over a larger range. So we certainly don’t want to
unconditionally make default-initialized elements EB. Instead, EB is a
replacement for UB, where the runtime cost is acceptable compared to the cost of
an out-of-bounds access.</p>
   <h3 class="heading settled" data-level="6.4" id="exception_behaviour"><span class="secno">6.4. </span><span class="content">Exception</span><a class="self-link" href="#exception_behaviour"></a></h3>
   <p>The final and most expensive option is to require the source range and the <code class="highlight"><c- n>simd</c-></code> size to be identical. A runtime check is inserted into the load to check
the extents match, and an exception thrown when they don’t. This is expensive
because of the runtime check, but also because the mechanics of exceptions often
disrupt optimized code.</p>
   <p>We could explicitly opt-in to this behaviour by passing in <code class="highlight"><c- n>simd_exception</c-></code> as a flag.</p>
   <h3 class="heading settled" data-level="6.5" id="choosing_default_load_behaviour"><span class="secno">6.5. </span><span class="content">Choosing the default behaviour</span><a class="self-link" href="#choosing_default_load_behaviour"></a></h3>
   <p>We have listed three options for what the behaviour of a load from an unknown
range should be. In each case we can define a suitable flag which opts in to
that behaviour: <code class="highlight"><c- n>simd_unchecked</c-></code>, <code class="highlight"><c- n>simd_flag_partial_loadstore</c-></code>, and <code class="highlight"><c- n>simd_exception</c-></code>. We
could require the user to always specify what behaviour they want, but this will
lead to verbose code. Ideally we should define what the default should be, and
realistically the choice is one of undefined behaviour, or defined
behaviour. Exceptional behaviour is really too expensive for what is considered
to be a performance library.</p>
   <p>If we chose to use defined behaviour as the default, where the data will be truncated or
default initialized depending upon the source size, then we get repeatable,
understandable and sane behaviour whatever the range of data we request. The big
downside is that every use of the function will incur a runtime cost to check
the bounds and to do something appropriate if a mismatch is found. This
introduces a potential performance bottleneck directly into one of the most
performance critical parts of <code class="highlight"><c- n>simd</c-></code>. We could accept this default if we found
that the compiler is able to keep the cost of the check as low as possible
(e.g., if it can statically analyse the code and remove any redundant checks),
but our experience so far is that the check is expensive (TBD: Qualify the expense).</p>
   <p>If we chose to use undefined behaviour then we avoid the need to insert a
run-time check and action in what is a low-level function with high performance
requirements. This most closely matches the status quo of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>simd</c-></code> as it is
currently defined. By providing the extra bounds information we allow the
compiler to do static checking of its own to detect issues, or allow it to emit
extra information to allow range checking in hardware, or through debug
facilities. We also get the best possible performance from the <code class="highlight"><c- n>simd</c-></code> library in
the common case.</p>
   <p>Given <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>simd</c-></code>’s primary use as a low-level performance library, we recommend
that the default should be undefined behaviour, with the user opting into one of
the other more expensive options. Higher level abstractions (such as the simd
execution policy discussed later) can use the extra knowledge they have about
context to improve on safety.</p>
   <h3 class="heading settled" data-level="6.6" id="examples"><span class="secno">6.6. </span><span class="content">Examples</span><a class="self-link" href="#examples"></a></h3>
   <p>All examples use the following alias <code class="highlight"><c- n>V</c-></code> and are compiled with <code class="highlight"><c- o>-</c-><c- n>march</c-><c- o>=</c-><c- n>skylake</c-></code> (32 byte wide SIMD). They implement the parallel part of a reduction over a 
larger <code class="highlight"><c- n>vector</c-></code>. The function <code class="highlight"><c- n>g</c-></code> would need to be a call to <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>reduce</c-><c- p>(</c-><c- n>simd</c-><c- p>)</c-></code> for a complete reduction. Since that would complicate an 
analysis we leave it at simply calling an anonymous function <code class="highlight"><c- n>g</c-></code>.</p>
<pre class="language-cpp highlight"><c- k>using</c-> <c- n>V</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>float</c-><c- o>></c-><c- p>;</c-></pre>
   <p>This first example incorrectly creates a <code class="highlight"><c- n>span</c-></code> of static extent at the end of
the loop, which, in general, goes beyond the size of the vector.</p>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>iter_ub1</c-><c- p>(</c-><c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>float</c-><c- o>>&amp;</c-> <c- n>x</c-><c- p>)</c->
<c- p>{</c->
  <c- n>V</c-> <c- n>acc</c-> <c- p>{};</c->
  <c- k>for</c-> <c- p>(</c-><c- k>auto</c-> <c- n>it</c-> <c- o>=</c-> <c- n>x</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c-> <c- n>it</c-> <c- o>&lt;</c-> <c- n>x</c-><c- p>.</c-><c- n>end</c-><c- p>();</c-> <c- n>it</c-> <c- o>+=</c-> <c- n>V</c-><c- o>::</c-><c- n>size</c-><c- p>)</c->
  <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>span</c-><c- o>&lt;</c-><c- k>const</c-> <c- b>float</c-><c- p>,</c-> <c- n>V</c-><c- o>::</c-><c- n>size</c-><c- p>()</c-><c- o>></c-> <c- n>chunk</c-><c- p>(</c-><c- n>it</c-><c- p>,</c-> <c- n>V</c-><c- o>::</c-><c- n>size</c-><c- p>());</c->
    <c- n>acc</c-> <c- o>+=</c-> <c- n>V</c-><c- p>(</c-><c- n>chunk</c-><c- p>);</c->
  <c- p>}</c->
  <c- n>g</c-><c- p>(</c-><c- n>acc</c-><c- p>);</c->
<c- p>}</c-></pre>
<pre class="language-asm highlight"><c- nf>iter_ub1</c-><c- p>(</c-><c- no>std</c-><c- p>::</c-><c- no>vector</c->&lt;<c- no>float</c-><c- p>,</c-> <c- no>std</c-><c- p>::</c-><c- no>allocator</c->&lt;<c- no>float</c->> > <c- no>const</c->&amp;<c- p>):</c->
  <c- nf>mov</c->  <c- no>rax</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c->+<c- mi>8</c-><c- p>]</c->
  <c- nf>vxorps</c->  <c- no>xmm0</c-><c- p>,</c-> <c- no>xmm0</c-><c- p>,</c-> <c- no>xmm0</c->
  <c- nf>cmp</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rdx</c->
  <c- nf>jnb</c->  <c- no>.L32</c->
<c- nl>.L33:</c->
  <c- nf>vaddps</c->  <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm0</c-><c- p>,</c-> <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax</c-><c- p>]</c->
  <c- nf>add</c->  <c- no>rax</c-><c- p>,</c-> <c- mi>32</c->
  <c- nf>cmp</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rdx</c->
  <c- nf>jb</c->  <c- no>.L33</c->
<c- nl>.L32:</c->
  <c- nf>jmp</c->  <c- no>void</c-> <c- no>g</c->&lt;<c- no>...</c->></pre>
   <p>So, if the user creates invalid <code class="highlight"><c- n>span</c-></code>s there’s nothing we can do in <code class="highlight"><c- n>simd</c-></code>. As
expected. But lets not create <code class="highlight"><c- n>span</c-></code>s anymore then. Instead we’re going to load 
from an iterator pair, but potentially calling load with a range size less than 8.</p>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>iter_ub2</c-><c- p>(</c-><c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>float</c-><c- o>>&amp;</c-> <c- n>x</c-><c- p>)</c->
<c- p>{</c->
  <c- n>V</c-> <c- n>acc</c-> <c- p>{};</c->
  <c- k>for</c-> <c- p>(</c-><c- k>auto</c-> <c- n>it</c-> <c- o>=</c-> <c- n>x</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c-> <c- n>it</c-> <c- o>&lt;</c-> <c- n>x</c-><c- p>.</c-><c- n>end</c-><c- p>();</c-> <c- n>it</c-> <c- o>+=</c-> <c- n>V</c-><c- o>::</c-><c- n>size</c-><c- p>)</c->
    <c- n>acc</c-> <c- o>+=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd_load</c-><c- p>(</c-><c- n>it</c-><c- p>,</c-> <c- n>x</c-><c- p>.</c-><c- n>end</c-><c- p>());</c->
  <c- n>g</c-><c- p>(</c-><c- n>acc</c-><c- p>);</c->
<c- p>}</c-></pre>
<pre class="language-asm highlight"><c- nf>iter_ub2</c-><c- p>(</c-><c- no>std</c-><c- p>::</c-><c- no>vector</c->&lt;<c- no>float</c-><c- p>,</c-> <c- no>std</c-><c- p>::</c-><c- no>allocator</c->&lt;<c- no>float</c->> > <c- no>const</c->&amp;<c- p>):</c->
  <c- nf>mov</c->  <c- no>rax</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c->+<c- mi>8</c-><c- p>]</c->
  <c- nf>vxorps</c->  <c- no>xmm0</c-><c- p>,</c-> <c- no>xmm0</c-><c- p>,</c-> <c- no>xmm0</c->
  <c- nf>cmp</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rdx</c->
  <c- nf>jnb</c->  <c- no>.L37</c->
<c- nl>.L38:</c->
  <c- nf>vaddps</c->  <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm0</c-><c- p>,</c-> <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax</c-><c- p>]</c->
  <c- nf>add</c->  <c- no>rax</c-><c- p>,</c-> <c- mi>32</c->
  <c- nf>cmp</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rdx</c->
  <c- nf>jb</c->  <c- no>.L38</c->
<c- nl>.L37:</c->
  <c- nf>jmp</c->  <c- no>void</c-> <c- no>g</c->&lt;<c- no>...</c->></pre>
   <p>Now a precondition check inside <code class="highlight"><c- n>simd_load</c-></code> can see the out-of-bounds access.
Contracts checking / debug builds / static analysis could easily catch this. 
But if the default behavior of <code class="highlight"><c- n>simd_load</c-></code> is UB, then this is still an invalid 
program. So, then what happens if we change <code class="highlight"><c- n>simd_load</c-></code> to partial-loadstore when
the range is too small?</p>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>iter_zero</c-><c- p>(</c-><c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>float</c-><c- o>>&amp;</c-> <c- n>x</c-><c- p>)</c->
<c- p>{</c->
  <c- n>V</c-> <c- n>acc</c-> <c- p>{};</c->
  <c- k>for</c-> <c- p>(</c-><c- k>auto</c-> <c- n>it</c-> <c- o>=</c-> <c- n>x</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c-> <c- n>it</c-> <c- o>&lt;</c-> <c- n>x</c-><c- p>.</c-><c- n>end</c-><c- p>();</c-> <c- n>it</c-> <c- o>+=</c-> <c- n>V</c-><c- o>::</c-><c- n>size</c-><c- p>)</c->
    <c- n>acc</c-> <c- o>+=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd_load</c-><c- p>(</c-><c- n>it</c-><c- p>,</c-> <c- n>x</c-><c- p>.</c-><c- n>end</c-><c- p>(),</c-> <c- n>std</c-><c- o>::</c-><c- n>simd_flag_partial_loadstore</c-><c- p>);</c->
  <c- n>g</c-><c- p>(</c-><c- n>acc</c-><c- p>);</c->
<c- p>}</c-></pre>
<pre class="language-asm highlight"><c- nf>iter_zero</c-><c- p>(</c-><c- no>std</c-><c- p>::</c-><c- no>vector</c->&lt;<c- no>float</c-><c- p>,</c-> <c- no>std</c-><c- p>::</c-><c- no>allocator</c->&lt;<c- no>float</c->> > <c- no>const</c->&amp;<c- p>):</c->
  <c- nf>mov</c->  <c- no>rax</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>rcx</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c->+<c- mi>8</c-><c- p>]</c->
  <c- nf>vxorps</c->  <c- no>xmm0</c-><c- p>,</c-> <c- no>xmm0</c-><c- p>,</c-> <c- no>xmm0</c->
  <c- nf>cmp</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>jnb</c->  <c- no>.L68</c->
  <c- nf>vmovaps</c->  <c- no>ymm2</c-><c- p>,</c-> <c- no>ymm0</c->
  <c- nf>mov</c->  <c- no>r10d</c-><c- p>,</c-> <c- mi>8</c->
<c- nl>.L65:</c->
  <c- nf>mov</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>sub</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rax</c->
  <c- nf>cmp</c->  <c- no>rdx</c-><c- p>,</c-> <c- mi>28</c->
  <c- nf>jle</c->  <c- no>.L69</c->
  <c- nf>vmovups</c->  <c- no>ymm1</c-><c- p>,</c-> <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax</c-><c- p>]</c->
  <c- nf>add</c->  <c- no>rax</c-><c- p>,</c-> <c- mi>32</c->
  <c- nf>vaddps</c->  <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm1</c->
  <c- nf>cmp</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>jb</c->  <c- no>.L65</c->
<c- nl>.L68:</c->
  <c- nf>jmp</c->  <c- no>void</c-> <c- no>g</c->&lt;<c- no>...</c->>
<c- nl>.L69:</c->
  <c- nf>push</c->  <c- no>r13</c->
  <c- nf>lea</c->  <c- no>r13</c-><c- p>,</c-> <c- p>[</c-><c- no>rsp</c->+<c- mi>16</c-><c- p>]</c->
  <c- nf>and</c->  <c- no>rsp</c-><c- p>,</c-> <c- mi>-32</c->
  <c- nf>push</c->  <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>r13-8</c-><c- p>]</c->
  <c- nf>push</c->  <c- no>rbp</c->
  <c- nf>mov</c->  <c- no>rbp</c-><c- p>,</c-> <c- no>rsp</c->
  <c- nf>push</c->  <c- no>r13</c->
<c- nl>.L43:</c->
  <c- nf>sar</c->  <c- no>rdx</c-><c- p>,</c-> <c- mi>2</c->
  <c- nf>mov</c->  <c- no>rsi</c-><c- p>,</c-> <c- no>r10</c->
  <c- nf>vmovaps</c->  <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rbp-48</c-><c- p>],</c-> <c- no>ymm2</c->
  <c- nf>lea</c->  <c- no>r8</c-><c- p>,</c-> <c- p>[</c-><c- no>rbp-48</c-><c- p>]</c->
  <c- nf>sub</c->  <c- no>rsi</c-><c- p>,</c-> <c- no>rdx</c->
  <c- nf>mov</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rax</c->
  <c- nf>cmp</c->  <c- no>esi</c-><c- p>,</c-> <c- mi>8</c->
  <c- nf>jnb</c->  <c- no>.L70</c->
<c- nl>.L45:</c->
  <c- nf>xor</c->  <c- no>edi</c-><c- p>,</c-> <c- no>edi</c->
  <c- nf>test</c->  <c- no>sil</c-><c- p>,</c-> <c- mi>4</c->
  <c- nf>je</c->  <c- no>.L48</c->
  <c- nf>mov</c->  <c- no>edi</c-><c- p>,</c-> <c- no>DWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdx</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>DWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>r8</c-><c- p>],</c-> <c- no>edi</c->
  <c- nf>mov</c->  <c- no>edi</c-><c- p>,</c-> <c- mi>4</c->
<c- nl>.L48:</c->
  <c- nf>test</c->  <c- no>sil</c-><c- p>,</c-> <c- mi>2</c->
  <c- nf>je</c->  <c- no>.L49</c->
  <c- nf>movzx</c->  <c- no>r9d</c-><c- p>,</c-> <c- no>WORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdx</c->+<c- no>rdi</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>WORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>r8</c->+<c- no>rdi</c-><c- p>],</c-> <c- no>r9w</c->
  <c- nf>add</c->  <c- no>rdi</c-><c- p>,</c-> <c- mi>2</c->
<c- nl>.L49:</c->
  <c- nf>and</c->  <c- no>esi</c-><c- p>,</c-> <c- mi>1</c->
  <c- nf>je</c->  <c- no>.L50</c->
  <c- nf>movzx</c->  <c- no>edx</c-><c- p>,</c-> <c- no>BYTE</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdx</c->+<c- no>rdi</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>BYTE</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>r8</c->+<c- no>rdi</c-><c- p>],</c-> <c- no>dl</c->
<c- nl>.L50:</c->
  <c- nf>vmovaps</c->  <c- no>ymm1</c-><c- p>,</c-> <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rbp-48</c-><c- p>]</c->
  <c- nf>add</c->  <c- no>rax</c-><c- p>,</c-> <c- mi>32</c->
  <c- nf>vaddps</c->  <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm1</c->
  <c- nf>cmp</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>jnb</c->  <c- no>.L71</c->
<c- nl>.L51:</c->
  <c- nf>mov</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>sub</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rax</c->
  <c- nf>cmp</c->  <c- no>rdx</c-><c- p>,</c-> <c- mi>28</c->
  <c- nf>jle</c->  <c- no>.L43</c->
  <c- nf>vmovups</c->  <c- no>ymm1</c-><c- p>,</c-> <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax</c-><c- p>]</c->
  <c- nf>add</c->  <c- no>rax</c-><c- p>,</c-> <c- mi>32</c->
  <c- nf>vaddps</c->  <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm1</c->
  <c- nf>cmp</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>jb</c->  <c- no>.L51</c->
<c- nl>.L71:</c->
  <c- nf>mov</c->  <c- no>r13</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rbp-8</c-><c- p>]</c->
  <c- nf>leave</c->
  <c- nf>lea</c->  <c- no>rsp</c-><c- p>,</c-> <c- p>[</c-><c- no>r13-16</c-><c- p>]</c->
  <c- nf>pop</c->  <c- no>r13</c->
  <c- nf>jmp</c->  <c- no>void</c-> <c- no>g</c->&lt;<c- no>...</c->>
<c- nl>.L70:</c->
  <c- nf>mov</c->  <c- no>r9d</c-><c- p>,</c-> <c- no>esi</c->
  <c- nf>xor</c->  <c- no>edx</c-><c- p>,</c-> <c- no>edx</c->
  <c- nf>and</c->  <c- no>r9d</c-><c- p>,</c-> <c- mi>-8</c->
<c- nl>.L46:</c->
  <c- nf>mov</c->  <c- no>edi</c-><c- p>,</c-> <c- no>edx</c->
  <c- nf>add</c->  <c- no>edx</c-><c- p>,</c-> <c- mi>8</c->
  <c- nf>mov</c->  <c- no>r8</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax</c->+<c- no>rdi</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rbp-48</c->+<c- no>rdi</c-><c- p>],</c-> <c- no>r8</c->
  <c- nf>cmp</c->  <c- no>edx</c-><c- p>,</c-> <c- no>r9d</c->
  <c- nf>jb</c->  <c- no>.L46</c->
  <c- nf>lea</c->  <c- no>rdi</c-><c- p>,</c-> <c- p>[</c-><c- no>rbp-48</c-><c- p>]</c->
  <c- nf>lea</c->  <c- no>r8</c-><c- p>,</c-> <c- p>[</c-><c- no>rdi</c->+<c- no>rdx</c-><c- p>]</c->
  <c- nf>add</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rax</c->
  <c- nf>jmp</c->  <c- no>.L45</c-></pre>
   <p>The program is correct now. But it’s not as efficient as it should be. There’s
no way around using UB loads inside the loop. We just need to end the loop 
earlier and then handle the remainder. For the remainder we can make good use 
of the <code class="highlight"><c- n>simd_flag_partial_loadstore</c-></code> behavior.</p>
<pre class="language-cpp highlight"><c- b>void</c-> <c- nf>iter_zero_efficient</c-><c- p>(</c-><c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>float</c-><c- o>>&amp;</c-> <c- n>x</c-><c- p>)</c->
<c- p>{</c->
  <c- n>V</c-> <c- n>acc</c-> <c- p>{};</c->
  <c- k>auto</c-> <c- n>it</c-> <c- o>=</c-> <c- n>x</c-><c- p>.</c-><c- n>begin</c-><c- p>();</c->
  <c- k>for</c-> <c- p>(;</c-> <c- n>it</c-> <c- o>+</c-> <c- n>V</c-><c- o>::</c-><c- n>size</c-><c- p>()</c-> <c- o>&lt;=</c-> <c- n>x</c-><c- p>.</c-><c- n>end</c-><c- p>();</c-> <c- n>it</c-> <c- o>+=</c-> <c- n>V</c-><c- o>::</c-><c- n>size</c-><c- p>)</c->
    <c- n>acc</c-> <c- o>+=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd_load</c-><c- p>(</c-><c- n>it</c-><c- p>,</c-> <c- n>x</c-><c- p>.</c-><c- n>end</c-><c- p>());</c->
  <c- n>acc</c-> <c- o>+=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd_load</c-><c- p>(</c-><c- n>it</c-><c- p>,</c-> <c- n>x</c-><c- p>.</c-><c- n>end</c-><c- p>(),</c-> <c- n>std</c-><c- o>::</c-><c- n>simd_flag_partial_loadstore</c-><c- p>);</c->
  <c- n>g</c-><c- p>(</c-><c- n>acc</c-><c- p>);</c->
<c- p>}</c-></pre>
<pre class="language-asm highlight"><c- nf>iter_zero_efficient</c-><c- p>(</c-><c- no>std</c-><c- p>::</c-><c- no>vector</c->&lt;<c- no>float</c-><c- p>,</c-> <c- no>std</c-><c- p>::</c-><c- no>allocator</c->&lt;<c- no>float</c->> > <c- no>const</c->&amp;<c- p>):</c->
  <c- nf>mov</c->  <c- no>rcx</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c->+<c- mi>8</c-><c- p>]</c->
  <c- nf>vxorps</c->  <c- no>xmm0</c-><c- p>,</c-> <c- no>xmm0</c-><c- p>,</c-> <c- no>xmm0</c->
  <c- nf>lea</c->  <c- no>rax</c-><c- p>,</c-> <c- p>[</c-><c- no>rcx</c->+<c- mi>32</c-><c- p>]</c->
  <c- nf>cmp</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rax</c->
  <c- nf>jb</c->  <c- no>.L109</c->
<c- nl>.L110:</c->
  <c- nf>vaddps</c->  <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm0</c-><c- p>,</c-> <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax-32</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>rcx</c-><c- p>,</c-> <c- no>rax</c->
  <c- nf>add</c->  <c- no>rax</c-><c- p>,</c-> <c- mi>32</c->
  <c- nf>cmp</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rax</c->
  <c- nf>jnb</c->  <c- no>.L110</c->
<c- nl>.L109:</c->
  <c- nf>sub</c->  <c- no>rdx</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>cmp</c->  <c- no>rdx</c-><c- p>,</c-> <c- mi>28</c->
  <c- nf>jbe</c->  <c- no>.L111</c->
  <c- nf>vmovups</c->  <c- no>ymm1</c-><c- p>,</c-> <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rcx</c-><c- p>]</c->
  <c- nf>vaddps</c->  <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm1</c->
  <c- nf>jmp</c->  <c- no>void</c-> <c- no>g</c->&lt;<c- no>...</c->>
<c- nl>.L111:</c->
  <c- nf>push</c->  <c- no>r13</c->
  <c- nf>sar</c->  <c- no>rdx</c-><c- p>,</c-> <c- mi>2</c->
  <c- nf>mov</c->  <c- no>esi</c-><c- p>,</c-> <c- mi>8</c->
  <c- nf>vxorps</c->  <c- no>xmm1</c-><c- p>,</c-> <c- no>xmm1</c-><c- p>,</c-> <c- no>xmm1</c->
  <c- nf>sub</c->  <c- no>rsi</c-><c- p>,</c-> <c- no>rdx</c->
  <c- nf>mov</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>lea</c->  <c- no>r13</c-><c- p>,</c-> <c- p>[</c-><c- no>rsp</c->+<c- mi>16</c-><c- p>]</c->
  <c- nf>and</c->  <c- no>rsp</c-><c- p>,</c-> <c- mi>-32</c->
  <c- nf>push</c->  <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>r13-8</c-><c- p>]</c->
  <c- nf>push</c->  <c- no>rbp</c->
  <c- nf>mov</c->  <c- no>rbp</c-><c- p>,</c-> <c- no>rsp</c->
  <c- nf>push</c->  <c- no>r13</c->
  <c- nf>lea</c->  <c- no>rdi</c-><c- p>,</c-> <c- p>[</c-><c- no>rbp-48</c-><c- p>]</c->
  <c- nf>vmovaps</c->  <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rbp-48</c-><c- p>],</c-> <c- no>ymm1</c->
  <c- nf>cmp</c->  <c- no>esi</c-><c- p>,</c-> <c- mi>8</c->
  <c- nf>jnb</c->  <c- no>.L134</c->
<c- nl>.L113:</c->
  <c- nf>xor</c->  <c- no>edx</c-><c- p>,</c-> <c- no>edx</c->
  <c- nf>test</c->  <c- no>sil</c-><c- p>,</c-> <c- mi>4</c->
  <c- nf>jne</c->  <c- no>.L135</c->
  <c- nf>test</c->  <c- no>sil</c-><c- p>,</c-> <c- mi>2</c->
  <c- nf>jne</c->  <c- no>.L136</c->
<c- nl>.L117:</c->
  <c- nf>and</c->  <c- no>esi</c-><c- p>,</c-> <c- mi>1</c->
  <c- nf>jne</c->  <c- no>.L137</c->
<c- nl>.L118:</c->
  <c- nf>vmovaps</c->  <c- no>ymm1</c-><c- p>,</c-> <c- no>YMMWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rbp-48</c-><c- p>]</c->
  <c- nf>vaddps</c->  <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm0</c-><c- p>,</c-> <c- no>ymm1</c->
  <c- nf>mov</c->  <c- no>r13</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rbp-8</c-><c- p>]</c->
  <c- nf>leave</c->
  <c- nf>lea</c->  <c- no>rsp</c-><c- p>,</c-> <c- p>[</c-><c- no>r13-16</c-><c- p>]</c->
  <c- nf>pop</c->  <c- no>r13</c->
  <c- nf>jmp</c->  <c- no>void</c-> <c- no>g</c->&lt;<c- no>...</c->>
<c- nl>.L137:</c->
  <c- nf>movzx</c->  <c- no>eax</c-><c- p>,</c-> <c- no>BYTE</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax</c->+<c- no>rdx</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>BYTE</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c->+<c- no>rdx</c-><c- p>],</c-> <c- no>al</c->
  <c- nf>jmp</c->  <c- no>.L118</c->
<c- nl>.L136:</c->
  <c- nf>movzx</c->  <c- no>ecx</c-><c- p>,</c-> <c- no>WORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax</c->+<c- no>rdx</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>WORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c->+<c- no>rdx</c-><c- p>],</c-> <c- no>cx</c->
  <c- nf>add</c->  <c- no>rdx</c-><c- p>,</c-> <c- mi>2</c->
  <c- nf>and</c->  <c- no>esi</c-><c- p>,</c-> <c- mi>1</c->
  <c- nf>je</c->  <c- no>.L118</c->
  <c- nf>jmp</c->  <c- no>.L137</c->
<c- nl>.L135:</c->
  <c- nf>mov</c->  <c- no>edx</c-><c- p>,</c-> <c- no>DWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rax</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>DWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rdi</c-><c- p>],</c-> <c- no>edx</c->
  <c- nf>mov</c->  <c- no>edx</c-><c- p>,</c-> <c- mi>4</c->
  <c- nf>test</c->  <c- no>sil</c-><c- p>,</c-> <c- mi>2</c->
  <c- nf>je</c->  <c- no>.L117</c->
  <c- nf>jmp</c->  <c- no>.L136</c->
<c- nl>.L134:</c->
  <c- nf>mov</c->  <c- no>r8d</c-><c- p>,</c-> <c- no>esi</c->
  <c- nf>xor</c->  <c- no>eax</c-><c- p>,</c-> <c- no>eax</c->
  <c- nf>and</c->  <c- no>r8d</c-><c- p>,</c-> <c- mi>-8</c->
<c- nl>.L114:</c->
  <c- nf>mov</c->  <c- no>edx</c-><c- p>,</c-> <c- no>eax</c->
  <c- nf>add</c->  <c- no>eax</c-><c- p>,</c-> <c- mi>8</c->
  <c- nf>mov</c->  <c- no>rdi</c-><c- p>,</c-> <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rcx</c->+<c- no>rdx</c-><c- p>]</c->
  <c- nf>mov</c->  <c- no>QWORD</c-> <c- no>PTR</c-> <c- p>[</c-><c- no>rbp-48</c->+<c- no>rdx</c-><c- p>],</c-> <c- no>rdi</c->
  <c- nf>cmp</c->  <c- no>eax</c-><c- p>,</c-> <c- no>r8d</c->
  <c- nf>jb</c->  <c- no>.L114</c->
  <c- nf>lea</c->  <c- no>rdi</c-><c- p>,</c-> <c- p>[</c-><c- no>rbp-48</c-><c- p>]</c->
  <c- nf>add</c->  <c- no>rdi</c-><c- p>,</c-> <c- no>rax</c->
  <c- nf>add</c->  <c- no>rax</c-><c- p>,</c-> <c- no>rcx</c->
  <c- nf>jmp</c->  <c- no>.L113</c-></pre>
   <p>This program is both correct and, at least in the loop, as efficient as
possible. With hardware support for masked instructions, a high quality 
implementation of the partial-init load turns into a single instruction.</p>
   <h2 class="heading settled" data-level="7" id="range_overloads"><span class="secno">7. </span><span class="content">Overloads for different range specifications</span><a class="self-link" href="#range_overloads"></a></h2>
   <p>Providing constructors which accept a static or a dynamic extent can solve all
of the basic needs of <code class="highlight"><c- n>simd</c-></code>, but it may be convenient to have additional
overloads which simplify some of the common ways in which <code class="highlight"><c- n>simd</c-></code> values are
constructed. <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>span</c-></code> already provides a variety of different styles of bound
specification, including:</p>
<pre class="highlight"><c- n>span</c-><c- p>(</c-> <c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>size_type</c-> <c- n>count</c-> <c- p>);</c->

<c- n>span</c-><c- p>(</c-> <c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>End</c-> <c- n>last</c-> <c- p>);</c->

<c- n>span</c-><c- p>(</c-> <c- n>std</c-><c- o>::</c-><c- n>type_identity_t</c-><c- o>&lt;</c-><c- n>element_type</c-><c- o>></c-> <c- p>(</c-><c- o>&amp;</c-><c- n>arr</c-><c- p>)[</c-> <c- n>N</c-> <c- p>]</c-> <c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

<c- n>span</c-><c- p>(</c-> <c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- n>U</c-><c- p>,</c-> <c- n>N</c-><c- o>>&amp;</c-> <c- n>arr</c-> <c- p>);</c->

<c- n>span</c-><c- p>(</c-> <c- n>R</c-><c- o>&amp;&amp;</c-> <c- n>range</c-> <c- p>);</c->

<c- n>span</c-><c- p>(</c-> <c- n>std</c-><c- o>::</c-><c- n>initializer_list</c-><c- o>&lt;</c-><c- n>value_type</c-><c- o>></c-> <c- n>il</c-> <c- p>)</c-> <c- k>noexcept</c-><c- p>;</c->

<c- n>span</c-><c- p>(</c-> <c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- n>span</c-><c- o>&lt;</c-><c- n>U</c-><c- p>,</c-> <c- n>N</c-><c- o>>&amp;</c-> <c- n>source</c-> <c- p>)</c-> <c- k>noexcept</c-><c- p>;</c-></pre>
   <p>Many of these styles are already handled by <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>simd</c-></code>, where constructors are
available for compile-time extents or dynamic ranges already, and need not be
considered for special treatment here. However, there are two common cases which could be added as utility constructors:</p>
<pre class="highlight"><c- k>constexpr</c-> <c- n>basic_simd</c-><c- p>(</c-> <c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>size_type</c-> <c- n>count</c-> <c- p>);</c->
<c- k>constexpr</c-> <c- n>basic_simd</c-><c- p>(</c-> <c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>It</c-> <c- n>last</c-> <c- p>);</c-></pre>
   <h2 class="heading settled" data-level="8" id="contiguous_source_or_not"><span class="secno">8. </span><span class="content">Contiguous or non-contiguous sources</span><a class="self-link" href="#contiguous_source_or_not"></a></h2>
   <p>In <span>[P1928R12]</span> and <a data-link-type="biblio" href="#biblio-p2664r6" title="Proposal to extend std::simd with permutation API">[P2664R6]</a> we make a distinction between
loads and stores to contiguous memory regions, which we call copy operations
(e.g., <code class="highlight"><c- n>copy_to</c-></code>, <code class="highlight"><c- n>copy_from</c-></code>) and non-contiguous operations, which we call <code class="highlight"><c- n>gather_from</c-></code> and <code class="highlight"><c- n>scatter_to</c-></code>. We have done so to call out the potentially
large performance difference between the two and make it obvious to the user
what the expectations should be.</p>
   <p>With ranges or spans as the source of data for <code class="highlight"><c- n>simd</c-></code> constructors we should
take similar care to avoid accidental performance traps. We recommend that the new
constructors described in this paper should work only on contiguous ranges. If the
user wishes to access data in a non-contiguous range then they should explicitly
build a suitable contiguous data source, using their expert knowledge to decide
how best to achieve that.</p>
   <h2 class="heading settled" data-level="9" id="simd_mask_ranges"><span class="secno">9. </span><span class="content">Range operations for <code class="highlight"><c- n>simd_mask</c-></code></span><a class="self-link" href="#simd_mask_ranges"></a></h2>
   <p>In the current definition of <code class="highlight"><c- n>simd_mask</c-></code> in <span>[P1928R12]</span> there are constructors,
and <code class="highlight"><c- n>copy_to</c-></code>/<code class="highlight"><c- n>copy_from</c-></code> functions which work with iterators to containers of <code class="highlight"><c- b>bool</c-></code> values.</p>
   <p>As noted in <a data-link-type="biblio" href="#biblio-p2876r1" title="Proposal to extend std::simd with more constructors and accessors">[P2876R1]</a>, a container of <code class="highlight"><c- b>bool</c-></code> values is not an ideal way to
store mask-like values. A better alternative for storing mask element bits
outside a <code class="highlight"><c- n>simd_mask</c-></code> is either as a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>bitset</c-></code> or as densely packed bits in
unsigned integers. <a data-link-type="biblio" href="#biblio-p2876r1" title="Proposal to extend std::simd with more constructors and accessors">[P2876R1]</a> proposes that <code class="highlight"><c- n>simd</c-></code> provide implicit
constructors and accessors for these cases, giving a more efficient and safer
mechanism for storing mask bits than the current functions in <span>[P1928R12]</span>. We
suggest that the <code class="highlight"><c- n>simd_mask</c-></code> iterator constructors, and the <code class="highlight"><c- n>simd_mask</c-><c- o>::</c-><c- n>copy_from</c-><c- o>/</c-><c- n>copy_to</c-></code> functions are removed entirely, and that <code class="highlight"><c- n>load_from</c-></code> and <code class="highlight"><c- n>store_to</c-></code> should only operate on <code class="highlight"><c- n>simd</c-></code> values.</p>
   <h2 class="heading settled" data-level="10" id="function_type_choice"><span class="secno">10. </span><span class="content">Constructor, member function or free function</span><a class="self-link" href="#function_type_choice"></a></h2>
   <p>At this point we have two constructors loading from a contiguous range: In the
static extent case the constructor requires an exact match of <code class="highlight"><c- n>simd</c-></code> width and
range size; in the dynamic extent case the range can be of any size. This
mismatch prompts the question whether we’re doing something wrong. Why does this
compile:</p>
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-> <c- n>data</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>,</c-> <c- mi>5</c-><c- p>};</c->
<c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>4</c-><c- o>></c-> <c- n>v</c-><c- p>(</c-><c- n>data</c-><c- p>);</c-></pre>
   <p>but this doesn’t compile:</p>
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-> <c- n>data</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>,</c-> <c- mi>5</c-><c- p>};</c->
<c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>4</c-><c- o>></c-> <c- n>v</c-><c- p>(</c-><c- n>data</c-><c- p>);</c-></pre>
   <p>and this doesn’t compile:</p>
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-> <c- n>data</c-> <c- o>=</c-> <c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>,</c-> <c- mi>5</c-><c- p>};</c->
<c- n>std</c-><c- o>::</c-><c- n>span</c-><c- o>&lt;</c-><c- k>const</c-> <c- b>int</c-><c- p>,</c-> <c- mi>5</c-><c- o>></c-> <c- n>chunk</c-><c- p>(</c-><c- n>data</c-><c- p>,</c-> <c- mi>5</c-><c- p>);</c->
<c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>4</c-><c- o>></c-> <c- n>v</c-><c- p>(</c-><c- n>chunk</c-><c- p>);</c-></pre>
   <p>We need to resolve this inconsistency. To this end, note that we can
characterize these two constructors as "conversion from array" and "load from 
range" constructors. Under the hood they are both just a <code class="highlight"><c- n>memcpy</c-></code>, but the 
semantics we are defining for the <code class="highlight"><c- n>simd</c-></code> type makes them different (implicit vs 
explicit, constrained size vs no size constraint). Also note that in most 
cases the "conversion from array" can also be implemented via a <code class="highlight"><c- n>bit_cast</c-></code>, 
which is not trivially possible for the "load from range" constructor.</p>
   <p>This leads us to reconsider whether we should have a load constructor at all.
If we have a "conversion from array" constructor the load we can consider 
"safe" to use is available to users. And given a facility that produces a <code class="highlight"><c- n>span</c-></code> of static extent from a given range we don’t actually need anything else 
anymore:</p>
<pre class="language-cpp highlight"><c- n>myvector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>data</c-> <c- o>=</c-> <c- d>/*...*/</c-><c- p>;</c->  <c- c1>// std::vector plus span subscript operator</c->
<c- n>std</c-><c- o>::</c-><c- n>basic_simd</c-> <c- n>v</c-> <c- o>=</c-> <c- n>data</c-><c- p>[</c-><c- n>i</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>::</c-><c- n>size</c-><c- p>];</c-></pre>
   <p>The other important consideration is the relation of loads to gathers. Both
fill all <code class="highlight"><c- n>simd</c-></code> elements from values stored in a contiguous range. The load can 
be considered a special case of a gather where the index vector is an iota 
vector (0, 1, 2, 3, ...). Thus, if we adopt the <code class="highlight"><c- n>gather_from</c-></code> function from 
P2664, the following two are functionally equivalent (using the P1928R12 and 
P2664R8 API):</p>
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-> <c- n>data</c-> <c- o>=</c-> <c- d>/*...*/</c-><c- p>;</c->
<c- k>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>4</c-><c- o>></c-> <c- n>iota</c-><c- p>([](</c-><c- b>int</c-> <c- n>i</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>i</c-><c- p>;</c-> <c- p>});</c->

<c- k>auto</c-> <c- n>v1</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>4</c-><c- o>></c-><c- p>(</c-><c- n>data</c-><c- p>.</c-><c- n>begin</c-><c- p>());</c->
<c- k>auto</c-> <c- n>v2</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>gather_from</c-><c- p>(</c-><c- n>data</c-><c- p>,</c-> <c- n>iota</c-><c- p>);</c->
<c- n>assert</c-><c- p>(</c-><c- n>all_of</c-><c- p>(</c-><c- n>v1</c-> <c- o>==</c-> <c- n>v2</c-><c- p>));</c-></pre>
   <p>A high-quality implementation can even recognize the index argument (constant
propagated) and implement the above <code class="highlight"><c- n>gather_from</c-></code> as a vector load instruction 
instead of a gather instruction.</p>
   <p>In terms of API design we immediately notice the inconsistency. These two
functions are closer related than the "conversion from array" constructor and 
"load from range" constructor. Consequently, either there needs to be a gather 
constructor or the "load from range" constructor should be a non-member function.</p>
<pre class="language-cpp highlight"><c- k>auto</c-> <c- n>v1</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>load_from</c-><c- p>(</c-><c- n>data</c-><c- p>);</c->
<c- k>auto</c-> <c- n>v2</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>gather_from</c-><c- p>(</c-><c- n>data</c-><c- p>,</c-> <c- n>iota</c-><c- p>);</c-></pre>
   <p>But these two still have an important difference, the former provides no
facility to choose the <code class="highlight"><c- n>simd</c-></code> width, whereas the latter infers it from the 
width of the index <code class="highlight"><c- n>simd</c-></code>. This could be solved with an optional template 
argument to the <code class="highlight"><c- n>load_from</c-></code> function. For consistency, the <code class="highlight"><c- n>gather_from</c-></code> function should provide the same optional template argument:</p>
<pre class="language-cpp highlight"><c- k>using</c-> <c- n>V</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>4</c-><c- o>></c-><c- p>;</c->
<c- k>auto</c-> <c- n>v1</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>load_from</c-><c- o>&lt;</c-><c- n>V</c-><c- o>></c-><c- p>(</c-><c- n>data</c-><c- p>);</c->
<c- k>auto</c-> <c- n>v2</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>gather_from</c-><c- o>&lt;</c-><c- n>V</c-><c- o>></c-><c- p>(</c-><c- n>data</c-><c- p>,</c-> <c- n>iota</c-><c- p>);</c-></pre>
   <p>With this definition of the load non-member function, we retain the same
functionality the constructor provides (converting loads, choose <code class="highlight"><c- n>simd</c-></code> width). 
If we replace the load constructor with a non-member function, we should at the 
same time remove the <code class="highlight"><c- n>simd</c-><c- o>::</c-><c- n>copy_from</c-></code> member function. The analogue non-member 
function <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>store_to</c-><c- p>(</c-><c- n>simd</c-><c- p>,</c-> <c- n>range</c-><c- p>,</c-> <c- n>flags</c-><c- p>)</c-></code> replaces <code class="highlight"><c- n>simd</c-><c- o>::</c-><c- n>copy_to</c-></code>. Stores 
don’t require a template argument, since the <code class="highlight"><c- n>simd</c-></code> type is already give via 
the first function argument.</p>
   <p>Providing loads and stores as non-member functions enables us to provide them
for scalar types as well, enabling more SIMD-generic programming. Consider:</p>
<pre class="language-cpp highlight"><c- k>template</c-> <c- o>&lt;</c-><c- n>simd_integral</c-> <c- n>T</c-><c- o>></c->
<c- b>void</c-> <c- n>f</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>&amp;</c-> <c- n>data</c-><c- p>)</c-> <c- p>{</c->
  <c- n>T</c-> <c- n>v</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>load_from</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(</c-><c- n>data</c-><c- p>);</c->
  <c- n>v</c-> <c- o>+=</c-> <c- mi>1</c-><c- p>;</c->
  <c- n>std</c-><c- o>::</c-><c- n>store_to</c-><c- p>(</c-><c- n>v</c-><c- p>,</c-> <c- n>data</c-><c- p>);</c->
<c- p>}</c-></pre>
   <p>This function <code class="highlight"><c- n>f</c-></code> can be called as <code class="highlight"><c- n>f</c-><c- o>&lt;</c-><c- b>int</c-><c- o>></c-></code> and <code class="highlight"><c- n>f</c-><c- o>&lt;</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- o>>></c-></code> if <code class="highlight"><c- n>load_from</c-></code> and <code class="highlight"><c- n>store_to</c-></code> are overloaded for scalars. With the P1928R12 API the 
implementation of <code class="highlight"><c- n>f</c-></code> requires constexpr-if branches.</p>
   <p>For completeness, the load and store functions need to be overloaded with a
mask argument preceding the flags argument.</p>
   <h3 class="heading settled" data-level="10.1" id="range_to"><span class="secno">10.1. </span><span class="content">Design alternative replacing <code class="highlight"><c- n>load_from</c-></code> by <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code></span><a class="self-link" href="#range_to"></a></h3>
   <p>An alternative to providing <code class="highlight"><c- n>load_from</c-></code> is to use an existing C++ feature called <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code> instead. Here are a couple of examples showing the potential
of doing this:</p>
<pre class="highlight"><c- k>auto</c-> <c- n>v0</c-> <c- o>=</c-> <c- n>array</c-><c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>2</c-><c- p>,</c-> <c- mi>3</c-><c- p>,</c-> <c- mi>4</c-><c- p>}</c-> <c- o>|</c-> <c- n>ranges</c-><c- o>::</c-><c- n>to</c-><c- o>&lt;</c-><c- n>basic_simd</c-><c- o>></c->`<c- p>;</c->

<c- n>std</c-><c- o>::</c-><c- n>vector</c-><c- o>&lt;</c-><c- b>double</c-><c- o>></c-> <c- n>floats</c-><c- p>{</c-><c- mf>2.4</c-><c- p>,</c-> <c- mf>1.1</c-><c- p>,</c-> <c- mf>9.7</c-><c- p>,</c-> <c- mf>6.3</c-><c- p>,</c-> <c- mf>9.6</c-><c- p>};</c->
<c- k>auto</c-> <c- n>v1</c-> <c- o>=</c-> <c- n>floats</c-> <c- o>|</c-> <c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-><c- o>&lt;</c-><c- n>basic_simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>3</c-><c- o>></c-><c- p>();</c-></pre>
   <p>The first example works already using the span-constructor proposed earlier. The
second example could also be made to work if another constructor were provided
which took <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>from_range_t</c-></code> as its first parameter. Both examples would also
require CTAD to deduce the correct simd template parameters.</p>
   <p>While <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code> does seem to be a potential replacement for <code class="highlight"><c- n>load_from</c-></code> which is consistent with existing C++ facilities, there are a number of API
mis-matches which potentially make this confusing:</p>
   <ul>
    <li data-md>
     <p>The range will be silently truncated if the output <code class="highlight"><c- n>basic_simd</c-></code> object is too
small. This alone is sufficiently undesirable behaviour to persuade us not
to use <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code>.</p>
    <li data-md>
     <p>Other standard types which serve as the destination of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code> can
resize at runtime to store all the available input elements. Standard types
which can’t resize (e.g., <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-></code>) are not permitted as the destination
of <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code>, so <code class="highlight"><c- n>basic_simd</c-></code> arguably shouldn’t either.</p>
    <li data-md>
     <p>The <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code> function would not allow a mask to be passed in, so <code class="highlight"><c- n>load_from</c-></code> would still be needed for the masked variation.</p>
    <li data-md>
     <p>There is no obvious way for <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code> to replace <code class="highlight"><c- n>store_to</c-></code>, so <code class="highlight"><c- n>store_to</c-></code> would still be required.</p>
   </ul>
   <p>For all these reasons we do not think that using <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>to</c-></code> is a viable
full or partial replacement for <code class="highlight"><c- n>load_from</c-></code>.</p>
   <h3 class="heading settled" data-level="10.2" id="combine_load_gather_store_scatter"><span class="secno">10.2. </span><span class="content">Design alternative combining load and gather / store and scatter</span><a class="self-link" href="#combine_load_gather_store_scatter"></a></h3>
   <p>As noted above, an implementation could recognize a constant propagated iota
index vector passed to a gather and emit an much faster load instruction. What 
if we provide a special type denoting a contiguous index range? In that case 
there could be a single <code class="highlight"><c- n>simd_load</c-><c- p>(</c-><c- n>range</c-><c- p>,</c-> <c- n>simd_or_index_range</c-><c- p>,</c-> <c- n>flags</c-><c- p>)</c-></code> function 
implementing gather and load efficiently. Example:</p>
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- n>index_range</c-><c- o>&lt;</c-><c- mi>4</c-><c- o>></c-> <c- n>i4</c-> <c- o>=</c-> <c- mi>1</c-><c- p>;</c->
<c- n>std</c-><c- o>::</c-><c- n>simd</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>4</c-><c- o>></c-> <c- n>iota</c-><c- p>([](</c-><c- b>int</c-> <c- n>i</c-><c- p>)</c-> <c- p>{</c-> <c- k>return</c-> <c- n>i</c-> <c- o>+</c-> <c- mi>1</c-><c- p>;</c-> <c- p>});</c->

<c- k>auto</c-> <c- n>v1</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd_load</c-><c- p>(</c-><c- n>data</c-><c- p>,</c-> <c- n>i4</c-><c- p>);</c->
<c- k>auto</c-> <c- n>v2</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>simd_load</c-><c- p>(</c-><c- n>data</c-><c- p>,</c-> <c- n>iota</c-><c- p>);</c->
<c- n>assert</c-><c- p>(</c-><c- n>all_of</c-><c- p>(</c-><c- n>v1</c-> <c- o>==</c-> <c- n>v2</c-><c- p>));</c-></pre>
   <p>Such an <code class="highlight"><c- n>index_range</c-><c- o>&lt;</c-><c- n>size</c-><c- o>></c-></code> type is also interesting for subscripting into
contiguous ranges, producing a <code class="highlight"><c- n>span</c-></code> of static extent, which is consequently 
convertible to <code class="highlight"><c- n>simd</c-></code>:</p>
<pre class="language-cpp highlight"><c- n>std</c-><c- o>::</c-><c- n>basic_simd</c-> <c- n>v3</c-> <c- o>=</c-> <c- n>data</c-><c- p>[</c-><c- n>i4</c-><c- p>];</c->
<c- n>assert</c-><c- p>(</c-><c- n>all_of</c-><c- p>(</c-><c- n>v1</c-> <c- o>==</c-> <c- n>v3</c-><c- p>));</c-></pre>
   <h2 class="heading settled" data-level="11" id="data_parallel_execution_policy"><span class="secno">11. </span><span class="content">Data parallel execution policy</span><a class="self-link" href="#data_parallel_execution_policy"></a></h2>
   <p>Many of the arguments in this proposal concern how explicit the programmer needs
to be in what they are doing (e.g., exception or default-initialization) to
achieve safe but high-performance. For example, a very common use case for <code class="highlight"><c- n>simd</c-></code> is to iterate through a large data set in small simd-sized blocks,
processing each block in turn. The code might look something like:</p>
<pre class="highlight"><c- b>void</c-> <c- nf>process</c-><c- p>(</c-><c- n>Range</c-><c- o>&amp;&amp;</c-> <c- n>r</c-><c- p>)</c->
<c- p>{</c->
  <c- k>constexpr</c-> <c- b>int</c-> <c- n>N</c-> <c- o>=</c-> <c- n>simd</c-><c- o>&lt;</c-><c- b>float</c-><c- o>>::</c-><c- n>size</c-><c- p>;</c->

  <c- c1>// Whole blocks</c->
  <c- k>for</c-> <c- p>(</c-><c- b>int</c-> <c- n>i</c-><c- o>=</c-><c- mi>0</c-><c- p>;</c-> <c- n>i</c-><c- o>&lt;</c-><c- n>r</c-><c- p>.</c-><c- n>size</c-><c- p>();</c-> <c- n>i</c-><c- o>+=</c-><c- n>N</c-><c- p>)</c->
  <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>span</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- n>simd</c-><c- o>&lt;</c-><c- b>float</c-><c- o>>::</c-><c- n>size</c-><c- o>></c-> <c- n>block</c-><c- p>(</c-><c- n>r</c-><c- p>.</c-><c- n>begin</c-><c- p>()</c-> <c- o>+</c-> <c- n>i</c-><c- p>,</c-> <c- n>N</c-><c- p>);</c->
    <c- n>doSomething</c-><c- p>(</c-><c- n>block</c-><c- p>);</c-> <c- c1>// Standard load - no runtime checks, but its within the known range.</c->
  <c- p>}</c->

  <c- c1>// Remainder</c->
  <c- k>if</c-> <c- p>(</c-><c- n>remainder</c-><c- p>)</c->
  <c- p>{</c->
    <c- c1>// range checked</c->
    <c- n>simd</c-><c- o>&lt;</c-><c- b>float</c-><c- o>></c-> <c- n>remainder</c-><c- p>(</c-><c- n>r</c-><c- p>.</c-><c- n>begin</c-><c- p>(),</c-> <c- n>N</c-><c- p>,</c-> <c- n>simd_flag_partial_loadstore</c-><c- p>);</c->
    <c- n>doSomething</c-><c- p>(</c-><c- n>block</c-><c- p>);</c->
  <c- p>}</c->
<c- p>}</c-></pre>
   <p>This is efficient and correct, but is verbose common code for the user to write.
If an execution policy for <code class="highlight"><c- n>simd</c-></code> was available then this could be written much
more simply, with all the mechanics hidden away.</p>
<pre class="highlight"><c- n>std</c-><c- o>::</c-><c- n>for_each</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>execution</c-><c- o>::</c-><c- n>simd</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>ptr</c-><c- p>),</c-> <c- n>std</c-><c- o>::</c-><c- n>end</c-><c- p>(</c-><c- n>ptr</c-><c- p>),</c-> <c- p>[</c-><c- o>&amp;</c-><c- p>](</c-><c- n>simdable</c-> <c- n>block</c-><c- p>)</c->
<c- p>{</c->
    <c- n>doSomething</c-><c- p>(</c-><c- n>block</c-><c- p>);</c->
<c- p>});</c-></pre>
   <p>In this case the <code class="highlight"><c- n>simd</c-></code> library need not worry too much about choosing what
default to use in the absence of any flags (e.g., <code class="highlight"><c- n>simd_flag_partial_loadstore</c-></code>, <code class="highlight"><c- n>simd_unchecked</c-></code>) because the library code wil use whatever it needs explicitly.</p>
   <p>It is not our intent to define an execution policy in this paper, but we point
out its potential as it may help guide us to a decision on what <code class="highlight"><c- n>simd</c-></code> should do by
default.</p>
   <h2 class="heading settled" data-level="12" id="wording"><span class="secno">12. </span><span class="content">Wording</span><a class="self-link" href="#wording"></a></h2>
   <p>The wording relies on <span>[P1928R12]</span> being landed to the Working Draft. Below,
substitute the � character with a number the editor finds appropriate for the
table, paragraph, section or sub-section.</p>
   <h3 class="heading settled" data-level="12.1" id="wording_simd_flags"><span class="secno">12.1. </span><span class="content">Modify [<strong>simd.flags</strong>]</span><a class="self-link" href="#wording_simd_flags"></a></h3>
   <p>Add the following:</p>
   <blockquote>
<pre class="highlight"><c- c1>// [simd.flags], Load and store flags</c->
�    <ins><c- k>struct</c-> <c- nc>partial</c-><c- o>-</c-><c- n>loadstore</c-><c- o>-</c-><c- n>flag</c-><c- p>;</c-> <c- c1>// exposition only</c-></ins>

�    <ins><c- kr>inline</c-> <c- k>constexpr</c-> <c- n>simd_flags</c-><partial-loadstore-flag> <c- n>simd_flag_partial_loadstore</c-><c- p>{};</c-></partial-loadstore-flag></ins></pre>
   </blockquote>
   <blockquote>
<pre class="highlight"><c- c1>// Class template simd_flags overview</c->
�    <c- n>Every</c-> <c- n>type</c-> <c- n>in</c-> <c- n>Flags</c-> <c- n>is</c-> <c- n>one</c-> <c- n>of</c-> <i><c- n>convert</c-><c- o>-</c-><c- n>flag</c-></i><c- p>,</c-> <i><c- n>aligned</c-><c- o>-</c-><c- n>flag</c-></i><c- p>,</c-> <ins><i><c- n>partial</c-><c- o>-</c-><c- n>loadstore</c-><c- o>-</c-><c- n>flag</c-></i></ins>
      <c- n>or</c-> <i><c- n>overaligned</c-><c- o>-</c-><c- n>flag</c-><n></n></i><c- p>.</c-></pre>
   </blockquote>
   <h3 class="heading settled" data-level="12.2" id="word_simd_syn"><span class="secno">12.2. </span><span class="content">Modify [<strong>simd.synopsis</strong>]</span><a class="self-link" href="#word_simd_syn"></a></h3>
   <p>Add functions to load a simd value from a range.</p>
   <ins>
    <blockquote>
      <span><b>�    [simd.range_load], basic_simd load from range</b></span> 
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>V</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Range</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- k>const</c-> <c- n>Range</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- k>const</c-> <c- n>Range</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>,</c->
                      <c- k>const</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                      <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>V</c-><c- p>,</c-> <c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- n>It</c-> <c- n>begin</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>count</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>V</c-><c- p>,</c-> <c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- n>It</c-> <c- n>begin</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>count</c-><c- p>,</c->
                      <c- k>const</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                      <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>V</c-><c- p>,</c-> <c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- n>It</c-> <c- n>begin</c-><c- p>,</c-> <c- n>It</c-> <c- n>end</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>V</c-><c- p>,</c-> <c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- n>It</c-> <c- n>begin</c-><c- p>,</c-> <c- n>It</c-> <c- n>end</c-><c- p>,</c-> 
                      <c- k>const</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                      <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c-></pre>
    </blockquote>
   </ins>
   <p>Add functions to load a simd value from a range.</p>
   <ins>
    <blockquote>
      <span><b>�    [simd.range_store], basic_simd store into a range</b></span> 
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Abi</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Range</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>store_to</c-><c- p>(</c-><c- k>const</c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>&amp;</c-> <c- n>v</c-><c- p>,</c-> <c- n>Range</c-><c- o>&amp;&amp;</c-> <c- n>r</c-><c- p>,</c->
                        <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Abi</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Range</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>store_to</c-><c- p>(</c-><c- k>const</c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>&amp;</c-> <c- n>v</c-><c- p>,</c-> <c- n>Range</c-><c- o>&amp;&amp;</c-> <c- n>r</c-><c- p>,</c->
                        <c- k>const</c-> <c- k>typename</c-> <c- nc>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>::</c-><c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                        <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Abi</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Out</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>store_to</c-><c- p>(</c-><c- k>const</c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>&amp;</c-> <c- n>v</c-><c- p>,</c->
                        <c- n>Out</c-> <c- n>begin</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>count</c-><c- p>,</c->
                        <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Abi</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Out</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>store_to</c-><c- p>(</c-><c- k>const</c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>&amp;</c-> <c- n>v</c-><c- p>,</c->
                        <c- n>Out</c-> <c- n>begin</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>count</c-><c- p>,</c->
                        <c- k>typename</c-> <c- nc>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>::</c-><c- k>const</c-> <c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                        <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Abi</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Out</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>store_to</c-><c- p>(</c-><c- k>const</c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>&amp;</c-> <c- n>v</c-><c- p>,</c->
                        <c- n>Out</c-> <c- n>begin</c-><c- p>,</c-> <c- n>Out</c-> <c- n>end</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>T</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Abi</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Out</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>store_to</c-><c- p>(</c-><c- k>const</c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>&amp;</c-> <c- n>v</c-><c- p>,</c->
                        <c- n>Out</c-> <c- n>begin</c-><c- p>,</c-> <c- n>Out</c-> <c- n>end</c-><c- p>,</c->
                        <c- k>const</c-> <c- k>typename</c-> <c- nc>basic_simd</c-><c- o>&lt;</c-><c- n>T</c-><c- p>,</c-> <c- n>Abi</c-><c- o>>::</c-><c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                        <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c-></pre>
    </blockquote>
   </ins>
   <h3 class="heading settled" data-level="12.3" id="word_simd_overview"><span class="secno">12.3. </span><span class="content">Modify [<strong>simd.overview</strong>]</span><a class="self-link" href="#word_simd_overview"></a></h3>
   <p>Replace iterator-based constructors with static-span constructors:</p>
   <blockquote>
     <span><b>�    [simd.ctor], basic_simd constructors</b></span> 
    <remove>
     <blockquote>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- k>explicit</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- k>explicit</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- k>const</c-> <c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c-></pre>
     </blockquote>
    </remove>
    <ins>
     <blockquote>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Span</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- k>explicit</c-> <c- n>basic_simd</c-><c- p>(</c-><c- k>const</c-> <c- n>Span</c-><c- o>&amp;</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Span</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- k>explicit</c-> <c- n>basic_simd</c-><c- p>(</c-><c- k>const</c-> <c- n>Span</c-><c- o>&amp;</c-> <c- n>first</c-><c- p>,</c-> <c- k>const</c-> <c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                              <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c-></pre>
     </blockquote>
    </ins>
   </blockquote>
   <p>Remove <code class="highlight"><c- n>copy_to</c-></code> and <code class="highlight"><c- n>copy_from</c-></code> functions.</p>
   <blockquote>
     <span><b>�  [simd.copy], basic_simd copy functions</b></span> 
    <remove>
     <blockquote>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>copy_from</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>copy_from</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- k>const</c-> <c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Out</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>copy_to</c-><c- p>(</c-><c- n>Out</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{})</c-> <c- k>const</c-><c- p>;</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Out</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>copy_to</c-><c- p>(</c-><c- n>Out</c-> <c- n>first</c-><c- p>,</c-> <c- k>const</c-> <c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{})</c-> <c- k>const</c-><c- p>;</c-></pre>
     </blockquote>
    </remove>
   </blockquote>
   <h3 class="heading settled" data-level="12.4" id="word_simd_mask_overview"><span class="secno">12.4. </span><span class="content">Modify [<strong>simd.mask.overview</strong>]</span><a class="self-link" href="#word_simd_mask_overview"></a></h3>
   <p>Remove <code class="highlight"><c- n>simd_mask</c-></code> memory interaction.</p>
   <blockquote>
     <span><b>�    [simd.mask.ctor], <code class="highlight"><c- n>basic_simd_mask</c-></code> constructors</b></span> 
    <remove>
     <blockquote>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>basic_simd_mask</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- n>basic_simd_mask</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- k>const</c-> <c- n>basic_simd_mask</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c-></pre>
     </blockquote>
    </remove>
   </blockquote>
   <p>Remove <code class="highlight"><c- n>simd_mask</c-></code> <code class="highlight"><c- n>copy_to</c-></code> and <code class="highlight"><c- n>copy_from</c-></code> functions.</p>
   <blockquote>
     <span><b>�  [simd.mask.copy], <code class="highlight"><c- n>basic_simd_mask</c-></code> copy functions</b></span> 
    <remove>
     <blockquote>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>copy_from</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>copy_from</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- k>const</c-> <c- n>basic_simd_mask</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Out</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>copy_to</c-><c- p>(</c-><c- n>Out</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{})</c-> <c- k>const</c-><c- p>;</c->
<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>Out</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- b>void</c-> <c- n>copy_to</c-><c- p>(</c-><c- n>Out</c-> <c- n>first</c-><c- p>,</c-> <c- k>const</c-> <c- n>basic_simd_mask</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                       <c- n>simd_flags</c-><c- o>&lt;</c-><flags...> <c- o>=</c-> <c- p>{})</c-> <c- k>const</c-><c- p>;</c->
</flags...></pre>
     </blockquote>
    </remove>
   </blockquote>
   <h3 class="heading settled" data-level="12.5" id="word_simd_ctor"><span class="secno">12.5. </span><span class="content">Modify [<strong>simd.ctor</strong>] <code class="highlight"><c- n>basic_simd</c-></code> constructors</span><a class="self-link" href="#word_simd_ctor"></a></h3>
   <p>Remove iterator-based constructors.</p>
   <remove>
    <blockquote>
<pre class="highlight"><c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- k>explicit</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- n>simd_flags</c-><flags...> <c- o>=</c-> <c- p>{});</c->

  <c- p>[</c-><c- n>remove</c-> <c- n>all</c-> <c- n>descriptions</c-> <c- n>too</c-><c- p>]</c->

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- k>explicit</c-> <c- n>basic_simd</c-><c- p>(</c-><c- n>It</c-> <c- n>first</c-><c- p>,</c-> <c- k>const</c-> <c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c-> <c- n>simd_flags</c-><flags...> <c- o>=</c-> <c- p>{});</c->

  <c- p>[</c-><c- n>remove</c-> <c- n>all</c-> <c- n>descriptions</c-> <c- n>too</c-><c- p>]</c->
</flags...></flags...></pre>
    </blockquote>
   </remove>
   <p>Add static-extent span constructors.</p>
   <ins>
    <blockquote>
      <span><b>� <code class="highlight"><c- n>basic_simd</c-></code> constructors        [simd.ctor]</b></span> 
<pre class="highlight"><c- c1>// Construct a basic_simd from the values contained in the given span-like object with</c->
<c- c1>// the same static extent.</c->

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>StaticSpan</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- k>explicit</c-> <c- n>basic_simd</c-><c- p>(</c-><c- k>const</c-> <c- n>StaticSpan</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c->

<c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>StaticSpan</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- k>constexpr</c-> <c- k>explicit</c-> <c- n>basic_simd</c-><c- p>(</c-><c- k>const</c-> <c- n>StaticSpan</c-><c- o>&amp;</c-> <c- n>s</c-><c- p>,</c-> <c- k>const</c-> <c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                              <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- o>=</c-> <c- p>{});</c-></pre>
     <p><i>Constraints:</i></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>element</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;</c-><c- n>StaticSpan</c-><c- o>></c-></code> must be a vectorizable type.</p>
      <li data-md>
       <p>The static extent of the <code class="highlight"><c- n>StaticSpan</c-></code> must be the same as <code class="highlight"><c- n>size</c-></code>.</p>
     </ul>
     <p><i>Mandates:</i></p>
     <ul>
      <li data-md>
       <p>If the template parameter pack <code class="highlight"><c- n>Flags</c-></code> does not contain <code class="highlight"><c- n>convert</c-><c- o>-</c-><c- n>flag</c-></code>, then the conversion
from <code class="highlight"><c- n>element</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;</c-><c- n>StaticSpan</c-><c- o>></c-></code> to <code class="highlight"><c- n>value_type</c-></code> is value-preserving.</p>
     </ul>
     <p><i>Preconditions:</i></p>
     <ul>
      <li data-md>
       <p>If the template parameter pack <code class="highlight"><c- n>Flags</c-></code> contains <code class="highlight"><c- n>aligned</c-><c- o>-</c-><c- n>flag</c-></code>, then <code class="highlight"><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>s</c-><c- p>))</c-></code> points to storage
aligned by <code class="highlight"><c- n>simd_alignment_v</c-><c- o>&lt;</c-><c- n>basic_simd</c-><c- p>,</c-> <c- n>span</c-><c- o>-</c-><c- n>value</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;</c-><c- n>StaticSpan</c-><c- o>>></c-></code>.</p>
      <li data-md>
       <p>If the template parameter pack <code class="highlight"><c- n>Flags</c-></code> contains <code class="highlight"><c- n>overaligned</c-><c- o>-</c-><c- n>flag</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-></code>, then <code class="highlight"><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>s</c-><c- p>))</c-></code> points
to storage aligned by <code class="highlight"><c- n>N</c-></code>.</p>
     </ul>
     <p><i>Effects:</i></p>
     <ul>
      <li data-md>
       <p>For the unmasked constructor, initializes the <code class="highlight"><c- n>i</c->’<c- n>th</c-></code> element with <code class="highlight"><c- k>static_cast</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(</c-><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>s</c-><c- p>))[</c-><c- n>i</c-><c- p>])</c-></code> for all <code class="highlight"><c- n>i</c-></code> in the range of <code class="highlight"><c- p>[</c-><c- mi>0</c-><c- p>,</c-> <c- n>size</c-><c- p>())</c-></code>.</p>
      <li data-md>
       <p>For the masked constructor,  initializes the <code class="highlight"><c- n>i</c->’<c- n>th</c-></code> element with <code class="highlight"><c- n>mask</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>?</c-> <c- k>static_cast</c-><c- o>&lt;</c-><c- n>T</c-><c- o>></c-><c- p>(</c-><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>s</c-><c- p>))[</c-><c- n>i</c-><c- p>])</c-> <c- o>:</c-> <c- n>T</c-><c- p>()</c-></code> for all <code class="highlight"><c- n>i</c-></code> in the range of <code class="highlight"><c- p>[</c-><c- mi>0</c-><c- p>,</c-> <c- n>size</c-><c- p>())</c-></code>.</p>
     </ul>
    </blockquote>
   </ins>
   <h3 class="heading settled" data-level="12.6" id="word_simd_from_range"><span class="secno">12.6. </span><span class="content">Add [<strong>simd.from_range</strong>] <code class="highlight"><c- n>basic_simd</c-></code> load from range</span><a class="self-link" href="#word_simd_from_range"></a></h3>
   <p>Add free-functions to load a basic_simd’s elements from a range.</p>
   <ins>
    <blockquote>
      <span><b>� <code class="highlight"><c- n>basic_simd</c-></code> load from range        [simd.from_range]</b></span> 
<pre class="highlight"><c- p>(</c-><c- mi>1</c-><c- p>)</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>V</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Range</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
    <c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- k>const</c-> <c- n>Range</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- p>(</c-><c- mi>2</c-><c- p>)</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
    <c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- k>const</c-> <c- n>Range</c-><c- o>&amp;</c-> <c- n>r</c-><c- p>,</c->
                          <c- k>const</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                          <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->

<c- p>(</c-><c- mi>3</c-><c- p>)</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>V</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Iter</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
    <c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- n>Iter</c-> <c- n>first</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>count</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- p>(</c-><c- mi>4</c-><c- p>)</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
    <c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- n>Iter</c-> <c- n>first</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>count</c-><c- p>,</c->
                          <c- k>const</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                          <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->

<c- p>(</c-><c- mi>5</c-><c- p>)</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>V</c-><c- p>,</c-> <c- k>class</c-> <c- nc>Iter</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
    <c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- n>Iter</c-> <c- n>first</c-><c- p>,</c-> <c- n>Iter</c-> <c- n>last</c-><c- p>,</c-> <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c->
<c- p>(</c-><c- mi>6</c-><c- p>)</c-> <c- k>template</c-><c- o>&lt;</c-><c- k>class</c-> <c- nc>It</c-><c- p>,</c-> <c- k>class</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
    <c- k>constexpr</c-> <c- n>V</c-> <c- n>load_from</c-><c- p>(</c-><c- n>Iter</c-> <c- n>first</c-><c- p>,</c-> <c- n>Iter</c-> <c- n>last</c-><c- p>,</c->
                          <c- k>const</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>mask_type</c-><c- o>&amp;</c-> <c- n>mask</c-><c- p>,</c->
                          <c- n>simd_flags</c-><c- o>&lt;</c-><c- n>Flags</c-><c- p>...</c-><c- o>></c-> <c- n>f</c-> <c- o>=</c-> <c- p>{});</c-></pre>
     <p><i>Constraints:</i></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Range</c-><c- o>></c-></code> or <code class="highlight"><c- n>iter_value_t</c-><c- o>&lt;</c-><c- n>Iter</c-><c- o>></c-></code> is a vectorizable type.</p>
      <li data-md>
       <p><code class="highlight"><c- n>Range</c-></code> models <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>contiguous_range</c-></code></p>
      <li data-md>
       <p><code class="highlight"><c- n>Range</c-></code> models <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>sized_range</c-></code></p>
      <li data-md>
       <p><code class="highlight"><c- n>Iter</c-></code> models <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>contiguous_iterator</c-></code></p>
      <li data-md>
       <p><code class="highlight"><c- n>V</c-></code> is a <code class="highlight"><c- n>basic_simd</c-></code></p>
     </ul>
     <p><i>Mandates:</i></p>
     <ul>
      <li data-md>
       <p>If the template parameter pack <code class="highlight"><c- n>Flags</c-></code> does not contain <code class="highlight"><c- n>convert</c-><c- o>-</c-><c- n>flag</c-></code>, then the conversion
from <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Range</c-><c- o>></c-></code> or <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>iter_value_t</c-><c- o>&lt;</c-><c- n>Iter</c-><c- o>></c-></code> to <code class="highlight"><c- n>V</c-><c- o>::</c-><c- n>value_type</c-></code> is value-preserving.</p>
     </ul>
     <p><i>Preconditions:</i></p>
     <ul>
      <li data-md>
       <p>If the template parameter pack <code class="highlight"><c- n>Flags</c-></code> does not contain <code class="highlight"><c- n>simd_flag_partial_loadstore</c-></code> then the source must be a valid range of equal or greater extent to <code class="highlight"><c- n>V</c-><c- o>::</c-><c- n>size</c-></code>.</p>
      <li data-md>
       <p>For 3 and 4, <code class="highlight"><c- p>[</c-><c- n>first</c-><c- p>,</c-> <c- n>first</c-> <c- o>+</c-> <c- n>count</c-><c- p>)</c-></code> must be a valid range.</p>
      <li data-md>
       <p>For 5 and 6, <code class="highlight"><c- p>[</c-><c- n>first</c-><c- p>,</c-> <c- n>last</c-><c- p>)</c-></code> must be a valid range.</p>
      <li data-md>
       <p>If the template parameter pack <code class="highlight"><c- n>Flags</c-></code> contains <code class="highlight"><c- n>aligned</c-><c- o>-</c-><c- n>flag</c-></code>, then the source range (e.g., <code class="highlight"><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>r</c-><c- p>))</c-></code>, <code class="highlight"><c- n>to_address</c-><c- p>(</c-><c- n>first</c-><c- p>)</c-></code>) points to storage
aligned by <code class="highlight"><c- n>simd_alignment_v</c-><c- o>&lt;</c-><c- n>basic_simd</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Range</c-><c- o>>></c-></code>.</p>
      <li data-md>
       <p>If the template parameter pack <code class="highlight"><c- n>Flags</c-></code> contains <code class="highlight"><c- n>overaligned</c-><c- o>-</c-><c- n>flag</c-><c- o>&lt;</c-><c- n>N</c-><c- o>></c-></code>, then <code class="highlight"><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>r</c-><c- p>))</c-></code> points
to storage aligned by <code class="highlight"><c- n>N</c-></code>.</p>
     </ul>
     <p><i>Returns:</i></p>
     <p>A <code class="highlight"><c- n>basic_simd</c-></code> object of type <code class="highlight"><c- n>V</c-></code>. When <code class="highlight"><c- n>Flags</c-></code> contains <code class="highlight"><c- n>simd_flag_partial_loadstore</c-></code>, the i’th element of the return value will be:</p>
     <ul>
      <li data-md>
       <p>For unmasked function: <code class="highlight"><c- n>i</c-> <c- o>&lt;</c-> <c- n>size</c-> <c- o>?</c-> <c- k>static_cast</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>value_type</c-><c- o>></c-><c- p>(</c-><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>s</c-><c- p>))[</c-><c- n>i</c-><c- p>])</c-> <c- o>?</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>value_type</c-><c- p>{}</c-></code>.</p>
      <li data-md>
       <p>For masked function: <code class="highlight"><c- p>(</c-><c- n>i</c-> <c- o>&lt;</c-> <c- n>size</c-> <c- o>&amp;&amp;</c-> <c- n>mask</c-><c- p>[</c-><c- n>i</c-><c- p>])</c-> <c- o>?</c-> <c- k>static_cast</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>value_type</c-><c- o>></c-><c- p>(</c-><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>s</c-><c- p>))[</c-><c- n>i</c-><c- p>])</c-> <c- o>?</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>value_type</c-><c- p>{}</c-></code>.</p>
     </ul>
     <p>When <code class="highlight"><c- n>Flags</c-></code> does not contain <code class="highlight"><c- n>simd_flag_partial_loadstore</c-></code>, the i’th element of the return value will be:</p>
     <ul>
      <li data-md>
       <p>For unmasked function: <code class="highlight"><c- k>static_cast</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>value_type</c-><c- o>></c-><c- p>(</c-><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>s</c-><c- p>))[</c-><c- n>i</c-><c- p>])</c-></code>.</p>
      <li data-md>
       <p>For masked function: <code class="highlight"><c- n>mask</c-><c- p>[</c-><c- n>i</c-><c- p>]</c-> <c- o>?</c-> <c- k>static_cast</c-><c- o>&lt;</c-><c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>value_type</c-><c- o>></c-><c- p>(</c-><c- n>to_address</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>begin</c-><c- p>(</c-><c- n>s</c-><c- p>))[</c-><c- n>i</c-><c- p>])</c-> <c- o>?</c-> <c- k>typename</c-> <c- nc>V</c-><c- o>::</c-><c- n>value_type</c-><c- p>{}</c-></code>.</p>
     </ul>
    </blockquote>
   </ins>
   <h3 class="heading settled" data-level="12.7" id="wording_ctad"><span class="secno">12.7. </span><span class="content">Add [<strong>simd.overview</strong>]</span><a class="self-link" href="#wording_ctad"></a></h3>
   <p>Add class template argument deduction to overview.</p>
   <p><span><b>�    [simd.overview]</b></span></p>
   <ins>
    <blockquote>
<pre class="highlight"><c- c1>// SIMD ctad.</c->
<c- k>template</c-> <c- o>&lt;</c-><c- n>contiguous</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>with</c-><c- o>-</c-><c- k>static</c-><c- o>-</c-><c- n>extent</c-> <c- n>Rg</c-><c- o>></c->
<c- n>basic_simd</c-><c- p>(</c-><c- n>Rg</c-><c- o>&amp;&amp;</c-><c- p>)</c->
  <c- o>-></c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c->
                <c- n>deduce</c-><c- o>-</c-><c- n>t</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c-> <c- k>static</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>size</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>>>></c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- n>contiguous</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>with</c-><c- o>-</c-><c- k>static</c-><c- o>-</c-><c- n>extent</c-> <c- n>Rg</c-><c- p>,</c-> <c- k>typename</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- n>basic_simd</c-><c- p>(</c-><c- n>Rg</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- n>simd_flags</c-><flags...><c- p>)</c->
  <c- o>-></c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c->
                <c- n>deduce</c-><c- o>-</c-><c- n>t</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c-> <c- k>static</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>size</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>>>></c-><c- p>;</c-></flags...></pre>
    </blockquote>
   </ins>
   <h3 class="heading settled" data-level="12.8" id="word_simd_ctad"><span class="secno">12.8. </span><span class="content">Add [<strong>simd.ctad</strong>] <code class="highlight"><c- n>basic_simd</c-></code> class template argument deduction</span><a class="self-link" href="#word_simd_ctad"></a></h3>
   <ins>
    <blockquote>
      <span><b>� <code class="highlight"><c- n>basic_simd</c-></code> class template argument deduction        [simd.ctad]</b></span> 
<pre class="highlight"><c- k>template</c-> <c- o>&lt;</c-><c- n>contiguous</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>with</c-><c- o>-</c-><c- k>static</c-><c- o>-</c-><c- n>extent</c-> <c- n>Rg</c-><c- o>></c->
<c- n>basic_simd</c-><c- p>(</c-><c- n>Rg</c-><c- o>&amp;&amp;</c-><c- p>)</c->
  <c- o>-></c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c->
                <c- n>deduce</c-><c- o>-</c-><c- n>t</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c-> <c- k>static</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>size</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>>>></c-><c- p>;</c->

<c- k>template</c-> <c- o>&lt;</c-><c- n>contiguous</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>with</c-><c- o>-</c-><c- k>static</c-><c- o>-</c-><c- n>extent</c-> <c- n>Rg</c-><c- p>,</c-> <c- k>typename</c-><c- p>...</c-> <c- n>Flags</c-><c- o>></c->
<c- n>basic_simd</c-><c- p>(</c-><c- n>Rg</c-><c- o>&amp;&amp;</c-><c- p>,</c-> <c- n>simd_flags</c-><flags...><c- p>)</c->
  <c- o>-></c-> <c- n>basic_simd</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c->
                <c- n>deduce</c-><c- o>-</c-><c- n>t</c-><c- o>&lt;</c-><c- n>ranges</c-><c- o>::</c-><c- n>range_value_t</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>></c-><c- p>,</c-> <c- k>static</c-><c- o>-</c-><c- n>range</c-><c- o>-</c-><c- n>size</c-><c- o>&lt;</c-><c- n>Rg</c-><c- o>>>></c-><c- p>;</c-></flags...></pre>
     <p><i>Constraints:</i></p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>Rg</c-></code> represents something with a compile-time constant extent which is not larger than an implementation defined maximum.</p>
      <li data-md>
       <p><code class="highlight"><c- n>Rg</c-></code> contains elements of a vectorizable type.</p>
     </ul>
     <p><i>Returns:</i></p>
     <ul>
      <li data-md>
       <p>A <code class="highlight"><c- n>basic_simd</c-></code> parameterized to have exactly the same number of elements as the statically bounded span-like type, and the same element type.</p>
     </ul>
     <p><i>Remarks:</i></p>
     <ul>
      <li data-md>
       <p>The span-like object can be a span with known compile-time, or something equivalent (e.g., a C-array with known bounds).</p>
     </ul>
    </blockquote>
   </ins>
   <p>-NOTE: Add suitable note about erroneous behaviour.</p>
   <h2 class="heading settled" data-level="13" id="polls"><span class="secno">13. </span><span class="content">Polls</span><a class="self-link" href="#polls"></a></h2>
   <h3 class="heading settled" data-level="13.1" id="poll_st_louis"><span class="secno">13.1. </span><span class="content">St Louis 2024</span><a class="self-link" href="#poll_st_louis"></a></h3>
   <p><strong>Poll</strong>: We agree with the direction of P3299R0 regarding non-member functions
for loads and stores, and a conversion operator (whether explicit or otherwise)
for ranges with static extents.</p>
   <table>
    <tbody>
     <tr>
      <th>SF
      <th>F
      <th>N
      <th>A
      <th>SA
     <tr>
      <th>6
      <th>10
      <th>1
      <th>0
      <th>0
   </table>
  </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="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-p2664r6">[P2664R6]
   <dd>Daniel Towner, Ruslan Arutyunyan. <a href="https://wg21.link/p2664r6"><cite>Proposal to extend std::simd with permutation API</cite></a>. 16 January 2024. URL: <a href="https://wg21.link/p2664r6">https://wg21.link/p2664r6</a>
   <dt id="biblio-p2876r1">[P2876R1]
   <dd>Daniel Towner, Matthias Kretz. <a href="https://wg21.link/p2876r1"><cite>Proposal to extend std::simd with more constructors and accessors</cite></a>. 22 May 2024. URL: <a href="https://wg21.link/p2876r1">https://wg21.link/p2876r1</a>
   <dt id="biblio-p3024r0">[P3024R0]
   <dd>David Sankel, Jeff Garland, Matthias Kretz, Ruslan Arutyunyan. <a href="https://wg21.link/p3024r0"><cite>Interface Directions for std::simd</cite></a>. 20231130. URL: <a href="https://wg21.link/p3024r0">https://wg21.link/p3024r0</a>
   <dt id="biblio-p3116r0">[P3116R0]
   <dd>Zach Laine. <a href="https://wg21.link/p3116r0"><cite>Policy for explicit</cite></a>. 8 February 2024. URL: <a href="https://wg21.link/p3116r0">https://wg21.link/p3116r0</a>
  </dl>