<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<html>
<style type="text/css">
  ins, ins * { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  del, del * { text-decoration:line-through; background-color:#FFA0A0 }
  #hidedel:checked ~ * del, #hidedel:checked ~ * del * { display:none; visibility:hidden }

blockquote {
  padding: .5em;
  border: .5em;
  border-color: silver;
  border-left-style: solid;
}

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em; padding-right: 0.5em; }

p.grammarlhs { margin-bottom: 0 }
p.grammarrhs { margin-left:8em; margin-top:0; margin-bottom:0; text-indent:-4em }

div.wrapper {
    max-width: 60em;
    margin: auto;
}

a { text-decoration: none; }

a.hidden_link {
    text-decoration: none;
    color: inherit;
}

li {
    margin-top: 0.0em;
    margin-bottom: 0.0em;
}

h1 { line-height: 1; }
h2 { line-height: 1; }
h3 { line-height: 1; }
h4 { line-height: 1; }

: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; }
.annexnum { display: block; }

div.sourceLinkParent {
    float: right;
}

a.sourceLink {
    position: absolute;
    opacity: 0;
    margin-left: 10pt;
}

a.sourceLink:hover {
    opacity: 1;
}

div.marginalizedparent {
    position: relative;
    left: -5em;
}

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: "Ã¢Å¸Âµ"; }
    /* this way the content is not selectable */

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;
}

.bnftab {
    font-family: serif;
    font-style: italic;
    margin-left: 40pt;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
}

.ncsimplebnf {
    font-family: serif;
    font-style: italic;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 40pt;
}

.ncbnftab {
    font-family: serif;
    font-style: italic;
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 40pt;
}

.bnfkeywordtab {
    margin-top: 0.5em;
    margin-bottom: 0.5em;
    margin-left: 40pt;
}

span.textnormal {
    font-style: normal;
    font-family: serif;
    white-space: normal;
    display: inline-block;
}

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 { }

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%;
}

code {
    font-family: monospace;
    font-style: normal;
}

code.itemdecl {
    margin-top: 2ex;
    white-space: pre;
    display: block;
}

.comment {
    font-style: italic;
    font-family: serif;
}

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; /* otherwise some columns get very narrow, e.g. [tab:hash] */
}

td, th {
    padding-left: 1em;
    padding-right: 1em;
    vertical-align: top;
}

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.capsep {
    border-top: 3px solid black;
    border-top-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;
}
</style>

<title>P2833R2: Freestanding Library: inout expected span</title>
<body>
<h1>Freestanding Library: inout expected span</h1>
Document number: P2833R2<br/>
Date: 2023-09-13<br/>
Reply-to: Ben Craig &lt;ben dot craig at gmail dot com&gt;<br/>
Audience: Library Working Group

<h1>Changes from previous revisions</h1>
<h3>Changes from R1</h3>
<ul>
<li>Removed forward declaration of <code>shared_ptr</code></li>
</ul>
<h3>Changes from R0</h3>
<ul>
<li>Reworked wording based on changes in P2407R5</li>
<li>Made feature test macros <code>// freestanding</code></li>
<li>Discuss P2821 <code>span::at</code> merge conflict</li>
</ul>

<h1>Introduction</h1>
<p>
This proposal is part of a group of papers aimed at improving the state of freestanding.
It adds facilities that are largely unrelated to each other, but didn't fit into a better category.
Most of these facilities were added in C++23, and missed the last sweep of freestanding utilities.
</p><p>
At a high level, this proposal adds the following facilities:
<ul>
    <li><code>out_ptr</code></li>
    <li><code>inout_ptr</code></li>
    <li>Most of <code>expected</code></li>
    <li><code>span</code></li>
    <li><code>mdspan</code></li>
</ul>
</p>

<h1>Motivation and Scope</h1>
<p>
On hosted implementations, the included facilities don't directly require heap allocations, don't use system calls, and don't require exceptions.
The facilities are generally useful.
This combination keeps the burden low for standard library implementations to single source these facilities as both hosted and freestanding.
</p>

