<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2022-03-15" />
  <title>Make mdspan size_type controllable</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>Make mdspan size_type controllable</code></h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>P2553R1</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2022-03-15</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>
      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>
    </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="#r1"><span class="toc-section-number">1.1</span>
R1<span></span></a></li>
<li><a href="#initial-version-2022-02-mailing"><span class="toc-section-number">1.2</span> Initial Version 2022-02
Mailing<span></span></a>
<ul>
<li><a href="#review-in-lewg-2022-03-01"><span class="toc-section-number">1.2.1</span> Review in LEWG
2022-03-01<span></span></a></li>
</ul></li>
</ul></li>
<li><a href="#description"><span class="toc-section-number">2</span>
Description<span></span></a>
<ul>
<li><a href="#example"><span class="toc-section-number">2.1</span>
Example<span></span></a></li>
<li><a href="#possible-ways-to-address-the-issue"><span class="toc-section-number">2.2</span> Possible Ways To Address The
Issue<span></span></a>
<ul>
<li><a href="#mappings-doing-offset-calculation-with-argument-type"><span class="toc-section-number">2.2.1</span> Mappings Doing Offset
Calculation With Argument Type<span></span></a></li>
<li><a href="#template-extents-on-size_type"><span class="toc-section-number">2.2.2</span> Template <code>extents</code> on
<code>size_type</code><span></span></a></li>
<li><a href="#second-extents-type-templated-on-size_type"><span class="toc-section-number">2.2.3</span> Second Extents Type Templated on
<code>size_type</code><span></span></a></li>
<li><a href="#template-layoutpolicy-on-size_type"><span class="toc-section-number">2.2.4</span> Template LayoutPolicy on
<code>size_type</code><span></span></a></li>
<li><a href="#what-we-prefer"><span class="toc-section-number">2.2.5</span> What we
prefer:<span></span></a></li>
</ul></li>
<li><a href="#why-we-cant-fix-this-later"><span class="toc-section-number">2.3</span> Why we can’t fix this
later<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>
<ul>
<li><a href="#in-22.7.x-mdspan.syn"><span class="toc-section-number">4.1</span> In 22.7.X
[mdspan.syn]<span></span></a></li>
<li><a href="#in-22.7.x.1-mdspan.extents.overview"><span class="toc-section-number">4.2</span> In 22.7.X.1
[mdspan.extents.overview]:<span></span></a></li>
<li><a href="#in-22.7.x.2-mdspan.extents.helpers"><span class="toc-section-number">4.3</span> In 22.7.X.2
[mdspan.extents.helpers]:<span></span></a></li>
<li><a href="#in-subsection-22.7.x.3-mdspan.extents.cons"><span class="toc-section-number">4.4</span> In subsection 22.7.X.3
[mdspan.extents.cons]<span></span></a></li>
<li><a href="#in-subsection-22.7.x.4-mdspan.extents.obs"><span class="toc-section-number">4.5</span> In subsection 22.7.X.4
[mdspan.extents.obs]<span></span></a></li>
<li><a href="#in-subsection-22.7.x.5-mdspan.extents.compare"><span class="toc-section-number">4.6</span> In subsection 22.7.X.5
[mdspan.extents.compare]<span></span></a></li>
<li><a href="#in-subsection-22.7.x.6-mdspan.extents.dextents"><span class="toc-section-number">4.7</span> In subsection 22.7.X.6
[mdspan.extents.dextents]<span></span></a></li>
<li><a href="#in-subsection-22.7.x.3.1-mdspan.layout.left.ctors"><span class="toc-section-number">4.8</span> In subsection 22.7.X.3.1
[mdspan.layout.left.ctors]<span></span></a></li>
<li><a href="#in-subsection-22.7.x.4.1-mdspna.layout.right.ctors"><span class="toc-section-number">4.9</span> In subsection 22.7.X.4.1
[mdspna.layout.right.ctors]<span></span></a></li>
<li><a href="#in-subsection-22.7.x.5.2-mdspan.layout.stride.cotrs"><span class="toc-section-number">4.10</span> In Subsection 22.7.X.5.2
[mdspan.layout.stride.cotrs]<span></span></a></li>
<li><a href="#in-subsection-22.7.x.1-mdspan.mdspan.overview"><span class="toc-section-number">4.11</span> In subsection 22.7.X.1
[mdspan.mdspan.overview]<span></span></a></li>
<li><a href="#in-subsection-22.7.x.1-mdspan.mdspan.ctors"><span class="toc-section-number">4.12</span> In subsection 22.7.X.1
[mdspan.mdspan.ctors]<span></span></a></li>
<li><a href="#in-subsection-22.7.x-mdspan.submdspan"><span class="toc-section-number">4.13</span> In Subsection 22.7.X
[mdspan.submdspan]<span></span></a></li>
</ul></li>
<li><a href="#implementation"><span class="toc-section-number">5</span>
Implementation<span></span></a></li>
<li><a href="#related-work"><span class="toc-section-number">6</span>
Related Work<span></span></a></li>
</ul>
</div>
<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="r1"><span class="header-section-number">1.1</span> R1<a href="#r1" class="self-link"></a></h2>
<ul>
<li>don’t constrain the index-type via <code>unsigned_integral</code>
concept</li>
<li>add preconditions to <code>extents</code> constructor to account for
signed types</li>
<li>make extents conversion construction explicit when narrowing
<code>size_type</code></li>
</ul>
<h2 data-number="1.2" id="initial-version-2022-02-mailing"><span class="header-section-number">1.2</span> Initial Version 2022-02
Mailing<a href="#initial-version-2022-02-mailing" class="self-link"></a></h2>
<h3 data-number="1.2.1" id="review-in-lewg-2022-03-01"><span class="header-section-number">1.2.1</span> Review in LEWG 2022-03-01<a href="#review-in-lewg-2022-03-01" class="self-link"></a></h3>
<ul>
<li>don’t constrain the index-type via
<code>unsigned_integral</code></li>
<li>allow signed integers as <code>size_type</code> for
<code>extents</code></li>
</ul>
<h1 data-number="2" id="description"><span class="header-section-number">2</span> Description<a href="#description" class="self-link"></a></h1>
<p>P0009 explicitly sets the <code>size_type</code> of
<code>extents</code> to <code>size_t</code>, which is then used by
<em>layout mappings</em> and <code>mdspan</code>. While this matches
<code>span</code> whose <code>extent</code> function returns
<code>size_t</code>, this behavior has significant performance impact on
various architectures where 64-bit integer throughput is significantly
lower than 32-bit integer computation throughput.</p>
<p>While that problem is present for <code>span</code> it is a much
bigger issue for <code>mdspan</code>, since every data access into a
multi-dimensional array is accompanied by an offset calculation which
typically costs two integer operations per dimension.</p>
<p>On current GPUs, which are an essential hardware component in
machines used for high performance computing, machine learning and
graphics (arguably the core constituency for <code>mdspan</code>), the
ratio between 32-bit and 64-bit integer throughput is often 2x-4x.</p>
<h2 data-number="2.1" id="example"><span class="header-section-number">2.1</span> Example<a href="#example" class="self-link"></a></h2>
<p>To gauge the impact, we investigated a simple stencil code benchmark,
which is hosted in the <a href="https://github.com/kokkos/mdspan">mdspan
reference implementation</a>. That benchmark is using CUDA and compares
a variant with raw pointers and explicit index calculation against a
version which uses <code>mdspan</code>.</p>
<p>The <code>mdspan</code> variant does in each CUDA thread the
following code:</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="cf">for</span><span class="op">(</span><span class="dt">size_t</span> i <span class="op">=</span> blockIdx<span class="op">.</span>x<span class="op">+</span>d; i <span class="op">&lt;</span> s<span class="op">.</span>extent<span class="op">(</span><span class="dv">0</span><span class="op">)-</span>d; i <span class="op">+=</span> gridDim<span class="op">.</span>x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> j <span class="op">=</span> threadIdx<span class="op">.</span>z<span class="op">+</span>d; j <span class="op">&lt;</span> s<span class="op">.</span>extent<span class="op">(</span><span class="dv">1</span><span class="op">)-</span>d; j <span class="op">+=</span> blockDim<span class="op">.</span>z<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="cf">for</span><span class="op">(</span><span class="dt">size_t</span> k <span class="op">=</span> threadIdx<span class="op">.</span>y<span class="op">+</span>d; k <span class="op">&lt;</span> s<span class="op">.</span>extent<span class="op">(</span><span class="dv">2</span><span class="op">)-</span>d; k <span class="op">+=</span> blockDim<span class="op">.</span>y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>      value_type sum_local <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>      <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> di <span class="op">=</span> i<span class="op">-</span>d; di <span class="op">&lt;</span> i<span class="op">+</span>d<span class="op">+</span><span class="dv">1</span>; di<span class="op">++)</span> <span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> dj <span class="op">=</span> j<span class="op">-</span>d; dj <span class="op">&lt;</span> j<span class="op">+</span>d<span class="op">+</span><span class="dv">1</span>; dj<span class="op">++)</span> <span class="op">{</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>      <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> dk <span class="op">=</span> k<span class="op">-</span>d; dk <span class="op">&lt;</span> k<span class="op">+</span>d<span class="op">+</span><span class="dv">1</span>; dk<span class="op">++)</span> <span class="op">{</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        sum_local <span class="op">+=</span> s<span class="op">(</span>di, dj, dk<span class="op">)</span>;</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">}}}</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>      o<span class="op">(</span>i,j,k<span class="op">)</span> <span class="op">=</span> sum_local;</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The raw pointer variant looks like this:</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 class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> i <span class="op">=</span> blockIdx<span class="op">.</span>x<span class="op">+</span>d; i <span class="op">&lt;</span> x<span class="op">-</span>d; i <span class="op">+=</span> gridDim<span class="op">.</span>x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> j <span class="op">=</span> threadIdx<span class="op">.</span>z<span class="op">+</span>d; j <span class="op">&lt;</span> y<span class="op">-</span>d; j <span class="op">+=</span> blockDim<span class="op">.</span>z<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> k <span class="op">=</span> threadIdx<span class="op">.</span>y<span class="op">+</span>d; k <span class="op">&lt;</span> z<span class="op">-</span>d; k <span class="op">+=</span> blockDim<span class="op">.</span>y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>      value_type sum_local <span class="op">=</span> <span class="dv">0</span>;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>      <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> di <span class="op">=</span> i<span class="op">-</span>d; di <span class="op">&lt;</span> i<span class="op">+</span>d<span class="op">+</span><span class="dv">1</span>; di<span class="op">++)</span> <span class="op">{</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> dj <span class="op">=</span> j<span class="op">-</span>d; dj <span class="op">&lt;</span> j<span class="op">+</span>d<span class="op">+</span><span class="dv">1</span>; dj<span class="op">++)</span> <span class="op">{</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>      <span class="cf">for</span><span class="op">(</span><span class="dt">size_t</span> dk <span class="op">=</span> k<span class="op">-</span>d; dk <span class="op">&lt;</span> k<span class="op">+</span>d<span class="op">+</span><span class="dv">1</span>; dk<span class="op">++)</span> <span class="op">{</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>        sum_local <span class="op">+=</span> data<span class="op">[</span>dk <span class="op">+</span> dj<span class="op">*</span>z <span class="op">+</span> di<span class="op">*</span>z<span class="op">*</span>y<span class="op">]</span>;</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">}}}</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>      data_o<span class="op">[</span>k <span class="op">+</span> j<span class="op">*</span>z <span class="op">+</span> i<span class="op">*</span>z<span class="op">*</span>y<span class="op">]</span> <span class="op">=</span> sum_local;</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Running the raw pointer variant with <code>unsigned</code> vs
<code>size_t</code> as the loop indices, results in a timing of 31ms vs
56ms. The same is observed for the <code>mdspan</code> variant when
switching in the <code>mdspan</code> implementation the
<code>size_type</code> from <code>size_t</code> to
<code>unsigned</code>. The 31ms result can also be obtained when leaving
<code>size_type</code> as <code>size_t</code> but casting
<code>extents.extent(r)</code> to the user provided index type inside
the <em>layout mappings</em> index calculation <code>operator</code>
while using <code>unsigned</code> as the loop index type in the
algorithm.</p>
<h2 data-number="2.2" id="possible-ways-to-address-the-issue"><span class="header-section-number">2.2</span> Possible Ways To Address The
Issue<a href="#possible-ways-to-address-the-issue" class="self-link"></a></h2>
<h3 data-number="2.2.1" id="mappings-doing-offset-calculation-with-argument-type"><span class="header-section-number">2.2.1</span> Mappings Doing Offset
Calculation With Argument Type<a href="#mappings-doing-offset-calculation-with-argument-type" class="self-link"></a></h3>
<p>One way to address this issue would be for mappings to do all their
internal calculations with the <code>common_type</code> of the
user-provided indices. That includes casting
<code>extents.extent(i)</code>. However the drawback of this approach is
that it is hard to identify overflows, which depend on layout as
well.</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><span class="co">// The following is ok, extents converts to size_t, required_span_size returns size_t too</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">&lt;</span><span class="dt">double</span>,dextents<span class="op">&lt;</span><span class="dv">3</span><span class="op">&gt;</span>,layout_right<span class="op">&gt;</span> r<span class="op">(</span>ptr,<span class="dv">2000</span>,<span class="dv">2000</span>,<span class="dv">2000</span><span class="op">)</span>; </span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>mdspan<span class="op">&lt;</span><span class="dt">double</span>,dextents<span class="op">&lt;</span><span class="dv">3</span><span class="op">&gt;</span>,layout_left<span class="op">&gt;</span>  l<span class="op">(</span>ptr,<span class="dv">2000</span>,<span class="dv">2000</span>,<span class="dv">2000</span><span class="op">)</span>;</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="op">...</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>r<span class="op">(</span><span class="dv">1</span>,<span class="dv">1</span>,<span class="dv">1000</span><span class="op">)</span> <span class="op">=</span> <span class="dv">5</span>; <span class="co">// ok</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>r<span class="op">(</span><span class="dv">1000</span>,<span class="dv">1</span>,<span class="dv">1</span><span class="op">)</span> <span class="op">=</span> <span class="dv">5</span>; <span class="co">// overflow</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>l<span class="op">(</span><span class="dv">1</span>,<span class="dv">1</span>,<span class="dv">1000</span><span class="op">)</span> <span class="op">=</span> <span class="dv">5</span>; <span class="co">// overflow</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>l<span class="op">(</span><span class="dv">1000</span>,<span class="dv">1</span>,<span class="dv">1</span><span class="op">)</span> <span class="op">=</span> <span class="dv">5</span>; <span class="co">// ok</span></span></code></pre></div>
<p>In particular, in situations where allocations and
<code>mdspan</code> creation happens in another code, location this
could be an issue.</p>
<h3 data-number="2.2.2" id="template-extents-on-size_type"><span class="header-section-number">2.2.2</span> Template <code>extents</code>
on <code>size_type</code><a href="#template-extents-on-size_type" class="self-link"></a></h3>
<p>In order to make overflow a better controllable artifact, and avoid
accidental overflows we can make the index type part of the type. The
natural place for this is <code>extents</code>. Every index calculation
related piece of the <code>mdspan</code> proposal gets its
<code>size_type</code> from <code>extents</code>, specifically both
layout mappings, and <code>mdspan</code> itself is required to get its
public <code>size_type</code> type member from
<code>extents_type::size_type</code>. Furthermore, <code>extents</code>
defines the complete iteration space for <code>mdspan</code>. Note, that
a mapping might require a larger integer range that the product of
extents (e.g. <code>layout_stride::required_span_size</code> can return
a number larger than the product of its extents).</p>
<h3 data-number="2.2.3" id="second-extents-type-templated-on-size_type"><span class="header-section-number">2.2.3</span> Second Extents Type Templated
on <code>size_type</code><a href="#second-extents-type-templated-on-size_type" class="self-link"></a></h3>
<p>Instead of modifying <code>extents</code>, we could introduce a new
type <code>basic_extents</code> which is templated on the size type and
the extents, but otherwise is identical to <code>extents</code>: When we
can make anything in the mdspan proposal which accepts
<code>extents</code> also accept <code>basic_extents</code>.</p>
<p>Potentially, <code>extents</code> could be just a template alias to
<code>basic_extents</code>:</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><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="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> extents <span class="op">=</span> basic_extents<span class="op">&lt;</span><span class="dt">size_t</span>, Extents<span class="op">...&gt;</span>;</span></code></pre></div>
<p>Unfortunately that means that the following type of code would not
work:</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">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> L, <span class="kw">class</span> A, <span class="dt">size_t</span> <span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> foo<span class="op">(</span>mdspan<span class="op">&lt;</span>T,extents<span class="op">&lt;</span>Extents<span class="op">...&gt;</span>,L,A<span class="op">&gt;</span> a<span class="op">)</span> <span class="op">{...{</span></span></code></pre></div>
<p>However we believe the common use case would be to template on the
extents object itself, mitigating this issue:</p>
<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="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> E, <span class="kw">class</span> L, <span class="kw">class</span> A<span class="op">&gt;</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> foo<span class="op">(</span>mdspan<span class="op">&lt;</span>T,E,L,A<span class="op">&gt;</span> a<span class="op">)</span> <span class="op">{...}</span></span></code></pre></div>
<h3 data-number="2.2.4" id="template-layoutpolicy-on-size_type"><span class="header-section-number">2.2.4</span> Template LayoutPolicy on
<code>size_type</code><a href="#template-layoutpolicy-on-size_type" class="self-link"></a></h3>
<p>We could also template the layout policy class on
<code>size_type</code>, and use that type for the offset calculation,
casting <code>extents::extent</code> explicitly on use. However this
still means that the size of the object is larger (i.e. we would still
store 64bit extents, instead of 32bit) and that additional casts will
happen.</p>
<h3 data-number="2.2.5" id="what-we-prefer"><span class="header-section-number">2.2.5</span> What we prefer:<a href="#what-we-prefer" class="self-link"></a></h3>
<p>All in all we prefer the option of making <code>extents</code>
require the additional argument (2.2.2), with the next best thing being
the introduction <code>basic_extents</code> and making
<code>extents</code> an alias to <code>basic_extents</code> with
<code>size_t</code> as the <code>size_type</code>. If LEWG would prefer
the second option, the wording is largely the same with the following
changes at the end:</p>
<ul>
<li><p>Rename <code>extents</code> to <code>basic_extents</code>
throughout P0009 and</p></li>
<li><p>Add an alias in [mdspan.syn]:</p></li>
</ul>
<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">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-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> extents <span class="op">=</span> basic_extents<span class="op">&lt;</span><span class="dt">size_t</span>, Extents<span class="op">...&gt;</span>;</span></code></pre></div>
<p>LEWG would need to decide whether to make <code>dextents</code> have
a <code>size_type</code> template parameter or not.</p>
<h2 data-number="2.3" id="why-we-cant-fix-this-later"><span class="header-section-number">2.3</span> Why we can’t fix this later<a href="#why-we-cant-fix-this-later" class="self-link"></a></h2>
<p>In principle we could add a second extents type later, though it may
break code such as the one shown before (in the sense that it wouldn’t
generally work for every instance of <code>mdspan</code> anymore):</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">template</span><span class="op">&lt;</span><span class="kw">class</span> T, <span class="kw">class</span> L, <span class="kw">class</span> A, <span class="dt">size_t</span> <span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> foo<span class="op">(</span>mdspan<span class="op">&lt;</span>T,extents<span class="op">&lt;</span>Extents<span class="op">...&gt;</span>,L,A<span class="op">&gt;</span> a<span class="op">)</span> <span class="op">{...{</span></span></code></pre></div>
<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="https://wg21.link/P0009">P0009</a> R16.</p>
<!--

 /$$      /$$                           /$$ /$$
