<!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="2021-11-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>2021-11-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="#p0009r14-2021-11-mailing"><span class="toc-section-number">1.1</span> P0009r14: 2021-11 Mailing<span></span></a></li>
<li><a href="#p0009r13-2021-10-mailing"><span class="toc-section-number">1.2</span> P0009r13: 2021-10 Mailing<span></span></a></li>
<li><a href="#p0009r12-post-2021-05-mailing"><span class="toc-section-number">1.3</span> P0009r12: post 2021-05 Mailing<span></span></a></li>
<li><a href="#p0009r11-2021-05-mailing"><span class="toc-section-number">1.4</span> P0009r11: 2021-05 Mailing<span></span></a></li>
<li><a href="#p0009r10-pre-2020-02-prague-mailing"><span class="toc-section-number">1.5</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.6</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.7</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.8</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.9</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.10</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.11</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.12</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.13</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.14</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.15</span> P0009r0 : Pre 2015-10-Kona Mailing<span></span></a></li>
<li><a href="#related-activity"><span class="toc-section-number">1.16</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="#next-steps"><span class="toc-section-number">5</span> Next Steps<span></span></a></li>
<li><a href="#implementation"><span class="toc-section-number">6</span> Implementation<span></span></a></li>
<li><a href="#related-work"><span class="toc-section-number">7</span> Related Work<span></span></a></li>
</ul>
</div>
<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="p0009r14-2021-11-mailing"><span class="header-section-number">1.1</span> P0009r14: 2021-11 Mailing<a href="#p0009r14-2021-11-mailing" class="self-link"></a></h2>
<h4 data-number="1.1.0.1" id="lewg-review-11012021"><span class="header-section-number">1.1.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.1.0.2" id="changes-from-r13"><span class="header-section-number">1.1.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.2" id="p0009r13-2021-10-mailing"><span class="header-section-number">1.2</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.3" id="p0009r12-post-2021-05-mailing"><span class="header-section-number">1.3</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.4" id="p0009r11-2021-05-mailing"><span class="header-section-number">1.4</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.5" id="p0009r10-pre-2020-02-prague-mailing"><span class="header-section-number">1.5</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.6" id="p0009r9-pre-2019-02-kona-mailing"><span class="header-section-number">1.6</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.7" id="p0009r8-pre-2018-11-sandiego-mailing"><span class="header-section-number">1.7</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.8" id="p0009r7-post-2018-06-rapperswil-mailing"><span class="header-section-number">1.8</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.9" id="p0009r6-pre-2018-06-rapperswil-mailing"><span class="header-section-number">1.9</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.10" id="p0009r5-pre-2018-03-jacksonville-mailing"><span class="header-section-number">1.10</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.11" id="p0009r4-pre-2017-11-albuquerque-mailing"><span class="header-section-number">1.11</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.12" id="p0009r3-post-2016-06-oulu-mailing"><span class="header-section-number">1.12</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.13" id="p0009r2-pre-2016-06-oulu-mailing"><span class="header-section-number">1.13</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.14" id="p0009r1-pre-2016-02-jacksonville-mailing"><span class="header-section-number">1.14</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.15" id="p0009r0-pre-2015-10-kona-mailing"><span class="header-section-number">1.15</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.16" id="related-activity"><span class="header-section-number">1.16</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> <span class="kw">decltype</span><span class="op">(</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">[]</span> <span class="op">&lt;</span><span class="dt">size_t</span><span class="op">...</span> Pack<span class="op">&gt;</span> <span class="op">(</span>index_sequence<span class="op">&lt;</span>Pack<span class="op">...&gt;)</span> <span class="kw">constexpr</span> <span class="op">{</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> extents<span class="op">&lt;</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>          <span class="op">[]</span> <span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="kw">constexpr</span> <span class="op">{</span> <span class="cf">return</span> dynamic_extent; <span class="op">}</span> <span class="op">(</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>            integral_constant<span class="op">&lt;</span><span class="dt">size_t</span>, Pack<span class="op">&gt;{})...&gt;{}</span>;</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">}(</span>make_index_sequence<span class="op">&lt;</span>Rank<span class="op">&gt;{}))</span>;</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="kw">template</span><span class="op">&lt;</span><span class="kw">class</span><span class="op">&gt;</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">size_t</span> make_dynamic_extent<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> dynamic_extent; <span class="op">}</span> <span class="co">// <em>exposition only</em></span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-17"><a href="#cb7-17" 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="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span> extents<span class="op">(</span>Integrals<span class="op">...)</span></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> extents<span class="op">&lt;</span>make_dynamic_extent<span class="op">&lt;</span>Integrals<span class="op">&gt;()...&gt;</span>;</span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.layout], Layout mapping policies</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> layout_left;</span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> layout_right;</span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> layout_stride;</span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.accessor.default]</span></span>
<span id="cb7-28"><a href="#cb7-28" 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-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a>    <span class="kw">class</span> default_accessor;</span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.mdspan], class template mdspan</span></span>
<span id="cb7-32"><a href="#cb7-32" 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-33"><a href="#cb7-33" 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-34"><a href="#cb7-34" aria-hidden="true" tabindex="-1"></a>    <span class="kw">class</span> mdspan;</span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-36"><a href="#cb7-36" 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="cb7-37"><a href="#cb7-37" 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="cb7-38"><a href="#cb7-38" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span>ElementType, dextents<span class="op">&lt;</span><span class="kw">sizeof</span><span class="op">...(</span>Integrals<span class="op">)&gt;</span>;</span>
<span id="cb7-39"><a href="#cb7-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-40"><a href="#cb7-40" 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="cb7-41"><a href="#cb7-41" 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="cb7-42"><a href="#cb7-42" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span>ElementType, dextents<span class="op">&lt;</span>N<span class="op">&gt;&gt;</span>;</span>
<span id="cb7-43"><a href="#cb7-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-44"><a href="#cb7-44" 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="cb7-45"><a href="#cb7-45" 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="cb7-46"><a href="#cb7-46" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span>ElementType, extents<span class="op">&lt;</span>ExtentsPack<span class="op">...&gt;&gt;</span>;</span>
<span id="cb7-47"><a href="#cb7-47" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-48"><a href="#cb7-48" 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="cb7-49"><a href="#cb7-49" 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="cb7-50"><a href="#cb7-50" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span>ElementType, <span class="kw">typename</span> MappingType<span class="op">::</span>extents_type, </span>
<span id="cb7-51"><a href="#cb7-51" aria-hidden="true" tabindex="-1"></a>              <span class="kw">typename</span> MappingType<span class="op">::</span>layout_type<span class="op">&gt;</span>;</span>
<span id="cb7-52"><a href="#cb7-52" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-53"><a href="#cb7-53" 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="cb7-54"><a href="#cb7-54" 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="cb7-55"><a href="#cb7-55" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span>ElementType, <span class="kw">typename</span> MappingType<span class="op">::</span>extents_type,</span>
<span id="cb7-56"><a href="#cb7-56" aria-hidden="true" tabindex="-1"></a>              <span class="kw">typename</span> MappingType<span class="op">::</span>layout_type, AccessorType<span class="op">&gt;</span>;</span>
<span id="cb7-57"><a href="#cb7-57" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-58"><a href="#cb7-58" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.submdspan]</span></span>
<span id="cb7-59"><a href="#cb7-59" 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-60"><a href="#cb7-60" 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-61"><a href="#cb7-61" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mdspan<span class="op">&lt;</span>ElementType, <em>see below</em>, <em>see below</em>, </span>
<span id="cb7-62"><a href="#cb7-62" aria-hidden="true" tabindex="-1"></a>                     <span class="kw">typename</span> AccessorPolicy<span class="op">::</span>offset_policy<span class="op">&gt;</span> submdspan<span class="op">(</span></span>
<span id="cb7-63"><a href="#cb7-63" 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-64"><a href="#cb7-64" aria-hidden="true" tabindex="-1"></a>      SliceSpecifiers <span class="op">...)</span>;</span>
<span id="cb7-65"><a href="#cb7-65" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-66"><a href="#cb7-66" aria-hidden="true" tabindex="-1"></a>  <span class="co">// tag supporting submdspan</span></span>
<span id="cb7-67"><a href="#cb7-67" 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-68"><a href="#cb7-68" 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> full_extent_t<span class="op">{}</span>;</span>
<span id="cb7-69"><a href="#cb7-69" 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 <em>multidimensional index</em> is an element within the a multidimensional index space and can be represented as a pack of integer types. The multidimensional index <code>idx...</code> refers to an element within the domain of a multidimensional index space if both the 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, 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 in the range <span class="math inline">[<em>I</em><sub><em>b</em></sub>, <em>I</em><sub><em>e</em></sub>)</span>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> For the following subsections, let <span class="math inline"><em>r</em></span> be a value 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.syn]</b></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 class="kw">constexpr</span> extents<span class="op">(</span>extents<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-13"><a href="#cb8-13" 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>extents<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-15"><a href="#cb8-15" 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-16"><a href="#cb8-16" 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-17"><a href="#cb8-17" 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-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><span class="op">...</span> SizeTypes<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="kw">constexpr</span> extents<span class="op">(</span>SizeTypes<span class="op">...)</span> <span class="kw">noexcept</span>;</span>
<span id="cb8-20"><a href="#cb8-20" 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-21"><a href="#cb8-21" 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-22"><a href="#cb8-22" 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-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.extents.obs], Observers of the domain multidimensional index space</span></span>
<span id="cb8-25"><a href="#cb8-25" 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-26"><a href="#cb8-26" 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-27"><a href="#cb8-27" 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>
<span id="cb8-28"><a href="#cb8-28" 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-29"><a href="#cb8-29" 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-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.extents.compare], extents comparison operators</span></span>
<span id="cb8-32"><a href="#cb8-32" 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-33"><a href="#cb8-33" 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-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> dynamic_index<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-37"><a href="#cb8-37" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> dynamic_index_inv<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>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true" tabindex="-1"></a>  array<span class="op">&lt;</span>size_type, rank_dynamic<span class="op">()&gt;</span> dynamic_extents_<span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><b>22.7.�.2 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>
<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>. For each <span class="math inline"><em>E</em><sub><em>r</em></sub></span> that is a <em>dynamic extent</em>, the upper bound of the interval is stored in the exposition-only array <code>dynamic_extents_</code> at <code>dynamic_extents_[dynamic_index(</code><em>r</em><code>)]</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> If <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a dynamic extent, let <span class="math inline"><em>D</em><sub><em>r</em></sub></span> be the value of <code>dynamic_extents_[dynamic_index(</code><em>r</em><code>)]</code>. 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 as follows:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.1)</a></span> <span class="math inline">[0, <em>E</em><sub><em>r</em></sub>)</span> if <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a static extent,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.2)</a></span> otherwise <span class="math inline">[0, <em>D</em><sub><em>r</em></sub>)</span>.</p></li>
</ul>
<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> dynamic_index<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>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Returns</em>: If <code>i &lt;= sizeof...(Extents)</code> is <code>true</code>, the number of arguments before the <code>i</code><em>th</em> template parameter in the template parameter pack <code>Extents</code> equivalent to <code>dynamic_extent</code>. Otherwise, <code>rank_dynamic()</code>.</li>
</ul>
<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> dynamic_index_inv<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>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Returns</em>: If <code>i &lt; rank_dynamic()</code> is true, the minimum value of <span class="math inline"><em>r</em></span> such that <code>dynamic_index(r+1)</code> equals <span class="math inline"><em>i</em> + 1</span>. Otherwise returns <code>rank()</code>.</li>
</ul>
<p><b>22.7.�.3 Constructors and assignment [mdspan.extents.cons]</b></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> OtherExtents<span class="op">&gt;</span></span>
<span id="cb11-2"><a href="#cb11-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="cb11-3"><a href="#cb11-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>
<ul>
<li><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)</code> equals <code>rank()</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span> For all <code>r</code> where <code>static_extent(r) != dynamic_extent</code> and <code>other.static_extent(r) != dynamic_extent</code> are both <code>true</code>, <code>static_extent(r) == other.static_extent(r)</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Preconditions:</em> For all <code>r</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">3</a></span> <em>Effects:</em> For each <code>r</code> where <code>static_extent(r) == dynamic_extent</code> is <code>true</code>, assigns <code>other.extent(r)</code> to <code>dynamic_extent[dynamic_index(r)]</code>.</p></li>
<li><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></li>
</ul>
<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="kw">class</span><span class="op">...</span> SizeTypes<span class="op">&gt;</span></span>
<span id="cb12-2"><a href="#cb12-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>
<ul>
<li><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>sizeof...(SizeTypes)</code> equals either <code>rank_dynamic()</code> or <code>rank()</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></li>
<li><p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Preconditions:</em> If the following three conditions are true, <code>sizeof...(SizeTypes) == rank()</code> is <code>true</code>, <span class="math inline"><em>r</em></span> is smaller than <code>sizeof...(SizeTypes)</code>, and <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a <em>static extent</em>; then <span class="math inline"><em>E</em><sub><em>r</em></sub></span> equals <code>std::array&lt;size_type,rank()&gt;{exts...}[r]</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.1)</a></span> If <code>sizeof...(sizeTypes)</code> equals <code>dynamic_rank()</code>, initializes <code>dynamic_extents_</code> with <code>{exts...}</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.2)</a></span> If <code>sizeof...(SizeTypes)</code> equals <code>rank()</code>, for all <span class="math inline"><em>d</em></span> in the range <code>[0, rank_dynamic())</code>, initializes <code>dynamic_extents_[d]</code> with <code>std::array&lt;size_type,rank()&gt;{exts...}[dynamic_index_inv(d)]</code>.</p></li>
</ul></li>
</ul>
<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="kw">class</span> SizeType, <span class="dt">size_t</span> N<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>N <span class="op">!=</span> rank_dynamic<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> 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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(8.1)</a></span> <code>is_convertible_v&lt;SizeType, size_type&gt;</code> equals <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(8.2)</a></span> <code>N</code> equals <code>rank_dynamic()</code> or <code>rank()</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">9</a></span> <em>Preconditions:</em> If <code>N</code> equals <code>rank()</code>, <span class="math inline"><em>r</em></span> is smaller than <code>N</code> and <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a <em>static extent</em>, then <span class="math inline"><em>E</em><sub><em>r</em></sub></span> equals <code>exts[r]</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">10</a></span> <em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.1)</a></span> If <code>N</code> equals <code>dynamic_rank()</code>, initializes <code>dynamic_extents_</code> with <code>exts</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.2)</a></span> If <code>N</code> equals <code>rank()</code>, for all <span class="math inline"><em>d</em></span> in the range <code>[0, rank_dynamic())</code>, initializes <code>dynamic_extents_[d]</code> with <code>exts[dynamic_index_inv(d)]</code>.</p></li>
</ul></li>
</ul>
<p><br /> <b>22.7.�.3 Observers of the domain multidimensional index space [mdspan.extents.obs]</b></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">constexpr</span> size_type static_extent<span class="op">(</span><span class="dt">size_t</span> r<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">1</a></span> <em>Preconditions:</em> <code>r &lt; rank()</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Returns:</em> the <span class="math inline"><em>r</em><sup><em>t</em><em>h</em></sup></span> value of <code>Extents</code>.</p></li>
</ul>
<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">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="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Preconditions:</em> <code>r &lt; rank()</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Returns:</em> <code>dynamic_extents_[dynamic_index(r)]</code> if <code>static_extent(r) == dynamic_extent</code> is <code>true</code>, otherwise <code>static_extent(r)</code>.</p></li>
</ul>
<p><br /> <b>22.7.�.4 <code>extents</code> comparison operators [mdspan.extents.compare]</b></p>
<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="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb16-2"><a href="#cb16-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="cb16-3"><a href="#cb16-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>
<ul>
<li><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 all <code>r</code>, otherwise <code>false</code>.</li>
</ul>
<!--
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><b>22.7.�.1 Layout mapping requirements [mdspan.layout.reqs]</b></p>
<ol type="1">
<li><p>A <em>layout mapping policy</em> is a class that contains a <em>layout mapping</em>, which is a nested class template.</p></li>
<li><p>A layout mapping policy and its layout mapping nested class template meet the requirements in Table �.</p></li>
<li><p>A layout mapping meets the requirements of <em>Cpp17CopyConstructible</em>, <em>Cpp17CopyAssignable</em>, and <em>Cpp17EqualityComparable</em>.</p></li>
<li><p>In Table �:</p>
<ul>
<li><code>MP</code> denotes a layout mapping policy.</li>
<li><code>M</code> denotes a specialization of the layout mapping policy’s nested layout mapping template class.</li>
<li><code>E</code> denotes a specialization of <code>extents</code>.</li>
<li><code>e</code> denotes an object of type <code>E</code>.</li>
<li><code>m</code> denotes an object of type <code>M</code>.</li>
<li><code>i...</code> and <code>j...</code> are multidimensional indices in the multidimensional index space defined by <code>e</code>.</li>
<li><code>r</code> is an integral value in the range <code>[0, e.rank())</code>.</li>
<li><code>dr...</code> is an integer pack where <code>sizeof...(dr)</code> equals <code>e.rank()</code>, the <code>r</code>-th element is equal to <code>1</code>, and all other elements are <code>0</code>.</li>
</ul></li>
</ol>
Table � — Layout mapping policy and layout mapping requirements
<table border="1">
<tr>
<th>
Expression
</th>
<th>
Return Type
</th>
<th>
Returns
</th>
<th>
Preconditions
</th>
</tr>
<tr>
<td>
<code>MP::template mapping&lt;E&gt;</code>
</td>
<td>
<code>M</code>
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>M::extents_type</code>
</td>
<td>
<code>E</code>
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>M::layout_type</code>
</td>
<td>
<code>MP</code>
</td>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>is_nothrow_move_constructible_v&lt;M&gt;</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<code>true</code>
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>is_nothrow_move_assignable_v&lt;M&gt;</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<code>true</code>
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>m.extents()</code>
</td>
<td>
<code>E</code>
</td>
<td>
<em>Returns:</em> <code>e</code>.
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>m(i...)</code>
</td>
<td>
<code>E::size_type</code>
</td>
<td>
<em>Returns:</em> A value in the range of <span class="math inline">[0,</span> <code>required_span_size()</code> <span class="math inline">)</span> defined by applying the layout mapping to a multidimensional index <code>i...</code>.
</td>
<td>
<em>Preconditions:</em><br /> <span class="math inline">0 ≤</span> <code>array{i...}[r]</code> <span class="math inline">&lt;</span> <code>extents().extent(r)</code> for all <code>r</code> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>.
</td>
</tr>
<tr>
<td>
<code>m.required_span_size()</code>
</td>
<td>
<code>E::size_type</code>
</td>
<td>
<em>Returns:</em> If the multidimensional index space that <code>e</code> defines is empty, then zero, else 1 plus the maximum value of <code>m(i...)</code> for all <code>i...</code> in <code>e</code>.
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>m.is_unique()</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<em>Returns:</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>.
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>m.is_contiguous()</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<em>Returns:</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>.
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>m.is_strided()</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<em>Returns:</em> <code>true</code> if for every <code>r</code> there exists an integer <code>sr</code> such that, for all <code>j...</code> and <code>i...</code> in <code>e</code>, where <code>j...</code> equals <code>(i+dr)...</code>, <code>m(j...) - m(i...)</code> equals <code>sr</code>. Otherwise, <code>false</code>.
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>M::is_always_unique()</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<em>Returns:</em> <code>true</code> if <code>m.is_unique()</code> is <code>true</code> for all objects of type <code>M</code>.
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>M::is_always_contiguous()</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<em>Returns:</em> <code>true</code> if <code>m.is_contiguous()</code> is <code>true</code> for all objects of type <code>M</code>.
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>M::is_always_strided()</code>
</td>
<td>
<code>bool</code>
</td>
<td>
<em>Returns:</em> true if <code>m.is_strided()</code> is <code>true</code> for all objects of type <code>M</code>.
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>m.stride(r)</code>
</td>
<td>
<code>E::size_type</code>
</td>
<td>
<em>Returns:</em> <code>sr</code> as defined in <code>m.is_strided()</code> above.
</td>
<td>
<em>Preconditions:</em> <code>m.is_strided()</code> is <code>true</code>.
</td>
</tr>
</table>
<!--


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

