<!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>P2833R0: Freestanding Library: inout expected span</title>
<body>
<h1>Freestanding Library: inout expected span</h1>
Document number: P2833R0<br/>
Date: 2023-03-13<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>
First revision!

<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 P2338 "Freestanding Library: Character primitives and the C library".
</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>

<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 is prototyping <code>out_ptr</code> and <code>inout_ptr</code> changes with MSVC's STL.
Ask about this implementation experience during the LEWG review!
</p>

<h1>Wording</h1>
This paper’s wording is based on the current working draft, [N4928], and it assumes that [P2338R4] 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 class introduced by a freestanding deleted class template declaration is a freestanding item or undefined.</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>
Instructions to the editor:<br/>
Add the following macro to <a href="https://eel.is/c++draft/version.syn">[version.syn]</a>:
<blockquote class="stdins">
<pre class='codeblock'>
#define __cpp_lib_freestanding_expected 20XXXXL //also in &lt;expected&gt;
#define __cpp_lib_freestanding_mdspan 20XXXXL //also in &lt;mdspan&gt;
</pre>
</blockquote>

Update the integer literal for the following macros:
<ul>
  <li><code>__cpp_lib_out_ptr</code></li>
  <li><code>__cpp_lib_span</code></li>
</ul>

<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>// freestanding-partial</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>
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>

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

[P2338R4] Ben Craig. 2022-12-06. Freestanding Library: Character primitives and the C library.<br/>
&emsp;&emsp;https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2338r4.html<br/>

</body>
</html>
