<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>P0009r6 : mdspan: A Non-Owning Multidimensional Array Reference</title>
<meta name="date" content="2018-05-07" />
<meta name="author" content="H. Carter Edwards" />
<meta name="author" content="Bryce Adelstein Lelbach" />
<meta name="author" content="Daniel Sunderland" />
<meta name="author" content="David Hollman" />
<meta name="author" content="Christian Trott" />
<meta name="author" content="Mauro Bianco" />
<meta name="author" content="Ben Sander" />
<meta name="author" content="Athanasios Iliopoulos" />
<meta name="author" content="John Michopoulos" />
<meta name="author" content="Daniel Sunderland" />
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

.subscript {
  vertical-align: sub;
  font-size: smaller }

.superscript {
  vertical-align: super;
  font-size: smaller }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left, table.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right, table.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

table.align-center {
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

.align-top    {
  vertical-align: top }

.align-middle {
  vertical-align: middle }

.align-bottom {
  vertical-align: bottom }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="p0009r6-mdspan-a-non-owning-multidimensional-array-reference">
<h1 class="title">P0009r6 : <tt class="docutils literal">mdspan</tt>: A Non-Owning Multidimensional Array Reference</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="project field"><th class="docinfo-name">Project:</th><td class="field-body">ISO JTC1/SC22/WG21: Programming Language C++</td>
</tr>
<tr class="number field"><th class="docinfo-name">Number:</th><td class="field-body">P0009r6</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2018-05-07</td></tr>
<tr class="reply-to field"><th class="docinfo-name">Reply-to:</th><td class="field-body"><a class="reference external" href="mailto:hedwards&#64;nvidia.com">hedwards&#64;nvidia.com</a></td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>H. Carter Edwards</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:hedwards&#64;nvidia.com">hedwards&#64;nvidia.com</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Bryce Adelstein Lelbach</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:blelbach&#64;nvidia.com">blelbach&#64;nvidia.com</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Daniel Sunderland</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:dsunder&#64;sandia.gov">dsunder&#64;sandia.gov</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>David Hollman</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:dshollm&#64;sandia.gov">dshollm&#64;sandia.gov</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Christian Trott</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:crtrott&#64;sandia.gov">crtrott&#64;sandia.gov</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Mauro Bianco</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:mbianco&#64;cscs.ch">mbianco&#64;cscs.ch</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Ben Sander</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:ben.sander&#64;amd.com">ben.sander&#64;amd.com</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Athanasios Iliopoulos</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:athanasios.iliopoulos&#64;nrl.navy.mil">athanasios.iliopoulos&#64;nrl.navy.mil</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>John Michopoulos</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:john.michopoulos&#64;nrl.navy.mil">john.michopoulos&#64;nrl.navy.mil</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Daniel Sunderland</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:dsunder&#64;sandia.gov">dsunder&#64;sandia.gov</a></td></tr>
<tr class="audience field"><th class="docinfo-name">Audience:</th><td class="field-body">Library Working Group (LWG)</td>
</tr>
<tr class="url field"><th class="docinfo-name">URL:</th><td class="field-body"><a class="reference external" href="https://github.com/ORNL/cpp-proposals-pub/P0009/P0009.rst">https://github.com/ORNL/cpp-proposals-pub/P0009/P0009.rst</a></td>
</tr>
</tbody>
</table>
<div class="section" id="revision-history">
<h1>1&nbsp;&nbsp;&nbsp;Revision History</h1>
<div class="section" id="p0009r0-pre-2015-10-kona-mailing">
<h2>1.1&nbsp;&nbsp;&nbsp;P0009r0 : Pre 2015-10-Kona Mailing</h2>
<p>Original non-owning multidimensional array reference (<tt class="docutils literal">view</tt>) paper
with motivation, specification, and examples.</p>
</div>
<div class="section" id="p0009r1-pre-2016-02-jacksonville-mailing">
<h2>1.2&nbsp;&nbsp;&nbsp;P0009r1 : Pre 2016-02-Jacksonville Mailing</h2>
<p><a class="reference external" href="http://wiki.edg.com/bin/view/Wg21kona2015/P0009">LEWG review at 2015-10-Kona</a>.</p>
<p><strong>LEWG Poll</strong>: What should this feature be called?</p>
<table border="1" class="docutils">
<colgroup>
<col width="88%" />
<col width="12%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Name</th>
<th class="head">#</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal">view</tt></td>
<td>5</td>
</tr>
<tr><td><tt class="docutils literal">span</tt></td>
<td>9</td>
</tr>
<tr><td><tt class="docutils literal">array_ref</tt></td>
<td>6</td>
</tr>
<tr><td><tt class="docutils literal">slice</tt></td>
<td>6</td>
</tr>
<tr><td><tt class="docutils literal">array_view</tt></td>
<td>6</td>
</tr>
<tr><td><tt class="docutils literal">ref</tt></td>
<td>0</td>
</tr>
<tr><td><tt class="docutils literal">array_span</tt></td>
<td>7</td>
</tr>
<tr><td><tt class="docutils literal">basic_span</tt></td>
<td>1</td>
</tr>
<tr><td><tt class="docutils literal">object_span</tt></td>
<td>3</td>
</tr>
<tr><td><tt class="docutils literal">field</tt></td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>LEWG Poll</strong>: Do we want 0-length static extents?</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>3</td>
<td>4</td>
<td>2</td>
<td>3</td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>LEWG POLL</strong>: Do we want the language to support syntaxes like X[3][][][5]?</p>
<table border="1" class="docutils">
<colgroup>
<col width="97%" />
<col width="3%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Syntax</th>
<th class="head">#</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">view&lt;int[3][0][][5],</span> property1&gt;</tt></td>
<td>12</td>
</tr>
<tr><td><tt class="docutils literal">view&lt;int, dimension&lt;3, 0, dynamic_extent, 5&gt;, property1&gt;</tt></td>
<td>4</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">view&lt;int[3][0][dynamic_extent][5],</span> property1&gt;</tt></td>
<td>5</td>
</tr>
<tr><td><tt class="docutils literal">view&lt;int, 3, 0, dynamic_extent, 5, property1&gt;</tt></td>
<td>4</td>
</tr>
<tr><td><tt class="docutils literal">view&lt;int, 3, 0, dynamic_extent, 5, properties&lt;property1&gt;&gt;</tt></td>
<td>2</td>
</tr>
<tr><td><tt class="docutils literal">view&lt;arr&lt;int, 3, 0, dynamic_extent, 5&gt;, property1&gt;</tt></td>
<td>4</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">view&lt;int[3][0][][5],</span> properties&lt;property1&gt;&gt;</tt></td>
<td>9</td>
</tr>
</tbody>
</table>
<p><strong>LEWG POLL</strong>: Do we want the variadic property list in template args (either
raw or in <tt class="docutils literal">properties&lt;&gt;</tt>)? Note there is no precedence for this in the
library.</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>3</td>
<td>6</td>
<td>3</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>LEWG POLL</strong>: Do we want the per-view bounds-checking knob?</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>3</td>
<td>4</td>
<td>1</td>
<td>2</td>
<td>1</td>
</tr>
</tbody>
</table>
<p><strong>Changes from P0009r0</strong>:</p>
<blockquote>
<ul class="simple">
<li>Renamed <tt class="docutils literal">view</tt> to <tt class="docutils literal">array_ref</tt>.</li>
<li>How are users allowed to add properties? Needs elaboration in paper.</li>
<li><tt class="docutils literal"><span class="pre">view&lt;int[][][]&gt;::layout</span></tt> should be named.</li>
<li><dl class="first docutils">
<dt>Rename <tt class="docutils literal">is_regular</tt> (possibly to <tt class="docutils literal">is_affine</tt>) to avoid overloading the</dt>
<dd>term with the <tt class="docutils literal">Regular</tt> concept.</dd>
</dl>
</li>
<li>Make static span(), operator(), constructor, etc variadic.</li>
<li>Demonstrate the need for improper access in the paper.</li>
<li>In <tt class="docutils literal">operator()</tt>, take integral types by value.</li>
</ul>
</blockquote>
</div>
<div class="section" id="p0009r2-pre-2016-06-oulu-mailing">
<h2>1.3&nbsp;&nbsp;&nbsp;P0009r2 : Pre 2016-06-Oulu Mailing</h2>
<p><a class="reference external" href="http://wiki.edg.com/bin/view/Wg21jacksonville/P0009">LEWG review at 2016-02-Jacksonville</a>.</p>
<p><strong>Changes from P0009r1</strong>:</p>
<blockquote>
<ul class="simple">
<li>Adding details for extensibility of layout mapping.</li>
<li>Move motivation, examples, and relaxed incomplete array type proposal to separate papers.
- <a class="reference external" href="https://wg21.link/P0331">P0331: Motivation and Examples for Polymorphic Multidimensional Array</a>.
- <a class="reference external" href="https://wg21.link/P0332">P0332: Relaxed Incomplete Multidimensional Array Type Declaration</a>.</li>
</ul>
</blockquote>
</div>
<div class="section" id="p0009r3-post-2016-06-oulu-mailing">
<h2>1.4&nbsp;&nbsp;&nbsp;P0009r3 : Post 2016-06-Oulu Mailing</h2>
<p><a class="reference external" href="http://wiki.edg.com/bin/view/Wg21oulu/P0009">LEWG review at 2016-06-Oulu</a></p>
<p>LEWG did not like the name <tt class="docutils literal">array_ref</tt>, and suggested the following alternatives:
- <tt class="docutils literal">sci_span</tt>
- <tt class="docutils literal">numeric_span</tt>
- <tt class="docutils literal">multidimensional_span</tt>
- <tt class="docutils literal">multidim_span</tt>
- <tt class="docutils literal">mdspan</tt>
- <tt class="docutils literal">md_span</tt>
- <tt class="docutils literal">vla_span</tt>
- <tt class="docutils literal">multispan</tt>
- <tt class="docutils literal">multi_span</tt></p>
<p><strong>LEWG Poll</strong>: Are member <tt class="docutils literal">begin()</tt>/<tt class="docutils literal">end()</tt> still good?</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>0</td>
<td>2</td>
<td>4</td>
<td>3</td>
<td>1</td>
</tr>
</tbody>
</table>
<p><strong>LEWG Poll</strong>: Want this proposal to provide range-producing functions outside array_ref?</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>0</td>
<td>1</td>
<td>3</td>
<td>2</td>
<td>3</td>
</tr>
</tbody>
</table>
<p><strong>LEWG Poll</strong>: Want a separate proposal to explore iteration design space?</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>9</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>Changes from P0009r2</strong>:</p>
<blockquote>
<ul class="simple">
<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 (<tt class="docutils literal">element_type</tt>, <tt class="docutils literal">reference</tt>, etc).</li>
<li>Expanded description of how the variadic properties list would work.</li>
<li>Stopped allowing <cite>array_ref&lt;T[N]&gt;</cite> in addition to <cite>array_ref&lt;extents&lt;N&gt;&gt;</cite>.</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>
</blockquote>
</div>
<div class="section" id="p0009r4-pre-2017-11-albuquerque-mailing">
<h2>1.5&nbsp;&nbsp;&nbsp;P0009r4 : Pre 2017-11-Albuquerque Mailing</h2>
<p><a class="reference external" href="http://wiki.edg.com/bin/view/Wg21kona2017/P0009">LEWG review at 2017-03-Kona meeting</a></p>
<p><a class="reference external" href="http://wiki.edg.com/bin/view/Wg21kona2017/P0546">LEWG review of P0546r1 at 2017-03-Kona meeting</a></p>
<p><strong>LEWG Poll</strong>: Should we have a single template that covers both single and multi-dimensional spans?</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>1</td>
<td>6</td>
<td>2</td>
<td>6</td>
<td>3</td>
</tr>
</tbody>
</table>
<p><strong>Changes from P0009r3</strong>:</p>
<blockquote>
<ul class="simple">
<li>Align with <cite>P0122r5 ``span`</cite> proposal &lt;<a class="reference external" href="https://wg21.link/P0122r5">https://wg21.link/P0122r5</a>&gt;`_.</li>
<li>Rename to <tt class="docutils literal">mdspan</tt>, multidimensional span, to align with <tt class="docutils literal">span</tt>.</li>
<li>Move preferred array extents mechanism to appendix.</li>
<li>Expose codomain as a <tt class="docutils literal">span</tt>.</li>
<li>Add layout mapping concept.</li>
</ul>
</blockquote>
</div>
<div class="section" id="p0009r5-pre-2018-03-jacksonville-mailing">
<h2>1.6&nbsp;&nbsp;&nbsp;P0009r5 : Pre 2018-03-Jacksonville Mailing</h2>
<p><a class="reference external" href="http://wiki.edg.com/bin/view/Wg21albuquerque/P0009">LEWG review of P0009r4 at 2017-11-Albuquerque meeting</a></p>
<p><strong>LEWG Poll</strong>: We should be able to index with span&lt;int type[N]&gt; (in addition to array).</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<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><strong>LEWG Poll</strong>: We should be able to index with 1d <tt class="docutils literal">mdspan</tt>.</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>0</td>
<td>8</td>
<td>7</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>LEWG Poll</strong>: We should put the requirement on &quot;rank() &lt;= N&quot; back to &quot;rank() == N&quot;.</p>
<p><em>Unanimous consent</em></p>
<p><strong>LEWG Poll</strong>: 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><strong>Changes from P0009r4</strong>:</p>
<blockquote>
<ul class="simple">
<li>Removed <cite>nullptr</cite> constructor.</li>
<li>Added constexpr to indexing operator.</li>
<li>Indexing operator requires that <tt class="docutils literal">rank() == <span class="pre">sizeof...(indices)</span></tt>.</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 &quot;see below&quot; to make it normative.</li>
</ul>
</blockquote>
<div class="section" id="related-activity">
<h3>1.6.1&nbsp;&nbsp;&nbsp;Related Activity</h3>
<p>Related <a class="reference external" href="http://wiki.edg.com/bin/view/Wg21albuquerque/P0546">LEWG review of P0546r1 at 2017-11-Albuquerque meeting</a></p>
<p><strong>LEWG Poll</strong>: <tt class="docutils literal">span</tt> should specify the dynamic extent as the element type of the first template parameter rather than the (current) second template parameter</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>5</td>
<td>3</td>
<td>2</td>
<td>2</td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>LEWG Poll</strong>: <tt class="docutils literal">span</tt> should support the addition of access properties variadic template parameters</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<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 (<a class="reference external" href="https://wg21.link/P0900">P0900</a>)
discussing how the variadic properties will work.</p>
</div>
</div>
<div class="section" id="p0009r6-pre-2018-06-rapperswil-mailing">
<h2>1.7&nbsp;&nbsp;&nbsp;P0009r6 : Pre 2018-06-Rapperswil Mailing</h2>
<p>P0009r5 was not taken up at 2018-03-Jacksonville meeting.
Related <a class="reference external" href="http://wiki.edg.com/bin/view/Wg21jacksonville2018/P0900">LEWG review of P0900 at 2018-03-Jacksonville meeting</a></p>
<p><strong>LEWG Poll</strong>: We want the ability to customize the access to elements of span
(ability to restrict, etc):</p>
<pre class="code c++ literal-block">
<span class="name">span</span><span class="operator">&lt;</span><span class="name">T</span><span class="punctuation">,</span> <span class="name">N</span><span class="punctuation">,</span> <span class="name">Accessor</span><span class="operator">=</span><span class="punctuation">...</span><span class="operator">&gt;</span>
</pre>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>1</td>
<td>1</td>
<td>1</td>
<td>2</td>
<td>8</td>
</tr>
</tbody>
</table>
<p><strong>LEWG Poll</strong>: We want the customization of basic_mdspan to be two
concepts <tt class="docutils literal">Mapper</tt> and <tt class="docutils literal">Accessor</tt> (akin to <tt class="docutils literal">Allocator</tt> design).</p>
<pre class="code c++ literal-block">
<span class="name">basic_mdspan</span><span class="operator">&lt;</span><span class="name">T</span><span class="punctuation">,</span> <span class="name">Extents</span><span class="punctuation">,</span> <span class="name">Mapper</span><span class="punctuation">,</span> <span class="name">Accessor</span><span class="operator">&gt;</span>
<span class="name">mdspan</span><span class="operator">&lt;</span><span class="name">T</span><span class="punctuation">,</span> <span class="name">N</span><span class="punctuation">...</span><span class="operator">&gt;</span>
</pre>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>3</td>
<td>4</td>
<td>5</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>
<p><strong>LEWG Poll</strong>: We want the customization of basic_mdspan to be an arbitrary
(and potentially user-extensible) list of properties.</p>
<pre class="code c++ literal-block">
<span class="name">basic_mdspan</span><span class="operator">&lt;</span><span class="name">T</span><span class="punctuation">,</span> <span class="name">Extents</span><span class="punctuation">,</span> <span class="name">Properties</span><span class="punctuation">...</span><span class="operator">&gt;</span>
</pre>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">SF</th>
<th class="head">F</th>
<th class="head">N</th>
<th class="head">A</th>
<th class="head">SA</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>1</td>
<td>2</td>
<td>2</td>
<td>6</td>
<td>2</td>
</tr>
</tbody>
</table>
<p><strong>Changes from P0009r5 due to related LEWG reviews</strong>:</p>
<blockquote>
<ul class="simple">
<li>Replaced variadic property list with <em>extents</em>, <em>layout mapping</em>, and <em>accessor</em> properties.</li>
<li>Incorporated <a class="reference external" href="https://wg21.link/P0454r1">P0454r1</a>.
- Added accessor policy concept.
- Renamed <tt class="docutils literal">mdspan</tt> to <tt class="docutils literal">basic_mdspan</tt>.
- Added a <tt class="docutils literal">mdspan</tt> alias to <tt class="docutils literal">basic_mdspan</tt>.</li>
</ul>
</blockquote>
</div>
</div>
<div class="section" id="description">
<h1>2&nbsp;&nbsp;&nbsp;Description</h1>
<p>The proposed polymorphic multidimensional array reference (<tt class="docutils literal">mdspan</tt>)
defines types and functions for mapping indices from the <strong>domain</strong>,
a <strong>multidimensional index space</strong>,
to the <strong>codomain</strong>, elements of a contiguous span of objects.
A multidimensional index space is defined as the
Cartesian product of integer extents,
<strong>[0..N0) X [0..N1) X [0..N2) ...</strong>.
An <tt class="docutils literal">mdspan</tt> has two policies: the <strong>layout mapping</strong> and the <strong>accessor</strong>.
The layout mapping specifies the formula, and properties of the formula,
for mapping a multi-index from the domain to an element in the codomain.
The accessor is an extension point that allows modification of how
elements are accessed.
For example, the Accessors paper (P0367) proposed a rich set of potential access properties.</p>
<p><strong>A multidimensional array is not an array-of-array-of-array-of-array...</strong></p>
<p>The multidimensional array abstraction has been fundamental
to numerical computations for over five decades.
However, the C/C++ language provides only a one dimensional array
abstraction which can be composed into array-of-array-of-array... types.
While such types have some similarity to multidimensional arrays they
do not provide adequate multidimensional array functionality
of this proposal.
Two critical functionality differences are
(1) multiple dynamic extents and
(2) polymorphic mapping of multi-indices to element objects.</p>
<p><strong>Optimized Implementation of Layout Mapping</strong></p>
<p>The layout mapping of a multi-index intended to be an O(1) <cite>constexpr</cite>
operation that is trivially inlined and optimized.
Note that FORTRAN compilers' optimizations include
loop invariant code motion, including partial evaluation
of multi-index layout mappings when indices are loop-invariant.</p>
</div>
<div class="section" id="multidimensional-array-and-subarray-proposal">
<h1>3&nbsp;&nbsp;&nbsp;Multidimensional Array and Subarray Proposal</h1>
<div class="section" id="add-to-same-section-and-header-as-span">
<h2>3.1&nbsp;&nbsp;&nbsp;Add to same section and header as <strong>span</strong></h2>
<pre class="code c++ literal-block">
<span class="keyword">namespace</span> <span class="name">std</span> <span class="punctuation">{</span>

  <span class="keyword reserved">inline</span> <span class="keyword">constexpr</span> <span class="keyword type">ptrdiff_t</span> <span class="name">dynamic_extent</span> <span class="operator">=</span> <span class="operator">-</span><span class="literal number integer">1</span><span class="punctuation">;</span> <span class="comment single">// as per span
</span>
  <span class="comment single">// Multidimensional extents:
</span>  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">...</span> <span class="name">StaticExtents</span> <span class="operator">&gt;</span>
  <span class="keyword">class</span> <span class="name class">extents</span> <span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">...</span> <span class="name">LHS</span> <span class="punctuation">,</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">...</span> <span class="name">RHS</span> <span class="operator">&gt;</span>
  <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="keyword">operator</span> <span class="operator">==</span> <span class="punctuation">(</span> <span class="name">extents</span><span class="operator">&lt;</span><span class="name">LHS</span><span class="punctuation">...</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">lhs</span> <span class="punctuation">,</span> <span class="name">extents</span><span class="operator">&lt;</span><span class="name">RHS</span><span class="punctuation">...</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">rhs</span> <span class="punctuation">)</span> <span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">...</span> <span class="name">LHS</span> <span class="punctuation">,</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">...</span> <span class="name">RHS</span> <span class="operator">&gt;</span>
  <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="keyword">operator</span> <span class="operator">!=</span> <span class="punctuation">(</span> <span class="name">extents</span><span class="operator">&lt;</span><span class="name">LHS</span><span class="punctuation">...</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">lhs</span> <span class="punctuation">,</span> <span class="name">extents</span><span class="operator">&lt;</span><span class="name">RHS</span><span class="punctuation">...</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">rhs</span> <span class="punctuation">)</span> <span class="punctuation">;</span>

  <span class="comment single">// Layout mapping of multidimensional extents:
</span>  <span class="keyword">class</span> <span class="name class">layout_right</span> <span class="punctuation">;</span>
  <span class="keyword">class</span> <span class="name class">layout_left</span> <span class="punctuation">;</span>
  <span class="keyword">class</span> <span class="name class">layout_stride</span> <span class="punctuation">;</span>

  <span class="comment single">// Multidimensional span:
</span>  <span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">ElementType</span><span class="punctuation">,</span>
            <span class="keyword">typename</span> <span class="name">Extents</span><span class="punctuation">,</span>
            <span class="keyword">typename</span> <span class="name">LayoutPolicy</span> <span class="operator">=</span> <span class="name">layout_right</span><span class="punctuation">,</span>
            <span class="keyword">typename</span> <span class="name">AccessorPolicy</span> <span class="operator">=</span> <span class="name">accessor_basic</span><span class="operator">&gt;</span>
  <span class="keyword">class</span> <span class="name class">basic_mdspan</span><span class="punctuation">;</span>

  <span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">class</span> <span class="name class">T</span><span class="punctuation">,</span> <span class="keyword type">ptrdiff_t</span><span class="punctuation">...</span> <span class="name">Extents</span><span class="operator">&gt;</span>
  <span class="keyword">using</span> <span class="name">mdspan</span> <span class="operator">=</span> <span class="name">basic_mdspan</span><span class="operator">&lt;</span><span class="name">T</span><span class="punctuation">,</span> <span class="name">extents</span><span class="operator">&lt;</span><span class="name">Extents</span><span class="punctuation">...</span><span class="operator">&gt;&gt;</span><span class="punctuation">;</span>

  <span class="comment single">// return type of subspan free function is an mdspan
</span>  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">typename</span> <span class="name">ElementType</span> <span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">Extents</span><span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">LayoutPolicy</span> <span class="punctuation">,</span>
            <span class="keyword">typename</span> <span class="name">AccessorPolicy</span> <span class="punctuation">,</span> <span class="keyword">typename</span> <span class="punctuation">...</span> <span class="name">SliceSpecifiers</span> <span class="operator">&gt;</span>
    <span class="comment single">// for exposition only:
</span>    <span class="name">detail</span><span class="operator">::</span><span class="name">subspan_deduction_t</span><span class="operator">&lt;</span> <span class="name">basic_mdspan</span><span class="operator">&lt;</span><span class="name">ElementType</span><span class="punctuation">,</span> <span class="name">Properties</span><span class="punctuation">...</span><span class="operator">&gt;</span><span class="punctuation">,</span><span class="name">SliceSpecifiers</span><span class="punctuation">...</span><span class="operator">&gt;</span>
  <span class="name">subspan</span><span class="punctuation">(</span> <span class="name">basic_mdspan</span><span class="operator">&lt;</span> <span class="name">ElementType</span><span class="punctuation">,</span> <span class="name">Extents</span> <span class="punctuation">,</span> <span class="name">LayoutPolicy</span> <span class="punctuation">,</span> <span class="name">AccessorPolicy</span> <span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">,</span> <span class="name">SliceSpecifiers</span> <span class="punctuation">...</span> <span class="punctuation">)</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

  <span class="comment single">// tag supporting subspan
</span>  <span class="keyword">struct</span> <span class="name">all_type</span> <span class="punctuation">{};</span>
  <span class="keyword reserved">inline</span> <span class="keyword">constexpr</span> <span class="name">all_type</span> <span class="name">all</span> <span class="operator">=</span> <span class="name">all_type</span><span class="punctuation">{};</span>
<span class="punctuation">}</span>
</pre>
<!--  -->
<p>The <tt class="docutils literal">basic_mdspan</tt> class maps a multi-index within a multi-index <strong>domain</strong>
to a reference an element the <strong>codomain</strong> span.</p>
<p>The <tt class="docutils literal">subspan</tt> free function generates an <tt class="docutils literal">basic_mdspan</tt> with a domain contained
within the input <tt class="docutils literal">basic_mdspan</tt> domain and codomain contained within the input
<tt class="docutils literal">basic_mdspan</tt> codomain.</p>
<p>The <em>detail::subspan_deduction_t</em> template class is not proposed and
appears for exposition only.
An implementation metafunction of this form is necessary
to deduce the specific <tt class="docutils literal">basic_mdspan</tt> return type of the <tt class="docutils literal">subspan</tt> function.</p>
</div>
<div class="section" id="class-template-basic-mdspan">
<h2>3.2&nbsp;&nbsp;&nbsp;Class template <tt class="docutils literal">basic_mdspan</tt></h2>
<pre class="code c++ literal-block">
<span class="keyword">namespace</span> <span class="name">std</span> <span class="punctuation">{</span>

<span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">typename</span> <span class="name">ElementType</span> <span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">Extents</span> <span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">LayoutPolicy</span> <span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">AccessorPolicy</span> <span class="operator">&gt;</span>
<span class="keyword">class</span> <span class="name class">basic_mdspan</span> <span class="punctuation">{</span>
<span class="keyword">public</span><span class="operator">:</span>
  <span class="comment single">// Domain and codomain types
</span>
  <span class="keyword">using</span> <span class="name">layout</span>   <span class="operator">=</span> <span class="name">LayoutPolicy</span><span class="punctuation">;</span>
  <span class="keyword">using</span> <span class="name">mapping</span>  <span class="operator">=</span> <span class="keyword">typename</span> <span class="name">layout</span><span class="operator">::</span><span class="name">mapping</span><span class="operator">&lt;</span><span class="name">Extents</span><span class="operator">&gt;</span><span class="punctuation">;</span>
  <span class="keyword">using</span> <span class="name">accessor</span> <span class="operator">=</span> <span class="keyword">typename</span> <span class="name">AccessorPolicy</span><span class="operator">::</span><span class="name">accessor</span><span class="operator">&lt;</span><span class="name">ElementType</span><span class="operator">&gt;</span><span class="punctuation">;</span>

  <span class="keyword">using</span> <span class="name">element_type</span>    <span class="operator">=</span> <span class="keyword">typename</span> <span class="name">accessor</span><span class="operator">::</span><span class="name">value_type</span><span class="punctuation">;</span>
  <span class="keyword">using</span> <span class="name">value_type</span>      <span class="operator">=</span> <span class="name">remove_cv_t</span><span class="operator">&lt;</span><span class="name">element_type</span><span class="operator">&gt;</span><span class="punctuation">;</span>
  <span class="keyword">using</span> <span class="name">index_type</span>      <span class="operator">=</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">;</span>
  <span class="keyword">using</span> <span class="name">difference_type</span> <span class="operator">=</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">;</span>
  <span class="keyword">using</span> <span class="name">pointer</span>         <span class="operator">=</span> <span class="keyword">typename</span> <span class="name">accessor</span><span class="operator">::</span><span class="name">pointer</span><span class="punctuation">;</span>
  <span class="keyword">using</span> <span class="name">reference</span>       <span class="operator">=</span> <span class="keyword">typename</span> <span class="name">accessor</span><span class="operator">::</span><span class="name">reference</span><span class="punctuation">;</span>

  <span class="comment single">// Standard constructors, assignments, and destructor
</span>
  <span class="operator">~</span><span class="name">basic_mdspan</span><span class="punctuation">()</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="keyword">constexpr</span> <span class="name function">basic_mdspan</span><span class="punctuation">()</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>
  <span class="keyword">constexpr</span> <span class="name function">basic_mdspan</span><span class="punctuation">(</span><span class="name">basic_mdspan</span><span class="operator">&amp;&amp;</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
  <span class="keyword">constexpr</span> <span class="name function">basic_mdspan</span><span class="punctuation">(</span><span class="name">basic_mdspan</span> <span class="keyword">const</span><span class="operator">&amp;</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
  <span class="name">basic_mdspan</span><span class="operator">&amp;</span> <span class="keyword">operator</span><span class="operator">=</span><span class="punctuation">(</span><span class="name">basic_mdspan</span><span class="operator">&amp;&amp;</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
  <span class="name">basic_mdspan</span><span class="operator">&amp;</span> <span class="keyword">operator</span><span class="operator">=</span><span class="punctuation">(</span><span class="name">basic_mdspan</span> <span class="keyword">const</span><span class="operator">&amp;</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>

  <span class="comment single">// Constructor and assignment for assignable basic_mdspan
</span>
  <span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">UT</span><span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">UExt</span><span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">ULayPol</span><span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">UAccPol</span><span class="operator">&gt;</span>
  <span class="keyword">constexpr</span> <span class="name">basic_mdspan</span><span class="punctuation">(</span><span class="keyword">const</span> <span class="name">basic_mdspan</span><span class="operator">&lt;</span><span class="name">UT</span><span class="punctuation">,</span> <span class="name">UExt</span><span class="punctuation">,</span> <span class="name">ULayPol</span><span class="punctuation">,</span> <span class="name">UAccPol</span><span class="operator">&gt;&amp;</span> <span class="name">other</span><span class="punctuation">)</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

  <span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">UType</span><span class="punctuation">,</span> <span class="keyword">typename</span> <span class="punctuation">...</span> <span class="name">UProp</span><span class="operator">&gt;</span>
  <span class="keyword">constexpr</span> <span class="name">basic_mdspan</span><span class="operator">&amp;</span> <span class="keyword">operator</span><span class="operator">=</span><span class="punctuation">(</span><span class="keyword">const</span> <span class="name">basic_mdspan</span><span class="operator">&lt;</span><span class="name">UT</span><span class="punctuation">,</span> <span class="name">UExt</span><span class="punctuation">,</span> <span class="name">ULayPol</span><span class="punctuation">,</span> <span class="name">UAccPol</span><span class="operator">&gt;&amp;</span> <span class="name">other</span><span class="punctuation">)</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

  <span class="comment single">// Wrapping constructors
</span>
  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">IndexType</span> <span class="operator">&gt;</span>
  <span class="keyword">explicit</span> <span class="keyword">constexpr</span> <span class="name">basic_mdspan</span><span class="punctuation">(</span><span class="name">pointer</span><span class="punctuation">,</span> <span class="name">IndexType</span> <span class="punctuation">...</span> <span class="name">DynamicExtents</span> <span class="punctuation">)</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">IndexType</span> <span class="operator">&gt;</span>
  <span class="keyword">explicit</span> <span class="keyword">constexpr</span> <span class="name">basic_mdspan</span><span class="punctuation">(</span><span class="name">span</span><span class="operator">&lt;</span><span class="name">element_type</span><span class="operator">&gt;</span><span class="punctuation">,</span> <span class="name">IndexType</span> <span class="punctuation">...</span> <span class="name">DynamicExtents</span> <span class="punctuation">)</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="name class">IndexType</span> <span class="punctuation">,</span> <span class="keyword type">size_t</span> <span class="name">N</span> <span class="operator">&gt;</span>
  <span class="keyword">explicit</span> <span class="keyword">constexpr</span> <span class="name">basic_mdspan</span><span class="punctuation">(</span><span class="name">pointer</span><span class="punctuation">,</span> <span class="name">array</span><span class="operator">&lt;</span><span class="name">IndexType</span><span class="punctuation">,</span><span class="name">N</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">DynamicExtents</span> <span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="name class">IndexType</span> <span class="punctuation">,</span> <span class="keyword type">size_t</span> <span class="name">N</span> <span class="operator">&gt;</span>
  <span class="keyword">explicit</span> <span class="keyword">constexpr</span> <span class="name">basic_mdspan</span><span class="punctuation">(</span><span class="name">span</span><span class="operator">&lt;</span><span class="name">element_type</span><span class="operator">&gt;</span><span class="punctuation">,</span> <span class="name">array</span><span class="operator">&lt;</span><span class="name">IndexType</span><span class="punctuation">,</span><span class="name">N</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">DynamicExtents</span> <span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="comment single">// Mapping domain multi-index to access codomain element
</span>
  <span class="keyword">constexpr</span> <span class="name">reference</span> <span class="keyword">operator</span><span class="punctuation">[](</span> <span class="name">index_type</span> <span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">IndexType</span> <span class="operator">&gt;</span>
  <span class="keyword">constexpr</span> <span class="name">reference</span> <span class="keyword">operator</span><span class="punctuation">()(</span> <span class="name">IndexType</span> <span class="punctuation">...</span> <span class="name">indices</span> <span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="name class">IndexType</span> <span class="punctuation">,</span> <span class="keyword type">size_t</span> <span class="name">N</span> <span class="operator">&gt;</span>
  <span class="keyword">constexpr</span> <span class="name">reference</span> <span class="keyword">operator</span><span class="punctuation">()(</span> <span class="name">array</span><span class="operator">&lt;</span><span class="name">IndexType</span><span class="punctuation">,</span><span class="name">N</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">indices</span> <span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

  <span class="comment single">// Observers of the domain multi-index space
</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">int</span> <span class="name function">rank</span><span class="punctuation">()</span> <span class="name">noexecept</span> <span class="punctuation">;</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">int</span> <span class="name function">rank_dynamic</span><span class="punctuation">()</span> <span class="name">noexecept</span> <span class="punctuation">;</span>

  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">static_extent</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">)</span> <span class="name">noexecept</span> <span class="punctuation">;</span>

  <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">extent</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">)</span> <span class="keyword">const</span> <span class="name">noexecept</span> <span class="punctuation">;</span>

  <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">size</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="name">noexecept</span> <span class="punctuation">;</span>

  <span class="comment single">// Observers of the codomain:
</span>
  <span class="keyword">constexpr</span> <span class="name">span</span><span class="operator">&lt;</span><span class="name">element_type</span><span class="operator">&gt;</span> <span class="name">span</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="name">noexecept</span> <span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">IndexType</span> <span class="operator">&gt;</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name">required_span_size</span><span class="punctuation">(</span> <span class="name">IndexType</span> <span class="punctuation">...</span> <span class="name">DynamicExtents</span> <span class="punctuation">);</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">IndexType</span> <span class="punctuation">,</span> <span class="keyword type">size_t</span> <span class="name">N</span> <span class="operator">&gt;</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name">required_span_size</span><span class="punctuation">(</span> <span class="name">array</span><span class="operator">&lt;</span><span class="name">IndexType</span><span class="punctuation">,</span><span class="name">N</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">DynamicExtents</span> <span class="punctuation">);</span>

  <span class="comment single">// Observers of the mapping : domain -&gt; codomain
</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name">is_always_unique</span>     <span class="operator">=</span> <span class="name">mapping</span><span class="operator">::</span><span class="name">is_always_unique</span> <span class="punctuation">;</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name">is_always_contiguous</span> <span class="operator">=</span> <span class="name">mapping</span><span class="operator">::</span><span class="name">is_always_contiguous</span> <span class="punctuation">;</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name">is_always_strided</span>    <span class="operator">=</span> <span class="name">mapping</span><span class="operator">::</span><span class="name">is_always_strided</span> <span class="punctuation">;</span>

  <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name function">is_unique</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>
  <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name function">is_contiguous</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>
  <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name function">is_strided</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">stride</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">)</span> <span class="keyword">const</span> <span class="punctuation">;</span>

<span class="keyword">private</span><span class="operator">:</span>
  <span class="comment single">// exposition only
</span>  <span class="name">accesor</span>      <span class="name">access</span><span class="punctuation">;</span>
  <span class="name">mapping</span>      <span class="name">map</span><span class="punctuation">;</span>
  <span class="name">pointer_type</span> <span class="name">ptr</span><span class="punctuation">;</span>
<span class="punctuation">};</span>

<span class="punctuation">}</span>
</pre>
<!--  -->
<div class="section" id="template-arguments">
<h3>3.2.1&nbsp;&nbsp;&nbsp;Template Arguments</h3>
<p><tt class="docutils literal">ElementType</tt> is a (possibly cv-qualified) non-array object type denoting the element type of the array.</p>
<p><tt class="docutils literal">Extents</tt> is an instantiation of <tt class="docutils literal">extents</tt>.</p>
<p><tt class="docutils literal">LayoutPolicy</tt> is a type that satisfies the <tt class="docutils literal">LayoutPolicy</tt> requirements.</p>
<p><tt class="docutils literal">AccessorPolicy</tt> is a type that satisfies the <tt class="docutils literal">AccessorPolicy</tt> requirements.</p>
</div>
<div class="section" id="domain-observers">
<h3>3.2.2&nbsp;&nbsp;&nbsp;Domain Observers</h3>
<p>The multi-index domain space is the Cartesian product of the extents:
<tt class="docutils literal"><span class="pre">[0..extent(0))</span> X <span class="pre">[0..extent(1))</span> X ... X <span class="pre">[0..extent(rank()</span> - 1))</tt>.
Each extent may be statically (at compile time) or dynamically (at runtime)
specified.</p>
<p><tt class="docutils literal">static constexpr int <span class="pre">rank();</span></tt></p>
<blockquote>
Returns: Rank of the multi-index domain.</blockquote>
<p><tt class="docutils literal">static constexpr int <span class="pre">rank_dynamic();</span></tt></p>
<blockquote>
Returns: number of extents that are dynamic.</blockquote>
<p><tt class="docutils literal">static constexpr index_type static_extent(int r);</tt></p>
<blockquote>
<p>Requires: <tt class="docutils literal">0 &lt;= r</tt>.</p>
<p>Returns: If <tt class="docutils literal">0 &lt;= r &lt; rank()</tt> the statically specified extent.
A statically declared extent of <tt class="docutils literal">dynamic_extent</tt>
denotes that the extent is dynamic.
If <tt class="docutils literal">rank() &lt;= r</tt> then <tt class="docutils literal">static_extent(r) == 1</tt>.</p>
</blockquote>
<p><tt class="docutils literal">constexpr index_type extent(int r) const ;</tt></p>
<blockquote>
<p>Requires: <tt class="docutils literal">0 &lt;= r</tt>.</p>
<p>Returns: If <tt class="docutils literal">0 &lt;= r &lt; rank()</tt> the extent of coordinate <tt class="docutils literal">r</tt>.
If <tt class="docutils literal">rank() &lt;= r</tt> then <tt class="docutils literal">extent(r) == 1</tt>.</p>
</blockquote>
<p><tt class="docutils literal">constexpr index_type size() const ;</tt></p>
<blockquote>
Returns: Product of <tt class="docutils literal">extent(r)</tt> where <tt class="docutils literal">0 &lt;= r &lt; rank()</tt>.</blockquote>
</div>
<div class="section" id="codomain-observers">
<h3>3.2.3&nbsp;&nbsp;&nbsp;Codomain Observers</h3>
<p>Not all elements of the codomain may be accessible through the layout mapping;
i.e., the range of the mapping is contained within the codomain but may not
be equal to the codomain.</p>
<p><tt class="docutils literal">constexpr span&lt;element_type&gt; span() const ;</tt></p>
<blockquote>
Returns: An <tt class="docutils literal">span</tt> for the codomain.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class ... IndexType &gt;</tt></div>
<div class="line"><tt class="docutils literal">static constexpr index_type required_span_size( IndexType ... DynamicExtents );</tt></div>
</div>
<blockquote>
<p>Requires:</p>
<ul class="simple">
<li><tt class="docutils literal">rank_dynamic() == <span class="pre">sizeof...(DynamicExtents)</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">is_integral_type_v&lt;IndexType&gt;...</span></tt>.</li>
<li>Let <tt class="docutils literal">DynamicExtents[ith]</tt> denote the ith coordinate of
<tt class="docutils literal"><span class="pre">DynamicExtents...</span></tt>. <tt class="docutils literal">0 &lt;= DynamicExtents[ith]</tt> for
<tt class="docutils literal">0 &lt;= ith &lt; rank_dynanic()</tt>.</li>
</ul>
<p>Returns: The minimum size of the codomain to support the multi-index domain
defined by the merging of <tt class="docutils literal">DynamicExents</tt> with <tt class="docutils literal">StaticExtents</tt>.</p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class ... IndexType , size_t N &gt;</tt></div>
<div class="line"><tt class="docutils literal">static constexpr index_type required_span_size( array&lt;IndexType,N&gt; const &amp; DynamicExtents );</tt></div>
</div>
<blockquote>
<p>Requires:</p>
<ul class="simple">
<li><tt class="docutils literal">rank_dynamic() == N</tt></li>
<li><tt class="docutils literal"><span class="pre">is_integral_type_v&lt;IndexType&gt;...</span></tt></li>
<li><tt class="docutils literal">0 &lt;= DynamicExtents[ith]</tt> for <tt class="docutils literal">0 &lt;= ith &lt; rank_dynanic()</tt></li>
</ul>
<p>Returns: The minimum size of the codomain to support the multi-index domain
defined by the merging of <tt class="docutils literal">DynamicExents</tt> with <tt class="docutils literal">StaticExtents</tt>.</p>
</blockquote>
</div>
<div class="section" id="constructors-assignments-destructor">
<h3>3.2.4&nbsp;&nbsp;&nbsp;Constructors, assignments, destructor</h3>
<p><tt class="docutils literal">constexpr <span class="pre">basic_mdspan();</span></tt></p>
<blockquote>
Effect: Construct a <em>null</em> <tt class="docutils literal">mdspan</tt> with codomain
<tt class="docutils literal">span() == <span class="pre">span&lt;element_type&gt;()</span></tt>
and <tt class="docutils literal">extent(r) == 0</tt> for all dynamic extents.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template &lt;typename UT, typename UExt, typename ULayPol, typename UAccPol&gt;</tt></div>
<div class="line">``  constexpr basic_mdspan(const basic_mdspan&lt;UT, UExt, ULayPol, UAccPol&gt;&amp; other) noexcept;``</div>
<div class="line"><tt class="docutils literal">template &lt;typename UType, typename ... UProp&gt;</tt></div>
<div class="line">``  constexpr basic_mdspan&amp; operator=(const basic_mdspan&lt;UT, UExt, ULayPol, UAccPol&gt;&amp; other) noexcept;``</div>
</div>
<blockquote>
<p>Requires:
Given <tt class="docutils literal">using V = basic_mdspan&lt;ElementType, Extents, LayoutPolicy, AccessorPolicy&gt;</tt> and
<tt class="docutils literal">using U = basic_mdspan&lt;UT, UExt, ULayPol, UAccPol&gt;</tt> then</p>
<div class="line-block">
<div class="line"><tt class="docutils literal">is_assignable_v&lt;typename <span class="pre">V::pointer,</span> typename <span class="pre">U::pointer&gt;</span> == true</tt> ,</div>
<div class="line"><tt class="docutils literal"><span class="pre">V::rank()</span> == <span class="pre">U::rank()</span></tt> ,</div>
<div class="line"><tt class="docutils literal"><span class="pre">V::static_extent(r)</span> == <span class="pre">U::static_extent(r)</span></tt> or <tt class="docutils literal"><span class="pre">V::static_extent(r)</span> == dynamic_extent</tt> for <tt class="docutils literal">0 &lt;= r &lt; <span class="pre">V::rank()</span></tt> ,</div>
<div class="line">compatibility of layout mapping</div>
</div>
<p>Effect: <tt class="docutils literal">* this</tt> has equal domain, equal codomain, and
equivalent mapping.</p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class ... IndexType &gt;</tt></div>
<div class="line"><tt class="docutils literal">constexpr basic_mdspan( pointer ptr , IndexType ... DynamicExtents) noexcept</tt></div>
</div>
<blockquote>
<p>Requires:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">sizeof...(DynamicExtents)</span> == rank_dynamic()</tt></li>
<li><tt class="docutils literal"><span class="pre">is_integral_type_v&lt;IndexType&gt;...</span></tt></li>
<li>The ith coordinate of <tt class="docutils literal"><span class="pre">DynamicExtents...</span></tt>,
denoted as <tt class="docutils literal">DynamicExtents[ith]</tt>, is <tt class="docutils literal">0 &lt;= DynamicExtents[ith]</tt>.</li>
<li><tt class="docutils literal">[ ptr , ptr + <span class="pre">required_span_size(DynamicExtents...)</span> )</tt>,
shall be a valid contiguous span of elements.</li>
</ul>
<p>Effects:
This <em>wrapping constructor</em> constructs <tt class="docutils literal">* this</tt>
with domain's dynamic extents equal to <tt class="docutils literal"><span class="pre">DynamicExtents...</span></tt>
and codomain equal to
<tt class="docutils literal">span&lt;element_type&gt;( ptr , <span class="pre">required_span_size(DynamicExtents...)</span> )</tt></p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class IndexType , size_t N &gt;</tt></div>
<div class="line"><tt class="docutils literal">constexpr basic_mdspan( pointer ptr , array&lt;IndexType,N&gt; const &amp; DynamicExtents) noexcept</tt></div>
</div>
<blockquote>
<p>Requires:</p>
<ul class="simple">
<li><tt class="docutils literal">N == rank_dynamic()</tt></li>
<li><tt class="docutils literal"><span class="pre">is_integral_type_v&lt;IndexType&gt;...</span></tt></li>
<li><tt class="docutils literal">0 &lt;= DynamicExtents[ith]</tt></li>
<li>The span of elements denoted by <tt class="docutils literal">[ ptr , ptr + required_span_size(DynamicExtents) )</tt>,
shall be a valid contiguous span of elements.</li>
</ul>
<p>Effects:
This <em>wrapping constructor</em> constructs <tt class="docutils literal">* this</tt>
with domain's dynamic extents equal to <tt class="docutils literal">DynamicExtents[ith].</tt>
and codomain equal to
<tt class="docutils literal">span&lt;element_type&gt;( ptr , required_span_size(DynamicExtents) )</tt></p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class ... IndexType &gt;</tt></div>
<div class="line"><tt class="docutils literal">constexpr basic_mdspan( span&lt;element_type&gt; s , IndexType ... DynamicExtents) noexcept</tt></div>
</div>
<blockquote>
<p>Requires:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">sizeof...(DynamicExtents)</span> == rank_dynamic()</tt></li>
<li><tt class="docutils literal"><span class="pre">is_integral_type_v&lt;IndexType&gt;...</span></tt></li>
<li>The ith coordinate of <tt class="docutils literal"><span class="pre">DynamicExtents...</span></tt>,
denoted as <tt class="docutils literal">DynamicExtents[ith]</tt>, is <tt class="docutils literal">0 &lt;= DynamicExtents[ith]</tt></li>
<li><tt class="docutils literal"><span class="pre">required_span_size(DynamicExtents...)</span> &lt;= s.size()</tt></li>
</ul>
<p>Effects: This <em>wrapping constructor</em> constructs <tt class="docutils literal">* this</tt>
with domain's dynamic extents equal to <tt class="docutils literal"><span class="pre">DynamicExtents...</span></tt>
and codomain equal to
<tt class="docutils literal">span&lt;element_type&gt;( ptr , <span class="pre">required_span_size(DynamicExtents...)</span> )</tt></p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class IndexType , size_t N &gt;</tt></div>
<div class="line"><tt class="docutils literal">constexpr basic_mdspan( span&lt;element_type&gt; s , array&lt;IndexType,N&gt; const &amp; DynamicExtents) noexcept</tt></div>
</div>
<blockquote>
<p>Requires:</p>
<ul class="simple">
<li><tt class="docutils literal">N == rank_dynamic()</tt></li>
<li><tt class="docutils literal"><span class="pre">is_integral_type_v&lt;IndexType&gt;...</span></tt></li>
<li><tt class="docutils literal">0 &lt;= DynamicExtents[ith]</tt></li>
<li><tt class="docutils literal">required_span_size(DynamicExtents) &lt;= s.size()</tt></li>
</ul>
<p>Effects: This <em>wrapping constructor</em> constructs <tt class="docutils literal">* this</tt>
with domain's dynamic extents equal to <tt class="docutils literal">DynamicExtents[ith]</tt>
and codomain equal to
<tt class="docutils literal">span&lt;element_type&gt;( ptr , required_span_size(DynamicExtents[ith]) )</tt></p>
</blockquote>
</div>
<div class="section" id="mapping-domain-multi-index-to-access-elements-in-the-codomain">
<h3>3.2.5&nbsp;&nbsp;&nbsp;Mapping domain multi-index to access elements in the codomain</h3>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class ... IndexType &gt;</tt></div>
<div class="line"><tt class="docutils literal">reference <span class="pre">operator()(</span> IndexType ... indices ) const noexcept</tt></div>
</div>
<blockquote>
<p>Requires: <tt class="docutils literal">indices</tt> is a multi-index in the domain:</p>
<ul class="simple">
<li><tt class="docutils literal">rank() == <span class="pre">sizeof...(IndexType)</span></tt></li>
<li>The ith coordinate of <tt class="docutils literal"><span class="pre">indices...</span></tt>, denoted as <tt class="docutils literal">indices[ith]</tt>,
is in the domain: <tt class="docutils literal">0 &lt;= indices[ith] &lt; extent(ith)</tt>.</li>
</ul>
<p>Returns: A <tt class="docutils literal">reference</tt> to the element mapped to by <tt class="docutils literal"><span class="pre">indices...</span></tt>.</p>
</blockquote>
<p><tt class="docutils literal">reference <span class="pre">operator[](</span> index_type index ) const noexcept</tt></p>
<blockquote>
Effects: Equivalent to <tt class="docutils literal">return <span class="pre">(*this)(index);</span></tt></blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class IndexType , size_t N &gt;</tt></div>
<div class="line"><tt class="docutils literal">reference <span class="pre">operator()(</span> array&lt;IndexType,N&gt; const &amp; indices ) const noexcept</tt></div>
</div>
<blockquote>
Effects: Equivalent to <tt class="docutils literal"><span class="pre">(*this)(indices[0],</span> ... <span class="pre">indices[N-1]);</span></tt>.</blockquote>
</div>
<div class="section" id="layout-mapping-observers">
<h3>3.2.6&nbsp;&nbsp;&nbsp;Layout Mapping Observers</h3>
<div class="line-block">
<div class="line"><tt class="docutils literal">static constexpr bool is_always_unique =</tt></div>
<div class="line"><tt class="docutils literal">constexpr bool is_unique() const noexcept ;</tt></div>
</div>
<blockquote>
A layout mapping is <em>unique</em> if each multi-index in the domain
is mapped to a unique element in the codomain.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">static constexpr bool is_always_contiguous =</tt></div>
<div class="line"><tt class="docutils literal">constexpr bool is_contiguous() const noexcept ;</tt></div>
</div>
<blockquote>
<p>A layout mapping is <em>contiguous</em> if the codomain elements accessed through
the layout mapping form a contiguous span.</p>
<p>A layout mapping that is both unique and contiguous is <em>bijective</em>,
and as a consequence <tt class="docutils literal">size() == <span class="pre">span().size()</span></tt>.</p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">static constexpr bool is_always_strided =</tt></div>
<div class="line"><tt class="docutils literal">constexpr bool is_strided() const noexcept ;</tt></div>
</div>
<blockquote>
A <em>strided</em> layout has constant striding between multi-index coordinates.
Let <tt class="docutils literal">A</tt> be an <tt class="docutils literal">mdspan</tt> and <tt class="docutils literal"><span class="pre">indices_V...</span></tt> and <tt class="docutils literal"><span class="pre">indices_U...</span></tt> be multi-indices
in the domain space such that all coordinates are equal except for
the <em>ith</em> coordinate where <tt class="docutils literal">indices_V[ith] = indices_U[ith] + 1</tt>.
Then <tt class="docutils literal">stride(ith) = distance(&amp; <span class="pre">A(indices_V...)</span> - &amp; A( <span class="pre">indices_U...</span> )</tt>
is constant for all valid coordinates.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; typename IntegralType &gt;</tt></div>
<div class="line"><tt class="docutils literal">constexpr index_type stride( IntegralType index ) const noexcept</tt></div>
</div>
<blockquote>
<p>Requires: <tt class="docutils literal">is_strided()</tt>.</p>
<p>Returns: When <tt class="docutils literal">r &lt; rank()</tt> the distance between elements
when the index of coordinate <tt class="docutils literal">r</tt> is incremented by one, otherwise 0.</p>
</blockquote>
</div>
</div>
<div class="section" id="class-template-extents">
<h2>3.3&nbsp;&nbsp;&nbsp;Class template <tt class="docutils literal">extents</tt></h2>
<p>An extents objects defines the lengths of the dimensions of an <tt class="docutils literal">mdspan</tt>.</p>
<pre class="code c++ literal-block">
<span class="keyword">namespace</span> <span class="name">std</span> <span class="punctuation">{</span>

<span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">...</span> <span class="name">StaticExtents</span> <span class="operator">&gt;</span>
<span class="keyword">class</span> <span class="name class">extents</span> <span class="punctuation">{</span>
<span class="keyword">public</span><span class="operator">:</span>

  <span class="keyword">using</span> <span class="name">index_type</span> <span class="operator">=</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">;</span>

  <span class="comment single">// Constructors/assignment/destructor
</span>
  <span class="operator">~</span><span class="name">extents</span><span class="punctuation">()</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
  <span class="keyword">constexpr</span> <span class="name function">extents</span><span class="punctuation">();</span>
  <span class="keyword">constexpr</span> <span class="name function">extents</span><span class="punctuation">(</span><span class="name">extents</span> <span class="keyword">const</span> <span class="operator">&amp;</span><span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
  <span class="keyword">constexpr</span> <span class="name function">extents</span><span class="punctuation">(</span><span class="name">extents</span> <span class="operator">&amp;&amp;</span><span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
  <span class="name">extents</span> <span class="operator">&amp;</span> <span class="keyword">operator</span> <span class="operator">=</span> <span class="punctuation">(</span><span class="name">extents</span> <span class="keyword">const</span> <span class="operator">&amp;</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
  <span class="name">extents</span> <span class="operator">&amp;</span> <span class="keyword">operator</span> <span class="operator">=</span> <span class="punctuation">(</span><span class="name">extents</span> <span class="operator">&amp;&amp;</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">IndexType</span> <span class="operator">&gt;</span>
  <span class="keyword">constexpr</span> <span class="name">extents</span><span class="punctuation">(</span> <span class="name">IndexType</span> <span class="punctuation">...</span> <span class="name">DynamicExtents</span> <span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="comment single">// Observers of the index space domain:
</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">int</span> <span class="name function">rank</span><span class="punctuation">()</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>
  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">int</span> <span class="name function">rank_dynamic</span><span class="punctuation">()</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">static_extent</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">extent</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>
<span class="punctuation">};</span>

<span class="punctuation">}</span>
</pre>
<!--  -->
<p>The multi-index domain space is the Cartesian product of the extents:
<tt class="docutils literal"><span class="pre">[0..extent(0))</span> X <span class="pre">[0..extent(1))</span> X ... X <span class="pre">[0..extent(rank()</span> - 1))</tt>.
Each extent may be statically (at compile time) or dynamically (at runtime)
specified.</p>
<p><tt class="docutils literal">template&lt; ptrdiff_t <span class="pre">StaticExtents...</span> &gt;</tt></p>
<blockquote>
Requires: <tt class="docutils literal">0 &lt;= StaticExtent</tt> or <tt class="docutils literal">dynamic_extent == StaticExtent</tt></blockquote>
<p><tt class="docutils literal">static constexpr int <span class="pre">rank();</span></tt></p>
<blockquote>
Returns: Rank of the multi-index domain, <tt class="docutils literal"><span class="pre">sizeof...(StaticExtents)</span></tt>.</blockquote>
<p><tt class="docutils literal">static constexpr int <span class="pre">rank_dynamic();</span></tt></p>
<blockquote>
Returns: number of <tt class="docutils literal"><span class="pre">StaticExtents...</span></tt> that are <tt class="docutils literal">dynamic_extent</tt>.</blockquote>
<p><tt class="docutils literal">static constexpr index_type static_extent(int r);</tt></p>
<blockquote>
<p>Requires: <tt class="docutils literal">0 &lt;= r</tt>.</p>
<p>Returns: If <tt class="docutils literal">0 &lt;= r &lt; rank()</tt> the statically specified extent.
A statically declared extent of <tt class="docutils literal">dynamic_extent</tt>
denotes that the extent is dynamic.
If <tt class="docutils literal">rank() &lt;= r</tt> then <tt class="docutils literal">static_extent(r) == 1</tt>.</p>
</blockquote>
<p><tt class="docutils literal">constexpr index_type extent(int r) const ;</tt></p>
<blockquote>
<p>Requires: <tt class="docutils literal">0 &lt;= r</tt>.</p>
<p>Returns: If <tt class="docutils literal">0 &lt;= r &lt; rank()</tt> the extent of coordinate <tt class="docutils literal">r</tt>.
If <tt class="docutils literal">rank() &lt;= r</tt> then <tt class="docutils literal">extent(r) == 1</tt>.</p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; ptrdiff_t ... LHS , ptrdiff_t ... RHS &gt;</tt></div>
<div class="line"><tt class="docutils literal">constexpr bool operator == ( <span class="pre">extents&lt;LHS...&gt;</span> const &amp; lhs , <span class="pre">extents&lt;RHS...&gt;</span> const &amp; rhs ) ;</tt></div>
</div>
<blockquote>
Returns: <tt class="docutils literal">lhs.rank() == rhs.rank()</tt> and
<tt class="docutils literal">lhs.extent(r) == rhs.extent(r)</tt> for <tt class="docutils literal">0 &lt;= r &lt; lhs.rank()</tt>.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; ptrdiff_t ... LHS , ptrdiff_t ... RHS &gt;</tt></div>
<div class="line"><tt class="docutils literal">constexpr bool operator != ( <span class="pre">extents&lt;LHS...&gt;</span> const &amp; lhs , <span class="pre">extents&lt;RHS...&gt;</span> const &amp; rhs ) ;</tt></div>
</div>
<blockquote>
Returns: <tt class="docutils literal">! ( lhs == rhs )</tt></blockquote>
</div>
<div class="section" id="subspan">
<h2>3.4&nbsp;&nbsp;&nbsp;<tt class="docutils literal">subspan</tt></h2>
<pre class="code c++ literal-block">
<span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">ElementType</span><span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">Extents</span><span class="punctuation">,</span>
          <span class="keyword">typename</span> <span class="name">LayoutPolicy</span><span class="punctuation">,</span> <span class="keyword">typename</span> <span class="name">AccessorPolicy</span><span class="operator">&gt;</span>
<span class="comment single">// for exposition only:
</span><span class="name">detail</span><span class="operator">::</span><span class="name">subspan_deduction_t</span><span class="operator">&lt;</span><span class="name">basic_mdspan</span><span class="operator">&lt;</span><span class="name">ElementType</span><span class="punctuation">,</span> <span class="name">Extents</span><span class="punctuation">,</span> <span class="name">LayoutPolicy</span><span class="punctuation">,</span> <span class="name">AccessorPolicy</span><span class="operator">&gt;</span><span class="punctuation">,</span> <span class="name">SliceSpecifiers</span><span class="punctuation">...</span><span class="operator">&gt;</span>
<span class="name">subspan</span><span class="punctuation">(</span><span class="keyword">const</span> <span class="name">basic_mdspan</span><span class="operator">&lt;</span><span class="name">ElementType</span><span class="punctuation">,</span> <span class="name">Extents</span><span class="punctuation">,</span> <span class="name">LayoutPolicy</span><span class="punctuation">,</span> <span class="name">AccessorPolicy</span><span class="operator">&gt;&amp;</span> <span class="name">U</span> <span class="punctuation">,</span> <span class="name">SliceSpecifiers</span><span class="punctuation">...</span> <span class="name">slices</span><span class="punctuation">)</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>
</pre>
<!--  -->
<blockquote>
<p>The <tt class="docutils literal"><span class="pre">detail::subspan_deduction_t</span></tt> is for exposition only to indicate
that the implementation is required to deduce the resulting
<tt class="docutils literal">basic_mdspan</tt> type from <tt class="docutils literal">U</tt> and <tt class="docutils literal"><span class="pre">slices...</span></tt>.</p>
<p>Let the <em>ith</em> element of <tt class="docutils literal"><span class="pre">slices...</span></tt> be denoted by <tt class="docutils literal">slices[ith]</tt>.</p>
<p>Let an <em>integral range</em> be denoted by any of the following.</p>
<ul class="simple">
<li>an <tt class="docutils literal">initializer_list&lt;T&gt;</tt> of integral type <tt class="docutils literal">T</tt> and size 2</li>
<li>a <tt class="docutils literal">pair&lt;T,T&gt;</tt> of integral type <tt class="docutils literal">T</tt></li>
<li>a <tt class="docutils literal">tuple&lt;T,T&gt;</tt>  of integral type <tt class="docutils literal">T</tt></li>
<li>an <tt class="docutils literal">array&lt;T,2&gt;</tt> of integral type <tt class="docutils literal">T</tt></li>
<li><tt class="docutils literal">all</tt> to denote the range <tt class="docutils literal">[0 .. U.extent(ith))</tt></li>
</ul>
<p>If <tt class="docutils literal">slices[ith]</tt> is an integral range then let
<tt class="docutils literal">begin(slices[ith])</tt> be the beginning of the integral range
<tt class="docutils literal">end(slices[ith])</tt> be the end of the integral range.
If <tt class="docutils literal">slices[ith]</tt> is an integral value then let
<tt class="docutils literal">begin(slices[ith]) == slices[ith]</tt> and
<tt class="docutils literal">end(slices[ith]) == <span class="pre">slices[ith]+1</span></tt>.</p>
<p>Requires:</p>
<ul class="simple">
<li><tt class="docutils literal">U.rank() == <span class="pre">sizeof...(slices)</span></tt>.</li>
<li>Each element of the <tt class="docutils literal"><span class="pre">slices...</span></tt> pack is either an <em>integral range</em>
or an <em>integral value</em>.</li>
<li><tt class="docutils literal">0 &lt;= begin(slices[ith]) &lt;= end(slices[ith]) &lt;= U.extent(ith)</tt>.</li>
</ul>
<p>Returns:
A <tt class="docutils literal">basic_mdspan V</tt> with a domain contained within the domain of <tt class="docutils literal">U</tt> ,
codomain contained within the codomain of <tt class="docutils literal">U</tt> ,
<tt class="docutils literal">V.rank()</tt> is the number of integral ranges in <tt class="docutils literal"><span class="pre">slices...</span></tt> ,
<tt class="docutils literal">U( <span class="pre">begin(slices)...</span> )</tt> refers to the same codomain element
refered to by the mapping the zero-index of <tt class="docutils literal">V</tt> ,
each integral value in <tt class="docutils literal"><span class="pre">slices...</span></tt> contracts the corresponding
extent of <tt class="docutils literal">U</tt>.</p>
<p>[Note: An illustrative example</p>
</blockquote>
<pre class="code c++ literal-block">
<span class="comment single">// given U.rank() == 4
</span><span class="keyword type">void</span> <span class="name function">foo</span><span class="punctuation">(</span> <span class="name">basic_mdspan</span><span class="operator">&lt;</span> <span class="name">ElementType</span> <span class="punctuation">,</span> <span class="name">Extents</span> <span class="punctuation">,</span> <span class="name">LayoutPolicy</span> <span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">U</span> <span class="punctuation">)</span>
<span class="punctuation">{</span>
  <span class="keyword">auto</span> <span class="name">V</span> <span class="operator">=</span> <span class="name">subspan</span><span class="punctuation">(</span> <span class="name">U</span> <span class="punctuation">,</span> <span class="name">make_pair</span><span class="punctuation">(</span><span class="literal number integer">1</span><span class="punctuation">,</span><span class="name">U</span><span class="punctuation">.</span><span class="name">extent</span><span class="punctuation">(</span><span class="literal number integer">0</span><span class="punctuation">)</span><span class="operator">-</span><span class="literal number integer">1</span><span class="punctuation">)</span> <span class="punctuation">,</span> <span class="literal number integer">1</span> <span class="punctuation">,</span> <span class="name">make_pair</span><span class="punctuation">(</span><span class="literal number integer">2</span><span class="punctuation">,</span><span class="name">U</span><span class="punctuation">.</span><span class="name">extent</span><span class="punctuation">(</span><span class="literal number integer">2</span><span class="punctuation">)</span><span class="operator">-</span><span class="literal number integer">2</span> <span class="punctuation">);</span>
  <span class="name">assert</span><span class="punctuation">(</span> <span class="name">V</span><span class="punctuation">.</span><span class="name">extent</span><span class="punctuation">(</span><span class="literal number integer">0</span><span class="punctuation">)</span> <span class="operator">==</span> <span class="name">U</span><span class="punctuation">.</span><span class="name">extent</span><span class="punctuation">(</span><span class="literal number integer">0</span><span class="punctuation">)</span> <span class="operator">-</span> <span class="literal number integer">2</span> <span class="punctuation">);</span>
  <span class="name">assert</span><span class="punctuation">(</span> <span class="name">V</span><span class="punctuation">.</span><span class="name">extent</span><span class="punctuation">(</span><span class="literal number integer">1</span><span class="punctuation">)</span> <span class="operator">==</span> <span class="name">U</span><span class="punctuation">.</span><span class="name">extent</span><span class="punctuation">(</span><span class="literal number integer">2</span><span class="punctuation">)</span> <span class="operator">-</span> <span class="literal number integer">2</span> <span class="punctuation">);</span>
  <span class="name">assert</span><span class="punctuation">(</span> <span class="operator">&amp;</span> <span class="name">V</span><span class="punctuation">(</span><span class="literal number integer">0</span><span class="punctuation">,</span><span class="literal number integer">0</span><span class="punctuation">)</span> <span class="operator">==</span> <span class="name">U</span><span class="punctuation">(</span><span class="literal number integer">1</span><span class="punctuation">,</span><span class="literal number integer">1</span><span class="punctuation">,</span><span class="literal number integer">2</span><span class="punctuation">,</span><span class="literal number integer">2</span><span class="punctuation">)</span> <span class="punctuation">);</span>
  <span class="name">assert</span><span class="punctuation">(</span> <span class="operator">&amp;</span> <span class="name">V</span><span class="punctuation">(</span><span class="literal number integer">1</span><span class="punctuation">,</span><span class="literal number integer">0</span><span class="punctuation">)</span> <span class="operator">==</span> <span class="name">U</span><span class="punctuation">(</span><span class="literal number integer">2</span><span class="punctuation">,</span><span class="literal number integer">1</span><span class="punctuation">,</span><span class="literal number integer">2</span><span class="punctuation">,</span><span class="literal number integer">2</span><span class="punctuation">)</span> <span class="punctuation">);</span>
  <span class="name">assert</span><span class="punctuation">(</span> <span class="operator">&amp;</span> <span class="name">V</span><span class="punctuation">(</span><span class="literal number integer">0</span><span class="punctuation">,</span><span class="literal number integer">1</span><span class="punctuation">)</span> <span class="operator">==</span> <span class="name">U</span><span class="punctuation">(</span><span class="literal number integer">1</span><span class="punctuation">,</span><span class="literal number integer">1</span><span class="punctuation">,</span><span class="literal number integer">3</span><span class="punctuation">,</span><span class="literal number integer">2</span><span class="punctuation">)</span> <span class="punctuation">);</span>
<span class="punctuation">}</span>
</pre>
<!--  -->
<blockquote>
--end note]</blockquote>
<div class="section" id="slice-specifier-with-static-extent">
<h3>3.4.1&nbsp;&nbsp;&nbsp;Slice Specifier with Static Extent</h3>
<p>The proposed <tt class="docutils literal">initializer_list</tt>, <tt class="docutils literal">pair</tt>, <tt class="docutils literal">tuple</tt>, and
<tt class="docutils literal">array</tt> slice specifier types define dynamic extents.
When the <tt class="docutils literal">all</tt> slice specifier references a static
extent then the subspan's corresponding extent should be
static as well.
When the extent of a slice specifier is statically known
there should be a slice specifier type to explicitly
express this knowledge.
Such a static extent slice specifier type is to-be-done.</p>
</div>
</div>
<div class="section" id="layout-policy-requirements">
<h2>3.5&nbsp;&nbsp;&nbsp;Layout Policy Requirements</h2>
<p>A <tt class="docutils literal">basic_mdspan</tt> maps multi-indices from the domain to
reference elements in the codomain by composing a <em>layout mapping</em>
with a span of elements.
The layout mapping is an extension point such that an <tt class="docutils literal">basic_mdspan</tt> may be
instantiated with non-standard layout mappings.</p>
<div class="section" id="predefined-standard-layout-policies">
<h3>3.5.1&nbsp;&nbsp;&nbsp;Predefined, Standard Layout Policies</h3>
<p>The <tt class="docutils literal">layout_right</tt> property denotes the C/C++ standard
multidimensional array index mapping
where the right-most extent is stride one and strides increase right-to-left
as the product of extents.</p>
<p>The <tt class="docutils literal">layout_left</tt> property denotes the FORTRAN standard
multidimensional array index mapping
where the left-most extent is stride one and strides increase left-to-right
as the product of extents.</p>
<p>The <tt class="docutils literal">layout_stride</tt> property denotes a multidimensional array index mapping
with arbitrary strides for each extent.
This is the layout for subarrays that are not contiguous.</p>
<p>The three standard layouts have the following layout mapping traits.</p>
<p><tt class="docutils literal">layout_right</tt> ; i.e., the C/C++ standard layout</p>
<blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">is_always_unique == true</tt></div>
<div class="line"><tt class="docutils literal">is_always_contiguous == true</tt></div>
<div class="line"><tt class="docutils literal">is_always_strided == true</tt></div>
<div class="line">When <tt class="docutils literal">0 &lt; rank()</tt> then <tt class="docutils literal"><span class="pre">stride(rank()-1)</span> == 1</tt> .</div>
<div class="line">When <tt class="docutils literal">1 &lt; rank()</tt> then <tt class="docutils literal"><span class="pre">stride(r-1)</span> = stride(r) * extent(r)</tt> for <tt class="docutils literal">0 &lt; r &lt; rank()</tt> ..</div>
</div>
<p>For rank-two arrays (a.k.a., matrices) this is also known as <em>row major</em> layout.</p>
</blockquote>
<p><tt class="docutils literal">layout_left</tt> ; i.e., the FORTRAN standard layout</p>
<blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">is_always_unique == true</tt></div>
<div class="line"><tt class="docutils literal">is_always_contiguous == true</tt></div>
<div class="line"><tt class="docutils literal">is_always_strided == true</tt></div>
<div class="line">When <tt class="docutils literal">0 &lt; rank()</tt> then <tt class="docutils literal">stride(0) == 1</tt> .</div>
<div class="line">When <tt class="docutils literal">1 &lt; rank()</tt> then <tt class="docutils literal">stride(r) = <span class="pre">stride(r-1)</span> * <span class="pre">extent(r-1)</span></tt> for <tt class="docutils literal">0 &lt; r &lt; rank()</tt> ..</div>
</div>
<p>For rank-two arrays (a.k.a., matrices) this is also known as <em>column major</em> layout.</p>
</blockquote>
<p><tt class="docutils literal">layout_stride</tt> ; i.e., an arbitrary <strong>strided</strong> layout</p>
<blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">is_always_unique == false</tt></div>
<div class="line"><tt class="docutils literal">is_always_contiguous == false</tt></div>
<div class="line"><tt class="docutils literal">is_always_strided == true</tt></div>
</div>
</blockquote>
</div>
<div class="section" id="concept-for-extensible-layout-mapping">
<h3>3.5.2&nbsp;&nbsp;&nbsp;Concept for Extensible Layout Mapping</h3>
<p>A <em>layout</em> class conforms to the following interface such that an
<tt class="docutils literal">mdspan</tt> can compose the layout mapping with its <tt class="docutils literal">mdspan</tt>
codomain element reference generation.</p>
<pre class="code c++ literal-block">
<span class="keyword">class</span> <span class="name class">layout_property</span> <span class="comment multiline">/* exposition only */</span> <span class="punctuation">{</span>
<span class="keyword">public</span><span class="operator">:</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">...</span> <span class="name">StaticExtents</span> <span class="operator">&gt;</span>
  <span class="keyword">class</span> <span class="name class">mapping</span> <span class="punctuation">{</span>
  <span class="keyword">public</span><span class="operator">:</span>

    <span class="comment single">// Domain types
</span>
    <span class="keyword">using</span> <span class="name">index_type</span> <span class="operator">=</span> <span class="keyword type">ptrdiff_t</span> <span class="punctuation">;</span>

    <span class="comment single">// Constructors, copy, assignment, and destructor
</span>
    <span class="operator">~</span><span class="name">mapping</span><span class="punctuation">()</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
    <span class="keyword">constexpr</span> <span class="name function">mapping</span><span class="punctuation">()</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
    <span class="keyword">constexpr</span> <span class="name function">mapping</span><span class="punctuation">(</span><span class="name">mapping</span> <span class="keyword">const</span><span class="operator">&amp;</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>
    <span class="name">mapping</span><span class="operator">&amp;</span> <span class="keyword">operator</span><span class="operator">=</span><span class="punctuation">(</span><span class="name">mapping</span> <span class="keyword">const</span><span class="operator">&amp;</span><span class="punctuation">)</span> <span class="keyword">noexcept</span> <span class="operator">=</span> <span class="keyword">default</span> <span class="punctuation">;</span>

    <span class="comment single">// Observers of domain
</span>
    <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">int</span> <span class="name function">rank</span><span class="punctuation">()</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>
    <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">int</span> <span class="name function">rank_dynamic</span><span class="punctuation">()</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

    <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">static_extent</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">)</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

    <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">extent</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

    <span class="comment single">// Observers of the codomain: [0..required_span_size())
</span>
    <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">required_span_size</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

    <span class="comment single">// Observers of the mapping from domain to codomain
</span>
    <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name">is_always_unique</span>     <span class="operator">=</span> <span class="comment multiline">/* unspecified */</span> <span class="punctuation">;</span>
    <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name">is_always_contiguous</span> <span class="operator">=</span> <span class="comment multiline">/* unspecified */</span> <span class="punctuation">;</span>
    <span class="keyword">static</span> <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name">is_always_strided</span>    <span class="operator">=</span> <span class="comment multiline">/* unspecified */</span> <span class="punctuation">;</span>

    <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name function">is_unique</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>
    <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name function">is_contiguous</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>
    <span class="keyword">constexpr</span> <span class="keyword type">bool</span> <span class="name function">is_strided</span><span class="punctuation">()</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

    <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="name function">stride</span><span class="punctuation">(</span><span class="keyword type">int</span><span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>

    <span class="comment single">// Mapping domain index to access codomain element
</span>
    <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">IndexType</span> <span class="operator">&gt;</span>
    <span class="keyword">constexpr</span> <span class="name">index_type</span> <span class="keyword">operator</span><span class="punctuation">()(</span> <span class="name">IndexType</span> <span class="punctuation">...</span> <span class="name">indices</span> <span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>
  <span class="punctuation">};</span>
<span class="punctuation">};</span>
</pre>
<!--  -->
<p><tt class="docutils literal">template&lt; ptrdiff_t ... StaticExtents &gt; class mapping</tt></p>
<blockquote>
<p>Requires:
Let <tt class="docutils literal">StaticExtents[ith]</tt> be the ith member of the pack.
<tt class="docutils literal">StaticExtents[ith] == dynamic_extent</tt> or
<tt class="docutils literal">0 &lt;= StaticExtents[ith]</tt>.</p>
<p>Effects: Defines the domain index space where
<tt class="docutils literal">rank() == <span class="pre">sizeof...(StaticExtents)</span></tt> and
each <tt class="docutils literal">StaticExtents[ith] == dynamic_extent</tt>
denotes that <tt class="docutils literal">ith</tt> extent coordinate is a dynamic extent.</p>
</blockquote>
<p><tt class="docutils literal">constexpr <span class="pre">mapping();</span></tt></p>
<blockquote>
Effects:
If <tt class="docutils literal">static_extent(i) != dynamic_extent</tt> then
<tt class="docutils literal">extent(i) == static_extent(i)</tt>
otherwise <tt class="docutils literal">extent(i) == 0</tt>.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">explicit constexpr mapping( <span class="pre">index_type...</span> ) noexcept;</tt></div>
<div class="line"><tt class="docutils literal">explicit constexpr mapping(</tt> <em>layout_property</em> <tt class="docutils literal">const&amp;) noexcept;</tt></div>
</div>
<blockquote>
Constructors, assignment operators, and destructor requires and effects
correspond to the corresponding members of <tt class="docutils literal">basic_mdspan</tt> .</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">static constexpr int rank() noexcept;</tt></div>
<div class="line"><tt class="docutils literal">static constexpr int rank_dynamic() noexcept;</tt></div>
<div class="line"><tt class="docutils literal">constexpr index_type extent(int) const noexcept;</tt></div>
<div class="line"><tt class="docutils literal">constexpr index_type static_extent(int) noexcept;</tt></div>
<div class="line"><br /></div>
<div class="line"><tt class="docutils literal">template &lt; class ... IndexType &gt;</tt></div>
<div class="line"><tt class="docutils literal">static constexpr index_type required_span_size( IndexType ... DynamicExtents ) noexcept;</tt></div>
<div class="line"><tt class="docutils literal">static constexpr index_type required_span_size( *layout_property* const &amp; ) noexcept;</tt></div>
<div class="line"><br /></div>
<div class="line"><tt class="docutils literal">static constexpr bool is_always_unique&nbsp;&nbsp;&nbsp;&nbsp; = /* unspecified */ ;</tt></div>
<div class="line"><tt class="docutils literal">static constexpr bool is_always_contiguous = /* unspecified */ ;</tt></div>
<div class="line"><tt class="docutils literal">static constexpr bool is_always_strided&nbsp;&nbsp;&nbsp; = /* unspecified */ ;</tt></div>
<div class="line"><br /></div>
<div class="line"><tt class="docutils literal">constexpr bool is_unique() const noexcept;</tt></div>
<div class="line"><tt class="docutils literal">constexpr bool is_contiguous() const noexcept;</tt></div>
<div class="line"><tt class="docutils literal">constexpr bool is_strided() noexcept;</tt></div>
<div class="line"><br /></div>
<div class="line"><tt class="docutils literal">constexpr index_type stride(int) const noexcept;</tt></div>
</div>
<blockquote>
Domain, codomain, and mapping observers requires and effects
correspond to the corresponding members of <tt class="docutils literal">basic_mdspan</tt> .</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">constexpr index_type required_span_size() const noexcept;</tt></div>
</div>
<blockquote>
Returns: The upper bound of the codomain one dimensional index space
<tt class="docutils literal"><span class="pre">[0..required_span_size())</span></tt>.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class ... IndexType &gt;</tt></div>
<div class="line"><tt class="docutils literal">constexpr index_type <span class="pre">operator()(IndexType</span> ... indices) const noexcept;</tt></div>
</div>
<blockquote>
<p>Requires: <tt class="docutils literal">rank() == <span class="pre">sizeof...(indices)</span></tt> and
<tt class="docutils literal">0 &lt;= indices[ith] &lt; extent(ith)</tt>.</p>
<p>Returns: Result of mapping <tt class="docutils literal"><span class="pre">indices...</span></tt> from the domain
multidimensional index space to the codomain one dimensional index space
<tt class="docutils literal"><span class="pre">[0..required_span_size())</span></tt>.</p>
</blockquote>
</div>
</div>
<div class="section" id="accessor-policy-requirements">
<h2>3.6&nbsp;&nbsp;&nbsp;Accessor Policy Requirements</h2>
<!-- Straight from P0454 -->
<p>An <em>accessor policy</em> is a class that contains an <em>accessor</em>, a nested
template class.</p>
<p>An accessor takes a pointer to an array and an index and returns a
reference to the element of the array at the given index. <tt class="docutils literal">basic_mdspan</tt>
is parameterized in terms of accessor.</p>
<p>An accessor fulfills the <tt class="docutils literal">DefaultConstructible</tt> and <tt class="docutils literal">CopyAssignable</tt>
requirements.</p>
<p>In Table �:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal">AP</tt> denotes an accessor policy.</li>
<li><tt class="docutils literal">A</tt> denotes an accessor.</li>
<li><tt class="docutils literal">a</tt> denotes a value of type <tt class="docutils literal">A</tt>.</li>
<li><tt class="docutils literal">p</tt> denotes a pointer of type <tt class="docutils literal">T</tt>.</li>
<li><tt class="docutils literal">i</tt> denotes an integer.</li>
</ul>
</blockquote>
<table border="1" class="docutils">
<colgroup>
<col width="13%" />
<col width="17%" />
<col width="26%" />
<col width="45%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Expression</th>
<th class="head">Return Type</th>
<th class="head">Operational Semantics</th>
<th class="head">Requirements/Note</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">AP::accessor&lt;T&gt;</span></tt></td>
<td><tt class="docutils literal">A</tt></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">A::pointer</span></tt></td>
<td>A <tt class="docutils literal">RandomAccessIterator</tt></td>
<td>&nbsp;</td>
<td><em>Requires:</em> This iterator type's value type shall be convertible to <tt class="docutils literal">T</tt>.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">A::reference</span></tt></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><em>Requires:</em> This type shall be convertible to <tt class="docutils literal">T</tt>.</td>
</tr>
<tr><td><tt class="docutils literal">a(p, i)</tt></td>
<td><tt class="docutils literal">reference</tt></td>
<td><em>Effects:</em> Equivalent to <tt class="docutils literal">return p[i];</tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="accessor-policies">
<h2>3.7&nbsp;&nbsp;&nbsp;Accessor Policies</h2>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="name">accessor_basic</span>
<span class="punctuation">{</span>
  <span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">T</span><span class="operator">&gt;</span>
  <span class="keyword">struct</span> <span class="name">accessor</span>
  <span class="punctuation">{</span>
    <span class="keyword">using</span> <span class="name">pointer</span>      <span class="operator">=</span> <span class="name">T</span><span class="operator">*</span><span class="punctuation">;</span>
    <span class="keyword">using</span> <span class="name">reference</span>    <span class="operator">=</span> <span class="name">T</span><span class="operator">&amp;</span><span class="punctuation">;</span>

    <span class="keyword">constexpr</span> <span class="name">reference</span> <span class="name function">operator</span><span class="punctuation">()(</span><span class="name">pointer</span> <span class="name">p</span><span class="punctuation">,</span> <span class="keyword type">ptrdiff_t</span> <span class="name">i</span><span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>
  <span class="punctuation">};</span>
<span class="punctuation">};</span>
</pre>
<!--  -->
<pre class="code c++ literal-block">
<span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">Index</span><span class="operator">&gt;</span>
<span class="keyword">constexpr</span> <span class="name">reference</span> <span class="keyword">operator</span><span class="punctuation">()(</span><span class="name">pointer</span> <span class="name">p</span><span class="punctuation">,</span> <span class="name">Index</span> <span class="name">i</span><span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="punctuation">;</span>
</pre>
<!--  -->
<p><em>Effects:</em> Equivalent to <tt class="docutils literal">return p[i];</tt></p>
</div>
</div>
<div class="section" id="next-steps">
<h1>4&nbsp;&nbsp;&nbsp;Next Steps</h1>
<ul class="simple">
<li>Wording editing as per guidance from LWG.</li>
<li>Address verbose syntax when using <tt class="docutils literal"><span class="pre">std::dynamic_extent</span></tt>
to denote dynamic extents; <em>e.g.</em>, perhaps alias to <tt class="docutils literal"><span class="pre">std::dyn</span></tt>.</li>
</ul>
</div>
<div class="section" id="related-work">
<h1>5&nbsp;&nbsp;&nbsp;Related Work</h1>
<p><a class="reference external" href="https://issues.isocpp.org/show_bug.cgi?id=80">LEWG issue</a></p>
<p><strong>Previous paper:</strong></p>
<ul class="simple">
<li><a class="reference external" href="https://wg21.link/N4355">N4355</a></li>
</ul>
<p><strong>P0860 : Access Policy Generating Proxy Reference</strong></p>
<p>The <tt class="docutils literal">reference</tt> type may be a proxy for accessing an <tt class="docutils literal">element_type</tt> object.
For example, the <em>atomic</em> <tt class="docutils literal">AccessorPolicy</tt> in <strong>P0860</strong> defines
<tt class="docutils literal"><span class="pre">AccessorPolicy::accessor&lt;T&gt;::reference</span></tt> to be <tt class="docutils literal">atomic_ref&lt;T&gt;</tt> from <strong>P0019</strong>.</p>
<p><strong>Related papers:</strong></p>
<ul class="simple">
<li><strong>P0122</strong> : span: bounds-safe views for sequences of objects
The <tt class="docutils literal">mdspan</tt> codomain concept of <em>span</em> is well-aligned with this paper.</li>
<li><strong>P0367</strong> : Accessors
The P0367 Accessors proposal includes polymorphic mechanisms for
accessing the memory an object or span of objects.
The <tt class="docutils literal">AccessPolicy</tt> extension point in this proposal is intended
to include such memory access properties.</li>
<li><strong>P0331</strong> : Motivation and Examples for Multidimensional Array</li>
<li><strong>P0332</strong> : Relaxed Incomplete Multidimensional Array Type Declaration</li>
<li><strong>P0454</strong> : Wording for a Minimal <tt class="docutils literal">mdspan</tt>
Included proposed modification of <tt class="docutils literal">span</tt> to better align
<tt class="docutils literal">span</tt> with <tt class="docutils literal">mdspan</tt>.</li>
<li><strong>P0546</strong> : Preparing <tt class="docutils literal">span</tt> for the future
Proposed modification of <tt class="docutils literal">span</tt></li>
<li><strong>P0856</strong> : Restric access property for <tt class="docutils literal">mdspan</tt> and <tt class="docutils literal">span</tt></li>
<li><strong>P0860</strong> : atomic access policy for <tt class="docutils literal">mdspan</tt></li>
<li><strong>P0900</strong> : An Ontology of Properties for <tt class="docutils literal">mdspan</tt></li>
</ul>
</div>
</div>
</body>
</html>
