<!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>P1642R3: Freestanding Library: Easy [utilities], [ranges], and [iterators]</title>
<body>
<h1>Freestanding Library: Easy [utilities], [ranges], and [iterators]</h1>
Document number: P1642R3<br/>
Date: 2020-05-24<br/>
Reply-to: Ben Craig &lt;ben dot craig at gmail dot com&gt;<br/>
Audience: Library Evolution Working Group
<h1>Change history</h1>
<h3> R3 </h3>
<ul>
  <li>Rebased to N4861</li>
  <li>Putting wording back (in the form of instructions to editor)</li>
  <li>Per-header feature test macro, similar to <code>constexpr</code> macros</li>
</ul>
<h3> R2 </h3>
<ul>
  <li>Rebased to N4842</li>
  <li>No longer including <code>istream_view</code></li>
</ul>
<h3> R1 </h3>
<ul>
  <li>Adding section summarizing what is getting added.</li>
  <li>Adding all of [ranges] and most of [iterators]</li>
  <li>Adding <code>uses_allocator_construction_args</code></li>
  <li>Adding feature test macro</li>
  <li>Now discussing split overload sets.</li>
  <li>Dropping wording for now</li>
</ul>
<h3> R0 </h3>
<p>
Branching from P0829R4.  This "omnibus" paper is still the direction I am aiming for.  However, it is too difficult to review.  It needs to change with almost every meeting.  Therefore, it is getting split up into smaller, more manageable chunks.
</p><p>
Limiting paper to the [utilities], [ranges], and [iterators] clauses.
</p>
<h1>Introduction</h1>
<p>
This paper proposes adding many of the facilities in the [utilities], [ranges], and [iterators] clause to the freestanding subset of C++.  The paper will only be adding complete entities, and will not tackle partial classes.  In other words, classes like <code>pair</code> and <code>tuple</code> are being added, but trickier classes like <code>optional</code>, <code>variant</code>, and <code>bitset</code> will come in another paper.
</p><p>
The <code>&lt;memory&gt;</code> header has a dependency on facilities in <code>&lt;ranges&gt;</code> and <code>&lt;iterator&gt;</code>, so those headers (and clauses) are addressed as well.
</p>
<h1>Motivation and Design</h1>
<p>
Many existing facilities in the C++ standard library could be used without trouble in freestanding environments.  This series of papers will specify the maximal subset of the C++ standard library that does not require an OS or space overhead.
</p><p>
For a more in depth rationale, see P0829.
</p><p>
<code>&lt;optional&gt;</code>, <code>&lt;variant&gt;</code>, and <code>&lt;bitset&gt;</code> are not in this paper, as all have non-essential functions that can throw an exception.  <code>&lt;charconv&gt;</code> is not in this paper as it will require us to deal with the thorny issue of overload sets involving floating point and non-floating point types.  I plan on addressing all four of these headers in later papers, so that the topics in question can be debated in relative isolation.
</p>
<h1>Splitting overload sets</h1>
<p>
Modifying an overload set needs to be treated with great care.  Ideally, libraries built in freestanding environments will have the same semantics (including selected overloads) when built in a hosted environment.  I don't think that goal is 100% achievable, as sufficiently clever programmers will be able to detect the difference and modify behavior accordingly.
</p><p>
My approach will be to avoid splitting overload sets that could cause accidental freestanding / hosted differences.  In future papers, I may need to lean on <code>= delete</code> techniques to avoid silent behavior changes, but this paper hasn't needed that approach.
</p><p>
<code>swap</code> has <code>shared_ptr</code>, <code>weak_ptr</code>, and <code>unique_ptr</code> overloads, but this paper only marks the <code>unique_ptr</code> overload as freestanding.  <code>&lt;memory&gt;</code> has many algorithms with <code>ExecutionPolicy</code> overloads.  This paper does not mark the <code>ExectuionPolicy</code> overloads as freestanding.  I was unable to come up with any compelling "accidental" way to select one <code>swap</code> or algorithm overload in freestanding, but a different one in hosted.
</p><p>
Also note that the <code>swap</code> overload set visible to a given translation unit is already indeterminate.  A user may include <code>&lt;memory&gt;</code> which guarantees the smart pointer overloads, but an implementation could expose any (or none!) of the other <code>swap</code> overloads from other STL headers.
</p>
<h1>Justification for omissions</h1>
<p>
The following functions and classes rely on dynamic memory allocation and exceptions:
</p>
<ul>
  <li><code>make_obj_using_allocator</code></li>
  <li><code>make_unique</code></li>
  <li><code>make_unique_default_init</code></li>
  <li><code>shared_ptr</code></li>
  <li><code>weak_ptr</code></li>
  <li><code>function</code></li>
  <li><code>boyer_moore_searcher</code></li>
  <li><code>boyer_moore_horspool_searcher</code></li>
