<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
    <title>Rebase the Library Fundamentals v3 TS on C++20</title>
    <style type="text/css">
      html { margin: 0; padding: 0; color: black; background-color: white; }
      body { padding: 2em; font-size: medium; font-family: "DejaVu Serif", serif; line-height: 150%; }
      code { font-family: "DejaVu Sans Mono", monospace; color: #006; }

      h1, h2, h3 { margin: 1.5em 0 .75em 0; line-height: 125%; }

      sup, sub { line-height: 0; }

      div.code { white-space: pre-line; font-family: "DejaVu Sans Mono", monospace;
                 border: thin solid #E0E0E0; background-color: #F8F8F8; padding: 1em;
                 border-radius: 4px; }

      div.strictpre { white-space: pre; }

      div.code em { font-family: "DejaVu Serif", serif; }

      table { border: 2px solid black; border-collapse: collapse; margin: 3em auto; }
      thead th { border-bottom: 2px solid black; }
      th, td { text-align: left; padding: 1ex; border: 1px solid black; }
      th:first-child, td:first-child { padding-left: 1ex; }

      tr.new td { background-color: #EFE; }
      td.new:after { content: "new!"; font-family: "DejaVu Sans", sans-serif; font-weight: bold; font-size: xx-small;
                     vertical-align: top; top: -1em; right: -1em; position: relative; float: right; color: #090; }

      .docinfo { float: right }
      .docinfo p { margin: 0; text-align:right; }
      .docinfo address { font-style: normal; }

      .quote { display: inline-block; clear: both; margin-left: 1ex;
               border: thin solid #E0E0E0; background-color: #F8F8F8; padding: 1ex; }

      .placeholder { font-style: italic; }

      /*  Use DIV[insert] and DIV[delete] if the entire paragraph is added or removed; otherwise
       *  use DIV[modify] and use INS/DEL elements to mark up individual changes.
       */

      div.insert { border-left: thick solid #0A0; border-right: thick solid #0A0; padding: 0 1em; }
      div.modify { border-left: thick solid #999; border-right: thick solid #999; padding: 0 1em; }
      div.delete { border-left: thick solid #A00; border-right: thick solid #A00; padding: 0 1em; }

      .comment { color: #753; }

      del { color: #A00; text-decoration: line-through; }
      ins { color: #090; }
      ins code, del code { color: inherit; }

      .box { border: thin black solid; padding: 2px; }

      .nowrap { white-space: nowrap; }
    </style>
  </head>
  <body>
    <div class="docinfo">
      <p>ISO/IEC JTC 1/SC 22/WG 21 P2081R1</p>
      <p>Date: 2020-02-14</p>
      <p>Audience: LEWG, LWG</p>
      <address>
        Thomas K&ouml;ppe &lt;<a href="mailto:tkoeppe@google.com">tkoeppe@google.com</a>&gt;<br />
      </address>
    </div>

    <h1>Rebase the Library Fundamentals v3 TS on C++20</h1>

    <h2>Abstract</h2>

    <p>The Library Fundamentals v3 TS should be based on C++20.</p>

    <h2>Contents</h2>
    <!-- fgrep -e "<h2 id=" rebase_lfts.html | sed -e 's/.*id="\(.*\)">\(.*\)<\/h2>/<li><a href="#\1">\2<\/a><\/li>/g' -->
    <ol>
      <li><a href="#history">Revision history</a></li>
      <li><a href="#proposal">Proposal</a></li>
      <li><a href="#wording">Proposed wording</a>
        <ol>
          <li><a href="#frontmatter">Front matter updates</a></li>
          <li><a href="#deletions">Deletions of merged material</a></li>
          <li><a href="#sysups">Systematic updates of the method of specification and presentation</a></li>
        </ol>
      </li>
    </ol>

    <h2 id="history">Revision history</h2>
    <ul>
      <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2081r0.html">P2081R0</a>:
        Initial proposal, pre-Prague 2020.</li>
      <li>P2081R1 (this revision): Also remove <code>make_array</code> (with discussion);
        provide full edit instructions for <em>Mandates</em>/... changes, and use the new
        &ldquo;enabled hash specialization&rdquo; wording.</li>
    </ul>

    <h2 id="proposal">Proposal</h2>

    <p>The working draft of the Extensions for Library Fundamentals, Version 3
    Technical Specification (&ldquo;LFTSv3&rdquo; or just &ldquo;LFTS&rdquo; for
    short) is currently (as of
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0996r1.html">P0996R1</a>)
    based on the published C++ standard, i.e. C++17. It is very unlikely, and
    indeed not planned at this point, that we will publish the TS before the
    C++20 DIS has been published (which we expect to happen at the next meeting
    as of the time of writing, which is Prague 2020). Therefore, we have the option
    of basing the TS on the C++20 DIS, and we should do this to allow us to remove
    facilities that have been merged into the main standard, and to take advantage
    of new language facilities.</p>

    <p>If the C++20 IS is published before we complete the PDTS ballot for the
    LFTS, we should update the LFTS working draft to refer to the IS instead of
    the DIS. The acceptance of this proposal should include approval of such a
    future change, which would then be an editorial matter to align the wording
    with the design intent.</p>

    <p><strong>A noteworthy removal:</strong> We propose to remove <code>make_array</code>
    from the TS. The feature was added to the TS by
    <a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4391.html">N4391</a>
    (adopted in Lenexa 2015) together with <code>to_array</code>. Later,
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0325r4.html">P0325R4</a>
    (adopted in Cologne 2019) added <code>to_array</code> to the C++20 working draft,
    but <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0325r4.html#Impact-on-the-Standard">explained</a>
    that because of class template argument deduction, &ldquo;we no longer need <code>make_array</code>&rdquo;.

    <p><strong>Other removals:</strong> Uniform container erasure was moved into C++20 by
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1209r0.html">P1209R0</a>
    (adopted in San Diego 2018), and <code>source_location</code> was moved by
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r6.pdf">P1208R6</a>
    (adopted in Cologne 2019).</p>

    <h2 id="wording">Proposed wording</h2>

    <h3 id="frontmatter">Front matter updates</h3>

    <p>Modify [1.2, general.references] paragraphs 1, 2, and 3 as follows:</p>

    <div class="modify">
      <p><strong>1.2 Normative references [general.references]</strong></p>

      <p>1. The following referenced document is indispensable for the application
      of this document. For dated references, only the edition cited applies.
      For undated references, the latest edition of the referenced document
      (including any amendments) applies.</p>

      <ul><li>ISO/IEC <del>14882:2017</del><ins>14882:&ndash;</ins>, Programming Languages &mdash; C++</li></ul>
      <p><ins>[<em>Note</em>: Under preparation. Stage at the time of publication: ISO/DIS 14882:2020.
      &mdash;&nbsp;<em>end note</em>]</ins></p>

      <p>2. ISO/IEC <del>14882:2017</del><ins>14882:&ndash;</ins> is herein
      called the <em>C++ Standard</em>. References to clauses within the C++
      Standard are written as "<del>C++17</del><ins>C++20</ins> §3.2". The
      library described in ISO/IEC <del>14882:2017 clauses
      20&ndash;33</del><ins>14882:&ndash; clauses 16&ndash;32</ins> is herein
      called the <em>C++ Standard Library.</em></p>

      <p>3. Unless otherwise specified, the whole of the C++ Standard's Library
      introduction (<del>C++17 §20</del><ins>C++20 §16</ins>) is included into
      this Technical Specification by reference.</p>
    </div>

    <p>Modify [1.3, general.namespaces] paragraphs 2:</p>

    <div class="modify">
      <p>2. Each header described in this technical specification shall import the
        contents of <code>std::experimental::fundamentals_v3</code> into
        <code>std::experimental</code> as if by</p>
      <div class="code"><del>namespace std::experimental {</del>
        &nbsp; <del>inline namespace fundamentals_v3 {}</del>
        <del>}</del>
        <ins>namespace std::experimental::inline fundamentals_v3 {}</ins>
      </div>
    </div>

    <h3 id="deletions">Deletions of merged material</h3>

    <p>Delete subclause [6, container]. This includes the deletion of <code>make_array</code>,
    as discussed above, which does <em>not</em> appear in C++20.</p>

    <div class="delete">
      <p><strong><del>6 Containers [container]</del></strong></p>
      <p><strong><del>6.1 Uniform container erasure [container.erasure]</del></strong></p>
      <p><strong><del>6.1.1 Header synopsis [container.erasure.syn]</del></strong></p>
      <p><del>1. For brevity, [&hellip;]</del></p>
      <p><del>[&hellip;] are intentionally not provided. &ndash;&nbsp;<em>end note</em>]</del></p>
      <p><strong><del>6.2 Class template <code>array</code> [container.array]</del></strong></p>
      <p><strong><del>6.2.1 Header <code>&lt;experimental/array&gt;</code> synopsis [array.syn]</del></strong></p>
      <p><del>[&hellip;]</del></p>
      <p><strong><del>6.2.2 Array creartion functions [container.array.creation]</del></strong></p>
      <p><del>[&hellip;]</del></p>
    </div>

    <p>Delete clause [11, reflection].</p>
    <div class="delete">
      <p><strong><del>11 Reflection library [reflection]</del></strong></p>
      <p><del>[&hellip;]</del></p>
    </div>

    <p>Delete from Table 1 &mdash; C++ library headers:</p>
    <div class="modify">
      <code>&lt;experimental/algorithm&gt;</code><br>
      <del><code>&lt;experimental/array&gt;</code></del><br>
      <del><code>&lt;experimental/deque&gt;</code></del><br>
      <del><code>&lt;experimental/forward_list&gt;</code></del><br>
      <code>&lt;experimental/functional&gt;</code><br>
      <code>&lt;experimental/future&gt;</code><br>
      <code>&lt;experimental/iterator&gt;</code><br>
      <del><code>&lt;experimental/list&gt;</code></del><br>
      <del><code>&lt;experimental/map&gt;</code></del><br>
      <code>&lt;experimental/memory&gt;</code><br>
      <code>&lt;experimental/memory_resource&gt;</code><br>
      <code>&lt;experimental/propagate_const&gt;</code><br>
      <code>&lt;experimental/random&gt;</code><br>
      <code>&lt;experimental/scope&gt;</code><br>
      <del><code>&lt;experimental/set&gt;</code></del><br>
      <del><code>&lt;experimental/source_location&gt;</code></del><br>
      <del><code>&lt;experimental/string&gt;</code></del><br>
      <code>&lt;experimental/type_traits&gt;</code><br>
      <del><code>&lt;experimental/unordered_map&gt;</code></del><br>
      <del><code>&lt;experimental/unordered_set&gt;</code></del><br>
      <code>&lt;experimental/utility&gt;</code><br>
      <del><code>&lt;experimental/vector&gt;</code></del>
    </div>

    <p>Delete from Table 2 &mdash; Significant features in this technical specification:</p>

    <div class="modify">
      <table style="margin: 0;">
        <thead>
          <tr><th>Doc. No.</th><th>Title</th><th>[&hellip;]</th></tr>
        </thead>
        <tbody>
          <tr>
            <td>N4388</td>
            <td>A Proposal to Add a Const-Propagating Wrapper to the Standard Library</td>
            <td>[&hellip;]</td>
          </tr>
          <tr><td>[&hellip;]</td><td>[&hellip;]</td><td>[&hellip;]</td></tr>
          <tr>
            <td><del>N4273</del></td>
            <td><del>Uniform Container Erasure</del></td>
            <td><del>[&hellip;]</del></td>
          </tr>
          <tr>
            <td><del>N4391</del></td>
            <td><del><code>make_array</code></del></td>
            <td><del>[&hellip;]</del></td>
          </tr>
          <tr><td>[&hellip;]</td><td>[&hellip;]</td><td>[&hellip;]</td></tr>
          <tr>
            <td><del>N4519</del></td>
            <td><del>Source-Code Information Capture</del></td>
            <td><del>[&hellip;]</del></td>
          </tr>
        </tbody>
      </table>
    </div>

    <h3 id="sysups">Systematic updates of the method of specification and presentation</h3>

    <p>Editorially apply the new compact inline namespace syntax wherever it applies.</p>

    <div class="modify">
      <p><strong>3.1.1 Header <code>&lt;experimental/utility&gt; synopsis [utility.syn]</code></strong></p>
      <div class="code">#include &lt;utility&gt;

        namespace std::experimental<ins>::inline fundamentals_v3</ins> {
        <del>inline namespace fundamentals_v3 {</del>

        // 3.1.2, Class erased_type
        struct erased_type { };

        <del>} // namespace fundamentals_v3</del>
        } // namespace std::experimental<ins>::inline fundamentals_v3</ins></div>
      <p>[Further edits not shown.]</p>
    </div>

    <p>Update section numbers, and update the &ldquo;C++17-concept&rdquo; names everywhere
      and replace &ldquo;satisfies&rdquo; with &ldquo;meets&rdquo;, e.g. &ldquo;satisfies
      the requirements of <code>CopyConstructible</code>&rdquo; becomes &ldquo;meets
      the <em>Cpp17CopyConstructible</em> requirements&rdquo;.</p>
    <div class="modify">
      <p><strong><del>20.7.7</del><ins>20.10.8</ins> uses_allocator [allocator.uses]</strong></p>
      <p><strong><del>20.7.7.1</del><ins>20.10.8.1</ins> uses_allocator trait [allocator.uses.trait]</strong></p>
      <p><code>template &lt;class T, class Alloc&gt; struct uses_allocator;</code></p>
      <p>
        1. <em>Remarks</em>: Automatically detects whether <code>T</code> has a nested
        <code>allocator_type</code> that is convertible from <code>Alloc</code>.
        Meets the <del>BinaryTypeTrait</del><ins><em>Cpp17BinaryTypeTrait</em></ins>
        requirements (<del>C++17 §23.15.1</del><ins>C++20 §20.15.1</ins>).
        The implementation <del>shall provide</del><ins>provides</ins> a definition [&hellip;]
      </p>

      <p>[Further edits not shown, though some instances will be part of the edits of the next instruction.]</p>
    </div>

    <p>Update C++17-style <em>Requires</em>/<em>Remarks</em> into
      <em>Mandates</em>/<em>Expects</em>/<em>Constraints</em>.</p>
    <div class="modify">
      <p><strong>3.2.2.3 <code>propagate_const</code> constructors [propagate_const.ctor]</strong></p>
      <p>[<em>Note</em>: The following constructors are conditionally specified as <code>explicit</code>.
        This is typically implemented by declaring two such constructors, of which at most
        one participates in overload resolution. &mdash;&nbsp;<em>end note</em>]</p>

      <p><code>template &lt;class U&gt; <em>see below</em> constexpr propagate_const(propagate_const&lt;U&gt;&amp;&amp; pu);</code></p>
      <p><ins><em>Constraints</em>: <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code>.</ins></p>
      <p><em>Remarks</em>:
        <del>This constructor shall not participate in overload resolution unless <code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code>.</del>
        The constructor is specified as explicit if and only if <code>!is_convertible_v&lt;U&amp;&amp;, T&gt;</code>.</p>
      <p><em>Effects</em>: Initializes <code>t_</code> as if direct-non-list-initializing an object of type
        <code>T</code> with the expression <code>std::move(pu.t_)</code>.</p>

      <p><code>template &lt;class U&gt; <em>see below</em> constexpr propagate_const(U&amp;&amp; pu);</code></p>
      <p><ins><em>Constraints</em>: <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code> and
        <code>decay_t&lt;U&gt;</code> is not a specialization of <code>propagate_const</code>.</ins></p>
      <p><em>Remarks</em>:
        <del>This constructor shall not participate in overload resolution unless <code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code>
        and <code>decay_t&lt;U&gt;</code> is not a specialization of <code>propagate_const</code>.</del>
        The constructor is specified as explicit if and only if <code>!is_convertible_v&lt;U&amp;&amp;, T&gt;</code>.
      <p><em>Effects</em>: Initializes <code>t_</code> as if direct-non-list-initializing an object of type
        <code>T</code> with the expression <code>std::forward&lt;U&gt;(u)</code>.</p>
    </div>

    <p><em>Editorial note</em>: The rvalue reference in <code>is_constructible</code> is redundant,
    since it is already contained in the definition of <code>is_constructible</code> (or, more concretely,
    in the definition of <code>declval</code>), and therefore we remove it here.</p>

    <div class="modify">
      <p><strong>3.2.2.4 <code>propagate_const</code> assignment [propagate_const.assignment]</strong></p>
      <p>[&hellip;]</p>
      <p><del><em>Remarks</em>: This function shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        <code>U</code> is implicitly convertible to <code>T</code>.</p>
      <p>[&hellip;]</p>
      <p><del><em>Remarks</em>: This function shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        <code>U</code> is implicitly convertible to <code>T</code> and <code>decay_t&lt;U&gt;</code> is not a specialization of <code>propagate_const</code>.</p>
      <p>[&hellip;]</p>

      <p><strong>3.2.2.5 <code>propagate_const</code> const observers [propagate_const.const_observers]</strong></p>
      <p>[&hellip;]</p>
      <p><del><em>Remarks</em>: This function shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        <code>T</code> is an object pointer type or has an implicit conversion to <code>const element_type*</code>.</p>
      <p>[&hellip;]</p>

      <p><strong>3.2.2.6 <code>propagate_const</code> non-const observers [propagate_const.non_const_observers]</strong></p>
      <p>[&hellip;]</p>
      <p><del><em>Remarks</em>: This function shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        <code>T</code> is an object pointer type or has an implicit conversion to <code>const element_type*</code>.</p>
      <p>[&hellip;]</p>

      <p><strong>3.2.2.11 <code>propagate_const</code> hash support [propagate_const.hash]</strong></p>
      <div class="code">template &lt;class T&gt;
        &nbsp; struct hash&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;;</div>
      <p><ins>The specialization <code>hash&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;</code>
        is enabled (C++20 §20.14.18) if and only if <code>hash&lt;T&gt;</code> is enabled.</ins>
        <del>For</del><ins>When enabled, for</ins> an object <code>p</code> of type <code>propagate_const&lt;T&gt;</code>,
        <code>hash&lt;experimental::fundamentals_v3::propagate_const&lt;T&gt;&gt;()(p)</code>
        <del>shall evaluate</del><ins>evaluates</ins> to the same value as <code>hash&lt;T&gt;()(p.t_)</code>.</p>
      <p><del><em>Requires</em>: The specialization <code>hash&lt;T&gt;</code> shall be well-formed and well-defined, and shall meet the requirements of class template <code>hash</code>.</del>

      <p><strong>3.2.2.12 <code>propagate_const</code> comparison function objects [propagate_const.comparison_function_objects]</strong></p>
      <p>[&hellip;]</p>
      <p><em><del>Requires</del><ins>Mandates</ins></em>: The specialization
        <code>equal_to&lt;T&gt;</code> <del>shall be</del><ins>is</ins> well-formed<ins>.</ins></p>
      <p><ins><em>Preconditions</em>: The specialization
        <code>equal_to&lt;T&gt;</code> is</ins> <del>and</del> well-defined.</p>
      <p>[&hellip;]</p>
      <p><em><del>Requires</del><ins>Mandates</ins></em>: The specialization
        <code>not_equal_to&lt;T&gt;</code> <del>shall be</del><ins>is</ins> well-formed<ins>.</ins></p>
      <p><ins><em>Preconditions</em>: The specialization
        <code>not_equal_to&lt;T&gt;</code> is</ins> <del>and</del> well-defined.</p>
      <p>[&hellip;]</p>
      <p><em><del>Requires</del><ins>Mandates</ins></em>: The specialization
        <code>less&lt;T&gt;</code> <del>shall be</del><ins>is</ins> well-formed<ins>.</ins></p>
      <p><ins><em>Preconditions</em>: The specialization
        <code>less&lt;T&gt;</code> is</ins> <del>and</del> well-defined.</p>
      <p>[&hellip;]</p>
      <p><em><del>Requires</del><ins>Mandates</ins></em>: The specialization
        <code>greater&lt;T&gt;</code> <del>shall be</del><ins>is</ins> well-formed<ins>.</ins></p>
      <p><ins><em>Preconditions</em>: The specialization
        <code>greater&lt;T&gt;</code> is</ins> <del>and</del> well-defined.</p>
      <p>[&hellip;]</p>
      <p><em><del>Requires</del><ins>Mandates</ins></em>: The specialization
        <code>less_equal&lt;T&gt;</code> <del>shall be</del><ins>is</ins> well-formed<ins>.</ins></p>
      <p><ins><em>Preconditions</em>: The specialization
        <code>less_equal&lt;T&gt;</code> is</ins> <del>and</del> well-defined.</p>
      <p>[&hellip;]</p>
      <p><em><del>Requires</del><ins>Mandates</ins></em>: The specialization
        <code>greater_equal&lt;T&gt;</code> <del>shall be</del><ins>is</ins> well-formed<ins>.</ins></p>
      <p><ins><em>Preconditions</em>: The specialization
        <code>greater_equal&lt;T&gt;</code> is</ins> <del>and</del> well-defined.</p>
      <p>[&hellip;]</p>
    </div>

    <div class="modify">
      <p><strong>Class templates <code>scope_exit</code>, <code>scope_fail</code>, and <code>scope_success</code> [scopeguard.exit]</strong></p>
      <p>[&hellip;]</p>
      <div class="code">template &lt;class EFP&gt;
        &nbsp; explicit <span class="placeholder">scope-guard</span>(EFP&amp;&amp; f) noexcept(
        &nbsp; &nbsp; is_nothrow_constructible_v&lt;EF, EFP&gt; ||
        &nbsp; &nbsp; is_nothrow_constructible_v&lt;EF, EFP&amp;&gt;);</div>
      <p><em><del>Requires</del><ins>Mandates</ins></em>:
        The expression <code>f()</code> <del>shall be</del><ins>is</ins> well-formed.</p>
      <p><ins><em>Preconditions</em>:</ins>
        Calling <code>f()</code> <del>shall have</del><ins>has</ins> well-defined behavior.
        For <code>scope_exit</code> and <code>scope_fail</code>, calling <code>f()</code>
        <del>shall</del><ins>does</ins> not throw an exception.</p>
      <p><em>Effects</em>:
        If <code>EFP</code> is not an lvalue reference type and
        <code>is_nothrow_constructible_v&lt;EF, EFP&gt;</code> is <code>true</code>,
        initialize <code>exit_function</code> with <code>std::forward&lt;EFP&gt;(f)</code>;
        otherwise initialize <code>exit_function</code> with <code>f</code>.
        For <code>scope_exit</code> and <code>scope_fail</code>,
        if the initialization of <code>exit_function</code> throws an exception,
        calls <code>f()</code>. [<em>Note</em>: For <code>scope_success</code>,
        <code>f()</code> will not be called if the initialization fails. &mdash;&nbsp;<em>end note</em>]</p>
      <p><em>Throws</em>: Any exception thrown during the initialization of <code>exit_function</code>.</p>
      <p><del><em>Remarks</em>: This constructor shall not participate in overload resolution unless</del>
        <ins><em>Constraints:</em></ins> <code>is_same_v&lt;remove_cvref_t&lt;EFP&gt;, scope-guard&gt;</code>
        is <code>false</code> and <code>is_constructible_v&lt;EF, EFP&gt;</code> is <code>true</code>.</p>

      <div class="code"><span class="placeholder">scope-guard</span>(<span class="placeholder">scope-guard</span>&amp;&amp; rhs) noexcept(<span class="placeholder">see below</span>)</div>
      <p><em><del>Requires</del><ins>Preconditions</ins></em>: If <code>EF</code> is an object type:</p>
      <ul>
        <li>if <code>is_nothrow_move_constructible_v&lt;EF&gt;</code> is <code>true</code>,
          <code>EF</code> <del>shall meet</del><ins>meets</ins> the <del>requirements of <code>MoveConstructible</code>
          (C++17 Table 23)</del><ins><em>Cpp17MoveConstructible</em> (C++20 Table 26) requirements</ins>,</li>
        <li>otherwise <code>EF</code> <del>shall meet</del><ins>meets</ins> the <del>requirements of CopyConstructible
            (C++17 Table 24)</del><ins>Cpp17CopyConstructible requirements (C++20 Table 27)</ins>.</li>
      </ul>
      <p>[&hellip;]</p>
      <p><del><em>Remarks</em>: This constructor shall not participate in overload resolution
        unless</del><ins><em>Constraints</em>:</ins> <code>(is_nothrow_move_constructible_v&lt;EF&gt; || is_copy_constructible_v&lt;EF&gt;)</code>
        is <code>true</code>.</p>
      <p><ins><em>Remarks</em>:</ins> The expression inside <code>noexcept</code> is equivalent to <code>is_nothrow_move_constructible_v&lt;EF&gt; || is_nothrow_copy_constructible_v&lt;EF&gt;</code>.
      <p>[&hellip;]</p>
    </div>

    <div class="modify">
      <p><strong>Class template <code>unique_resource</code> [scopeguard.uniqueres]</strong></p>
      <p>[&hellip;]</p>
      <p><strong>Constructors [scopeguard.uniqueres.ctor]</strong></p>
      <div class="code">unique_resource()</div>
      <p><em>Effects</em>: Value-initializes <code>resource</code> and <code>deleter</code>;
        <code>execute_on_reset</code> is <code>initialized</code> with <code>false</code>.</p>
      <p><del><em>Remarks</em>: This constructor shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        <code>is_default_constructible_v&lt;R&gt; &amp;&amp; is_default_constructible_v&lt;D&gt;</code> is <code>true</code>.</p>

      <div class="code">template &lt;class RR, class DD&gt;
      &nbsp; unique_resource(RR&amp;&amp; r, DD&amp;&amp; d) noexcept(<span class="placeholder">see below</span>)</div>

      <p><em><del>Requires</del><ins>Mandates</ins></em>:
        The expressions <code>d(r)</code>, <code>d(<span class="placeholder">RESOURCE</span>)</code>
        and <code>deleter(<span class="placeholder">RESOURCE</span>)</code> are well-formed.</p>
      <p><ins><em>Preconditions:</em></ins>
        Calling <code>d(r)</code>, <code>d(<span class="placeholder">RESOURCE</span>)</code>
        or <code>deleter(<span class="placeholder">RESOURCE</span>)</code>
        <del>shall have</del><ins>has</ins> well-defined behavior and
        <del>shall</del><ins>does</ins> not throw an exception.</p>
      <p><em>Effects</em>: [&hellip;]</p>
      <p><em>Throws</em>: [&hellip;]</p>
      <p><del><em>Remarks:</em> This constructor shall not participate in overload resolution unless</del>
        <ins><em>Constraints</em>:</ins> <code>is_constructible_v&lt;R1, RR&gt; &amp;&amp;
        is_constructible_v&lt;D , DD&gt; &amp;&amp;
        (is_nothrow_constructible_v&lt;R1, RR&gt; || is_constructible_v&lt;R1,RR&&gt;) &amp;&amp;
        (is_nothrow_constructible_v&lt;D , DD&gt; || is_constructible_v&lt;D ,DD&&gt;)</code>
        is <code>true</code>. [<em>Note</em>: The first two conditions prohibit initialization
        from an rvalue reference when either <code>R1</code> or <code>D</code> is a specialization
        of <code>reference_wrapper</code>. &mdash;&nbsp;<em>end note</em>]</p>
      <p><ins><em>Remarks</em>:</ins> The expression inside
        <code>noexcept</code> is equivalent to [&hellip;]</p>

      <div class="code">unique_resource(unique_resource&amp;&amp; rhs) noexcept(<span class="placeholder">see below</span>);</div>
      <p>[&hellip;]</p>

      <p><strong>Destructor [scopeguard.uniqueres.dtor]</strong></p>
      <p>[&hellip;]</p>

      <p><strong>Assignment [scopeguard.uniqueres.assign]</strong></p>
      <div class="code">unique_resource&amp;operator=(unique_resource&amp;&amp; rhs) noexcept(<span class="placeholder">see below</span>);</div>
      <p><em><del>Requires</del><ins>Preconditions</ins></em>:
        If <code>is_nothrow_move_assignable_v&lt;R1&gt;</code> is <code>true</code>,
        <code>R1</code> <del>shall satisfy the <code>MoveAssignable</code> requirements
        (C++17 Table 25)</del><ins>meets the <em>Cpp17MoveAssignable</em> (C++20 Table 28) requirements</ins>;
        otherwise <code>R1</code> <del>shall satisfy the <code>CopyAssignable</code> requirements
        (C++17 Table 26)</del><ins>meets the <em>Cpp17CopyAssignable</em> (C++20 Table 29) requirements</ins>.
        If <code>is_nothrow_move_assignable_v&lt;D&gt;</code> is <code>true</code>,
        <code>D</code> <del>shall satisfy the <code>MoveAssignable</code> requirements
        (C++17 Table 25)</del><ins>meets the <em>Cpp17MoveAssignable</em> (C++20 Table 28) requirements</ins>;
        otherwise <code>D</code> <del>shall satisfy the <code>CopyAssignable</code> requirements
        (C++17 Table 26)</del><ins>meets the <em>Cpp17CopyAssignable</em> (C++20 Table 29) requirements</ins>.
      <p><em>Effects</em>: [&hellip;]</p>
      <p><em>Throws</em>: [&hellip;]</p>
      <p><em>Remarks</em>: [&hellip;]</p>

      <p><strong>Other member functions [scopeguard.uniqueres.members]</strong></p>
      <div class="code">void reset() noexcept;</div>
      <p><em>Effects</em>: [&hellip;]</p>

      <div class="code">template &lt;class RR&gt; void reset(RR&amp;&amp; r);</div>
      <p><em><del>Requires</del><ins>Mandates</ins></em>:
        The expression <code>deleter(r)</code> <del>shall be</del><ins>is</ins> well-formed.</p>
      <p><ins><em>Preconditions:</em></ins> Calling <code>deleter(r)</code> <del>shall have</del><ins>has</ins>
        well-defined behavior and <del>shall</del><ins>does</ins> not throw an exception.</p>
      <p><em>Effects</em>: [&hellip;]</p>
      <p><del><em>Remarks</em>: This function shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        the selected assignment expression statement assigning <code>resource</code> is well-formed.

      <div class="code">void release() noexcept;</div>
      <p><em>Effects</em>: Equivalent to <code>execute_on_reset = false</code>.</p>

      <div class="code">const R&amp; get() const noexcept;</div>
      <p><em>Returns</em>: <code>resource</code>.</p>

      <div class="code"><span class="placeholder">see below</span> operator*() const noexcept;</div>
      <p><em>Effects</em>: Equivalent to: <code>return *get();</code></p>
      <p><del><em>Remarks</em>: This function shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        <code>is_pointer_v&lt;R&gt;</code> is <code>true</code> and <code>is_void_v&lt;remove_pointer_t&lt;R&gt;&gt;</code> is <code>false</code>.</p>
      <p><ins><em>Remarks</em>:</ins> The return type is <code>add_lvalue_reference_t&lt;remove_pointer_t&lt;R&gt;&gt;</code>.</p>

      <div class="code">R operator-&gt;() const noexcept;</div>
      <p><em>Returns</em>: <code>get()</code>.</p>
      <p><del><em>Remarks</em>: This function shall not participate in overload resolution unless</del>
        <ins><em>Constraints</em>:</ins> <code>is_pointer_v&lt;R&gt;</code> is <code>true</code>.</p>

      <div class="code">const D&amp; get_deleter() const noexcept;</div>
      <p><em>Returns</em>: <code>deleter</code>.</p>

      <p><strong><code>unique_resource</code> creation [scopeguard.uniqueres.create]</strong></p>
      <div class="code">template &lt;class R, class D, class S=decay_t&lt;R&gt;&gt;
        &nbsp; unique_resource&lt;decay_t&lt;R&gt;, decay_t&lt;D&gt;&gt;  make_unique_resource_checked(R&amp;&amp; resource, const S&amp; invalid, D&amp;&amp; d)
        &nbsp; noexcept(is_nothrow_constructible_v&lt;decay_t&lt;R&gt;, R&gt; &amp;&amp; is_nothrow_constructible_v&lt;decay_t&lt;D&gt;, D&gt;);</div>
      <p><em><del>Requires</del><ins>Mandates</ins></em>:
        The expression <code>(resource == invalid ? true : false)</code>
        <del>shall be</del><ins>is</ins> well-formed.</p>
      <p><ins><em>Preconditions</em>:</ins> Evaluation of the expression
        <code>(resource == invalid ? true : false)</code> <del>shall have</del><ins>has</ins>
        well-defined behavior and <del>shall</del><ins>does</ins> not throw an exception.</p>
      <p><em>Effects</em>: [&hellip;]</p>

      <p>[&hellip;]</p>
    </div>

    <div class="modify">
      <p><strong>Class template <code>function</code> [func.wrap.func]</strong></p>
      <p>[&hellip;]</p>
      <p><strong><code>function</code> construct/copy/destroy [func.wrap.func.con]</strong></p>
      <p>[&hellip;]</p>
      <div class="code">template&lt;class F&gt; function&amp; operator=(F&amp;&amp; f);</div>
      <p><em>Effects</em>: <code>function(allocator_arg, <span class="placeholder">ALLOCATOR_OF</span>(*this), std::forward&lt;F&gt;(f)).swap(*this);</code></p>
      <p><em>Returns</em>: <code>*this</code>.</p>
      <p><del><em>Remarks</em>: This assignment operator shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        <code>declval&lt;decay_t&lt;F&gt;&amp;&gt;()</code> is
        <del><em>Callable</em> (C++17 §23.14.13.2)</del><ins><em>Lvalue-Callable</em> (C++20 §20.14.16.2)</ins>
        for argument types <code>ArgTypes...</code> and return type <code>R</code>.</p>
      <p>[&hellip;]</p>
      <p><strong><code>function</code> modifiers [func.wrap.func.mod]</strong></p>
      <div class="code">void swap(function&amp; other);</div>
      <p><em><del>Requires</del><ins>Preconditions</ins>:</em> <code>*this-&gt;get_memory_resource() == *other.get_memory_resource()</code>.</p>
      <p><em>Effects</em>: Interchanges the targets of <code>*this</code> and <code>other</code>.</p>
      <p><em>Remarks</em>: The allocators of <code>*this</code> and <code>other</code> are not interchanged.</p>
    </div>

    <p><em>Editorial note</em>: The change from &ldquo;<em>Callable</em>&rdquo; to &ldquo;<em>Lvalue-Callable</em>&rdquo;
      was part of the transition from C++14 to C++17 and was previously missed
      by <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1210r0.html">P1210R0</a>.</p>

    <div class="modify">
      <p><strong>Non-owning pointers [memory.observer.ptr]</strong></p>
      <p>[&hellip;]</p>
      <p><strong><code>observer_ptr</code> constructors [memory.observer.ptr.ctor]</strong></p>
      <p>[&hellip;]</p>
      <div class="code">template &lt;class W2&gt; constexpr observer_ptr(observer_ptr&lt;W2&gt; other) noexcept;</div>
      <p><em>Postconditions</em>: <code>get() == other.get()</code>.</p>
      <p><del><em>Remarks</em>: This constructor shall not participate in overload resolution unless</del><ins><em>Constraints</em>:</ins>
        <code>W2*</code> is convertible to <code>W*</code>.

      <p><strong><code>observer_ptr</code> observers [memory.observer.ptr.obs]</strong></p>
      <p>[&hellip;]</p>
      <div class="code">constexpr reference operator*() const;</div>
      <p><em><del>Requires</del><ins>Preconditions</ins></em>: <code>get() != nullptr</code> <ins>is <code>true</code></ins>.</p>
      <p><em>Returns</em>: <code>*get()</code>.</p>
      <p><em>Throws</em>: Nothing.</p>
      <p>[&hellip;]</p>

      <p><strong><code>observer_ptr</code> hash support [memory.observer.ptr.hash]</strong></p>
      <div class="code">template &lt;class T&gt; struct hash&lt;experimental::observer_ptr&lt;T&gt;&gt;;</div>
      <p>The <del>template specialization shall meet the requirements of class template <code>hash</code> (C++17 §23.14.15</del>)<ins>specialization is enabled (C++20 §20.14.18)</ins>.
        For an object <code>p</code> of type <code>observer_ptr&lt;T&gt;</code>, <code>hash&lt;observer_ptr&lt;T&gt;&gt;()(p)</code>
          <del>shall evaluate</del><ins>evaluates</ins> to the same value as <code>hash&lt;T*&gt;()(p.get())</code>.</p>
    </div>

    <div class="modify">
      <p><strong>Type-erased allocator [memory.type.erased.allocator]</strong></p>
      <p>[&hellip;]</p>
      <p>Additionally, class <code>C</code> <del>shall meet</del><ins>meets</ins> the following requirements:</p>
      <ul>
        <li><code>C::allocator_type</code> <del>shall be identical to</del><ins>denotes</ins> <code>std::experimental::erased_type</code>.</li>
        <li><code>X.get_memory_resource()</code> returns <code>rptr</code>.</li>
      </ul>
      
      <p><strong>Header <code>&lt;experimental/memory_resource&gt;</code> synopsis [memory.resource.syn]</strong></p>
      <p>[&hellip;]</p>

      <p><strong>Alias template <code>resource_adaptor</code> [memory.resource.adaptor]</strong></p>
      <p><strong><code>resource_adaptor</code> [memory.resource.adaptor.overview]</strong></p>
      <p>[&hellip;] In addition to the <del><code>Allocator</code> requirements (C++17 §20.5.3.5)</del><ins><em>Cpp17AllocatorRequirements</em> (C++20 §16.5.3.5)</ins>,
        the parameter to <code>resource_adaptor</code> shall meet the following additional requirements: [&hellip;]</p>
      <p>[&hellip;]</p>
      <p><strong><code><em>resource_adaptor_imp</em> member functions</code> [memory.resource.adaptor.mem]</strong></p>
      <p>[&hellip;]</p>
      <div class="code">void do_deallocate(void* p, size_t bytes, size_t alignment);</div>
      <p><em><del>Requires</del><ins>Preconditions</ins></em>: <code>p</code> was previously allocated
        using <code>A.allocate</code>, where <code>A == m_alloc</code>, and not subsequently deallocated.</p>
      <p><em>Effects</em>: [&hellip;]</p>
      <p>[&hellip;]</p>
    </div>

    <div class="modify">
      <p><strong>Algorithms library [algorithms]</strong></p>
      <p>[&hellip;]</p>
      <p><strong>Shuffle [alg.random.shuffle]</strong></p>
      <p>[&hellip;]</p>
      <p><del><em>Requires</em>: <code>RandomAccessIterator</code> shall satisfy the
      requirements of <code>ValueSwappable</code> (C++17 §20.5.3.2)</del><ins><em>Preconditions</em>:
          <code>RandomAccessIterator</code> meets the <em>Cpp17ValueSwappable</em> requirements (C++20 §16.5.3.2)</ins>.</p>
      <p><em>Complexity</em>: [&hellip;]</p>
      <p><em>Remarks</em>: To the extent that the implementation of this function makes use of random numbers,
        the per-thread engine (10.1.2.1) <del>shall serve</del><ins>serves</ins> as the implementation&rsquo;s
        source of randomness.</p>
    </div>

    <div class="modify">
      <p><strong>Numerics library [numeric]</strong></p>
      <p>[&hellip;]</p>
      <p><strong>Utilities [rand.util]</strong></p>
      <p><strong>Function template <code>randint</code> [rand.util.randint]</strong></p>
      <p>A separate <em>per-thread engine</em> of type <code>default_random_engine</code> (<del>C++17 §29.6.5</del><ins>C++20 §26.6.5</ins>),
        initialized to an unpredictable state, shall be maintained for each thread.</p>

      <div class="code">template&lt;class IntType&gt; IntType randint(IntType a, IntType b);</div>
      <p><em><del>Requires</del><ins>Preconditions</ins></em>: <code>a</code> &le; <code>b</code>.</p>
      <p><del><em>Remarks</em>: If the template argument does not meet the requirements for <code>IntType</code>, the program is ill-formed
        (C++17 §29.6.1.1)</del><ins><em>Mandates</em>: The template argument meets the requirements for a template parameter named <code>IntType</code> in C++20 §26.6.2.1</ins>.</p>
      <p><em>Returns</em>: A random integer <em>i</em>, <code>a</code> &le; <em>i</em> &le; <code>b</code>,
        produced from a thread-local instance of <code>uniform_int_distribution&lt;IntType&gt;</code>
        (<del>C++17 §29.6.8.2.1</del><ins>C++20 §26.6.8.2.1</ins>) invoked with the per-thread engine.</p>
      <p>[&hellip;]</p>
    </div>

    <p><em>Editorial instruction</em>: The specification elements should be reordered editorially
      according to the order provided by [C++20, structure.specifications].</p>

  </body>
</html>
