<!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>P2642R1: Padded mdspan layouts</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;
		}
		#toc .content:hover,
		#toc .content:focus {
			background: rgba(75%, 75%, 75%, .25);
			background: var(--a-hover-bg);
			border-bottom: 3px solid #054572;
			border-bottom: 3px solid var(--toclink-underline);
			margin-bottom: -3px;
		}
		#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 b0de3432c, updated Thu Oct 13 09:16:59 2022 -0700" name="generator">
  <link href="https://github.com/ORNL/cpp-proposals-pub/blob/master/layout_padded/layout_padded.bs" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
<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%;
}
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">P2642R1<br>Padded mdspan layouts</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="2022-10-15">2022-10-15</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://github.com/ORNL/cpp-proposals-pub/blob/master/layout_padded/layout_padded.bs">https://github.com/ORNL/cpp-proposals-pub/blob/master/layout_padded/layout_padded.bs</a>
     <dt class="editor">Author:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:mhoemmen@nvidia.com">Mark Hoemmen</a> (<span class="p-org org">NVIDIA</span>)
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </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>We propose two new mdspan layouts, layout_left_padded and layout_right_padded.  These are strided layouts where the leftmost resp. rightmost extent is always stride 1, but the next stride to the right resp. left can be larger than the leftmost resp. rightmost extent.  The new layouts can represent this "padding stride" as either a compile-time or a run-time value.  We also propose adding submdspan (P2630) support for these layouts, and changing P2630 so that submdspan of a layout_left resp. layout_right mdspan produces a layout_left_padded resp. layout_right_padded mdspan whenever possible.</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="#authors-and-contributors"><span class="secno">1</span> <span class="content">Authors and contributors</span></a>
     <ol class="toc">
      <li><a href="#authors"><span class="secno">1.1</span> <span class="content">Authors</span></a>
     </ol>
    <li><a href="#revision-history"><span class="secno">2</span> <span class="content">Revision history</span></a>
    <li>
     <a href="#proposed-changes-and-justification"><span class="secno">3</span> <span class="content">Proposed changes and justification</span></a>
     <ol class="toc">
      <li><a href="#summary-of-proposed-changes"><span class="secno">3.1</span> <span class="content">Summary of proposed changes</span></a>
      <li>
       <a href="#two-new-mdspan-layouts"><span class="secno">3.2</span> <span class="content">Two new mdspan layouts</span></a>
       <ol class="toc">
        <li><a href="#optimizations-over-layout_stride"><span class="secno">3.2.1</span> <span class="content">Optimizations over <code class="highlight"><c- n>layout_stride</c-></code></span></a>
        <li><a href="#new-layouts-unify-two-use-cases"><span class="secno">3.2.2</span> <span class="content">New layouts unify two use cases</span></a>
        <li><a href="#design-change-from-r0"><span class="secno">3.2.3</span> <span class="content">Design change from R0</span></a>
        <li><a href="#padding-stride-equality-for-layout-mapping-conversions"><span class="secno">3.2.4</span> <span class="content">Padding stride equality for layout mapping conversions</span></a>
       </ol>
      <li>
       <a href="#integration-with-submdspan"><span class="secno">3.3</span> <span class="content">Integration with <code class="highlight"><c- n>submdspan</c-></code></span></a>
       <ol class="toc">
        <li><a href="#layout_left_padded-and-layout_left-cases"><span class="secno">3.3.1</span> <span class="content"><code class="highlight"><c- n>layout_left_padded</c-></code> and <code class="highlight"><c- n>layout_left</c-></code> cases</span></a>
        <li><a href="#layout_right_padded-and-layout_right-cases"><span class="secno">3.3.2</span> <span class="content"><code class="highlight"><c- n>layout_right_padded</c-></code> and <code class="highlight"><c- n>layout_right</c-></code> cases</span></a>
       </ol>
      <li>
       <a href="#examples"><span class="secno">3.4</span> <span class="content">Examples</span></a>
       <ol class="toc">
        <li><a href="#directly-call-c-blas-without-checks"><span class="secno">3.4.1</span> <span class="content">Directly call C BLAS without checks</span></a>
        <li><a href="#overaligned-access"><span class="secno">3.4.2</span> <span class="content">Overaligned access</span></a>
       </ol>
      <li><a href="#alternatives"><span class="secno">3.5</span> <span class="content">Alternatives</span></a>
      <li><a href="#implementation-experience"><span class="secno">3.6</span> <span class="content">Implementation experience</span></a>
      <li><a href="#desired-ship-vehicle"><span class="secno">3.7</span> <span class="content">Desired ship vehicle</span></a>
     </ol>
    <li>
     <a href="#wording"><span class="secno">4</span> <span class="content">Wording</span></a>
     <ol class="toc">
      <li><a href="#class-template-layout_left_paddedmapping-mdspanlayoutleft_padded"><span class="secno">4.1</span> <span class="content">Class template <code class="highlight"><c- n>layout_left_padded</c-><c- o>::</c-><c- n>mapping</c-></code> [mdspan.layout.left_padded]</span></a>
      <li><a href="#class-template-layout_right_paddedmapping-mdspanlayoutright_padded"><span class="secno">4.2</span> <span class="content">Class template <code class="highlight"><c- n>layout_right_padded</c-><c- o>::</c-><c- n>mapping</c-></code> [mdspan.layout.right_padded]</span></a>
      <li><a href="#layout-specializations-of-submdspan_mapping-mdspansubmdspanmapping"><span class="secno">4.3</span> <span class="content">Layout specializations of <code class="highlight"><c- n>submdspan_mapping</c-></code> [mdspan.submdspan.mapping]</span></a>
      <li><a href="#layout-specializations-of-submdspan_offset-mdspansubmdspanoffset"><span class="secno">4.4</span> <span class="content">Layout specializations of <code class="highlight"><c- n>submdspan_offset</c-></code> [mdspan.submdspan.offset]</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="authors-and-contributors"><span class="secno">1. </span><span class="content">Authors and contributors</span><a class="self-link" href="#authors-and-contributors"></a></h2>
   <h3 class="heading settled" data-level="1.1" id="authors"><span class="secno">1.1. </span><span class="content">Authors</span><a class="self-link" href="#authors"></a></h3>
   <ul>
    <li data-md>
     <p>Mark Hoemmen (mhoemmen@nvidia.com) (NVIDIA)</p>
    <li data-md>
     <p>Christian Trott (crtrott@sandia.gov) (Sandia National Laboratories)</p>
    <li data-md>
     <p>Damien Lebrun-Grandie (lebrungrandt@ornl.gov) (Oak Ridge National Laboratory)</p>
    <li data-md>
     <p>Malte Förster (mfoerster@nvidia.com) (NVIDIA)</p>
    <li data-md>
     <p>Jiaming Yuan (jiamingy@nvidia.com) (NVIDIA)</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="revision-history"><span class="secno">2. </span><span class="content">Revision history</span><a class="self-link" href="#revision-history"></a></h2>
   <ul>
    <li data-md>
     <p>Revision 0 submitted 2022-09-14</p>
    <li data-md>
     <p>Revision 1 submitted 2022-10-15</p>
     <ul>
      <li data-md>
       <p>Change padding stride to function as an overalignment factor
if less than the extent to pad.  Remove mapping constructor
that takes <code class="highlight"><c- n>extents_type</c-></code> and <code class="highlight"><c- n>extents</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>padding_stride</c-><c- o>></c-></code>,
because the latter may not be the actual padding stride.</p>
      <li data-md>
       <p>Make converting constructors from <code class="highlight"><c- n>layout_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_padded</c-><c- o>::</c-><c- n>mapping</c-></code> to <code class="highlight"><c- n>layout_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- o>::</c-><c- n>mapping</c-></code> use Mandates rather than Constraints to check compile-time stride compatibility.</p>
      <li data-md>
       <p>Mandate that <code class="highlight"><c- n>layout_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_padded</c-><c- o>::</c-><c- n>mapping</c-></code>'s actual padding stride, if known at compile time, be representable as a value of type <code class="highlight"><c- n>index_type</c-></code> (as well as of type <code class="highlight"><c- b>size_t</c-></code>, the previous requirement).</p>
      <li data-md>
       <p>Add section explaining why we don’t permit conversion from more aligned to less aligned.</p>
      <li data-md>
       <p>Fixed typos in Wording</p>
      <li data-md>
       <p>Fix formatting in non-Wording, and add links for BLAS and LAPACK</p>
     </ul>
   </ul>
   <h2 class="heading settled" data-level="3" id="proposed-changes-and-justification"><span class="secno">3. </span><span class="content">Proposed changes and justification</span><a class="self-link" href="#proposed-changes-and-justification"></a></h2>
   <h3 class="heading settled" data-level="3.1" id="summary-of-proposed-changes"><span class="secno">3.1. </span><span class="content">Summary of proposed changes</span><a class="self-link" href="#summary-of-proposed-changes"></a></h3>
   <p>We propose two new mdspan layouts, <code class="highlight"><c- n>layout_left_padded</c-></code> and <code class="highlight"><c- n>layout_right_padded</c-></code>.
These layouts support two use cases:</p>
   <ol>
    <li data-md>
     <p>array layouts that are contiguous in one dimension,
as supported by commonly used libraries
like the <a href="https://netlib.org/blas/blast-forum/">BLAS</a> (Basic Linear Algebra Subroutines;
see P1417 and P1674 for historical overview and references)
and <a href="https://netlib.org/lapack/">LAPACK</a> (Linear Algebra PACKage); and</p>
    <li data-md>
     <p>"padded" storage for overaligned access
of the start of every contiguous segment of the array.</p>
   </ol>
   <p>We also propose changing <code class="highlight"><c- n>submdspan</c-></code> of a <code class="highlight"><c- n>layout_left</c-></code> resp. <code class="highlight"><c- n>layout_right</c-></code> mdspan
to return <code class="highlight"><c- n>layout_left_padded</c-></code> resp. <code class="highlight"><c- n>layout_right_padded</c-></code> instead of <code class="highlight"><c- n>layout_stride</c-></code>, when the slice arguments permit it.</p>
   <h3 class="heading settled" data-level="3.2" id="two-new-mdspan-layouts"><span class="secno">3.2. </span><span class="content">Two new mdspan layouts</span><a class="self-link" href="#two-new-mdspan-layouts"></a></h3>
   <p>The two new mdspan layouts <code class="highlight"><c- n>layout_left_padded</c-></code> and <code class="highlight"><c- n>layout_right_padded</c-></code> are strided, unique layouts.
If the rank is zero or one,
then the layouts behave exactly like <code class="highlight"><c- n>layout_left</c-></code> resp. <code class="highlight"><c- n>layout_right</c-></code>.
If the rank is two or more,
then the layouts implement a special case of <code class="highlight"><c- n>layout_stride</c-></code> where only one stride may differ from the extent
that in <code class="highlight"><c- n>layout_left</c-></code> resp. <code class="highlight"><c- n>layout_right</c-></code> would completely define the stride.
We call that stride the <em>padding stride</em>,
and the extent that in <code class="highlight"><c- n>layout_left</c-></code> resp. <code class="highlight"><c- n>layout_right</c-></code> would define it the <em>extent to pad</em>.
The padding stride of <code class="highlight"><c- n>layout_left_padded</c-></code> is <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>,
and the extent to pad is <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
The padding stride of <code class="highlight"><c- n>layout_right_padded</c-></code> is <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- p>)</c-></code>,
and the extent to pad is <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>.
All other strides of <code class="highlight"><c- n>layout_left_padded</c-></code> are the same as in <code class="highlight"><c- n>layout_left</c-></code>,
and all other strides of <code class="highlight"><c- n>layout_right_padded</c-></code> are the same as in <code class="highlight"><c- n>layout_right</c-></code>.</p>
   <h4 class="heading settled" data-level="3.2.1" id="optimizations-over-layout_stride"><span class="secno">3.2.1. </span><span class="content">Optimizations over <code class="highlight"><c- n>layout_stride</c-></code></span><a class="self-link" href="#optimizations-over-layout_stride"></a></h4>
   <p>The two new layouts offer the following optimizations over <code class="highlight"><c- n>layout_stride</c-></code>.</p>
   <ol>
    <li data-md>
     <p>They guarantee at compile time
that one extent always has stride-1 access.
While <code class="highlight"><c- n>layout_stride</c-></code>'s member functions are all <code class="highlight"><c- k>constexpr</c-></code>,
its mapping constructor takes the strides as a <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>array</c-></code> with <code class="highlight"><c- n>rank</c-><c- p>()</c-></code> size.</p>
    <li data-md>
     <p>They do not need to store any strides
if the padding stride is known at compile time.
Even if the padding stride is a run-time value,
these layouts only need to store the one stride value (as <code class="highlight"><c- n>index_type</c-></code>).
The <code class="highlight"><c- n>layout_stride</c-><c- o>::</c-><c- n>mapping</c-></code> class must store all <code class="highlight"><c- n>rank</c-><c- p>()</c-></code> stride values.</p>
   </ol>
   <h4 class="heading settled" data-level="3.2.2" id="new-layouts-unify-two-use-cases"><span class="secno">3.2.2. </span><span class="content">New layouts unify two use cases</span><a class="self-link" href="#new-layouts-unify-two-use-cases"></a></h4>
   <p>The proposed layouts unify two different use cases:</p>
   <ol>
    <li data-md>
     <p>overaligned access to the beginning
of each contiguous segment of elements, and</p>
    <li data-md>
     <p>representing exactly the data layout assumed by
the General (GE) matrix type in the BLAS' C binding.</p>
   </ol>
   <p>Regarding (1), an appropriate choice of padding
can ensure any desired overalignment
of the beginning of each contiguous segment of elements in an mdspan,
as long as the entire memory allocation has the same overalignment.
This is useful for hardware features that require
or perform better with overaligned access,
such as SIMD (Single Instruction Multiple Data) instructions.</p>
   <p>Regarding (2), the padding stride is the same as
BLAS' "leading dimension" of the matrix (<code class="highlight"><c- n>LDA</c-></code>) argument.
Unlike <code class="highlight"><c- n>layout_left</c-></code> and <code class="highlight"><c- n>layout_right</c-></code>,
any subview of a contiguous subset of rows and columns
of a rank-2 <code class="highlight"><c- n>layout_left_padded</c-></code> or <code class="highlight"><c- n>layout_right_padded</c-></code> mdspan
preserves the layout.
For example, if <code class="highlight"><c- n>A</c-></code> is a rank-2 mdspan
whose layout is <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-></code>,
then <code class="highlight"><c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>tuple</c-><c- p>{</c-><c- n>r1</c-><c- p>,</c-> <c- n>r2</c-><c- p>},</c-> <c- n>tuple</c-><c- p>{</c-><c- n>c1</c-><c- p>,</c-> <c- n>c2</c-><c- p>})</c-></code> also has layout <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-></code> with the same padding stride as before.
The BLAS and algorithms that use it
(such as the blocked algorithms in LAPACK)
depend on this ability to operate on contiguous submatrices
with the same layout as their parent.
For this reason, we can replace the <code class="highlight"><c- n>layout_blas_general</c-></code> layout in <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1673r9.html">P1673R9</a> with <code class="highlight"><c- n>layout_left_padded</c-></code> and <code class="highlight"><c- n>layout_right_padded</c-></code>.
Making most effective use of the new layouts in code that uses P1673
calls for integrating them with <code class="highlight"><c- n>submdspan</c-></code>.
This is why we propose the following changes as well.</p>
   <h4 class="heading settled" data-level="3.2.3" id="design-change-from-r0"><span class="secno">3.2.3. </span><span class="content">Design change from R0</span><a class="self-link" href="#design-change-from-r0"></a></h4>
   <p>A design change from R0 of this paper makes this overalignment case