</ul>
<p>
The following classes rely on iostreams facilities.  iostreams facilities use dynamic memory allocations and rely on the operating system.
</p>
<ul>
  <li><code>istream_iterator</code></li>
  <li><code>ostream_iterator</code></li>
  <li><code>istreambuf_iterator</code></li>
  <li><code>ostreambuf_iterator</code></li>
  <li><code>basic_istream_view</code></li>
  <li><code>istream_view</code></li>
</ul>
<p>
The ExecutionPolicy overloads of algorithms are of minimal utility on systems that do not support C++ threads.
</p>
<h1>Feature test macros</h1>
Add the following feature test macros to <b>freestanding only</b>:
<table border="1">
    <thead><tr>
        <th>Name</th>
        <th>Header</th>
    </tr></thead>
    <tbody><tr>
        <td><code>__cpp_lib_freestanding_utility</code></td>
        <td><code>&lt;utility&gt;<code></td>
    </tr><tr>
        <td><code>__cpp_lib_freestanding_tuple</code></td>
        <td><code>&lt;tuple&gt;<code></td>
    </tr><tr>
        <td><code>__cpp_lib_freestanding_ratio</code></td>
        <td><code>&lt;ratio&gt;<code></td>
    </tr><tr>
        <td><code>__cpp_lib_freestanding_memory</code></td>
        <td><code>&lt;memory&gt;<code></td>
    </tr><tr>
        <td><code>__cpp_lib_freestanding_functional</code></td>
        <td><code>&lt;functional&gt;<code></td>
    </tr><tr>
        <td><code>__cpp_lib_freestanding_iterator</code></td>
        <td><code>&lt;iterator&gt;<code></td>
    </tr><tr>
        <td><code>__cpp_lib_freestanding_ranges</code></td>
        <td><code>&lt;ranges&gt;<code></td>
    </tr></tbody>
</table>

<p>The following, existing feature test macros cover some features that I am making freestanding, and some features that I am not requiring to be freestanding.  These feature test macros won't be required in freestanding, as they could cause substantial confusion when the hosted parts of those features aren't available.  The header-based <code>__cpp_lib_freestanding_*</code> macros should provide a suitable replacement in freestanding environments.</p>
<ul>
  <li><code>__cpp_lib_boyer_moore_searcher</code></li>
  <li><code>__cpp_lib_constexpr_dynamic_alloc</code></li>
  <li><code>__cpp_lib_ranges</code></li>
  <li><code>__cpp_lib_raw_memory_algorithms</code></li>
</ul>

<h1>Wording</h1>
Wording assumes that <a href="https://wg21.link/P1641">P1641</a> has been applied.<br>

<h2>Full headers</h2>
Instructions to the editor:<br>
Please add a <span class="comment">// <span class="textit">freestanding</span></span> comment to the beginning of the following synopses.  These headers are entirely freestanding.
<ul>
<li><a href="https://wg21.link/utility.syn">[utility.syn]</a></li>
<li><a href="https://wg21.link/tuple.syn">[tuple.syn]</a></li>
<li><a href="https://wg21.link/ratio.syn">[ratio.syn]</a></li>
</ul>