-->
<p><br /> <b>22.7.�.2 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> meets the requirements of layout mapping policy.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <code>layout_left</code> is a trivially copyable type. <code>layout_left::mapping&lt;Extents&gt;</code> is a trivially copyable type.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</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>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> If <code>Extents</code> is not a (possibly cv-qualified) specialization of <code>extents</code>, then the program is ill-formed.</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">namespace</span> std <span class="op">{</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> layout_left <span class="op">{</span></span>
<span id="cb17-4"><a href="#cb17-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="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> mapping <span class="op">{</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb17-7"><a href="#cb17-7" 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="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> extents_type <span class="op">=</span> Extents;</span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> layout_type <span class="op">=</span> layout_left;</span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-11"><a href="#cb17-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="cb17-12"><a href="#cb17-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="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span>mapping<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> Extents<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb17-15"><a href="#cb17-15" 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="cb17-16"><a href="#cb17-16" 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<span class="op">&gt;)</span></span>
<span id="cb17-17"><a href="#cb17-17" 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="cb17-18"><a href="#cb17-18" 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="cb17-19"><a href="#cb17-19" 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<span class="op">&gt;)</span></span>
<span id="cb17-20"><a href="#cb17-20" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> layout_right<span class="op">::</span><span class="kw">template</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span></span>
<span id="cb17-21"><a href="#cb17-21" aria-hidden="true" tabindex="-1"></a>      <span class="kw">requires</span><span class="op">(</span>rank<span class="op">()</span> <span class="op">&lt;=</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb17-22"><a href="#cb17-22" 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="cb17-23"><a href="#cb17-23" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><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="cb17-24"><a href="#cb17-24" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> layout_stride<span class="op">::</span><span class="kw">template</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;</span> other<span class="op">)</span>;</span>
<span id="cb17-25"><a href="#cb17-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-26"><a href="#cb17-26" 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="cb17-27"><a href="#cb17-27" 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>mapping<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb17-28"><a href="#cb17-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-29"><a href="#cb17-29" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> Extents 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="cb17-30"><a href="#cb17-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-31"><a href="#cb17-31" 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="cb17-32"><a href="#cb17-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-33"><a href="#cb17-33" 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="cb17-34"><a href="#cb17-34" 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="cb17-35"><a href="#cb17-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-36"><a href="#cb17-36" 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="cb17-37"><a href="#cb17-37" 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="cb17-38"><a href="#cb17-38" 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="cb17-39"><a href="#cb17-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-40"><a href="#cb17-40" 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="cb17-41"><a href="#cb17-41" 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="cb17-42"><a href="#cb17-42" 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="cb17-43"><a href="#cb17-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-44"><a href="#cb17-44" 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="cb17-45"><a href="#cb17-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-46"><a href="#cb17-46" 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="cb17-47"><a href="#cb17-47" 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="cb17-48"><a href="#cb17-48" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-49"><a href="#cb17-49" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span><span class="op">:</span></span>
<span id="cb17-50"><a href="#cb17-50" aria-hidden="true" tabindex="-1"></a>    Extents extents_<span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb17-51"><a href="#cb17-51" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb17-52"><a href="#cb17-52" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb17-53"><a href="#cb17-53" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><b>22.7.�.2.1 <code>layout_left::mapping</code> members [mdspan.layout.layout_left]</b></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> mapping<span class="op">(</span><span class="kw">const</span> Extents<span class="op">&amp;</span> e<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">1</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>e</code>.</li>
</ul>
<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="kw">class</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">explicit</span><span class="op">(!</span>std<span class="op">::</span>is_convertible_v<span class="op">&lt;</span>OtherExtents,Extents<span class="op">&gt;)</span></span>
<span id="cb19-3"><a href="#cb19-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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Constraints:</em> <code>is_constructible_v&lt;Extents,OtherExtents&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>other.extents()</code>.</p></li>
</ul>
<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="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb20-2"><a href="#cb20-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<span class="op">&gt;)</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> layout_right<span class="op">::</span><span class="kw">template</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>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">requires</span><span class="op">(</span>rank<span class="op">()</span> <span class="op">&lt;=</span> <span class="dv">1</span><span class="op">)</span>;</span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Constraints:</em> <code>is_constructible_v&lt;Extents,OtherExtents&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>other.extents()</code>.</p></li>
</ul>
<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><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><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="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> layout_stride<span class="op">::</span><span class="kw">template</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;</span> other<span class="op">)</span>;</span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Constraints:</em> <code>is_constructible_v&lt;Extents,OtherExtents&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Preconditions:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.1)</a></span> <code>other.stride(0)</code> equals <code>1</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.2)</a></span> for all <code>r</code> in the range <span class="math inline">[1,</span> <code>rank()</code><span class="math inline">)</span>, <code>other.stride(r)</code> equals the product of <code>extents().extent(k)</code> for all <code>k</code> in the range of <span class="math inline">[0,</span> <code>r</code><span class="math inline">)</span>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>other.extents()</code>.</p></li>
</ul>
<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><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>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">9</a></span> <em>Returns:</em> If <code>Extents::rank() &gt; 0</code> is true, the product of <code>extents().extent(r)</code> for all <code>r</code> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>. Otherwise, 1.</li>
</ul>
<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">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="cb23-2"><a href="#cb23-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>
<ul>
<li><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::rank()</code> is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.1)</a></span> <code>(is_convertible_v&lt;Indices, size_type&gt; &amp;&amp; ...)</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Preconditions:</em> <span class="math inline">0 ≤</span> <code>array{i...}[r]</code> <span class="math inline">&lt;</span> <code>extents().extent(r)</code> for all <code>r</code> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>.</p></li>
<li><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;size_type, sizeof...(Indices)&gt;, integer_sequence&lt;size_type, P...&gt;&gt;</code> is <code>true</code>. <br /> Equivalent to: <code>return Extents::rank() &gt; 0 ? (i*stride(P()) + ...) : 0;</code></p></li>
</ul>
<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">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></code></pre></div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Returns:</em> <code>1</code> if <code>r</code> equals zero, otherwise, the product of <code>extents().extent(k)</code> for all <code>k</code> in the range <span class="math inline">[0,</span> <code>r</code> <span class="math inline">)</span>.</li>
</ul>
<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">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb25-2"><a href="#cb25-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>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">14</a></span> <em>Effects:</em> Equivalent to: <code>return x.extents() == y.extents();</code>.</li>
</ul>
<!--

 #                   #           #      #    #
 #   ## # # ### # # ###     ###     ### ### ###
 #  # # ### # # # #  #      #    #  # # # #  #
 ## ###   # ### ###  ##     #    ##  ## # #  ##
        ###             ###         ###