easier to use and more like the existing <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>assume_aligned</c-></code> interface.
In R0 of this paper, the user’s padding input parameter
(either a compile-time <code class="highlight"><c- n>padding_stride</c-></code> or a run-time value)
was exactly the padding stride.
As such, it had to be greater than or equal to the extent to pad.
For example, if users had an <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> of 13
and wanted to overalign the corresponding <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> to a multiple of 4,
they would have had to specify <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>16</c-><c- o>></c-></code>.
This was inconsistent with <code class="highlight"><c- n>std</c-><c- o>::</c-><c- n>assume_aligned</c-></code>,
whose template argument (the byte alignment)
would need to be <code class="highlight"><c- mi>4</c-> <c- o>*</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>element_type</c-><c- p>)</c-></code>.
Also, users who wanted a compile-time padding stride
would have needed to compute it themselves
from the corresponding compile-time extent,
rather than prespecifying a fixed overalignment factor
that could be used for any extent.
This was not only harder to use, but it made the layout itself
(not just the layout mapping) depend on the extent.
That was inconsistent with the existing mdspan layouts,
where the layout type itself (e.g., <code class="highlight"><c- n>layout_left</c-></code>)
is always a function from <code class="highlight"><c- n>extents</c-></code> specialization to layout mapping.</p>
   <p>In this version of the paper,
we interpret the case where the input padding stride
is less than the extent to pad
as an "overalignment factor" instead of a stride.
To revisit the above example, <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>4</c-><c- o>></c-></code> would take an <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> of 13
and round up the corresponding <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> to 16.
However, as before, <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>17</c-><c- o>></c-></code> would take an <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> of 13
and round up the corresponding <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> to 17.
The rule is consistent: the actual padding stride is always
the next multiple of the input padding stride
greater than or equal to the extent-to-pad.</p>
   <p>In R0 of this paper, the following alias</p>
<pre class="language-c++ highlight"><c- n>using</c-> <c- n>overaligned_matrix_t</c-> <c- o>=</c->
  <c- n>mdspan</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- n>dextents</c-><c- o>&lt;</c-><c- b>size_t</c-><c- p>,</c-> <c- mi>2</c-><c- o>></c-><c- p>,</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- mi>4</c-><c- o>>></c-><c- p>;</c->
</pre>
   <p>would only be meaningful if the run-time extents are less than or equal to 4.
In this version of the paper, this alias would always mean
"the padding stride rounds up the rightmost extent to a multiple of 4,
whatever the extent may be."
R0 had no way to express that use case
with a compile-time input padding stride.
This is important for hardware features and compiler optimizations
that require overalignment of multidimensional arrays.</p>
   <h4 class="heading settled" data-level="3.2.4" id="padding-stride-equality-for-layout-mapping-conversions"><span class="secno">3.2.4. </span><span class="content">Padding stride equality for layout mapping conversions</span><a class="self-link" href="#padding-stride-equality-for-layout-mapping-conversions"></a></h4>
   <p><code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>></c-></code> has a converting constructor from <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code>.
Similarly, <code class="highlight"><c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>></c-></code> has a converting constructor from <code class="highlight"><c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code>.
These constructors require, among other conditions,
that if <code class="highlight"><c- n>padding_stride</c-></code> and <code class="highlight"><c- n>other_padding_stride</c-></code> do not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,
then <code class="highlight"><c- n>padding_stride</c-></code> equals <code class="highlight"><c- n>other_padding_stride</c-></code>.</p>
   <p>Users may ask why they can’t convert a more overaligned mapping,
such as <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>4</c-><c- o>>::</c-><c- n>mapping</c-></code>,
to a less overaligned mapping, such as <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>2</c-><c- o>>::</c-><c- n>mapping</c-></code>.
The problem is that this may not be correct for all extents.
For example, the following code would be incorrect
if it were well formed (it is not, in this proposal).</p>
<pre class="language-c++ highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>4</c-><c- o>>::</c-><c- n>mapping</c-> <c- n>m_orig</c-><c- p>{</c-><c- n>extents</c-><c- p>{</c-><c- mi>9</c-><c- p>,</c-> <c- mi>2</c-><c- p>}};</c->
<c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>2</c-><c- o>>::</c-><c- n>mapping</c-> <c- n>m_new</c-><c- p>(</c-><c- n>m_orig</c-><c- p>);</c->
</pre>
   <p>The issue is that <code class="highlight"><c- n>m_orig</c-></code> has an underlying ("physical") layout of <code class="highlight"><c- n>extents</c-><c- p>{</c-><c- mi>12</c-><c- p>,</c-> <c- mi>2</c-><c- p>}</c-></code>,
but <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>2</c-><c- o>>::</c-><c- n>mapping</c-><c- p>{</c-><c- n>extents</c-><c- p>{</c-><c- mi>9</c-><c- p>,</c-> <c- mi>2</c-><c- p>}}</c-></code> would have an underlying layout of <code class="highlight"><c- n>extents</c-><c- p>{</c-><c- mi>10</c-><c- p>,</c-> <c- mi>2</c-><c- p>}</c-></code>.
That is, <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>4</c-><c- o>>::</c-><c- n>mapping</c-><c- p>{</c-><c- n>extents</c-><c- p>{</c-><c- mi>9</c-><c- p>,</c-> <c- mi>2</c-><c- p>}}.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> is 12,
but <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>2</c-><c- o>>::</c-><c- n>mapping</c-><c- p>{</c-><c- n>extents</c-><c- p>{</c-><c- mi>9</c-><c- p>,</c-> <c- mi>2</c-><c- p>}}.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> is 10.</p>
   <p>In case one is tempted to permit
assigning dynamic padding stride to static padding stride,
the following code would also be incorrect
if it were well formed (it is not, in this proposal).
Again, <code class="highlight"><c- n>m_orig</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> is 12.</p>
<pre class="language-c++ highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>::</c-><c- n>mapping</c-> <c- n>m_orig</c-><c- p>{</c-><c- n>extents</c-><c- p>{</c-><c- mi>9</c-><c- p>,</c-> <c- mi>2</c-><c- p>},</c-> <c- mi>4</c-><c- p>};</c->
<c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>2</c-><c- o>>::</c-><c- n>mapping</c-> <c- n>m_new</c-><c- p>(</c-><c- n>m_orig</c-><c- p>);</c->
</pre>
   <p>The following code is well formed in this proposal,
and it gives <code class="highlight"><c- n>m_new</c-></code> the expected original padding stride of 12.</p>
<pre class="language-c++ highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>::</c-><c- n>mapping</c-> <c- n>m_orig</c-><c- p>{</c-><c- n>extents</c-><c- p>{</c-><c- mi>9</c-><c- p>,</c-> <c- mi>2</c-><c- p>},</c-> <c- mi>4</c-><c- p>};</c->
<c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>::</c-><c- n>mapping</c-> <c- n>m_new</c-><c- p>(</c-><c- n>m_orig</c-><c- p>);</c->
</pre>
   <p>Similarly, the following code is well formed in this proposal,
and it gives <code class="highlight"><c- n>m_new</c-></code> the expected original padding stride of 12.</p>
<pre class="language-c++ highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- mi>4</c-><c- o>>::</c-><c- n>mapping</c-> <c- n>m_orig</c-><c- p>{</c-><c- n>extents</c-><c- p>{</c-><c- mi>9</c-><c- p>,</c-> <c- mi>2</c-><c- p>}};</c->
<c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>dynamic_extent</c-><c- o>>::</c-><c- n>mapping</c-> <c- n>m_new</c-><c- p>(</c-><c- n>m_orig</c-><c- p>);</c->
</pre>
   <h3 class="heading settled" data-level="3.3" id="integration-with-submdspan"><span class="secno">3.3. </span><span class="content">Integration with <code class="highlight"><c- n>submdspan</c-></code></span><a class="self-link" href="#integration-with-submdspan"></a></h3>
   <p>We propose changing <code class="highlight"><c- n>submdspan</c-></code> (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2630r0.html">see P2630</a>)
of a <code class="highlight"><c- n>layout_left</c-></code> resp. <code class="highlight"><c- n>layout_right</c-></code> mdspan
to return <code class="highlight"><c- n>layout_left_padded</c-></code> resp. <code class="highlight"><c- n>layout_right_padded</c-></code> instead of <code class="highlight"><c- n>layout_stride</c-></code>, if the slice arguments permit it.
Taking the <code class="highlight"><c- n>submdspan</c-></code> of a <code class="highlight"><c- n>layout_left_padded</c-></code> resp. <code class="highlight"><c- n>layout_right_padded</c-></code> mdspan
will preserve the layout, again if the slice arguments permit it.</p>
   <p>The phrase "if the slice arguments permit it" means the following.</p>
   <h4 class="heading settled" data-level="3.3.1" id="layout_left_padded-and-layout_left-cases"><span class="secno">3.3.1. </span><span class="content"><code class="highlight"><c- n>layout_left_padded</c-></code> and <code class="highlight"><c- n>layout_left</c-></code> cases</span><a class="self-link" href="#layout_left_padded-and-layout_left-cases"></a></h4>
   <p>In what follows, let <code class="highlight"><c- n>left_submatrix</c-></code> be the following function,</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Elt</c-><c- p>,</c-> <c- n>class</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>class</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>class</c-> <c- n>Accessor</c-><c- p>,</c-> <c- n>class</c-> <c- n>S0</c-><c- p>,</c-> <c- n>class</c-> <c- n>S1</c-><c- o>></c->
<c- n>requires</c-><c- p>(</c->
  <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>S0</c-><c- p>,</c->
    <c- n>tuple</c-><c- o>&lt;</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-><c- p>,</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-><c- o>>></c-> <c- o>&amp;&amp;</c->
  <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>S1</c-><c- p>,</c->
    <c- n>tuple</c-><c- o>&lt;</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-><c- p>,</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-><c- o>>></c->
<c- p>)</c->
<c- k>auto</c-> <c- n>left_submatrix</c-><c- p>(</c-><c- n>mdspan</c-><c- o>&lt;</c-><c- n>Elt</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-> <c- n>X</c-><c- p>,</c-> <c- n>S0</c-> <c- n>s0</c-><c- p>,</c-> <c- n>S1</c-> <c- n>s1</c-><c- p>)</c->
<c- p>{</c->
  <c- k>auto</c-> <c- n>full_extents</c-> <c- o>=</c-> <c- p>[]</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- p>...</c-> <c- n>Indices</c-><c- o>></c-><c- p>(</c-><c- n>index_sequence</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>...</c-><c- o>></c-><c- p>)</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>tuple</c-><c- p>{</c-> <c- p>(</c-><c- n>Indices</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>)...</c-> <c- p>};</c->
    <c- p>}(</c-><c- n>make_index_sequence</c-><c- o>&lt;</c-><c- n>X</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- o>></c-><c- p>());</c->
  <c- k>return</c-> <c- n>apply</c-><c- p>(</c-> <c- p>[</c-><c- o>&amp;</c-><c- p>](</c-><c- n>full_extent_t</c-> <c- p>...</c-> <c- n>fe</c-><c- p>)</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>X</c-><c- p>,</c-> <c- n>s0</c-><c- p>,</c-> <c- n>s1</c-><c- p>,</c-> <c- n>fe</c-><c- p>...);</c->
    <c- p>},</c-> <c- n>full_extents</c-> <c- p>);</c->
<c- p>}</c->
</pre>
   <p>let <code class="highlight"><c- n>index_type</c-></code> be an integral type,
let <code class="highlight"><c- n>s0</c-></code> be an object of a type <code class="highlight"><c- n>S0</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>S0</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>,
and let <code class="highlight"><c- n>s1</c-></code> be an object of a type <code class="highlight"><c- n>S1</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>S1</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>.</p>
   <p>Let <code class="highlight"><c- n>X</c-></code> be an <code class="highlight"><c- n>mdspan</c-></code> with rank at least two
with <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>X</c-><c- p>)</c-><c- o>::</c-><c- n>index_type</c-></code> naming the same type as <code class="highlight"><c- n>index_type</c-></code>,
whose layout is <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride_X</c-><c- o>></c-></code> for some <code class="highlight"><c- k>constexpr</c-> <c- b>size_t</c-> <c- n>padding_stride_X</c-></code>.
Let <code class="highlight"><c- n>X_sub</c-></code> be the object returned from <code class="highlight"><c- n>left_submatrix</c-><c- p>(</c-><c- n>X</c-><c- p>,</c-> <c- n>s0</c-><c- p>,</c-> <c- n>s1</c-><c- p>)</c-></code>.
Then, <code class="highlight"><c- n>X_sub</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> of rank <code class="highlight"><c- n>X</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> with layout <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride_X</c-><c- o>></c-></code>,
and <code class="highlight"><c- n>X_sub</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>X</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   <p>Let <code class="highlight"><c- n>Z</c-></code> be an <code class="highlight"><c- n>mdspan</c-></code> with rank at least two
with <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>Z</c-><c- p>)</c-><c- o>::</c-><c- n>index_type</c-></code> naming the same type as <code class="highlight"><c- n>index_type</c-></code>,
whose layout is <code class="highlight"><c- n>layout_left</c-></code>.
Let <code class="highlight"><c- n>Z_sub</c-></code> be the object returned from <code class="highlight"><c- n>left_submatrix</c-><c- p>(</c-><c- n>Z</c-><c- p>,</c-> <c- n>s0</c-><c- p>,</c-> <c- n>s1</c-><c- p>)</c-></code>.
Then, <code class="highlight"><c- n>Z_sub</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> of rank <code class="highlight"><c- n>Z</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> with layout <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride_Z</c-><c- o>></c-></code>,
where <code class="highlight"><c- n>padding_stride_Z</c-></code> is</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>srm1_val1</c-> <c- o>-</c-> <c- n>srm1_val0</c-></code>, if <code class="highlight"><c- n>srm1</c-></code> is convertible to <code class="highlight"><c- n>tuple</c-><c- o>&lt;</c-><c- n>integral_constant</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- n>W</c-><c- p>)</c-><c- o>::</c-><c- n>index_type</c-><c- p>,</c-> <c- n>srm1_val0</c-><c- o>></c-><c- p>,</c-> <c- n>integral_constant</c-><c- o>&lt;</c-><c- k>decltype</c-><c- p>(</c-><c- n>W</c-><c- p>)</c-><c- o>::</c-><c- n>index_type</c-><c- p>,</c-> <c- n>srm1_val1</c-><c- o>>></c-></code> with <code class="highlight"><c- n>srm1_val1</c-></code> greater than to equal to <code class="highlight"><c- n>srm1_val0</c-></code>; else,</p>
    <li data-md>
     <p><code class="highlight"><c- n>dynamic_rank</c-></code>.</p>
   </ul>
   <p>Also, <code class="highlight"><c- n>Z_sub</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>Z</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   <h4 class="heading settled" data-level="3.3.2" id="layout_right_padded-and-layout_right-cases"><span class="secno">3.3.2. </span><span class="content"><code class="highlight"><c- n>layout_right_padded</c-></code> and <code class="highlight"><c- n>layout_right</c-></code> cases</span><a class="self-link" href="#layout_right_padded-and-layout_right-cases"></a></h4>
   <p>In what follows, let <code class="highlight"><c- n>right_submatrix</c-></code> be the following function,</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Elt</c-><c- p>,</c-> <c- n>class</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>class</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>class</c-> <c- n>Accessor</c-><c- p>,</c-> <c- n>class</c-> <c- n>Srm2</c-><c- p>,</c-> <c- n>class</c-> <c- n>Srm1</c-><c- o>></c->
