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

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

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

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

code.sourceCode > span { display: inline; }

div#refs p { padding-left: 32px; text-indent: -32px; }
</style>
  <link href="data:text/html; charset=utf-8;charset=utf-8,%3Chtml%3E%0A%3Chead%3E%0A%3Ctitle%3EBIG%2DIP%20Per%20Request%20Policy%20Resource%20blocked%20page%3C%2Ftitle%3E%0A%3Cstyle%3E%0Abody%2C%20html%20%7B%0A%20%20%20%20padding%3A%200%3B%0A%20%20%20%20margin%3A%200%3B%0A%20%20%20%20height%3A%20100%25%3B%0A%7D%0Atable%2C%20td%2C%20th%2C%20div%20%7B%0A%20%20%20%20border%3A%200%3B%0A%20%20%20%20padding%3A%200%3B%0A%20%20%20%20margin%3A%200%3B%0A%7D%0Abody%2C%20table%2C%20td%2C%20th%2C%20div%2C%20input%2C%20h1%2C%20h2%2C%20h3%2C%20h4%2C%20h5%2C%20h6%20%7B%0A%20%20%20%20font%2Dfamily%20%3A%20Calibri%2C%20Tahoma%2C%20Verdana%2C%20Arial%2C%20Helvetica%2C%20Sans%2DSerif%3B%0A%20%20%20%20color%3A%20%23000000%3B%0A%20%20%20%20text%2Dalign%3A%20center%3B%0A%7D%0Abody%2C%20table%2C%20td%2C%20th%2C%20div%2C%20input%20%7B%0A%20%20%20%20font%2Dsize%20%3A%2014px%3B%0A%7D%0Ah1%2C%20h2%2C%20h3%2C%20h4%2C%20h5%2C%20h6%20%7B%0A%20%20%20%20font%2Dsize%20%3A%2018px%3B%0A%20%20%20%20text%2Ddecoration%3A%20none%3B%0A%20%20%20%20margin%2Dbottom%3A%200px%3B%0A%7D%0Abody%0A%7B%0A%20%20%20%20background%2Dcolor%3A%20%23FFFFFF%3B%0A%7D%0Atable%23page%5Fheader%0A%7B%0A%20%20%20%20width%3A%20100%25%3B%0A%20%20%20%20height%3A%2080px%3B%0A%20%20%20%20background%2Dcolor%3A%20%23FFFFFF%3B%0A%20%20%20%20background%2Drepeat%3A%20repeat%2Dx%3B%0A%7D%0Atable%23main%5Ftable%0A%7B%0A%20%20%20%20width%3A100%25%3B%0A%7D%0A%3C%2Fstyle%3E%0A%3C%2Fhead%3E%0A%0A%3Cscript%20language%3D%22javascript%22%3E%0Afunction%20OnLoad%28%29%20%7B%0A%20%20%20%20var%20category%20%3D%20%22Information%20Technology%22%3B%0A%20%20%20%20var%20categoryDiv%20%3D%20document%2EgetElementById%28%27display%5Fcategory%27%29%3B%0A%20%20%20%20if%20%28category%20%3D%3D%3D%20%22%22%29%20%7B%0A%20%20%20%20%20%20%20%20categoryDiv%2Estyle%2Evisibility%20%3D%20%27hidden%27%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20categoryDiv%2Estyle%2Evisibility%20%3D%20%27visible%27%3B%0A%20%20%20%20%20%20%20%20categoryDiv%2EinnerHTML%20%2B%3D%20%27%3Ctd%3E%27%20%2B%20%22The%20category%20reference%20is%3A%22%20%2B%20%27%20%27%20%2B%20category%20%2B%20%27%3C%2Ftd%3E%27%3B%0A%20%20%20%20%7D%0A%7D%0A%3C%2Fscript%3E%0A%3Cbody%20onload%3D%22OnLoad%28%29%3B%22%3E%0A%20%20%20%20%3Ctable%20id%3D%22page%5Fheader%22%3E%0A%20%20%20%20%20%20%20%20%3Ctr%3E%3Ctd%20style%3D%22padding%2Dleft%3A10px%3B%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ch1%3ETransparent%20proxy%20access%20blocked%2E%20%3Cbr%3E%20Please%20verify%20your%20proxy%20setting%20are%20correct%2E%20%3Cbr%3E%20Contact%20CCHD%20if%20you%20need%20assistance%2E%3C%2Fh1%3E%20%20%20%20%20%20%20%20%3C%2Ftd%3E%3C%2Ftr%3E%0A%20%20%20%20%3C%2Ftable%3E%0A%20%20%20%20%3Ctable%20id%3D%27main%5Ftable%27%3E%0A%20%20%20%20%20%20%20%20%3Ctr%20id%3D%27display%5Fcategory%27%3E%3C%2Ftr%3E%0A%20%20%20%20%3C%2Ftable%3E%0A%3C%2Fbody%3E%0A%3C%2Fhtml%3E%0A" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center"><code>layout_stride</code>