-->
<p><br /> <b>22.7.�.3 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> meets the requirements of layout mapping policy.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <code>layout_right</code> is a trivially copyable type. <code>layout_right::mapping&lt;Extents&gt;</code> is a trivially copyable type.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</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>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> If <code>Extents</code> is not a (possibly cv-qualified) specialization of <code>extents</code>, then the program is ill-formed.</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><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> layout_right <span class="op">{</span></span>
<span id="cb26-4"><a href="#cb26-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="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> mapping <span class="op">{</span></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb26-7"><a href="#cb26-7" 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="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> extents_type <span class="op">=</span> Extents;</span>
<span id="cb26-9"><a href="#cb26-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> layout_type <span class="op">=</span> layout_right;</span>
<span id="cb26-10"><a href="#cb26-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-11"><a href="#cb26-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="cb26-12"><a href="#cb26-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="cb26-13"><a href="#cb26-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span>mapping<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb26-14"><a href="#cb26-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> Extents<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb26-15"><a href="#cb26-15" 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="cb26-16"><a href="#cb26-16" 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<span class="op">&gt;)</span></span>
<span id="cb26-17"><a href="#cb26-17" 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="cb26-18"><a href="#cb26-18" 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="cb26-19"><a href="#cb26-19" 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<span class="op">&gt;)</span></span>
<span id="cb26-20"><a href="#cb26-20" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> layout_left<span class="op">::</span><span class="kw">template</span> mapping<span class="op">&lt;</span>OtherExtents<span class="op">&gt;&amp;)</span> <span class="kw">noexcept</span></span>
<span id="cb26-21"><a href="#cb26-21" aria-hidden="true" tabindex="-1"></a>      <span class="kw">requires</span><span class="op">(</span>rank<span class="op">()</span> <span class="op">&lt;=</span> <span class="dv">1</span><span class="op">)</span>;</span>
<span id="cb26-22"><a href="#cb26-22" 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="cb26-23"><a href="#cb26-23" aria-hidden="true" tabindex="-1"></a>      <span class="kw">explicit</span><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="cb26-24"><a href="#cb26-24" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> layout_stride<span class="op">::</span><span class="kw">template</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>
<span id="cb26-25"><a href="#cb26-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-26"><a href="#cb26-26" 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="cb26-27"><a href="#cb26-27" 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>mapping<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb26-28"><a href="#cb26-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-29"><a href="#cb26-29" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> Extents 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="cb26-30"><a href="#cb26-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-31"><a href="#cb26-31" 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="cb26-32"><a href="#cb26-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-33"><a href="#cb26-33" 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="cb26-34"><a href="#cb26-34" 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="cb26-35"><a href="#cb26-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-36"><a href="#cb26-36" 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="cb26-37"><a href="#cb26-37" 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="cb26-38"><a href="#cb26-38" 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="cb26-39"><a href="#cb26-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-40"><a href="#cb26-40" 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="cb26-41"><a href="#cb26-41" 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="cb26-42"><a href="#cb26-42" 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="cb26-43"><a href="#cb26-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-44"><a href="#cb26-44" 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="cb26-45"><a href="#cb26-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-46"><a href="#cb26-46" 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="cb26-47"><a href="#cb26-47" 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="cb26-48"><a href="#cb26-48" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-49"><a href="#cb26-49" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span><span class="op">:</span></span>
<span id="cb26-50"><a href="#cb26-50" aria-hidden="true" tabindex="-1"></a>    Extents extents_<span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb26-51"><a href="#cb26-51" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb26-52"><a href="#cb26-52" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb26-53"><a href="#cb26-53" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><b>22.7.�.3.1 <code>layout_right::mapping</code> members [mdspan.layout.layout_right]</b></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><span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> Extents<span class="op">&amp;</span> e<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">1</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>e</code>.</li>
</ul>
<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><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb28-2"><a href="#cb28-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<span class="op">&gt;)</span></span>
<span id="cb28-3"><a href="#cb28-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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Constraints:</em> <code>is_constructible_v&lt;Extents,OtherExtents&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>other.extents()</code>.</p></li>
</ul>
<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><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb29-2"><a href="#cb29-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<span class="op">&gt;)</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> layout_left<span class="op">::</span><span class="kw">template</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>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">requires</span><span class="op">(</span>rank<span class="op">()</span> <span class="op">&lt;=</span> <span class="dv">1</span><span class="op">)</span>;</span></code></pre></div>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Constraints:</em> <code>is_constructible_v&lt;Extents,OtherExtents&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>other.extents()</code>.</p></li>
</ul>
<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><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><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="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> layout_stride<span class="op">::</span><span class="kw">template</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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Constraints:</em> <code>is_constructible_v&lt;Extents,OtherExtents&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Preconditions:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.1)</a></span> <code>other.stride(rank()-1)</code> equals <code>1</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.2)</a></span> for all <code>r</code> in the range <span class="math inline">[0,</span> <code>rank()-2</code><span class="math inline">)</span>, <code>other.stride(r)</code> equals the product of <code>extents().extent(k)</code> for all <code>k</code> in the range of <span class="math inline">[<em>r</em> + 1,</span> <code>rank()</code><span class="math inline">)</span>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>other.extents()</code>.</p></li>
</ul>
<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>size_type required_span_size<span class="op">()</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">9</a></span> <em>Returns:</em> If <code>Extents::rank() &gt; 0</code> is true, the product of <code>extents().extent(r)</code> for all <code>r</code> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>. Otherwise, 1.</li>
</ul>
<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><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="cb32-2"><a href="#cb32-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>
<ul>
<li><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::rank()</code> is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.1)</a></span> <code>(is_convertible_v&lt;Indices, size_type&gt; &amp;&amp; ...)</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Preconditions:</em> <span class="math inline">0 ≤</span> <code>array{i...}[r]</code> <span class="math inline">&lt;</span> <code>extents().extent(r)</code> for all <code>r</code> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Effects:</em> Let <code>P...</code> be the parameter pack such that <code>is_same_v&lt;make_index_sequence&lt;size_type, sizeof...(Indices)&gt;, integer_sequence&lt;size_type, P...&gt;&gt;</code> is <code>true</code>. <br /> Equivalent to: <code>return Extents::rank() &gt; 0 ? (i*stride(P()) + ...) : 0;</code></p></li>
</ul>
<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><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="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">12</a></span> <em>Returns:</em> <code>1</code> if <code>r</code> equals <code>Extents::rank()-1</code>, otherwise, the product of <code>extents().extent(k)</code> for all <code>k</code> in the range <span class="math inline">[</span> <code>r+1</code> <span class="math inline">,</span> <code>Extents::rank()</code> <span class="math inline">)</span>.</li>
</ul>
<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><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb34-2"><a href="#cb34-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>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Effects:</em> Equivalent to: <code>return x.extents() == y.extents();</code>.</li>
</ul>
<!--
layout_stride

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