| $$  /$ | $$                          | $$|__/
| $$ /$$$| $$  /$$$$$$   /$$$$$$   /$$$$$$$ /$$ /$$$$$$$   /$$$$$$
| $$/$$ $$ $$ /$$__  $$ /$$__  $$ /$$__  $$| $$| $$__  $$ /$$__  $$
| $$$$_  $$$$| $$  \ $$| $$  \__/| $$  | $$| $$| $$  \ $$| $$  \ $$
| $$$/ \  $$$| $$  | $$| $$      | $$  | $$| $$| $$  | $$| $$  | $$
| $$/   \  $$|  $$$$$$/| $$      |  $$$$$$$| $$| $$  | $$|  $$$$$$$
|__/     \__/ \______/ |__/       \_______/|__/|__/  |__/ \____  $$
                                                          /$$  \ $$
                                                         |  $$$$$$/
                                                          \______/
-->
<h1 data-number="4" id="wording"><span class="header-section-number">4</span> Wording<a href="#wording" class="self-link"></a></h1>
<h2 data-number="4.1" id="in-22.7.x-mdspan.syn"><span class="header-section-number">4.1</span> In 22.7.X [mdspan.syn]<a href="#in-22.7.x-mdspan.syn" class="self-link"></a></h2>
<p>Replace:</p>
<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">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="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> extents;</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-4"><a href="#cb9-4" 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="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> dextents <span class="op">=</span> see below;</span></code></pre></div>
<p>with:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeT, <span class="dt">size_t</span><span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">class</span> extents;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeT, <span class="dt">size_t</span> Rank<span class="op">&gt;</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> dextents <span class="op">=</span> see below;</span></code></pre></div>
<h2 data-number="4.2" id="in-22.7.x.1-mdspan.extents.overview"><span class="header-section-number">4.2</span> In 22.7.X.1
[mdspan.extents.overview]:<a href="#in-22.7.x.1-mdspan.extents.overview" class="self-link"></a></h2>
<ul>
<li>In the synopsis replace:</li>
</ul>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="dt">size_t</span><span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> extents <span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb11-4"><a href="#cb11-4" 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="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> rank_type <span class="op">=</span> <span class="dt">size_t</span>;</span></code></pre></div>
<p>with</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SizeT, <span class="dt">size_t</span><span class="op">...</span> Extents<span class="op">&gt;</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> extents <span class="op">{</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span><span class="op">:</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> size_type <span class="op">=</span> SizeT;</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> rank_type <span class="op">=</span> <span class="dt">size_t</span>;</span></code></pre></div>
<ul>
<li>In the synopsis replace:</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">static</span> <span class="kw">constexpr</span> size_type static_extent<span class="op">(</span>rank_type<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p>with</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">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> static_extent<span class="op">(</span>rank_type<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li>In the synopsis replace:</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">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="cb15-2"><a href="#cb15-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="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> extents<span class="op">(</span><span class="kw">const</span> extents<span class="op">&lt;</span>OtherExtents<span class="op">...&gt;&amp;)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p>with:</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="kw">class</span> OtherSizeT, <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">explicit</span><span class="op">(</span><em>see below</em><span class="op">)</span></span>
<span id="cb16-3"><a href="#cb16-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>OtherSizeT, OtherExtents<span class="op">...&gt;&amp;)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li>In the synopsis replace:</li>
</ul>
<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="co">// [mdspan.extents.cmp], extents comparison operators</span></span>
<span id="cb17-2"><a href="#cb17-2" 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="cb17-3"><a href="#cb17-3" 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></code></pre></div>
<p>with:</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="co">// [mdspan.extents.cmp], extents comparison operators</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherSizeT, <span class="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb18-3"><a href="#cb18-3" 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>OtherSizeT, OtherExtents<span class="op">...&gt;&amp;)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li>In the synopsis add the following public static exposition only
member functions:</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><span class="op">...</span> Integrals<span class="op">&gt;</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <em>are-valid-extents</em><span class="op">(</span>Integrals<span class="op">...</span> values<span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherSizeT, <span class="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <em>are-valid-extents</em><span class="op">(</span>extents<span class="op">&lt;</span>OtherSizeT, OtherExtents<span class="op">&gt;)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherSizeT, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <em>are-valid-extents</em><span class="op">(</span>array<span class="op">&lt;</span>OtherSizeT, N<span class="op">&gt;)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span></code></pre></div>
<ul>
<li>After paragraph 2 insert a new paragraph 3:</li>
</ul>
<p>If <code>SizeT</code> is not an integral type other than
<code>bool</code>, then the program is ill-formed.</p>
<h2 data-number="4.3" id="in-22.7.x.2-mdspan.extents.helpers"><span class="header-section-number">4.3</span> In 22.7.X.2
[mdspan.extents.helpers]:<a href="#in-22.7.x.2-mdspan.extents.helpers" class="self-link"></a></h2>
<ul>
<li>Add new paragraphs after 8:</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><span class="op">...</span> Integrals<span class="op">&gt;</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <em>are-valid-extents</em><span class="op">(</span>Integrals<span class="op">...</span> values<span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span></code></pre></div>
<p><em>Returns</em>:</p>
<ul>
<li><p><code>true</code> if <code>sizeof...(Integrals) == 0</code> is
<code>true</code>, otherwise</p></li>
<li><p><code>true</code> if
<code>((values &gt; 0) &amp;&amp; ...)</code> is <code>true</code> and
each element of <code>values</code> is a representable value of
<code>size_type</code>, otherwise</p></li>
<li><p><code>false</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> OtherSizeT, <span class="dt">size_t</span><span class="op">...</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">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <em>are-valid-extents</em><span class="op">(</span>extents<span class="op">&lt;</span>OtherSizeT, OtherExtents<span class="op">&gt;</span> e<span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span></code></pre></div>
<p><em>Returns</em>:</p>
<ul>
<li><p><code>true</code> if <code>sizeof...(OtherExtents) == 0</code> is
<code>true</code>, otherwise</p></li>
<li><p><code>true</code> if <code>e.extent(r) &gt; 0</code> is
<code>true</code> for all rank index <code>r</code> of <code>e</code>
and <code>e.extent(r)</code> is a representable value of
<code>size_type</code> for all rank index <code>r</code> of
<code>e</code>, otherwise</p></li>
<li><p><code>false</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">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherSizeT, <span class="dt">size_t</span> N<span class="op">&gt;</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">bool</span> <em>are-valid-extents</em><span class="op">(</span>array<span class="op">&lt;</span>OtherSizeT, N<span class="op">&gt;</span> arr<span class="op">)</span> <span class="kw">noexcept</span>; <span class="co">// <em>exposition only</em></span></span></code></pre></div>
<p><em>Returns</em>:</p>
<ul>
<li><p><code>true</code> if <code>N == 0</code> is <code>true</code>,
otherwise</p></li>
<li><p><code>true</code> if for all <code>r</code> in the range of <span class="math inline">[</span><code>0</code>,<code>N</code><span class="math inline">)</span> <code>arr[r] &gt; 0</code> is
<code>true</code> and <code>arr[r]</code> is a representable value of
<code>size_type</code>, otherwise</p></li>
<li><p><code>false</code>.</p></li>
</ul>
<h2 data-number="4.4" id="in-subsection-22.7.x.3-mdspan.extents.cons"><span class="header-section-number">4.4</span> In subsection 22.7.X.3
[mdspan.extents.cons]<a href="#in-subsection-22.7.x.3-mdspan.extents.cons" class="self-link"></a></h2>
<ul>
<li>Change the following:</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="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">explicit</span><span class="op">((((</span>Extents<span class="op">!=</span>dynamic_extent<span class="op">)</span> <span class="op">&amp;&amp;</span> <span class="op">(</span>OtherExtents<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="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> extents<span class="op">(</span><span class="kw">const</span> extents<span class="op">&lt;</span>OtherExtents<span class="op">...&gt;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p>to:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherSizeT, <span class="dt">size_t</span><span class="op">...</span> OtherExtents<span class="op">&gt;</span></span>
<span id="cb24-2"><a href="#cb24-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="cb24-3"><a href="#cb24-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>OtherSizeT, OtherExtents<span class="op">...&gt;&amp;</span> other<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li><p>Change Paragraph 2 to:</p>
<p><em>Preconditions:</em></p>
<ul>
<li><p><code>other.extent(r)</code> equals <span class="math inline"><em>E</em><sub><em>r</em></sub></span> for each
<span class="math inline"><em>r</em></span> for which <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a static
extent, and</p></li>
<li><p><em><code>are-valid-extents</code></em><code>(other)</code> is
<code>true</code>.</p></li>
</ul></li>
<li><p>Add new paragraph 4:</p>
<p><em>Remarks:</em> The expression inside explicit is equivalent
to:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>  <span class="op">(((</span>Extents<span class="op">!=</span>dynamic_extent<span class="op">)</span> <span class="op">&amp;&amp;</span> <span class="op">(</span>OtherExtents<span class="op">==</span>dynamic_extent<span class="op">))</span> <span class="op">||</span> <span class="op">...</span> <span class="op">)</span> <span class="op">||</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">(</span>numeric_limits<span class="op">&lt;</span>size_type<span class="op">&gt;::</span>max<span class="op">()</span> <span class="op">&lt;</span> numeric_limits<span class="op">&lt;</span>OtherSizeT<span class="op">&gt;::</span>max<span class="op">())</span></span></code></pre></div></li>
<li><p>Change Paragrpah 6 to:</p>
<p><em>Preconditions</em>:</p>
<ul>
<li><p>If <code>sizeof...(SizeTypes) != rank_dynamic()</code> is
<code>true</code>, <code>exts_arr[r]</code> equals <span class="math inline"><em>E</em><sub><em>r</em></sub></span> for each
<span class="math inline"><em>r</em></span> for which <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a static
extent, and</p></li>
<li><p><em><code>are-valid-extents</code></em><code>(exts...)</code> is
<code>true</code>.</p></li>
</ul></li>
<li><p>Change Paragrpah 9 to:</p>
<p><em>Preconditions</em>:</p>
<ul>
<li><p>If <code>N != rank_dynamic()</code> is <code>true</code>,
<code>exts[r]</code> equals <span class="math inline"><em>E</em><sub><em>r</em></sub></span> for each
<span class="math inline"><em>r</em></span> for which <span class="math inline"><em>E</em><sub><em>r</em></sub></span> is a static
extent, and</p></li>
<li><p><em><code>are-valid-extents</code></em><code>(exts)</code> is
<code>true</code>.</p></li>
</ul></li>
<li><p>Change paragraph 12 to:</p>
<p><em>Remarks:</em> The deduced type is
<code>dextents&lt;size_t, sizeof...(Integrals)&gt;</code>.</p></li>
</ul>
<h2 data-number="4.5" id="in-subsection-22.7.x.4-mdspan.extents.obs"><span class="header-section-number">4.5</span> In subsection 22.7.X.4
[mdspan.extents.obs]<a href="#in-subsection-22.7.x.4-mdspan.extents.obs" class="self-link"></a></h2>
<ul>
<li><p>Replace the following:</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">static</span> <span class="kw">constexpr</span> size_type static_extent<span class="op">(</span>rank_type i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div></li>
</ul>
<p>with:</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">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> static_extent<span class="op">(</span>rank_type i<span class="op">)</span> <span class="kw">const</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<h2 data-number="4.6" id="in-subsection-22.7.x.5-mdspan.extents.compare"><span class="header-section-number">4.6</span> In subsection 22.7.X.5
[mdspan.extents.compare]<a href="#in-subsection-22.7.x.5-mdspan.extents.compare" class="self-link"></a></h2>
<ul>
<li><p>Replace the following:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>  <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="cb28-2"><a href="#cb28-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="cb28-3"><a href="#cb28-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></li>
</ul>
<p>with:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> OtherSizeT, <span class="dt">size_t</span><span class="op">...</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">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="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>                                     <span class="kw">const</span> extents<span class="op">&lt;</span>OtherSizeT, OtherExtents<span class="op">...&gt;&amp;</span> rhs<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<ul>
<li>Change paragraph 1 to:</li>
</ul>
<p><em>Returns:</em> <code>true</code> if
<code>lhs.rank() == rhs.rank()</code> is <code>true</code> and
<code>lhs.extents(r)</code> equals <code>rhs.extents(r)</code> for every
rank index <code>r</code> of <code>rhs</code>, otherwise
<code>false</code>.</p>
<h2 data-number="4.7" id="in-subsection-22.7.x.6-mdspan.extents.dextents"><span class="header-section-number">4.7</span> In subsection 22.7.X.6
[mdspan.extents.dextents]<a href="#in-subsection-22.7.x.6-mdspan.extents.dextents" class="self-link"></a></h2>
<ul>
<li><p>Replace section with:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> SizeT, <span class="dt">size_t</span> Rank<span class="op">&gt;</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> dextents <span class="op">=</span> <em>see below</em>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Result:</em> A type <code>E</code> that is a specialization of
<code>extents</code> such that
<code>E::rank() == Rank &amp;&amp; E::rank() == E::rank_dynamic()</code>
is <code>true</code> and <code>E::size_type</code> denotes
<code>SizeT</code>.</p></li>
</ul>
<h2 data-number="4.8" id="in-subsection-22.7.x.3.1-mdspan.layout.left.ctors"><span class="header-section-number">4.8</span> In subsection 22.7.X.3.1
[mdspan.layout.left.ctors]<a href="#in-subsection-22.7.x.3.1-mdspan.layout.left.ctors" class="self-link"></a></h2>
<ul>
<li>After paragraph 3 add new paragraph:</li>
</ul>
<p><em>Preconditions</em>: <code>other.required_span_size()</code> is a
representable value of <code>size_type</code> ([basic.fundamental]).</p>
<ul>
<li>After paragraph 5 add new paragraph:</li>
</ul>
<p><em>Preconditions</em>: <code>other.required_span_size()</code> is a
representable value of <code>size_type</code> ([basic.fundamental]).</p>
<ul>
<li>Change paragraph 8 to:</li>
</ul>
<p><em>Preconditions</em>:</p>
<ul>
<li><p>If <code>extents_type::rank() &gt; 0</code> is <code>true</code>
then for all <span class="math inline"><em>r</em></span> in the range
<span class="math inline">[</span><code>0</code>,
<code>extents_type::rank()</code><span class="math inline">)</span>,
<code>other.stride(r)</code> equals
<code>extents().</code><em>fwd-prod-of-extents</em><code>(r)</code>,
and</p></li>
<li><p><code>other.required_span_size()</code> is a representable value
of <code>size_type</code> ([basic.fundamental]).</p></li>
</ul>
<h2 data-number="4.9" id="in-subsection-22.7.x.4.1-mdspna.layout.right.ctors"><span class="header-section-number">4.9</span> In subsection 22.7.X.4.1
[mdspna.layout.right.ctors]<a href="#in-subsection-22.7.x.4.1-mdspna.layout.right.ctors" class="self-link"></a></h2>
<ul>
<li>After paragraph 3 add new paragraph:</li>
</ul>
<p><em>Preconditions</em>: <code>other.required_span_size()</code> is a
representable value of <code>size_type</code> ([basic.fundamental]).</p>
<ul>
<li>After paragraph 5 add new paragraph:</li>
</ul>
<p><em>Preconditions</em>: <code>other.required_span_size()</code> is a
representable value of <code>size_type</code> ([basic.fundamental]).</p>
<ul>
<li>Change paragraph 8 to:</li>
</ul>
<p><em>Preconditions</em>:</p>
<ul>
<li><p>If <code>extents_type::rank() &gt; 0</code> is <code>true</code>
then for all <span class="math inline"><em>r</em></span> in the range
<span class="math inline">[</span><code>0</code>,
<code>extents_type::rank()</code><span class="math inline">)</span>,
<code>other.stride(r)</code> equals
<code>extents().</code><em>rev-prod-of-extents</em><code>(r+1)</code>,
and</p></li>
<li><p><code>other.required_span_size()</code> is a representable value
of <code>size_type</code> ([basic.fundamental]).</p></li>
</ul>
<h2 data-number="4.10" id="in-subsection-22.7.x.5.2-mdspan.layout.stride.cotrs"><span class="header-section-number">4.10</span> In Subsection 22.7.X.5.2
[mdspan.layout.stride.cotrs]<a href="#in-subsection-22.7.x.5.2-mdspan.layout.stride.cotrs" class="self-link"></a></h2>
<ul>
<li><p>add in paragraph 6 additiona precondition:</p>
<ul>
<li><code>other.stride(r) &gt; 0</code> is <code>true</code> for all
rank index <code>r</code> of <code>extents()</code>,</li>
</ul></li>
</ul>
<h2 data-number="4.11" id="in-subsection-22.7.x.1-mdspan.mdspan.overview"><span class="header-section-number">4.11</span> In subsection 22.7.X.1
[mdspan.mdspan.overview]<a href="#in-subsection-22.7.x.1-mdspan.mdspan.overview" class="self-link"></a></h2>
<ul>
<li><p>In the synopsis replace:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>  <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></code></pre></div></li>
</ul>
<p>with:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">static</span> <span class="kw">constexpr</span> <span class="dt">size_t</span> 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></code></pre></div>
<ul>
<li><p>In the synopsis replace:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> size_type size<span class="op">()</span> <span class="kw">const</span>;</span></code></pre></div></li>
</ul>
<p>with</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constexpr</span> <span class="dt">size_t</span> size<span class="op">()</span> <span class="kw">const</span>;</span></code></pre></div>
<ul>
<li><p>In the synopsis replace:</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">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="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>  mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;)</span></span>
<span id="cb35-3"><a href="#cb35-3" 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="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-5"><a href="#cb35-5" 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="cb35-6"><a href="#cb35-6" 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="cb35-7"><a href="#cb35-7" 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></code></pre></div></li>
</ul>
<p>with:</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> ElementType, <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>  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="cb36-3"><a href="#cb36-3" 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="dt">size_t</span>, N<span class="op">&gt;&gt;</span>;</span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb36-5"><a href="#cb36-5" 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> SizeT, <span class="dt">size_t</span><span class="op">...</span> ExtentsPack<span class="op">&gt;</span></span>
<span id="cb36-6"><a href="#cb36-6" 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>SizeT, ExtentsPack<span class="op">...&gt;&amp;)</span></span>
<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> mdspan<span class="op">&lt;</span>ElementType, extents<span class="op">&lt;</span>SizeT, ExtentsPack<span class="op">...&gt;&gt;</span>;</span></code></pre></div>
<h2 data-number="4.12" id="in-subsection-22.7.x.1-mdspan.mdspan.ctors"><span class="header-section-number">4.12</span> In subsection 22.7.X.1
[mdspan.mdspan.ctors]<a href="#in-subsection-22.7.x.1-mdspan.mdspan.ctors" class="self-link"></a></h2>
<ul>
<li><p>Change code after paragraph 19 to:</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">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="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>  mdspan<span class="op">(</span>ElementType<span class="op">*</span>, <span class="kw">const</span> array<span class="op">&lt;</span>SizeType, N<span class="op">&gt;&amp;)</span></span>
<span id="cb37-3"><a href="#cb37-3" 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="dt">size_t</span>, N<span class="op">&gt;&gt;</span>;</span></code></pre></div></li>
</ul>
<h2 data-number="4.13" id="in-subsection-22.7.x-mdspan.submdspan"><span class="header-section-number">4.13</span> In Subsection 22.7.X
[mdspan.submdspan]<a href="#in-subsection-22.7.x-mdspan.submdspan" class="self-link"></a></h2>
<ul>
<li><p>Add a sub-bullet in 11.1:</p>
<ul>
<li><code>typename SubExtents::size_type</code> is
<code>typename Extents::size_type</code></li>
</ul></li>
</ul>
<h1 data-number="5" id="implementation"><span class="header-section-number">5</span> Implementation<a href="#implementation" class="self-link"></a></h1>
<p>There is an mdspan implementation available at <a href="https://github.com/kokkos/mdspan/">https://github.com/kokkos/mdspan/</a>.</p>
<h1 data-number="6" id="related-work"><span class="header-section-number">6</span> Related Work<a href="#related-work" class="self-link"></a></h1>
<ul>
<li><b>P0009</b> : <code>mdspan</code></li>
</ul>
</div>
</div>
</body>
</html>