<c- n>requires</c-><c- p>(</c->
  <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Srm2</c-><c- p>,</c->
    <c- n>tuple</c-><c- o>&lt;</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-><c- p>,</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-><c- o>>></c-> <c- o>&amp;&amp;</c->
  <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Srm1</c-><c- p>,</c->
    <c- n>tuple</c-><c- o>&lt;</c-><c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-><c- p>,</c-> <c- n>typename</c-> <c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-><c- o>>></c->
<c- p>)</c->
<c- k>auto</c-> <c- n>left_submatrix</c-><c- p>(</c-><c- n>mdspan</c-><c- o>&lt;</c-><c- n>Elt</c-><c- p>,</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>Layout</c-><c- p>,</c-> <c- n>Accessor</c-><c- o>></c-> <c- n>X</c-><c- p>,</c-> <c- n>Srm2</c-> <c- n>srm2</c-><c- p>,</c-> <c- n>Srm1</c-> <c- n>srm1</c-><c- p>)</c->
<c- p>{</c->
  <c- k>auto</c-> <c- n>full_extents</c-> <c- o>=</c-> <c- p>[]</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- p>...</c-> <c- n>Indices</c-><c- o>></c-><c- p>(</c-><c- n>index_sequence</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>...</c-><c- o>></c-><c- p>)</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>tuple</c-><c- p>{</c-> <c- p>(</c-><c- n>Indices</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>)...</c-> <c- p>};</c->
    <c- p>}(</c-><c- n>make_index_sequence</c-><c- o>&lt;</c-><c- n>X</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- o>></c-><c- p>());</c->
  <c- k>return</c-> <c- n>apply</c-><c- p>(</c-> <c- p>[</c-><c- o>&amp;</c-><c- p>](</c-><c- n>full_extent_t</c-> <c- p>...</c-> <c- n>fe</c-><c- p>)</c-> <c- p>{</c->
      <c- k>return</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>X</c-><c- p>,</c-> <c- n>fe</c-><c- p>...,</c-> <c- n>srm2</c-><c- p>,</c-> <c- n>srm1</c-><c- p>);</c->
    <c- p>},</c-> <c- n>full_extents</c-> <c- p>);</c->
<c- p>}</c->
</pre>
   <p>let <code class="highlight"><c- n>srm2</c-></code> ("s of rank minus 2") be an object of a type <code class="highlight"><c- n>Srm2</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>S0</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type_X</c-><c- p>,</c-> <c- n>index_type_X</c-><c- o>>></c-></code> is <code class="highlight">true</code>,
and let <code class="highlight"><c- n>srm1</c-></code> ("s of rank minus 1") be an object of a type <code class="highlight"><c- n>Srm1</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>S1</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type_X</c-><c- p>,</c-> <c- n>index_type_X</c-><c- o>>></c-></code> is <code class="highlight">true</code>.</p>
   <p>Similarly, let <code class="highlight"><c- n>Y</c-></code> be an <code class="highlight"><c- n>mdspan</c-></code> with rank at least two
whose layout is <code class="highlight"><c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride_Y</c-><c- o>></c-></code> for some <code class="highlight"><c- k>constexpr</c-> <c- b>size_t</c-> <c- n>padding_stride_Y</c-></code>.
Let <code class="highlight"><c- n>index_type_Y</c-></code> name the type <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>Y</c-><c- p>)</c-><c- o>::</c-><c- n>index_type</c-></code>.
Let <code class="highlight"><c- n>srm2</c-></code> ("S of rank minus 2") be an object of a type <code class="highlight"><c- n>Srm2</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Srm2</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type_Y</c-><c- p>,</c-> <c- n>index_type_Y</c-><c- o>>></c-></code> is <code class="highlight">true</code>,
and let <code class="highlight"><c- n>srm1</c-></code> ("S of rank minus 1") be an object of a type <code class="highlight"><c- n>Srm1</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Srm1</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type_Y</c-><c- p>,</c-> <c- n>index_type_Y</c-><c- o>>></c-></code> is <code class="highlight">true</code>.
In the following code fragment,</p>
<pre class="language-c++ highlight"><c- k>auto</c-> <c- n>full_extents</c-> <c- o>=</c-> <c- p>[]</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- p>...</c-> <c- n>Indices</c-><c- o>></c-><c- p>(</c-><c- n>index_sequence</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>...</c-><c- o>></c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>tuple</c-><c- p>{</c-> <c- p>(</c-><c- n>Indices</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>)...</c-> <c- p>};</c->
  <c- p>}(</c-><c- n>make_index_sequence</c-><c- o>&lt;</c-><c- n>Y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- o>></c-><c- p>());</c->

<c- k>auto</c-> <c- n>Y_sub</c-> <c- o>=</c-> <c- n>apply</c-><c- p>(</c-> <c- p>[</c-><c- o>&amp;</c-><c- p>](</c-><c- n>full_extent_t</c-> <c- p>...</c-> <c- n>fe</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>Y</c-><c- p>,</c-> <c- n>fe</c-><c- p>...,</c-> <c- n>srm2</c-><c- p>,</c-> <c- n>srm1</c-><c- p>);</c->
  <c- p>},</c-> <c- n>full_extents</c-> <c- p>);</c->
</pre>
   <p><code class="highlight"><c- n>Y_sub</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> of rank <code class="highlight"><c- n>Y</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> with layout <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-></code>,
and <code class="highlight"><c- n>Y_sub</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>Y</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   <p>Let <code class="highlight"><c- n>Z</c-></code> be an <code class="highlight"><c- n>mdspan</c-></code> with rank at least two whose layout is <code class="highlight"><c- n>layout_left</c-></code>.
Let <code class="highlight"><c- n>index_type_Z</c-></code> name the type <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>Z</c-><c- p>)</c-><c- o>::</c-><c- n>index_type</c-></code>.
Let <code class="highlight"><c- n>s0</c-></code> be an object of a type <code class="highlight"><c- n>S0</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>S0</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type_Z</c-><c- p>,</c-> <c- n>index_type_Z</c-><c- o>>></c-></code> is <code class="highlight">true</code>,
and let <code class="highlight"><c- n>s1</c-></code> be an object of a type <code class="highlight"><c- n>S1</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>S1</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type_Z</c-><c- p>,</c-> <c- n>index_type_Z</c-><c- o>>></c-></code> is <code class="highlight">true</code>.
In the following code fragment,</p>
<pre class="language-c++ highlight"><c- k>auto</c-> <c- n>full_extents</c-> <c- o>=</c-> <c- p>[]</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- p>...</c-> <c- n>Indices</c-><c- o>></c-><c- p>(</c-><c- n>index_sequence</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>...</c-><c- o>></c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>tuple</c-><c- p>{</c-> <c- p>(</c-><c- n>Indices</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>)...</c-> <c- p>};</c->
  <c- p>}(</c-><c- n>make_index_sequence</c-><c- o>&lt;</c-><c- n>Z</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- o>></c-><c- p>());</c->

<c- k>auto</c-> <c- n>Z_sub</c-> <c- o>=</c-> <c- n>apply</c-><c- p>(</c-> <c- p>[</c-><c- o>&amp;</c-><c- p>](</c-><c- n>full_extent_t</c-> <c- p>...</c-> <c- n>fe</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>Z</c-><c- p>,</c-> <c- n>s0</c-><c- p>,</c-> <c- n>s1</c-><c- p>,</c-> <c- n>fe</c-><c- p>...);</c->
  <c- p>},</c-> <c- n>full_extents</c-> <c- p>);</c->
</pre>
   <p><code class="highlight"><c- n>Z_sub</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> of rank <code class="highlight"><c- n>Z</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> with layout <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride_Z</c-><c- o>></c-></code>,
where <code class="highlight"><c- n>padding_stride_Z</c-></code> is <code class="highlight"><c- n>s0_val1</c-> <c- o>-</c-> <c- n>s0_val0</c-></code> if <code class="highlight"><c- n>s0</c-></code> is convertible to <code class="highlight"><c- n>tuple</c-><c- o>&lt;</c-><c- n>integral_constant</c-><c- o>&lt;</c-><c- n>index_type_Z</c-><c- p>,</c-> <c- n>s0_val0</c-><c- o>></c-><c- p>,</c-> <c- n>integral_constant</c-><c- o>&lt;</c-><c- n>index_type_Z</c-><c- p>,</c-> <c- n>s0_val1</c-><c- o>>></c-></code> with <code class="highlight"><c- n>s0_val1</c-></code> greater than to equal to <code class="highlight"><c- n>s0_val0</c-></code>.
Also, <code class="highlight"><c- n>Z_sub</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>Z</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   <p>Similarly, let <code class="highlight"><c- n>W</c-></code> be an <code class="highlight"><c- n>mdspan</c-></code> with rank at least two whose layout is <code class="highlight"><c- n>layout_right</c-></code>.
Let <code class="highlight"><c- n>index_type_W</c-></code> name the type <code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>W</c-><c- p>)</c-><c- o>::</c-><c- n>index_type</c-></code>.
Let <code class="highlight"><c- n>srm2</c-></code> ("S of rank minus 2") be an object of a type <code class="highlight"><c- n>Srm2</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Srm2</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type_W</c-><c- p>,</c-> <c- n>index_type_W</c-><c- o>>></c-></code> is <code class="highlight">true</code>,
and let <code class="highlight"><c- n>srm1</c-></code> ("S of rank minus 1") be an object of a type <code class="highlight"><c- n>Srm1</c-></code> such that <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Srm1</c-><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type_W</c-><c- p>,</c-> <c- n>index_type_W</c-><c- o>>></c-></code> is <code class="highlight">true</code>.
In the following code fragment,</p>
<pre class="language-c++ highlight"><c- k>auto</c-> <c- n>full_extents</c-> <c- o>=</c-> <c- p>[]</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- p>...</c-> <c- n>Indices</c-><c- o>></c-><c- p>(</c-><c- n>index_sequence</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>...</c-><c- o>></c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>tuple</c-><c- p>{</c-> <c- p>(</c-><c- n>Indices</c-><c- p>,</c-> <c- n>full_extent</c-><c- p>)...</c-> <c- p>};</c->
  <c- p>}(</c-><c- n>make_index_sequence</c-><c- o>&lt;</c-><c- n>W</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- o>></c-><c- p>());</c->

<c- k>auto</c-> <c- n>W_sub</c-> <c- o>=</c-> <c- n>apply</c-><c- p>(</c-> <c- p>[</c-><c- o>&amp;</c-><c- p>](</c-><c- n>full_extent_t</c-> <c- p>...</c-> <c- n>fe</c-><c- p>)</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>W</c-><c- p>,</c-> <c- n>fe</c-><c- p>...,</c-> <c- n>srm2</c-><c- p>,</c-> <c- n>srm1</c-><c- p>);</c->
  <c- p>},</c-> <c- n>full_extents</c-> <c- p>);</c->
</pre>
   <p><code class="highlight"><c- n>W_sub</c-></code> is an <code class="highlight"><c- n>mdspan</c-></code> of rank <code class="highlight"><c- n>W</c-><c- p>.</c-><c- n>rank</c-><c- p>()</c-></code> with layout <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride_W</c-><c- o>></c-></code>,
where <code class="highlight"><c- n>padding_stride_W</c-></code> is <code class="highlight"><c- n>srm1_val1</c-> <c- o>-</c-> <c- n>srm1_val0</c-></code> if <code class="highlight"><c- n>srm1</c-></code> is convertible to <code class="highlight"><c- n>tuple</c-><c- o>&lt;</c-><c- n>integral_constant</c-><c- o>&lt;</c-><c- n>index_type_W</c-><c- p>,</c-> <c- n>srm1_val0</c-><c- o>></c-><c- p>,</c-> <c- n>integral_constant</c-><c- o>&lt;</c-><c- n>index_type_W</c-><c- p>,</c-> <c- n>srm1_val1</c-><c- o>>></c-></code> with <code class="highlight"><c- n>srm1_val1</c-></code> greater than to equal to <code class="highlight"><c- n>srm1_val0</c-></code>.
Also, <code class="highlight"><c- n>W_sub</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals <code class="highlight"><c- n>W</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>.</p>
   <p>Preservation of these layouts under <code class="highlight"><c- n>submdspan</c-></code> is an important feature for our linear algebra library proposal P1673,
because it means that for existing BLAS and LAPACK use cases,
if we start with one of these layouts,
we know that we can implement fast linear algebra algorithms
by calling directly into an optimized C or Fortran BLAS.</p>
   <h3 class="heading settled" data-level="3.4" id="examples"><span class="secno">3.4. </span><span class="content">Examples</span><a class="self-link" href="#examples"></a></h3>
   <h4 class="heading settled" data-level="3.4.1" id="directly-call-c-blas-without-checks"><span class="secno">3.4.1. </span><span class="content">Directly call C BLAS without checks</span><a class="self-link" href="#directly-call-c-blas-without-checks"></a></h4>
   <p>We show examples before and after this proposal of functions
that compute the matrix-matrix product <code class="highlight"><c- n>C</c-> <c- o>+=</c-> <c- n>A</c-> <c- o>*</c-> <c- n>B</c-></code>.
The <code class="highlight"><c- n>recursive_matrix_product</c-></code> function computes this product recursively,
by partitioning each of the three matrices into a 2 x 2 block matrix
using the <code class="highlight"><c- n>partition</c-></code> function.
When the <code class="highlight"><c- n>C</c-></code> matrix is small enough, <code class="highlight"><c- n>recursive_matrix_product</c-></code> stops recursing
and instead calls a <code class="highlight"><c- n>base_case_matrix_product</c-></code> function
with different overloads for different matrix layouts.
If the matrix layouts support it, <code class="highlight"><c- n>base_case_matrix_product</c-></code> can call the C BLAS function <code class="highlight"><c- n>cblas_sgemm</c-></code> directly on the <code class="highlight"><c- n>mdspan</c-></code>s' data.
This is fast if the C BLAS is optimized.
Otherwise, <code class="highlight"><c- n>base_case_matrix_product</c-></code> falls back to a slow generic implementation.</p>
   <p>This example is far from ideally optimized,
but it hints at the kind of optimizations
that linear algebra computations do in practice.</p>
   <p>Common code:</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Layout</c-><c- o>></c->
<c- n>using</c-> <c- n>out_matrix_view</c-> <c- o>=</c-> <c- n>mdspan</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- n>dextents</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>2</c-><c- o>></c-><c- p>,</c-> <c- n>Layout</c-><c- o>></c-><c- p>;</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Layout</c-><c- o>></c->
<c- n>using</c-> <c- n>in_matrix_view</c-> <c- o>=</c-> <c- n>mdspan</c-><c- o>&lt;</c-><c- k>const</c-> <c- b>float</c-><c- p>,</c-> <c- n>dextents</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>2</c-><c- o>></c-><c- p>,</c-> <c- n>Layout</c-><c- o>></c-><c- p>;</c->