-->
<p><br /> <b>22.7.�.4 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> meets the requirements of layout mapping policy.</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <code>layout_stride</code> is a trivially copyable type. <code>layout_stride::mapping&lt;Extents&gt;</code> is a trivially copyable type.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> The layout mapping property <code>layout_stride</code> gives a layout mapping where the strides are user defined.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> If <code>Extents</code> is not a (possibly cv-qualified) specialization of <code>extents</code>, then the program is ill-formed.</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><span class="kw">namespace</span> std <span class="op">{</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> layout_stride <span class="op">{</span></span>
<span id="cb35-4"><a href="#cb35-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="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> mapping <span class="op">{</span></span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb35-7"><a href="#cb35-7" 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="cb35-8"><a href="#cb35-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> extents_type <span class="op">=</span> Extents;</span>
<span id="cb35-9"><a href="#cb35-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> layout_type <span class="op">=</span> layout_stride;</span>
<span id="cb35-10"><a href="#cb35-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-11"><a href="#cb35-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="cb35-12"><a href="#cb35-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="cb35-13"><a href="#cb35-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span>mapping<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb35-14"><a href="#cb35-14" 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="cb35-15"><a href="#cb35-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> Extents<span class="op">&amp;</span>,</span>
<span id="cb35-16"><a href="#cb35-16" 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="cb35-17"><a href="#cb35-17" 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="cb35-18"><a href="#cb35-18" 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<span class="op">&gt;)</span></span>
<span id="cb35-19"><a href="#cb35-19" 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="cb35-20"><a href="#cb35-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-21"><a href="#cb35-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutMapping<span class="op">&gt;</span></span>
<span id="cb35-22"><a href="#cb35-22" 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="cb35-23"><a href="#cb35-23" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> LayoutMapping<span class="op">&amp;)</span> <span class="kw">noexcept</span>;</span>
<span id="cb35-24"><a href="#cb35-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-25"><a href="#cb35-25" 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="cb35-26"><a href="#cb35-26" 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>mapping<span class="op">&amp;&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb35-27"><a href="#cb35-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-28"><a href="#cb35-28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> Extents 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="cb35-29"><a href="#cb35-29" 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<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="cb35-30"><a href="#cb35-30" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span> <span class="cf">return</span> strides_; <span class="op">}</span></span>
<span id="cb35-31"><a href="#cb35-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-32"><a href="#cb35-32" 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="cb35-33"><a href="#cb35-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-34"><a href="#cb35-34" 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="cb35-35"><a href="#cb35-35" 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="cb35-36"><a href="#cb35-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-37"><a href="#cb35-37" 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="cb35-38"><a href="#cb35-38" 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="cb35-39"><a href="#cb35-39" 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="cb35-40"><a href="#cb35-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-41"><a href="#cb35-41" 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="cb35-42"><a href="#cb35-42" 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="cb35-43"><a href="#cb35-43" 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="cb35-44"><a href="#cb35-44" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-45"><a href="#cb35-45" 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="cb35-46"><a href="#cb35-46" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-47"><a href="#cb35-47" 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="cb35-48"><a href="#cb35-48" 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="cb35-49"><a href="#cb35-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-50"><a href="#cb35-50" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span><span class="op">:</span></span>
<span id="cb35-51"><a href="#cb35-51" aria-hidden="true" tabindex="-1"></a>    Extents extents_<span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb35-52"><a href="#cb35-52" aria-hidden="true" tabindex="-1"></a>    array<span class="op">&lt;</span>size_type, Extents<span class="op">::</span>rank<span class="op">()&gt;</span> strides_<span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb35-53"><a href="#cb35-53" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb35-54"><a href="#cb35-54" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb35-55"><a href="#cb35-55" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><b>22.7.�.4.1 <code>layout_stride::mapping</code> members [mdspan.layout.layout_stride]</b></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">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="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> Extents<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::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>
<ul>
<li><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;SizeType, 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 == rank()</code> is <code>true</code>.</p></li>
</ul></li>
<li><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::rank()</code> <span class="math inline">)</span>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span> If <code>Extents::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::rank()</code> <span class="math inline">)</span>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>e</code>, and initializes <code>strides_</code> with <code>s</code>.</p></li>
</ul>
<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">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb37-2"><a href="#cb37-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<span class="op">&gt;)</span></span>
<span id="cb37-3"><a href="#cb37-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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Constraints:</em> <code>is_constructible_v&lt;Extents,OtherExtents&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>other.extents()</code>, and initializes <code>strides_</code> with <code>other.strides()</code>.</p></li>
</ul>
<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">template</span><span class="op">&lt;</span><span class="kw">class</span> LayoutMapping<span class="op">&gt;</span></span>
<span id="cb38-2"><a href="#cb38-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="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> LayoutMapping<span class="op">&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><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>LayoutMapping::layout_type</code> meets the layout mapping policy requirements.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.2)</a></span> <code>std::is_same_v&lt;LayoutMapping, LayoutMapping::layout_type::mapping&lt;LayoutMapping::extents_type&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.3)</a></span> <code>is_constructible_v&lt;Extents, LayoutMapping::extents_type&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.4)</a></span> <code>other.is_always_unique()</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(7.5)</a></span> <code>other.is_always_strided()</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Effects:</em> Initializes <code>extents_</code> with <code>other.extents()</code>, and initializes <code>strides_</code> such that <code>strides_[r] == other.stride(r)</code> is true for all <span class="math inline"><em>r</em></span> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">9</a></span> <em>Remarks:</em> The expression inside <code>explicit</code> is equivalent to: <code>!std::is_convertible_v&lt;typename LayoutMapping::extents_type,Extents&gt;</code>.</p></li>
</ul>
<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">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>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Returns:</em> If <code>(Extents::rank() &gt; 0)</code> is true and <code>(extents().extent(r) &gt; 0)</code> is true for all <code>r</code> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>, the maximum of <code>extents().extent(r) * stride(r)</code> for all <code>r</code> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>. Otherwise, <code>Extents::rank() == 0 ? 1 : 0</code>.</li>
</ul>
<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><span class="op">...</span> Indices<span class="op">&gt;</span></span>
<span id="cb40-2"><a href="#cb40-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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">12</a></span> <em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(12.1)</a></span> <code>sizeof...(Indices) == Extents::rank()</code> is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(12.1)</a></span> <code>(is_convertible_v&lt;Indices, size_type&gt; &amp;&amp; ...)</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Preconditions:</em> <span class="math inline">0 ≤</span> <code>array{i...}[r]</code> <span class="math inline">&lt;</span> <code>extents().extent(r)</code> for all <code>r</code> in the range <span class="math inline">[0,</span> <code>Extents::rank()</code> <span class="math inline">)</span>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">14</a></span> <em>Effects:</em> Let <code>P...</code> be the parameter pack such that <code>is_same_v&lt;make_index_sequence&lt;size_type, sizeof...(Indices)&gt;, integer_sequence&lt;size_type, P...&gt;&gt;</code> is <code>true</code>. <br /> Equivalent to: <code>return Extents::rank() &gt; 0 ? (i*stride(P()) + ...) : 0;</code></p></li>
</ul>
<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">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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">15</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::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></li>
<li><p><span class="marginalizedparent"><a class="marginalized">16</a></span><em>Returns:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(16.1)</a></span> <code>true</code> if <code>Extents::ranks()</code> is zero.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(16.2)</a></span> Otherwise, <code>true</code> if there is a permutation <span class="math inline"><em>P</em></span> such that <code>min(stride(</code> <span class="math inline"><em>p</em><sub>0</sub></span> <code>))</code> equals one, 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::rank()</code> <span class="math inline">)</span>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(16.3)</a></span> Otherwise, <code>false</code>.</p></li>
</ul></li>
</ul>
<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">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb42-2"><a href="#cb42-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>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">17</a></span> <em>Effects:</em> Equivalent to: <code>return x.extents() == y.extents();</code>.</li>
</ul>
<!--


 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>
