<!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>P2833R1: Freestanding Library: inout expected span</title>
<body>
<h1>Freestanding Library: inout expected span</h1>
Document number: P2833R1<br/>
Date: 2023-08-19<br/>
Reply-to: Ben Craig &lt;ben dot craig at gmail dot com&gt;<br/>
Audience: Library Evolution Working Group

<h1>Changes from previous revisions</h1>
<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>
The declaration of <code>shared_ptr</code> is included, but the template class is left undefined.
This allows <code>out_ptr</code> and <code>inout_ptr</code> to disallow certain <code>shared_ptr</code> usages in the same way in hosted and freestanding.
This approach is less specification work and less implementation work, while still providing reasonable diagnostics to users if they mistakenly use <code>shared_ptr</code> on a minimal freestanding implementation.
This approach still allows non-minimal freestanding implementations to provide a <code>shared_ptr</code> implementation that will interact with <code>out_ptr</code> and <code>inout_ptr</code> the same as they do on hosted implementations.
</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>weak_ptr</code>, as well as the definitions of <code>shared_ptr</code> facilities.
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>Change in <a href="https://eel.is/c++draft/freestanding.item">[freestanding.item]</a></h2>
Add a new paragraph to <a href="https://wg21.link/freestanding.item">[freestanding.item]</a>.

<blockquote class="stdins">
<div class="para">
    <div class="marginalizedparent"><a class="marginalized">?</a></div>
    <div class="sentence">Class template declarations followed by a comment that include <span class="textit">freestanding-deleted</span> are <span class="textit">freestanding deleted class template declarations</span>.</div>
    <div class="sentence">On freestanding implementations, it is implementation-defined whether each entity introduced by a freestanding deleted class template declaration is undefined or whether the requirements are the same as the corresponding requirements for a hosted implementation.</div>
    <div class="note">[  <span class="textit">Note:</span> An instantiation of an undefined template yields an incomplete class type (<a href="https://wg21.link/temp.inst#2.sentence-4">temp.inst#2.sentence-4</a>). -<i>end note</i>]</div>
    <div class="example">[  <span class="textit">Example:</span>
<pre class="codeblock">template&lt;class T&gt; class shared_ptr; <span class="comment">// <span class="textit">freestanding-deleted</span></span>
</pre>
    -<i>end example</i>]</div>
</div>
</blockquote>

<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-deleted</i></code> comment to the following declaration:
<ul>
  <li><code>shared_ptr</code></li>
</ul>
</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>

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