<h2>Change in <a href="https://wg21.link/memory.syn">[memory.syn]</a></h2>
Instructions to the editor:<br>
Please add a <span class="comment">// <span class="textit">freestanding</span></span> comment to the following declarations:
<ul>
  <li><code>pointer_traits</code></li>
  <li><code>to_address</code></li>
  <li><code>align</code></li>
  <li><code>assume_aligned</code></li>
  <li><code>allocator_arg_t</code></li>
  <li><code>allocator_arg</code></li>
  <li><code>uses_allocator</code></li>
  <li><code>uses_allocator_v</code></li>
  <li><code>uses_allocator_construction_args</code></li>
  <li><code>allocator_traits</code></li>
  <li>[specialized.algorithms], except for the <code>ExecutionPolicy</code> overloads.  This includes the algorithms in the <code>ranges</code> namespace</li>
  <li><code>default_delete</code></li>
  <li><code>unique_ptr</code></li>
  <li><code>unique_ptr</code> overload of <code>swap</code></li>
  <li>relational operators (including three-way / spaceship) involving <code>unique_ptr</code></li>
  <li><code>hash</code></li>
  <li><code>unique_ptr</code> specialization of <code>hash</code></li>
  <li><code>atomic</code></li>
</ul>

Note: the following portions of <code>&lt;memory&gt;</code> are <b>omitted</b>.  No change to the working draft should be made for these declarations:
<ul>
  <li>[util.dynamic.safety], pointer safety</li>
  <li><code>make_obj_using_allocator</code></li>
  <li><code>uninitialized_construct_using_allocator</code></li>
  <li><code>allocator</code> and associated comparisons</li>
  <li><code>ExecutionPolicy</code> overloads in [specialized.algorithms]</li>
  <li><code>make_unique</code></li>
  <li><code>make_unique_default_init</code></li>
  <li>All <code>operator&lt;&lt;</code> overloads</li>
  <li><code>bad_weak_ptr</code></li>
  <li><code>shared_ptr</code></li>
  <li><code>make_shared</code></li>
  <li><code>allocate_shared</code></li>
  <li><code>make_shared_default_init</code></li>
  <li><code>allocate_shared_default_init</code></li>
  <li>relational operators (including three-way / spaceship) involving <code>shared_ptr</code></li>
  <li><code>shared_ptr</code> overload of <code>swap</code></li>
  <li><code>static_pointer_cast</code></li>
  <li><code>dynamic_pointer_cast</code></li>
  <li><code>const_pointer_cast</code></li>
  <li><code>reinterpret_pointer_cast</code></li>
  <li><code>get_deleter</code></li>
  <li><code>weak_ptr</code></li>
  <li><code>weak_ptr</code> overload of <code>swap</code></li>
  <li><code>owner_less</code></li>
  <li><code>enable_shared_from_this</code></li>
  <li><code>shared_ptr</code> specialization of <code>hash</code></li>
  <li><code>shared_ptr</code> specialization of <code>atomic</code></li>
  <li><code>weak_ptr</code> specialization of <code>atomic</code></li>
</ul>

<h2>Change in <a href="https://wg21.link/functional.syn">[functional.syn]</a></h2>
Instructions to the editor:<br>
Please add a <span class="comment">// <span class="textit">freestanding</span></span> comment to every entity in <code>&lt;functional&gt;</code> <b>except</b> for the following entities:
<ul>
  <li><code>bad_function_call</code></li>
  <li><code>function</code></li>
  <li><code>function</code> overloads of <code>swap</code></li>
  <li><code>function</code> overloads of <code>operator==</code></li>
  <li><code>boyer_moore_searcher</code></li>
  <li><code>boyer_moore_horspool_searcher</code></li>
</ul>

<h2>Change in <a href="https://wg21.link/iterator.synopsis">[iterator.synopsis]</a></h2>
Instructions to the editor:<br>
Please add a <span class="comment">// <span class="textit">freestanding</span></span> comment to every entity in <code>&lt;iterator&gt;</code> <b>except</b> for the following entities:
<ul>
  <li><code>istream_iterator</code> and associated comparison operators</li>
  <li><code>ostream_iterator</code></li>
  <li><code>istreambuf_iterator</code> and associated comparison operators</li>
  <li><code>ostreambuf_iterator</code></li>
