<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2022-02-14" />
  <title>MDSPAN</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <style>
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  background-color: #f6f8fa; }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span { } /* Normal */
code span.al { color: #ff0000; } /* Alert */
code span.an { } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #9f6807; } /* BaseN */
code span.bu { color: #9f6807; } /* BuiltIn */
code span.cf { color: #00607c; } /* ControlFlow */
code span.ch { color: #9f6807; } /* Char */
code span.cn { } /* Constant */
code span.co { color: #008000; font-style: italic; } /* Comment */
code span.cv { color: #008000; font-style: italic; } /* CommentVar */
code span.do { color: #008000; } /* Documentation */
code span.dt { color: #00607c; } /* DataType */
code span.dv { color: #9f6807; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #9f6807; } /* Float */
code span.fu { } /* Function */
code span.im { } /* Import */
code span.in { color: #008000; } /* Information */
code span.kw { color: #00607c; } /* Keyword */
code span.op { color: #af1915; } /* Operator */
code span.ot { } /* Other */
code span.pp { color: #6f4e37; } /* Preprocessor */
code span.re { } /* RegionMarker */
code span.sc { color: #9f6807; } /* SpecialChar */
code span.ss { color: #9f6807; } /* SpecialString */
code span.st { color: #9f6807; } /* String */
code span.va { } /* Variable */
code span.vs { color: #9f6807; } /* VerbatimString */
code span.wa { color: #008000; font-weight: bold; } /* Warning */
code.diff {color: #898887}
code.diff span.va {color: #6.0e28}
code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
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;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }

div#refs p { padding-left: 32px; text-indent: -32px; }
</style>
  <link href="data:image/vnd.microsoft.icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center"><code>MDSPAN</code></h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>P0009r14</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2022-02-14</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project: </td>
    <td>Programming Language C++<br>
      LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to: </td>
    <td>
      Christian Trott<br>&lt;<a href="mailto:crtrott@sandia.gov" class="email">crtrott@sandia.gov</a>&gt;<br>
      D.S. Hollman<br>&lt;<a href="mailto:me@dsh.fyi" class="email">me@dsh.fyi</a>&gt;<br>
      Damien Lebrun-Grandie<br>&lt;<a href="mailto:lebrungrandt@ornl.gov" class="email">lebrungrandt@ornl.gov</a>&gt;<br>
      Mark Hoemmen<br>&lt;<a href="mailto:mhoemmen@stellarscience.com" class="email">mhoemmen@stellarscience.com</a>&gt;<br>
      Daniel Sunderland<br>&lt;<a href="mailto:dansunderland@gmail.com" class="email">dansunderland@gmail.com</a>&gt;<br>
      H. Carter Edwards<br>&lt;<a href="mailto:hedwards@nvidia.com" class="email">hedwards@nvidia.com</a>&gt;<br>
      Bryce Adelstein Lelbach<br>&lt;<a href="mailto:brycelelbach@gmail.com" class="email">brycelelbach@gmail.com</a>&gt;<br>
      Mauro Bianco<br>&lt;<a href="mailto:mbianco@cscs.ch" class="email">mbianco@cscs.ch</a>&gt;<br>
      Ben Sander<br>&lt;<a href="mailto:ben.sander@amd.com" class="email">ben.sander@amd.com</a>&gt;<br>
      Athanasios Iliopoulos<br>&lt;&gt;<br>
      John Michopoulos<br>&lt;&gt;<br>
      Nevin Liber<br>&lt;<a href="mailto:nliber@anl.gov" class="email">nliber@anl.gov</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#revision-history"><span class="toc-section-number">1</span> Revision History<span></span></a>
<ul>
<li><a href="#p0009r15-2022-02-mailing"><span class="toc-section-number">1.1</span> P0009r15: 2022-02
Mailing<span></span></a></li>
<li><a href="#p0009r14-2021-11-mailing"><span class="toc-section-number">1.2</span> P0009r14: 2021-11
Mailing<span></span></a></li>
<li><a href="#p0009r13-2021-10-mailing"><span class="toc-section-number">1.3</span> P0009r13: 2021-10
Mailing<span></span></a></li>
<li><a href="#p0009r12-post-2021-05-mailing"><span class="toc-section-number">1.4</span> P0009r12: post 2021-05
Mailing<span></span></a></li>
<li><a href="#p0009r11-2021-05-mailing"><span class="toc-section-number">1.5</span> P0009r11: 2021-05
Mailing<span></span></a></li>
<li><a href="#p0009r10-pre-2020-02-prague-mailing"><span class="toc-section-number">1.6</span> P0009r10: Pre 2020-02-Prague
Mailing<span></span></a></li>
<li><a href="#p0009r9-pre-2019-02-kona-mailing"><span class="toc-section-number">1.7</span> P0009r9: Pre 2019-02-Kona
Mailing<span></span></a></li>
<li><a href="#p0009r8-pre-2018-11-sandiego-mailing"><span class="toc-section-number">1.8</span> P0009r8: Pre 2018-11-SanDiego
Mailing<span></span></a></li>
<li><a href="#p0009r7-post-2018-06-rapperswil-mailing"><span class="toc-section-number">1.9</span> P0009r7: Post 2018-06-Rapperswil
Mailing<span></span></a></li>
<li><a href="#p0009r6-pre-2018-06-rapperswil-mailing"><span class="toc-section-number">1.10</span> P0009r6 : Pre 2018-06-Rapperswil
Mailing<span></span></a></li>
<li><a href="#p0009r5-pre-2018-03-jacksonville-mailing"><span class="toc-section-number">1.11</span> P0009r5 : Pre
2018-03-Jacksonville Mailing<span></span></a></li>
<li><a href="#p0009r4-pre-2017-11-albuquerque-mailing"><span class="toc-section-number">1.12</span> P0009r4 : Pre 2017-11-Albuquerque
Mailing<span></span></a></li>
<li><a href="#p0009r3-post-2016-06-oulu-mailing"><span class="toc-section-number">1.13</span> P0009r3 : Post 2016-06-Oulu
Mailing<span></span></a></li>
<li><a href="#p0009r2-pre-2016-06-oulu-mailing"><span class="toc-section-number">1.14</span> P0009r2 : Pre 2016-06-Oulu
Mailing<span></span></a></li>
<li><a href="#p0009r1-pre-2016-02-jacksonville-mailing"><span class="toc-section-number">1.15</span> P0009r1 : Pre
2016-02-Jacksonville Mailing<span></span></a></li>
<li><a href="#p0009r0-pre-2015-10-kona-mailing"><span class="toc-section-number">1.16</span> P0009r0 : Pre 2015-10-Kona
Mailing<span></span></a></li>
<li><a href="#related-activity"><span class="toc-section-number">1.17</span> Related
Activity<span></span></a></li>
</ul></li>
<li><a href="#description"><span class="toc-section-number">2</span>
Description<span></span></a>
<ul>
<li><a href="#what-we-propose-to-add"><span class="toc-section-number">2.1</span> What we propose to
add<span></span></a></li>
<li><a href="#definitions"><span class="toc-section-number">2.2</span>
Definitions<span></span></a></li>
<li><a href="#why-do-we-need-multidimensional-arrays"><span class="toc-section-number">2.3</span> Why do we need multidimensional
arrays?<span></span></a></li>
<li><a href="#why-are-existing-c-data-structures-not-enough"><span class="toc-section-number">2.4</span> Why are existing C++ data
structures not enough?<span></span></a></li>
<li><a href="#mixing-compile-time-and-run-time-extents"><span class="toc-section-number">2.5</span> Mixing compile-time and run-time
extents<span></span></a></li>
<li><a href="#why-custom-memory-layouts"><span class="toc-section-number">2.6</span> Why custom memory
layouts?<span></span></a></li>
<li><a href="#why-custom-accessors"><span class="toc-section-number">2.7</span> Why custom
accessors?<span></span></a></li>
<li><a href="#subspan-support"><span class="toc-section-number">2.8</span> Subspan
Support<span></span></a></li>
<li><a href="#why-propose-a-multidimensional-array-view-before-a-container"><span class="toc-section-number">2.9</span> Why propose a multidimensional
array view before a container?<span></span></a></li>
<li><a href="#use-multiple-parameter-operator-for-array-access"><span class="toc-section-number">2.10</span> Use multiple-parameter operator[]
for array access<span></span></a></li>
<li><a href="#reference-implementation"><span class="toc-section-number">2.11</span> Reference
Implementation<span></span></a></li>
<li><a href="#references"><span class="toc-section-number">2.12</span>
References<span></span></a></li>
</ul></li>
<li><a href="#editing-notes"><span class="toc-section-number">3</span>
Editing Notes<span></span></a></li>
<li><a href="#wording"><span class="toc-section-number">4</span>
Wording<span></span></a></li>
<li><a href="#implementation"><span class="toc-section-number">5</span>
Implementation<span></span></a></li>
<li><a href="#related-work"><span class="toc-section-number">6</span>
Related Work<span></span></a></li>
</ul>
</div>
<p>Special thanks to Tomasz Kaminski for invaluable help in preparing
this paper for wording review.</p>
<h1 data-number="1" id="revision-history"><span class="header-section-number">1</span> Revision History<a href="#revision-history" class="self-link"></a></h1>
<h2 data-number="1.1" id="p0009r15-2022-02-mailing"><span class="header-section-number">1.1</span> P0009r15: 2022-02 Mailing<a href="#p0009r15-2022-02-mailing" class="self-link"></a></h2>
<h4 data-number="1.1.0.1" id="changes-from-r14"><span class="header-section-number">1.1.0.1</span> Changes from R14<a href="#changes-from-r14" class="self-link"></a></h4>
<ul>
<li><p><code>mdspan::rank[_dynamic]</code> returns
<code>size_t</code></p></li>
<li><p>fix comparison operator for <code>layout_stride</code> to take
strides into account.</p></li>
<li><p>fix <code>layout_stride</code> mapping
<code>required_span_size</code></p></li>
<li><p>Consistently use “<code>&lt;</code><em>expr</em><code>&gt;</code>
is <code>true</code>” instead of
“<code>&lt;</code><em>expr</em><code>&gt;</code> is true”.</p></li>
<li><p>In the layout mappings’ <code>operator()</code> <em>Effects</em>
clauses, use only <code>index_sequence</code>and fix syntax error in
<code>stride(P())</code>.</p></li>
<li><p>Replace various unary folds with binary to handle
<code>extents&lt;&gt;</code>.</p></li>
<li><p>Consistently use <code>Extents::rank()</code> in layout mapping
wording.</p></li>
<li><p>Typo in <code>mdspan::mapping_type</code>:
<code>template mapping_type</code> should be
<code>template mapping</code>.</p></li>
<li><p><code>mdspan</code>’s <code>array</code> constructor calls
<code>Extents</code>’s <code>array</code> constructor.</p></li>
<li><p>Clarify the value of <code>static_stride</code> for
<code>submdspan</code>’s result.</p></li>
<li><p>Significant editorial changes based on LWG small-group
review</p></li>
</ul>
<h2 data-number="1.2" id="p0009r14-2021-11-mailing"><span class="header-section-number">1.2</span> P0009r14: 2021-11 Mailing<a href="#p0009r14-2021-11-mailing" class="self-link"></a></h2>
<h4 data-number="1.2.0.1" id="lewg-review-11012021"><span class="header-section-number">1.2.0.1</span> LEWG Review 11/01/2021<a href="#lewg-review-11012021" class="self-link"></a></h4>
<ul>
<li>ACTION: Maybe a default constructible accessor should imply default
constructible spans. Default constructible spans are important in many
cases.
<ul>
<li>done</li>
</ul></li>
<li>ACTION: Make extents conditionally explicit when converting from
dynamic to static extents.
<ul>
<li>done</li>
</ul></li>
<li>ACTION: Make layout and mdspan converting constructors conditionally
explicit based upon the underlying types
<ul>
<li>done</li>
</ul></li>
<li>ACTION: constructing extents from std::array needs a deduction
guide?
<ul>
<li>not done: you can’t do this since you can’t use alias and you can’t
return a parameter pack</li>
</ul></li>
<li>QUESTION: Extents parameter pack ctor needs to be explicit?
Deduction guide needs to be explicit?
<ul>
<li>we made that change</li>
</ul></li>
<li>QUESTION: submdspan constructor can take tuple&lt;size_t, size_t&gt;
and get pair&lt;size_t, size_t&gt; for free (could add specific type for
submdspan, so long as it can be converted from pair and tuple).
<ul>
<li>we changed submdspan to take things convertible to
<code>tuple&lt;size_t,size_t&gt;</code></li>
</ul></li>
<li>ACTION: needs feature test macro
<ul>
<li>done</li>
</ul></li>
<li>QUESTION: Can get rid of mdspan ctor takes pointer + array? Can
construct extent from array. Disagreement on authors on this one.
<ul>
<li>not done: would remove ctad from array</li>
</ul></li>
<li>ACTION: Explore modifying the requirements on which extents need to
be provided when constructing an mdspan or extents object.
<ul>
<li>done</li>
<li>Authors decided to enable construction from both dynamic extents
only, and all extents (for both integer packs and arrays)</li>
<li>Why from dynamic extents only:
<ul>
<li>no redundant information</li>
<li>precondition free constructor</li>
<li>enables fully static extents mdspan construction from ptr only</li>
</ul></li>
<li>Why from all extents:
<ul>
<li><p>no confusion what extent a given argument is associated
with</p></li>
<li><p>enables easier writing of certain types of generic code e.g.:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> mds1_t, <span class="kw">class</span> mds2_t<span class="op">&gt;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> alloc_gemm_result<span class="op">(</span>mds1_t mdspan1, mds2_t mdspan2<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>   <span class="kw">using</span> return_t <span class="op">=</span> mdspan<span class="op">&lt;</span><span class="dt">double</span>,</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>     Extents<span class="op">&lt;</span> mds1_t<span class="op">::</span>extents_type<span class="op">::</span>static_extent<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;</span>,</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>              mds2_t<span class="op">::</span>extents_type<span class="op">::</span>static_extent<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;&gt;</span>;</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>   <span class="dt">double</span><span class="op">*</span> ptr <span class="op">=</span> <span class="kw">new</span> <span class="dt">double</span><span class="op">[</span>mdspan1<span class="op">.</span>extent<span class="op">(</span><span class="dv">0</span><span class="op">)*</span>mdspan2<span class="op">.</span>extent<span class="op">(</span><span class="dv">1</span><span class="op">)]</span>;</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>   <span class="cf">return</span> return_t<span class="op">(</span>ptr, mdspan1<span class="op">.</span>extent<span class="op">(</span><span class="dv">0</span><span class="op">)</span>,mdspan2<span class="op">.</span>extent<span class="op">(</span><span class="dv">1</span><span class="op">))</span>;</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span></code></pre></div></li>
</ul></li>
</ul></li>
</ul>
<h4 data-number="1.2.0.2" id="changes-from-r13"><span class="header-section-number">1.2.0.2</span> Changes from R13<a href="#changes-from-r13" class="self-link"></a></h4>
<ul>
<li>changes to harmonize with <code>std::span</code>
<ul>
<li>made <code>extents</code> converting constructor conditionally
explicit, for cases where dynamic extents are turned into static
extents</li>
<li>made convertibility of <code>default_accessor</code> depend on
convertibility of <code>element_type(*)[]</code> instead of
<code>pointer</code> to prevent derived class to base class
assignment</li>
<li>remove converting assignment operators throughout</li>
</ul></li>
<li>made layout mapping converting constructors conditionally explicit,
depending on <code>extents</code> being not implicitly convertible</li>
<li>made <code>mdspan</code> converting constructor conditionally
explicit, for cases where any of the exposition only members or the
template parameters are only explicitly convertible</li>
<li>Improve submdspan wording
<ul>
<li>the wording defines more clearly how the submdspan is constructed,
not just through ensures</li>
</ul></li>
<li>made layout wording style consistent</li>
<li>don’t require default constructibility from accessors and mappings
(still require it for pointer though)</li>
<li>fixed layout_stride conversion construction</li>
<li>made deduction guide from integers for extents/mdspan explicit</li>
<li>tweaked constraints on mdspan to not include element type and the
full extents
<ul>
<li>left pointer, since mdspan converts those in its converting
constructor</li>
<li>also left some specific constraints regarding extents to prevent
custom layouts from changing rank or assigning different sized static
extents</li>
</ul></li>
<li>add feature test macro</li>
<li>accept <code>tuple</code> instead of <code>pair</code> for subslice
arguments in <code>submdspan</code>.</li>
<li>remove <code>mdspan::unique_size</code></li>
<li>fix <code>layout_stride</code> constructor to be flexible with
integral types of strides array</li>
<li>make <code>extents</code> and <code>mdspan</code> constructors
accept either <code>rank_dynamic</code> or <code>rank</code> integer
arguments (or an <code>array</code> of that size)</li>
<li>remove mdspan trivially default constructible clause: it never is
because we value initialize pointer inline</li>
<li>remove <em>nonowning</em> word from mdspan description: there is not
really a reason to have it. Would allow <code>shared_ptr</code> as
<code>pointer</code></li>
<li>allow conversion for 1D <code>layout_left</code> to
<code>layout_right</code> and vice versa</li>
<li>allow implicit conversion for rank-0 <code>layout_left</code>,
<code>layout_right</code>, and <code>layout_stride</code> to each
other</li>
</ul>
<h2 data-number="1.3" id="p0009r13-2021-10-mailing"><span class="header-section-number">1.3</span> P0009r13: 2021-10 Mailing<a href="#p0009r13-2021-10-mailing" class="self-link"></a></h2>
<p>LEWG reviewed P0009r12 together with P2299r3 on 2021-06-08.</p>
<p><b>LEWG Poll</b> Approve the direction of P2299R3 and merge it into
P0009.</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
12
</td>
<td>
6
</td>
<td>
0
</td>
<td>
1
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p>Attendance: 25; Number of authors: 1 [presumably for P2299, as P0009
coauthors were also attending]; Author’s Position: SF.</p>
<ul>
<li>Incorporated changes proposed by P2299r3
<ul>
<li>Added <code>dextents</code> alias</li>
<li>Removed <code>mdspan</code> alias and renamed
<code>basic_mdspan</code> to <code>mdspan</code> (which is now a class
type, not an alias). This undoes a change introduced in P0009r6. P2299r3
explains the rationale. Existing code using the <code>mdspan</code>
alias will need to change by replacing the list of extents template
arguments with a single <code>extents</code> type.</li>
<li>Added <code>mdspan</code> deduction guides</li>
<li>As needed for deduction guides, added <code>layout_type</code> alias
to layout mapping requirements and to <code>layout_left</code>,
<code>layout_right</code>, and <code>layout_stride</code></li>
</ul></li>
<li>Adapted new LWG wording guidelines by replacing “Expects” with
“Preconditions”</li>
<li>Minor formatting corrections</li>
<li>Added design discussion as requested by LEWG</li>
<li>Remove unconditional <code>noexcept</code> from
<code>mdspan</code></li>
<li>Fix layout <code>required_span_size</code> for rank-0 mdspan</li>
<li>Fix <code>layout_stride::required_span_size</code> for mdspans with
at least one extent being zero</li>
<li>Use <code>operator[]</code> in <code>mdspan</code> for
multidimensional array access, and add explanation to Discussion
section</li>
<li>Remove reference to <code>span</code> in the <code>mdspan</code>
wording, since <code>mdspan</code> does not necessarily require a
backing <code>span</code> (because <code>pointer</code> need not be
<code>ElementType*</code>)</li>
<li>added conversion constructor for strided and unique layouts to
<code>layout_stride</code></li>
<li>added constructor for <code>mdspan</code> from <code>pointer</code>
and <code>extents</code></li>
<li>added requirement for layout policy mapping to be nothrow move
constructible and assignable</li>
<li>added requirement for accessor policy to be nothrow move
constructible and assignable</li>
<li>added requirement for accessor policy pointer to be nothrow move
constructible and assignable</li>
<li>remove throws nothing clauses from mdspan and submdspan.</li>
</ul>
<h2 data-number="1.4" id="p0009r12-post-2021-05-mailing"><span class="header-section-number">1.4</span> P0009r12: post 2021-05
Mailing<a href="#p0009r12-post-2021-05-mailing" class="self-link"></a></h2>
<ul>
<li>Fixed definition of <code>static_extent</code></li>
<li>Added converting constructor for <code>default_accessor</code> (when
the pointers to elements are convertible) for things like
<code>default_accessor&lt;double&gt;</code> to
<code>default_accessor&lt;const double&gt;</code></li>
<li>Changed [mdspan.accessor.basic] to [mdspan.accessor.default], to
correspond with the name change in P0009r11</li>
<li>Minor formatting corrections</li>
</ul>
<h2 data-number="1.5" id="p0009r11-2021-05-mailing"><span class="header-section-number">1.5</span> P0009r11: 2021-05 Mailing<a href="#p0009r11-2021-05-mailing" class="self-link"></a></h2>
<ul>
<li>Ask LEWG to poll on targeting P0009 for C++23</li>
<li>Change all the sizes from <code>ptrdiff_t</code> to
<code>size_t</code> and <code>index_type</code> to
<code>size_type</code>, for consistency with <code>span</code> and the
rest of the standard library`</li>
<li>Renamed <code>IndexType</code> to <code>SizeType</code> or
<code>SizeTypes</code> (depending if it is a single type or a parameter
pack)</li>
<li>Changed comparisons to hidden friends</li>
<li>Explicitly mention which types are trivially copyable or empty. This
is important as a major intended use case for this is heterogeneous
computing. A trivially copyable is heavily used as a proxy for types
which can be copied between a host (such as a CPU) and a device (such as
a GPU) or between two devices by just copying the bytes which make up
the object representation of the type. If they are not trivially
copyable, heterogeneous computing would not be able to use these types
as vocabulary types.</li>
<li>State the conditions that make <code>basic_mdspan</code> trivially
default constructible</li>
<li>In <code>layout_*</code> types, made <code>operator()</code> and
<code>stride()</code> constexpr</li>
<li>In <code>layout_stride</code>, made assignment operators and
<code>required_span_size()</code> constexpr to match the other
<code>layout_*</code> types</li>
<li>Renamed <code>subspan</code> to <code>submdspan</code>, as this only
applies to <code>mdspan</code></li>
<li>Made <code>submdspan()</code> constexpr</li>
<li>Tweak the wording of <code>is_strided</code></li>
<li>Renamed <code>all_type</code> to <code>full_extent_t</code> and
<code>all</code> to <code>full_extent</code></li>
<li>Renamed <code>accessor_basic</code> to
<code>default_accessor</code></li>
<li>Removed accessor policy <code>decay(p)</code> member function as it
was an artifact from an earlier version of this proposal when
<code>basic_mdspan</code> had a <code>span()</code> member function that
returned a <code>std::span</code></li>
<li>Removed <code>span()</code> from [mdspan.basic.members] description
as <code>.span()</code> was removed from an earlier version of this
proposal</li>
</ul>
<h2 data-number="1.6" id="p0009r10-pre-2020-02-prague-mailing"><span class="header-section-number">1.6</span> P0009r10: Pre 2020-02-Prague
Mailing<a href="#p0009r10-pre-2020-02-prague-mailing" class="self-link"></a></h2>
<ul>
<li>Switched to mpark/wg21 pandoc format</li>
<li>Add general description of span and mdspan</li>
<li>Removed <code>mdspan_subspan</code> expo only type; use
<code>basic_mdspan&lt;</code><em>see below</em><code>&gt;</code>
instead</li>
<li>Fixed typos in accessor table</li>
<li>Made editorial changes to wording based on San Diego feedback</li>
<li>Updated operational semantics subsection heading based on new style
guidelines</li>
</ul>
<h2 data-number="1.7" id="p0009r9-pre-2019-02-kona-mailing"><span class="header-section-number">1.7</span> P0009r9: Pre 2019-02-Kona
Mailing<a href="#p0009r9-pre-2019-02-kona-mailing" class="self-link"></a></h2>
<ul>
<li>Wording fixes based on guidance: <a href="http://wiki.edg.com/bin/view/Wg21sandiego2018/SanDiego2018P0009">LWG
small group at 2018-11-SanDiego</a></li>
</ul>
<h2 data-number="1.8" id="p0009r8-pre-2018-11-sandiego-mailing"><span class="header-section-number">1.8</span> P0009r8: Pre 2018-11-SanDiego
Mailing<a href="#p0009r8-pre-2018-11-sandiego-mailing" class="self-link"></a></h2>
<ul>
<li>Refinement based upon updated <a href="https://github.com/ORNL/cpp-proposals-pub/blob/master/P0009/prototype">prototype</a>
/ reference implementation</li>
</ul>
<h2 data-number="1.9" id="p0009r7-post-2018-06-rapperswil-mailing"><span class="header-section-number">1.9</span> P0009r7: Post
2018-06-Rapperswil Mailing<a href="#p0009r7-post-2018-06-rapperswil-mailing" class="self-link"></a></h2>
<ul>
<li>wording reworked based on guidance: <a href="http://wiki.edg.com/bin/view/Wg21rapperswil2018/LWGSatAM">LWG
review at 2018-06-Rapperswil</a></li>
<li>usage of <code>span</code> requires reference to C++20 working
draft</li>
<li>namespace for library TS
<code>std::experimental::fundamentals_v3</code></li>
</ul>
<h2 data-number="1.10" id="p0009r6-pre-2018-06-rapperswil-mailing"><span class="header-section-number">1.10</span> P0009r6 : Pre
2018-06-Rapperswil Mailing<a href="#p0009r6-pre-2018-06-rapperswil-mailing" class="self-link"></a></h2>
<p>P0009r5 was not taken up at 2018-03-Jacksonville meeting. Related <a href="http://wiki.edg.com/bin/view/Wg21jacksonville2018/P0900">LEWG
review of P0900 at 2018-03-Jacksonville meeting</a></p>
<p><b>LEWG Poll</b> We want the ability to customize the access to
elements of span (ability to restrict, etc):</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>span<span class="op">&lt;</span>T, N, Accessor<span class="op">=...&gt;</span></span></code></pre></div>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
1
</td>
<td>
1
</td>
<td>
1
</td>
<td>
2
</td>
<td>
8
</td>
</tr>
</tbody>
</table>
<p><b>LEWG Poll</b> We want the customization of
<code>basic_mdspan</code> to be two concepts <code>Mapper</code> and
<code>Accessor</code> (akin to <code>Allocator</code> design).</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>basic_mdspan<span class="op">&lt;</span>T, Extents, Mapper, Accessor<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">&lt;</span>T, N<span class="op">...&gt;</span></span></code></pre></div>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
3
</td>
<td>
4
</td>
<td>
5
</td>
<td>
1
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p><b>LEWG Poll</b>: We want the customization of
<code>basic_mdspan</code> to be an arbitrary (and potentially
user-extensible) list of properties.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>basic_mdspan<span class="op">&lt;</span>T, Extents, Properties<span class="op">...&gt;</span></span></code></pre></div>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
1
</td>
<td>
2
</td>
<td>
2
</td>
<td>
6
</td>
<td>
2
</td>
</tr>
</tbody>
</table>
<p><b>Changes from P0009r5 due to related LEWG reviews</b>:</p>
<ul>
<li>Replaced variadic property list with <em>extents</em>, <em>layout
mapping</em>, and <em>accessor</em> properties.</li>
<li>Incorporated <a href="https://wg21.link/P0454r1">P0454r1</a>.
<ul>
<li>Added accessor policy concept.</li>
<li>Renamed <code>mdspan</code> to <code>basic_mdspan</code>.</li>
<li>Added a <code>mdspan</code> alias to <code>basic_mdspan</code>.</li>
</ul></li>
</ul>
<h2 data-number="1.11" id="p0009r5-pre-2018-03-jacksonville-mailing"><span class="header-section-number">1.11</span> P0009r5 : Pre
2018-03-Jacksonville Mailing<a href="#p0009r5-pre-2018-03-jacksonville-mailing" class="self-link"></a></h2>
<p><a href="http://wiki.edg.com/bin/view/Wg21albuquerque/P0009">LEWG
review of P0009r4 at 2017-11-Albuquerque meeting</a></p>
<p><b>LEWG Poll</b>: We should be able to index with
<code>span&lt;int type[N]&gt;</code> (in addition to array).</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
2
</td>
<td>
11
</td>
<td>
1
</td>
<td>
1
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p>Against comment - there is not a proven needs for this feature.</p>
<p><b>LEWG Poll</b>: We should be able to index with 1d
<code>mdspan</code>.</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
0
</td>
<td>
8
</td>
<td>
7
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p><b>LEWG Poll</b>: We should put the requirement on “rank() &lt;= N”
back to “rank()==N”.</p>
<p><em>Unanimous consent</em></p>
<p><b>LEWG Poll</b>: With the editorial changes from small group, plus
the above polls, forward this to LWG for Fundamentals v3.</p>
<p><em>Unanimous consent</em></p>
<p><b>Changes from P0009r4</b>:</p>
<ul>
<li>Removed nullptr constructor.</li>
<li>Added constexpr to indexing operator.</li>
<li>Indexing operator requires that
<code>rank()==sizeof...(indices)</code>.</li>
<li>Fixed typos in examples and moved them to appendix.</li>
<li>Converted note on how extentions to access properties may cause
reference to be a proxy type to an “see below” to make it
normative.</li>
</ul>
<h2 data-number="1.12" id="p0009r4-pre-2017-11-albuquerque-mailing"><span class="header-section-number">1.12</span> P0009r4 : Pre
2017-11-Albuquerque Mailing<a href="#p0009r4-pre-2017-11-albuquerque-mailing" class="self-link"></a></h2>
<p><a href="http://wiki.edg.com/bin/view/Wg21kona2017/P0009">LEWG review
at 2017-03-Kona meeting</a></p>
<p><a href="http://wiki.edg.com/bin/view/Wg21kona2017/P0546">LEWG review
of P0546r1 at 2017-03-Kona meeting</a></p>
<p><b>LEWG Poll</b>: Should we have a single template that covers both
single and multi-dimensional spans?</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
1
</td>
<td>
6
</td>
<td>
2
</td>
<td>
6
</td>
<td>
3
</td>
</tr>
</tbody>
</table>
<p><b>Changes from P0009r3</b>:</p>
<ul>
<li>Align with P0122r5 span <a href="https://wg21.link/P0122r5">proposal</a>.</li>
<li>Rename to <code>mdspan</code>, multidimensional span, to align with
<code>span</code>.</li>
<li>Move preferred array extents mechanism to appendix.</li>
<li>Expose codomain as a <code>span</code>.</li>
<li>Add layout mapping concept.</li>
</ul>
<h2 data-number="1.13" id="p0009r3-post-2016-06-oulu-mailing"><span class="header-section-number">1.13</span> P0009r3 : Post 2016-06-Oulu
Mailing<a href="#p0009r3-post-2016-06-oulu-mailing" class="self-link"></a></h2>
<p><a href="http://wiki.edg.com/bin/view/Wg21oulu/P0009">LEWG review at
2016-06-Oulu</a></p>
<p>LEWG did not like the name <code>array_ref</code>, and suggested the
following alternatives: - <code>sci_span</code> -
<code>numeric_span</code> - <code>multidimensional_span</code> -
<code>multidim_span</code> - <code>mdspan</code> - <code>md_span</code>
- <code>vla_span</code> - <code>multispan</code> -
<code>multi_span</code></p>
<p><b>LEWG Poll</b>: Are member <code>begin()</code>/<code>end()</code>
still good?</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
0
</td>
<td>
2
</td>
<td>
4
</td>
<td>
3
</td>
<td>
1
</td>
</tr>
</tbody>
</table>
<p><b>LEWG Poll</b>: Want this proposal to provide range-producing
functions outside <code>array_ref</code>?</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
0
</td>
<td>
1
</td>
<td>
3
</td>
<td>
2
</td>
<td>
3
</td>
</tr>
</tbody>
</table>
<p><b>LEWG Poll</b>: Want a separate proposal to explore iteration
design space?</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
9
</td>
<td>
1
</td>
<td>
0
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p><b>Changes from P0009r2</b>:</p>
<ul>
<li>Removed iterator support; a future paper will be written on the
subject.</li>
<li>Noted difference between multidimensional array versus language’s
array-of-array-of-array…</li>
<li>Clearly describe requirements for the embedded type aliases
(<code>element_type</code>, <code>reference</code>, etc).</li>
<li>Expanded description of how the variadic properties list would
work.</li>
<li>Stopped allowing <code>array_ref&lt;T[N]&gt;</code> in addition to
<code>array_ref&lt;extents&lt;N&gt;&gt;</code>.</li>
<li>Clarified domain, codomain, and domain -&gt; codomain mapping
specifications.</li>
<li>Consistently use <em>extent</em> and <em>extents</em> for the
multidimensional index space.</li>
</ul>
<h2 data-number="1.14" id="p0009r2-pre-2016-06-oulu-mailing"><span class="header-section-number">1.14</span> P0009r2 : Pre 2016-06-Oulu
Mailing<a href="#p0009r2-pre-2016-06-oulu-mailing" class="self-link"></a></h2>
<p><a href="http://wiki.edg.com/bin/view/Wg21jacksonville/P0009">LEWG
review at 2016-02-Jacksonville</a>.</p>
<p><b>Changes from P0009r1</b>:</p>
<ul>
<li>Adding details for extensibility of layout mapping.</li>
<li>Move motivation, examples, and relaxed incomplete array type
proposal to separate papers.
<ul>
<li><a href="https://wg21.link/P0331">P0331: Motivation and Examples for
Polymorphic Multidimensional Array</a>.</li>
<li><a href="https://wg21.link/P0332">P0332: Relaxed Incomplete
Multidimensional Array Type Declaration</a>.</li>
</ul></li>
</ul>
<h2 data-number="1.15" id="p0009r1-pre-2016-02-jacksonville-mailing"><span class="header-section-number">1.15</span> P0009r1 : Pre
2016-02-Jacksonville Mailing<a href="#p0009r1-pre-2016-02-jacksonville-mailing" class="self-link"></a></h2>
<p><a href="http://wiki.edg.com/bin/view/Wg21kona2015/P0009">LEWG review
at 2015-10-Kona</a>.</p>
<p><b>LEWG Poll</b>: What should this feature be called?</p>
<table>
<thead>
<tr>
<th>
Name
</th>
<th>
#
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>view</code>
</td>
<td>
5
</td>
</tr>
<tr>
<td>
<code>span</code>
</td>
<td>
9
</td>
</tr>
<tr>
<td>
<code>array_ref</code>
</td>
<td>
6
</td>
</tr>
<tr>
<td>
<code>slice</code>
</td>
<td>
6
</td>
</tr>
<tr>
<td>
<code>array_view</code>
</td>
<td>
6
</td>
</tr>
<tr>
<td>
<code>ref</code>
</td>
<td>
0
</td>
</tr>
<tr>
<td>
<code>array_span</code>
</td>
<td>
7
</td>
</tr>
<tr>
<td>
<code>basic_span</code>
</td>
<td>
1
</td>
</tr>
<tr>
<td>
<code>object_span</code>
</td>
<td>
3
</td>
</tr>
<tr>
<td>
<code>field</code>
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p><b>LEWG Poll</b>: Do we want 0-length static extents?</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
3
</td>
<td>
4
</td>
<td>
2
</td>
<td>
3
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p><b>LEWG POLL</b>: Do we want the language to support syntaxes like
<code>X[3][][][5]</code>?</p>
<table>
<thead>
<tr>
<th>
Syntax
</th>
<th>
#
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>view&lt;int[3][0][][5], property1&gt;</code>
</td>
<td>
12
</td>
</tr>
<tr>
<td>
<code>view&lt;int, dimension&lt;3, 0, dynamic_extent, 5&gt;,
property1&gt;</code>
</td>
<td>
4
</td>
</tr>
<tr>
<td>
<code>view&lt;int[3][0][dynamic_extent][5], property1&gt;</code>
</td>
<td>
5
</td>
</tr>
<tr>
<td>
<code>view&lt;int, 3, 0, dynamic_extent, 5, property1&gt;</code>
</td>
<td>
4
</td>
</tr>
<tr>
<td>
<code>view&lt;int, 3, 0, dynamic_extent, 5,
properties&lt;property1&gt;&gt;</code>
</td>
<td>
2
</td>
</tr>
<tr>
<td>
<code>view&lt;arr&lt;int, 3, 0, dynamic_extent, 5&gt;,
property1&gt;</code>
</td>
<td>
4
</td>
</tr>
<tr>
<td>
<code>view&lt;int[3][0][][5], properties&lt;property1&gt;&gt;</code>
</td>
<td>
9
</td>
</tr>
</tbody>
</table>
<p><b>LEWG POLL</b>: Do we want the variadic property list in template
args (either raw or in <code>properties&lt;&gt;</code>)? Note there is
no precedence for this in the library.</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
3
</td>
<td>
6
</td>
<td>
3
</td>
<td>
0
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p><b>LEWG POLL</b>: Do we want the per-view bounds-checking knob?</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
3
</td>
<td>
4
</td>
<td>
1
</td>
<td>
2
</td>
<td>
1
</td>
</tr>
</tbody>
</table>
<p><b>Changes from P0009r0</b>:</p>
<ul>
<li>Renamed <code>view</code> to <code>array_ref</code>.</li>
<li>How are users allowed to add properties? Needs elaboration in
paper.</li>
<li><code>view&lt;int[][][]&gt;::layout</code> should be named.</li>
<li>Rename <code>is_regular</code> (possibly to <code>is_affine</code>)
to avoid overloading the term with the <code>Regular</code>
concept.</li>
<li>Make static span(), operator(), constructor, etc variadic.</li>
<li>Demonstrate the need for improper access in the paper.</li>
<li>In <code>operator()</code>, take integral types by value.</li>
</ul>
<h2 data-number="1.16" id="p0009r0-pre-2015-10-kona-mailing"><span class="header-section-number">1.16</span> P0009r0 : Pre 2015-10-Kona
Mailing<a href="#p0009r0-pre-2015-10-kona-mailing" class="self-link"></a></h2>
<p>Original non-owning multidimensional array reference
(<code>view</code>) paper with motivation, specification, and
examples.</p>
<h2 data-number="1.17" id="related-activity"><span class="header-section-number">1.17</span> Related Activity<a href="#related-activity" class="self-link"></a></h2>
<p>Related <a href="http://wiki.edg.com/bin/view/Wg21albuquerque/P0546">LEWG review of
P0546r1 at 2017-11-Albuquerque meeting</a></p>
<p><b>LEWG Poll</b>: <code>span</code> should specify the dynamic extent
as the element type of the first template parameter rather than the
(current) second template parameter</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
5
</td>
<td>
3
</td>
<td>
2
</td>
<td>
2
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p><b>LEWG Poll</b>: <code>span</code> should support the addition of
access properties variadic template parameters</p>
<table>
<thead>
<tr>
<th>
SF
</th>
<th>
F
</th>
<th>
N
</th>
<th>
A
</th>
<th>
SA
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
0
</td>
<td>
10
</td>
<td>
1
</td>
<td>
5
</td>
<td>
0
</td>
</tr>
</tbody>
</table>
<p>Authors agreed to bring a separate paper ([[P0900r0]]) discussing how
the variadic properties will work.</p>
<h1 data-number="2" id="description"><span class="header-section-number">2</span> Description<a href="#description" class="self-link"></a></h1>
<h2 data-number="2.1" id="what-we-propose-to-add"><span class="header-section-number">2.1</span> What we propose to add<a href="#what-we-propose-to-add" class="self-link"></a></h2>
<p>This paper proposes adding to the C++ Standard Library a
multidimensional array view, <code>mdspan</code>, along with classes,
class templates, and constants for describing and creating
multidimensional array views. It also proposes adding the
<code>submdspan</code> function that “slices” (returns an
<code>mdspan</code> that views a subset of) an existing mdspan`.</p>
<p>The <code>mdspan</code> class template can represent arbitrary mixes
of compile-time or run-time extents. Its element type can be any
complete object type that is neither an abstract class type nor an array
type. It has two customization opportunities for users: the <em>layout
mapping</em> and the <em>accessor</em>. The layout mapping specifies the
formula, and properties of the formula, for mapping a multidimensional
index to an element of the array. The accessor governs how elements are
read and written.</p>
<h2 data-number="2.2" id="definitions"><span class="header-section-number">2.2</span> Definitions<a href="#definitions" class="self-link"></a></h2>
<p>A <em>multidimensional array view</em> views a multidimensional
array, just as a <code>span</code> views a one-dimensional
<code>array</code> or <code>vector</code>.</p>
<p>A <em>multidimensional array</em> of <em>rank</em> <math>R</math>
maps from a tuple of <math>R</math> indices to a single offset index.
Each of the <math>R</math> indices in the tuple is in a bounded range
whose inclusive lower bound is zero, and whose nonnegative exclusive
upper bound is that index’s <em>extent</em>. The array thus has
<math>R</math> extents. The offset index ranges over a subset of a
bounded contiguous index range whose lower bound is zero, and whose
upper bound is the product of the <math>R</math> extents.</p>
<p>More formally, a multidimensional array of rank <math>R</math> maps
from its <em>domain</em>, a multidimensional index space of rank
<math>R</math>, to its <em>codomain</em>, a set of objects accessible
from a contiguous range of integer indices. A <em>multidimensional index
space</em> of rank <math>R</math> is the Cartesian product <math>[0,
N<sub>0</sub>) ⨯ [0, N<sub>1</sub>) ⨯ … ⨯ [0, N<sub>R-1</sub>)</math> of
half-open integer intervals, where the <math>N<sub>k</sub></math> for
<math>k = 0</math>, …, <math>R-1</math> are the array’s extents. A
<em>multidimensional index</em> is a element of a multidimensional index
space.</p>
<h2 data-number="2.3" id="why-do-we-need-multidimensional-arrays"><span class="header-section-number">2.3</span> Why do we need multidimensional
arrays?<a href="#why-do-we-need-multidimensional-arrays" class="self-link"></a></h2>
<p>Multidimensional arrays are fundamental concepts in many fields,
including graphics, mathematics, statistics, engineering, and the
sciences. Many programming languages thus come with multidimensional
array data structures either as a core language feature, or as a tightly
integrated standard library. Example languages include Ada, ANSI Common
Lisp, APL, C#, Fortran, Julia, Matlab, Mathematica, Pascal, Python (via
NumPy), and Visual Basic. The original version of the Fortran language
for the IBM 704 featured arrays with one, two, or three extents (Backus
1956, pp. 10-11).</p>
<p>Multidimensional arrays have long been useful for representing large
amounts of data, describing points in physical space, or expressing
approximations of functions. They are a natural way to represent
mathematical objects like matrices and tensors. This makes
multidimensional arrays a critical data structure for many computations
at the heart of modern machine learning. In fact, one of the predominant
machine learning frameworks is called <a href="https://www.tensorflow.org/">TensorFlow</a>.</p>
<h2 data-number="2.4" id="why-are-existing-c-data-structures-not-enough"><span class="header-section-number">2.4</span> Why are existing C++ data
structures not enough?<a href="#why-are-existing-c-data-structures-not-enough" class="self-link"></a></h2>
<p>C++ currently has the following approaches that could be used to
represent multidimensional arrays:</p>
<ol type="1">
<li><p>“native” arrays where all the extents are compile-time constants,
like <code>int[3][4][5]</code>;</p></li>
<li><p>pointer-of-pointers(-of-pointers…), like <code>int***</code>, set
up as a data structure to view multidimensional data;</p></li>
<li><p>arrays-of-arrays(-of-arrays…) data structures, like
<code>vector&lt;vector&lt;array&lt;int, N&gt;&gt;&gt;</code>;
or</p></li>
<li><p><code>gslice</code>, which selects a subset of indices of a
<code>valarray</code> and can be used to impose a multidimensional array
layout on the <code>valarray</code>, in a way analogous to
<code>layout_stride</code>.</p></li>
</ol>
<p>If a multidimensional array has any extents that are not known at
compile time, Approach (1) does not work.</p>
<p>Approach (2) does not suffice as a stand-alone data structure,
because a pointer-of-pointers does not carry along the array’s run-time
extents. Users thus end up building some subset of <code>mdspan</code>’s
functionality to represent a multidimensional array view. Every run-time
extent other than the rightmost requires a separate memory allocation
for an array of pointers. A pointer-of-pointers also loses information
about any dimensions known at compile time. Users cannot arbitrarily mix
compile-time and run-time extents.</p>
<p>Approach (3) can mix <code>vector</code> and <code>array</code> to
represent extents known at run time resp. compile time. However, any use
of <code>vector</code> at any position other than the outermost results
in the data structure no longer having a contiguous memory allocation
(or a subset thereof) for the elements. This makes the data structure
incompatible with many libraries that expect a subset of a contiguous
allocation. Also, every run-time extent other than the rightmost
requires a separate memory allocation for an array of arrays. In
addition, each element access requires reading multiple memory locations
(“pointer chasing”). Finally, the inlining depth for an element access
is proportional to the array’s rank.</p>
<p>Approach (4) is meant for addressing many elements of a
<code>valarray</code> all at once. Even though <code>valarray</code>
itself is a one-dimensional array, one can use <code>gslice</code> to
make the <code>valarray</code> represent multidimensional data. Giving a
<code>gslice</code> to <code>valarray::operator[]</code> returns
something that references a subset of elements of the original
<code>valarray</code>. However, the result (a <code>gslice_array</code>
in the nonconst case, some type that might be an expression template in
the const case) is not guaranteed to have an <code>operator[]</code>.
Thus, it’s not a view, whereas our proposed <code>submdspan</code>
function always takes and returns a view. In the const case, the result
might even be a (deep) copy of the input. Finally, <code>gslice</code>
offers no efficient way to address a single element. The
<code>gslice</code> constructor takes strides and lengths as
<code>valarray</code>s and is meant for array-based computation.
Accessing a single element requires accessing the memory of three
<code>valarray</code>s.</p>
<h2 data-number="2.5" id="mixing-compile-time-and-run-time-extents"><span class="header-section-number">2.5</span> Mixing compile-time and
run-time extents<a href="#mixing-compile-time-and-run-time-extents" class="self-link"></a></h2>
<p>The fundamental reason to allow expressing extents at compile time is
performance. Knowing an extent at compile time enables many compiler
optimizations, such as unrolling and precomputing of offsets. These can
significantly improve the generated code. Not storing extents at run
time may help conserve registers and stack space.</p>
<p>In many fields, some extents are naturally known at compile time. For
many physics and engineering algorithms, some extents are dictated by
fundamental properties of the physical world or the discretization
scheme. For example, the position of a particle in space requires a
rank-3 array, since physical space has three dimensions. At the same
time, other extents are only known at run time, such as the number of
particles in a simulation. A natural data structure for storing a list
of particles would thus be a rank-2 array, where the one run-time extent
is the number of particles and the one compile-time extent is three. In
graphics, some of the most fundamental objects are square matrices with
2, 3, or 4 rows and columns. The number of matrices with which one would
like to compute might only be known at run time. This would make a
rank-3 array with two compile-time extents a natural data structure for
the matrices.</p>
<h2 data-number="2.6" id="why-custom-memory-layouts"><span class="header-section-number">2.6</span> Why custom memory layouts?<a href="#why-custom-memory-layouts" class="self-link"></a></h2>
<p>Our <code>mdspan</code> class template permits custom layouts. Our
proposal comes with three memory layouts:</p>
<ul>
<li><p><code>layout_right</code>: C or C++ style, row major, where the
rightmost index gives stride-1 access to the underlying memory;</p></li>
<li><p><code>layout_left</code>: Fortran or Matlab style, column major,
where the leftmost index gives stride-1 access to the underlying
memory;</p></li>
<li><p><code>layout_stride</code>: a generalization of the two layouts
above, which stores a separate stride (possibly not one) for each
extent.</p></li>
</ul>
<p>“Custom” layouts besides these could include space-filling curves or
“tiled” layouts.</p>
<p>An important reason we allow different layouts is language
interoperability. For example, C++ and Fortran have different “native”
layouts. Python’s NumPy arrays have a configurable layout, to provide
compatibility with both languages.</p>
<p>Control of the layout can also be used to write code that performs
well on different computer architectures when only changing a template
argument. Consider the following implementation of a parallel dense
matrix-vector product.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> layout <span class="op">=</span> <span class="co">/* see-below */</span>;</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>mdspan<span class="op">&lt;</span><span class="dt">double</span>, std<span class="op">::</span>extents<span class="op">&lt;</span>N, M<span class="op">&gt;</span>, layout<span class="op">&gt;</span> A <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>mdspan<span class="op">&lt;</span><span class="dt">double</span>, std<span class="op">::</span>extents<span class="op">&lt;</span>N<span class="op">&gt;&gt;</span> y <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>mdspan<span class="op">&lt;</span><span class="dt">double</span>, std<span class="op">::</span>extents<span class="op">&lt;</span>M<span class="op">&gt;&gt;</span> x <span class="op">=</span> <span class="op">...</span>;</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>ranges<span class="op">::</span>iota_view range<span class="op">{</span><span class="dv">0</span>, N<span class="op">}</span>;</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>std<span class="op">::</span>for_each<span class="op">(</span>std<span class="op">::</span>execution<span class="op">::</span>par_unseq, </span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>  std<span class="op">::</span>ranges<span class="op">::</span>begin<span class="op">(</span>range<span class="op">)</span>, std<span class="op">::</span>ranges<span class="op">::</span>end<span class="op">(</span>range<span class="op">)</span>,</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">[=](</span><span class="dt">int</span> i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>     <span class="dt">double</span> sum <span class="op">=</span> <span class="fl">0.0</span>;</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>     <span class="cf">for</span><span class="op">(</span><span class="dt">int</span> j <span class="op">=</span> <span class="dv">0</span>; j <span class="op">&lt;</span> M; <span class="op">++</span>j<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>       sum <span class="op">+=</span> A<span class="op">[</span>i, j<span class="op">]</span> <span class="op">*</span> x<span class="op">[</span>j<span class="op">]</span>;</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>     <span class="op">}</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>     y<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> sum;</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">})</span>;</span></code></pre></div>
<p>On conventional CPU architectures, this code performs well with
<code>layout = layout_right</code>, the native C++ row-major layout.
However, when offloading the <code>for_each</code> to NVIDIA GPUs (which
NVIDIA’s <code>nvc++</code> compiler can do),
<code>layout = layout_left</code> (Fortran’s column-major layout)
performs much better, since it enables coalesced data access on the
matrix <code>A</code>.</p>
<p>However, it is not enough to have just C++ and Fortran memory
mappings. For instance, one way to compute tensor products is to
decompose them into many matrix-matrix multiplications. The resulting
decomposition may involve matrices with non-unit strides in both
extents. This means that they have neither a row-major nor a
column-major layout.</p>
<p>More complex layouts can improve performance significantly for some
algorithms. For instance, tiling (a “matrix of small matrices” layout)
can improve data locality for many computations relevant to linear
algebra and the discretization of partial differential equations. Tiled
layouts can also improve vectorization. For example, Intel’s Math Kernel
Library introduced the Vectorized Compact Routines. These provide
“batched” matrix operations that increase available parallelism by
operating on many matrices at once. The Vectorized Compact Routines
accept matrices in an “interleaved” layout that optimizes vectorized
memory access.</p>
<p>Another design goal for our custom layouts is to permit nonunique
layouts. A <em>nonunique</em> layout lets multiple index tuples refer to
the same element. This can save memory for data structures that have
natural symmetry. For example, if <code>A</code> is a symmetric matrix,
then <code>A[i,j]</code> and <code>A[j,i]</code> refer to the same
element, so the element can and should only be stored once.</p>
<h2 data-number="2.7" id="why-custom-accessors"><span class="header-section-number">2.7</span> Why custom accessors?<a href="#why-custom-accessors" class="self-link"></a></h2>
<p>Custom accessors can provide information to the compiler, or permit
the injection of special ways of doing data access. Most hardware today
has more ways to access data than simple reads and writes. For example,
some instructions affect caching behavior, by making loads and/or stores
nontemporal (not cached at some level) or even noncoherent. Other
instructions implement atomic access. This is why several of us proposed
<code>atomic_ref</code>, as the heart of an “atomic accessor” for
<code>mdspan</code>. C’s <code>restrict</code> qualifier conveys whether
an array is assumed never to alias another array in some context. The
<code>volatile</code> keyword is yet another qualifier which limits
compiler optimizations around data access. Custom <code>mdspan</code>
accessors can apply <code>restrict</code> (if the C++ implementation
supports this extension) or <code>volatile</code> to array accesses.</p>
<p>Custom accessors also address concerns relating to heterogeneous
memory. Standard C++ does not have the idea of “memory spaces that
normal code cannot access,” but many extensions to C++ do have this
idea. For example, a custom accessor could convey accessibility by CPU
or GPU threads, so that the compiler would prevent users from accessing
GPU memory while running on the CPU, or vice versa. Multiple memory
spaces occur in programming models other than for GPUs. For example,
“partitioned global address space” models have a “global shared memory”
that requires special operations to access. C++ libraries like <a href="https://github.com/kokkos/kokkos">Kokkos</a> expose access to such
memory using an analog of a custom accessor. Other accessors could
expose an array interface to a persistent storage device that is not
directly byte addressable. We do not propose such accessors here, but
this is a customization point third-party libraries could directly use,
and is available for any future extensions of the C++ standard for
supporting heterogeneous memory.</p>
<p>For a discussion of the idea of accessors and several examples,
please see (Keryell and Falcou 2016).</p>
<h2 data-number="2.8" id="subspan-support"><span class="header-section-number">2.8</span> Subspan Support<a href="#subspan-support" class="self-link"></a></h2>
<p>A critical feature of this proposal is <code>submdspan</code>, the
subspan or “slicing” function that returns a view of a subset of an
existing <code>mdspan</code>. The result may have any rank up to and
including the rank of the input. All of the aforementioned languages
with multidimensional array support provide subspan capabilities.
Subspans are important because they enable code reuse. For example, the
inner loop in the dense matrix-vector product described above actually
represents a <em>dot product</em> – an inner product of two vectors. If
one already has a function for such an inner product, then a natural
implementation would simply reuse that function. The LAPACK linear
algebra library depends on subspan reuse for the performance of its
one-sided “blocked” matrix factorizations (Cholesky, LU, and QR). These
factorizations reuse textbook non-blocked algorithms by calling them on
groups of contiguous columns at a time. This lets LAPACK spend as much
time in dense matrix-matrix multiply (or algorithms with analogous
performance) as possible.</p>
<h2 data-number="2.9" id="why-propose-a-multidimensional-array-view-before-a-container"><span class="header-section-number">2.9</span> Why propose a multidimensional
array view before a container?<a href="#why-propose-a-multidimensional-array-view-before-a-container" class="self-link"></a></h2>
<p>Factoring views from containers generally makes sense. For example,
one often sees functions that take <code>vector</code> by reference when
they only need to access the <code>vector</code>’s elements or call
<code>.size()</code> on it. This is one reason for <code>span</code>.
Some of us have proposed a multidimensional array container,
<code>mdarray</code> <a href="wg21.link/p1684">P1684</a>, but we have
focused on <code>mdspan</code> because we consider views more
fundamental.</p>
<p>Many fields that compute with multidimensional arrays rely heavily on
shared-memory parallel programming, where multiple processing units
(threads, vector units, etc.) access different elements of the same
array in parallel. Memory allocation and deallocation are
“synchronization points” for parallel processing units, and thus hinder
parallelization. This makes just <em>viewing</em> a multidimensional
array, rather than managing its ownership, the most fundamental way for
parallel computations to express how they access an array.</p>
<p>It is often necessary to view previously allocated memory as a
multidimensional array. An important special case is when C++ code is
calling or being called from another programming language, such as C,
Fortran, or Python. This use case matters enough to Python that its C
API defines a <a href="https://docs.python.org/3/c-api/buffer.html">Buffer Protocol</a>
for viewing multidimensional arrays across languages. Language
interoperability is key to the success of the various Python-based data
analysis frameworks built up around NumPy.</p>
<h2 data-number="2.10" id="use-multiple-parameter-operator-for-array-access"><span class="header-section-number">2.10</span> Use multiple-parameter
operator[] for array access<a href="#use-multiple-parameter-operator-for-array-access" class="self-link"></a></h2>
<p>We welcome multiple-parameter <code>operator[]</code> as the
preferred multidimensional array access operator. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1161r3.html">P1161R3</a>,
now part of C++20, prepared the way for this by deprecating comma
expressions inside <code>operator[]</code> invocations. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2128r6.pdf">P2128R6</a>,
which proposed changing <code>operator[]</code> to accept multiple
parameters, was approved at the October 2021 WG21 Plenary meeting.
Please refer to P2128 for an extensive discussion.</p>
<p>Many existing libraries use the function call <code>operator()</code>
for multidimensional array access, with <code>operator[]</code>
available for rank-1 (single-dimensional) <code>mdspan</code>. P2128
gives examples. It’s straightforward to adapt these libraries to
transition to <code>mdspan</code>. For example, a subclass or wrapper of
<code>mdspan</code> can provide an <code>operator()</code> that simply
forwards to <code>mdspan::operator[]</code>. The subclass or wrapper can
then deprecate <code>operator()</code> to help developers find and
change all the code that uses it.</p>
<h2 data-number="2.11" id="reference-implementation"><span class="header-section-number">2.11</span> Reference Implementation<a href="#reference-implementation" class="self-link"></a></h2>
<p>A reference implementation of this proposal under BSD license is
available at: <a href="https://github.com/kokkos/mdspan">mdspan</a>.
This implementation is also available on godbolt for experimentation: <a href="https://godbolt.org/z/ehErvsTce">godbolt</a>.</p>
<h2 data-number="2.12" id="references"><span class="header-section-number">2.12</span> References<a href="#references" class="self-link"></a></h2>
<ul>
<li><p>J. W. Backus et al. “Programmer’s Reference Manual: Fortran
Automatic Coding System for the IBM 704.” Applied Science Division and
Programming Research Department, International Business Machines
Corporation, Oct. 15, 1956. <a href="https://archive.computerhistory.org/resources/text/Fortran/102649787.05.01.acc.pdf">Available
online</a> (last accessed Oct. 10, 2021).</p></li>
<li><p>D. Hollman, C. Trott, M. Hoemmen, and D. Sunderland.
“<code>mdarray</code>: An Owning Multidimensional Array Analog of
<code>mdspan</code>.” P1684r0, May 28, 2019. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1684r0.pdf">Available
online</a> (last accessed Oct. 10, 2021).</p></li>
<li><p>R. Keryell and J. Falcou. “Accessors: A C++ standard library
class to qualify data accesses.” P0367r0, May 29, 2016. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0367r0.pdf">Available
online</a> (last accessed Oct. 10, 2021).</p></li>
</ul>
<h1 data-number="3" id="editing-notes"><span class="header-section-number">3</span> Editing Notes<a href="#editing-notes" class="self-link"></a></h1>
<p>The proposed changes are relative to the working draft of the
standard as of <a href="http://wg21.link/n4842">N4842</a>.</p>
<p>The � character is used to denote a placeholder section number, table
number, or paragraph number which the editor shall determine.</p>
<p>Add the header <code>&lt;mdspan&gt;</code> to the “C++ library
headers” table in <b>[headers]</b> in a place that respects the table’s
current alphabetic order.</p>
<p>Add the header <code>&lt;mdspan&gt;</code> to the “Containers library
summary” table in <b>[containers.general]</b> below the listing for
<code>&lt;span&gt;</code>.</p>
<!--

 /$$      /$$                           /$$ /$$
| $$  /$ | $$                          | $$|__/
| $$ /$$$| $$  /$$$$$$   /$$$$$$   /$$$$$$$ /$$ /$$$$$$$   /$$$$$$
| $$/$$ $$ $$ /$$__  $$ /$$__  $$ /$$__  $$| $$| $$__  $$ /$$__  $$
| $$$$_  $$$$| $$  \ $$| $$  \__/| $$  | $$| $$| $$  \ $$| $$  \ $$
| $$$/ \  $$$| $$  | $$| $$      | $$  | $$| $$| $$  | $$| $$  | $$
| $$/   \  $$|  $$$$$$/| $$      |  $$$$$$$| $$| $$  | $$|  $$$$$$$
|__/     \__/ \______/ |__/       \_______/|__/|__/  |__/ \____  $$
                                                          /$$  \ $$
                                                         |  $$$$$$/
                                                          \______/
-->
<h1 data-number="4" id="wording"><span class="header-section-number">4</span> Wording<a href="#wording" class="self-link"></a></h1>
<blockquote>
<p><em>The � character is used to denote a placeholder section number
which the editor shall determine.</em></p>
</blockquote>
<blockquote>
<p><em>In <b>[version.syn]</b>, add:</em></p>
</blockquote>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define __cpp_lib_mdspan </span>YYYYMML<span class="pp"> </span><span class="co">// also in &lt;mdspan&gt;</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
Adjust the placeholder value as needed so as to denote this proposal’s
date of adoption.</p>
<blockquote>
<p><em>Make the following changes to 22.7.1
<b>[views.general]</b></em>,</p>
</blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
The header <code>&lt;span&gt;</code> defines the view span. <span class="add" style="color: #6.0e28"><ins>The header
<span><code>&lt;mdspan&gt;</code></span> defines the class template
<span><code>mdspan</code></span> and other facilities for interacting
with these multidimensional views.</ins></span></p>
<hr />
<blockquote>
<p><em>Add the following subclauses to the end of the <b>[views]</b>
subclause (after <code>span</code>):</em></p>
</blockquote>
<!--
 .d8888b.                                               d8b
d88P  Y88b                                              Y8P
Y88b.
 "Y888b.   888  888 88888b.   .d88b.  88888b.  .d8888b  888 .d8888b
    "Y88b. 888  888 888 "88b d88""88b 888 "88b 88K      888 88K
      "888 888  888 888  888 888  888 888  888 "Y8888b. 888 "Y8888b.
Y88b  d88P Y88b 888 888  888 Y88..88P 888 d88P      X88 888      X88
 "Y8888P"   "Y88888 888  888  "Y88P"  88888P"   88888P' 888  88888P'
                888                   888
           Y8b d88P                   888
            "Y88P"                    888
-->
<p><br /> <b>22.7.� Header <code>&lt;mdspan&gt;</code> synopsis
[mdspan.syn]</b></p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.extents], class template extents</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span><span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">class</span> extents;</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span> Rank<span class="op">&gt;</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> dextents <span class="op">=</span> <em>see below</em>;</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.layout], Layout mapping policies</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> layout_left;</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> layout_right;</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> layout_stride;</span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.accessor.default]</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ElementType<span class="op">&gt;</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">class</span> default_accessor;</span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.mdspan], class template mdspan</span></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> Extents, <span class="kw">class</span> LayoutPolicy <span class="op">=</span> layout_right,</span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>           <span class="kw">class</span> AccessorPolicy <span class="op">=</span> default_accessor<span class="op">&lt;</span>ElementType<span class="op">&gt;&gt;</span></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">class</span> mdspan;</span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.submdspan]</span></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> Extents, <span class="kw">class</span> LayoutPolicy,</span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a>           <span class="kw">class</span> AccessorPolicy, <span class="kw">class</span><span class="op">...</span> SliceSpecifiers<span class="op">&gt;</span></span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> submdspan<span class="op">(</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> mdspan<span class="op">&lt;</span>ElementType, Extents, LayoutPolicy, AccessorPolicy<span class="op">&gt;&amp;</span>,</span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a>      SliceSpecifiers<span class="op">...)</span> <span class="op">-&gt;</span> <em>see below</em>;</span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a>  <span class="co">// tag supporting submdspan</span></span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a>  <span class="kw">struct</span> full_extent_t <span class="op">{</span> <span class="kw">explicit</span> full_extent_t<span class="op">()</span> <span class="op">=</span> <span class="cf">default</span>; <span class="op">}</span>;</span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true" tabindex="-1"></a>  <span class="kw">inline</span> <span class="kw">constexpr</span> full_extent_t full_extent<span class="op">{}</span>;</span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><b>22.7.� Overview [mdspan.terms]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
A <em>multidimensional index space</em> is a Cartesian product of
integer intervals. Each interval can be represented by a half-open range
<span class="math inline">[<em>I</em><sub><em>b</em></sub>, <em>I</em><sub><em>e</em></sub>)</span>,
where <span class="math inline"><em>I</em><sub><em>b</em></sub></span>
and <span class="math inline"><em>I</em><sub><em>e</em></sub></span> are
the lower and upper bounds of the <span class="math inline"><em>i</em><sup><em>t</em><em>h</em></sup></span>
dimension. The <em>rank</em> of a multidimensional index space is the
number of intervals it represents.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
A pack of integers <code>idx...</code> is a <em>multidimensional
index</em> into a multidimensional index space <span class="math inline"><em>S</em></span> (or representation thereof) if
both of following are true:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.1)</a></span>
<code>sizeof...(idx)</code> is equal to rank of S, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.2)</a></span> For
all <span class="math inline"><em>i</em></span> in the range <span class="math inline">[0,</span>rank<span class="math inline">)</span>,
the <span class="math inline"><em>i</em><sup><em>t</em><em>h</em></sup></span>
value of <code>idx</code> is an integer in the interval <span class="math inline">[<em>I</em><sub><em>b</em></sub>, <em>I</em><sub><em>e</em></sub>)</span>
of <span class="math inline"><em>S</em></span>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
An integer <code>r</code> is a <em>rank index</em> of an index space
<span class="math inline"><em>S</em></span> (or representation thereof)
if <span class="math inline"><em>r</em></span> is in the range <span class="math inline">[0,</span>rank<span class="math inline">)</span>.</p>
<!--
                  888                     888
                  888                     888
                  888                     888
 .d88b.  888  888 888888 .d88b.  88888b.  888888 .d8888b
d8P  Y8b `Y8bd8P' 888   d8P  Y8b 888 "88b 888    88K
88888888   X88K   888   88888888 888  888 888    "Y8888b.
Y8b.     .d8""8b. Y88b. Y8b.     888  888 Y88b.       X88
 "Y8888  888  888  "Y888 "Y8888  888  888  "Y888  88888P'


-->
<p><b>22.7.� Class template <code>extents</code>
[mdspan.extents]</b></p>
<p><b>22.7.�.1 Overview [mdspan.extents.overview]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
The class template <code>extents</code> represents a multidimensional
index space of rank equal to <code>sizeof...(Extents)</code>.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span><span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> extents <span class="op">{</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> size_type <span class="op">=</span> <span class="dt">size_t</span>;</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.extents.cons], Constructors and assignment</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> extents<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> extents<span class="op">(</span><span class="kw">const</span> extents<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> extents<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> extents<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> extents<span class="op">(</span><span class="kw">const</span> extents<span class="op">&lt;</span>OtherExtents<span class="op">...&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> SizeTypes<span class="op">&gt;</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span> <span class="kw">constexpr</span> extents<span class="op">(</span>SizeTypes<span class="op">...)</span> <span class="kw">noexcept</span>;</span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span><span class="op">(</span>N <span class="op">!=</span> rank_dynamic<span class="op">())</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> extents<span class="op">(</span><span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.extents.obs], Observers of the domain multidimensional index space</span></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> rank<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">sizeof</span><span class="op">...(</span>Extents<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> rank_dynamic<span class="op">()</span> <span class="kw">noexcept</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span> <span class="cf">return</span> <span class="op">((</span>Extents <span class="op">==</span> dynamic_extent<span class="op">)</span> <span class="op">+</span> <span class="op">...</span> <span class="op">+</span> <span class="dv">0</span><span class="op">)</span>; <span class="op">}</span></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> size_type static_extent<span class="op">(</span><span class="dt">size_t</span><span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> size_type extent<span class="op">(</span><span class="dt">size_t</span><span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.extents.compare], extents comparison operators</span></span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a>    <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> extents<span class="op">&amp;</span>, <span class="kw">const</span> extents<span class="op">&lt;</span>OtherExtents<span class="op">...&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> <em>dynamic-index</em><span class="op">(</span><span class="dt">size_t</span><span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> <em>dynamic-index-inv</em><span class="op">(</span><span class="dt">size_t</span><span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true" tabindex="-1"></a>  array<span class="op">&lt;</span>size_type, rank_dynamic<span class="op">()&gt;</span> <em>dynamic-extents</em><span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Integrals<span class="op">&gt;</span></span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> extents<span class="op">(</span>Integrals<span class="op">...)</span></span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> extents<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span>
<span id="cb8-42"><a href="#cb8-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-43"><a href="#cb8-43" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span> <span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb8-44"><a href="#cb8-44" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">size_t</span> <em>fwd-prod-of-extents</em><span class="op">(</span>extents<span class="op">&lt;</span>Extents<span class="op">...&gt;</span>, <span class="dt">size_t</span><span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb8-45"><a href="#cb8-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-46"><a href="#cb8-46" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span> <span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb8-47"><a href="#cb8-47" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">size_t</span> <em>rev-prod-of-extents</em><span class="op">(</span>extents<span class="op">&lt;</span>Extents<span class="op">...&gt;</span>, <span class="dt">size_t</span><span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb8-48"><a href="#cb8-48" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<code>extents&lt;Extents...&gt;</code> is a trivially copyable type.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
Let <span class="math inline"><em>E</em><sub><em>r</em></sub></span> be
the <span class="math inline"><em>r</em><sup><em>t</em><em>h</em></sup></span>
element of <span class="math inline"><em>E</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em></span>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a
<em>dynamic extent</em> if it is equal to <code>dynamic_extent</code>,
otherwise <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a
<em>static extent</em>.</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
Let <span class="math inline"><em>D</em><sub><em>r</em></sub></span> be
the value of
<em><code>dynamic-extents</code></em><code>[</code><em><code>dynamic-index</code></em><code>(</code><em>r</em><code>)]</code>
if <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a
dynamic extent, otherwise <span class="math inline"><em>E</em><sub><em>r</em></sub></span>.</p>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
The <span class="math inline"><em>r</em><sup><em>t</em><em>h</em></sup></span>
interval of an <code>extents</code> object is <span class="math inline">[0, <em>D</em><sub><em>r</em></sub>)</span>.</p>
<hr />
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">size_t</span> <em>dynamic-index</em><span class="op">(</span><span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Precondition:</em> <code>i &lt;= rank()</code> is
<code>true</code></p>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Returns:</em> Number of <span class="math inline"><em>E</em><sub><em>r</em></sub></span> with <span class="math inline"><em>r</em> &lt; <em>i</em></span> for which <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a dynamic
extent.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">size_t</span> <em>dynamic-index-inv</em><span class="op">(</span><span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<em>Precondition:</em> <code>i &lt; rank_dynamic()</code> is
<code>true</code></p>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Returns:</em> Minimum value of <span class="math inline"><em>r</em></span> such that
<em><code>dynamic-index</code></em><code>(</code><span class="math inline"><em>r</em></span><code>+1) == i+1</code> is
<code>true</code>.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span> <span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">size_t</span> <em>fwd-prod-of-extents</em><span class="op">(</span>extents<span class="op">&lt;</span>Extents<span class="op">...&gt;</span> e, <span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Precondition:</em> <code>i &lt; e.rank()</code> is
<code>true</code></p>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span>
<em>Returns:</em> If <code>i &gt; 0</code> is <code>true</code> product
of <code>e.extent(k)</code> for all <code>k</code> in the range <span class="math inline">[0,</span> <code>i</code> <span class="math inline">)</span>, otherwise <code>1</code>.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span> <span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">size_t</span> <em>rev-prod-of-extents</em><span class="op">(</span>extents<span class="op">&lt;</span>Extents<span class="op">...&gt;</span>, <span class="dt">size_t</span><span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span>
<em>Precondition:</em> <code>i &lt; e.rank()</code> is
<code>true</code></p>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span>
<em>Returns:</em> If <code>i+1 &lt; e.rank()</code> is <code>true</code>
product of <code>e.extent(k)</code> for all <code>k</code> in the range
<span class="math inline">[</span> <code>i</code> <span class="math inline">,</span> <code>e.rank()</code> <span class="math inline">)</span>, otherwise <code>1</code>.</p>
<p><b>22.7.�.3 Constructors and assignment [mdspan.extents.cons]</b></p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> extents<span class="op">(</span><span class="kw">const</span> extents<span class="op">&lt;</span>OtherExtents<span class="op">...&gt;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span>
<code>sizeof...(OtherExtents) == rank()</code> is
<code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span>
<code>((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents == Extents) &amp;&amp; ...)</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Preconditions:</em> For each rank index <code>r</code> of
<code>*this</code>,
<code>static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)</code>
is <code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Postconditions:</em> <code>*this == other</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Remarks:</em> The expression inside <code>explicit</code> is
equivalent to:
<code>(((Extents!=dynamic_extent) &amp;&amp; (OtherExtents==dynamic_extent)) || ... )</code>
<br /></p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> SizeTypes<span class="op">&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> extents<span class="op">(</span>SizeTypes<span class="op">...</span> exts<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.1)</a></span>
<code>(is_convertible_v&lt;SizeTypes, size_type&gt; &amp;&amp; ...)</code>
is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.2)</a></span>
<code>(is_nothrow_constructible_v&lt;size_type, SizeTypes&gt; &amp;&amp; ...)</code>
is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.3)</a></span>
<code>sizeof...(SizeTypes) == rank_dynamic() || sizeof...(SizeTypes) == rank()</code>
is <code>true</code>. <i>[Note:</i> One can construct
<code>extents</code> from just <em>dynamic extents</em>, which are all
the values getting stored, or from all the extents with a precondition.
<i>— end note]</i></p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
Let <code>exts_arr</code> be
<code>std::array&lt;size_type,sizeof...(SizeTypes)&gt;{static_cast&lt;size_type&gt;(std::move(exts))...}</code></p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Preconditions:</em> If
<code>sizeof...(SizeTypes) != rank_dynamic()</code> is
<code>true</code>, <code>exts_arr[r]</code> equals <span class="math inline"><em>E</em><sub><em>r</em></sub></span> for each
<span class="math inline"><em>r</em></span> for which <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a
<em>static extent</em>.</p>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Postconditions:</em> <code>*this == extents(exts_arr)</code> is
<code>true</code>.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(</span>N <span class="op">!=</span> rank_dynamic<span class="op">())</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> extents<span class="op">(</span><span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;</span> exts<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.1)</a></span>
<code>is_convertible_v&lt;const SizeType&amp;, size_type&gt;</code>
equals <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.2)</a></span>
<code>is_nothrow_constructible_v&lt;size_type, const SizeType&amp;&gt;</code>
is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.3)</a></span>
<code>N</code> equals <code>rank_dynamic()</code> or
<code>rank()</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Preconditions:</em> If <code>N + rank_dynamic()</code> is
<code>true</code>, <code>exts[r]</code> equals <span class="math inline"><em>E</em><sub><em>r</em></sub></span> for each
<span class="math inline"><em>r</em></span> for which <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a
<em>static extent</em>.</p>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(11.1)</a></span> If
<code>N</code> equals <code>dynamic_rank()</code>,
direct-non-list-initializes <em><code>dynamic-extent</code></em> with
<code>exts</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(11.2)</a></span>
Otherwise, for all <span class="math inline"><em>d</em></span> in the
range <span class="math inline">[0,</span>
<code>rank_dynamic()</code><span class="math inline">)</span>,
direct-non-list-initializes
<em><code>dynamic-extent</code></em><code>[d]</code> with
<code>exts[</code><em><code>dynamic-index-inv</code></em><code>(d)]</code>.</p></li>
</ul>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Integrals<span class="op">&gt;</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> extents<span class="op">(</span>Integrals<span class="op">...)</span> <span class="op">-&gt;</span> extents<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span>
<em>Constraints:</em>
<code>(is_convertible_v&lt;Integrals, size_t&gt; &amp;&amp; ...)</code>
is <code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span>
<em>Remarks:</em> The deduced type is
<code>dextents&lt;sizeof...(Integrals)&gt;</code>.</p>
<p><br /> <b>22.7.�.3 Observers of the domain multidimensional index
space [mdspan.extents.obs]</b></p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> size_type static_extent<span class="op">(</span><span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Preconditions:</em> <code>i &lt; rank()</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Returns:</em> <span class="math inline"><em>E</em><sub><em>i</em></sub></span>.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> size_type extent<span class="op">(</span><span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Preconditions:</em> <code>i &lt; rank()</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Returns:</em> <span class="math inline"><em>D</em><sub><em>i</em></sub></span>.</p>
<p><br /> <b>22.7.�.4 <code>extents</code> comparison operators
[mdspan.extents.compare]</b></p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> extents<span class="op">&amp;</span> lhs, </span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>                                   <span class="kw">const</span> extents<span class="op">&lt;</span>OtherExtents<span class="op">...&gt;&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Returns:</em> true if <code>lhs.rank()</code> equals
<code>rhs.rank()</code> and <code>lhs.extents(r)</code> equals
<code>rhs.extents(r)</code> for every rank index <code>r</code> of
<code>rhs</code>, otherwise <code>false</code>.</p>
<p><br /> <b>22.7.�.5 Template alias <code>dextents</code>
[mdspan.extents.dextents]</b></p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">size_t</span> Rank<span class="op">&gt;</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> dextents <span class="op">=</span> <em>see below</em>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Result:</em> A type <code>E</code> that is a specialization of
<code>extents</code> such that
<code>E::rank() == Rank &amp;&amp; E::rank() == E::rank_dynamic()</code>
is <code>true</code>.</p>
<!--
888                                     888                                                  d8b
888                                     888                                                  Y8P
888                                     888
888  8888b.  888  888  .d88b.  888  888 888888      88888b.d88b.   8888b.  88888b.  88888b.  888 88888b.   .d88b.
888     "88b 888  888 d88""88b 888  888 888         888 "888 "88b     "88b 888 "88b 888 "88b 888 888 "88b d88P"88b
888 .d888888 888  888 888  888 888  888 888         888  888  888 .d888888 888  888 888  888 888 888  888 888  888
888 888  888 Y88b 888 Y88..88P Y88b 888 Y88b.       888  888  888 888  888 888 d88P 888 d88P 888 888  888 Y88b 888
888 "Y888888  "Y88888  "Y88P"   "Y88888  "Y888      888  888  888 "Y888888 88888P"  88888P"  888 888  888  "Y88888
                  888                                                      888      888                        888
             Y8b d88P                                                      888      888                   Y8b d88P
              "Y88P"                                                       888      888                    "Y88P"
-->
<p><br /> <br /> <b>22.7.� Layout mapping policy [mdspan.layout]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
In subclause 22.7.�.1 and subclause 22.7.�.2</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span>
<code>M</code> denotes a layout mapping class.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span>
<code>MP</code> denotes a layout mapping policy class.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.3)</a></span>
<code>m</code> denotes a (possibly const) value of type
<code>M</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.4)</a></span>
<code>E</code> denotes a specialization of
<code>extents</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.5)</a></span>
<code>e</code> denotes a (possibly const) value of type
<code>E</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.6)</a></span>
<code>i...</code> and <code>j...</code> are multidimensional indices
into <code>e</code> ([mdspan.terms]).</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.7)</a></span>
<code>r</code> is a (possibly const) rank index.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.8)</a></span>
<code>dr...</code> is a (possibly const) pack of integers for which
<code>sizeof...(dr) == e.rank()</code> is <code>true</code>, the
<code>r</code>-th element is equal to <code>1</code>, and all other
elements are equal to <code>0</code>.</p></li>
</ul>
<p><b>22.7.�.2 Layout mapping requirements
[mdspan.layout.reqmts]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
A type <code>M</code> meets the <em>layout mapping</em> requirements if
<code>M</code> meets the requirements of
<em>Cpp17CopyConstructible</em>, <em>Cpp17CopyAssignable</em>, and
<em>Cpp17EqualityComparable</em>, and the following types and
expressions are well-formed and have the specified semantics.</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>is_nothrow_move_constructible_v<span class="op">&lt;</span>M<span class="op">&gt;</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Value:</em> <code>true</code>.</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>is_nothrow_move_assignable_v<span class="op">&lt;</span>M<span class="op">&gt;</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Value:</em> <code>true</code>.</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typename</span> M<span class="op">::</span>extents_type</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Result:</em> <code>E</code>.</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typename</span> M<span class="op">::</span>size_type</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Result:</em> <code>typename M::extents_type::size_type</code>.</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typename</span> M<span class="op">::</span>layout_type</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Result:</em> <code>MP</code></p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Preconditions:</em>
<code>is_same_v&lt;typename MP::template mapping&lt;typename M::extents_type&gt;, M&gt;</code>
is <code>true</code> and <code>MP</code> meets the <em>layout mapping
policy</em> requirements ([mdspan.layoutpolicy.reqmts]).</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a>m<span class="op">.</span>extents<span class="op">()</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Result:</em> <code>const typename M::extents_type&amp;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<em>Value:</em> <code>e</code></p>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a>m<span class="op">(</span>i<span class="op">...)</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Result:</em> <code>typename M::size_type</code></p>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Postcondition:</em>
<code>m(i...)==m(static_cast&lt;typename M::size_type&gt;(i)...)</code>
is <code>true</code>.</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>m<span class="op">.</span>required_span_size<span class="op">()</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span>
<em>Result:</em> <code>typename M::size_type</code></p>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span>
<em>Value:</em> If the multidimensional index space that <code>e</code>
defines is empty, then <code>0</code>, else <code>1</code> plus the
maximum value of <code>m(i...)</code> for all <code>i...</code> in
<code>e</code>.</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>m<span class="op">.</span>is_unique<span class="op">()</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span>
<em>Result:</em> <code>bool</code></p>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span>
<em>Value:</em> <code>true</code> if for every <code>i...</code> and
<code>j...</code> where <code>(i != j || ...)</code> is
<code>true</code>, <code>m(i...) != m(j...)</code> is <code>true</code>.
Otherwise <code>false</code>.</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a>m<span class="op">.</span>is_contiguous<span class="op">()</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span>
<em>Result:</em> <code>bool</code></p>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span>
<em>Value:</em> <code>true</code> if for all <span class="math inline"><em>k</em></span> in the range <span class="math inline">[0,</span> <code>m.required_span_size()</code> <span class="math inline">)</span> there exists an <code>i...</code> such that
<code>m(i...)</code> equals <span class="math inline"><em>k</em></span>.
Otherwise <code>false</code>.</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>m<span class="op">.</span>is_strided<span class="op">()</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">18</a></span>
<em>Result:</em> <code>bool</code></p>
<p><span class="marginalizedparent"><a class="marginalized">19</a></span>
<em>Value:</em> <code>true</code> if for every <code>r</code> there
exists an integer <code>sr</code> such that, for all <code>i...</code>
where <code>(i+dr)...</code> is a multidimensional index into
<code>e</code> ([mdspan.terms]), <code>m((i+dr)...) - m(i...)</code>
equals <code>sr</code>. Otherwise, <code>false</code>.</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a>M<span class="op">::</span>is_always_unique<span class="op">()</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">20</a></span>
<em>Result:</em> <code>bool</code></p>
<p><span class="marginalizedparent"><a class="marginalized">21</a></span>
<em>Value:</em> <code>true</code> if <code>m.is_unique()</code> is
<code>true</code> for all objects <code>m</code> of type <code>M</code>.
Otherwise, <code>false</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">22</a></span>
<em>Remarks:</em> <code>M::is_always_unique()</code> is a core constant
expression ([expr.const]).</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a>M<span class="op">::</span>is_always_contiguous<span class="op">()</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">23</a></span>
<em>Result:</em> <code>bool</code></p>
<p><span class="marginalizedparent"><a class="marginalized">24</a></span>
<em>Value:</em> <code>true</code> if <code>m.is_contiguous()</code> is
<code>true</code> for all objects <code>m</code> of type <code>M</code>.
Otherwise, <code>false</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">25</a></span>
<em>Remarks:</em> <code>M::is_always_contiguous()</code> is a core
constant expression ([expr.const]).</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a>M<span class="op">::</span>is_always_strided<span class="op">()</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">26</a></span>
<em>Result:</em> <code>bool</code></p>
<p><span class="marginalizedparent"><a class="marginalized">27</a></span>
<em>Value:</em> <code>true</code> if <code>m.is_strided()</code> is
<code>true</code> for all objects <code>m</code> of type <code>M</code>.
Otherwise, <code>false</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">28</a></span>
<em>Remarks:</em> <code>M::is_always_strided()</code> is a core constant
expression ([expr.const]).</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a>m<span class="op">.</span>stride<span class="op">(</span>r<span class="op">)</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">29</a></span>
<em>Preconditions:</em> <code>m.is_strided()</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">30</a></span>
<em>Result:</em> <code>typename M::size_type</code></p>
<p><span class="marginalizedparent"><a class="marginalized">31</a></span>
<em>Value:</em> <code>sr</code> as defined in
<code>m.is_strided()</code> above.</p>
<p><b>22.7.�.3 Layout mapping policy requirements
[mdspan.layoutpolicy.reqmts]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
A type <code>MP</code> meets the <em>layout mapping policy</em>
requirements if the following types are well formed and have the
specified semantics.</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typename</span> MP<span class="op">::</span><span class="kw">template</span> mapping_type<span class="op">&lt;</span>E<span class="op">&gt;</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Result:</em> <code>M</code></p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Preconditions:</em> <code>M</code> meets the <em>layout mapping</em>
requirements ([mdspan.layout.reqmts]),
<code>is_same_v&lt;typename M::layout_type,MP&gt;</code> is
<code>true</code> and
<code>is_same&lt;typename M::extents_type,E&gt;</code> is
<code>true</code></p>
<!--


  #                   #       #       ##  #
  #   ## # # ### # # ###      #  ###  #  ###
  #  # # ### # # # #  #       #  ##  ###  #
  ## ###   # ### ###  ##      ## ###  #   ##
         ###             ###         ##

-->
<p><br /> <b>22.7.�.3 Class template <code>layout_left</code>
[mdspan.layout.left]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<code>layout_left</code> provides a layout mapping where the left-most
extent is stride one and strides increase left-to-right as the product
of extents.</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> layout_left <span class="op">{</span></span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Extents<span class="op">&gt;</span></span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> mapping <span class="op">{</span></span>
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> extents_type <span class="op">=</span> Extents;</span>
<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> size_type <span class="op">=</span> <span class="kw">typename</span> extents_type<span class="op">::</span>size_type;</span>
<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> layout_type <span class="op">=</span> layout_left;</span>
<span id="cb37-10"><a href="#cb37-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-11"><a href="#cb37-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb37-12"><a href="#cb37-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb37-13"><a href="#cb37-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> extents_type<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb37-14"><a href="#cb37-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb37-15"><a href="#cb37-15" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><span class="op">(!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span>OtherExtents,extents_type<span class="op">&gt;)</span></span>
<span id="cb37-16"><a href="#cb37-16" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb37-17"><a href="#cb37-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutRightMapping<span class="op">&gt;</span></span>
<span id="cb37-18"><a href="#cb37-18" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb37-19"><a href="#cb37-19" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> LayoutRightMapping<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb37-20"><a href="#cb37-20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutStrideMapping<span class="op">&gt;</span></span>
<span id="cb37-21"><a href="#cb37-21" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><span class="op">(</span>extents_type<span class="op">::</span>rank<span class="op">()</span> <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="kw">constexpr</span> mapping<span class="op">(</span></span>
<span id="cb37-22"><a href="#cb37-22" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> LayoutStrideMapping<span class="op">&amp;</span> other<span class="op">)</span>;</span>
<span id="cb37-23"><a href="#cb37-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-24"><a href="#cb37-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb37-25"><a href="#cb37-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-26"><a href="#cb37-26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">const</span> extents_type<span class="op">&amp;</span> extents<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> extents_; <span class="op">}</span></span>
<span id="cb37-27"><a href="#cb37-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-28"><a href="#cb37-28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> size_type required_span_size<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb37-29"><a href="#cb37-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-30"><a href="#cb37-30" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Indices<span class="op">&gt;</span></span>
<span id="cb37-31"><a href="#cb37-31" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> size_type <span class="kw">operator</span><span class="op">()(</span>Indices<span class="op">...)</span> <span class="kw">const</span> <span class="kw">noexcept</span>; </span>
<span id="cb37-32"><a href="#cb37-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-33"><a href="#cb37-33" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_unique<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb37-34"><a href="#cb37-34" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_contiguous<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb37-35"><a href="#cb37-35" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_strided<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb37-36"><a href="#cb37-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-37"><a href="#cb37-37" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_unique<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb37-38"><a href="#cb37-38" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_contiguous<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb37-39"><a href="#cb37-39" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_strided<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb37-40"><a href="#cb37-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-41"><a href="#cb37-41" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> size_type stride<span class="op">(</span><span class="dt">size_t</span><span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb37-42"><a href="#cb37-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-43"><a href="#cb37-43" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb37-44"><a href="#cb37-44" aria-hidden="true" tabindex="-1"></a>      <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> mapping<span class="op">&amp;</span>, <span class="kw">const</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb37-45"><a href="#cb37-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-46"><a href="#cb37-46" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span><span class="op">:</span></span>
<span id="cb37-47"><a href="#cb37-47" aria-hidden="true" tabindex="-1"></a>    extents_type <em>extents_</em><span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb37-48"><a href="#cb37-48" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb37-49"><a href="#cb37-49" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb37-50"><a href="#cb37-50" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<code>layout_left</code> meets the requirements of layout mapping
policy.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<code>layout_left</code> is a trivially copyable type.
<code>layout_left::mapping&lt;E&gt;</code> is a trivially copyable type
for each <code>E</code> that is a specialization of
<code>extents</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
If <code>Extents</code> is not a specialization of <code>extents</code>,
then the program is ill-formed.</p>
<p><b>22.7.�.3.1 <code>layout_left::mapping</code> members
[mdspan.layout.layout_left]</b></p>
<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> extents_type<span class="op">&amp;</span> e<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>e</code>.</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span>OtherExtents,extents_type<span class="op">&gt;)</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Constraints:</em>
<code>is_constructible_v&lt;extents_type,OtherExtents&gt;</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>other.extents()</code>.</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutRightMapping<span class="op">&gt;</span></span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span><span class="kw">typename</span> LayoutRightMapping<span class="op">::</span>extents_type,extents_type<span class="op">&gt;)</span></span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> LayoutRightMapping<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.1)</a></span>
<code>is_same_v&lt;typename layout_right::template mapping&lt;typename LayoutRightMapping::extents_type&gt;,LayoutRightMapping&gt;</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.2)</a></span>
<code>extents_type::rank() &lt;= 1</code> is <code>true</code>,
and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.3)</a></span>
<code>is_constructible_v&lt;extents_type,typename LayoutRightMapping::extents_type&gt;</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>other.extents()</code>.</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutStrideMapping<span class="op">&gt;</span></span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(</span>extents_type<span class="op">::</span>rank<span class="op">()</span> <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="kw">constexpr</span> mapping<span class="op">(</span></span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> LayoutStrideMapping<span class="op">&amp;</span> other<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(6.1)</a></span>
<code>is_same_v&lt;typename layout_stride::template mapping&lt;typename LayoutStrideMapping::extents_type&gt;,LayoutStrideMapping&gt;</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(6.2)</a></span>
<code>is_constructible_v&lt;extents_type,typename LayoutRightMapping::extents_type&gt;</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Preconditions:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(7.1)</a></span> if
<code>extents_type::rank() &gt; 0</code> then for all <code>r</code> in
the range <span class="math inline">[0,</span>
<code>extents_type::rank()</code><span class="math inline">)</span>,
<code>other.stride(r)</code> equals
<em><code>fwd-prod-of-extents</code></em><code>(extents(),r)</code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>other.extents()</code>.</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> size_type required_span_size<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<em>Returns:</em>
<em><code>fwd-prod-of-extents</code></em><code>(extents(),extents_type::rank())</code>.</p>
<div class="sourceCode" id="cb43"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Indices<span class="op">&gt;</span> </span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> size_type <span class="kw">operator</span><span class="op">()(</span>Indices<span class="op">...</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.1)</a></span>
<code>sizeof...(Indices) == extents_type::rank()</code> is
<code>true</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.2)</a></span>
<code>(is_convertible_v&lt;Indices, size_type&gt; &amp;&amp; ...)</code>
is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.3)</a></span>
<code>(is_nothrow_constructible_v&lt;size_type, Indices&gt; &amp;&amp; ...)</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Preconditions:</em> <code>static_cast&lt;size_type&gt;(i)...</code>
is a multidimensional index into <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
([mdspan.terms]).</p>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span>
<em>Effects:</em> Let <code>P...</code> be the parameter pack such that
<code>is_same_v&lt;make_index_sequence&lt;sizeof...(Indices)&gt;, index_sequence&lt;P...&gt;&gt;</code>
is <code>true</code>. <br /> Equivalent to:
<code>return ((static_cast&lt;size_type&gt;(i)*stride(P)) + ... + 0);</code></p>
<div class="sourceCode" id="cb44"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> size_type stride<span class="op">(</span><span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">const</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span>
<em>Constraints:</em> <code>extents_type::rank() &gt; 0</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span>
<em>Preconditions:</em> <code>i &lt; extents_type::rank()</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span>
<em>Returns:</em>
<em><code>fwd-prod-of-extents</code></em><code>(extents(), i)</code>.</p>
<div class="sourceCode" id="cb45"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> mapping<span class="op">&amp;</span> x, <span class="kw">const</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;</span> y<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span>
<em>Constraints:</em>
<code>extents_type::rank() == OtherExtents::rank()</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span>
<em>Effects:</em> Equivalent to:
<code>return x.extents() == y.extents();</code></p>
<!--

 #                   #           #      #    #
 #   ## # # ### # # ###     ###     ### ### ###
 #  # # ### # # # #  #      #    #  # # # #  #
 ## ###   # ### ###  ##     #    ##  ## # #  ##
        ###             ###         ###
-->
<p><br /> <b>22.7.�.4 Class template <code>layout_right</code>
[mdspan.layout.right]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<code>layout_right</code> provides a layout mapping where the right-most
extent is stride one and strides increase right-to-left as the product
of extents.</p>
<div class="sourceCode" id="cb46"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> layout_right <span class="op">{</span></span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Extents<span class="op">&gt;</span></span>
<span id="cb46-5"><a href="#cb46-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> mapping <span class="op">{</span></span>
<span id="cb46-6"><a href="#cb46-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb46-7"><a href="#cb46-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> extents_type <span class="op">=</span> Extents;</span>
<span id="cb46-8"><a href="#cb46-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> size_type <span class="op">=</span> <span class="kw">typename</span> extents_type<span class="op">::</span>size_type;</span>
<span id="cb46-9"><a href="#cb46-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> layout_type <span class="op">=</span> layout_right;</span>
<span id="cb46-10"><a href="#cb46-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-11"><a href="#cb46-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb46-12"><a href="#cb46-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb46-13"><a href="#cb46-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> extents_type<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb46-14"><a href="#cb46-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb46-15"><a href="#cb46-15" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><span class="op">(!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span>OtherExtents,extents_type<span class="op">&gt;)</span></span>
<span id="cb46-16"><a href="#cb46-16" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb46-17"><a href="#cb46-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutLeftMapping<span class="op">&gt;</span></span>
<span id="cb46-18"><a href="#cb46-18" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb46-19"><a href="#cb46-19" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> LayoutLeftMapping<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb46-20"><a href="#cb46-20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutStrideMapping<span class="op">&gt;</span></span>
<span id="cb46-21"><a href="#cb46-21" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><span class="op">(</span>extents_type<span class="op">::</span>rank<span class="op">()</span> <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="kw">constexpr</span> mapping<span class="op">(</span></span>
<span id="cb46-22"><a href="#cb46-22" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> LayoutStrideMappping<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb46-23"><a href="#cb46-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-24"><a href="#cb46-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb46-25"><a href="#cb46-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-26"><a href="#cb46-26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">const</span> extents_type<span class="op">&amp;</span> extents<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> extents_; <span class="op">}</span></span>
<span id="cb46-27"><a href="#cb46-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-28"><a href="#cb46-28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> size_type required_span_size<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb46-29"><a href="#cb46-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-30"><a href="#cb46-30" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Indices<span class="op">&gt;</span></span>
<span id="cb46-31"><a href="#cb46-31" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> size_type <span class="kw">operator</span><span class="op">()(</span>Indices<span class="op">...)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb46-32"><a href="#cb46-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-33"><a href="#cb46-33" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_unique<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb46-34"><a href="#cb46-34" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_contiguous<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb46-35"><a href="#cb46-35" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_strided<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb46-36"><a href="#cb46-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-37"><a href="#cb46-37" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_unique<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb46-38"><a href="#cb46-38" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_contiguous<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb46-39"><a href="#cb46-39" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_strided<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb46-40"><a href="#cb46-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-41"><a href="#cb46-41" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> size_type stride<span class="op">(</span><span class="dt">size_t</span><span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb46-42"><a href="#cb46-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-43"><a href="#cb46-43" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb46-44"><a href="#cb46-44" aria-hidden="true" tabindex="-1"></a>      <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> mapping<span class="op">&amp;</span>, <span class="kw">const</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb46-45"><a href="#cb46-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb46-46"><a href="#cb46-46" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span><span class="op">:</span></span>
<span id="cb46-47"><a href="#cb46-47" aria-hidden="true" tabindex="-1"></a>    extents_type <em>extents_</em><span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb46-48"><a href="#cb46-48" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb46-49"><a href="#cb46-49" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb46-50"><a href="#cb46-50" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<code>layout_right</code> meets the requirements of layout mapping
policy.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<code>layout_right</code> is a trivially copyable type.
<code>layout_right::mapping&lt;E&gt;</code> is a trivially copyable type
for each <code>E</code> that is a specialization of
<code>extents</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
If <code>Extents</code> is not a specialization of <code>extents</code>,
then the program is ill-formed.</p>
<p><b>22.7.�.4.1 <code>layout_right::mapping</code> members
[mdspan.layout.layout_right]</b></p>
<div class="sourceCode" id="cb47"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> extents_type<span class="op">&amp;</span> e<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>e</code>.</p>
<div class="sourceCode" id="cb48"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span>OtherExtents,extents_type<span class="op">&gt;)</span></span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Constraints:</em>
<code>is_constructible_v&lt;extents_type,OtherExtents&gt;</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>other.extents()</code>.</p>
<div class="sourceCode" id="cb49"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutLeftMapping<span class="op">&gt;</span></span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span><span class="kw">typename</span> LayoutLeftMapping<span class="op">::</span>extents_type,extents_type<span class="op">&gt;)</span></span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> LayoutLeftMapping<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.1)</a></span>
<code>is_same_v&lt;typename layout_left::template mapping&lt;typename LayoutLeftMapping::extents_type&gt;,LayoutLeftMapping&gt;</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.2)</a></span>
<code>extents_type::rank() &lt;= 1</code> is <code>true</code>,
and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.3)</a></span>
<code>is_constructible_v&lt;extents_type,typename LayoutLeftMapping::extents_type&gt;</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>other.extents()</code>.</p>
<div class="sourceCode" id="cb50"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutStrideMapping<span class="op">&gt;</span></span>
<span id="cb50-2"><a href="#cb50-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(</span>extents_type<span class="op">::</span>rank<span class="op">()</span> <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="kw">constexpr</span> mapping<span class="op">(</span></span>
<span id="cb50-3"><a href="#cb50-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> LayoutStrideMapping<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(6.1)</a></span>
<code>is_same_v&lt;typename layout_stride::template mapping&lt;typename LayoutStrideMapping::extents_type&gt;,LayoutStrideMapping&gt;</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(6.2)</a></span>
<code>is_constructible_v&lt;extents_type,typename LayoutStrideMapping::extents_type&gt;</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Preconditions:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(7.1)</a></span> if
<code>extents_type::rank() &gt; 0</code> then for all <code>r</code> in
the range <span class="math inline">[0,</span>
<code>extents_type::rank()</code><span class="math inline">)</span>,
<code>other.stride(r)</code> equals
<em><code>rev-prod-of-extents</code></em><code>(extents(),r+1)</code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>other.extents()</code>.</p>
<div class="sourceCode" id="cb51"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true" tabindex="-1"></a>size_type required_span_size<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<em>Returns:</em>
<em><code>fwd-prod-of-extents</code></em><code>(extents(), extents_type::rank())</code></p>
<div class="sourceCode" id="cb52"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Indices<span class="op">&gt;</span> </span>
<span id="cb52-2"><a href="#cb52-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> size_type <span class="kw">operator</span><span class="op">()(</span>Indices<span class="op">...</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.1)</a></span>
<code>sizeof...(Indices) == extents_type::rank()</code> is
<code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.2)</a></span>
<code>(is_convertible_v&lt;Indices, size_type&gt; &amp;&amp; ...)</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.3)</a></span>
<code>(is_nothrow_constructlible_v&lt;size_type, Indices&gt; &amp;&amp; ...)</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Preconditions:</em> <code>static_cast&lt;size_type&gt;(i)...</code>
is a multidimensional index into <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
([mdspan.terms]).</p>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span>
<em>Effects:</em> Let <code>P...</code> be the parameter pack such that
<code>is_same_v&lt;make_index_sequence&lt;sizeof...(Indices)&gt;, index_sequence&lt;P...&gt;&gt;</code>
is <code>true</code>. <br /> Equivalent to:
<code>return ((static_cast&lt;size_type&gt;(i)*stride(P)) + ... + 0);</code></p>
<div class="sourceCode" id="cb53"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb53-1"><a href="#cb53-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> size_type stride<span class="op">(</span><span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span>
<em>Constraints:</em> <code>extents_type::rank() &gt; 0</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span>
<em>Preconditions:</em> <code>i &lt; extents_type::rank()</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span>
<em>Returns:</em>
<em><code>rev-prod-of-extents</code></em><code>(extents(), i+1)</code></p>
<div class="sourceCode" id="cb54"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb54-2"><a href="#cb54-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> mapping<span class="op">&amp;</span> x, <span class="kw">const</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;</span> y<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span>
<em>Constraints:</em>
<code>extents_type::rank() == OtherExtents::rank()</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span>
<em>Effects:</em> Equivalent to:
<code>return x.extents() == y.extents();</code>.</p>
<!--
layout_stride

 /$$                                           /$$                      /$$               /$$       /$$
| $$                                          | $$                     | $$              |__/      | $$
| $$  /$$$$$$  /$$   /$$  /$$$$$$  /$$   /$$ /$$$$$$         /$$$$$$$ /$$$$$$    /$$$$$$  /$$  /$$$$$$$  /$$$$$$
| $$ |____  $$| $$  | $$ /$$__  $$| $$  | $$|_  $$_/        /$$_____/|_  $$_/   /$$__  $$| $$ /$$__  $$ /$$__  $$
| $$  /$$$$$$$| $$  | $$| $$  \ $$| $$  | $$  | $$         |  $$$$$$   | $$    | $$  \__/| $$| $$  | $$| $$$$$$$$
| $$ /$$__  $$| $$  | $$| $$  | $$| $$  | $$  | $$ /$$      \____  $$  | $$ /$$| $$      | $$| $$  | $$| $$_____/
| $$|  $$$$$$$|  $$$$$$$|  $$$$$$/|  $$$$$$/  |  $$$$/      /$$$$$$$/  |  $$$$/| $$      | $$|  $$$$$$$|  $$$$$$$
|__/ \_______/ \____  $$ \______/  \______/    \___//$$$$$$|_______/    \___/  |__/      |__/ \_______/ \_______/
               /$$  | $$                           |______/
              |  $$$$$$/
               \______/

-->
<p><br /> <b>22.7.�.5 Class template <code>layout_stride</code>
[mdspan.layout.stride]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<code>layout_stride</code> provides a layout mapping where the strides
are user defined.</p>
<div class="sourceCode" id="cb55"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb55-1"><a href="#cb55-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb55-2"><a href="#cb55-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-3"><a href="#cb55-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> layout_stride <span class="op">{</span></span>
<span id="cb55-4"><a href="#cb55-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Extents<span class="op">&gt;</span></span>
<span id="cb55-5"><a href="#cb55-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> mapping <span class="op">{</span></span>
<span id="cb55-6"><a href="#cb55-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb55-7"><a href="#cb55-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> extents_type <span class="op">=</span> Extents;</span>
<span id="cb55-8"><a href="#cb55-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> size_type <span class="op">=</span> <span class="kw">typename</span> extents_type<span class="op">::</span>size_type;</span>
<span id="cb55-9"><a href="#cb55-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> layout_type <span class="op">=</span> layout_stride;</span>
<span id="cb55-10"><a href="#cb55-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-11"><a href="#cb55-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb55-12"><a href="#cb55-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb55-13"><a href="#cb55-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb55-14"><a href="#cb55-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> extents_type<span class="op">&amp;</span>,</span>
<span id="cb55-15"><a href="#cb55-15" aria-hidden="true" tabindex="-1"></a>                      <span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb55-16"><a href="#cb55-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-17"><a href="#cb55-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> StridedLayoutMapping<span class="op">&gt;</span></span>
<span id="cb55-18"><a href="#cb55-18" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb55-19"><a href="#cb55-19" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> StridedLayoutMapping<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb55-20"><a href="#cb55-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-21"><a href="#cb55-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb55-22"><a href="#cb55-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-23"><a href="#cb55-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">const</span> extents_type<span class="op">&amp;</span> extents<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> extents_; <span class="op">}</span></span>
<span id="cb55-24"><a href="#cb55-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> array<span class="op">&lt;</span><span class="kw">typename</span> size_type, extents_type<span class="op">::</span>rank<span class="op">()&gt;</span> strides<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span></span>
<span id="cb55-25"><a href="#cb55-25" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span> <span class="cf">return</span> <em>strides_</em>; <span class="op">}</span></span>
<span id="cb55-26"><a href="#cb55-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-27"><a href="#cb55-27" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> size_type required_span_size<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb55-28"><a href="#cb55-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-29"><a href="#cb55-29" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Indices<span class="op">&gt;</span></span>
<span id="cb55-30"><a href="#cb55-30" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> size_type <span class="kw">operator</span><span class="op">()(</span>Indices<span class="op">...)</span> <span class="kw">const</span> <span class="kw">noexcept</span> ;</span>
<span id="cb55-31"><a href="#cb55-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-32"><a href="#cb55-32" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_unique<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb55-33"><a href="#cb55-33" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_contiguous<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">false</span>; <span class="op">}</span></span>
<span id="cb55-34"><a href="#cb55-34" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_strided<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb55-35"><a href="#cb55-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-36"><a href="#cb55-36" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_unique<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb55-37"><a href="#cb55-37" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_contiguous<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb55-38"><a href="#cb55-38" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="dt">bool</span> is_strided<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">true</span>; <span class="op">}</span></span>
<span id="cb55-39"><a href="#cb55-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-40"><a href="#cb55-40" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> size_type stride<span class="op">(</span><span class="dt">size_t</span><span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb55-41"><a href="#cb55-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-42"><a href="#cb55-42" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherMapping<span class="op">&gt;</span></span>
<span id="cb55-43"><a href="#cb55-43" aria-hidden="true" tabindex="-1"></a>      <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> mapping<span class="op">&amp;</span>, <span class="kw">const</span> OtherMapping<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb55-44"><a href="#cb55-44" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-45"><a href="#cb55-45" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span><span class="op">:</span></span>
<span id="cb55-46"><a href="#cb55-46" aria-hidden="true" tabindex="-1"></a>    extents_type <em>extents_</em><span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb55-47"><a href="#cb55-47" aria-hidden="true" tabindex="-1"></a>    array<span class="op">&lt;</span>size_type, extents_type<span class="op">::</span>rank<span class="op">()&gt;</span> <em>strides_</em><span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb55-48"><a href="#cb55-48" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb55-49"><a href="#cb55-49" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb55-50"><a href="#cb55-50" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<code>layout_stride</code> meets the requirements of layout mapping
policy.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<code>layout_stride</code> is a trivially copyable type.
<code>layout_stride::mapping&lt;E&gt;</code> is a trivially copyable
type for each <code>E</code> that is a specialization of
<code>extents</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
If <code>Extents</code> is not a specialization of <code>extents</code>,
then the program is ill-formed.</p>
<p><b>22.7.�.5.1 <code>layout_stride::mapping</code> members
[mdspan.layout.layout_stride]</b></p>
<div class="sourceCode" id="cb56"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb56-1"><a href="#cb56-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb56-2"><a href="#cb56-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> extents_type<span class="op">&amp;</span> e, array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;</span> s<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
Let <span class="math inline"><em>P</em></span> be a permutation of the
integers <span class="math inline">0, ...,</span>
<code>extents_type::rank()-1</code> and let <span class="math inline"><em>p</em><sub><em>i</em></sub></span> be the <span class="math inline"><em>i</em><sup><em>t</em><em>h</em></sup></span>
element of <span class="math inline"><em>P</em></span>.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.1)</a></span>
<code>is_convertible_v&lt;const SizeType&amp;, size_type&gt;</code> is
<code>true</code> and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.2)</a></span>
<code>N == extents_type::rank()</code> is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Preconditions:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.1)</a></span><code>s[i] &gt; 0</code>
is <code>true</code> for all <code>i</code> in the range <span class="math inline">[0,</span> <code>extents_type::rank()</code> <span class="math inline">)</span>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span> If
<code>extents_type::rank()</code> is greater than zero, then there
exists a permutation <span class="math inline"><em>P</em></span> such
that <code>s[</code> <span class="math inline"><em>p</em><sub><em>i</em></sub></span>
<code>] &gt;= s[</code> <span class="math inline"><em>p</em><sub><em>i</em> − 1</sub></span>
<code>] * e.extent(</code> <span class="math inline"><em>p</em><sub><em>i</em> − 1</sub></span>
<code>)</code> is <code>true</code> for all <span class="math inline"><em>i</em></span> in the range <span class="math inline">[1,</span> <code>extents_type::rank()</code> <span class="math inline">)</span>. <i>[Note:</i> This condition guarantess
that <code>is_unique()</code> is <code>true</code>. <i>— end
note]</i></p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Effects:</em> Direct-non-list-initializes <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
with <code>e</code>, and direct-non-list-initializes <span class="math inline"><em>s</em><em>t</em><em>r</em><em>i</em><em>d</em><em>e</em><em>s</em>_</span>
with <code>s</code>.</p>
<div class="sourceCode" id="cb57"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb57-1"><a href="#cb57-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> StridedLayoutMapping<span class="op">&gt;</span></span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb57-3"><a href="#cb57-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> StridedLayoutMapping<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.1)</a></span>
<code>is_constructible_v&lt;extents_type, StridedLayoutMapping::extents_type&gt;</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.2)</a></span>
<code>StridedLayoutMapping::is_always_unique()</code> is
<code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.3)</a></span>
<code>StridedLayoutMapping::is_always_strided()</code> is
<code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.4)</a></span>
<code>is_same_v&lt;typename StridedLayoutMapping::extents_type,decltype(other.extents())&gt;</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.5)</a></span> if
<code>extents_type::rank()&gt;0</code> then
<code>is_same_v&lt;decltype(other.stride(0)),typename StridedLayoutMapping::size_type&gt;</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Precondition:</em> <code>StridedLayoutMapping</code> meets the
layout mapping requirements.</p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Postcondition:</em> <code>*this == other</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Remarks:</em> The expression inside <code>explicit</code> is
equivalent to:
<code>!std::is_convertible_v&lt;typename StridedLayoutMapping::extents_type,extents_type&gt;</code>.</p>
<div class="sourceCode" id="cb58"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb58-1"><a href="#cb58-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> size_type required_span_size<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<em>Returns:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.1)</a></span>
<code>1</code>, if <code>extents_type::rank()==0</code> is
<code>true</code>, otherwise</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.2)</a></span>
<code>0</code>, if
<em><code>fwd-prod-of-extents</code></em><code>(extents(), extents_type::rank()-1)==0</code>
is <code>true</code>, otherwise</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.3)</a></span>
<code>1</code> plus the sum of
<code>(extents().extent(r) - 1) * stride(r)</code> for all
<code>r</code> in the range <span class="math inline">[0,</span>
<code>extents_type::rank()</code> <span class="math inline">)</span>.</p></li>
</ul>
<div class="sourceCode" id="cb59"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb59-1"><a href="#cb59-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> Indices<span class="op">&gt;</span></span>
<span id="cb59-2"><a href="#cb59-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> size_type <span class="kw">operator</span><span class="op">()(</span>Indices<span class="op">...</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.1)</a></span>
<code>sizeof...(Indices) == extents_type::rank()</code> is
<code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.2)</a></span>
<code>(is_convertible_v&lt;Indices, size_type&gt; &amp;&amp; ...)</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.3)</a></span>
<code>(is_nothrow_constructible_v&lt;size_type, Indices&gt; &amp;&amp; ...)</code>
is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Preconditions:</em> <code>static_cast&lt;size_type&gt;(i)...</code>
is a multidimensional index into <span class="math inline"><em>e</em><em>x</em><em>t</em><em>e</em><em>n</em><em>t</em><em>s</em>_</span>
([mdspan.terms]).</p>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span>
<em>Effects:</em> Let <code>P...</code> be the parameter pack such that
<code>is_same_v&lt;make_index_sequence&lt;sizeof...(Indices)&gt;, index_sequence&lt;P...&gt;&gt;</code>
is <code>true</code>. <br /> Equivalent to:
<code>return ((static_cast&lt;size_type&gt;(i)*stride(P)) + ... + 0);</code></p>
<div class="sourceCode" id="cb60"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb60-1"><a href="#cb60-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="dt">bool</span> is_contiguous<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span> Let
<span class="math inline"><em>P</em></span> be a permutation of the
integers <span class="math inline">0, ...,</span>
<code>extents_type::rank()-1</code> and let <span class="math inline"><em>p</em><sub><em>i</em></sub></span> be the <span class="math inline"><em>i</em><sup><em>t</em><em>h</em></sup></span>
element of <span class="math inline"><em>P</em></span>.</p>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span><em>Returns:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(14.1)</a></span>
<code>true</code> if <code>extents_type::ranks()</code> is
zero.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(14.2)</a></span>
Otherwise, <code>true</code> if there is a permutation <span class="math inline"><em>P</em></span> such that <code>stride(</code>
<span class="math inline"><em>p</em><sub>0</sub></span> <code>)</code>
equals <code>1</code>, and <code>stride(</code> <span class="math inline"><em>p</em><sub><em>i</em></sub></span>
<code>)</code> equals <code>stride(</code> <span class="math inline"><em>p</em><sub><em>i</em> − 1</sub></span>
<code>) * extents().extent(</code> <span class="math inline"><em>p</em><sub><em>i</em> − 1</sub></span>
<code>)</code> for <span class="math inline"><em>i</em></span> in the
range <span class="math inline">[1,</span>
<code>extents_type::rank()</code> <span class="math inline">)</span>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(14.3)</a></span>
Otherwise, <code>false</code>.</p></li>
</ul>
<div class="sourceCode" id="cb61"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb61-1"><a href="#cb61-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherMapping<span class="op">&gt;</span></span>
<span id="cb61-2"><a href="#cb61-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">friend</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="kw">const</span> mapping<span class="op">&amp;</span> x, <span class="kw">const</span> OtherMapping<span class="op">&amp;</span> y<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span>
<em>Constraints:</em>
<code>extents_type::rank() == OtherMapping::extents_type::rank()</code>
is <code>true</code>, and <code>OtherMapping::is_always_strided()</code>
is <code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span>
<em>Preconditions:</em> <code>OtherMapping</code> meets layout mapping
requirements.</p>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span>
<em>Returns:</em> If <code>x.extents() == y.extents()</code> is
<code>true</code> and each of <code>x.stride(r) == y.stride(r)</code> is
<code>true</code> for <code>r</code> in the range of <span class="math inline">[0,</span> <code>x.extents.rank()</code> <span class="math inline">)</span>, <code>true</code>. Otherwise,
<code>false</code>.</p>
<!--


 8888b.   .d8888b .d8888b .d88b.  .d8888b  .d8888b   .d88b.  888d888
    "88b d88P"   d88P"   d8P  Y8b 88K      88K      d88""88b 888P"
.d888888 888     888     88888888 "Y8888b. "Y8888b. 888  888 888
888  888 Y88b.   Y88b.   Y8b.          X88      X88 Y88..88P 888
"Y888888  "Y8888P "Y8888P "Y8888   88888P'  88888P'  "Y88P"  888



-->
<p><b>22.7.� Accessor Policy [mdspan.accessor]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
An <em>accessor policy</em> defines types and operations by which a set
of objects are accessed from a subset of a contiguous range of integer
indices.</p>
<!--
[2]{.pnum} An accessor policy defines:

   * [2.1]{.pnum} `pointer`, the type of a handle to a set of objects
       accessible from a subset of a contiguous range of integer indices;

   * [2.2]{.pnum} `reference`, the type of a handle to a single element of type `element_type`;

   * [2.3]{.pnum} `access`, a method to access the `i`-th element
      in the range of elements represented by a `pointer`;

   * [2.4]{.pnum} `offset`, a method to create a subrange,
      beginning at an integer offset value and
      accessible from a subset of a contiguous range of integer indices,
      of a given range of elements; and

   * [2.5]{.pnum} `offset_policy`, the type of a
      <i>[Note:</i> possibly different <i>— end note]</i>
      accessor policy for accessing the result of `offset`.

[3]{.pnum} <i>[Note:</i> The type of `reference` need not be `element_type&`.
  The type of `pointer` need not be `element_type*`. <i>— end note]</i>
-->
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
In subclause 22.7.�.1,</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.1)</a></span>
<code>A</code> denotes an accessor policy.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.2)</a></span>
<code>a</code> denotes an object of type <code>A</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.3)</a></span>
<code>p</code> denotes an object of type
<code>A::pointer</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.4)</a></span>
<code>n</code>, <code>i</code> and <code>j</code> each denote a
<code>size_t</code> value.</p></li>
</ul>
<p><b>22.7.�.1 Accessor policy requirements
[mdspan.accessor.reqs]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
A type <code>A</code> meets the accessor policy requirements if
<code>A</code> meets the requirements of
<em>Cpp17CopyConstructible</em>, <em>Cpp17CopyAssignable</em> and the
following types and expressions are well-formed and have the specified
semantics.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<span class="math inline">[</span><code>p</code>,<code>n</code><span class="math inline">)</span> is an <em>accessible range</em> for
<code>a</code> if for each <code>i</code> in the range <span class="math inline">[0,</span><code>n</code><span class="math inline">)</span> <code>a.access(p,i)</code> is well
defined.</p>
<div class="sourceCode" id="cb62"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb62-1"><a href="#cb62-1" aria-hidden="true" tabindex="-1"></a>is_nothrow_move_constructible_v<span class="op">&lt;</span>A<span class="op">&gt;</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Value:</em> <code>true</code>.</p>
<div class="sourceCode" id="cb63"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true" tabindex="-1"></a>is_nothrow_move_assignable_v<span class="op">&lt;</span>A<span class="op">&gt;</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Value:</em> <code>true</code>.</p>
<div class="sourceCode" id="cb64"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb64-1"><a href="#cb64-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typename</span> A<span class="op">::</span>element_type</span></code></pre></div>
<span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Result:</em> A type that is a complete object type that is not an
abstract class type.
</td>
<div class="sourceCode" id="cb65"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb65-1"><a href="#cb65-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typename</span> A<span class="op">::</span>pointer</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Result:</em> A type that meets the requirements of
<em>Cpp17DefaultConstructible</em>, <em>Cpp17CopyConstructible</em>, and
<em>Cpp17CopyAssignable</em>.
<code>is_nothrow_move_constructible_v&lt;A::pointer&gt;</code> is
<code>true</code> and
<code>is_nothrow_move_assignable_v&lt;A::pointer&gt;</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<i>[Note:</i> The type of <code>pointer</code> need not be
<code>element_type*</code>. <i>— end note]</i></p>
<div class="sourceCode" id="cb66"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb66-1"><a href="#cb66-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typename</span> A<span class="op">::</span>reference</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Result:</em> A type for which
<code>is_convertible_v&lt;A::reference,A::element_type&gt;</code> is
<code>true</code>, and if <code>is_const_v&lt;A::element_type&gt;</code>
is <code>false</code> then
<code>is_assignable_v&lt;A::element_type&amp;,A::reference&gt;</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<i>[Note:</i> The type of <code>reference</code> need not be
<code>element_type&amp;</code>. <i>— end note]</i></p>
<div class="sourceCode" id="cb67"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb67-1"><a href="#cb67-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typename</span> A<span class="op">::</span>offset_policy</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Result:</em> An accessor policy type <code>O</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Preconditions:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(11.1)</a></span>
<code>O</code> meets the accessor policy requirements.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(11.2)</a></span>
<code>constructible_from&lt;O,A&gt;</code> is modeled.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(11.3)</a></span>
<code>is_same_v&lt;typename O::element_type, typename A::element_type&gt;</code>
is <code>true</code></p></li>
</ul>
<div class="sourceCode" id="cb68"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb68-1"><a href="#cb68-1" aria-hidden="true" tabindex="-1"></a>a<span class="op">.</span>access<span class="op">(</span>p, i<span class="op">)</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span>
<em>Result:</em> <code>A::reference</code></p>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span>
<em>Value:</em> An object which provides access to the <code>i</code>-th
element in the range of elements that starts at <code>p</code>.</p>
<div class="sourceCode" id="cb69"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb69-1"><a href="#cb69-1" aria-hidden="true" tabindex="-1"></a>a<span class="op">.</span>offset<span class="op">(</span>p, i<span class="op">)</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span>
<em>Result:</em> <code>A::offset_policy::pointer</code></p>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span>
<em>Postconditions:</em> Let <code>a_sub</code> be
<code>A::offset_policy(a)</code>, <code>p_sub</code> be
<code>a.offset(p,i)</code>, and <code>n</code> have a value such that
<span class="math inline">[</span><code>p</code>,<code>n</code><span class="math inline">)</span> is the accessible range of <code>a</code>,
then</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(15.1)</a></span>
<span class="math inline">[</span><code>p_sub</code>,<code>n-i</code><span class="math inline">)</span> is the accessible range of
<code>a_sub</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(15.2)</a></span>
<code>a_sub.access(p_sub,j)</code> provides acces to the same element as
<code>a.access(p,i+j)</code>.</p></li>
</ul>
<!--
[13]{.pnum} The accessible range $R$ of an accessor `a` for a pointer `p` is defined by the set of integers `i` for which `a.access(p,i)` is well defined.
-->
<!--

                                    #            #
 ## ### ### ###  ##  ## ### ###     ###  ##  ##     ###
# # #   #   ##   #   #  # # #       # # # #  #   #  #
### ### ### ### ##  ##  ### #       ### ### ##   ## ###
                                ###
-->
<p><b>22.7.�.2 Class template <code>default_accessor</code>
[mdspan.accessor.default]</b></p>
<div class="sourceCode" id="cb70"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb70-1"><a href="#cb70-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb70-2"><a href="#cb70-2" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ElementType<span class="op">&gt;</span></span>
<span id="cb70-3"><a href="#cb70-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">struct</span> default_accessor <span class="op">{</span></span>
<span id="cb70-4"><a href="#cb70-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> offset_policy <span class="op">=</span> default_accessor;</span>
<span id="cb70-5"><a href="#cb70-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> element_type <span class="op">=</span> ElementType;</span>
<span id="cb70-6"><a href="#cb70-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> reference <span class="op">=</span> ElementType<span class="op">&amp;</span>;</span>
<span id="cb70-7"><a href="#cb70-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> pointer <span class="op">=</span> ElementType<span class="op">*</span>;</span>
<span id="cb70-8"><a href="#cb70-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-9"><a href="#cb70-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> default_accessor<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb70-10"><a href="#cb70-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-11"><a href="#cb70-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherElementType<span class="op">&gt;</span></span>
<span id="cb70-12"><a href="#cb70-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> default_accessor<span class="op">(</span>default_accessor<span class="op">&lt;</span>OtherElementType<span class="op">&gt;)</span> <span class="kw">noexcept</span> <span class="op">{}</span></span>
<span id="cb70-13"><a href="#cb70-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-14"><a href="#cb70-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">typename</span> offset_policy<span class="op">::</span>pointer</span>
<span id="cb70-15"><a href="#cb70-15" aria-hidden="true" tabindex="-1"></a>      offset<span class="op">(</span>pointer p, <span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb70-16"><a href="#cb70-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-17"><a href="#cb70-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> reference access<span class="op">(</span>pointer p, <span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span>
<span id="cb70-18"><a href="#cb70-18" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb70-19"><a href="#cb70-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<code>default_accessor</code> meets the requirements of accessor
policy.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<code>ElementType</code> is required to be a complete object type that
is neither an abstract class type nor an array type.
<!-- mfh 20 Jan 2019: This imitates [span.overview] para 4 wording, with an additional restriction --></p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
Each specialization of <code>default_accessor</code> is a trivially
copyable type.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
For a <code>pointer</code> <code>p</code> and <code>size_type</code>
<code>n</code>, <span class="math inline">[</span><code>p</code>,<code>n</code><span class="math inline">)</span> is an accessible range for an instance of
<code>default_accessor</code> if and only if <span class="math inline">[</span><code>p</code>,<code>p+n</code><span class="math inline">)</span> is a valid range.</p>
<p><b>22.7.�.2 Class template <code>default_accessor</code> members
[mdspan.accessor.members]</b></p>
<div class="sourceCode" id="cb71"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb71-1"><a href="#cb71-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherElementType<span class="op">&gt;</span></span>
<span id="cb71-2"><a href="#cb71-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> default_accessor<span class="op">(</span>default_accessor<span class="op">&lt;</span>OtherElementType<span class="op">&gt;)</span> <span class="kw">noexcept</span> <span class="op">{}</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Constraints:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span>
<code>is_convertible_v&lt;typename default_accessor&lt;OtherElementType&gt;::element_type(*)[], element_type(*)[]&gt;</code>
is <code>true</code>.</li>
</ul>
<div class="sourceCode" id="cb72"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb72-1"><a href="#cb72-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> <span class="kw">typename</span> offset_policy<span class="op">::</span>pointer</span>
<span id="cb72-2"><a href="#cb72-2" aria-hidden="true" tabindex="-1"></a>  offset<span class="op">(</span>pointer p, <span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Preconditions:</em> <code>p + i</code> is dereferenceable.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Returns:</em> <code>p + i</code>.</p>
<div class="sourceCode" id="cb73"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb73-1"><a href="#cb73-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> reference access<span class="op">(</span>pointer p, <span class="dt">size_t</span> i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Preconditions:</em> <code>p + i</code> is dereferenceable.</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Returns:</em> <code>p[i]</code>.</p>
<!--
                   888
                   888
                   888
88888b.d88b.   .d88888 .d8888b  88888b.   8888b.  88888b.
888 "888 "88b d88" 888 88K      888 "88b     "88b 888 "88b
888  888  888 888  888 "Y8888b. 888  888 .d888888 888  888
888  888  888 Y88b 888      X88 888 d88P 888  888 888  888
888  888  888  "Y88888  88888P' 88888P"  "Y888888 888  888
                                888
                                888
-->
<p><b>22.7.� Class template <code>mdspan</code> [mdspan.mdspan]</b></p>
<p><br /> <b>22.7.�.1 <code>mdspan</code> overview
[mdspan.mdspan.overview]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<code>mdspan</code> maps a multidimensional index in its domain to a
reference to an element in its codomain.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
The <em>domain</em> of an <code>mdspan</code> object is a
multidimensional index space defined by an <code>extents</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
The <em>codomain</em> of an <code>mdspan</code> object is a set of
elements accessible from a contiguous range of integer indices.</p>
<div class="sourceCode" id="cb74"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb74-1"><a href="#cb74-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb74-2"><a href="#cb74-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-3"><a href="#cb74-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> Extents, <span class="kw">class</span> LayoutPolicy, <span class="kw">class</span> AccessorPolicy<span class="op">&gt;</span></span>
<span id="cb74-4"><a href="#cb74-4" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> mdspan <span class="op">{</span></span>
<span id="cb74-5"><a href="#cb74-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb74-6"><a href="#cb74-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-7"><a href="#cb74-7" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Domain and codomain types</span></span>
<span id="cb74-8"><a href="#cb74-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> extents_type <span class="op">=</span> Extents;</span>
<span id="cb74-9"><a href="#cb74-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> layout_type <span class="op">=</span> LayoutPolicy;</span>
<span id="cb74-10"><a href="#cb74-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> accessor_type <span class="op">=</span> AccessorPolicy;</span>
<span id="cb74-11"><a href="#cb74-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> mapping_type <span class="op">=</span> <span class="kw">typename</span> layout_type<span class="op">::</span><span class="kw">template</span> mapping<span class="op">&lt;</span>extents_type<span class="op">&gt;</span>;</span>
<span id="cb74-12"><a href="#cb74-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> element_type <span class="op">=</span> ElementType;</span>
<span id="cb74-13"><a href="#cb74-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> value_type <span class="op">=</span> remove_cv_t<span class="op">&lt;</span>element_type<span class="op">&gt;</span>;</span>
<span id="cb74-14"><a href="#cb74-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> size_type <span class="op">=</span> <span class="kw">typename</span> Extents<span class="op">::</span>size_type ;</span>
<span id="cb74-15"><a href="#cb74-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> pointer <span class="op">=</span> <span class="kw">typename</span> accessor_type<span class="op">::</span>pointer;</span>
<span id="cb74-16"><a href="#cb74-16" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> reference <span class="op">=</span> <span class="kw">typename</span> accessor_type<span class="op">::</span>reference;</span>
<span id="cb74-17"><a href="#cb74-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-18"><a href="#cb74-18" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.mdspan.cons], mdspan constructors, assignment, and destructor</span></span>
<span id="cb74-19"><a href="#cb74-19" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">()</span> <span class="kw">requires</span><span class="op">(</span>rank_dynamic<span class="op">()</span> <span class="op">!=</span> <span class="dv">0</span><span class="op">)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb74-20"><a href="#cb74-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">(</span><span class="kw">const</span> mdspan<span class="op">&amp;</span> rhs<span class="op">)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb74-21"><a href="#cb74-21" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">(</span>mdspan<span class="op">&amp;&amp;</span> rhs<span class="op">)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb74-22"><a href="#cb74-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-23"><a href="#cb74-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> SizeTypes<span class="op">&gt;</span></span>
<span id="cb74-24"><a href="#cb74-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span> <span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer ptr, SizeTypes<span class="op">...</span> exts<span class="op">)</span>;</span>
<span id="cb74-25"><a href="#cb74-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb74-26"><a href="#cb74-26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span><span class="op">(</span>N <span class="op">!=</span> rank_dynamic<span class="op">())</span></span>
<span id="cb74-27"><a href="#cb74-27" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, <span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;</span> exts<span class="op">)</span>;</span>
<span id="cb74-28"><a href="#cb74-28" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, <span class="kw">const</span> Extents<span class="op">&amp;</span> ext<span class="op">)</span>;</span>
<span id="cb74-29"><a href="#cb74-29" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, <span class="kw">const</span> mapping_type<span class="op">&amp;</span> m<span class="op">)</span>;</span>
<span id="cb74-30"><a href="#cb74-30" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, <span class="kw">const</span> mapping_type<span class="op">&amp;</span> m, <span class="kw">const</span> accessor_type<span class="op">&amp;</span> a<span class="op">)</span>;</span>
<span id="cb74-31"><a href="#cb74-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-32"><a href="#cb74-32" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherElementType, <span class="kw">class</span> OtherExtents, </span>
<span id="cb74-33"><a href="#cb74-33" aria-hidden="true" tabindex="-1"></a>           <span class="kw">class</span> OtherLayoutPolicy, <span class="kw">class</span> OtherAccessorPolicy<span class="op">&gt;</span></span>
<span id="cb74-34"><a href="#cb74-34" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb74-35"><a href="#cb74-35" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mdspan<span class="op">(</span></span>
<span id="cb74-36"><a href="#cb74-36" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> mdspan<span class="op">&lt;</span>OtherElementType, OtherExtents, </span>
<span id="cb74-37"><a href="#cb74-37" aria-hidden="true" tabindex="-1"></a>                   OtherLayoutPolicy, OtherAccessorPolicy<span class="op">&gt;&amp;</span> other<span class="op">)</span>;</span>
<span id="cb74-38"><a href="#cb74-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-39"><a href="#cb74-39" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span><span class="kw">const</span> mdspan<span class="op">&amp;</span> rhs<span class="op">)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb74-40"><a href="#cb74-40" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">=(</span>mdspan<span class="op">&amp;&amp;</span> rhs<span class="op">)</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb74-41"><a href="#cb74-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-42"><a href="#cb74-42" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.mdspan.mapping], mdspan mapping domain multidimensional index to access codomain element</span></span>
<span id="cb74-43"><a href="#cb74-43" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> SizeTypes<span class="op">&gt;</span></span>
<span id="cb74-44"><a href="#cb74-44" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> reference <span class="kw">operator</span><span class="op">[](</span>SizeTypes<span class="op">...</span> indices<span class="op">)</span> <span class="kw">const</span>;</span>
<span id="cb74-45"><a href="#cb74-45" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb74-46"><a href="#cb74-46" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> reference <span class="kw">operator</span><span class="op">[](</span><span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;</span> indices<span class="op">)</span> <span class="kw">const</span>;</span>
<span id="cb74-47"><a href="#cb74-47" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-48"><a href="#cb74-48" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="kw">const</span> accessor_type<span class="op">&amp;</span> accessor<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> <em>acc_</em>; <span class="op">}</span></span>
<span id="cb74-49"><a href="#cb74-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-50"><a href="#cb74-50" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> rank<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> Extents<span class="op">::</span>rank<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb74-51"><a href="#cb74-51" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> rank_dynamic<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> Extents<span class="op">::</span>rank_dynamic<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb74-52"><a href="#cb74-52" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> size_type static_extent<span class="op">(</span><span class="dt">size_t</span> r<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> Extents<span class="op">::</span>static_extent<span class="op">(</span>r<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb74-53"><a href="#cb74-53" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-54"><a href="#cb74-54" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="kw">const</span> extents_type<span class="op">&amp;</span> extents<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> <em>map_</em><span class="op">.</span>extents<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb74-55"><a href="#cb74-55" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> size_type extent<span class="op">(</span><span class="dt">size_t</span> r<span class="op">)</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> extents<span class="op">().</span>extent<span class="op">(</span>r<span class="op">)</span>; <span class="op">}</span></span>
<span id="cb74-56"><a href="#cb74-56" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> size_type size<span class="op">()</span> <span class="kw">const</span>;</span>
<span id="cb74-57"><a href="#cb74-57" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-58"><a href="#cb74-58" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.basic.codomain], mdspan observers of the codomain</span></span>
<span id="cb74-59"><a href="#cb74-59" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="kw">const</span> pointer<span class="op">&amp;</span> data<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> <em>ptr_</em>; <span class="op">}</span></span>
<span id="cb74-60"><a href="#cb74-60" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="kw">const</span> mapping_type<span class="op">&amp;</span> mapping<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> <em>map_</em>; <span class="op">}</span></span>
<span id="cb74-61"><a href="#cb74-61" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-62"><a href="#cb74-62" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_unique<span class="op">()</span> <span class="op">{</span></span>
<span id="cb74-63"><a href="#cb74-63" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> mapping_type<span class="op">::</span>is_always_unique<span class="op">()</span>;</span>
<span id="cb74-64"><a href="#cb74-64" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb74-65"><a href="#cb74-65" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_contiguous<span class="op">()</span> <span class="op">{</span></span>
<span id="cb74-66"><a href="#cb74-66" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> mapping_type<span class="op">::</span>is_always_contiguous<span class="op">()</span>;</span>
<span id="cb74-67"><a href="#cb74-67" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb74-68"><a href="#cb74-68" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> is_always_strided<span class="op">()</span> <span class="op">{</span></span>
<span id="cb74-69"><a href="#cb74-69" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> mapping_type<span class="op">::</span>is_always_strided<span class="op">()</span>;</span>
<span id="cb74-70"><a href="#cb74-70" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb74-71"><a href="#cb74-71" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-72"><a href="#cb74-72" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> is_unique<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb74-73"><a href="#cb74-73" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <em>map_</em><span class="op">.</span>is_unique<span class="op">()</span>;</span>
<span id="cb74-74"><a href="#cb74-74" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb74-75"><a href="#cb74-75" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> is_contiguous<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb74-76"><a href="#cb74-76" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <em>map_</em><span class="op">.</span>is_contiguous<span class="op">()</span>;</span>
<span id="cb74-77"><a href="#cb74-77" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb74-78"><a href="#cb74-78" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">bool</span> is_strided<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb74-79"><a href="#cb74-79" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <em>map_</em><span class="op">.</span>is_strided<span class="op">()</span>;</span>
<span id="cb74-80"><a href="#cb74-80" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb74-81"><a href="#cb74-81" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> size_type stride<span class="op">(</span><span class="dt">size_t</span> r<span class="op">)</span> <span class="kw">const</span> <span class="op">{</span></span>
<span id="cb74-82"><a href="#cb74-82" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <em>map_</em><span class="op">.</span>stride<span class="op">(</span>r<span class="op">)</span>;</span>
<span id="cb74-83"><a href="#cb74-83" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb74-84"><a href="#cb74-84" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-85"><a href="#cb74-85" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb74-86"><a href="#cb74-86" aria-hidden="true" tabindex="-1"></a>  accessor_type <em>acc_</em>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb74-87"><a href="#cb74-87" aria-hidden="true" tabindex="-1"></a>  mapping_type <em>map_</em>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb74-88"><a href="#cb74-88" aria-hidden="true" tabindex="-1"></a>  pointer <em>ptr_</em> <span class="op">=</span> pointer<span class="op">()</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb74-89"><a href="#cb74-89" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb74-90"><a href="#cb74-90" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-91"><a href="#cb74-91" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span><span class="op">...</span> Integrals<span class="op">&gt;</span></span>
<span id="cb74-92"><a href="#cb74-92" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> mdspan<span class="op">(</span>ElementType<span class="op">*</span>, Integrals<span class="op">...)</span></span>
<span id="cb74-93"><a href="#cb74-93" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span>
<span id="cb74-94"><a href="#cb74-94" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-95"><a href="#cb74-95" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb74-96"><a href="#cb74-96" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;)</span></span>
<span id="cb74-97"><a href="#cb74-97" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span>
<span id="cb74-98"><a href="#cb74-98" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-99"><a href="#cb74-99" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="dt">size_t</span><span class="op">...</span> ExtentsPack<span class="op">&gt;</span></span>
<span id="cb74-100"><a href="#cb74-100" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> extents<span class="op">&lt;</span>ExtentsPack<span class="op">...&gt;&amp;)</span></span>
<span id="cb74-101"><a href="#cb74-101" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span>
<span id="cb74-102"><a href="#cb74-102" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-103"><a href="#cb74-103" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> MappingType<span class="op">&gt;</span></span>
<span id="cb74-104"><a href="#cb74-104" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> MappingType<span class="op">&amp;)</span></span>
<span id="cb74-105"><a href="#cb74-105" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span>
<span id="cb74-106"><a href="#cb74-106" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-107"><a href="#cb74-107" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> MappingType, <span class="kw">class</span> AccessorType<span class="op">&gt;</span></span>
<span id="cb74-108"><a href="#cb74-108" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> MappingType<span class="op">&amp;</span>, <span class="kw">const</span> AccessorType<span class="op">&amp;)</span></span>
<span id="cb74-109"><a href="#cb74-109" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span>
<span id="cb74-110"><a href="#cb74-110" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb74-111"><a href="#cb74-111" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<!-- mfh 20 Jan 2019: Putting the template parameters after the class declaration imitates [span.overview]. -->
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<code>mdspan&lt;ElementType, Extents, LayoutPolicy, AccessorPolicy&gt;</code>
is a trivially copyable type if <code>AccessorPolicy</code>,
<code>LayoutPolicy::mapping_type&lt;Extents&gt;</code> and
<code>AccessorPolicy::pointer</code> are trivially copyable types.</p>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<code>ElementType</code> is required to be a complete object type that
is neither an abstract class type nor an array type.
<!-- mfh 20 Jan 2019: This imitates [span.overview] para 4 wording, with an additional restriction --></p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
If <code>Extents</code> is not a specialization of <code>extents</code>,
then the program is ill-formed.</p>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
If <code>LayoutPolicy</code> does not meet the layout mapping policy
requirements, then behavior is undefined.</p>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<code>AccessorPolicy</code> shall meet the accessor policy requirements.
If
<code>is_same_v&lt;typename AccessorPolicy::element_type, ElementType&gt;</code>
equals <code>false</code>, then the program is ill-formed.</p>
<!--

 ##              #               #
#   ### ##   ## ### ### # # ### ### ### ###  ##
#   # # # #  #   #  #   # # #    #  # # #    #
#   ### # # ##   ## #   ### ###  ## ### #   ##
 ##

-->
<p><b>22.7.�.1 <code>mdspan</code> constructors and assignment operators
[mdspan.mdspan.cons]</b></p>
<div class="sourceCode" id="cb75"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb75-1"><a href="#cb75-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> SizeTypes<span class="op">&gt;</span></span>
<span id="cb75-2"><a href="#cb75-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> <span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, SizeTypes<span class="op">...</span> exts<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span>
<code>(is_convertible_v&lt;SizeTypes, size_type&gt; &amp;&amp; ...)</code>
is <code>true</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span>
<code>is_constructible_v&lt;Extents, static_cast&lt;size_type&gt;(SizeTypes)...&gt;</code>
is <code>true</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.3)</a></span>
<code>is_constructible_v&lt;mapping_type, Extents&gt;</code> is
<code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.4)</a></span>
<code>is_default_constructible_v&lt;accessor_type&gt;</code> is
<code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Precondition:</em> <span class="math inline">[</span><code>p</code>,<em><code>map_</code></em><code>.required_span_size()</code><span class="math inline">)</span> is an accesible range of
<em><code>acc_</code></em> for the values of <em><code>map_</code></em>
and <em><code>acc_</code></em> after the invocation of this
constructor.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.1)</a></span>
Direct-non-list-initializes <em><code>ptr_</code></em> with
<code>std::move(p)</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span>
Direct-non-list-initializes <em><code>map_</code></em> with
<code>Extents(static_cast&lt;size_type&gt;(std::move(exts))...)</code>.</p></li>
</ul>
<div class="sourceCode" id="cb76"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb76-1"><a href="#cb76-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb76-2"><a href="#cb76-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(</span>N <span class="op">!=</span> rank_dynamic<span class="op">())</span></span>
<span id="cb76-3"><a href="#cb76-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, <span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;</span> exts<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.1)</a></span>
<code>is_convertible_v&lt;const SizeType&amp;, size_type&gt;</code> is
<code>true</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.2)</a></span>
<code>is_constructible_v&lt;extents_type, const array&lt;SizeType, N&gt;&amp;&gt;</code>
is <code>true</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.3)</a></span>
<code>is_constructible_v&lt;mapping_type, extents_type&gt;</code> is
<code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.4)</a></span>
<code>is_default_constructible_v&lt;accessor_type&gt;</code> is
<code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Precondition:</em> <span class="math inline">[</span><code>p</code>,<em><code>map_</code></em><code>.required_span_size()</code><span class="math inline">)</span> is an accesible range of
<em><code>acc_</code></em> for the values of <em><code>map_</code></em>
and <em><code>acc_</code></em> after the invocation of this
constructor.</p>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(6.1)</a></span>
Direct-non-list-initializes <em><code>ptr_</code></em> with
<code>std::move(p)</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(6.2)</a></span>
Direct-non-list-initializes <em><code>map_</code></em> with
<code>extents_type(exts)</code>.</p></li>
</ul>
<div class="sourceCode" id="cb77"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb77-1"><a href="#cb77-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, <span class="kw">const</span> extents_type<span class="op">&amp;</span> ext<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.1)</a></span>
<code>is_constructible_v&lt;mapping_type, const extents_type&amp;&gt;</code>
is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.2)</a></span>
<code>is_default_constructible_v&lt;accessor_type&gt;</code> is
<code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Precondition:</em> <span class="math inline">[</span><code>p</code>,<em><code>map_</code></em><code>.required_span_size()</code><span class="math inline">)</span> is an accesible range of
<em><code>acc_</code></em> for the values of <em><code>map_</code></em>
and <em><code>acc_</code></em> after the invocation of this
constructor.</p>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.1)</a></span>
Direct-non-list-initializes <em><code>ptr_</code></em> with
<code>std::move(p)</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.2)</a></span>
Direct-non-list-initializes <em><code>map_</code></em> with
<code>ext</code>.</p></li>
</ul>
<div class="sourceCode" id="cb78"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb78-1"><a href="#cb78-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, <span class="kw">const</span> mapping_type<span class="op">&amp;</span> m<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Constraints:</em>
<code>is_default_constructible_v&lt;accessor_type&gt;</code> is
<code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Precondition:</em> <span class="math inline">[</span><code>p</code>,<code>m.required_span_size()</code><span class="math inline">)</span> is an accesible range of
<em><code>acc_</code></em> for value of <em><code>acc_</code></em> after
the invocation of this constructor.</p>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span>
<em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(12.1)</a></span>
Direct-non-list-initializes <em><code>ptr_</code></em> with
<code>std::move(p)</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(12.2)</a></span>
Direct-non-list-initializes <em><code>map_</code></em> with
<code>m</code>.</p></li>
</ul>
<div class="sourceCode" id="cb79"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb79-1"><a href="#cb79-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> mdspan<span class="op">(</span>pointer p, <span class="kw">const</span> mapping_type<span class="op">&amp;</span> m, <span class="kw">const</span> accessor_type<span class="op">&amp;</span> a<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span>
<em>Precondition:</em> <span class="math inline">[</span><code>p</code>,<code>m.required_span_size()</code><span class="math inline">)</span> is an accesible range of
<code>a</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span><em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(14.1)</a></span>
Direct-non-list-initializes <em><code>ptr_</code></em> with
<code>std::move(p)</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(14.2)</a></span>
Direct-non-list-initializes <em><code>map_</code></em> with
<code>m</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(14.3)</a></span>
Direct-non-list-initializes <em><code>acc_</code></em> with
<code>a</code>.</p></li>
</ul>
<div class="sourceCode" id="cb80"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb80-1"><a href="#cb80-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherElementType, <span class="kw">class</span> OtherExtents,</span>
<span id="cb80-2"><a href="#cb80-2" aria-hidden="true" tabindex="-1"></a>         <span class="kw">class</span> OtherLayoutPolicy, <span class="kw">class</span> OtherAccessor<span class="op">&gt;</span></span>
<span id="cb80-3"><a href="#cb80-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb80-4"><a href="#cb80-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mdspan<span class="op">(</span><span class="kw">const</span> mdspan<span class="op">&lt;</span>OtherElementType, OtherExtents, </span>
<span id="cb80-5"><a href="#cb80-5" aria-hidden="true" tabindex="-1"></a>                                OtherLayoutPolicy, OtherAccessor<span class="op">&gt;&amp;</span> other<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span>
<em>Mandates:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(15.1)</a></span>
<code>is_constructible_v&lt;pointer, const OtherAccessor::pointer&amp;&gt;</code>
is <code>true</code>;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(15.2)</a></span>
<code>is_constructible_v&lt;extents_type, OtherExtents&gt;</code> is
<code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(16.1)</a></span>
<code>is_constructible_v&lt;mapping_type, const OtherLayoutPolicy::template mapping&lt;OtherExtents&gt;&amp;&gt;</code>
is <code>true</code>;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(16.2)</a></span>
<code>is_constructible_v&lt;accessor_type, const OtherAccessor&amp;&gt;</code>
is <code>true</code>; and</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span>
<em>Preconditions:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(17.1)</a></span> For
each rank index <code>r</code> of <code>extents_type</code>,
<code>static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r)</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(17.2)</a></span>
<span class="math inline">[</span><em><code>ptr_</code></em>,<em><code>map_</code></em><code>.required_span_size()</code><span class="math inline">)</span> is an accesible range of
<em><code>acc_</code></em> for values of <em><code>ptr_</code></em>,
<em><code>map_</code></em> and <em><code>acc_</code></em> after the
invocation of this constructor.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">18</a></span>
<em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(18.1)</a></span>
Direct-non-list-initializes <em><code>ptr_</code></em> with
<code>other.</code><em><code>ptr_</code></em>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(18.2)</a></span>
Direct-non-list-initializes <em><code>map_</code></em> with
<code>other.</code><em><code>map_</code></em>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(18.3)</a></span>
Direct-non-list-initializes <em><code>acc_</code></em> with
<code>other.</code><em><code>acc_</code></em>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">19</a></span>
<em>Remarks:</em> The expression inside <code>explicit</code> is:</p>
<div class="sourceCode" id="cb81"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb81-1"><a href="#cb81-1" aria-hidden="true" tabindex="-1"></a>  <span class="op">!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span><span class="kw">const</span> <span class="kw">typename</span> OtherLayoutPolicy<span class="op">::</span>mapping_type<span class="op">&amp;</span>, mapping_type<span class="op">&gt;</span> <span class="op">||</span></span>
<span id="cb81-2"><a href="#cb81-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span><span class="kw">const</span> OtherAccessorPolicy<span class="op">&amp;</span>, AccessorPolicy<span class="op">&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb82"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb82-1"><a href="#cb82-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span><span class="op">...</span> Integrals<span class="op">&gt;</span></span>
<span id="cb82-2"><a href="#cb82-2" aria-hidden="true" tabindex="-1"></a><span class="kw">explicit</span> mdspan<span class="op">(</span>ElementType<span class="op">*</span>, Integrals<span class="op">...)</span></span>
<span id="cb82-3"><a href="#cb82-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">20</a></span>
<em>Constraints:</em>
<code>(is_convertible_v&lt;Integrals, size_type&gt; &amp;&amp; ...)</code>
is <code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">21</a></span>
<em>Remarks:</em> The deduced type is
<code>mdspan&lt;ElementType, dextents&lt;sizeof...(Integrals)&gt;&gt;</code>.</p>
<div class="sourceCode" id="cb83"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb83-1"><a href="#cb83-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb83-2"><a href="#cb83-2" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;)</span></span>
<span id="cb83-3"><a href="#cb83-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">22</a></span>
<em>Remarks:</em> The deduced type is
<code>mdspan&lt;ElementType, dextents&lt;N&gt;&gt;</code>.</p>
<div class="sourceCode" id="cb84"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb84-1"><a href="#cb84-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="dt">size_t</span><span class="op">...</span> ExtentsPack<span class="op">&gt;</span></span>
<span id="cb84-2"><a href="#cb84-2" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> extents<span class="op">&lt;</span>ExtentsPack<span class="op">...&gt;&amp;)</span></span>
<span id="cb84-3"><a href="#cb84-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">23</a></span>
<em>Remarks:</em> The deduced type is
<code>mdspan&lt;ElementType, extents&lt;ExtentsPack...&gt;&gt;</code>.</p>
<div class="sourceCode" id="cb85"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb85-1"><a href="#cb85-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> MappingType<span class="op">&gt;</span></span>
<span id="cb85-2"><a href="#cb85-2" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> MappingType<span class="op">&amp;)</span></span>
<span id="cb85-3"><a href="#cb85-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">24</a></span>
<em>Remarks:</em> The deduced type is
<code>mdspan&lt;ElementType, typename MappingType::extents_type, typename MappingType::layout_type&gt;</code>.</p>
<div class="sourceCode" id="cb86"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb86-1"><a href="#cb86-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> MappingType, <span class="kw">class</span> AccessorType<span class="op">&gt;</span></span>
<span id="cb86-2"><a href="#cb86-2" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> MappingType<span class="op">&amp;</span>, <span class="kw">const</span> AccessorType<span class="op">&amp;)</span></span>
<span id="cb86-3"><a href="#cb86-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span><em>see below</em><span class="op">&gt;</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">25</a></span>
<em>Remarks:</em> The deduced type is
<code>mdspan&lt;ElementType, typename MappingType::extents_type, typename MappingType::layout_type, AccessorType&gt;</code>.</p>
<!--

  #              #                           #
### ### ###  ##     ##      ###  ## ### ###     ##  ###
# # # # ### # #  #  # #     ### # # # # # #  #  # # # #
### ### # # ###  ## # #     # # ### ### ###  ## # #  ##
                                    #   #           ###
-->
<p><br /> <b>22.7.�.2 <code>mdspan</code> members
[mdspan.mdspan.members]</b></p>
<div class="sourceCode" id="cb87"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb87-1"><a href="#cb87-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> SizeTypes<span class="op">&gt;</span></span>
<span id="cb87-2"><a href="#cb87-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> reference <span class="kw">operator</span><span class="op">[](</span>SizeTypes<span class="op">...</span> indices<span class="op">)</span> <span class="kw">const</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span>
<code>(is_convertible_v&lt;SizeTypes, size_type&gt; &amp;&amp; ...)</code>
is <code>true</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span>
<code>(is_nothrow_constructible_v&lt;size_type, SizeTypes&gt; &amp;&amp; ...)</code>
is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.3)</a></span>
<code>sizeof...(SizeTypes) == rank()</code> is
<code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
Let <code>I</code> be
<code>static_cast&lt;size_type&gt;(std::move(indices))</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Preconditions:</em> <code>I...</code> is a multidimensional index
into <code>extents()</code>. <i>[Note:</i> This implies that
<em><code>map_</code></em><code>(I...) &lt;</code><em><code>map_</code></em><code>.required_span_size()</code>
is <code>true</code>.<i>— end note]</i>;</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Effects:</em> Equivalent to: <code>return</code>
<em><code>acc_</code></em><code>.access(</code><em><code>ptr_</code></em><code>,</code><em><code>map_</code></em><code>(I...));</code>.</p>
<div class="sourceCode" id="cb88"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb88-1"><a href="#cb88-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeType, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb88-2"><a href="#cb88-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> reference <span class="kw">operator</span><span class="op">[](</span><span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;</span> indices<span class="op">)</span> <span class="kw">const</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.1)</a></span>
<code>is_convertible_v&lt;const SizeType&amp;, size_type&gt;</code> is
<code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.2)</a></span>
<code>is_nothrow_constructible_v&lt;size_type, const SizeType&amp;&gt;</code>
is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.3)</a></span>
<code>rank() == N</code> is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Effects:</em> Let <code>P...</code> be the parameter pack such that
<code>is_same_v&lt;make_index_sequence&lt;rank()&gt;, index_sequence&lt;P...&gt;&gt;</code>
is <code>true</code>. <br /> Equivalent to:
<code>return operator[](static_cast&lt;size_type&gt;(indices[P])...);</code></p>
<div class="sourceCode" id="cb89"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb89-1"><a href="#cb89-1" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> size_type size<span class="op">()</span> <span class="kw">const</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Returns:</em>
<em><code>fwd-prod-of-extents</code></em><code>(extents(), rank())</code>.</p>
<!--
submdspan

                     /$$
                    | $$
  /$$$$$$$ /$$   /$$| $$$$$$$   /$$$$$$$  /$$$$$$   /$$$$$$  /$$$$$$$
 /$$_____/| $$  | $$| $$__  $$ /$$_____/ /$$__  $$ |____  $$| $$__  $$
|  $$$$$$ | $$  | $$| $$  \ $$|  $$$$$$ | $$  \ $$  /$$$$$$$| $$  \ $$
 \____  $$| $$  | $$| $$  | $$ \____  $$| $$  | $$ /$$__  $$| $$  | $$
 /$$$$$$$/|  $$$$$$/| $$$$$$$/ /$$$$$$$/| $$$$$$$/|  $$$$$$$| $$  | $$
|_______/  \______/ |_______/ |_______/ | $$____/  \_______/|__/  |__/
                                        | $$
                                        | $$
                                        |__/
-->
<p><b>22.7.� submdspan [mdspan.submdspan]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<code>submdspan</code> creates an <code>mdspan</code> with a domain that
is a subset of the input <code>mdspan</code>’s domain, and a codomain
that is a subset of the input <code>mdspan</code>’s codomain.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
The <code>SliceSpecifier</code> template argument(s) and the
corresponding value(s) of the arguments of <code>submdspan</code> after
<code>src</code> determine the subset of <code>src</code> that the
<code>mdspan</code> returned by <code>submdspan</code> views.</p>
<div class="sourceCode" id="cb90"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb90-1"><a href="#cb90-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb90-2"><a href="#cb90-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb90-3"><a href="#cb90-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.submdspan], submdspan creation</span></span>
<span id="cb90-4"><a href="#cb90-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> Extents, <span class="kw">class</span> LayoutPolicy,</span>
<span id="cb90-5"><a href="#cb90-5" aria-hidden="true" tabindex="-1"></a>           <span class="kw">class</span> AccessorPolicy, <span class="kw">class</span><span class="op">...</span> SliceSpecifiers<span class="op">&gt;</span></span>
<span id="cb90-6"><a href="#cb90-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> submdspan<span class="op">(</span></span>
<span id="cb90-7"><a href="#cb90-7" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> mdspan<span class="op">&lt;</span>ElementType, Extents, LayoutPolicy, AccessorPolicy<span class="op">&gt;&amp;</span> src,</span>
<span id="cb90-8"><a href="#cb90-8" aria-hidden="true" tabindex="-1"></a>      SliceSpecifiers<span class="op">...</span>slices<span class="op">)</span> <span class="op">-&gt;</span> <em>see below</em>;</span>
<span id="cb90-9"><a href="#cb90-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
Let <code>sub</code> be the return value of
<code>submdspan(src, slices...)</code>, let <span class="math inline"><em>s</em><sub><em>k</em></sub></span> be the <span class="math inline"><em>k</em></span>-th element of
<code>slices...</code>, and let <span class="math inline"><em>S</em><sub><em>k</em></sub></span> be the type
of the <span class="math inline"><em>k</em></span>-th element of
<code>slices...</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
Let <em><code>map-rank</code></em> be an
<code>array&lt;size_t,Extents::rank()&gt;</code> such that for all
<code>j</code> in the range <code>[0, Extents::rank())</code>
<em><code>map-rank</code></em><code>[j]</code> equals:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.1)</a></span>
<code>dynamic_extent</code> if <code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>j</em></sub></span><code>,size_t&gt;</code>
is <code>true</code>, or else</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.2)</a></span> the
number of <span class="math inline"><em>S</em><sub><em>k</em></sub></span> with <span class="math inline"><em>k</em> &lt; <em>j</em></span> such that
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,size_t&gt;</code>
is <code>false</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
Let <em><code>first</code></em> and <em><code>last</code></em> be
<code>array&lt;size_t,Extents::rank()&gt;</code>. For each rank index
<code>r</code> of <code>src.extents()</code>, define the values of
<em><code>first</code></em><code>[r]</code> and
<em><code>last</code></em><code>[r]</code> as follows:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.1)</a></span> if
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>r</em></sub></span><code>,size_t&gt;</code>
is <code>true</code>, then <em><code>first</code></em><code>[r]</code>
equals <span class="math inline"><em>s</em><sub><em>r</em></sub></span>,
and <em><code>last</code></em><code>[r]</code> equals
<em><code>first</code></em><code>[r]</code> + 1;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.2)</a></span>
otherwise, if <code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>r</em></sub></span><code>,tuple&lt;size_t,size_t&gt;&gt;</code>
is <code>true</code>, then <em><code>first</code></em><code>[r]</code>
equals <code>get&lt;0&gt;(t)</code>, and
<em><code>last</code></em><code>[r]</code> equals
<code>get&lt;1&gt;(t)</code>, where <code>t</code> is the result of
converting <span class="math inline"><em>s</em><sub><em>r</em></sub></span> to
<code>tuple&lt;size_t,size_t&gt;</code>;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.3)</a></span>
otherwise, if <code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>r</em></sub></span><code>,full_extent_t&gt;</code>
is <code>true</code>, then <em><code>first</code></em><code>[r]</code>
equals <code>0</code>, and <em><code>last</code></em><code>[r]</code>
equals <code>src.extent(r)</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span>
<em>Mandates:</em> For each rank index <code>r</code> of
<code>src.extents()</code> only one of the following is
<code>true</code>: <code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,size_t&gt;</code>,
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,tuple&lt;size_t,size_t&gt;&gt;</code>,
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,full_extent_t&gt;</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.1)</a></span>
<code>sizeof(slices...)</code> equals
<code>Extents::rank()</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.2)</a></span> For
each rank index <code>k</code> of <code>src.extents()</code>,
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,size_t&gt; || is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,tuple&lt;size_t,size_t&gt;&gt; || is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,full_extent_t&gt;</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.3)</a></span>
<code>LayoutPolicy</code> is <code>layout_left</code>,
<code>layout_right</code>, <code>layout_stride</code>, or an
implementation-defined layout mapping policy type.
<b>[mdspan.layout.reqs]</b> <i>[Note:</i> Implementation and user
defined layout mapping policies could exist, for which taking an
arbitrary <code>submdspan</code> does not make sense. <i>— end
note]</i>;</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span>
<em>Preconditions:</em> For each rank index <code>r</code> of
<code>src.extents()</code>,
<code>0 &lt;=</code><em><code>first</code></em><code>[r] &amp;&amp;</code><em><code>first</code></em><code>[r] &lt;=</code><em><code>last</code></em><code>[r] &amp;&amp;</code><em><code>last</code></em><code>[r] &lt;= src.extent(r)</code>
is <code>true</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span>
<em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.1)</a></span>
Direct-non-list-initializes <code>sub.</code><em><code>acc_</code></em>
with <code>src.accessor()</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.2)</a></span>
Direct-non-list-initializes <code>sub.</code><em><code>ptr_</code></em>
with
<code>src.accessor().offset(src.data(),apply(src.mapping(),</code><em><code>first</code></em><code>))</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span>
<em>Postconditions:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.1)</a></span> For
<span class="math inline">0 ≤</span> <code>k</code> &lt;
<code>Extents::rank()</code>, if
<em><code>map-rank</code></em><code>[k] != dynamic_extent</code> is
<code>true</code>, then
<code>sub.extent(</code><em><code>map-rank</code></em><code>[k])</code>
equals
<em><code>last</code></em><code>[k] -</code><em><code>first</code></em><code>[k]</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.2)</a></span> Let
<code>j...</code> be a multidimensional index into
<code>sub.extents()</code>, let <code>J</code> be
<code>array{static_cast&lt;size_t&gt;(j)...}</code>, let <code>I</code>
be <code>array&lt;size_t,decltype(src)::rank()&gt;</code> such that
<code>I[k] ==</code><em><code>first</code></em><code>[k] + (</code><em><code>map-rank</code></em><code>[k]==dynamic_extent?0:J[</code><em><code>map-rank</code></em><code>[k]])</code>
is <code>true</code>, then <code>sub[J]</code> and <code>src[I]</code>
refer to the same element.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.3)</a></span> If
<code>src.is_strided()</code> is <code>true</code>, then
<code>sub.is_strided()</code> is <code>true</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span>
<em>Remarks:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(11.1)</a></span> Let
<code>SubExtents</code> be a specialization of <code>extents</code> such
that:</p>
<ul>
<li><p><code>SubExtents::rank()</code> equals the number of <span class="math inline"><em>k</em></span> such that
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,tuple&lt;size_t,size_t&gt;&gt; || is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,full_extent_t&gt;</code>
is <code>true</code> and <code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,size_t&gt;</code>
is <code>false</code>.</p></li>
<li><p>For all rank index <code>k</code> of <code>Extents</code> such
that <em><code>map-rank</code></em><code>[k] != dynamic_extent</code> is
<code>true</code>
<code>SubExtents::static_extent(</code><em><code>map-rank</code></em><code>[k])</code>
equals:</p>
<ul>
<li><p><code>Extents::static_extent(k)</code> if
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,full_extent_t&gt;</code>
is <code>true</code>, otherwise</p></li>
<li><p><code>dynamic_extent</code>.</p></li>
</ul></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(11.2)</a></span> Let
<code>SubLayout</code> be a type that meets the requirements of layout
mapping policy and:</p>
<ul>
<li><p>if <code>LayoutPolicy</code> is not one of
<code>layout_left</code>, <code>layout_right</code>,
<code>layout_stride</code>, then <code>SubLayout</code> is
implementation defined, otherwise</p></li>
<li><p>if <code>SubExtents::rank()</code> is <code>0</code>, then
<code>SubLayout</code> is <code>LayoutPolicy</code>, otherwise</p></li>
<li><p>if <code>LayoutPolicy</code> is <code>layout_left</code>,
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,full_extent_t&gt;</code>
is <code>true</code> for all <code>k</code> in the range <span class="math inline">[0,</span><code>SubExtents::rank()-1</code><span class="math inline">)</span>, and <code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,size_t&gt;</code>
is <code>false</code> for <code>k</code> equal
<code>SubExtents::rank()-1</code>, then <code>SubLayout</code> is
<code>layout_left</code>, otherwise</p></li>
<li><p>if <code>LayoutPolicy</code> is <code>layout_right</code>,
<code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,full_extent_t&gt;</code>
is <code>true</code> for all <code>k</code> in the range <span class="math inline">[</span><code>Extents::rank()-SubExtents::rank()+1</code><span class="math inline">,</span><code>Extents::rank()</code><span class="math inline">)</span> and <code>is_convertible_v&lt;</code><span class="math inline"><em>S</em><sub><em>k</em></sub></span><code>,size_t&gt;</code>
is <code>false</code> for <code>k</code> equal
<code>Extents::rank()-SubExtents::rank()</code>, then
<code>SubLayout</code> is <code>layout_right</code>, otherwise</p></li>
<li><p><code>SubLayout</code> is <code>layout_stride</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(11.3)</a></span> The
return type is
<code>mdspan&lt;ElementType,SubExtents,SubLayout,typename Accesssor::offset_policy&gt;</code>
where</p></li>
</ul>
<p><br /></p>
<p><i>[Note:</i> Example of <code>submdspan</code> use: See code below
<i>- end note]</i></p>
<div class="sourceCode" id="cb91"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb91-1"><a href="#cb91-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Create a mapping</span></span>
<span id="cb91-2"><a href="#cb91-2" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> Extents3D <span class="op">=</span> extents<span class="op">&lt;</span><span class="dv">3</span>, dynamic_extent, <span class="dv">7</span><span class="op">&gt;</span>;</span>
<span id="cb91-3"><a href="#cb91-3" aria-hidden="true" tabindex="-1"></a>layout_right<span class="op">::</span><span class="kw">template</span> mapping<span class="op">&lt;</span>Extents3D<span class="op">&gt;</span> map_right<span class="op">(</span><span class="dv">10</span><span class="op">)</span>;</span>
<span id="cb91-4"><a href="#cb91-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-5"><a href="#cb91-5" aria-hidden="true" tabindex="-1"></a><span class="co">// Create an mdspan viewing allocated memory</span></span>
<span id="cb91-6"><a href="#cb91-6" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span><span class="op">*</span> ptr <span class="op">=</span> <span class="kw">new</span> <span class="dt">int</span><span class="op">[</span><span class="dv">3</span><span class="op">*</span><span class="dv">8</span><span class="op">*</span><span class="dv">10</span><span class="op">]</span>;</span>
<span id="cb91-7"><a href="#cb91-7" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">&lt;</span><span class="dt">int</span>, Extents3D, layout_right<span class="op">&gt;</span> a<span class="op">(</span>ptr, map_right<span class="op">)</span>;</span>
<span id="cb91-8"><a href="#cb91-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-9"><a href="#cb91-9" aria-hidden="true" tabindex="-1"></a><span class="co">// Initialize the span</span></span>
<span id="cb91-10"><a href="#cb91-10" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span><span class="op">(</span><span class="dt">int</span> i0 <span class="op">=</span> <span class="dv">0</span>; i0 <span class="op">&lt;</span> a<span class="op">.</span>extent<span class="op">(</span><span class="dv">0</span><span class="op">)</span>; <span class="op">++</span>i0<span class="op">)</span> <span class="op">{</span></span>
<span id="cb91-11"><a href="#cb91-11" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span><span class="op">(</span><span class="dt">int</span> i1 <span class="op">=</span> <span class="dv">0</span>; i1 <span class="op">&lt;</span> a<span class="op">.</span>extent<span class="op">(</span><span class="dv">1</span><span class="op">)</span>; <span class="op">++</span>i1<span class="op">)</span> <span class="op">{</span></span>
<span id="cb91-12"><a href="#cb91-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span><span class="op">(</span><span class="dt">int</span> i2 <span class="op">=</span> <span class="dv">0</span>; i2 <span class="op">&lt;</span> a<span class="op">.</span>extent<span class="op">(</span><span class="dv">2</span><span class="op">)</span>; <span class="op">++</span>i2<span class="op">)</span> <span class="op">{</span></span>
<span id="cb91-13"><a href="#cb91-13" aria-hidden="true" tabindex="-1"></a>      a<span class="op">[</span>i0, i1, i2<span class="op">]</span> <span class="op">=</span> <span class="dv">10000</span><span class="op">*</span>i0 <span class="op">+</span> <span class="dv">100</span><span class="op">*</span>i1 <span class="op">+</span> i2;</span>
<span id="cb91-14"><a href="#cb91-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb91-15"><a href="#cb91-15" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb91-16"><a href="#cb91-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb91-17"><a href="#cb91-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-18"><a href="#cb91-18" aria-hidden="true" tabindex="-1"></a><span class="co">// Create Subspan</span></span>
<span id="cb91-19"><a href="#cb91-19" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> a_sub <span class="op">=</span> submdspan<span class="op">(</span>a, <span class="dv">1</span>, tuple<span class="op">{</span><span class="dv">4</span>,<span class="dv">6</span><span class="op">}</span>, tuple<span class="op">{</span><span class="dv">1</span>,<span class="dv">6</span><span class="op">})</span>;</span>
<span id="cb91-20"><a href="#cb91-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-21"><a href="#cb91-21" aria-hidden="true" tabindex="-1"></a><span class="co">// Print values of submdspan</span></span>
<span id="cb91-22"><a href="#cb91-22" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span><span class="op">(</span><span class="dt">int</span> i0 <span class="op">=</span> <span class="dv">0</span>; i0 <span class="op">&lt;</span> a_sub<span class="op">.</span>extent<span class="op">(</span><span class="dv">0</span><span class="op">)</span>; <span class="op">++</span>i0<span class="op">)</span> <span class="op">{</span></span>
<span id="cb91-23"><a href="#cb91-23" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span><span class="op">(</span><span class="dt">int</span> i1 <span class="op">=</span> <span class="dv">0</span>; i1 <span class="op">&lt;</span> a_sub<span class="op">.</span>extent<span class="op">(</span><span class="dv">1</span><span class="op">)</span>; <span class="op">++</span>i1<span class="op">)</span> <span class="op">{</span></span>
<span id="cb91-24"><a href="#cb91-24" aria-hidden="true" tabindex="-1"></a>    cout <span class="op">&lt;&lt;</span> a_sub<span class="op">[</span>i0, i1<span class="op">]</span> <span class="op">&lt;&lt;</span> <span class="st">&quot; &quot;</span>;</span>
<span id="cb91-25"><a href="#cb91-25" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb91-26"><a href="#cb91-26" aria-hidden="true" tabindex="-1"></a>  cout <span class="op">&lt;&lt;</span> endl;</span>
<span id="cb91-27"><a href="#cb91-27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb91-28"><a href="#cb91-28" aria-hidden="true" tabindex="-1"></a><span class="kw">delete</span> <span class="op">[]</span> ptr;</span>
<span id="cb91-29"><a href="#cb91-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb91-30"><a href="#cb91-30" aria-hidden="true" tabindex="-1"></a><span class="co">/* Output</span></span>
<span id="cb91-31"><a href="#cb91-31" aria-hidden="true" tabindex="-1"></a><span class="co">10401 10402 10403 10404 10405</span></span>
<span id="cb91-32"><a href="#cb91-32" aria-hidden="true" tabindex="-1"></a><span class="co">10501 10502 10503 10504 10505</span></span>
<span id="cb91-33"><a href="#cb91-33" aria-hidden="true" tabindex="-1"></a><span class="co">*/</span></span></code></pre></div>
<h1 data-number="5" id="implementation"><span class="header-section-number">5</span> Implementation<a href="#implementation" class="self-link"></a></h1>
<p>There is an mdspan implementation available at <a href="https://github.com/kokkos/mdspan/">https://github.com/kokkos/mdspan/</a>.</p>
<h1 data-number="6" id="related-work"><span class="header-section-number">6</span> Related Work<a href="#related-work" class="self-link"></a></h1>
<p>The original version of this paper, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4355.pdf">N4355</a>,
predates the “P” naming for papers.</p>
<p><b>Related papers:</b></p>
<ul>
<li><b>P0122</b> : span: bounds-safe views for sequences of objects The
<code>mdspan</code> codomain concept of <em>span</em> is well-aligned
with this paper.</li>
<li><b>P0367</b> : Accessors: The P0367 Accessors proposal includes
polymorphic mechanisms for accessing the memory an object or span of
objects. The <code>AccessorPolicy</code> extension point in this
proposal is intended to include such memory access properties.</li>
<li><b>P0331</b> : Motivation and Examples for Multidimensional
Array</li>
<li><b>P0332</b> : Relaxed Incomplete Multidimensional Array Type
Declaration</li>
<li><b>P0454</b> : Wording for a Minimal <code>mdspan</code> Included
proposed modification of <code>span</code> to better align
<code>span</code> with <code>mdspan</code>.</li>
<li><b>P0546</b> : Preparing <code>span</code> for the future Proposed
modification of <code>span</code></li>
<li><b>P0856</b> : Restrict access property for <code>mdspan</code> and
<code>span</code></li>
<li><b>P0860</b> : atomic access policy for <code>mdspan</code></li>
<li><b>P0900</b> : An Ontology of Properties for
<code>mdspan</code></li>
<li><b>P2128</b> : Multidimensional subscript operator</li>
<li><b>P2299</b> : <code>mdspan</code> and CTAD</li>
</ul>
</div>
</div>
</body>
</html>