<c- c1>// Before this proposal, if Layout is layout_left or layout_right,</c->
<c- c1>// the returned mdspan would all be layout_stride.</c->
<c- c1>// After this proposal, the returned mdspan would be</c->
<c- c1>// layout_left_padded resp. layout_right_padded.</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c-> <c- n>class</c-> <c- n>Layout</c-><c- o>></c->
<c- k>auto</c-> <c- n>partition</c-><c- p>(</c-><c- n>mdspan</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>,</c-> <c- n>dextents</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>2</c-><c- o>></c-><c- p>,</c-> <c- n>Layout</c-><c- o>></c-> <c- n>A</c-><c- p>)</c->
<c- p>{</c->
  <c- k>auto</c-> <c- n>M</c-> <c- o>=</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c->
  <c- k>auto</c-> <c- n>N</c-> <c- o>=</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c->
  <c- k>auto</c-> <c- n>A00</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>tuple</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>M</c-> <c- o>/</c-> <c- mi>2</c-><c- p>},</c-> <c- n>tuple</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>N</c-> <c- o>/</c-> <c- mi>2</c-><c- p>});</c->
  <c- k>auto</c-> <c- n>A01</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>tuple</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>M</c-> <c- o>/</c-> <c- mi>2</c-><c- p>},</c-> <c- n>tuple</c-><c- p>{</c-><c- n>N</c-> <c- o>/</c-> <c- mi>2</c-><c- p>,</c-> <c- n>N</c-><c- p>});</c->
  <c- k>auto</c-> <c- n>A10</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>tuple</c-><c- p>{</c-><c- n>M</c-> <c- o>/</c-> <c- mi>2</c-><c- p>,</c-> <c- n>M</c-><c- p>},</c-> <c- n>tuple</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- n>N</c-> <c- o>/</c-> <c- mi>2</c-><c- p>});</c->
  <c- k>auto</c-> <c- n>A11</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>tuple</c-><c- p>{</c-><c- n>M</c-> <c- o>/</c-> <c- mi>2</c-><c- p>,</c-> <c- n>M</c-><c- p>},</c-> <c- n>tuple</c-><c- p>{</c-><c- n>N</c-> <c- o>/</c-> <c- mi>2</c-><c- p>,</c-> <c- n>N</c-><c- p>});</c->
  <c- k>return</c-> <c- n>tuple</c-><c- p>{</c->
    <c- n>A00</c-><c- p>,</c-> <c- n>A01</c-><c- p>,</c->
    <c- n>A10</c-><c- p>,</c-> <c- n>A11</c->
  <c- p>};</c->
<c- p>}</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Layout</c-><c- o>></c->
<c- b>void</c-> <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>in_matrix_view</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>></c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_view</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>></c-> <c- n>B</c-><c- p>,</c-> <c- n>out_matrix_view</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>></c-> <c- n>C</c-><c- p>)</c->
<c- p>{</c->
  <c- c1>// Some hardware-dependent constant</c->
  <c- n>constexpr</c-> <c- b>int</c-> <c- n>recursion_threshold</c-> <c- o>=</c-> <c- mi>16</c-><c- p>;</c->
  <c- k>if</c-><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>max</c-><c- p>(</c-><c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>||</c-> <c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>))</c-> <c- o>&lt;=</c-> <c- n>recursion_threshold</c-><c- p>)</c-> <c- p>{</c->
    <c- n>base_case_matrix_product</c-><c- p>(</c-><c- n>A</c-><c- p>,</c-> <c- n>B</c-><c- p>,</c-> <c- n>C</c-><c- p>);</c->
  <c- p>}</c-> <c- k>else</c-> <c- p>{</c->
    <c- k>auto</c-> <c- p>[</c-><c- n>C00</c-><c- p>,</c-> <c- n>C01</c-><c- p>,</c->
          <c- n>C10</c-><c- p>,</c-> <c- n>C11</c-><c- p>]</c-> <c- o>=</c-> <c- n>partition</c-><c- p>(</c-><c- n>C</c-><c- p>);</c->  
    <c- k>auto</c-> <c- p>[</c-><c- n>A00</c-><c- p>,</c-> <c- n>A01</c-><c- p>,</c->
          <c- n>A10</c-><c- p>,</c-> <c- n>A11</c-><c- p>]</c-> <c- o>=</c-> <c- n>partition</c-><c- p>(</c-><c- n>A</c-><c- p>);</c->  
    <c- k>auto</c-> <c- p>[</c-><c- n>B00</c-><c- p>,</c-> <c- n>B01</c-><c- p>,</c->
          <c- n>B10</c-><c- p>,</c-> <c- n>B11</c-><c- p>]</c-> <c- o>=</c-> <c- n>partition</c-><c- p>(</c-><c- n>B</c-><c- p>);</c->
    <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>A00</c-><c- p>,</c-> <c- n>B00</c-><c- p>,</c-> <c- n>C00</c-><c- p>);</c->
    <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>A01</c-><c- p>,</c-> <c- n>B10</c-><c- p>,</c-> <c- n>C00</c-><c- p>);</c->
    <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>A10</c-><c- p>,</c-> <c- n>B00</c-><c- p>,</c-> <c- n>C10</c-><c- p>);</c->
    <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>A11</c-><c- p>,</c-> <c- n>B10</c-><c- p>,</c-> <c- n>C10</c-><c- p>);</c->
    <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>A00</c-><c- p>,</c-> <c- n>B01</c-><c- p>,</c-> <c- n>C01</c-><c- p>);</c->
    <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>A01</c-><c- p>,</c-> <c- n>B11</c-><c- p>,</c-> <c- n>C01</c-><c- p>);</c->
    <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>A10</c-><c- p>,</c-> <c- n>B01</c-><c- p>,</c-> <c- n>C11</c-><c- p>);</c->
    <c- n>recursive_matrix_product</c-><c- p>(</c-><c- n>A11</c-><c- p>,</c-> <c- n>B11</c-><c- p>,</c-> <c- n>C11</c-><c- p>);</c->
  <c- p>}</c->
<c- p>}</c->

<c- c1>// Slow generic implementation</c->
<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Layout</c-><c- o>></c->
<c- b>void</c-> <c- n>base_case_matrix_product</c-><c- p>(</c-><c- n>in_matrix_view</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>></c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_view</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>></c-> <c- n>B</c-><c- p>,</c-> <c- n>out_matrix_view</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>></c-> <c- n>C</c-><c- p>)</c->
<c- p>{</c->
  <c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>j</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>j</c-> <c- o>&lt;</c-> <c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c-> <c- o>++</c-><c- n>j</c-><c- p>)</c-> <c- p>{</c->
    <c- k>for</c-><c- p>(</c-><c- b>size_t</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>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>);</c-> <c- o>++</c-><c- n>i</c-><c- p>)</c-> <c- p>{</c->
      <c- n>typename</c-> <c- n>out_matrix_view</c-><c- o>&lt;</c-><c- n>Layout</c-><c- o>>::</c-><c- n>value_type</c-> <c- n>C_ij</c-><c- p>{};</c->
      <c- k>for</c-><c- p>(</c-><c- b>size_t</c-> <c- n>k</c-> <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> <c- n>k</c-> <c- o>&lt;</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>);</c-> <c- o>++</c-><c- n>k</c-><c- p>)</c-> <c- p>{</c->
        <c- n>C_ij</c-> <c- o>+=</c-> <c- n>A</c-><c- p>(</c-><c- n>i</c-><c- p>,</c-><c- n>k</c-><c- p>)</c-> <c- o>*</c-> <c- n>B</c-><c- p>(</c-><c- n>k</c-><c- p>,</c-><c- n>j</c-><c- p>);</c->
      <c- p>}</c->
      <c- n>C</c-><c- p>(</c-><c- n>i</c-><c- p>,</c-><c- n>j</c-><c- p>)</c-> <c- o>+=</c-> <c- n>C_ij</c-><c- p>;</c->
    <c- p>}</c->
  <c- p>}</c->
<c- p>}</c->
</pre>
   <p>A user might interpret <code class="highlight"><c- n>layout_left</c-></code> as "column major,"
and therefore "the natural layout to pass into the BLAS."</p>
<pre class="language-c++ highlight"><c- b>void</c-> <c- nf>base_case_matrix_product</c-><c- p>(</c-><c- n>in_matrix_view</c-><c- o>&lt;</c-><c- n>layout_left</c-><c- o>></c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_view</c-><c- o>&lt;</c-><c- n>layout_left</c-><c- o>></c-> <c- n>B</c-><c- p>,</c-> <c- n>out_matrix_view</c-><c- o>&lt;</c-><c- n>layout_left</c-><c- o>></c-> <c- n>C</c-><c- p>)</c->
<c- p>{</c->
  <c- n>cblas_sgemm</c-><c- p>(</c-><c- n>CblasColMajor</c-><c- p>,</c-> <c- n>CblasNoTrans</c-><c- p>,</c-> <c- n>CblasNoTrans</c-><c- p>,</c->
    <c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>),</c-> <c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c-> <c- mf>1.0f</c-><c- p>,</c->
    <c- n>A</c-><c- p>.</c-><c- n>data_handle</c-><c- p>(),</c-> <c- n>A</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c-> <c- n>B</c-><c- p>.</c-><c- n>data_handle</c-><c- p>(),</c-> <c- n>B</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c->
    <c- mf>1.0f</c-><c- p>,</c-> <c- n>C</c-><c- p>.</c-><c- n>data_handle</c-><c- p>(),</c-> <c- n>C</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
<c- p>}</c->
</pre>
   <p>However, <code class="highlight"><c- n>recursive_matrix_product</c-></code> never gets to use
the <code class="highlight"><c- n>layout_left</c-></code> overload of <code class="highlight"><c- n>base_case_matrix_product</c-></code>,
because the base case matrices are always <code class="highlight"><c- n>layout_stride</c-></code>.</p>
   <p>On discovering this, the author of these functions
might be tempted to write a custom layout for "BLAS-compatible" matrices.
However, the <code class="highlight"><c- n>submdspan</c-></code> proposal <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2630r0.html">P2630R0</a> currently forces <code class="highlight"><c- n>partition</c-></code> to return four <code class="highlight"><c- n>layout_stride</c-></code> mdspan
if given a <code class="highlight"><c- n>layout_left</c-></code> (or <code class="highlight"><c- n>layout_right</c-></code>) input mdspan.
This would, in turn, force users of <code class="highlight"><c- n>recursive_matrix_product</c-></code> to commit to a custom layout, if they want to use the BLAS.</p>
   <p>Alternately, the author of these functions could specialize <code class="highlight"><c- n>base_case_matrix_product</c-></code> for <code class="highlight"><c- n>layout_stride</c-></code>, and check whether <code class="highlight"><c- n>A</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, <code class="highlight"><c- n>B</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, and <code class="highlight"><c- n>C</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> are all equal to one
before calling <code class="highlight"><c- n>cblas_sgemm</c-></code>.
However, that would force extra run-time checks for a use case
that most users might never encounter,
because most users are starting with <code class="highlight"><c- n>layout_left</c-></code> matrices
or contiguous submatrices thereof.</p>
   <p>After our proposal, the author can specialize <code class="highlight"><c- n>base_case_matrix_product</c-></code> for exactly the layout supported by the BLAS.
They could even get rid of the fall-back implementation
if users never exercise it.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>p</c-><c- o>></c->
<c- b>void</c-> <c- n>base_case_matrix_product</c-><c- p>(</c-><c- n>in_matrix_view</c-><c- o>&lt;</c-><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>p</c-><c- o>>></c-> <c- n>A</c-><c- p>,</c->
  <c- n>in_matrix_view</c-><c- o>&lt;</c-><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>p</c-><c- o>>></c-> <c- n>B</c-><c- p>,</c->
  <c- n>out_matrix_view</c-><c- o>&lt;</c-><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>p</c-><c- o>>></c-> <c- n>C</c-><c- p>)</c->
<c- p>{</c-> <c- c1>// same code as above</c->
  <c- n>cblas_sgemm</c-><c- p>(</c-><c- n>CblasColMajor</c-><c- p>,</c-> <c- n>CblasNoTrans</c-><c- p>,</c-> <c- n>CblasNoTrans</c-><c- p>,</c->
    <c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>),</c-> <c- n>C</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c-> <c- n>A</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c-> <c- mf>1.0f</c-><c- p>,</c->
    <c- n>A</c-><c- p>.</c-><c- n>data_handle</c-><c- p>(),</c-> <c- n>A</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c-> <c- n>B</c-><c- p>.</c-><c- n>data_handle</c-><c- p>(),</c-> <c- n>B</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c->
    <c- mf>1.0f</c-><c- p>,</c-> <c- n>C</c-><c- p>.</c-><c- n>data_handle</c-><c- p>(),</c-> <c- n>C</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>));</c->
<c- p>}</c->
</pre>
   <h4 class="heading settled" data-level="3.4.2" id="overaligned-access"><span class="secno">3.4.2. </span><span class="content">Overaligned access</span><a class="self-link" href="#overaligned-access"></a></h4>
   <p>By combining these new layouts with an accessor
that ensures overaligned access,
we can create an mdspan for which the beginning
of every contiguous segment of elements
is overaligned by some given factor.
This can enable use of hardware features 
that require overaligned memory access.</p>
   <p>The following <code class="highlight"><c- n>aligned_accessor</c-></code> class template