<p><b>22.7.�.1 Accessor policy requirements [mdspan.accessor.reqs]</b></p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> An accessor policy defines:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.1)</a></span> <code>pointer</code>, the type of a handle to a set of objects accessible from a subset of a contiguous range of integer indices;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.2)</a></span> <code>reference</code>, the type of a handle to a single element of type <code>element_type</code>;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.3)</a></span> <code>access</code>, a method to access the <code>i</code>-th element in the range of elements represented by a <code>pointer</code>;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.4)</a></span> <code>offset</code>, 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</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.5)</a></span> <code>offset_policy</code>, the type of a <i>[Note:</i> possibly different <i>— end note]</i> accessor policy for accessing the result of <code>offset</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <i>[Note:</i> The type of <code>reference</code> need not be <code>element_type&amp;</code>. The type of <code>pointer</code> need not be <code>element_type*</code>. <i>— end note]</i></p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> In Table �:</p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.1)</a></span> <code>A</code> denotes an accessor policy.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.2)</a></span> <code>a</code> denotes an object of type <code>A</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.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">(5.4)</a></span> <code>i</code> and <code>j</code> each denote a <code>size_t</code> value.</p></li>
</ul>
Table �: Accessor policy requirements
<table border="1">
<tr>
<th>
Expression
</th>
<th>
Return Type
</th>
<th>
Requirements
</th>
</tr>
<tr>
<td>
<code>A</code>
</td>
<td>
</td>
<td>
<code>A</code> meets the requirements of <em>Cpp17CopyConstructible</em> and <em>Cpp17CopyAssignable</em>. <code>is_nothrow_move_constructible_v&lt;A&gt;</code> is <code>true</code> and <code>is_nothrow_move_assignable_v&lt;A&gt;</code> is <code>true</code>.
</td>
</tr>
<tr>
<td>
<code>A::element_type</code>
</td>
<td>
</td>
<td>
<code>A::element_type</code> is required to be a complete object type that is not an abstract class type.
</td>
</tr>
<tr>
<td>
<code>A::pointer</code>
</td>
<td>
</td>
<td>
<code>A::pointer</code> 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>.
</td>
</tr>
<tr>
<td>
<code>A::reference</code>
</td>
<td>
</td>
<td>
<em>Constraints:</em> <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,A::reference&gt;</code> is <code>true</code>.
</td>
</tr>
<tr>
<td>
<code>A::offset_policy</code>
</td>
<td>
</td>
<td>
Accessor policy for accessing a pointer returned by <code>a.offset(p,i)</code>. <br /> <br /> <em>Constraints:</em> <br /> — <code>A::offset_policy</code> meets the requirements of an accessor policy in Table �, <br /> — <code>is_convertible_v&lt;A, A::offset_policy&gt;</code> is <code>true</code>, and <br /> — <code>A::offset_policy</code> can be constructed from <code>a</code>.
</td>
</tr>
<tr>
<td>
<code>a.access(p, i)</code>
</td>
<td>
<code>A::reference</code>
</td>
<td>
<em>Returns:</em> An object which provides access to the <code>i</code>-th element in the range of elements that starts at <code>p</code>.
</td>
</tr>
<tr>
<td>
<code>a.offset(p, i)</code>
</td>
<td>
<code>A::offset_policy::pointer</code>
</td>
<td>
<em>Returns:</em> A handle to the range of objects which that starts at the <code>i</code>-th element of the objects <code>p</code> is a handle for.
</td>
</tr>
</table>
<!--

                                    #            #
 ## ### ### ###  ##  ## ### ###     ###  ##  ##     ###