</ul>

<h2>Change in <a href="https://wg21.link/ranges.syn">[ranges.syn]</a></h2>
Instructions to the editor:<br>
Please add a <span class="comment">// <span class="textit">freestanding</span></span> comment to every entity in <code>&lt;ranges&gt;</code> <b>except</b> for the following entities:
<ul>
  <li><code>basic_istream_view</code></li>
  <li><code>istream_view</code></li>
</ul>

<h2>Change in <a href="https://wg21.link/version.syn">[version.syn]</a></h2>
Please add a <span class="comment">// <span class="textit">freestanding</span></span> comment to each of the following macro definitions:
<ul>
  <li><code>__cpp_lib_addressof_constexpr</code></li>
  <li><code>__cpp_lib_allocator_traits_is_always_equal</code></li>
  <li><code>__cpp_lib_apply</code></li>
  <li><code>__cpp_lib_as_const</code></li>
  <li><code>__cpp_lib_assume_aligned</code></li>
  <li><code>__cpp_lib_atomic_value_initialization</code></li>
  <li><code>__cpp_lib_bind_front</code></li>
  <li><code>__cpp_lib_constexpr_functional</code></li>
  <li><code>__cpp_lib_constexpr_iterator</code></li>
  <li><code>__cpp_lib_constexpr_memory</code></li>
  <li><code>__cpp_lib_constexpr_tuple</code></li>
  <li><code>__cpp_lib_constexpr_utility</code></li>
  <li><code>__cpp_lib_exchange_function</code></li>
  <li><code>__cpp_lib_integer_sequence</code></li>
  <li><code>__cpp_lib_invoke</code></li>
  <li><code>__cpp_lib_make_from_tuple</code></li>
  <li><code>__cpp_lib_make_reverse_iterator</code></li>
  <li><code>__cpp_lib_nonmember_container_access</code></li>
  <li><code>__cpp_lib_not_fn</code></li>
  <li><code>__cpp_lib_null_iterators</code></li>
  <li><code>__cpp_lib_ssize</code></li>
  <li><code>__cpp_lib_to_address</code></li>
  <li><code>__cpp_lib_transparent_operators</code></li>
  <li><code>__cpp_lib_tuple_element_t</code></li>
  <li><code>__cpp_lib_tuples_by_type</code></li>
  <li><code>__cpp_lib_unwrap_ref</code></li>
</ul>
Please add the following macro definitions:

<blockquote class="std"><pre class="codeblock"><ins>
#define __cpp_lib_freestanding_functional   202005L // also in &lt;functional&gt;, freestanding only
#define __cpp_lib_freestanding_iterator     202005L // also in &lt;iterator&gt;, freestanding only
#define __cpp_lib_freestanding_memory       202005L // also in &lt;memory&gt;, freestanding only
#define __cpp_lib_freestanding_ranges       202005L // also in &lt;ranges&gt;, freestanding only
#define __cpp_lib_freestanding_ratio        202005L // also in &lt;ratio&gt;, freestanding only
#define __cpp_lib_freestanding_tuple        202005L // also in &lt;tuple&gt;, freestanding only
#define __cpp_lib_freestanding_utility      202005L // also in &lt;utility&gt;, freestanding only
</pre></blockquote></ins>

<h1>Acknowledgements</h1>
<p>
Thanks to Brandon Streiff, Joshua Cannon, Phil Hindman, and Irwan Djajadi for reviewing P0829.
</p><p>
Thanks to Odin Holmes for providing feedback and helping publicize P0829.
</p><p>
Thanks to Paul Bendixen for providing feedback while prototyping P0829.
</p><p>
Similar work was done in the C++11 timeframe by Lawrence Crowl and Alberto Ganesh Barbati in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3256.html">N3256</a>.
</p>
</body>
</html>