(which this proposal does <em>not</em> propose to add to the C++ Standard Library)
uses the C++ Standard Library function <code class="highlight"><c- n>assume_aligned</c-></code> to decorate pointer access.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>byte_alignment</c-><c- o>></c->
<c- k>struct</c-> <c- nc>aligned_accessor</c-> <c- p>{</c->
  <c- c1>// Even if a pointer p is aligned, p + i might not be.</c->
  <c- n>using</c-> <c- n>offset_policy</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>default_accessor</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- o>></c-><c- p>;</c->

  <c- n>using</c-> <c- n>element_type</c-> <c- o>=</c-> <c- n>ElementType</c-><c- p>;</c->
  <c- n>using</c-> <c- n>reference</c-> <c- o>=</c-> <c- n>ElementType</c-><c- o>&amp;</c-><c- p>;</c->
  <c- c1>// Some implementations might have an easier time optimizing</c->
  <c- c1>// if this class applies an attribute to the pointer type.</c->
  <c- c1>// Examples of attributes include</c->
  <c- c1>// __declspec(align_value(byte_alignment))</c->
  <c- c1>// and</c->
  <c- c1>// __attribute__((align_value(byte_alignment))).</c->
  <c- n>using</c-> <c- n>data_handle_type</c-> <c- o>=</c-> <c- n>ElementType</c-><c- o>*</c-><c- p>;</c->

  <c- n>constexpr</c-> <c- nf>aligned_accessor</c-><c- p>()</c-> <c- n>noexcept</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->

  <c- c1>// A feature of default_accessor that permits</c->
  <c- c1>// conversion from nonconst to const.</c->
  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>OtherElementType</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>other_byte_alignment</c-><c- o>></c->
  <c- n>requires</c-> <c- p>(</c->
    <c- n>std</c-><c- o>::</c-><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherElementType</c-><c- p>(</c-><c- o>*</c-><c- p>)[],</c-> <c- n>element_type</c-><c- p>(</c-><c- o>*</c-><c- p>)[]</c-><c- o>></c-> <c- o>&amp;&amp;</c->
    <c- n>other_byte_alignment</c-> <c- o>==</c-> <c- n>byte_alignment</c-><c- p>)</c->
  <c- n>constexpr</c-> <c- n>aligned_accessor</c-><c- p>(</c->
    <c- n>aligned_accessor</c-><c- o>&lt;</c-><c- n>OtherElementType</c-><c- p>,</c-> <c- n>other_byte_alignment</c-><c- o>></c-><c- p>)</c-> <c- n>noexcept</c->
  <c- p>{}</c->

  <c- n>constexpr</c-> <c- n>reference</c->
  <c- n>access</c-><c- p>(</c-><c- n>data_handle_type</c-> <c- n>p</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>std</c-><c- o>::</c-><c- n>assume_aligned</c-><c- o>&lt;</c-> <c- n>byte_alignment</c-> <c- o>></c-><c- p>(</c-><c- n>p</c-><c- p>)[</c-><c- n>i</c-><c- p>];</c->
  <c- p>}</c->

  <c- n>constexpr</c-> <c- n>typename</c-> <c- n>offset_policy</c-><c- o>::</c-><c- n>data_handle_type</c->
  <c- n>offset</c-><c- p>(</c-><c- n>data_handle_type</c-> <c- n>p</c-><c- p>,</c-> <c- b>size_t</c-> <c- n>i</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-> <c- p>{</c->
    <c- k>return</c-> <c- n>p</c-> <c- o>+</c-> <c- n>i</c-><c- p>;</c->
  <c- p>}</c->
<c- p>};</c->
</pre>
   <p>We include some helper functions for making overaligned array allocations.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- o>></c->
<c- k>struct</c-> <c- nc>delete_raw</c-> <c- p>{</c->
  <c- b>void</c-> <c- nf>operator</c-><c- p>()(</c-><c- n>ElementType</c-><c- o>*</c-> <c- n>p</c-><c- p>)</c-> <c- k>const</c-> <c- p>{</c->
    <c- n>std</c-><c- o>::</c-><c- n>free</c-><c- p>(</c-><c- n>p</c-><c- p>);</c->
  <c- p>}</c->
<c- p>};</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- o>></c->
<c- n>using</c-> <c- n>allocation_t</c-> <c- o>=</c->
  <c- n>std</c-><c- o>::</c-><c- n>unique_ptr</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- p>[],</c-> <c- n>delete_raw</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- o>>></c-><c- p>;</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>ElementType</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>byte_alignment</c-><c- o>></c->
<c- n>allocation_t</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- o>></c->
<c- n>allocate_raw</c-><c- p>(</c-><c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>num_elements</c-><c- p>)</c->
<c- p>{</c->
  <c- k>const</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>num_bytes</c-> <c- o>=</c-> <c- n>num_elements</c-> <c- o>*</c-> <c- k>sizeof</c-><c- p>(</c-><c- n>ElementType</c-><c- p>);</c->
  <c- b>void</c-><c- o>*</c-> <c- n>ptr</c-> <c- o>=</c-> <c- n>std</c-><c- o>::</c-><c- n>aligned_alloc</c-><c- p>(</c-><c- n>byte_alignment</c-><c- p>,</c-> <c- n>num_bytes</c-><c- p>);</c->
  <c- k>return</c-> <c- p>{</c-><c- n>ptr</c-><c- p>,</c-> <c- n>delete_raw</c-><c- o>&lt;</c-><c- n>ElementType</c-><c- o>></c-><c- p>{}};</c->
<c- p>}</c->
</pre>
   <p>Now we can show our example.
This 15 x 17 matrix of <code class="highlight"><c- b>float</c-></code> will have extra padding so that
every column is aligned to <code class="highlight"><c- mi>8</c-> <c- o>*</c-> <c- k>sizeof</c-><c- p>(</c-><c- b>float</c-><c- p>)</c-></code> bytes.
We can use the layout mapping to determine
the required storage size (including padding).
Users can then prove at compile time
that they can use special hardware features
that require overaligned access
and/or assume that the padding element
at the end of each column is accessible memory.</p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>element_alignment</c-> <c- o>=</c-> <c- mi>8</c-><c- p>;</c->
<c- n>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>byte_alignment</c-> <c- o>=</c-> <c- n>element_alignment</c-> <c- o>*</c-> <c- k>sizeof</c-><c- p>(</c-><c- b>float</c-><c- p>);</c->

<c- n>using</c-> <c- n>layout_type</c-> <c- o>=</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>element_alignment</c-><c- o>></c-><c- p>;</c->
<c- n>layout_type</c-><c- o>::</c-><c- n>mapping</c-> <c- n>mapping</c-><c- p>{</c-><c- n>dextents</c-><c- o>&lt;</c-><c- b>int</c-><c- p>,</c-> <c- mi>2</c-><c- o>></c-><c- p>{</c-><c- mi>15</c-><c- p>,</c-> <c- mi>17</c-><c- p>}};</c->
<c- k>auto</c-> <c- n>allocation</c-> <c- o>=</c->
  <c- n>allocate_raw</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- n>byte_alignment</c-><c- o>></c-><c- p>(</c-><c- n>mapping</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>());</c->

<c- n>using</c-> <c- n>accessor_type</c-> <c- o>=</c-> <c- n>aligned_accessor</c-><c- o>&lt;</c-><c- b>float</c-><c- p>,</c-> <c- n>byte_alignment</c-><c- o>></c-><c- p>;</c->
<c- n>mdspan</c-> <c- n>m</c-><c- p>{</c-><c- n>allocation</c-><c- p>.</c-><c- n>get</c-><c- p>(),</c-> <c- n>mapping</c-><c- p>,</c-> <c- n>accessor_type</c-><c- p>{}};</c->

<c- c1>// m_sub has the same layout as m,</c->
<c- c1>// and each column of m_sub has the same overalignment.</c->
<c- k>auto</c-> <c- n>m_sub</c-> <c- o>=</c-> <c- n>submdspan</c-><c- p>(</c-><c- n>m</c-><c- p>,</c-> <c- n>tuple</c-><c- p>{</c-><c- mi>0</c-><c- p>,</c-> <c- mi>11</c-><c- p>},</c-> <c- n>tuple</c-><c- p>{</c-><c- mi>1</c-><c- p>,</c-> <c- mi>13</c-><c- p>});</c-> 
</pre>
   <h3 class="heading settled" data-level="3.5" id="alternatives"><span class="secno">3.5. </span><span class="content">Alternatives</span><a class="self-link" href="#alternatives"></a></h3>
   <p>We considered a variant of <code class="highlight"><c- n>layout_stride</c-></code> that could encode
any combination of compile-time or run-time strides in the layout type.
This could, for example, use the same mechanism that <code class="highlight"><c- n>extents</c-></code> uses.
(The reference implementation calls this mechanism a "partially static array.")
However, we rejected this approach as overly complex for our design goals.</p>
   <p>First, the goal of <code class="highlight"><c- n>layout_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_padded</c-></code> isn’t to insist even harder
that the compiler bake constants into <code class="highlight"><c- n>mapping</c-><c- o>::</c-><c- k>operator</c-><c- p>()</c-></code> evaluation.
The goal is to communicate compile-time information to <em>users</em>.
The most benefit comes not just from knowing the padding stride at compile time,
but also from knowing that one dimension always uses stride-one (contiguous) storage.
Putting these two pieces of information together
lets users apply compiler annotations like <code class="highlight"><c- n>assume_aligned</c-></code>,
as in the above <code class="highlight"><c- n>aligned_accessor</c-></code> example.
Knowing that one dimension always uses contiguous storage
also tells users that they can pass the mdspan’s data
directly into C or Fortran libraries like the BLAS or LAPACK.
Users can benefit from this even if the padding stride is a run-time value.</p>
   <p>Second, the <code class="highlight"><c- k>constexpr</c-></code> annotations in the existing layout mappings
mean that users might be evaluating <code class="highlight"><c- n>layout_stride</c-><c- o>::</c-><c- n>mapping</c-><c- o>::</c-><c- k>operator</c-><c- p>()</c-></code> fully at compile time.  The reference mdspan implementation has <a href="https://github.com/kokkos/mdspan/tree/stable/compilation_tests">several tests</a> that demonstrate this by using the result of a layout mapping evaluation
in a context where it needs to be known at compile time.</p>
   <p>
    Third, the performance benefit of storing 
    <it>some</it>
     strides
as compile-time constants goes down as the rank increases,
because most of the strides would end up depending on run-time values anyway.
Strided mdspan generally come from a subview
of an existing <code class="highlight"><c- n>layout_left</c-></code> or <code class="highlight"><c- n>layout_right</c-></code> mdspan.
In that case, the representation of the strides
that preserves the most compile-time information
would be just the original mdspan’s <code class="highlight"><c- n>extents_type</c-></code> object.
(Compare to the exposition-only 
    <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
     which we use in the wording for <code class="highlight"><c- n>layout_</c-><c- p>{</c-><c- n>left</c-><c- p>,</c-><c- n>right</c-><c- p>}</c-><c- n>_padded</c-></code>.)
Computing each stride would then call for a forward (for <code class="highlight"><c- n>layout_left</c-></code>)
or reverse (for <code class="highlight"><c- n>layout_right</c-></code>) product of the original mdspan’s extents.
As a result, any stride to the right resp. left of a run-time extent
would end up depending on that run-time extent anyway.
The larger the rank, the more strides get "touched" by run-time information.
   </p>
   <p>Fourth, a strided mdspan that can represent layouts as general as <code class="highlight"><c- n>layout_stride</c-></code>,
but has entirely compile-time extents <em>and</em> strides,
could be useful for supporting features of a specific computer architecture.
However, these hardware features would probably have limitations
that would prevent them from supporting general strided layouts anyway.
For example, they might require strides to be a power of two,
or they might be limited to specific ranges of extents or strides.
These limitations would call for custom implementation-specific layouts,
not something as general as a "compile-time <code class="highlight"><c- n>layout_stride</c-></code>."</p>
   <h3 class="heading settled" data-level="3.6" id="implementation-experience"><span class="secno">3.6. </span><span class="content">Implementation experience</span><a class="self-link" href="#implementation-experience"></a></h3>
   <p>Pull request <a href="https://github.com/kokkos/mdspan/pull/180">180</a> in the <a href="https://github.com/kokkos/mdspan/">reference mdspan implementation</a> implements most of this proposal.
Next steps are to add constructors to the existing layout mappings,
and to add <code class="highlight"><c- n>submdspan</c-></code> support for the new layouts.</p>
   <h3 class="heading settled" data-level="3.7" id="desired-ship-vehicle"><span class="secno">3.7. </span><span class="content">Desired ship vehicle</span><a class="self-link" href="#desired-ship-vehicle"></a></h3>
   <p>C++26 / IS.</p>
   <h2 class="heading settled" data-level="4" id="wording"><span class="secno">4. </span><span class="content">Wording</span><a class="self-link" href="#wording"></a></h2>
   <blockquote>
    <p>Text in blockquotes is not proposed wording, but rather instructions for generating proposed wording.
The � character is used to denote a placeholder section number which the editor shall determine.
First, apply all wording from P2630R0.
(This proposal is a "rebase" atop the changes proposed by P2630R0.)</p>
   </blockquote>
   <blockquote>
    <p>Add the following feature test macro to <em>[version.syn]</em>,
replacing YYYYMML with the integer literal
encoding the appropriate year (YYYY) and month (MM).</p>
   </blockquote>
<pre class="language-c++ highlight"><c- cp>#define __cpp_lib_mdspan_layout_padded YYYYMML </c-><c- c1>// also in &lt;mdspan></c->
</pre>
   <blockquote>
    <p>In Section � <em>[mdspan.syn]</em>, after <code class="highlight"><c- k>struct</c-> <c- nc>layout_stride</c-><c- p>;</c-></code>, add the following:</p>
   </blockquote>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>padding_stride</c-> <c- o>=</c-> <c- n>dynamic_extent</c-><c- o>></c->
<c- k>struct</c-> <c- nc>layout_left_padded</c-><c- p>;</c->
<c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>padding_stride</c-> <c- o>=</c-> <c- n>dynamic_extent</c-><c- o>></c->
<c- k>struct</c-> <c- nc>layout_right_padded</c-><c- p>;</c->
</pre>
   <blockquote>
    <p>In Section � <em>[mdspan.layout.left.overview]</em> ("Overview"), add the following constructor to the <code class="highlight"><c- n>layout_left</c-><c- o>::</c-><c- n>mapping</c-></code> class declaration, between the constructor converting from <code class="highlight"><c- n>layout_right</c-><c- o>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code> and the constructor converting from <code class="highlight"><c- n>layout_stride</c-><c- o>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code>:</p>
   </blockquote>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
  <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-><c- n>not</c-> <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>></c-><c- p>)</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <blockquote>
    <p>In Section � <em>[mdspan.layout.left.cons]</em> ("Constructors"), add the following between the constructor converting from <code class="highlight"><c- n>layout_right</c-><c- o>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code> and the constructor converting from <code class="highlight"><c- n>layout_stride</c-><c- o>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code>:</p>
   </blockquote>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
  <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-><c- n>not</c-> <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>></c-><c- p>)</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Constraints:</em> <code class="highlight"><c- n>is_constructible_v</c-><c- o>&lt;</c-><c- n>extents_type</c-><c- p>,</c-> <c- n>OtherExtents</c-><c- o>></c-></code> is <code class="highlight">true</code>.</p>
   <p><em>Mandates:</em> If</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one,</p>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,</p>
    <li data-md>
     <p><code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>other_padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,</p>
   </ul>
   <p>then the least multiple of <code class="highlight"><c- n>other_padding_stride</c-></code> greater than or equal to <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code></p>
   <ul>
    <li data-md>
     <p>is representable as a value of type <code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-></code>, and</p>
    <li data-md>
     <p>equals <code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
   </ul>
   <p><em>Preconditions:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one, then <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>;</p>
    <li data-md>
     <p>if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>></c-> <c- mi>0</c-></code> is <code class="highlight">true</code>, then for all $r$ in the range [0, <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code>), <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-></code> $r$ <code class="highlight"><c- p>)</c-></code> equals <code class="highlight"><c- n>extents</c-><c- p>().</c-></code><code class="highlight" data-span-tag="_"><c- n>fwd</c-><c- o>-</c-><c- n>prod</c-><c- o>-</c-><c- n>of</c-><c- o>-</c-><c- n>extents</c-></code><code class="highlight" data-span-tag="_"><c- p>(</c-></code> $r$ <code class="highlight"><c- p>)</c-></code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>()</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code> (<em>[basic.fundamental]</em>).</p>
   </ul>
   <p><em>Effects:</em> Direct-non-list-initializes <code class="highlight"><c- n>extents_</c-></code> with <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>()</c-></code>.</p>
   <blockquote>
    <p>In Section � <em>[mdspan.layout.right.overview]</em> ("Overview"), add the following constructor to the <code class="highlight"><c- n>layout_right</c-><c- o>::</c-><c- n>mapping</c-></code> class declaration, between the constructor converting from <code class="highlight"><c- n>layout_left</c-><c- o>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code> and the constructor converting from <code class="highlight"><c- n>layout_stride</c-><c- o>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code>:</p>
   </blockquote>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
  <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-><c- n>not</c-> <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>></c-><c- p>)</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <blockquote>
    <p>In Section � <em>[mdspan.layout.right.cons]</em> ("Constructors"), add the following between the constructor converting from <code class="highlight"><c- n>layout_left</c-><c- o>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code> and the constructor converting from <code class="highlight"><c- n>layout_stride</c-><c- o>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>></c-></code>:</p>
   </blockquote>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
  <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-><c- n>not</c-> <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>></c-><c- p>)</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Constraints:</em> <code class="highlight"><c- n>is_constructible_v</c-><c- o>&lt;</c-><c- n>extents_type</c-><c- p>,</c-> <c- n>OtherExtents</c-><c- o>></c-></code> is <code class="highlight">true</code>.</p>
   <p><em>Mandates:</em> If</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one,</p>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,</p>
    <li data-md>
     <p><code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>other_padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,</p>
   </ul>
   <p>then the least multiple of <code class="highlight"><c- n>other_padding_stride</c-></code> greater than or equal to <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code></p>
   <ul>
    <li data-md>
     <p>is representable as a value of type <code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>index_type</c-></code>, and</p>
    <li data-md>
     <p>equals <code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>.</p>
   </ul>
   <p><em>Preconditions:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one, then <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- p>)</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>;</p>
    <li data-md>
     <p>if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>></c-> <c- mi>0</c-></code> is <code class="highlight">true</code>, then for all $r$ in the range [0, <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code>), <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-></code> $r$ <code class="highlight"><c- p>)</c-></code> equals <code class="highlight"><c- n>extents</c-><c- p>().</c-></code><code class="highlight" data-span-tag="_"><c- n>rev</c-><c- o>-</c-><c- n>prod</c-><c- o>-</c-><c- n>of</c-><c- o>-</c-><c- n>extents</c-></code><code class="highlight" data-span-tag="_"><c- p>(</c-></code> $r$ <code class="highlight"><c- p>)</c-></code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>()</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code> (<em>[basic.fundamental]</em>).</p>
   </ul>
   <p><em>Effects:</em> Direct-non-list-initializes <code class="highlight"><c- n>extents_</c-></code> with <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>()</c-></code>.</p>
   <blockquote>
    <p>After the end of Section � <em>[mdspan.layout.stride]</em>, add the following:</p>
   </blockquote>
   <h3 class="heading settled" data-level="4.1" id="class-template-layout_left_paddedmapping-mdspanlayoutleft_padded"><span class="secno">4.1. </span><span class="content">Class template <code class="highlight"><c- n>layout_left_padded</c-><c- o>::</c-><c- n>mapping</c-></code> [mdspan.layout.left_padded]</span><a class="self-link" href="#class-template-layout_left_paddedmapping-mdspanlayoutleft_padded"></a></h3>
   <p><code class="highlight"><c- n>layout_left_padded</c-></code> provides a layout mapping