# # #   #   ##   #   #  # # #       # # # #  #   #  #
### ### ### ### ##  ##  ### #       ### ### ##   ## ###
                                ###
-->
<p><b>22.7.�.2 Class template <code>default_accessor</code> [mdspan.accessor.default]</b></p>
<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>
<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">namespace</span> std <span class="op">{</span></span>
<span id="cb43-2"><a href="#cb43-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="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">struct</span> default_accessor <span class="op">{</span></span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> offset_policy <span class="op">=</span> default_accessor;</span>
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> element_type <span class="op">=</span> ElementType;</span>
<span id="cb43-6"><a href="#cb43-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="cb43-7"><a href="#cb43-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="cb43-8"><a href="#cb43-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-9"><a href="#cb43-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="cb43-10"><a href="#cb43-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-11"><a href="#cb43-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="cb43-12"><a href="#cb43-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="cb43-13"><a href="#cb43-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-14"><a href="#cb43-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="cb43-15"><a href="#cb43-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="cb43-16"><a href="#cb43-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-17"><a href="#cb43-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="cb43-18"><a href="#cb43-18" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span>;</span>
<span id="cb43-19"><a href="#cb43-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><b>22.7.�.2 Class template <code>default_accessor</code> members [mdspan.accessor.members]</b></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">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherElementType<span class="op">&gt;</span></span>
<span id="cb44-2"><a href="#cb44-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>
<ul>
<li><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></li>
</ul>
<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">constexpr</span> <span class="kw">typename</span> offset_policy<span class="op">::</span>pointer</span>
<span id="cb45-2"><a href="#cb45-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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Preconditions:</em> <code>p + i</code> is dereferenceable.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Returns:</em> <code>p + i</code>.</p></li>
</ul>
<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">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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Preconditions:</em> <code>p + i</code> is dereferenceable.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Returns:</em> <code>p[i]</code>.</p></li>
</ul>
<!--
                   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>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> As with <code>span</code>, the storage of the objects in the codomain of an <code>mdspan</code> is owned by some other object.</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">namespace</span> std <span class="op">{</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-3"><a href="#cb47-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="cb47-4"><a href="#cb47-4" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> mdspan <span class="op">{</span></span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb47-6"><a href="#cb47-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-7"><a href="#cb47-7" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Domain and codomain types</span></span>
