<!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="2024-04-15" />
  <title>Copy and fill for mdspan</title>
  <style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
  <style>
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { 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 { display: inline-block; 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: #00AA00}
code.diff span.st {color: #bf0303}
</style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

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

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

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

code.sourceCode > span { display: inline; }

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

<table style="border:none;float:right">
  <tr>
    <td>Document #: </td>
    <td>P3242R0</td>
  </tr>
  <tr>
    <td>Date: </td>
    <td>2024-04-15</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project: </td>
    <td>Programming Language C++<br>
      LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to: </td>
    <td>
      Nicolas Morales<br>&lt;<a href="mailto:nmmoral@sandia.gov" class="email">nmmoral@sandia.gov</a>&gt;<br>
      Christian Trott<br>&lt;<a href="mailto:crtrott@sandia.gov" class="email">crtrott@sandia.gov</a>&gt;<br>
      Mark Hoemmen<br>&lt;<a href="mailto:mark.hoemmen@gmail.com" class="email">mark.hoemmen@gmail.com</a>&gt;<br>
      Damien Lebrun-Grandie<br>&lt;<a href="mailto:lebrungrandt@ornl.gov" class="email">lebrungrandt@ornl.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="#motivation" id="toc-motivation"><span class="toc-section-number">1</span> Motivation</a>
<ul>
<li><a href="#safety" id="toc-safety"><span class="toc-section-number">1.1</span> Safety</a></li>
</ul></li>
<li><a href="#design" id="toc-design"><span class="toc-section-number">2</span> Design</a>
<ul>
<li><a href="#header" id="toc-header"><span class="toc-section-number">2.1</span> Header</a></li>
<li><a href="#existing-copy-in-stdlinalg" id="toc-existing-copy-in-stdlinalg"><span class="toc-section-number">2.2</span> Existing <code>copy</code> in
<code>std::linalg</code></a></li>
<li><a href="#what-the-proposal-does-not-include" id="toc-what-the-proposal-does-not-include"><span class="toc-section-number">2.3</span> What the proposal does not
include</a></li>
<li><a href="#implementation-experience" id="toc-implementation-experience"><span class="toc-section-number">2.4</span> Implementation experience</a></li>
</ul></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">3</span> Wording</a></li>
<li><a href="#acknowledgments" id="toc-acknowledgments"><span class="toc-section-number">4</span> Acknowledgments</a></li>
<li><a href="#references" id="toc-references"><span class="toc-section-number">5</span> References</a></li>
</ul>
</div>
<h1 data-number="1" id="motivation"><span class="header-section-number">1</span> Motivation<a href="#motivation" class="self-link"></a></h1>
<p>C++23 introduced <code>mdspan</code> (<span class="citation" data-cites="P0009R18">[<a href="#ref-P0009R18" role="doc-biblioref">P0009R18</a>]</span>), a non-owning
multidimensional array abstraction that has a customizable layout.
Layout customization was originally motivated in <span class="citation" data-cites="P0009R18">[<a href="#ref-P0009R18" role="doc-biblioref">P0009R18</a>]</span> with considerations for
interoperability and performance, particularly on different
architectures. Moreover, <span class="citation" data-cites="P2630R4">[<a href="#ref-P2630R4" role="doc-biblioref">P2630R4</a>]</span> introduced
<code>submdspan</code>, a slicing function that can yield arbitrarily
strided layouts. However, without standard library support, copying
efficiently between <code>mdspan</code>s with mixes of complex layouts
is challenging for users.</p>
<p>Many applications, including high-performance computing (HPC), image
processing, computer graphics, etc that benefit from <code>mdspan</code>
also would benefit from basic memory operations provided in standard
algorithms such as copy and fill. Indeed, the authors found that a copy
algorithm would have been quite useful in their implementation of the
copying <code>mdarray</code> (<span class="citation" data-cites="P1684R5">[<a href="#ref-P1684R5" role="doc-biblioref">P1684R5</a>]</span>) constructor. A more
constrained form of <code>copy</code> is also included in the standard
linear algebra library (<span class="citation" data-cites="P1673R13">[<a href="#ref-P1673R13" role="doc-biblioref">P1673R13</a>]</span>).</p>
<p>However, existing standard library facilities are not sufficient
here. Currently, <code>mdspan</code> does not have iterators or ranges
that represent the span of the <code>mdspan</code>. Additionally, it’s
not entirely clear what this would entail.
<code>std::linalg::copy</code> (<span class="citation" data-cites="P1673R13">[<a href="#ref-P1673R13" role="doc-biblioref">P1673R13</a>]</span>) is limited to
<code>mdspan</code>s of rank 2 or lower.</p>
<p>Moreover, the manner in which an <code>mdspan</code> is copied (or
filled) is highly performance sensitive, particularly in regards to
caching behavior when traversing <code>mdspan</code> memory. A naive
user implementation is easy to get wrong in addition to being tedious
for higher rank <code>mdspan</code>s. Ideally, an implementation would
be free to use information about the layout of the <code>mdspan</code>
known at compile time to perform optimizations; e.g. a continuous span
<code>mdspan</code> copy for trivial types could be implemented with a
<code>memcpy</code>.</p>
<p>Finally, providing these generic algorithms would also enable these
operations for types that are representable by <code>mdspan</code>. For
example, this would naturally include <code>mdarray</code>, which is
convertible to <code>mdspan</code>, or for user-defined types whose view
of memory corresponds to <code>mdspan</code>s (e.g. an image class or
something similar).</p>
<h2 data-number="1.1" id="safety"><span class="header-section-number">1.1</span> Safety<a href="#safety" class="self-link"></a></h2>
<p>Due to the closed nature of <code>mdspan</code> extents, copy
operations can be checked by the implementation to prevent past-the-end
writes. This is an advantage the proposed copy operation has over the
existing operations in the standard.</p>
<h1 data-number="2" id="design"><span class="header-section-number">2</span> Design<a href="#design" class="self-link"></a></h1>
<p>The main design direction of this proposal is to provide methods for
copying and filling <code>mdspan</code>s that may have differing layouts
and accessors, while allowing implementations to provide efficient
implementations for special cases. For example, if a copy occurs between
two <code>mdspan</code>s with the same layout mapping type that is
contiguous and both use <code>default_accessor</code>, the intention is
that this could be implemented by a single <code>memcpy</code>.</p>
<p>Furthermore, accessors as a customization point should be enabled, as
with any other <code>mdspan</code> operation. For example, a custom
accessor that checks a condition inside of the <code>access</code>
method should still work and check that condition. It’s worth noting
that there may be a high sensitivity of how much implementations able to
optimize if provided custom accessors. For example, optimizations could
be disabled if using a custom accessor that is identical to the default
accessor.</p>
<p>Finally, there is some question as to whether <code>copy</code> and
<code>fill</code> should return a value when applied to
<code>mdspan</code>, as the iterator and ranged-based algorithms do. We
believe that <code>mdspan</code> copy and fill should return void, as
there is no past-the-end iterator that they could reasonably return.</p>
<h2 data-number="2.1" id="header"><span class="header-section-number">2.1</span> Header<a href="#header" class="self-link"></a></h2>
<p>Currently, we are proposing adding <code>copy</code> and
<code>fill</code> algorithms on <code>mdspan</code> to header
<code>&lt;mdspan&gt;</code>. We considered other options, namely:</p>
<ul>
<li><code>&lt;algorithm&gt;</code>: This would mean that users of
iterator-based algorithms would need to pull in
<code>&lt;mdspan&gt;</code>. On the other hand, this is where
iterator-based <code>copy</code> and <code>fill</code> live so may be
preferable in that sense.</li>
<li><code>&lt;mdspan_algorithm&gt;</code> (or similarly any other new
header): This seems like overkill for two functions. However, in the
future, we may want to add new algorithms for <code>mdspan</code> that
are not strictly covered by existing algorithms in
<code>&lt;algorithm&gt;</code>, so this option may be more future
proof.</li>
</ul>
<p>We settled on <code>&lt;mdspan&gt;</code> because as proposed this is
a relatively light-weight addition that reflects operations that are
commonly desired with <code>mdspan</code>s. However, the authors are
open to changing this.</p>
<h2 data-number="2.2" id="existing-copy-in-stdlinalg"><span class="header-section-number">2.2</span> Existing <code>copy</code> in
<code>std::linalg</code><a href="#existing-copy-in-stdlinalg" class="self-link"></a></h2>
<p><span class="citation" data-cites="P1673R13">[<a href="#ref-P1673R13" role="doc-biblioref">P1673R13</a>]</span> introduced several linear
algebra operations including <code>std::linalg::copy</code>. This
operation only applies to <code>mdspan</code>s with <span class="math inline"><em>r</em><em>a</em><em>n</em><em>k</em> ≤ 2</span>.
This paper is proposing a version of <code>copy</code> that is not
constrained by the number of ranks and differs from
<code>std::linalg::copy</code> in some important ways outline below.</p>
<p>Note that right now the strict addition of <code>copy</code> would
potentially cause the following code to be ambiguous, due to ADL-finding
<code>std::copy</code>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> std<span class="op">::</span>linalg<span class="op">::</span>copy;</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>copy<span class="op">(</span>mds1, mds2<span class="op">)</span>;</span></code></pre></div>
<p>One possibility would be to remove <code>std::linalg::copy</code>, as
it is a subset of the proposed <code>std::copy</code>. This was rejected
by the paper authors because of certain requirements in
[linalg.reqs.alg] – that is:</p>
<blockquote>
<p>The function may make arbitrarily many objects of any linear algebra
value type, value-initializing or direct-initializing them with any
existing object of that type.</p>
</blockquote>
<p>This requirement is likely undesirable for a generalized copy
algorithm.</p>
<p>There is a similar argument against simply generalizing
<code>std::linalg::copy</code>. In addition to the freedom of
<code>std::linalg::copy</code> to arbitrarily value or
direct-initializing values, using the linear algebra version of copy
would require the use of unnecessary includes and namespaces. It seems
not very ergonomic for a user to have to use
<code>std::linalg::copy</code> and include <code>&lt;linalg&gt;</code>
even if the <code>mdspan</code> operations they are performing are
unrelated to linear algebra.</p>
<h2 data-number="2.3" id="what-the-proposal-does-not-include"><span class="header-section-number">2.3</span> What the proposal does not
include<a href="#what-the-proposal-does-not-include" class="self-link"></a></h2>
<p>There are a few additions that are analogous to existing standard
algorithms that are not included in this proposal, both to keep the
proposal small and because some of these algorithms do not make sense in
the context of <code>mdspan</code>s:</p>
<ul>
<li><code>std::move</code>: Perhaps this should be included for
completeness’s sake. However, it doesn’t seem applicable to the typical
usage of <code>mdspan</code>.</li>
<li><code>(copy|fill)_n</code>: As a multidimensional view
<code>mdspan</code> does not in general follow a specific ordering.
Memory ordering may not be obvious to calling code, so it’s not even
clear how these would work. Any applications intending to copy a subset
of <code>mdspan</code> should use call <code>copy</code> on the result
of <code>submdspan</code>.</li>
<li><code>copy_backward</code>: As above, there is no specific ordering.
A similar effect could be achieved via transformations with a custom
layout, similar to <code>layout_transpose</code> in <span class="citation" data-cites="P1673R13">[<a href="#ref-P1673R13" role="doc-biblioref">P1673R13</a>]</span>.</li>
<li>Other algorithms, include <code>std::for_each</code>.
<code>for_each</code> in particular is a desirable but brings in many
unanswered questions that should be addressed in a different paper.</li>
</ul>
<h2 data-number="2.4" id="implementation-experience"><span class="header-section-number">2.4</span> Implementation experience<a href="#implementation-experience" class="self-link"></a></h2>
<p>A prototype implementation of this paper can be found in a PR in <a href="https://github.com/kokkos/mdspan/pull/325" class="uri">https://github.com/kokkos/mdspan/pull/325</a>. The PR
includes an example of how vendors could provide an efficient
implementation for certain combinations of <code>mdspan</code>
properties and layout policies.</p>
<h1 data-number="3" id="wording"><span class="header-section-number">3</span> Wording<a href="#wording" class="self-link"></a></h1>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> SrcElementType, <span class="kw">class</span> SrcExtents, <span class="kw">class</span> SrcLayoutPolicy, <span class="kw">class</span> SrcAccessorPolicy,</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>         <span class="kw">class</span> DstElementType, <span class="kw">class</span> DstExtents, <span class="kw">class</span> DstLayoutPolicy, <span class="kw">class</span> DstAccessorPolicy<span class="op">&gt;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> copy<span class="op">(</span>mdspan<span class="op">&lt;</span>SrcElementType, SrcExtents, SrcLayoutPolicy, SrcAccessorPolicy<span class="op">&gt;</span> src,</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>          mdspan<span class="op">&lt;</span>DstElementType, DstExtents, DstLayoutPolicy, DstAccessorPolicy<span class="op">&gt;</span> dst<span class="op">)</span>;</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ExecutionPolicy,</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>         <span class="kw">class</span> SrcElementType, <span class="kw">class</span> SrcExtents, <span class="kw">class</span> SrcLayoutPolicy, <span class="kw">class</span> SrcAccessorPolicy,</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>         <span class="kw">class</span> DstElementType, <span class="kw">class</span> DstExtents, <span class="kw">class</span> DstLayoutPolicy, <span class="kw">class</span> DstAccessorPolicy<span class="op">&gt;</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> copy<span class="op">(</span>ExecutionPolicy<span class="op">&amp;&amp;</span> policy,</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>          mdspan<span class="op">&lt;</span>SrcElementType, SrcExtents, SrcLayoutPolicy, SrcAccessorPolicy<span class="op">&gt;</span> src,</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>          mdspan<span class="op">&lt;</span>DstElementType, DstExtents, DstLayoutPolicy, DstAccessorPolicy<span class="op">&gt;</span> dst<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span>
<em>Constraints:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.1)</a></span>
<code>std::is_assignable_v&lt;typename mdspan&lt;SrcElementType, SrcExtents, SrcLayoutPolicy, SrcAccessorPolicy&gt;::reference, typename mdspan&lt;DstElementType, DstExtents, DstLayoutPolicy, DstAccessorPolicy&gt;::reference&gt;</code>
is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(1.2)</a></span>
<code>is_constructible_v&lt;DstExtents, SrcExtents&gt;</code>.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span>
<em>Preconditions:</em></p>
<ul>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.1)</a></span>
<code>src.extents() == dst.extents()</code> is
<code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.2)</a></span>
<code>dst.is_unique()</code> is <code>true</code>.</p></li>
<li><p><span class="marginalizedparent"><a class="marginalized">(2.3)</a></span>
there is no unique multidimensional index <code>i...</code> in
<code>src.extents()</code> where there exists a multidimensional index
<code>j...</code> in <code>dst.extents()</code> such that
<code>src[i...]</code> and <code>dst[j...]</code> refer to the same
element.</p></li>
</ul>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span>
<em>Effects:</em> for all unique multidimensional indices
<code>i...</code> in <code>src.extents()</code>, assigns
<code>src[i...]</code> to <code>dst[i...]</code></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="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ElementType, <span class="kw">class</span> Extents, <span class="kw">class</span> LayoutPolicy, <span class="kw">class</span> AccessorPolicy, <span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> fill<span class="op">(</span>mdspan<span class="op">&lt;</span>ElementType, Extents, LayoutPolicy, AccessorPolicy<span class="op">&gt;</span> dst, <span class="kw">const</span> T<span class="op">&amp;</span> value<span class="op">)</span>;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> ExecutionPolicy,</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>         <span class="kw">class</span> ElementType, <span class="kw">class</span> Extents, <span class="kw">class</span> LayoutPolicy, <span class="kw">class</span> AccessorPolicy, <span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> fill<span class="op">(</span>ExecutionPolicy<span class="op">&amp;&amp;</span> policy,</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>          mdspan<span class="op">&lt;</span>ElementType, Extents, LayoutPolicy, AccessorPolicy<span class="op">&gt;</span> dst, <span class="kw">const</span> T<span class="op">&amp;</span> value<span class="op">)</span>;</span></code></pre></div>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span>
<em>Constraints:</em>
<code>std::is_assignable_v&lt;typename mdspan&lt;ElementType, Extents, LayoutPolicy, AccessorPolicy&gt;::reference, const T&amp;&gt;</code></p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span>
<em>Effects:</em> for all unique multidimensional indices
<code>i...</code> in <code>dst.extents()</code>, assigns
<code>value</code> to <code>dst[i...]</code></p>
<h1 data-number="4" id="acknowledgments"><span class="header-section-number">4</span> Acknowledgments<a href="#acknowledgments" class="self-link"></a></h1>
<p>Sandia National Laboratories is a multimission laboratory managed and
operated by National Technology &amp; Engineering Solutions of Sandia,
LLC, a wholly owned subsidiary of Honeywell International Inc., for the
U.S. Department of Energy’s National Nuclear Security Administration
under contract DE-NA0003525. This paper describes objective technical
results and analysis. Any subjective views or opinions that might be
expressed in the paper do not necessarily represent the views of the
U.S. Department of Energy or the United States Government.</p>
<h1 data-number="5" id="references"><span class="header-section-number">5</span> References<a href="#references" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body" data-entry-spacing="0" role="list">
<div id="ref-P0009R18" class="csl-entry" role="listitem">
<div class="csl-left-margin">[P0009R18] </div><div class="csl-right-inline">Christian Trott, D.S. Hollman, Damien
Lebrun-Grandie, Mark Hoemmen, Daniel Sunderland, H. Carter Edwards,
Bryce Adelstein Lelbach, Mauro Bianco, Ben Sander, Athanasios
Iliopoulos, John Michopoulos, Nevin Liber. 2022. mdspan. <a href="https://wg21.link/p0009r18"><div class="csl-block">https://wg21.link/p0009r18</div></a></div>
</div>
<div id="ref-P1673R13" class="csl-entry" role="listitem">
<div class="csl-left-margin">[P1673R13] </div><div class="csl-right-inline">Mark Hoemmen, Daisy Hollman, Christian Trott,
Daniel Sunderland, Nevin Liber, Alicia Klinvex, Li-Ta Lo, Damien
Lebrun-Grandie, Graham Lopez, Peter Caday, Sarah Knepper, Piotr
Luszczek, Timothy Costa. 2023. A free function linear algebra interface
based on the BLAS. <a href="https://wg21.link/p1673r13"><div class="csl-block">https://wg21.link/p1673r13</div></a></div>
</div>
<div id="ref-P1684R5" class="csl-entry" role="listitem">
<div class="csl-left-margin">[P1684R5] </div><div class="csl-right-inline">Christian Trott, Daisy Hollman, Mark Hoemmen,
Daniel Sunderland, Damien Lebrun-Grandie. 2023. mdarray: An Owning
Multidimensional Array Analog of mdspan. <a href="https://wg21.link/p1684r5"><div class="csl-block">https://wg21.link/p1684r5</div></a></div>
</div>
<div id="ref-P2630R4" class="csl-entry" role="listitem">
<div class="csl-left-margin">[P2630R4] </div><div class="csl-right-inline">Christian Trott, Damien Lebrun-Grandie, Mark
Hoemmen, Nevin Liber. 2023. Submdspan. <a href="https://wg21.link/p2630r4"><div class="csl-block">https://wg21.link/p2630r4</div></a></div>
</div>
</div>
</div>
</div>
</body>
</html>