that behaves like <code class="highlight"><c- n>layout_left</c-><c- o>::</c-><c- n>mapping</c-></code>,
except that the <em>padding stride</em> <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> can be greater than or equal to <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
Users provide an input padding stride value
either as a <code class="highlight"><c- b>size_t</c-></code> template parameter <code class="highlight"><c- n>padding_stride</c-></code> of <code class="highlight"><c- n>layout_left_padded</c-></code>,
or as a run-time argument of <code class="highlight"><c- n>layout_left_padded</c-><c- o>::</c-><c- n>mapping</c-></code>'s constructor.
The padding stride is the least multiple of the input padding stride value
greater than or equal to <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>padding_stride</c-> <c- o>=</c-> <c- n>dynamic_extent</c-><c- o>></c->
<c- k>struct</c-> <c- nc>layout_left_padded</c-> <c- p>{</c->
  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- o>></c->
  <c- n>class</c-> <c- n>mapping</c-> <c- p>{</c->
  <c- n>public</c-><c- o>:</c->
    <c- n>using</c-> <c- n>extents_type</c-> <c- o>=</c-> <c- n>Extents</c-><c- p>;</c->
    <c- n>using</c-> <c- n>index_type</c-> <c- o>=</c-> <c- n>typename</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>index_type</c-><c- p>;</c->
    <c- n>using</c-> <c- n>size_type</c-> <c- o>=</c-> <c- n>typename</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>size_type</c-><c- p>;</c->
    <c- n>using</c-> <c- n>rank_type</c-> <c- o>=</c-> <c- n>typename</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>rank_type</c-><c- p>;</c->
    <c- n>using</c-> <c- n>layout_type</c-> <c- o>=</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-><c- p>;</c->

  <c- n>private</c-><c- o>:</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>size_t</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>actual</c-><c- o>-</c-><c- n>padding</c-><c- o>-</c-><c- n>stride</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->

    <c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
    <c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
    <c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c->
      <c- n>layout_left</c-><c- o>::</c-><c- n>template</c-> <c- n>mapping</c-><c- o>&lt;&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>>></c-><c- p>;</c-> <c- c1>// exposition only</c->

    <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-><c- p>;</c-> <c- c1>// exposition only</c->
    <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-><c- p>;</c-> <c- c1>// exposition only</c->

  <c- n>public</c-><c- o>:</c->
    <c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>extents_type</c-><c- o>&amp;</c-> <c- n>ext</c-><c- p>);</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Size</c-><c- o>></c->
    <c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>extents_type</c-><c- o>&amp;</c-> <c- n>ext</c-><c- p>,</c-> <c- n>Size</c-> <c- n>padding_value</c-><c- p>);</c->

    <c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
      <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-> <c- d>/* see below */</c-> <c- p>)</c->
        <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-><c- p>);</c->

    <c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
      <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-><c- n>not</c-> <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>></c-><c- p>)</c->
        <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- nf>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&amp;</c-><c- p>)</c-> <c- n>noexcept</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
    <c- n>mapping</c-><c- o>&amp;</c-> <c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&amp;</c-><c- p>)</c-> <c- n>noexcept</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>extents_type</c-> <c- n>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- o>></c->
    <c- n>strides</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>index_type</c-> <c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Indices</c-><c- o>></c->
    <c- n>constexpr</c-> <c- b>size_t</c-> <c- n>operator</c-><c- p>()(</c-><c- n>Indices</c-><c- p>...</c-> <c- n>idxs</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_unique</c-><c- p>()</c-> <c- n>noexcept</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_exhaustive</c-><c- p>()</c-> <c- n>noexcept</c-><c- p>;</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_strided</c-><c- p>()</c-> <c- n>noexcept</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_unique</c-><c- p>()</c-> <c- n>noexcept</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->
    <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_exhaustive</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_strided</c-><c- p>()</c-> <c- n>noexcept</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->

    <c- n>constexpr</c-> <c- n>index_type</c-> <c- n>stride</c-><c- p>(</c-><c- n>rank_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
  <c- p>};</c->
<c- p>};</c->
</pre>
   <p>Throughout this section, let <code class="highlight"><c- n>P_left</c-></code> be the following
size <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> parameter pack of <code class="highlight"><c- b>size_t</c-></code>:</p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one, then the empty parameter pack;</p>
    <li data-md>
     <p>else, the parameter pack <code class="highlight"><c- b>size_t</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>, <code class="highlight"><c- b>size_t</c-><c- p>(</c-><c- mi>2</c-><c- p>)</c-></code>, ..., <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-></code>.</p>
   </ul>
   <p><em>Mandates:</em> If</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one,</p>
    <li data-md>
     <p><code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,</p>
   </ul>
   <p>then the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> that is greater than or equal to <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> is representable as a value of type <code class="highlight"><c- b>size_t</c-></code>,
and is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>.</p>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>size_t</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>actual</c-><c- o>-</c-><c- n>padding</c-><c- o>-</c-><c- n>stride</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
</pre>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one, then <code class="highlight"><c- n>padding_stride</c-></code>.</p>
    <li data-md>
     <p>Else, if</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code> and</p>
      <li data-md>
       <p><code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,</p>
     </ul>
     <p>then the <code class="highlight"><c- b>size_t</c-></code> value which is the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> that is greater than or equal to <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p>Otherwise, <code class="highlight"><c- n>dynamic_extent</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
</pre>
   <ul>
    <li data-md>
     <p>
      If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one,
then 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-></code></it>
       names the type <code class="highlight"><c- n>extents_type</c-></code>.
     </p>
    <li data-md>
     <p>
      Otherwise, 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-></code></it>
       names the type <code class="highlight"><c- n>extents</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-></code> 
      <it><code class="highlight"><c- n>actual</c-><c- o>-</c-><c- n>padding</c-><c- o>-</c-><c- n>stride</c-></code></it>
       <code class="highlight"><c- p>,</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>P_left</c-><c- p>)...</c-><c- o>></c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
</pre>
   <ul>
    <li data-md>
     <p>
      If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero,
then 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-></code></it>
       names the type <code class="highlight"><c- n>extents</c-><c- o>&lt;</c-><c- n>index_type</c-><c- o>></c-></code>.
     </p>
    <li data-md>
     <p>
      Otherwise, 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-></code></it>
       names the type <code class="highlight"><c- n>extents</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-><c- o>></c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- nf>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>extents_type</c-><c- o>&amp;</c-> <c- n>ext</c-><c- p>);</c->
</pre>
   <p><em>Preconditions:</em> If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one
and <code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,
then the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> greater than to equal to <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>.</p>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>
      Direct-non-list-initializes 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
       with:
     </p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>ext</c-></code>, if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero or one; else,</p>
      <li data-md>
       <p><code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>),</c-> <c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>P_left</c-><c- p>)...</c-></code>,
if <code class="highlight"><c- n>padding_stride</c-></code> is <code class="highlight"><c- n>dynamic_extent</c-></code>; else,</p>
      <li data-md>
       <p><code class="highlight"><c- n>S_left</c-><c- p>,</c-> <c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>P_left</c-><c- p>)...</c-></code>, where <code class="highlight"><c- n>S_left</c-></code> is the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> greater than or equal to <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>; and</p>
     </ul>
    <li data-md>
     <p>
      if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, value-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      ;
else, direct-non-list-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
       with <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Size</c-><c- o>></c->
<c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>extents_type</c-><c- o>&amp;</c-> <c- n>ext</c-><c- p>,</c-> <c- n>Size</c-> <c- n>padding_value</c-><c- p>);</c->
</pre>
   <p><em>Constraints:</em></p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Size</c-><c- p>,</c-> <c- n>index_type</c-><c- o>></c-></code> is <code class="highlight">true</code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_nothrow_constructible_v</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>Size</c-><c- o>></c-></code> is <code class="highlight">true</code>.</p>
   </ul>
   <p><em>Preconditions:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>, then</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>padding_value</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>, and</p>
      <li data-md>
       <p>the result of converting <code class="highlight"><c- n>padding_value</c-></code> to <code class="highlight"><c- n>index_type</c-></code> equals <code class="highlight"><c- n>padding_stride</c-></code>.</p>
     </ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one,
then the least multiple of <code class="highlight"><c- n>padding_value</c-></code> greater than to equal to <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>.</p>
   </ul>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>
      Direct-non-list-initializes 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
       with:
     </p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>ext</c-></code>, if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero or one; else,</p>
      <li data-md>
       <p><code class="highlight"><c- n>S_left</c-><c- p>,</c-> <c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>P_left</c-><c- p>)...</c-></code>, where <code class="highlight"><c- n>S_left</c-></code> is the least multiple of <code class="highlight"><c- n>padding_value</c-></code> greater than or equal to <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>; and</p>
     </ul>
    <li data-md>
     <p>
      if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, value-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      ;
else, direct-non-list-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
       with <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
  <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-> <c- d>/* see below */</c-> <c- p>)</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>other</c-><c- p>);</c->
</pre>
   <p><em>Constraints:</em> <code class="highlight"><c- n>is_constructible_v</c-><c- o>&lt;</c-><c- n>extents_type</c-><c- p>,</c-> <c- n>OtherExtents</c-><c- o>></c-></code> is <code class="highlight">true</code>.</p>
   <p><em>Mandates:</em> <code class="highlight"><c- n>padding_stride</c-> <c- o>==</c-> <c- n>dynamic_extent</c-> <c- o>||</c-> <c- n>other_padding_stride</c-> <c- o>==</c-> <c- n>dynamic_extent</c-> <c- o>||</c-> <c- n>padding_stride</c-> <c- o>==</c-> <c- n>other_padding_stride</c-></code> is <code class="highlight">true</code>.</p>
   <p><em>Preconditions:</em></p>
   <ul>
    <li data-md>
     <p>
      If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>></c-> <c- mi>1</c-></code> is <code class="highlight">true</code> and <code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,
then <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code> equals
the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> greater than or equal to <code class="highlight"><c- n>extents_type</c-><c- o>::</c-></code> 
      <it><code class="highlight"><c- n>index</c-><c- o>-</c-><c- n>cast</c-></code></it>
       <code class="highlight"><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>))</c-></code>; and
     </p>
    <li data-md>
     <p><code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>()</c-></code> is representable
as a value of type <code class="highlight"><c- n>index_type</c-></code> (<em>[basic.fundamental]</em>).</p>
   </ul>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>
      Direct-non-list-initializes 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
       with:
     </p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>()</c-></code>, if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero or one; else</p>
      <li data-md>
       <p><code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>),</c-> <c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>().</c-><c- n>extent</c-><c- p>(</c-><c- n>P_left</c-><c- p>)...</c-></code>; and</p>
     </ul>
    <li data-md>
     <p>
      if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, value-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      ;
else, direct-non-list-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
       with <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>().</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
     </p>
   </ul>
   <p><em>Remarks:</em> The expression inside <code class="highlight"><c- k>explicit</c-></code> is equivalent to: <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>></c-> <c- mi>1</c-> <c- o>&amp;&amp;</c-> <c- p>(</c-><c- n>padding_stride</c-> <c- o>==</c-> <c- n>dynamic_extent</c-> <c- o>||</c-> <c- n>other_padding_stride</c-> <c- o>==</c-> <c- n>dynamic_extent</c-><c- p>)</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
  <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-><c- n>not</c-> <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>></c-><c- p>)</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Constraints:</em></p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one,</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_constructible_v</c-><c- o>&lt;</c-><c- n>extents_type</c-><c- p>,</c-> <c- n>OtherExtents</c-><c- o>></c-></code> is <code class="highlight">true</code>.</p>
   </ul>
   <p><em>Precondition:</em> <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>()</c-></code> is representable
as a value of type <code class="highlight"><c- n>index_type</c-></code> (<em>[basic.fundamental]</em>).</p>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>
      Direct-non-list-initializes 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
       with <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>()</c-></code>; and
     </p>
    <li data-md>
     <p>
      if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, value-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      ;
else, direct-non-list-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
       with <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>().</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
     </p>
   </ul>
   <p><i>[Note:</i> Neither mapping uses the padding stride
in the rank-0 or rank-1 case, so the padding stride does not affect
either the constraints or the preconditions. <i>— end note]</i></p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>extents_type</c-> <c- n>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, equivalent to <code class="highlight"><c- k>return</c-> <c- n>extents_type</c-><c- p>{};</c-></code>.</p>
    <li data-md>
     <p>
      Otherwise, equivalent to <code class="highlight"><c- k>return</c-> <c- n>extents_type</c-><c- p>(</c-></code>
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      <code class="highlight"><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>),</c-></code>
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
      <code class="highlight"><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>P_left</c-><c- p>)...);</c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- o>></c->
  <c- n>strides</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p>
    <em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-></code>
    <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
    <code class="highlight"><c- p>.</c-><c- n>strides</c-><c- p>();</c-></code>.
   </p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>index_type</c-> <c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p>
    <em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-></code>
    <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
    <code class="highlight"><c- p>.</c-><c- n>required_span_size</c-><c- p>();</c-></code>.
   </p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Indices</c-><c- o>></c->
<c- n>constexpr</c-> <c- b>size_t</c-> <c- n>operator</c-><c- p>()(</c-><c- n>Indices</c-><c- p>...</c-> <c- n>idxs</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Constraints:</em></p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>sizeof</c-><c- p>...(</c-><c- n>Indices</c-><c- p>)</c-> <c- o>==</c-> <c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is <code class="highlight">true</code>,</p>
    <li data-md>
     <p><code class="highlight"><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>,</c-> <c- n>index_type</c-><c- o>></c-> <c- o>&amp;&amp;</c-> <c- p>...)</c-></code> is <code class="highlight">true</code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>is_nothrow_constructible</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>Indices</c-><c- o>></c-> <c- o>&amp;&amp;</c-> <c- p>...)</c-></code> is <code class="highlight">true</code>.</p>
   </ul>
   <p>
    <em>Precondition:</em> <code class="highlight"><c- n>extents_type</c-><c- o>::</c-></code>
    <it><code class="highlight"><c- n>index</c-><c- o>-</c-><c- n>cast</c-></code></it>
    <code class="highlight"><c- p>(</c-><c- n>i</c-><c- p>)</c-></code> is a multidimensional index in <code class="highlight"><c- n>extents</c-><c- p>()</c-></code> ([mdspan.overview]).
   </p>
   <p><em>Effects:</em> Let P be a parameter pack such that <code class="highlight"><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>index_sequence_for</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>...</c-><c- o>></c-><c- p>,</c-> <c- n>index_sequence</c-><c- o>&lt;</c-><c- n>P</c-><c- p>...</c-><c- o>>></c-></code> is <code class="highlight">true</code>.
