<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>p0856r0: Restrict Access Property for &lt;code>mdspan&lt;/code> and &lt;code>span&lt;/code></title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in §N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .assertion  for assertions                    (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/******************************************************************************/
/*                                   Body                                     */
/******************************************************************************/

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;               /* limit line length to 50em for readability   */
		margin: 0 auto;                /* center text within page                     */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag     */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		/* Colors */
		color: black;
		background: white top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		color: white;
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		border-color: #c00;
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 2;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
			color: black;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			background: white;
			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;
			background: white;
		}
		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		#toc-nav > a:hover,
		#toc-nav > a:focus {
			background: #f8f8f8;
		}
		#toc-nav > a:not(:hover):not(:focus) {
			color: #707070;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}

		#toc-toggle-inline {
			vertical-align: 0.05em;
			font-size: 80%;
			color: gray;
			color: hsla(203,20%,40%,.7);
			border-style: none;
			background: transparent;
			position: relative;
		}
		#toc-toggle-inline:hover:not(:active),
		#toc-toggle-inline:focus:not(:active) {
			text-shadow: 1px 1px silver;
			top: -1px;
			left: -1px;
		}

		#toc-nav :active {
			color: #C00;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;    /* Inherit the font family. */
		line-height: 1.2;        /* Keep wrapped headings compact */
		hyphens: manual;         /* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		background: transparent;
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#subtitle {
		/* #subtitle is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	 border-left: 0.5em solid #DEF;
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd; border-radius: .5em;
	  margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	  margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	  margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	 margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	 margin-left: -2em;
	}
	dl.switch {
	 padding-left: 2em;
	}
	dl.switch > dt {
	 text-indent: -1.5em;
	 margin-top: 1em;
	}
	dl.switch > dt + dt {
	 margin-top: 0;
	}
	dl.switch > dt::before {
	 content: '\21AA';
	 padding: 0 0.5em 0 0;
	 display: inline-block;
	 width: 1em;
	 text-align: right;
	 line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: medium;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del { color: red;  text-decoration: line-through; }
	ins { color: #080; text-decoration: underline;    }

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

  /* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		text-decoration: none;
		border-bottom: 1px solid #707070;
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		border-bottom-color: #BBB;
	}

	/* Use distinguishing colors when user is interacting with the link */
	a[href]:focus,
	a[href]:hover {
		background: #f8f8f8;
		background: rgba(75%, 75%, 75%, .25);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	a[href]:active {
		color: #C00;
		border-color: #C00;
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	/* For autogen numbers, add
	   .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,    .sidefigure img,    figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote {
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	.issue,
	.note,
	.example,
	.advisement,
	.assertion,
	blockquote {
		margin: 1em auto;
	}
	.note  > p:first-child,
	.issue > p:first-child,
	blockquote > :first-child {
		margin-top: 0;
	}
	blockquote > :last-child {
		margin-bottom: 0;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	   or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #E0CB52;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	   or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52E052;
		background: #E9FBE9;
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary::before,
	details.note > summary > .marker {
		text-transform: uppercase;
		display: block;
		color: hsl(120, 70%, 30%);
	}
	/* Add .note::before { content: "Note"; } for autogen label,
	   or use class="marker" to mark up the label in source. */

	details.note > summary {
		display: block;
		color: hsl(120, 70%, 30%);
	}
	details.note[open] > summary {
		border-bottom: 1px silver solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		background: #EEE;
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-style: none solid;
		background: #FFEECC;
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement > .marker {
		color: #B35F00;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 1em;
		right: 1em;
		bottom: 1em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #DEF;
		margin: 1.2em 0;
		border-left: 0.5em solid #8CCBF2;
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def           td.footnote {
		padding-top: 0.6em;
	}
	table.def           td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		 <table class="data"> highlights structural relationships in a table
		 when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		 Use class="complex data" for particularly complicated tables --
		 (This will draw more lines: busier, but clearer.)

		 Use class="long" on table cells with paragraph-like contents
		 (This will adjust text alignment accordingly.)
		 Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
	 vertical-align: baseline;
	 text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
		line-height: 1.1rem; /* consistent spacing */
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li             { font-weight: bold;   }
	.toc > li li          { font-weight: normal; }
	.toc > li li li       { font-size:   95%;    }
	.toc > li li li li    { font-size:   90%;    }
	.toc > li li li li li { font-size:   85%;    }

	.toc > li             { margin: 1.5rem 0;    }
	.toc > li li          { margin: 0.3rem 0;    }
	.toc > li li li       { margin-left: 2rem;   }

	/* Section numbers in a column of their own */
	.toc .secno {
		float: left;
		width: 4rem;
		white-space: nowrap;
	}
	.toc > li li li li .secno {
		font-size: 85%;
	}
	.toc > li li li li li .secno {
		font-size: 100%;
	}

	:not(li) > .toc              { margin-left:  5rem; }
	.toc .secno                  { margin-left: -5rem; }
	.toc > li li li .secno       { margin-left: -7rem; }
	.toc > li li li li .secno    { margin-left: -9rem; }
	.toc > li li li li li .secno { margin-left: -11rem; }

	/* Tighten up indentation in narrow ToCs */
	@media (max-width: 30em) {
		:not(li) > .toc              { margin-left:  4rem; }
		.toc .secno                  { margin-left: -4rem; }
		.toc > li li li              { margin-left:  1rem; }
		.toc > li li li .secno       { margin-left: -5rem; }
		.toc > li li li li .secno    { margin-left: -6rem; }
		.toc > li li li li li .secno { margin-left: -7rem; }
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) :not(li) > .toc              { margin-left:  4rem; }
		body:not(.toc-inline) .toc .secno                  { margin-left: -4rem; }
		body:not(.toc-inline) .toc > li li li              { margin-left:  1rem; }
		body:not(.toc-inline) .toc > li li li .secno       { margin-left: -5rem; }
		body:not(.toc-inline) .toc > li li li li .secno    { margin-left: -6rem; }
		body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	body.toc-sidebar #toc :not(li) > .toc              { margin-left:  4rem; }
	body.toc-sidebar #toc .toc .secno                  { margin-left: -4rem; }
	body.toc-sidebar #toc .toc > li li li              { margin-left:  1rem; }
	body.toc-sidebar #toc .toc > li li li .secno       { margin-left: -5rem; }
	body.toc-sidebar #toc .toc > li li li li .secno    { margin-left: -6rem; }
	body.toc-sidebar #toc .toc > li li li li li .secno { margin-left: -7rem; }

	.toc li {
		clear: both;
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index       { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li    { margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em }
	ul.index dl    { margin-top: 0; }
	ul.index dt    { margin: .2em 0 .2em 20px;}
	ul.index dd    { margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		background: #f7f8f9;
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

	/* This rule is inherited from past style sheets. No idea what it's for. */
	.hide { display: none }



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-left: calc(13px + 26.5rem - 50vw);
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-left: calc(40em - 50vw) !important;
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-left: 0 !important;
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			 * http://lea.verou.me/2012/04/background-attachment-local/
			 *
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
			            top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
			            top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style type="text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }
  </style>
  <meta content="Bikeshed version 166744eb86a34dbc5493268ea410dc65275aa964" name="generator">
  <link href="https://kokkos.github.io/array_ref/proposals/P0856.html" rel="canonical">
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-syntax-highlighting */

.highlight:not(.idl) { background: hsl(24, 20%, 95%); }
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }
.highlight .c { color: #708090 } /* Comment */
.highlight .k { color: #990055 } /* Keyword */
.highlight .l { color: #000000 } /* Literal */
.highlight .n { color: #0077aa } /* Name */
.highlight .o { color: #999999 } /* Operator */
.highlight .p { color: #999999 } /* Punctuation */
.highlight .cm { color: #708090 } /* Comment.Multiline */
.highlight .cp { color: #708090 } /* Comment.Preproc */
.highlight .c1 { color: #708090 } /* Comment.Single */
.highlight .cs { color: #708090 } /* Comment.Special */
.highlight .kc { color: #990055 } /* Keyword.Constant */
.highlight .kd { color: #990055 } /* Keyword.Declaration */
.highlight .kn { color: #990055 } /* Keyword.Namespace */
.highlight .kp { color: #990055 } /* Keyword.Pseudo */
.highlight .kr { color: #990055 } /* Keyword.Reserved */
.highlight .kt { color: #990055 } /* Keyword.Type */
.highlight .ld { color: #000000 } /* Literal.Date */
.highlight .m { color: #000000 } /* Literal.Number */
.highlight .s { color: #a67f59 } /* Literal.String */
.highlight .na { color: #0077aa } /* Name.Attribute */
.highlight .nc { color: #0077aa } /* Name.Class */
.highlight .no { color: #0077aa } /* Name.Constant */
.highlight .nd { color: #0077aa } /* Name.Decorator */
.highlight .ni { color: #0077aa } /* Name.Entity */
.highlight .ne { color: #0077aa } /* Name.Exception */
.highlight .nf { color: #0077aa } /* Name.Function */
.highlight .nl { color: #0077aa } /* Name.Label */
.highlight .nn { color: #0077aa } /* Name.Namespace */
.highlight .py { color: #0077aa } /* Name.Property */
.highlight .nt { color: #669900 } /* Name.Tag */
.highlight .nv { color: #222222 } /* Name.Variable */
.highlight .ow { color: #999999 } /* Operator.Word */
.highlight .mb { color: #000000 } /* Literal.Number.Bin */
.highlight .mf { color: #000000 } /* Literal.Number.Float */
.highlight .mh { color: #000000 } /* Literal.Number.Hex */
.highlight .mi { color: #000000 } /* Literal.Number.Integer */
.highlight .mo { color: #000000 } /* Literal.Number.Oct */
.highlight .sb { color: #a67f59 } /* Literal.String.Backtick */
.highlight .sc { color: #a67f59 } /* Literal.String.Char */
.highlight .sd { color: #a67f59 } /* Literal.String.Doc */
.highlight .s2 { color: #a67f59 } /* Literal.String.Double */
.highlight .se { color: #a67f59 } /* Literal.String.Escape */
.highlight .sh { color: #a67f59 } /* Literal.String.Heredoc */
.highlight .si { color: #a67f59 } /* Literal.String.Interpol */
.highlight .sx { color: #a67f59 } /* Literal.String.Other */
.highlight .sr { color: #a67f59 } /* Literal.String.Regex */
.highlight .s1 { color: #a67f59 } /* Literal.String.Single */
.highlight .ss { color: #a67f59 } /* Literal.String.Symbol */
.highlight .vc { color: #0077aa } /* Name.Variable.Class */
.highlight .vg { color: #0077aa } /* Name.Variable.Global */
.highlight .vi { color: #0077aa } /* Name.Variable.Instance */
.highlight .il { color: #000000 } /* Literal.Number.Integer.Long */
</style>
<style>/* style-selflinks */

.heading, .issue, .note, .example, li, dt {
    position: relative;
}
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;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: gray;
    color: white;
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: black;
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: #005a9c;
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">p0856r0<br>Restrict Access Property for <code class="highlight"><span class="n">mdspan</span></code> and <code class="highlight"><span class="n">span</span></code></h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2018-02-12">12 February 2018</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://kokkos.github.io/array_ref/proposals/P0856.html">https://kokkos.github.io/array_ref/proposals/P0856.html</a>
     <dt>Authors:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:dshollm@sandia.gov">David S. Hollman</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:hcedwar@sandia.gov">H. Carter Edwards</a>
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:crtrott@sandia.gov">Christian Trott</a>
     <dt>Audience:
     <dd>LEWG
     <dt>Project:
     <dd>ISO JTC1/SC22/WG21: Programming Language C++
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>This paper proposes a semantic for the use of the property customization point on <code class="highlight"><span class="n">span</span></code> and <code class="highlight"><span class="n">mdspan</span></code> to express non-aliasing semantics analogous to those of the ISO-C keyword <code class="highlight"><span class="k">restrict</span></code>.  Reconceptualizing non-aliasing semantics as a customization point on a library feature addresses many of the previous ambiguities in non-aliasing semantics for C++, and the implications of this new approach are discussed.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li>
     <a href="#revision-history"><span class="secno">1</span> <span class="content">Revision History</span></a>
     <ol class="toc">
      <li><a href="#p0856r0"><span class="secno">1.1</span> <span class="content">P0856r0</span></a>
     </ol>
    <li><a href="#motivation"><span class="secno">2</span> <span class="content">Motivation</span></a>
    <li>
     <a href="#background-and-precedent"><span class="secno">3</span> <span class="content">Background and Precedent</span></a>
     <ol class="toc">
      <li>
       <a href="#iso-c-language-standard"><span class="secno">3.1</span> <span class="content">ISO C Language Standard</span></a>
       <ol class="toc">
        <li><a href="#dependence-of-n4700-on-iso-c-restrict"><span class="secno">3.1.1</span> <span class="content">Dependence of N4700 on ISO C <code class="highlight"><span class="k">restrict</span></code></span></a>
       </ol>
      <li><a href="#gccs-__restrict__"><span class="secno">3.2</span> <span class="content">GCC’s <code class="highlight"><span class="n">__restrict__</span></code></span></a>
      <li><a href="#msvcs-__declspec-restrict"><span class="secno">3.3</span> <span class="content">MSVC’s <code class="highlight"><span class="kr">__declspec</span><span class="p">(</span><span class="k">restrict</span><span class="p">)</span></code></span></a>
      <li><a href="#clang-and-the-noalias-metadata-in-llvm-ir"><span class="secno">3.4</span> <span class="content">Clang++ and the <code class="highlight"><span class="n">noalias</span></code> Metadata in LLVM IR</span></a>
      <li><a href="#ibm-xl-c"><span class="secno">3.5</span> <span class="content">IBM XL C++</span></a>
      <li><a href="#nvidias-nvcc"><span class="secno">3.6</span> <span class="content">NVIDIA’s nvcc</span></a>
     </ol>
    <li>
     <a href="#proposal"><span class="secno">4</span> <span class="content">Proposal</span></a>
     <ol class="toc">
      <li><a href="#has_propertyt-restrict_accessvalue"><span class="secno">4.1</span> <span class="content"><code class="highlight"><span class="n">has_property</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">restrict_access</span><span class="o">>::</span><span class="n">value</span></code></span></a>
      <li><a href="#application-of-the-restriction-to-span"><span class="secno">4.2</span> <span class="content">Application of the Restriction to <code class="highlight"><span class="n">span</span></code></span></a>
     </ol>
    <li>
     <a href="#discussion"><span class="secno">5</span> <span class="content">Discussion</span></a>
     <ol class="toc">
      <li><a href="#whylib"><span class="secno">5.1</span> <span class="content">Why a library feature?</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="revision-history"><span class="secno">1. </span><span class="content">Revision History</span><a class="self-link" href="#revision-history"></a></h2>
   <h3 class="heading settled" data-level="1.1" id="p0856r0"><span class="secno">1.1. </span><span class="content">P0856r0</span><a class="self-link" href="#p0856r0"></a></h3>
   <p>Address <a href="http://wiki.edg.com/bin/view/Wg21albuquerque/P00546">2017-11-Albuquerque LEWG feedback</a> to generate paper for <em>restrict_access</em> property for <code class="highlight"><span class="n">mdspan</span></code> and <code class="highlight"><span class="n">span</span></code>.</p>
   <h2 class="heading settled" data-level="2" id="motivation"><span class="secno">2. </span><span class="content">Motivation</span><a class="self-link" href="#motivation"></a></h2>
   <p>The restrict (non-aliasing) property is a widely useful mechanism to enable
array access optimization. This functionality is part of the C standard, several
C++ compilers' extensions, and native to FORTRAN array semantics.</p>
   <p>While the utility of non-aliasing type annotations is well-established in the
literature, it is useful to reproduce several common motivating examples here
to illustrate the utility in the context of <code class="highlight"><span class="n">span</span></code> and <code class="highlight"><span class="n">mdspan</span></code>.</p>
   <p>Linear algebra produces one of the most compelling needs for non-aliasing
semantics. Even the simplest operations, such as vector addition, suffer
noticable degredation in the absense of a non-aliasing guarantee:</p>
<pre class="language-c++ highlight"><span class="c1">// Performce element-wise dest = a + b </span>
<span class="c1"></span><span class="n">template</span> <span class="o">&lt;</span><span class="kr">typename</span> <span class="n">T</span><span class="o">></span>
<span class="kt">void</span> <span class="n">element_product</span><span class="p">(</span><span class="n">span</span><span class="o">&lt;</span><span class="k">const</span> <span class="n">T</span><span class="o">></span> <span class="n">a</span><span class="p">,</span> <span class="n">span</span><span class="o">&lt;</span><span class="k">const</span> <span class="n">T</span><span class="o">></span> <span class="n">b</span><span class="p">,</span> <span class="n">span</span><span class="o">&lt;</span><span class="n">T</span><span class="o">></span> <span class="n">dest</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">assert</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="n">b</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">b</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="n">c</span><span class="p">.</span><span class="n">size</span><span class="p">());</span>
  <span class="k">for</span><span class="p">(</span><span class="kr">typename</span> <span class="n">span</span><span class="o">&lt;</span><span class="n">T</span><span class="o">>::</span><span class="n">size_type</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">dest</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
  <span class="p">}</span>
<span class="p">}</span>
</pre>
   <p>Without <code class="highlight"><span class="k">restrict</span></code> annotations, the compiler cannot vectorize this code, since <code class="highlight"><span class="n">a</span></code> or <code class="highlight"><span class="n">b</span></code> could point to the same memory as <code class="highlight"><span class="n">dest</span></code>.  With <code class="highlight"><span class="n">dest</span></code> being changed
every iteration, the compiler needs to preform fresh loads <code class="highlight"><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span></code> and <code class="highlight"><span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">]</span></code> every iteration in case, for instance, they point to <code class="highlight"><span class="n">dest</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span></code>.</p>
   <p>Reordering for the purposes of optimizing memory operations is another example of
an optimization that <code class="highlight"><span class="k">restrict</span></code> enables.  Consider the (albeit naïve)
implementation of a function that initializes two arrays at the start of some
user’s program:</p>
<pre class="language-c++ highlight"><span class="kt">void</span> <span class="nf">initialize_data</span><span class="p">(</span><span class="n">span</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">></span> <span class="n">v0</span><span class="p">,</span> <span class="n">span</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">></span> <span class="n">v1</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">for</span><span class="p">(</span><span class="kr">typename</span> <span class="n">span</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">>::</span><span class="n">size_type</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">v0</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
      <span class="n">v0</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
      <span class="n">v1</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</pre>
   <p>In the absence of <code class="highlight"><span class="k">restrict</span></code> information, the compiler cannot tell at what
point, if any, the statement <code class="highlight"><span class="n">v1</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span></code> starts to overwrite the effects of
previous statements on <code class="highlight"><span class="n">v0</span></code> (or vice versa).  With non-aliasing information
provided, however, the compiler can transform this function into two calls to <code class="highlight"><span class="n">memset</span></code>, which would be much more efficient on most architectures.  (It’s clear
to most people in this example that the user should have made this
transformation to begin with, but with intervening work in between the two
assignments, or other increased complexity, this may not be as clear).</p>
   <p>We propose to add the <code class="highlight"><span class="n">restrict_access</span></code> property to the set of admissible
properties of <code class="highlight"><span class="n">mdspan</span></code> and <code class="highlight"><span class="n">span</span></code>.</p>
   <p>This paper does not propose a strategy for subsequent extensibility. We identify
open questions that must be addressed in the design of such a strategy.  P0900
addresses the design of the customization point utilized here in a more generic
context.</p>
   <h2 class="heading settled" data-level="3" id="background-and-precedent"><span class="secno">3. </span><span class="content">Background and Precedent</span><a class="self-link" href="#background-and-precedent"></a></h2>
   <p><a data-link-type="biblio" href="#biblio-n3538">[N3538]</a>, <a data-link-type="biblio" href="#biblio-n3635">[N3635]</a>, and <a data-link-type="biblio" href="#biblio-n3988">[N3988]</a> previously proposed restrict-like semantics as a
language feature rather than a library feature.  A discussion of how presenting <code class="highlight"><span class="k">restrict</span></code> semantics as a library feature addresses many of the concerns
previously raised about these papers is given below in <a href="#whylib">§5.1 Why a library feature?</a></p>
   <h3 class="heading settled" data-level="3.1" id="iso-c-language-standard"><span class="secno">3.1. </span><span class="content">ISO C Language Standard</span><a class="self-link" href="#iso-c-language-standard"></a></h3>
   <p>The C language standard provides the <code class="highlight"><span class="k">restrict</span></code> keyword in 6.7.3 of the WG14
document <a data-link-type="biblio" href="#biblio-wg14-n1570">[WG14-N1570]</a>.  An informal definition is given in paragraph 8 of
6.7.3:</p>
   <blockquote>
    <p>An object that is accessed through a restrict-qualified pointer has a special
association with that pointer. This association, defined in 6.7.3.1 below,
requires that all accesses to that object use, directly or indirectly, the value
of that particular pointer. The intended use of the <code class="highlight"><span class="k">restrict</span></code> qualifier (like
the <code class="highlight"><span class="k">register</span></code> storage class) is to promote optimization, and deleting all
instances of the qualifier from all preprocessing translation units composing a
conforming program does not change its meaning (i.e., observable behavior).</p>
   </blockquote>
   <p>A formal definition of <code class="highlight"><span class="k">restrict</span></code> follows in 6.7.3.1 of <a data-link-type="biblio" href="#biblio-wg14-n1570">[WG14-N1570]</a>:</p>
   <blockquote>
     Let <code class="highlight"><span class="n">D</span></code> be a declaration of an ordinary identifier that provides a
means of designating an object <code class="highlight"><span class="n">P</span></code> as a restrict-qualified pointer to type <code class="highlight"><span class="n">T</span></code>. 
    <p>If <code class="highlight"><span class="n">D</span></code> appears inside a block and does not have storage class extern, let <code class="highlight"><span class="n">B</span></code> denote the block. If <code class="highlight"><span class="n">D</span></code> appears in the list of parameter declarations of a
function definition, let <code class="highlight"><span class="n">B</span></code> denote the associated block. Otherwise, let <code class="highlight"><span class="n">B</span></code> denote the block of main (or the block of whatever function is called at program
startup in a freestanding environment).</p>
    <p>In what follows, a pointer expression <code class="highlight"><span class="n">E</span></code> is said to be <em>based on</em> object <code class="highlight"><span class="n">P</span></code> if
(at some sequence point in the execution of <code class="highlight"><span class="n">B</span></code> prior to the evaluation of <code class="highlight"><span class="n">E</span></code>)
modifying <code class="highlight"><span class="n">P</span></code> to point to a copy of the array object into which it formerly
pointed would change the value of <code class="highlight"><span class="n">E</span></code>.  Note that "based" is defined only for
expressions with pointer types.</p>
    <p>During each execution of <code class="highlight"><span class="n">B</span></code>, let <code class="highlight"><span class="n">L</span></code> be any lvalue that has <code class="highlight"><span class="o">&amp;</span><span class="n">L</span></code> based on <code class="highlight"><span class="n">P</span></code>.
If <code class="highlight"><span class="n">L</span></code> is used to access the value of the object <code class="highlight"><span class="n">X</span></code> that it designates, and <code class="highlight"><span class="n">X</span></code> is also modified (by any means), then the following requirements apply: <code class="highlight"><span class="n">T</span></code> shall not be const-qualified. Every other lvalue used to access the value of <code class="highlight"><span class="n">X</span></code> shall also have its address based on <code class="highlight"><span class="n">P</span></code>. Every access that modifies <code class="highlight"><span class="n">X</span></code> shall
be considered also to modify <code class="highlight"><span class="n">P</span></code>, for the purposes of this subclause. If <code class="highlight"><span class="n">P</span></code> is
assigned the value of a pointer expression <code class="highlight"><span class="n">E</span></code> that is based on another
restricted pointer object <code class="highlight"><span class="n">P2</span></code>, associated with block <code class="highlight"><span class="n">B2</span></code>, then either the
execution of <code class="highlight"><span class="n">B2</span></code> shall begin before the execution of <code class="highlight"><span class="n">B</span></code>, or the execution of <code class="highlight"><span class="n">B2</span></code> shall end prior to the assignment. If these requirements are not met, then
the behavior is undefined.</p>
    <p>Here an execution of <code class="highlight"><span class="n">B</span></code> means that portion of the execution of the program that
would correspond to the lifetime of an object with scalar type and automatic
storage duration associated with <code class="highlight"><span class="n">B</span></code>.</p>
    <p>A translator is free to ignore any or all aliasing implications of uses of <code class="highlight"><span class="k">restrict</span></code>.</p>
   </blockquote>
   <h4 class="heading settled" data-level="3.1.1" id="dependence-of-n4700-on-iso-c-restrict"><span class="secno">3.1.1. </span><span class="content">Dependence of N4700 on ISO C <code class="highlight"><span class="k">restrict</span></code></span><a class="self-link" href="#dependence-of-n4700-on-iso-c-restrict"></a></h4>
   <p>Note that <a data-link-type="biblio" href="#biblio-n4700">[N4700]</a> already references the ISO C <code class="highlight"><span class="k">restrict</span></code> keyword in paragraph
2 of [library.c], implying that C++ implementations should already be aware of
its semantics (though, as stated in <a data-link-type="biblio" href="#biblio-wg14-n1570">[WG14-N1570]</a>, conforming implementations
can completely ignore <code class="highlight"><span class="k">restrict</span></code>):</p>
   <blockquote> The descriptions of many library functions rely on the C standard
library for the semantics of those functions. In some cases, the signatures
specified in this document may be different from the signatures in the C
standard library, and additional overloads may be declared in this document, but
the behavior and the preconditions (including any preconditions implied by the
use of an ISO C <code class="highlight"><span class="k">restrict</span></code> qualifier) are the same unless otherwise stated. </blockquote>
   <h3 class="heading settled" data-level="3.2" id="gccs-__restrict__"><span class="secno">3.2. </span><span class="content">GCC’s <code class="highlight"><span class="n">__restrict__</span></code></span><a class="self-link" href="#gccs-__restrict__"></a></h3>
   <p>GCC implements restricted access in C++ via the <code class="highlight"><span class="n">__restrict__</span></code> (or <code class="highlight"><span class="n">__restrict</span></code>)
compiler-specific extension.  The compiler documentation <a data-link-type="biblio" href="#biblio-gccrestrictdoc">[GCCRestrictDoc]</a> provides the following description:</p>
   <blockquote>
    <p>In addition to allowing restricted pointers, you can specify
restricted references, which indicate that the reference is not aliased in the
local context.</p>
<pre class="highlight"><span class="kt">void</span> <span class="nf">fn</span> <span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="n">__restrict__</span> <span class="n">rptr</span><span class="p">,</span> <span class="kt">int</span> <span class="o">&amp;</span><span class="n">__restrict__</span> <span class="n">rref</span><span class="p">)</span>
<span class="p">{</span>
  <span class="cm">/* … */</span>
<span class="p">}</span>
</pre>
    <p>In the body of <code class="highlight"><span class="n">fn</span></code>, <code class="highlight"><span class="n">rptr</span></code> points to an unaliased integer and <code class="highlight"><span class="n">rref</span></code> refers to
a (different) unaliased integer.</p>
    <p>You may also specify whether a member function’s this pointer is unaliased by
using <code class="highlight"><span class="n">__restrict__</span></code> as a member function qualifier.</p>
<pre class="highlight"><span class="kt">void</span> <span class="n">T</span><span class="o">::</span><span class="n">fn</span> <span class="p">()</span> <span class="n">__restrict__</span>
<span class="p">{</span>
  <span class="cm">/* … */</span>
<span class="p">}</span>
</pre>
    <p>Within the body of <code class="highlight"><span class="n">T</span><span class="o">::</span><span class="n">fn</span></code>, this has the effective definition <code class="highlight"><span class="n">T</span> <span class="o">*</span><span class="n">__restrict__</span> <span class="k">const</span> <span class="k">this</span></code>. Notice that the interpretation of a <code class="highlight"><span class="n">__restrict__</span></code> member function qualifier is different to that of <code class="highlight"><span class="k">const</span></code> or <code class="highlight"><span class="k">volatile</span></code> qualifier, in that it is applied to the pointer rather than the
object. This is consistent with other compilers that implement restricted
pointers.</p>
    <p>As with all outermost parameter qualifiers, <code class="highlight"><span class="n">__restrict__</span></code> is ignored in
function definition matching. This means you only need to specify <code class="highlight"><span class="n">__restrict__</span></code> in a function definition, rather than in a function prototype as well.</p>
   </blockquote>
   <p>It is clear that GCC’s implementation of this extension would be sufficient to
 implement the proposed feature trivially. Tests with gcc 7.3 and subsequent
 analysis of the machine code produced during compilation indicates that the
 existing extension would support the semantics proposed herein and perform the
 expected optimizations consistent with analogous non-aliasing information on
 raw pointers.</p>
   <h3 class="heading settled" data-level="3.3" id="msvcs-__declspec-restrict"><span class="secno">3.3. </span><span class="content">MSVC’s <code class="highlight"><span class="kr">__declspec</span><span class="p">(</span><span class="k">restrict</span><span class="p">)</span></code></span><a class="self-link" href="#msvcs-__declspec-restrict"></a></h3>
   <p>MSVC provides a couple of similar compiler-specific extensions via the syntaxes <code class="highlight"><span class="kr">__declspec</span><span class="p">(</span><span class="k">restrict</span><span class="p">)</span></code> and <code class="highlight"><span class="n">__restrict</span></code>.  The compiler documentation <a data-link-type="biblio" href="#biblio-msvcrestrictdoc">[MSVCRestrictDoc]</a> gives the following description of <code class="highlight"><span class="kr">__declspec</span><span class="p">(</span><span class="k">restrict</span><span class="p">)</span></code>:</p>
   <blockquote> Applied to a function declaration or definition that returns a
pointer type and tells the compiler that the function returns an object that
will not be aliased with any other pointers. </blockquote>
   <p>The compiler documentation’s description for <code class="highlight"><span class="n">__restrict</span></code> indicates that it is
similar to <code class="highlight"><span class="kr">__declspec</span><span class="p">(</span><span class="k">restrict</span><span class="p">)</span></code>, and, indeed, to ISO C <code class="highlight"><span class="k">restrict</span></code>:</p>
   <blockquote> <code class="highlight"><span class="n">__restrict</span></code> is similar to restrict from the C99 spec, but <code class="highlight"><span class="n">__restrict</span></code> can be used in C++ or C programs. </blockquote>
   <h3 class="heading settled" data-level="3.4" id="clang-and-the-noalias-metadata-in-llvm-ir"><span class="secno">3.4. </span><span class="content">Clang++ and the <code class="highlight"><span class="n">noalias</span></code> Metadata in LLVM IR</span><a class="self-link" href="#clang-and-the-noalias-metadata-in-llvm-ir"></a></h3>
   <p>LLVM’s internal representation (IR) includes a rich set of memory aliasing
metadata annotations <a data-link-type="biblio" href="#biblio-llvmirdoc">[LLVMIRDoc]</a>, including the <code class="highlight"><span class="n">noalias</span></code> metadata that
expresses <code class="highlight"><span class="k">restrict</span></code>-like semantics for function parameters (among other uses).
Clang++ supports the <code class="highlight"><span class="n">__restrict</span></code> and <code class="highlight"><span class="n">__restrict__</span></code> extensions from GCC both in
the Clang++ frontend and through these metadata attributes.  The presence of
these attributes in the LLVM IR means that other frontends that translate into
LLVM IR will also have the ability to express these semantics.</p>
   <h3 class="heading settled" data-level="3.5" id="ibm-xl-c"><span class="secno">3.5. </span><span class="content">IBM XL C++</span><a class="self-link" href="#ibm-xl-c"></a></h3>
   <p>The documentation for IBM XL C++ <a data-link-type="biblio" href="#biblio-xlcrestrictdoc">[XLCRestrictDoc]</a> indicates that it supports
ISO C <code class="highlight"><span class="k">restrict</span></code> semantics in C++ via the <code class="highlight"><span class="n">__restrict</span></code> or <code class="highlight"><span class="n">__restrict__</span></code> extensions.</p>
   <h3 class="heading settled" data-level="3.6" id="nvidias-nvcc"><span class="secno">3.6. </span><span class="content">NVIDIA’s nvcc</span><a class="self-link" href="#nvidias-nvcc"></a></h3>
   <p>The nvcc compiler supports the <code class="highlight"><span class="n">__restrict</span></code> or <code class="highlight"><span class="n">__restrict__</span></code> extensions for the
GPU and (as long as the underlying CPU compiler supports it) the CPU. <a data-link-type="biblio" href="#biblio-nvccrestrict">[NVCCRestrict]</a></p>
   <h2 class="heading settled" data-level="4" id="proposal"><span class="secno">4. </span><span class="content">Proposal</span><a class="self-link" href="#proposal"></a></h2>
   <p>We propose utilitzing the customization point explored in P0900 to express the <code class="highlight"><span class="n">restrict_access</span></code> property:</p>
<pre class="highlight"><span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">experimental</span> <span class="p">{</span>
<span class="kr">inline</span> <span class="k">namespace</span> <span class="n">fundamentals_v3</span> <span class="p">{</span>

  <span class="c1">// Trait common to all span and mdspan property proposals, as given in e.g., P0009r4</span>
<span class="c1"></span>  <span class="k">template</span><span class="o">&lt;</span> <span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">P</span> <span class="o">></span>
  <span class="k">struct</span> <span class="n">has_property</span><span class="p">;</span>

  <span class="c1">// Variable template for has_property</span>
<span class="c1"></span>  <span class="k">template</span><span class="o">&lt;</span> <span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">P</span> <span class="o">></span>
  <span class="kr">inline</span> <span class="k">constexpr</span> <span class="kt">bool</span> <span class="n">has_property_v</span> <span class="o">=</span> <span class="n">has_property</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">P</span><span class="o">>::</span><span class="n">value</span> <span class="p">;</span>

  <span class="c1">// Tag class for indicating restrict access</span>
<span class="c1"></span>  <span class="k">struct</span> <span class="n">restrict_access</span> <span class="p">;</span>

  <span class="c1">// Specialization of has_property for restrict_access</span>
<span class="c1"></span>  <span class="k">template</span><span class="o">&lt;</span> <span class="k">class</span> <span class="nc">T</span> <span class="o">></span>
  <span class="k">struct</span> <span class="n">has_property</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">restrict_access</span><span class="o">></span> <span class="p">{</span>
    <span class="kr">inline</span> <span class="k">constexpr</span> <span class="kt">bool</span> <span class="n">value</span> <span class="o">=</span> <span class="cm">/* see below */</span><span class="p">;</span>
  <span class="p">};</span>

<span class="p">}}}</span>
</pre>
   <h3 class="heading settled" data-level="4.1" id="has_propertyt-restrict_accessvalue"><span class="secno">4.1. </span><span class="content"><code class="highlight"><span class="n">has_property</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">restrict_access</span><span class="o">>::</span><span class="n">value</span></code></span><a class="self-link" href="#has_propertyt-restrict_accessvalue"></a></h3>
   <p>Evaluates to true if <code class="highlight"><span class="n">T</span></code> is instantiation of <code class="highlight"><span class="n">span</span></code> or <code class="highlight"><span class="n">mdspan</span></code> and the <code class="highlight"><span class="n">Properties</span><span class="p">...</span></code> parameter pack of <code class="highlight"><span class="n">T</span></code> contains <code class="highlight"><span class="n">restrict_access</span></code>.</p>
   <h3 class="heading settled" data-level="4.2" id="application-of-the-restriction-to-span"><span class="secno">4.2. </span><span class="content">Application of the Restriction to <code class="highlight"><span class="n">span</span></code></span><a class="self-link" href="#application-of-the-restriction-to-span"></a></h3>
   <p>Working relative to <a data-link-type="biblio" href="#biblio-p0122r5">[P0122r5]</a>, a preliminary attempt at wording the
restriction proposed herein is as follows (in addition to the changes proposed by <a data-link-type="biblio" href="#biblio-p0546r1">[P0546r1]</a>):</p>
   <blockquote>
    <p><strong>23.7.2.7 [span.restrict]</strong></p>
    <p>Let <code class="highlight"><span class="n">S</span></code> be an instantiation of <code class="highlight"><span class="n">span</span></code> such that <code class="highlight"><span class="n">has_property</span><span class="o">&lt;</span><span class="n">S</span><span class="p">,</span><span class="n">restrict_access</span><span class="o">>::</span><span class="n">value</span></code> is <code class="highlight">true</code>, and let <code class="highlight"><span class="n">s</span></code> be an
instance of <code class="highlight"><span class="n">S</span></code>.  Let <code class="highlight"><span class="n">p</span></code> be an object of type <code class="highlight"><span class="n">S</span><span class="o">::</span><span class="n">pointer</span></code> and <code class="highlight"><span class="n">sz</span></code> be an
object of type <code class="highlight"><span class="n">S</span><span class="o">::</span><span class="n">index_type</span></code>.  The <em>restricted lifetime of</em> <code class="highlight"><span class="n">s</span></code> <em>with respect to {</em> <code class="highlight"><span class="n">p</span><span class="p">,</span> <span class="n">sz</span></code> <em>}</em> is defined such that it either:</p>
    <ul>
     <li data-md="">
      <p>begins with the construction of <code class="highlight"><span class="n">s</span></code> and ends with the destruction of <code class="highlight"><span class="n">s</span></code></p>
     <li data-md="">
      <p>begins with the construction of <code class="highlight"><span class="n">s</span></code> and ends with <code class="highlight"><span class="n">s</span></code> becoming an <em>xvalue</em></p>
     <li data-md="">
      <p>begins with the construction of <code class="highlight"><span class="n">s</span></code> and ends with the first invocation of
an assignment operator of <code class="highlight"><span class="n">s</span></code>.</p>
     <li data-md="">
      <p>begins with an invocation of an assignment operator of <code class="highlight"><span class="n">s</span></code> and ends with
the immediately subsequent invocation of an assignment operator of <code class="highlight"><span class="n">s</span></code>.</p>
     <li data-md="">
      <p>begins with an invocation of an assignment operator of <code class="highlight"><span class="n">s</span></code> and ends with
the destruction of <code class="highlight"><span class="n">s</span></code></p>
     <li data-md="">
      <p>begins with an invocation of an assignment operator of <code class="highlight"><span class="n">s</span></code> and ends <code class="highlight"><span class="n">s</span></code> becoming an <em>xvalue</em>.</p>
    </ul>
    <p><em>and</em> has the property that <code class="highlight"><span class="n">p</span> <span class="o">==</span> <span class="n">s</span><span class="p">.</span><span class="n">data</span><span class="p">()</span></code> and <code class="highlight"><span class="n">sz</span> <span class="o">==</span> <span class="n">s</span><span class="p">.</span><span class="n">size</span><span class="p">()</span></code>.  We abbreviate
the "<em>restricted lifetime of</em> <code class="highlight"><span class="n">s</span></code> <em>with respect to {</em> <code class="highlight"><span class="n">p</span><span class="p">,</span> <span class="n">sz</span></code> <em>}</em> with the
notation <code class="highlight"><span class="n">L</span><span class="p">{</span><span class="n">s</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="n">sz</span><span class="p">}</span></code>.  The lifetime of <code class="highlight"><span class="n">s</span></code> thus consists of a disjoint set of <em>restricted lifetimes</em> <code class="highlight"><span class="n">L_1</span><span class="p">{</span><span class="n">s</span><span class="p">,</span> <span class="n">p_1</span><span class="p">,</span> <span class="n">sz_1</span><span class="p">}</span></code>, ..., <code class="highlight"><span class="n">L_n</span><span class="p">{</span><span class="n">s</span><span class="p">,</span> <span class="n">p_n</span><span class="p">,</span> <span class="n">sz_n</span><span class="p">}</span></code>.  The truth of <code class="highlight"><span class="n">has_property</span><span class="o">&lt;</span><span class="n">S</span><span class="p">,</span><span class="n">restrict_access</span><span class="o">>::</span><span class="n">value</span></code> implies that during any given
restricted lifetime <code class="highlight"><span class="n">L_i</span><span class="p">{</span><span class="n">s</span><span class="p">,</span> <span class="n">p_i</span><span class="p">,</span> <span class="n">sz_i</span><span class="p">}</span></code> of an instance <code class="highlight"><span class="n">s</span></code> of <code class="highlight"><span class="n">S</span></code>, no value of a
pointer or address of a reference may be used to form a glvalue expression that
modifies an object with an address in the range <code class="highlight"><span class="p">[</span><span class="n">p_i</span><span class="p">,</span> <span class="n">p_i</span> <span class="o">+</span> <span class="n">sz_i</span><span class="p">)</span></code> except for
those derived from:</p>
    <ul>
     <li data-md="">
      <p><code class="highlight"><span class="n">s</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span></code></p>
     <li data-md="">
      <p><code class="highlight"><span class="n">s</span><span class="p">.</span><span class="n">cbegin</span><span class="p">()</span></code></p>
     <li data-md="">
      <p><code class="highlight"><span class="n">s</span><span class="p">.</span><span class="n">rbegin</span><span class="p">()</span></code></p>
     <li data-md="">
      <p><code class="highlight"><span class="n">s</span><span class="p">.</span><span class="n">crbegin</span><span class="p">()</span></code></p>
     <li data-md="">
      <p><code class="highlight"><span class="n">s</span><span class="p">.</span><span class="k">operator</span><span class="p">[]()</span></code></p>
     <li data-md="">
      <p><code class="highlight"><span class="n">s</span><span class="p">.</span><span class="k">operator</span><span class="p">()()</span></code></p>
     <li data-md="">
      <p><code class="highlight"><span class="n">s</span><span class="p">.</span><span class="n">data</span><span class="p">()</span></code></p>
     <li data-md="">
      <p><code class="highlight"><span class="n">as_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">)</span></code></p>
     <li data-md="">
      <p><code class="highlight"><span class="n">as_writable_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">)</span></code></p>
     <li data-md="">
      <p>Any of these operations on a copy of <code class="highlight"><span class="n">s</span></code> made during this restricted lifetime</p>
     <li data-md="">
      <p>Any of these operations on a reference to <code class="highlight"><span class="n">s</span></code> or the dereference of a pointer
to <code class="highlight"><span class="n">s</span></code>.</p>
     <li data-md="">
      <p>Any of these operations on a subspan derived from <code class="highlight"><span class="n">s</span></code></p>
    </ul>
    <p>These restrictions apply to any modifying accesses indeterminately sequenced
with the beginning or end of the given restricted lifetime <code class="highlight"><span class="n">L_i</span></code>.  Any other
accesses that modify the referenced memory through any other means result in
undefined behavior.  Additionally, accessing any object not in the range <code class="highlight"><span class="p">[</span><span class="n">p_i</span><span class="p">,</span> <span class="n">p_i</span> <span class="o">+</span> <span class="n">sz_i</span><span class="p">)</span></code> via a pointer or reference derived from any of the above sources
results in undefined behavior.</p>
   </blockquote>
   <p>Formal wording for the application of the restriction to <code class="highlight"><span class="n">mdspan</span></code> will follow
discussion of the content in the current paper, but it likely to be similar to
the wording for <code class="highlight"><span class="n">span</span></code> above.</p>
   <h2 class="heading settled" data-level="5" id="discussion"><span class="secno">5. </span><span class="content">Discussion</span><a class="self-link" href="#discussion"></a></h2>
   <h3 class="heading settled" data-level="5.1" id="whylib"><span class="secno">5.1. </span><span class="content">Why a library feature?</span><a class="self-link" href="#whylib"></a></h3>
   <p>From <a data-link-type="biblio" href="#biblio-n3988">[N3988]</a> itself and from the on-the-record discussion of it at the
Rapperswil meeting in 2014, here are some of the objections raised about
restrict-like semantics in C++:</p>
   <ul>
    <li data-md="">
     <p>Unclear whether it should affect name mangling</p>
     <ul>
      <li data-md="">
       <p>As a library feature, the name mangling behavior is well-defined and
obvious</p>
     </ul>
    <li data-md="">
     <p>Unclear whether it should affect overloading</p>
     <ul>
      <li data-md="">
       <p>As a library feature, the overload behavior is well-defined and obvious.
It can also be manipulated in the same way as any other template
parameter, for instance using SFINAE.</p>
     </ul>
    <li data-md="">
     <p><code class="highlight"><span class="k">restrict</span></code>, as given in ISO C, has insufficient expressiveness (you cannot
precisely enough describe what is restricted)</p>
     <ul>
      <li data-md="">
       <p>The extensibility of <code class="highlight"><span class="n">Properties</span><span class="p">...</span></code> for <code class="highlight"><span class="n">span</span></code> and <code class="highlight"><span class="n">mdspan</span></code> as a
library feature provides a clear path forward towards addressing this.</p>
     </ul>
    <li data-md="">
     <p>In C, the lifetime of the <code class="highlight"><span class="k">restrict</span></code> contract is awkward to express and
therefore is restricted to initialization.</p>
     <ul>
      <li data-md="">
       <p>Object lifetime of a library wrapper provides clear bounds for the
contract.</p>
     </ul>
    <li data-md="">
     <p>Semantics for implicit or explicit capture of <code class="highlight"><span class="k">restrict</span></code> pointers in lambdas
is unclear.</p>
     <ul>
      <li data-md="">
       <p>As a library feature, the object will not change type during capture,
therefore the transfer of the restrict contract is immediately clear.</p>
     </ul>
   </ul>
  </main>

		Active content removed
	
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-gccrestrictdoc">[GCCRestrictDoc]
   <dd><a href="https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html">Restricted Pointer Aliasing</a>. URL: <a href="https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html">https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html</a>
   <dt id="biblio-llvmirdoc">[LLVMIRDoc]
   <dd><a href="https://llvm.org/docs/LangRef.html">LLVM Language Reference Manual</a>. URL: <a href="https://llvm.org/docs/LangRef.html">https://llvm.org/docs/LangRef.html</a>
   <dt id="biblio-msvcrestrictdoc">[MSVCRestrictDoc]
   <dd><a href="https://docs.microsoft.com/en-us/cpp/cpp/restrict">restrict</a>. URL: <a href="https://docs.microsoft.com/en-us/cpp/cpp/restrict">https://docs.microsoft.com/en-us/cpp/cpp/restrict</a>
   <dt id="biblio-n3538">[N3538]
   <dd>Lawrence Crowl. <a href="https://wg21.link/n3538">Pass by Const Reference or Value</a>. 6 March 2013. URL: <a href="https://wg21.link/n3538">https://wg21.link/n3538</a>
   <dt id="biblio-n3635">[N3635]
   <dd>M. Wong, R. Silvera, R. Mak, C. Cambly, et al.. <a href="https://wg21.link/n3635">Towards restrict-like semantics for C++</a>. 29 April 2013. URL: <a href="https://wg21.link/n3635">https://wg21.link/n3635</a>
   <dt id="biblio-n3988">[N3988]
   <dd>H. Finkel, H. Tong, et al.. <a href="https://wg21.link/n3988">Towards restrict-like aliasing semantics for C++</a>. 23 May 2014. URL: <a href="https://wg21.link/n3988">https://wg21.link/n3988</a>
   <dt id="biblio-n4700">[N4700]
   <dd>Richard Smith. <a href="https://wg21.link/n4700">Working Draft, Standard for Programming Language C++ Note:</a>. URL: <a href="https://wg21.link/n4700">https://wg21.link/n4700</a>
   <dt id="biblio-nvccrestrict">[NVCCRestrict]
   <dd>Jeremy Appleyard. <a href="https://devblogs.nvidia.com/parallelforall/cuda-pro-tip-optimize-pointer-aliasing/">CUDA Pro Tip: Optimize for Pointer Aliasing</a>. URL: <a href="https://devblogs.nvidia.com/parallelforall/cuda-pro-tip-optimize-pointer-aliasing/">https://devblogs.nvidia.com/parallelforall/cuda-pro-tip-optimize-pointer-aliasing/</a>
   <dt id="biblio-p0122r5">[P0122r5]
   <dd>Neil MacIntosh. <a href="https://wg21.link/p0122r5">span: bounds-safe views for sequences of objects</a>. URL: <a href="https://wg21.link/p0122r5">https://wg21.link/p0122r5</a>
   <dt id="biblio-p0546r1">[P0546r1]
   <dd>Carter Edwards, Bryce Lelbach. <a href="https://wg21.link/p0546r1">Span - foundation for the future</a>. URL: <a href="https://wg21.link/p0546r1">https://wg21.link/p0546r1</a>
   <dt id="biblio-wg14-n1570">[WG14-N1570]
   <dd><a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf">Committee Draft, Programming Languages — C</a>. URL: <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf">http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf</a>
   <dt id="biblio-xlcrestrictdoc">[XLCRestrictDoc]
   <dd><a href="https://www.ibm.com/support/knowledgecenter/en/SS2LWA_12.1.0/com.ibm.xlcpp121.bg.doc/language_ref/restrict_type_qualifier.html">The restrict type qualifier</a>. URL: <a href="https://www.ibm.com/support/knowledgecenter/en/SS2LWA_12.1.0/com.ibm.xlcpp121.bg.doc/language_ref/restrict_type_qualifier.html">https://www.ibm.com/support/knowledgecenter/en/SS2LWA_12.1.0/com.ibm.xlcpp121.bg.doc/language_ref/restrict_type_qualifier.html</a>
  </dl>