<span id="cb47-8"><a href="#cb47-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> extents_type <span class="op">=</span> Extents;</span>
<span id="cb47-9"><a href="#cb47-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> layout_type <span class="op">=</span> LayoutPolicy;</span>
<span id="cb47-10"><a href="#cb47-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> accessor_type <span class="op">=</span> AccessorPolicy;</span>
<span id="cb47-11"><a href="#cb47-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_type<span class="op">&lt;</span>extents_type<span class="op">&gt;</span>;</span>
<span id="cb47-12"><a href="#cb47-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> element_type <span class="op">=</span> ElementType;</span>
<span id="cb47-13"><a href="#cb47-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="cb47-14"><a href="#cb47-14" 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="cb47-15"><a href="#cb47-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> difference_type <span class="op">=</span> <span class="dt">ptrdiff_t</span>;</span>
<span id="cb47-16"><a href="#cb47-16" 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="cb47-17"><a href="#cb47-17" 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="cb47-18"><a href="#cb47-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-19"><a href="#cb47-19" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.mdspan.cons], mdspan constructors, assignment, and destructor</span></span>
<span id="cb47-20"><a href="#cb47-20" 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="cb47-21"><a href="#cb47-21" 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="cb47-22"><a href="#cb47-22" 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="cb47-23"><a href="#cb47-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-24"><a href="#cb47-24" 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="cb47-25"><a href="#cb47-25" 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="cb47-26"><a href="#cb47-26" 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="cb47-27"><a href="#cb47-27" 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="cb47-28"><a href="#cb47-28" 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="cb47-29"><a href="#cb47-29" 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="cb47-30"><a href="#cb47-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="op">)</span>;</span>
<span id="cb47-31"><a href="#cb47-31" 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="cb47-32"><a href="#cb47-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-33"><a href="#cb47-33" 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="cb47-34"><a href="#cb47-34" 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="cb47-35"><a href="#cb47-35" 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="cb47-36"><a href="#cb47-36" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mdspan<span class="op">(</span></span>
<span id="cb47-37"><a href="#cb47-37" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> mdspan<span class="op">&lt;</span>OtherElementType, OtherExtents, </span>
<span id="cb47-38"><a href="#cb47-38" aria-hidden="true" tabindex="-1"></a>                   OtherLayoutPolicy, OtherAccessorPolicy<span class="op">&gt;&amp;</span> other<span class="op">)</span>;</span>
<span id="cb47-39"><a href="#cb47-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-40"><a href="#cb47-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><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="cb47-41"><a href="#cb47-41" 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="cb47-42"><a href="#cb47-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-43"><a href="#cb47-43" 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="cb47-44"><a href="#cb47-44" 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="cb47-45"><a href="#cb47-45" 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="cb47-46"><a href="#cb47-46" 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="cb47-47"><a href="#cb47-47" 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="cb47-48"><a href="#cb47-48" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-49"><a href="#cb47-49" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> accessor_type accessor<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> acc_; <span class="op">}</span></span>
<span id="cb47-50"><a href="#cb47-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-51"><a href="#cb47-51" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">int</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="cb47-52"><a href="#cb47-52" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">int</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="cb47-53"><a href="#cb47-53" 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="cb47-54"><a href="#cb47-54" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-55"><a href="#cb47-55" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> Extents extents<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> map_<span class="op">.</span>extents<span class="op">()</span>; <span class="op">}</span></span>
<span id="cb47-56"><a href="#cb47-56" 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="cb47-57"><a href="#cb47-57" 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="cb47-58"><a href="#cb47-58" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-59"><a href="#cb47-59" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.basic.codomain], mdspan observers of the codomain</span></span>
<span id="cb47-60"><a href="#cb47-60" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> pointer data<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> ptr_; <span class="op">}</span></span>
<span id="cb47-61"><a href="#cb47-61" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> mapping_type mapping<span class="op">()</span> <span class="kw">const</span> <span class="op">{</span> <span class="cf">return</span> map_; <span class="op">}</span></span>
<span id="cb47-62"><a href="#cb47-62" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-63"><a href="#cb47-63" 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="cb47-64"><a href="#cb47-64" 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="cb47-65"><a href="#cb47-65" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb47-66"><a href="#cb47-66" 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="cb47-67"><a href="#cb47-67" 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="cb47-68"><a href="#cb47-68" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb47-69"><a href="#cb47-69" 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="cb47-70"><a href="#cb47-70" 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="cb47-71"><a href="#cb47-71" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb47-72"><a href="#cb47-72" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-73"><a href="#cb47-73" 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="cb47-74"><a href="#cb47-74" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> map_<span class="op">.</span>is_unique<span class="op">()</span>;</span>
<span id="cb47-75"><a href="#cb47-75" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb47-76"><a href="#cb47-76" 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="cb47-77"><a href="#cb47-77" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> map_<span class="op">.</span>is_contiguous<span class="op">()</span>;</span>
<span id="cb47-78"><a href="#cb47-78" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb47-79"><a href="#cb47-79" 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="cb47-80"><a href="#cb47-80" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> map_<span class="op">.</span>is_strided<span class="op">()</span>;</span>
<span id="cb47-81"><a href="#cb47-81" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb47-82"><a href="#cb47-82" 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="cb47-83"><a href="#cb47-83" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> map_<span class="op">.</span>stride<span class="op">(</span>r<span class="op">)</span>;</span>
<span id="cb47-84"><a href="#cb47-84" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb47-85"><a href="#cb47-85" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-86"><a href="#cb47-86" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span><span class="op">:</span></span>
<span id="cb47-87"><a href="#cb47-87" aria-hidden="true" tabindex="-1"></a>  accessor_type acc_; <span class="co">// <em>exposition only</em></span></span>
<span id="cb47-88"><a href="#cb47-88" aria-hidden="true" tabindex="-1"></a>  mapping_type map_; <span class="co">// <em>exposition only</em></span></span>
<span id="cb47-89"><a href="#cb47-89" aria-hidden="true" tabindex="-1"></a>  pointer ptr_<span class="op">{}</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb47-90"><a href="#cb47-90" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb47-91"><a href="#cb47-91" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-92"><a href="#cb47-92" 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. <code>mdspan&lt;ElementType, Extents, LayoutPolicy, AccessorPolicy&gt;</code> is a default constructible type if <code>AccessorPolicy</code> and <code>LayoutPolicy::mapping_type&lt;Extents&gt;</code> are default constructible 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 (cv-unqualified) 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 the program is ill-formed.</p>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span> If <code>AccessorPolicy</code> does not meet the accessor policy requirements or 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="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><span class="op">...</span> SizeTypes<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="kw">constexpr</span> mdspan<span class="op">(</span>pointer ptr, SizeTypes<span class="op">...</span> exts<span class="op">)</span>;</span></code></pre></div>
<ul>
<li><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, 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></li>
<li><p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.1)</a></span> Initializes <code>ptr_</code> with <code>ptr</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.2)</a></span> Initializes <code>map_</code> with <code>Extents(exts...)</code>.</p></li>
</ul></li>
</ul>
<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> SizeType, <span class="dt">size_t</span> N<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>N <span class="op">!=</span> rank_dynamic<span class="op">())</span></span>
<span id="cb49-3"><a href="#cb49-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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.1)</a></span> <code>is_convertible_v&lt;SizeType, size_type&gt;</code> is <code>true</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.2)</a></span> <code>is_constructible_v&lt;Extents, array&lt;SizeType, N&gt;&gt;</code> is <code>true</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(3.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">(3.4)</a></span> <code>is_default_constructible_v&lt;accessor_type&gt;</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Effects:</em> Equivalent to: <code>mdspan(p, exts[Rs]...)</code>, with <code>Rs...</code> from <code>index_sequence&lt;Rs...&gt;</code> matching <code>make_index_sequence&lt;N&gt;</code>.</p></li>
</ul>
<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">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></code></pre></div>
<ul>
<li><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;mapping_type, Extents&gt;</code> is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(5.2)</a></span> <code>is_default_constructible_v&lt;accessor_type&gt;</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Effects:</em> Equivalent to: <code>mdspan(p, mapping_type(ext))</code>.</p></li>
</ul>
<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><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>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Constraints:</em> <code>is_default_constructible_v&lt;accessor_type&gt;</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(8.1)</a></span> Initializes <code>ptr_</code> with <code>p</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(8.2)</a></span> Initializes <code>map_</code> with <code>m</code>.</p></li>
</ul></li>
</ul>
<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">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>
<ul>
<li><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> Initializes <code>ptr_</code> with <code>p</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.2)</a></span> Initializes <code>map_</code> with <code>m</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(9.3)</a></span> Initializes <code>acc_</code> with <code>a</code>.</p></li>
</ul></li>
</ul>
<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">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherElementType, <span class="kw">class</span> OtherExtents,</span>
<span id="cb53-2"><a href="#cb53-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="cb53-3"><a href="#cb53-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="cb53-4"><a href="#cb53-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="cb53-5"><a href="#cb53-5" aria-hidden="true" tabindex="-1"></a>                                OtherLayoutPolicy, OtherAccessor<span class="op">&gt;&amp;</span> other<span class="op">)</span>;</span></code></pre></div>
<ul>
<li><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>is_constructible_v&lt;mapping_type, OtherLayoutPolicy::template mapping&lt;OtherExtents&gt;</code> is <code>true</code>;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.2)</a></span> <code>is_constructible_v&lt;Accessor, OtherAccessor&gt;</code> is <code>true</code>;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.3)</a></span> <code>is_constructible_v&lt;pointer, OtherAccessor::pointer&gt;</code> is <code>true</code>;</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.4)</a></span> <code>OtherExtents::rank() == rank()</code> is <code>true</code>; and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(10.5)</a></span> For all <code>r</code> in the range <code>[0, rank())</code>, if <code>other.static_extent(r) != dynamic_extent &amp;&amp; static_extent(r) != dynamic_extent</code> is <code>true</code>, then <code>other.static_extent(r) == static_extent(r)</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Preconditions:</em> For all <code>r</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">12</a></span> <em>Effects:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(12.1)</a></span> Initializes <code>ptr_</code> with <code>other.ptr_</code>,</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(12.2)</a></span> initializes <code>map_</code> with <code>other.map_</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(12.3)</a></span> initializes <code>acc_</code> with <code>other.acc_</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Remarks:</em> The expression inside <code>explicit</code> is equivalent to: <code>!std::is_convertible_v&lt;typename OtherLayoutPolicy::mapping_type, mapping_type&gt; ||               !std::is_convertible_v&lt;OtherAccessorPolicy, AccessorPolicy&gt; ||               !std::is_convertible_v&lt;typename OtherAccessorPolicy::pointer, pointer&gt;</code></p></li>
</ul>
<!--

  #              #                           #
### ### ###  ##     ##      ###  ## ### ###     ##  ###
# # # # ### # #  #  # #     ### # # # # # #  #  # # # #
### ### # # ###  ## # #     # # ### ### ###  ## # #  ##
                                    #   #           ###