Equivalent to: <code class="highlight"><c- k>return</c-> <c- p>((</c-><c- k>static_cast</c-><c- o>&lt;</c-><c- n>index_type</c-><c- o>></c-><c- p>(</c-><c- n>i</c-><c- p>)</c-> <c- o>*</c-> <c- n>stride</c-><c- p>(</c-><c- n>P</c-><c- p>))</c-> <c- o>+</c-> <c- p>...</c-> <c- o>+</c-> <c- mi>0</c-><c- p>);</c-></code>.</p>
   <p><i>[Note:</i> Effects are also equivalent to</p>
   <it><code class="highlight"><c- k>return</c-> <c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
   <code class="highlight"><c- p>(</c-><c- n>idxs</c-><c- p>...);</c-></code>,
but only after the Precondition has been applied. <i>— end note]</i> 
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_exhaustive</c-><c- p>()</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Returns:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one, then <code class="highlight">true</code>;</p>
    <li data-md>
     <p>else, if neither <code class="highlight"><c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> equal <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>;</p>
    <li data-md>
     <p>otherwise, <code class="highlight">false</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_exhaustive</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Returns:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero, then <code class="highlight">true</code>;</p>
    <li data-md>
     <p>
      else, 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
      <code class="highlight"><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-> <c- o>==</c-></code>
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      <code class="highlight"><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>index_type</c-> <c- n>stride</c-><c- p>(</c-><c- n>rank_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p>
    <em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-></code>
    <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
    <code class="highlight"><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>r</c-><c- p>);</c-></code>.
   </p>
   <h3 class="heading settled" data-level="4.2" id="class-template-layout_right_paddedmapping-mdspanlayoutright_padded"><span class="secno">4.2. </span><span class="content">Class template <code class="highlight"><c- n>layout_right_padded</c-><c- o>::</c-><c- n>mapping</c-></code> [mdspan.layout.right_padded]</span><a class="self-link" href="#class-template-layout_right_paddedmapping-mdspanlayoutright_padded"></a></h3>
   <p><code class="highlight"><c- n>layout_right_padded</c-></code> provides a layout mapping
that behaves like <code class="highlight"><c- n>layout_right</c-><c- o>::</c-><c- n>mapping</c-></code>,
except that the <em>padding stride</em> <code class="highlight"><c- n>stride</c-><c- p>(</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- p>)</c-></code> can be greater than or equal to <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>.
Users provide an input padding stride value
either as a <code class="highlight"><c- b>size_t</c-></code> template parameter <code class="highlight"><c- n>padding_stride</c-></code> of <code class="highlight"><c- n>layout_right_padded</c-></code>,
or as a run-time argument of <code class="highlight"><c- n>layout_right_padded</c-><c- o>::</c-><c- n>mapping</c-></code>'s constructor.
The padding stride is the least multiple of the input padding stride value
greater than or equal to <code class="highlight"><c- n>extent</c-><c- p>(</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>padding_stride</c-> <c- o>=</c-> <c- n>dynamic_extent</c-><c- o>></c->
<c- k>struct</c-> <c- nc>layout_right_padded</c-> <c- p>{</c->
  <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- o>></c->
  <c- k>struct</c-> <c- nc>mapping</c-> <c- p>{</c->
  <c- n>public</c-><c- o>:</c->
    <c- n>using</c-> <c- n>extents_type</c-> <c- o>=</c-> <c- n>Extents</c-><c- p>;</c->
    <c- n>using</c-> <c- n>index_type</c-> <c- o>=</c-> <c- n>typename</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>index_type</c-><c- p>;</c->
    <c- n>using</c-> <c- n>size_type</c-> <c- o>=</c-> <c- n>typename</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>size_type</c-><c- p>;</c->
    <c- n>using</c-> <c- n>rank_type</c-> <c- o>=</c-> <c- n>typename</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>rank_type</c-><c- p>;</c->
    <c- n>using</c-> <c- n>layout_type</c-> <c- o>=</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-><c- p>;</c->

  <c- n>private</c-><c- o>:</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>size_t</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>actual</c-><c- o>-</c-><c- n>padding</c-><c- o>-</c-><c- n>stride</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->

    <c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
    <c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
    <c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c->
      <c- n>layout_right</c-><c- o>::</c-><c- n>template</c-> <c- n>mapping</c-><c- o>&lt;&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>>></c-><c- p>;</c-> <c- c1>// exposition only</c->

    <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-><c- p>;</c-> <c- c1>// exposition only</c->
    <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-><c- p>;</c-> <c- c1>// exposition only</c->

  <c- n>public</c-><c- o>:</c->
    <c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>extents_type</c-><c- o>&amp;</c-> <c- n>ext</c-><c- p>);</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Size</c-><c- o>></c->
    <c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>extents_type</c-><c- o>&amp;</c-> <c- n>ext</c-><c- p>,</c-> <c- n>Size</c-> <c- n>padding_value</c-><c- p>);</c->

    <c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
      <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-> <c- d>/* see below */</c-> <c- p>)</c->
        <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>other</c-><c- p>);</c->

    <c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
      <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-><c- n>not</c-> <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>></c-><c- p>)</c->
        <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- nf>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&amp;</c-><c- p>)</c-> <c- n>noexcept</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->
    <c- n>mapping</c-><c- o>&amp;</c-> <c- n>operator</c-><c- o>=</c-><c- p>(</c-><c- k>const</c-> <c- n>mapping</c-><c- o>&amp;</c-><c- p>)</c-> <c- n>noexcept</c-> <c- o>=</c-> <c- k>default</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>extents_type</c-> <c- n>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- o>></c->
    <c- n>strides</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>constexpr</c-> <c- n>index_type</c-> <c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- n>template</c-><c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Indices</c-><c- o>></c->
    <c- n>constexpr</c-> <c- b>size_t</c-> <c- n>operator</c-><c- p>()(</c-><c- n>Indices</c-><c- p>...</c-> <c- n>idxs</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_unique</c-><c- p>()</c-> <c- n>noexcept</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_exhaustive</c-><c- p>()</c-> <c- n>noexcept</c-><c- p>;</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_strided</c-><c- p>()</c-> <c- n>noexcept</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->

    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_unique</c-><c- p>()</c-> <c- n>noexcept</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->
    <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_exhaustive</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
    <c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_strided</c-><c- p>()</c-> <c- n>noexcept</c-> <c- p>{</c-> <c- k>return</c-> true<c- p>;</c-> <c- p>}</c->

    <c- n>constexpr</c-> <c- n>index_type</c-> <c- n>stride</c-><c- p>(</c-><c- n>rank_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
  <c- p>};</c->
<c- p>};</c->
</pre>
   <p>Throughout this section, let <code class="highlight"><c- n>P_right</c-></code> be the following
size <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> parameter pack of <code class="highlight"><c- b>size_t</c-></code>:</p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one, then the empty parameter pack;</p>
    <li data-md>
     <p>else, the parameter pack <code class="highlight"><c- b>size_t</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>, <code class="highlight"><c- b>size_t</c-><c- p>(</c-><c- mi>1</c-><c- p>)</c-></code>, ..., <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-></code>.</p>
   </ul>
   <p><em>Mandates:</em> If</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one,</p>
    <li data-md>
     <p><code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,</p>
   </ul>
   <p>then the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> that is greater than or equal to <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code> is representable as a value of type <code class="highlight"><c- b>size_t</c-></code>,
and is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>.</p>
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>size_t</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>actual</c-><c- o>-</c-><c- n>padding</c-><c- o>-</c-><c- n>stride</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
</pre>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one, then <code class="highlight"><c- n>padding_stride</c-></code>.</p>
    <li data-md>
     <p>Else, if</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code> and</p>
      <li data-md>
       <p><code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,</p>
     </ul>
     <p>then the <code class="highlight"><c- b>size_t</c-></code> value which is the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> that is greater than or equal to <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.</p>
    <li data-md>
     <p>Otherwise, <code class="highlight"><c- n>dynamic_extent</c-></code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
</pre>
   <ul>
    <li data-md>
     <p>
      If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one,
then 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-></code></it>
       names the type <code class="highlight"><c- n>extents_type</c-></code>.
     </p>
    <li data-md>
     <p>
      Otherwise, 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>extents</c-><c- o>-</c-><c- n>type</c-></code></it>
       names the type <code class="highlight"><c- n>extents</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>P_right</c-><c- p>)...,</c-></code> 
      <it><code class="highlight"><c- n>actual</c-><c- o>-</c-><c- n>padding</c-><c- o>-</c-><c- n>stride</c-></code></it>
       <code class="highlight"><c- o>></c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>using</c-> <c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>></c-> <c- o>=</c-> <c- d>/* see-below */</c-><c- p>;</c-> <c- c1>// exposition only</c->
</pre>
   <ul>
    <li data-md>
     <p>
      If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero,
then 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-></code></it>
       names the type <code class="highlight"><c- n>extents</c-><c- o>&lt;</c-><c- n>index_type</c-><c- o>></c-></code>.
     </p>
    <li data-md>
     <p>
      Otherwise, 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent</c-><c- o>-</c-><c- n>type</c-></code></it>
       names the type <code class="highlight"><c- n>extents</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-><c- o>></c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- nf>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>extents_type</c-><c- o>&amp;</c-> <c- n>ext</c-><c- p>);</c->
</pre>
   <p><em>Preconditions:</em> If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one
and <code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,
then the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> greater than to equal to <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>.</p>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>
      Direct-non-list-initializes 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
       with:
     </p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>ext</c-></code>, if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero or one; else,</p>
      <li data-md>
       <p><code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>P_right</c-><c- p>)...,</c-> <c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>,
if <code class="highlight"><c- n>padding_stride</c-></code> is <code class="highlight"><c- n>dynamic_extent</c-></code>; else,</p>
      <li data-md>
       <p><code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>P_right</c-><c- p>)...,</c-> <c- n>S_right</c-></code>, where <code class="highlight"><c- n>S_right</c-></code> is the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> greater than or equal to <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>; and</p>
     </ul>
    <li data-md>
     <p>
      if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, value-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      ;
else, direct-non-list-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
       with <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Size</c-><c- o>></c->
<c- n>constexpr</c-> <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>extents_type</c-><c- o>&amp;</c-> <c- n>ext</c-><c- p>,</c-> <c- n>Size</c-> <c- n>padding_value</c-><c- p>);</c->
</pre>
   <p><em>Constraints:</em></p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Size</c-><c- p>,</c-> <c- n>index_type</c-><c- o>></c-></code> is <code class="highlight">true</code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_nothrow_constructible_v</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>Size</c-><c- o>></c-></code> is <code class="highlight">true</code>.</p>
   </ul>
   <p><em>Preconditions:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>, then</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>padding_value</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>, and</p>
      <li data-md>
       <p>the result of converting <code class="highlight"><c- n>padding_value</c-></code> to <code class="highlight"><c- n>index_type</c-></code> equals <code class="highlight"><c- n>padding_stride</c-></code>.</p>
     </ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one,
then the least multiple of <code class="highlight"><c- n>padding_value</c-></code> greater than to equal to <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code> is representable as a value of type <code class="highlight"><c- n>index_type</c-></code>.</p>
   </ul>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>
      Direct-non-list-initializes 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
       with:
     </p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>ext</c-></code>, if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero or one; else</p>
      <li data-md>
       <p><code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>P_right</c-><c- p>)...,</c-> <c- n>S_right</c-></code>, where <code class="highlight"><c- n>S_right</c-></code> is the least multiple of <code class="highlight"><c- n>padding_value</c-></code> greater than or equal to <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>; and</p>
     </ul>
    <li data-md>
     <p>
      if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, value-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      ;
else, direct-non-list-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
       with <code class="highlight"><c- n>ext</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
  <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-> <c- d>/* see below */</c-> <c- p>)</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>other</c-><c- p>);</c->
</pre>
   <p><em>Constraints:</em> <code class="highlight"><c- n>is_constructible_v</c-><c- o>&lt;</c-><c- n>extents_type</c-><c- p>,</c-> <c- n>OtherExtents</c-><c- o>></c-></code> is <code class="highlight">true</code>.</p>
   <p><em>Mandates:</em> <code class="highlight"><c- n>padding_stride</c-> <c- o>==</c-> <c- n>dynamic_extent</c-> <c- o>||</c-> <c- n>other_padding_stride</c-> <c- o>==</c-> <c- n>dynamic_extent</c-> <c- o>||</c-> <c- n>padding_stride</c-> <c- o>==</c-> <c- n>other_padding_stride</c-></code> is <code class="highlight">true</code>.</p>
   <p><em>Preconditions:</em></p>
   <ul>
    <li data-md>
     <p>
      If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>></c-> <c- mi>1</c-></code> is <code class="highlight">true</code> and <code class="highlight"><c- n>padding_stride</c-></code> does not equal <code class="highlight"><c- n>dynamic_extent</c-></code>,
then <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- p>)</c-></code> equals
the least multiple of <code class="highlight"><c- n>padding_stride</c-></code> greater than or equal to <code class="highlight"><c- n>extents_type</c-><c- o>::</c-></code> 
      <it><code class="highlight"><c- n>index</c-><c- o>-</c-><c- n>cast</c-></code></it>
       <code class="highlight"><c- p>(</c-><c- n>other</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>OtherExtents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>))</c-></code>; and
     </p>
    <li data-md>
     <p><code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>()</c-></code> is representable
as a value of type <code class="highlight"><c- n>index_type</c-></code> (<em>[basic.fundamental]</em>).</p>
   </ul>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>
      Direct-non-list-initializes 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
       with:
     </p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>()</c-></code>, if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero or one; else,</p>
      <li data-md>
       <p><code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>().</c-><c- n>extent</c-><c- p>(</c-><c- n>P_right</c-><c- p>)...,</c-> <c- n>other</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>2</c-><c- p>)</c-></code>; and</p>
     </ul>
    <li data-md>
     <p>
      if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, value-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      ;
else, direct-non-list-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
       with <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>().</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>.
     </p>
   </ul>
   <p><em>Remarks:</em> The expression inside <code class="highlight"><c- k>explicit</c-></code> is equivalent to: <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>></c-> <c- mi>1</c-> <c- o>&amp;&amp;</c-> <c- p>(</c-><c- n>padding_stride</c-> <c- o>==</c-> <c- n>dynamic_extent</c-> <c- o>||</c-> <c- n>other_padding_stride</c-> <c- o>==</c-> <c- n>dynamic_extent</c-><c- p>)</c-></code>.</p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- b>size_t</c-> <c- n>other_padding_stride</c-><c- p>,</c-> <c- n>class</c-> <c- n>OtherExtents</c-><c- o>></c->
  <c- n>constexpr</c-> <c- n>explicit</c-><c- p>(</c-><c- n>not</c-> <c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>></c-><c- p>)</c->
    <c- n>mapping</c-><c- p>(</c-><c- k>const</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>other_padding_stride</c-><c- o>>::</c-><c- n>mapping</c-><c- o>&lt;</c-><c- n>OtherExtents</c-><c- o>>&amp;</c-> <c- n>other</c-><c- p>)</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Constraints:</em></p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one, and</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_constructible_v</c-><c- o>&lt;</c-><c- n>extents_type</c-><c- p>,</c-> <c- n>OtherExtents</c-><c- o>></c-></code> is <code class="highlight">true</code>.</p>
   </ul>
   <p><em>Preconditions:</em> <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>required_span_size</c-><c- p>()</c-></code> is representable
as a value of type <code class="highlight"><c- n>index_type</c-></code> (<em>[basic.fundamental]</em>).</p>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>
      Direct-non-list-initializes 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
       with <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>()</c-></code>; and
     </p>
    <li data-md>
     <p>
      if <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, value-initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      ;