<h1>Design</h1>
<p>
All overloads of <code>expected::value</code> are deleted, as they can throw exceptions.
This follows the precedent from P2407 "Freestanding Library: Partial Classes".
</p><p>
<code>out_ptr</code> and <code>inout_ptr</code> have mandates involving <code>shared_ptr</code>.
<code>shared_ptr</code> is not freestanding.
This paper leaves those mandates in place, without changing the freestanding status of <code>shared_ptr</code>.
Implementations are expected to <code>#if</code> out those mandates as needed.
</p><p>
This paper mostly follows the guide lines as specified in [P2198R6] "Freestanding Feature-Test Macros and Implementation-Defined Extensions".
However, <code>__cpp_lib_freestanding_mdspan</code> is added instead of bumping <code>__cpp_lib_mdspan</code> because I suspect the mdspan authors will be bumping the <code>__cpp_lib_mdspan</code> macro frequently in the C++26 cycle.
When multiple orthogonal papers bump the same feature test macro, it becomes difficult for users to test for the specific features they care about.
</p><p>
The in flight paper [P2821] "span.at()" paper adds <code>at()</code> to <code>span</code>.  The <code>at()</code> function originates exceptions, so it will not be required to be present in a freestanding implementation.  This follows the precedent set by <code>array</code> in P2407 "Freestanding Library: Partial Classes".
</p>

<h1>Experience</h1>
<p>
[P0323R12 std::expected] cites usage experience on bare metal systems without exceptions enabled.
[P0009R18 MDSPAN] has a reference implementation that is usable with CUDA.
<code>mdspan</code> uses <code>span</code> in the implementation and interface, so the CUDA experience extends to <code>span</code> as well.
</p><p>
The author has prototyped the necessary <code>out_ptr</code> and <code>inout_ptr</code> changes with MSVC's STL.
This involved <code>#if</code>'ing out <code>shared_ptr</code> and <code>weak_ptr</code> facilities, as well as one <code>static_assert</code> in <code>out_ptr_t</code> and one <code>static_assert</code> in <code>inout_ptr_t</code>.
The tests worked as is, except for the ones specifically testing <code>shared_ptr</code>.
</p>

<h1>Wording</h1>
This paper’s wording is based on the current working draft, [N4950], and it assumes that [P2407R5] has been applied.

<h2>Changes in <a href="https://eel.is/c++draft/compliance">[compliance]</a></h2>
Add new rows to the "C++ headers for freestanding implementations" table:
<table style="border: 1px solid black">
<thead>
<tr style="border: 1px solid black">
<th colspan="2" style="text-align: center">Subclause</th><th style="text-align: center">Header(s)</th>
</tr>
</thead>
<tbody>
<tr style="border: 1px solid black">
<td style="padding: 0ex 1ex 0ex 1ex">[&hellip;]</td>
<td style="padding: 0ex 1ex 0ex 1ex">[&hellip;]</td>
<td style="padding: 0ex 1ex 0ex 1ex">[&hellip;]</td>
</tr>
<tr style="border: 1px solid black">
<td style="padding: 0ex 1ex 0ex 1ex"><ins>?.? <a href="https://wg21.link/expected">[expected]</a></ins></td>
<td style="padding: 0ex 1ex 0ex 1ex"><ins>Expected objects</ins></td>
<td style="padding: 0ex 1ex 0ex 1ex"><ins><tt>&lt;expected&gt;</tt></ins></td>
</tr>
<tr style="border: 1px solid black">
<td style="padding: 0ex 1ex 0ex 1ex"><ins>?.? <a href="https://eel.is/c++draft/views.contiguous">[views.contiguous]</a></ins></td>
<td style="padding: 0ex 1ex 0ex 1ex"><ins>Contiguous access</ins></td>
<td style="padding: 0ex 1ex 0ex 1ex"><ins><tt>&lt;span&gt;</tt></ins></td>
</tr>
<tr style="border: 1px solid black">
<td style="padding: 0ex 1ex 0ex 1ex"><ins>?.? <a href="https://eel.is/c++draft/views.multidim">[views.multidim]</a></ins></td>
<td style="padding: 0ex 1ex 0ex 1ex"><ins>Multidimensional access </ins></td>
<td style="padding: 0ex 1ex 0ex 1ex"><ins><tt>&lt;mdspan&gt;</tt></ins></td>
</tr>
<tr style="border: 1px solid black">
<td style="padding: 0ex 1ex 0ex 1ex">[&hellip;]</td>
<td style="padding: 0ex 1ex 0ex 1ex">[&hellip;]</td>
<td style="padding: 0ex 1ex 0ex 1ex">[&hellip;]</td>
</tr>
</tbody>
</table>

<h2>Changes in <a href="https://eel.is/c++draft/version.syn">[version.syn]</a></h2>
Drafting note: <code>__cpp_lib_mdspan</code> is intentionally left unmodified.<br/>
<blockquote class="std">
<pre class='codeblock'>
<ins>#define __cpp_lib_freestanding_expected             <i>new-val</i> // freestanding, also in &lt;expected&gt;</ins>
<ins>#define __cpp_lib_freestanding_mdspan               <i>new-val</i> // freestanding, also in &lt;mdspan&gt;</ins>
<i>...</i>
#define __cpp_lib_out_ptr                           <del>202106L</del><ins><i>new-val</i></ins> // <ins>freestanding, </ins>also in &lt;memory&gt;
<i>...</i>
#define __cpp_lib_span                              <del>202002L</del><ins><i>new-val</i></ins> // <ins>freestanding, </ins>also in &lt;span&gt;
</pre>
</blockquote>