-->
<p><br /> <b>22.7.�.2 <code>mdspan</code> members [mdspan.mdspan.members]</b></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><span class="op">...</span> SizeTypes<span class="op">&gt;</span></span>
<span id="cb54-2"><a href="#cb54-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>
<ul>
<li><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>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span> <code>sizeof...(SizeTypes) == rank()</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Preconditions:</em> <code>acc_.access(ptr_, map_(indices...))</code> shall be valid.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects:</em> Equivalent to: <code>return acc_.access(ptr_, map_(indices...));</code>.</p></li>
</ul>
<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">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-2"><a href="#cb55-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>
<ul>
<li><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;SizeType, size_type&gt;</code> is <code>true</code>, and</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(4.2)</a></span> <code>rank() == N</code> is <code>true</code>.</p></li>
</ul></li>
<li><p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Effects:</em> Equivalent to: <code>return apply(*this, indices);</code>.</p></li>
</ul>
<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">constexpr</span> size_type size<span class="op">()</span> <span class="kw">const</span>;</span></code></pre></div>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Returns:</em> Product of <code>extent(r)</code> for all <code>r</code> in the range <code>[0, Extents::rank())</code>.</li>
</ul>
<!--
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="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">namespace</span> std <span class="op">{</span></span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb57-3"><a href="#cb57-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">// [mdspan.submdspan], submdspan creation</span></span>
<span id="cb57-4"><a href="#cb57-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="cb57-5"><a href="#cb57-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="cb57-6"><a href="#cb57-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">constexpr</span> mdspan<span class="op">&lt;</span>ElementType, <em>see below</em>, <em>see below</em>, </span>
<span id="cb57-7"><a href="#cb57-7" aria-hidden="true" tabindex="-1"></a>                       <span class="kw">typename</span> AccessorPolicy<span class="op">::</span>offset_policy<span class="op">&gt;</span></span>
<span id="cb57-8"><a href="#cb57-8" aria-hidden="true" tabindex="-1"></a>      submdspan<span class="op">(</span><span class="kw">const</span> mdspan<span class="op">&lt;</span>ElementType, Extents, LayoutPolicy,</span>
<span id="cb57-9"><a href="#cb57-9" aria-hidden="true" tabindex="-1"></a>                             AccessorPolicy<span class="op">&gt;&amp;</span> src, SliceSpecifiers<span class="op">...</span> slices<span class="op">)</span>;</span>
<span id="cb57-10"><a href="#cb57-10" 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> Define <code>map_rank</code> as an <code>array&lt;size_t,src.rank()&gt;</code> such that for all <code>j</code> in the range <code>[0, src.rank())</code> <code>map_rank[j]</code> equals <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 <code>map_rank[j]</code> equals 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>,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>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> Let <code>first</code> and <code>last</code> be exposition-only variables of type <code>array&lt;size_t,src.rank()&gt;</code>. For <span class="math inline"><em>r</em></span> in the range <span class="math inline">[0,</span> <code>src.rank()</code><span class="math inline">)</span>, define the values of <code>first[r]</code> and <code>last[r]</code> as follows:</p>
<ul>
<li>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>, then <code>first[r]</code> equals <span class="math inline"><em>s</em><sub><em>r</em></sub></span>, and <code>last[r]</code> equals <code>first[r]</code> + 1;</li>
<li>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>, then <code>first[r]</code> equals <code>get&lt;0&gt;(t)</code>, and <code>last[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>;</li>
<li>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>, then <code>first[r]</code> equals <code>0</code>, and <code>last[r]</code> equals <code>src.extent(r)</code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Constraints:</em></p>
<ul>
<li><code>sizeof(slices...)</code> equals <code>src.rank()</code>,</li>
<li><code>LayoutPolicy</code> is <code>layout_left</code>, <code>layout_right</code>, <code>layout_stride</code>, or any type in a possibly empty set of implementation-defined types, each of which meets the requirements of a layout mapping policy <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>; and</li>
<li>For all <code>k</code> in the range <code>[0, src.rank())</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>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Preconditions:</em></p>
<ul>
<li>For <span class="math inline">0 ≤</span> <code>r</code> &lt; <code>src.rank()</code>, <code>0 &lt;= first[r] &amp;&amp; first[r] &lt;= last[r] &amp;&amp; last[r] &lt;= src.extent(r)</code> is <code>true</code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Ensures:</em> All of the following:</p>
<ul>
<li><code>sub.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>.</li>
<li>Let the pack <code>i...</code> denote a multidimensional index in the domain of <code>src</code> with <span class="math inline"><em>i</em><sub><em>k</em></sub></span> denoting the <span class="math inline"><em>k</em></span>-th element of <code>i...</code>, such that <span class="math inline"><em>i</em><sub><em>k</em></sub></span> is greater than or equal to <code>first[k]</code> and <span class="math inline"><em>i</em><sub><em>k</em></sub></span> is less than <code>last[k]</code> for all <code>k</code> in the range <span class="math inline">[0,</span><code>src.rank()</code><span class="math inline">)</span>. Let the pack <code>j...</code> denote a multidimensional index in the domain of <code>sub</code> with <span class="math inline"><em>j</em><sub><em>s</em></sub></span> denoting the <span class="math inline"><em>s</em></span>-th element of <code>j...</code>, such that <span class="math inline"><em>j</em><sub><em>s</em></sub></span> is equal to <span class="math inline"><em>i</em><sub><em>k</em></sub></span> minus <code>first[k]</code> where <code>map_rank[k]</code> equals <code>s</code> for all <code>s</code> in the range <span class="math inline">[0,</span><code>sub.rank()</code><span class="math inline">)</span>. Then <code>sub(j...)</code> and <code>src(i...)</code> refer to the same element in the codomain of <code>src</code>.</li>
<li>For <span class="math inline">0 ≤</span> <code>k</code> &lt; <code>src.rank()</code>, if <code>map_rank[k] != dynamic_extent</code> is <code>true</code>, then <code>sub.extent(map_rank[k])</code> equals <code>last[k] - first[k]</code>.</li>
<li>If <code>src.is_strided()</code> is <code>true</code>, then <code>sub.is_strided()</code> is <code>true</code>, and for all <code>k</code> in the range <code>[0, src.rank())</code>, if <code>map_rank[k] != dynamic_extent</code> is <code>true</code>, then <code>sub.stride(map_rank[k])</code> equals <code>src.stride(k)</code>.</li>
<li>For all <code>k</code> in the range <code>[0, src.rank())</code>, if <code>map_rank[k] != dynamic_extent</code> is <code>true</code> and <code>src.static_extent(k)</code> does not equal <code>dynamic_extent</code> and <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>, then <code>sub.static_extent(map_rank[k])</code> equals <code>src.static_extent(k)</code>.</li>
<li>If <code>LayoutPolicy</code> is <code>layout_left</code> and <code>sub.rank() &gt; 0</code> is <code>true</code>, then:
<ul>
<li>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> for all <code>k</code> in the range <span class="math inline">[0,</span><code>sub.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>sub.rank()-1</code>, then <code>decltype(sub)::layout_type</code> is <code>layout_left</code>, otherwise</li>
<li><code>decltype(sub)::layout_type</code> is <code>layout_stride</code>.</li>
</ul></li>
<li>If <code>LayoutPolicy</code> is <code>layout_left</code> and <code>sub.rank()</code> is <code>0</code>, then <code>decltype(sub)::layout_type</code> is <code>layout_left</code>.</li>
<li>If <code>LayoutPolicy</code> is <code>layout_right</code> and <code>sub.rank() &gt; 0</code> is <code>true</code>, then:
<ul>
<li>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> for all <code>k</code> in the range <span class="math inline">[</span><code>src.rank()-sub.rank()+1</code><span class="math inline">,</span><code>src.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>src.rank()-sub.rank()</code>, then <code>decltype(sub)::layout_type</code> is <code>layout_right</code>, else</li>
<li><code>decltype(sub)::layout_type</code> is <code>layout_stride</code>.</li>
</ul></li>
<li>If <code>LayoutPolicy</code> is <code>layout_right</code> and <code>sub.rank()</code> is <code>0</code>, then <code>decltype(sub)::layout_type</code> is <code>layout_right</code>.</li>
<li>If <code>LayoutPolicy</code> is <code>layout_stride</code>, then <code>decltype(sub)::layout_type</code> is <code>layout_stride</code>.</li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span> <em>Effects:</em></p>
<ul>
<li>Initializes <code>sub.acc_</code> with <code>src.accessor()</code>.</li>
<li>Initializes <code>sub.ptr_</code> with <code>src.accessor().offset(src.data(),apply(src.mapping(),first))</code>.</li>
<li>Initializes <code>sub.map_</code> in a way that above conditions are satisfied.</li>
</ul>
<p><br /></p>
<p><em>[Note:* Example of <code>submdspan</code> use:]</em></p>
<h1 data-number="5" id="next-steps"><span class="header-section-number">5</span> Next Steps<a href="#next-steps" class="self-link"></a></h1>
<p>We would like LEWG to poll on sending P0009 (‘mdspan’) to LWG for C++23.</p>
<h1 data-number="6" id="implementation"><span class="header-section-number">6</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="7" id="related-work"><span class="header-section-number">7</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>