else, initializes 
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
       with <code class="highlight"><c- n>other</c-><c- p>.</c-><c- n>extents</c-><c- p>().</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-></code>.
     </p>
   </ul>
   <p><i>[Note:</i> Neither mapping uses the padding stride
in the rank-0 or rank-1 case, so the padding stride does not affect
either the constraints or the preconditions. <i>— end note]</i></p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>extents_type</c-> <c- n>extents</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Effects:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is zero, equivalent to <code class="highlight"><c- k>return</c-> <c- n>extents_type</c-><c- p>{};</c-></code>.</p>
    <li data-md>
     <p>
      Otherwise, equivalent to <code class="highlight"><c- k>return</c-> <c- n>extents_type</c-><c- p>(</c-></code>
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
      <code class="highlight"><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>P_right</c-><c- p>)...,</c-></code>
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      <code class="highlight"><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>));</c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>std</c-><c- o>::</c-><c- n>array</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-><c- o>></c->
  <c- n>strides</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p>
    <em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-></code>
    <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
    <code class="highlight"><c- p>.</c-><c- n>strides</c-><c- p>();</c-></code>.
   </p>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>index_type</c-> <c- n>required_span_size</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p>
    <em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-></code>
    <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
    <code class="highlight"><c- p>.</c-><c- n>required_span_size</c-><c- p>();</c-></code>.
   </p>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-><c- p>...</c-> <c- n>Indices</c-><c- o>></c->
<c- n>constexpr</c-> <c- b>size_t</c-> <c- n>operator</c-><c- p>()(</c-><c- n>Indices</c-><c- p>...</c-> <c- n>idxs</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Constraints:</em></p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>sizeof</c-><c- p>...(</c-><c- n>Indices</c-><c- p>)</c-> <c- o>==</c-> <c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is <code class="highlight">true</code>,</p>
    <li data-md>
     <p><code class="highlight"><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>is_convertible_v</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>,</c-> <c- n>index_type</c-><c- o>></c-> <c- o>&amp;&amp;</c-> <c- p>...)</c-></code> is <code class="highlight">true</code>, and</p>
    <li data-md>
     <p><code class="highlight"><c- p>(</c-><c- n>std</c-><c- o>::</c-><c- n>is_nothrow_constructible</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>Indices</c-><c- o>></c-> <c- o>&amp;&amp;</c-> <c- p>...)</c-></code> is <code class="highlight">true</code>.</p>
   </ul>
   <p><em>Precondition:</em> <code class="highlight"><c- n>extents_type</c-><c- o>::</c-></code><code class="highlight" data-span-tag="_"><c- n>index</c-><c- o>-</c-><c- n>cast</c-></code><code class="highlight" data-span-tag="_"><c- p>(</c-><c- n>i</c-><c- p>)</c-></code> is a multidimensional index in <code class="highlight"><c- n>extents</c-><c- p>()</c-></code> ([mdspan.overview]).</p>
   <p><em>Effects:</em> Let <code class="highlight"><c- n>P</c-></code> be a parameter pack such that <code class="highlight"><c- n>is_same_v</c-><c- o>&lt;</c-><c- n>index_sequence_for</c-><c- o>&lt;</c-><c- n>Indices</c-><c- p>...</c-><c- o>></c-><c- p>,</c-> <c- n>index_sequence</c-><c- o>&lt;</c-><c- n>P</c-><c- p>...</c-><c- o>>></c-></code> is <code class="highlight">true</code>.
Equivalent to: <code class="highlight"><c- k>return</c-> <c- p>((</c-><c- k>static_cast</c-><c- o>&lt;</c-><c- n>index_type</c-><c- o>></c-><c- p>(</c-><c- n>i</c-><c- p>)</c-> <c- o>*</c-> <c- n>stride</c-><c- p>(</c-><c- n>P</c-><c- p>))</c-> <c- o>+</c-> <c- p>...</c-> <c- o>+</c-> <c- mi>0</c-><c- p>);</c-></code>.</p>
   <p><i>[Note:</i> Effects are also equivalent to</p>
   <it><code class="highlight"><c- k>return</c-> <c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
   <code class="highlight"><c- p>(</c-><c- n>idxs</c-><c- p>...);</c-></code>,
but only after the Precondition has been applied. <i>— end note]</i> 
<pre class="language-c++ highlight"><c- k>static</c-> <c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_always_exhaustive</c-><c- p>()</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Returns:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one, <code class="highlight">true</code>;</p>
    <li data-md>
     <p>else, if neither <code class="highlight"><c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code> nor <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code> equal <code class="highlight"><c- n>dynamic_extent</c-></code>, then <code class="highlight"><c- o>&lt;</c-><c- n>it</c-><c- o>></c-><c- n>inner</c-><c- o>-</c-><c- n>mapping</c-><c- o>-</c-><c- n>type</c-><c- o>&lt;/</c-><c- n>it</c-><c- o>>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-> <c- o>==</c-> <c- n>extents_type</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>;</p>
    <li data-md>
     <p>otherwise, <code class="highlight">false</code>.</p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- b>bool</c-> <c- n>is_exhaustive</c-><c- p>()</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p><em>Returns:</em></p>
   <ul>
    <li data-md>
     <p>If <code class="highlight"><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero, then <code class="highlight">true</code>;</p>
    <li data-md>
     <p>
      else, 
      <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
      <code class="highlight"><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-> <c- o>==</c-></code>
      <it><code class="highlight"><c- n>unpadded</c-><c- o>-</c-><c- n>extent_</c-></code></it>
      <code class="highlight"><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>extents_type</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-></code>.
     </p>
   </ul>
<pre class="language-c++ highlight"><c- n>constexpr</c-> <c- n>index_type</c-> <c- n>stride</c-><c- p>(</c-><c- n>rank_type</c-> <c- n>r</c-><c- p>)</c-> <c- k>const</c-> <c- n>noexcept</c-><c- p>;</c->
</pre>
   <p>
    <em>Effects:</em> Equivalent to <code class="highlight"><c- k>return</c-></code>
    <it><code class="highlight"><c- n>inner</c-><c- o>-</c-><c- n>mapping_</c-></code></it>
    <code class="highlight"><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>r</c-><c- p>);</c-></code>.
   </p>
   <h3 class="heading settled" data-level="4.3" id="layout-specializations-of-submdspan_mapping-mdspansubmdspanmapping"><span class="secno">4.3. </span><span class="content">Layout specializations of <code class="highlight"><c- n>submdspan_mapping</c-></code> [mdspan.submdspan.mapping]</span><a class="self-link" href="#layout-specializations-of-submdspan_mapping-mdspansubmdspanmapping"></a></h3>
   <blockquote>
    <p>At the top of Section � [mdspan.submdspan.mapping] ("Layout specializations of <code class="highlight"><c- n>submdspan_mapping</c-></code>"), before paragraph 1, add the following to the end of the synopsis of specializations.</p>
   </blockquote>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>padding_stride</c-><c- p>,</c-> <c- n>class</c-><c- p>...</c-> <c- n>SliceSpecifiers</c-><c- o>></c->
  <c- n>constexpr</c-> <c- k>auto</c-> <c- n>submdspan_mapping</c-><c- p>(</c->
    <c- k>const</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- n>template</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>>&amp;</c-> <c- n>src</c-><c- p>,</c-> 
    <c- n>SliceSpecifiers</c-> <c- p>...</c-> <c- n>slices</c-><c- p>)</c-> <c- o>-></c-> <c- n>see</c-> <c- n>below</c-><c- p>;</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>padding_stride</c-><c- p>,</c-> <c- n>class</c-><c- p>...</c-> <c- n>SliceSpecifiers</c-><c- o>></c->
  <c- n>constexpr</c-> <c- k>auto</c-> <c- n>submdspan_mapping</c-><c- p>(</c->
    <c- k>const</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- n>template</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>>&amp;</c-> <c- n>src</c-><c- p>,</c-> 
    <c- n>SliceSpecifiers</c-> <c- p>...</c-> <c- n>slices</c-><c- p>)</c-> <c- o>-></c-> <c- n>see</c-> <c- n>below</c-><c- p>;</c->
</pre>
   <blockquote>
    <p>In paragraph 7 (the "Returns" clause) of Section � [mdspan.submdspan.mapping] ("Layout specializations of submdspan_mapping"), replace (7.3) (the <code class="highlight"><c- n>layout_stride</c-></code> fall-back return type) with the following.</p>
   </blockquote>
   <p>(7.3) Else, if</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>src</c-><c- p>)</c-><c- o>::</c-><c- n>layout_type</c-></code> is <code class="highlight"><c- n>layout_left</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one;</p>
    <li data-md>
     <p>all the $S_k$ except for $S_0$ and $S_1$ are <code class="highlight"><c- n>full_extent_t</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_0$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>; and</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_1$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>;</p>
   </ul>
   <p>then <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- mi>0</c-><c- p>)</c-><c- o>>::</c-><c- k>template</c-> <c- n>mapping</c-><c- p>(</c-><c- n>sub_ext</c-><c- p>,</c-> <c- n>src</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- mi>0</c-><c- p>))</c-></code>.</p>
   <p>(7.4) Else, if</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>src</c-><c- p>)</c-><c- o>::</c-><c- n>layout_type</c-></code> is <code class="highlight"><c- n>layout_right</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one;</p>
    <li data-md>
     <p>all the $S_k$ except for the two rightmost $S_{r-2}$ and $S_{r-1}$ are <code class="highlight"><c- n>full_extent_t</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_{r-2}$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>; and</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_{r-1}$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>;</p>
   </ul>
   <p>then <code class="highlight"><c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>::</c-><c- n>static_extent</c-><c- p>(</c-><c- n>r</c-> <c- o>-</c-> <c- mi>1</c-><c- p>)</c-><c- o>>::</c-><c- k>template</c-> <c- n>mapping</c-><c- p>(</c-><c- n>sub_ext</c-><c- p>,</c-> <c- n>src</c-><c- p>.</c-><c- n>extent</c-><c- p>(</c-><c- n>r</c-> <c- o>-</c-> <c- mi>1</c-><c- p>))</c-></code>.</p>
   <p>(7.5) Else, if</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>src</c-><c- p>)</c-><c- o>::</c-><c- n>layout_type</c-></code> is <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-></code> for some <code class="highlight"><c- b>size_t</c-> <c- n>padding_stride</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one; and</p>
    <li data-md>
     <p>if <code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals one, then $S_0$ is <code class="highlight"><c- n>full_extent_t</c-></code> or <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_0$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>;</p>
   </ul>
   <p>then, <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- k>template</c-> <c- n>mapping</c-><c- p>(</c-><c- n>sub_ext</c-><c- p>)</c-></code>.</p>
   <p>(7.6) Else, if</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>src</c-><c- p>)</c-><c- o>::</c-><c- n>layout_type</c-></code> is <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-></code> for some <code class="highlight"><c- b>size_t</c-> <c- n>padding_stride</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one;</p>
    <li data-md>
     <p>all the $S_k$ except for $S_0$ and $S_1$ are <code class="highlight"><c- n>full_extent_t</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_0$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>; and</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_1$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>;</p>
   </ul>
   <p>then <code class="highlight"><c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- k>template</c-> <c- n>mapping</c-><c- p>(</c-><c- n>sub_ext</c-><c- p>,</c-> <c- n>src</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- mi>1</c-><c- p>))</c-></code>;</p>
   <p>(7.7) Else, if</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>src</c-><c- p>)</c-><c- o>::</c-><c- n>layout_type</c-></code> is <code class="highlight"><c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-></code> for some <code class="highlight"><c- b>size_t</c-> <c- n>padding_stride</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals zero or one; and</p>
    <li data-md>
     <p>if <code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> equals one, then $S_0$ is <code class="highlight"><c- n>full_extent_t</c-></code> or <code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_0$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>;</p>
   </ul>
   <p>then, <code class="highlight"><c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- k>template</c-> <c- n>mapping</c-><c- p>(</c-><c- n>sub_ext</c-><c- p>)</c-></code>.</p>
   <p>(7.8) Else, if</p>
   <ul>
    <li data-md>
     <p><code class="highlight"><c- k>decltype</c-><c- p>(</c-><c- n>src</c-><c- p>)</c-><c- o>::</c-><c- n>layout_type</c-></code> is <code class="highlight"><c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>></c-></code> for some <code class="highlight"><c- b>size_t</c-> <c- n>padding_stride</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>Extents</c-><c- o>::</c-><c- n>rank</c-><c- p>()</c-></code> is greater than one;</p>
    <li data-md>
     <p>all the $S_k$ except for the two rightmost $S_{r-2}$ and $S_{r-1}$ are <code class="highlight"><c- n>full_extent_t</c-></code>;</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_{r-2}$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>; and</p>
    <li data-md>
     <p><code class="highlight"><c- n>is_convertible_v</c-><c- o>&lt;</c-></code> $S_{r-1}$ <code class="highlight"><c- p>,</c-> <c- n>tuple</c-><c- o>&lt;</c-><c- n>index_type</c-><c- p>,</c-> <c- n>index_type</c-><c- o>>></c-></code> is <code class="highlight">true</code>;</p>
   </ul>
   <p>then,</p>
   <p>then <code class="highlight"><c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- k>template</c-> <c- n>mapping</c-><c- p>(</c-><c- n>sub_ext</c-><c- p>,</c-> <c- n>src</c-><c- p>.</c-><c- n>stride</c-><c- p>(</c-><c- n>r</c-> <c- o>-</c-> <c- mi>2</c-><c- p>))</c-></code>;</p>
   <p>(7.9) Otherwise, <code class="highlight"><c- n>layout_stride</c-><c- o>::</c-><c- n>mapping</c-><c- p>(</c-><c- n>sub_ext</c-><c- p>,</c-> <c- n>sub_strides</c-><c- p>)</c-></code>;</p>
   <h3 class="heading settled" data-level="4.4" id="layout-specializations-of-submdspan_offset-mdspansubmdspanoffset"><span class="secno">4.4. </span><span class="content">Layout specializations of <code class="highlight"><c- n>submdspan_offset</c-></code> [mdspan.submdspan.offset]</span><a class="self-link" href="#layout-specializations-of-submdspan_offset-mdspansubmdspanoffset"></a></h3>
   <blockquote>
    <p>At the top of Section � [mdspan.submdspan.offset] ("Layout specializations of <code class="highlight"><c- n>submdspan_offset</c-></code>"), before paragraph 1, add the following to the end of the synopsis of specializations.  (Note that all the specializations of <code class="highlight"><c- n>submdspan_offset</c-></code> share the same wording.)</p>
   </blockquote>
<pre class="language-c++ highlight"><c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>padding_stride</c-><c- p>,</c-> <c- n>class</c-><c- p>...</c-> <c- n>SliceSpecifiers</c-><c- o>></c->
  <c- n>constexpr</c-> <c- b>size_t</c-> <c- n>submdspan_offset</c-><c- p>(</c->
    <c- k>const</c-> <c- n>layout_left_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- n>template</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>>&amp;</c-> <c- n>src</c-><c- p>,</c-> 
    <c- n>SliceSpecifiers</c-> <c- p>...</c-> <c- n>slices</c-><c- p>);</c->

<c- n>template</c-><c- o>&lt;</c-><c- n>class</c-> <c- n>Extents</c-><c- p>,</c-> <c- n>std</c-><c- o>::</c-><c- b>size_t</c-> <c- n>padding_stride</c-><c- p>,</c-> <c- n>class</c-><c- p>...</c-> <c- n>SliceSpecifiers</c-><c- o>></c->
  <c- n>constexpr</c-> <c- b>size_t</c-> <c- n>submdspan_offset</c-><c- p>(</c->
    <c- k>const</c-> <c- n>layout_right_padded</c-><c- o>&lt;</c-><c- n>padding_stride</c-><c- o>>::</c-><c- n>template</c-> <c- n>mapping</c-><c- o>&lt;</c-><c- n>Extents</c-><c- o>>&amp;</c-> <c- n>src</c-><c- p>,</c-> 
    <c- n>SliceSpecifiers</c-> <c- p>...</c-> <c- n>slices</c-><c- p>);</c->
</pre>
  </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>