<!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>P1642R2: Freestanding Library: Easy [utilities], [ranges], and [iterators]</title>
<body>
<h1>Freestanding Library: Easy [utilities], [ranges], and [iterators]</h1>
Document number: P1642R2<br/>
Date: 2020-01-10<br/>
Reply-to: Ben Craig &lt;ben dot craig at gmail dot com&gt;<br/>
Audience: SG14, Library Evolution Working Group
<h1>Change history</h1>
<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 macro to freestanding only:
<table border="1">
    <thead><tr>
        <th>Name</th>
        <th>Value</th>
        <th>Header</th>
    </tr></thead>
    <tbody><tr>
        <td><code>__cpp_lib_freestanding_iterator</code></td>
        <td><var ignore="true">202001</var></td>
        <td><code>&lt;version&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.</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>Summary of inclusions</h1>
<p>
The entirety of the following headers are included:
<ul>
  <li><code>&lt;utility&gt;</code></li>
  <li><code>&lt;tuple&gt;</code></li>
  <li><code>&lt;ratio&gt;</code></li>
</ul>
The following portions of <code>&lt;memory&gt;</code> are included:
<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>
The following portions of <code>&lt;memory&gt;</code> are <b>omitted</b>:
<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>

Mark everything in <code>&lt;functional&gt;</code> as freestanding <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>

Mark everything in <code>&lt;iterator&gt;</code> as freestanding <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>

Mark everything in <code>&lt;ranges&gt;</code> as freestanding <b>except</b> for the following entities:
<ul>
  <li><code>basic_istream_view</code></li>
  <li><code>istream_view</code></li>
</ul>

Mark the following macros in <code>&lt;version&gt;</code> as freestanding
<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>

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