static extents default constructor fix</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>P2763R1</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2023-02-07</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project: </td>
    <td>Programming Language C++<br>
      LWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to: </td>
    <td>
      Christian Trott<br>&lt;<a href="mailto:crtrott@sandia.gov" class="email">crtrott@sandia.gov</a>&gt;<br>
      Damien Lebrun-Grandie<br>&lt;<a href="mailto:lebrungrandt@ornl.gov" class="email">lebrungrandt@ornl.gov</a>&gt;<br>
      Mark Hoemmen<br>&lt;<a href="mailto:mhoemmen@nvidia.com" class="email">mhoemmen@nvidia.com</a>&gt;<br>
      Nevin Liber<br>&lt;<a href="mailto:nliber@anl.gov" class="email">nliber@anl.gov</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#revision-history" id="toc-revision-history"><span class="toc-section-number">1</span> Revision History</a></li>
<li><a href="#revision-1" id="toc-revision-1"><span class="toc-section-number">2</span> Revision 1:</a>
<ul>
<li><a href="#initial-version-2023-01-mailing" id="toc-initial-version-2023-01-mailing"><span class="toc-section-number">2.1</span> Initial Version 2023-01
Mailing</a></li>
</ul></li>
<li><a href="#rationale" id="toc-rationale"><span class="toc-section-number">3</span> Rationale</a></li>
<li><a href="#possible-fixes" id="toc-possible-fixes"><span class="toc-section-number">4</span> Possible Fixes</a>
<ul>
<li><a href="#delete-default-constructor-for-fully-static-extents" id="toc-delete-default-constructor-for-fully-static-extents"><span class="toc-section-number">4.1</span> Delete default constructor for
fully static extents</a></li>
<li><a href="#construct-a-layout_right-equivalent-mapping-for-fully-static-extents" id="toc-construct-a-layout_right-equivalent-mapping-for-fully-static-extents"><span class="toc-section-number">4.2</span> Construct a
<code>layout_right</code> equivalent mapping for fully static
extents</a></li>
<li><a href="#preference-for-resolution" id="toc-preference-for-resolution"><span class="toc-section-number">4.3</span> Preference for Resolution</a></li>
<li><a href="#proposed-wording" id="toc-proposed-wording"><span class="toc-section-number">4.4</span> Proposed Wording</a></li>
</ul></li>
</ul>
</div>
<h1 data-number="1" id="revision-history"><span class="header-section-number">1</span> Revision History<a href="#revision-history" class="self-link"></a></h1>
<h1 data-number="2" id="revision-1"><span class="header-section-number">2</span> Revision 1:<a href="#revision-1" class="self-link"></a></h1>
<ul>
<li>LWG wants the default constructor to behave the same regardless of
whether all the extents are static: that is, it should fill in the
strides in the same way as <code>layout_right::mapping</code>
would.</li>
<li>add precondtion to ensure representability in index type of the
required span size.</li>
</ul>
<h2 data-number="2.1" id="initial-version-2023-01-mailing"><span class="header-section-number">2.1</span> Initial Version 2023-01
Mailing<a href="#initial-version-2023-01-mailing" class="self-link"></a></h2>
<h1 data-number="3" id="rationale"><span class="header-section-number">3</span> Rationale<a href="#rationale" class="self-link"></a></h1>
<p>During work on the padded layouts project an oversight in the
<code>layout_stride</code> definition was discovered for a corner case.
Specifically, the default constructor of a <code>layout_stride</code>
with fully static <code>extents</code> will produce an invalid
mapping.</p>
<p>The default constructor is defaulted, which means that the
<code>array</code> for the <code>strides</code> member will be all
zeros. As such the mappings <code>operator()</code> will return always
zero for a defaulted <code>layout_stride::mapping</code>. In the case of
at least one dynamic extent this is not an issue, because the valid
index space for calling <code>operator()</code> is empty. Thus the
statement that <code>layout_stride::mapping</code> is always unique is
not violated. However for fully static (non zero) extents, the valid
index space is not empty, and thus no precondition is violated if a user
calls <code>operator()</code> with a valid multidimensional index.<br />
</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>layout_stride<span class="op">::</span>mapping<span class="op">&lt;</span>extents<span class="op">&lt;</span><span class="dt">int</span>, <span class="dv">4</span><span class="op">&gt;&gt;</span> map;</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="co">// map.is_unique() == true;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="co">// map(0) == 0; </span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="co">// map(1) == 0;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co">// map(2) == 0;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="co">// map(3) == 0; </span></span></code></pre></div>
<p>Note: this issue does NOT affect mappings with extents of rank zero.
It also does not affect <code>layout_left</code> and
<code>layout_right</code> mappings. Their default constructed mappings
with static extents are fully useable.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>layout_left<span class="op">::</span>mapping<span class="op">&lt;</span>extents<span class="op">&lt;</span><span class="dt">int</span>, <span class="dv">4</span><span class="op">&gt;&gt;</span> map;</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="co">// map.is_unique() == true;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="co">// map(0) == 0; </span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="co">// map(1) == 1;</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="co">// map(2) == 2;</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="co">// map(3) == 3; </span></span></code></pre></div>
<p>We believe that this issue is a defect in the C++23 draft and should
be considered for defect resolution process.</p>
<h1 data-number="4" id="possible-fixes"><span class="header-section-number">4</span> Possible Fixes<a href="#possible-fixes" class="self-link"></a></h1>
<h2 data-number="4.1" id="delete-default-constructor-for-fully-static-extents"><span class="header-section-number">4.1</span> Delete default constructor for
fully static extents<a href="#delete-default-constructor-for-fully-static-extents" class="self-link"></a></h2>
<p>One option is to simply make the default constructor unavailable for
<code>layout_stride</code> mappings of fully static extents.</p>
<p>The wording change would simply add a requires clause to the class
synopsis</p>
<p>In subsection 24.7.3.4.7.1 [mdspan.layout.stride.overview]
replace:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>    <span class="co">// [mdspan.layout.stride.cons], constructors</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span></code></pre></div>
<p>With:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>    <span class="co">// [mdspan.layout.stride.cons], constructors</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>      <span class="kw">requires</span><span class="op">(</span>extents_type<span class="op">::</span>rank_dynamic<span class="op">()&gt;</span><span class="dv">0</span> <span class="op">||</span> extents_type<span class="op">::</span>rank<span class="op">()==</span><span class="dv">0</span><span class="op">)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span></code></pre></div>
<p>Note that this approach mirrors the approach of <code>mdspan</code>
itself, where the default constructor requires
<code>rank_dynamic()&gt;0</code>. For <code>mdspan</code> we can’t avoid
that, since there is no way to generate a valid
<code>data_handle</code>.</p>
<h2 data-number="4.2" id="construct-a-layout_right-equivalent-mapping-for-fully-static-extents"><span class="header-section-number">4.2</span> Construct a
<code>layout_right</code> equivalent mapping for fully static extents<a href="#construct-a-layout_right-equivalent-mapping-for-fully-static-extents" class="self-link"></a></h2>
<p>If one would want to preserve the default constructibility of every
<code>layout_stride</code> mapping, one could create some valid strides
in the case where all extents are static.</p>
<p>Specifically, one could constructs strides such that the resulting
mapping is the standard C-Layout. Conveniently, we can obtain such
strides from a default constructed <code>layout_right</code> mapping
with the same extents.</p>
<p>It would be desirable to preserve the trivial constructibility of
<code>layout_stride</code> mappings for all the cases where that is
still possible.</p>
<p>In subsection 24.7.3.4.7.1 [mdspan.layout.stride.overview]
replace:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>    <span class="co">// [mdspan.layout.stride.cons], constructors</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span></code></pre></div>
<p>With:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>    <span class="co">// [mdspan.layout.stride.cons], constructors</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> </span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>      <span class="kw">requires</span><span class="op">(</span>extents_type<span class="op">::</span>rank_dynamic<span class="op">()&gt;</span><span class="dv">0</span> <span class="op">||</span> extents_type<span class="op">::</span>rank<span class="op">()==</span><span class="dv">0</span><span class="op">)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> </span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">requires</span><span class="op">(</span>extents_type<span class="op">::</span>rank_dynamic<span class="op">()==</span><span class="dv">0</span> <span class="op">&amp;&amp;</span> extents_type<span class="op">::</span>rank<span class="op">()&gt;</span><span class="dv">0</span><span class="op">)</span> <span class="kw">noexcept</span>;</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span></code></pre></div>
<p>Add at the beginning of subsection 24.7.3.4.7.3
[mdspan.layout.stride.cons] insert:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> </span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>      <span class="kw">requires</span><span class="op">(</span>extents_type<span class="op">::</span>rank_dynamic<span class="op">()==</span><span class="dv">0</span> <span class="op">&amp;&amp;</span> extents_type<span class="op">::</span>rank<span class="op">()&gt;</span><span class="dv">0</span><span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><em>Effects:</em> Direct-non-list-initializes
<em><code>extents_</code></em> with <code>extents_type()</code> , and
for all <span class="math inline"><em>d</em></span> in the range <span class="math inline">[</span><code>0,</code><em><code>rank_</code></em><span class="math inline">)</span>, direct-non-list-initializes
<em><code>strides_</code></em><code>[d]</code> with
<code>layout_right::mapping&lt;extents_type&gt;().stride(d)</code>.</p>
<h2 data-number="4.3" id="preference-for-resolution"><span class="header-section-number">4.3</span> Preference for Resolution<a href="#preference-for-resolution" class="self-link"></a></h2>
<p>We believe that it is preferable to preserve default constructibility
of <code>layout_stride</code> for all specializations of
<code>layout_stride</code> to simplify a number of generic programming
cases – specifically, if layout policies are used directly in
higher-level data structures for which the user wants to enable default
constructibility.</p>
<p>Based on feedback in LWG we leave out the defaulted constructor for
cases with dynamic extents and just always default construct
<code>layout_stride::mapping</code> as if it were a
<code>layout_right::mapping</code> with the same default constructed
<code>extents</code>.</p>
<h2 data-number="4.4" id="proposed-wording"><span class="header-section-number">4.4</span> Proposed Wording<a href="#proposed-wording" class="self-link"></a></h2>
<p>In subsection 24.7.3.4.7.1 [mdspan.layout.stride.overview]
replace:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>    <span class="co">// [mdspan.layout.stride.cons], constructors</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span></code></pre></div>
<p>With:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>    <span class="co">// [mdspan.layout.stride.cons], constructors</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> <span class="kw">noexcept</span>; </span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">(</span><span class="kw">const</span> mapping<span class="op">&amp;)</span> <span class="kw">noexcept</span> <span class="op">=</span> <span class="cf">default</span>;</span></code></pre></div>
<p>Add at the beginning of subsection 24.7.3.4.7.3
[mdspan.layout.stride.cons] insert:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> mapping<span class="op">()</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<p><em>Preconditions</em>:
<code>layout_right::mapping&lt;extents_type&gt;().required_span_size()</code>
is representable as a value of type <code>index_type</code> (<a href="https://eel.is/c++draft/basic.fundamental">[basic.fundamental]</a>).</p>
<p><em>Effects:</em> Direct-non-list-initializes
<em><code>extents_</code></em> with <code>extents_type()</code> , and
for all <span class="math inline"><em>d</em></span> in the range <span class="math inline">[</span><code>0,</code><em><code>rank_</code></em><span class="math inline">)</span>, direct-non-list-initializes
<em><code>strides_</code></em><code>[d]</code> with
<code>layout_right::mapping&lt;extents_type&gt;().stride(d)</code>.</p>
</div>
</div>
</body>
</html>