<h2>Changes in <a href="https://eel.is/c++draft/memory.syn">[memory.syn]</a></h2>
Instructions to the editor:<br/>
<p>
Please append a <code><i>// freestanding</i></code> comment to the following declarations:
<ul>
  <li><code>out_ptr_t</code></li>
  <li><code>out_ptr</code></li>
  <li><code>inout_ptr_t</code></li>
  <li><code>inout_ptr</code></li>
</ul>
</p>

<h2>Changes in <a href="https://eel.is/c++draft/expected.syn">[expected.syn]</a></h2>
Instructions to the editor:<br/>
<p>
Please insert a <code><i>// mostly freestanding</i></code> comment at the beginning of the <a href="https://eel.is/c++draft/expected.syn">[expected.syn]</a> synopsis.<br/>
</p><p>
Please append a <code><i>// partially freestanding</i></code> comment to every <code>expected</code> declaration in the synopsis.
</p>

<h2>Changes in <a href="https://eel.is/c++draft/expected.object.general">[expected.object.general]</a></h2>
Instructions to the editor:<br/>
<p>
Please append a <code><i>// freestanding-deleted</i></code> comment to every <code>value</code> overload in the class synopsis.
</p>

<h2>Changes in <a href="https://eel.is/c++draft/expected.object.general">[expected.void.general]</a></h2>
Instructions to the editor:<br/>
<p>
Please append a <code><i>// freestanding-deleted</i></code> comment to every <code>value</code> overload in the class synopsis.
</p>

<h2>Changes in <a href="https://eel.is/c++draft/span.syn">[span.syn]</a></h2>
There are two versions of this wording.
One version assumes that span.at() has been added in [P2821] "span.at()", the other version assumes that it has not been added yet.

<h3>Changes assuming [P2821] "span.at()" has <b>NOT</b> been merged</h3>
Instructions to the editor:<br/>
<p>
Please insert an <code><i>// all freestanding</i></code> comment at the beginning of the <a href="https://eel.is/c++draft/span.syn">[span.syn]</a> synopsis.<br/>
</p>

<h3>Changes assuming [P2821] "span.at()" has been merged</h3>
Instructions to the editor:<br/>
<p>
Please insert a <code><i>// mostly freestanding</i></code> comment at the beginning of the <a href="https://eel.is/c++draft/span.syn">[span.syn]</a> synopsis.
</p><p>
Please append a <code><i>// partially freestanding</i></code> comment to the <code>span</code> declaration.
</p>

<h2>Changes in <a href="https://eel.is/c++draft/views.span">[views.span]</a></h2>
<p>
Drafting note: Only apply this change if [P2821] "span.at()" has been merged.
</p><p>
Please append a <code><i>// freestanding-deleted</i></code> comment to every overload of <code>at</code>.
</p>

<h2>Changes in <a href="https://eel.is/c++draft/mdspan.syn">[mdspan.syn]</a></h2>
Instructions to the editor:<br/>
<p>
Please insert an <code><i>// all freestanding</i></code> comment at the beginning of the <a href="https://eel.is/c++draft/mdspan.syn">[mdspan.syn]</a> synopsis.<br/>
</p>

<h1>References</h1>
[P0009R18] Christian Trott et al. 2022-07-13. MDSPAN.<br/>
&emsp;&emsp;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html<br/>

[P0122R7] Neil MacIntosh et al. 2018-03-16. span: bounds-safe views for sequences of objects.<br/>
&emsp;&emsp;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0122r7.pdf<br/>

[P0323R12] Vicente Botet et al. 2022-01-07. std::expected.<br/>
&emsp;&emsp;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html<br/>

[P1132R8] JeanHeyd Meneide et al. 2021-06-15. out_ptr - a scalable output pointer abstraction.<br/>
&emsp;&emsp;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1132r8.html<br/>

[P2407R5] Ben Craig. 2023-07-26. Freestanding Library: Freestanding Library: Partial Classes.<br/>
&emsp;&emsp;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2338r4.html<br/>

[N4950] Thomas Köppe. 2023-05-10. Working Draft, Standard for Programming Language C++.<br/>
&emsp;&emsp;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf<br/>

</body>
</html>
