<!DOCTYPE html>
<html lang="en">

<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">

  <meta name="description" content="Remove redundant use of typename from the Library">
  <meta name="keywords" content="C++,cplusplus,wg21,typename,library,template">
  <meta name="author" content="Alisdair Meredith">

  <title>Down with typename in the Library!</title>

  <style>
    ins {background-color:#A0FFA0}
    del {background-color:#FFA0A0}
    p {text-align:justify}
    li {text-align:justify}
    blockquote.note
    {
      background-color:#E0E0E0;
      padding-left: 15px;
      padding-right: 15px;
      padding-top: 1px;
      padding-bottom: 1px;
    }
    blockquote.invented_example
    {
      background-color:#f4f4f4;
      padding-left: 15px;
      padding-right: 15px;
      padding-top: 1px;
      padding-bottom: 1px;
    }
    blockquote.standard_example
    {
      background-color:#ffffcc;
      padding-left: 15px;
      padding-right: 15px;
      padding-top: 1px;
      padding-bottom: 1px;
    }

  </style>
</head>

<body>
<table>
<tr>
  <td>Doc. no.</td>
  <td>P2150R0</td>
</tr>
<tr>
  <td>Date:</td>
  <td>2020-04-14</td>
</tr>
<tr>
  <td>Project:</td>
  <td>Programming Language C++</td>
</tr>
<tr>
  <td>Audience:</td>
  <td>Library Working Group</td>
</tr>
<tr>
  <td>Reply to:</td>
  <td>Alisdair Meredith &lt;<a href="mailto:ameredith1@bloomberg.net">ameredith1@bloomberg.net</a>&gt;</td>
</tr>
</table>

<h1>Down with <code><del>typename</del></code> in the Library!</h1>

<h2>Table of Contents</h2>
<ol start="0">
<li><a href="#rev.hist">Revision History</a>
  <ul>
  <li><a href="#rev.0">Revision 0</a></li>
  </ul>
</li>
<li><a href="#1.0">Abstract</a></li>
<li><a href="#2.0">Stating the problem</a>
  <ol>
  <li><a href="#2.1">Why Is <code>typename</code> Necessary?</a></li>
  </ol>
</li>
<li><a href="#3.0">Propose Solution</a>
  <ol>
  <li><a href="#3.1">Patterns that Preserve <code>typename</code></a>
    <ol>
    <li><a href="#3.1.1">Preserve <code>typename</code> in <i>Non-member</i> Function Parameter Declarations</a></li>
    <li><a href="#3.1.2">Preserve <code>typename</code> Instantiating Template Arguments</a></li>
    <li><a href="#3.1.3">Preserve <code>typename</code> for Partial Template Specializations</a></li>
    <li><a href="#3.1.4">Preserve <code>typename</code> for Arguments to Concepts</a></li>
    <li><a href="#3.1.5">Preserve <code>typename</code> in Deduction Guides</a></li>
    <li><a href="#3.1.6">Preserve <code>typename</code> in Variable Template definitions</a></li>
    <li><a href="#3.1.7">Preserve <code>typename</code> for Local Variable Declarations</a></li>
    <li><a href="#3.1.8">Preserve <code>typename</code> when Constructing Temporary Objects for Return Expressions</a></li>
    <li><a href="#3.1.9">Preserve <code>typename</code> when Constructing Temporary Objects for Function Arguments</a></li>
    <li><a href="#3.1.A">Preserve <code>typename</code> for Default Function Arguments</a></li>
    <li><a href="#3.1.B">Preserve <code>typename</code> for Default Member Initializers</a></li>
    <li><a href="#3.1.C">Preserve <code>typename</code> for <code>alignof</code> Expressions</a></li>
    <li><a href="#3.1.D">Preserve <code>typename</code> within <code>decltype</code> Expressions</a></li>
    <li><a href="#3.1.E">Preserve <code>typename</code> for <code>noexcept</code> Expressions</a></li>
    <li><a href="#3.1.F">Preserve <code>typename</code> for <code>sizeof</code> Expressions</a></li>
    <li><a href="#3.1.G">Preserve <code>typename</code> for <code>throw</code> Expressions</a></li>
    <li><a href="#3.1.H">Preserve <code>typename</code> for <code>typeid</code> Expressions</a></li>
    <li><a href="#3.1.I">Preserve <code>typename</code> for Cast Expressions</a></li>
    <li><a href="#3.1.J">Preserve <code>typename</code> for Exception Specifications</a></li>
    </ol>
  </li>
  <li><a href="#3.2">Patterns that Remove <code>typename</code></a>
    <ol>
    <li><a href="#3.2.1">Remove <code>typename</code> from Alias Definitions</a></li>
    <li><a href="#3.2.2">Remove <code>typename</code> from Default Template Arguments</a></li>
    <li><a href="#3.2.3">Remove <code>typename</code> from Variable Template declarations</a></li>
    <li><a href="#3.2.4">Remove <code>typename</code> from Function Return Types</a></li>
    <li><a href="#3.2.5">Remove <code>typename</code> from Friend Function Declarations</a></li>
    <li><a href="#3.2.6">Remove <code>typename</code> from Member Function Declarations</a></li>
    <li><a href="#3.2.7">Remove <code>typename</code> from Data Member Declarations</a></li>
    <li><a href="#3.2.8">Remove <code>typename</code> from C++ Cast Types</a></li>
    <li><a href="#3.2.9">Remove <code>typename</code> from New Expressions</a></li>
    </ol>
  </li>
  </ol>
</li>
<li><a href="#4.0">Impact on the Standard</a></li>
<li><a href="#5.0">Tentative Wording (Informative)</a></li>
<li><a href="#6.0">Acknowledgements</a></li>
<li><a href="#7.0">References</a></li>
</ol>


<h2><a id="rev.hist">Revision History</a></h2>

<h3><a id="rev.0">Revision 0</a></h3>
<p>
Original version of the paper for the 2020 April mailing.
</p>


<h2><a id="1.0">1 Abstract</a></h2>
<p>
The paper
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3">P0634R3</a>,
adopted at Jacksonville 2018, simplified the rules requiring the use of the
<code>typename</code> keyword where no other interpretation might be permitted.
This paper suggests editorially applying the practice consistently,
throughout the library clauses, so that unnecessary <code>typename</code>s are
omitted.
</p>


<h2><a id="2.0">2 Stating the problem</a></h2>
<p>
As the C++ language evolves, simpler and cleaner ways of expressing ideas
become available.  Over time, the Library specification style becomes outdated
and cumbersome, unless we try to stay on top of relevant changes when they are
adopted.  One example is
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3">P0634R3</a>
adopted at Jacksonville (2018) that makes many uses of the <code>typename</code>
keyword redundant, when used to disambiguate types from expressions in
dependent contexts by the library specification.  While we could retain this
usage for clarity, informed readers of the specification will start wondering
why the redundant keyword is present, and start looking for the ambiguity that
the keyword resolves, where none exists.
</p>
<p>
It should be noted that a related paper was rejected by the Evolution Working
Group that could have had an impact on a subset of these now redundant
<code>typename</code>s.  Specifically,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0945r0">P0945R0</a>
would have reintroduced a context where <code>typename</code> is a necessary
disambiguator in alias template declarations.  As this proposal was rejected
for C++20, it could not be resurrected without making breaking changes to
valid user programs, and should no longer be a concern for recommending best
practice for the library specification.
</p>

<h2><a id="2.1">2.1 Why Is <code>typename</code> Necessary?</a></h2>
<p>
As a quick refresher before jumping into a case-by-case analysis, let's
remind ourselves why the <code>typename</code> keyword is needed in the first
place.
</p>

<p>
The need for the <code>typename</code> keyword falls out of the two-phase name
lookup scheme for templates, adopted for C++98.  In the first phase of name
lookup, if a template parses a dependent name, it cannot know if that name
refers to a type, a template, or a value.  In order to catch more errors while
parsing an uninstantiated template (phase 1) we assume that any dependent name
denotes a value, and so can be consumed by an expression.  If a type or a
template is required, that is a diagnosable error, indicating a likely problem
in the template.  If a template is required, we can disambiguate with the
<code>.template</code> or <code>::template</code> syntax.  Likewise, if a type is
required, we can disambiguate with the <code>typename</code> keyword.
</p>

<p>
Prior to
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3">P0634R3</a>
the grammar would always assume that a dependent name denoted a value, without
regard to context.  However, that paper simplifies usage in the cases where the
grammar can unambiguously expect a type, making use of the <code>typename</code>
keyword to disambiguate types from values optional in such contexts.
</p>


<h2><a id="3.0">3 Propose Solution</a></h2>
<p>
The recommendation of this paper is to adopt editorial guidelines for the
library clauses of the standard (16-32 plus Annex D) to eliminate redundant use
of the <code>typename</code> keyword.  Once applied, this should become the
expected form of wording for subsequent LWG reviews, although there may be a
meeting or two lag where such changes to incoming papers are applied
editorially, to avoid asking LWG to spend additional time re-reviewing largely
approved wording.
</p>

<p>
Below, we analyze a set of common code patterns where <code>typename</code> is
required by the C++17 grammar that may (or may not) be affected by the
application of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3">P0634R3</a>.
This paper attempts to evaluate a wide variety of syntax patterns to cover
cases not yet present in library wording, in case guidance for future papers
is needed.  It is intended that this paper could serve as a style guide for
future papers regarding appropriate use of <code>typename</code>, and may be
updated as additional questions of usage arise - unless a more broad reaching
paper of library coding conventions is adopted.
</p>

<p>
At the time of writing, two compilers implement the needed language feature:
the EDG front end and the (not yet released) gcc 10 compiler.  All code has
been tested against a recent build of the pending gcc 10 compiler.  If there is
any bad analysis in the examples below, we should likely file bug reports
against this compiler (and amend the paper!)
</p>

<p>
Note that it would be quite reasonable to adopt just a selected subset of the
options to remove redundant <code>typename</code>s below.  For simplicity, this
first draft of the paper assumes that all possible options will be taken, and
defers finding a markup for which valid options are not taken up until it is
needed.
</p>

<p>
All wording is relative to the initial working draft for C++23,
<a href=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4861>N4861</a>.
</p>

<h3><a id="3.1">3.1 Patterns that Preserve <code>typename</code></a></h3>
<p>
First we will examine the places where the language is not yet ready to drop
the requirement to use <code>typename</code>, with a relevant example in each case.
Ideally examples will quote from the standard library, otherwise fresh examples
are created where the syntax pattern is not yet used within the library clauses
of the standard, to preserve the knowledge in case it becomes relevant to
wording future proposals.
</p>

<h4><a id="3.1.1">3.1.1 Preserve <code>typename</code> in <i>Non-member</i> Function Parameter Declarations</a></h4>
<p>
Relevant examples from the standard library:
</p>

<blockquote class="standard_example">
<h4>31.2 Header <code>&lt;atomic&gt;</code> synopsis [atomics.syn]</h4>
<pre>
namespace std {
  // 31.9, non-member functions
  template&lt;class T&gt;
    bool atomic_is_lock_free(const volatile atomic&lt;T&gt;*) noexcept;
  template&lt;class T&gt;
    bool atomic_is_lock_free(const atomic&lt;T&gt;*) noexcept;

  template&lt;class T&gt;
    void atomic_store(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    void atomic_store(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    void atomic_store_explicit(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                               memory_order) noexcept;
  template&lt;class T&gt;
    void atomic_store_explicit(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                               memory_order) noexcept;
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
I was given the following by Richard Smith which is far better quoted directly
than paraphrasing in in my own words:
</p>

<blockquote class="note">
This definitely isn't a case the &quot;down with typename&quot; paper missed
accidentally: we need these <code>typename</code>s (at least when they're part of the
<b>first</b> parameter) in order to distinguish between a function template
declaration and a variable template declaration:

<blockquote><pre>
template&lt;typename T&gt; T x(typename T::foo); <i>// function template</i>
template&lt;typename T&gt; T x(T::foo);          <i>// variable template</i>
</pre></blockquote>

and we very consciously did not want to make a special rule for
&quot;subsequent parameters&quot;.
</blockquote>

<p>
Note that there are no variable template class members, so this ambiguity
does not arise for member functions.
</p>

<p>
Also note that this restriction does not apply to the return type of a
function, nor does it apply to a function definition with a qualified
name, so:
</p>
<blockquote class="invented_example"><pre>
template &lt;class T&gt;
struct Identity {
   using type = T;
};

namespace ns {
  template &lt;class T&gt;
  <del>typename</del> Identity&lt;T&gt;::type clone(<ins>typename</ins> Identity&lt;T&gt;::type dummy);
}

template &lt;class T&gt;
<del>typename</del> Identity&lt;T&gt;::type ns::clone(<del>typename</del> Identity&lt;T&gt;::type dummy) {
   return <ins>typename</ins> Identity&lt;T&gt;::type{};
}
</pre>
</blockquote>

<h4><a id="3.1.2">3.1.2 Preserve <code>typename</code> Instantiating Template Arguments</a></h4>
<p>
Relevant examples from the standard library:
</p>

<blockquote class="standard_example">
<h4>20.11.1.5 Specialized algorithms [unique.ptr.special]</h4>
<ol start="4">
<pre>
template &lt;class T1, class D1, class T2, class D2&gt;
  bool operator&lt;(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);
</pre>
<li>
Let <code>CT</code> denote<pre>
common_type_t&lt;<ins>typename</ins> unique_ptr&lt;T1, D1&gt;::pointer,
              <ins>typename</ins> unique_ptr&lt;T2, D2&gt;::pointer&gt;</pre>
</li>
<li>
<i>Mandates:</i>
  <ol>
  <li>&mdash; <code>unique_ptr&lt;T1, D1&gt;::pointer</code> is implicitly convertible to <code>CT</code> and</li>
  <li>&mdash; <code>unique_ptr&lt;T2, D2&gt;::pointer</code> is implicitly convertible to <code>CT</code>.</li>
  </ol>
</li>
</ol>
</blockquote>

<blockquote class="standard_example">
<h4>29.9.2 Class template <code>basic_filebuf</code> [filebuf]</h4>
<ol start="5">
<li>
In order to support file I/O and multibyte/wide character conversion,
conversions are performed using members of a facet, referred to as
<code>a_codecvt</code> in following subclauses, obtained as if by
<pre>
const codecvt&lt;charT, char, traits::state_type&gt;&amp; a_codecvt =
  use_facet&lt;codecvt&lt;charT, char, <ins>typename</ins> traits::state_type&gt;&gt;(getloc());
</pre>
</li>
</ol>
</blockquote>

<p>
<b>Rationale:</b>
When instantiating a template, the compiler does not look at the template
declaration to guide whether the supplied arguments should be parsed as a type,
as a template, or as an expression (value).  Hence, the <code>typename</code>
keyword is not optional for any template instantiation.
</p>

<h5>Suggestion by Richard Smith to further revise Core language to support template arguments</h5>
<blockquote class="note">
When parsing a template-argument for which the template-name resolves to a
specific non-function template that is not a member of an unknown
specialization, parse the <i>template-argument</i> as a type if the
corresponding parameter is a type parameter, as an expression if the
corresponding parameter is a non-type template parameter, and as a template
name otherwise. (We'll still need the "parse it as whatever you can, and try to
deal with the mess later" approach for the dependent template cases, or when
the <i>template-name</i> names a function template.)
</blockquote>
<blockquote class="note">
This is not entirely backwards-compatible (there are obscure cases where the
existence of a type template causes us to parse a <code>&lt;</code> as being part
of a <i>template-id</i>, but we later resolve that <i>template-id</i> as a
function template name), and it creates a jarring dissonance between function
templates and other kinds of templates (and we still don't get to make
<code>dynamic_pointer_cast&lt;...&gt;</code> accept the same template-argument
syntax as <code>dynamic_cast&lt;...&gt;</code>). These concerns (particularly the
latter) make me think that this isn't an obviously good change, but on balance
it seems worthwhile.
</blockquote>


<h4><a id="3.1.3">3.1.3 Preserve <code>typename</code> for Partial Template Specializations</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template&lt;class Type, class Iterator&gt;
struct Host {};

template&lt;class Type&gt;
struct Host&lt;Type, <ins>typename</ins> Type::iterator&gt; {};
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Just as when instantiating a template, the compiler does not look at the
template declaration to guide whether the supplied arguments should be parsed
as a type, as a template, or as an expression (value).  Hence, the
<code>typename</code> keyword is not optional for template partial specializations
either.
</p>


<h4><a id="3.1.4">3.1.4 Preserve <code>typename</code> for Arguments to Concepts</a></h4>
<p>
Relevant example from the standard library:
</p>

<blockquote class="standard_example">
<h4>27.5.6 Comparisons [time.duration.comparisons]</h4>
<ol start="7">
<pre>
template&lt;class Rep1, class Period1, class Rep2, class Period2&gt;
    requires three_way_comparable&lt;<ins>typename</ins> CT::rep&gt;
  constexpr auto operator&lt;=&gt;(const duration&lt;Rep1, Period1&gt;&amp; lhs,
                             const duration&lt;Rep2, Period2&gt;&amp; rhs);
</pre>
<li>
<i>Returns:</i> <code>CT(lhs).count() &lt;=&gt; CT(rhs).count()</code>.
</li>
</ol>
</blockquote>

<p>
<b>Rationale:</b>
Just as when instantiating a template, the compiler does not look at the
concept declaration to guide whether the supplied arguments should be parsed as
a type, as a template, or as an expression (value).  Hence, the
<code>typename</code> keyword is not optional when using a concept.
</p>


<h4><a id="3.1.5">3.1.5 Preserve <code>typename</code> in Deduction Guides</a></h4>
<p>
Relevant examples from the standard library:
</p>

<blockquote class="standard_example">
<h4>21.3.2 Class template <code>basic_string</code> [basic.string]</h4>
<pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;,
           class Allocator = allocator&lt;charT&gt;&gt;
  class basic_string {
    <i>// ...</i>
  };


  template&lt;class InputIterator,
	   class Allocator = allocator&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type&gt;&gt;
    basic_string(InputIterator, InputIterator, Allocator = Allocator())
      -&gt; basic_string&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type,
                      char_traits&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type&gt;,
                      Allocator&gt;;

  template&lt;class charT, class traits,
           class Allocator = allocator&lt;charT&gt;&gt;
    basic_string(basic_string_view&lt;charT, traits&gt;,
                 <ins>typename</ins> <i>see below</i>::size_type, <ins>typename</ins> <i>see below</i>::size_type,
                 const Allocator&amp; = Allocator())
      -&gt; basic_string&lt;charT, traits, Allocator&gt;;
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
The <code>typename</code> keyword remains non-optional at all points in the
deduction guide grammar.  In the template-head, it is as essential as in any
other template declaration.  In the guiding declaration, it remains essential
for all the constructor parameters, as this appears in the language grammar
similar to a non-member function.  Finally, it remains essential in the guided
deduction, as that acts like any other template instantiation.
</p>


<h4><a id="3.1.6">3.1.6 Preserve <code>typename</code> in Variable Template definitions</a></h4>
<p>
There is no example in the standard library, so we provide our own
example to illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
struct Indirect {
   using type = T;
};

template &lt;class T&gt;
auto default_value = <ins>typename</ins> Indirect&lt;T&gt;::type{};
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Variables are initialized by expressions, which is what a dependent name is
expected to produce absent the <code>typename</code> keyword.  Hence, its use
remains non-optional in this case.  However, see <a href="#3.2.3">3.2.3</a>
for the declaration on the left-hand hand of the initializer.
</p>


<h4><a id="3.1.7">3.1.7 Preserve <code>typename</code> for Local Variable Declarations</a></h4>
<p>
Relevant example from the standard library:
</p>

<blockquote class="standard_example">
<h4>28.3.1 <code>Class locale</code> [locale]</h4>
<ol start="3">
<li>
[ <i>Example:</i> An iostream <code>operator&lt;&lt;</code> might be implemented as:<sup>257</sup>
<blockquote><pre>
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt; (basic_ostream&lt;charT, traits&gt;&amp; s, Date d) {
  <ins>typename</ins> basic_ostream&lt;charT, traits&gt;::sentry cerberos(s);
  if (cerberos) {
    tm tmbuf; d.extract(tmbuf);
    bool failed =
      use_facet&lt;time_put&lt;charT, ostreambuf_iterator&lt;charT, traits&gt;&gt;&gt;(
        s.getloc()).put(s, s, s.fill(), &amp;tmbuf, 'x').failed();
    if (failed)
      s.setstate(s.badbit);     <i>// might throw</i>
  }
  return s;
}
</pre></blockquote>
&mdash; <i>end example</i> ]
</li>
</ol>
</blockquote>

<p>
<b>Rationale:</b>
Variables are initialized by expressions, which is what a dependent name is
expected to produce absent the <code>typename</code> keyword.  Hence, its use
remains non-optional in this case.
</p>



<h4><a id="3.1.8">3.1.8 Preserve <code>typename</code> when Constructing Temporary Objects for Return Expressions</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
struct Indirect {
   using type = T;
};

template &lt;class T&gt;
auto factory() -&gt; Indirect&lt;T&gt;::type {
   return <ins>typename</ins> Indirect&lt;T&gt;::type{};
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Return values are necessarily expressions, and so continue to require the
<code>typename</code> keyword, as this is the very reason it exists.
</p>



<h4><a id="3.1.9">3.1.9 Preserve <code>typename</code> when Constructing Temporary Objects for Function Arguments</a></h4>
<p>
Relevant example from the standard library:
</p>

<blockquote class="standard_example">
<h4>25.10.3 Reduce [reduce]</h4>
<ol>
<pre>
template&lt;class InputIterator&gt;
  typename iterator_traits&lt;InputIterator&gt;::value_type
    reduce(InputIterator first, InputIterator last);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<pre>
return reduce(first, last,
              <ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type{});
</pre>
</li>
</ol>
</blockquote>

<p>
<b>Rationale:</b>
Passing a temporary value to a function call necessarily creates an expression,
and so continues to require the <code>typename</code> keyword, as this is the very
reason it exists.
</p>


<h4><a id="3.1.A">3.1.10 Preserve <code>typename</code> for Default Function Arguments</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
struct Indirect {
   using type = T;
};

template &lt;class T&gt;
void fun(typename Indirect&lt;T&gt;::type = <ins>typename</ins> Indirect&lt;T&gt;::type{}) {}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Default function arguments are just another way of packaging up the value to
pass, and so have the same concerns as any other expression to pass a function
argument, as above.  Hence, the <code>typename</code> keyword remains required.
</p>


<h4><a id="3.1.B">3.1.11 Preserve <code>typename</code> for Default Member Initializers</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template&lt;class T&gt;
struct host {
   T::type d_value = <ins>typename</ins> T::type{};
};
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Default member initializers are necessarily expressions, and so continue to
require the <code>typename</code> keyword to construct temporary arguments.
</p>


<h4><a id="3.1.C">3.1.12 Preserve <code>typename</code> for <code>alignof</code> Expressions</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
void func() {
   auto x = alignof(<ins>typename</ins> T::type); 
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
An <code>alignof</code> expression requires that its argument be a <i>type-id</i>,
and so in principle the requirement for <code>typename</code> could be relaxed in
this context by a future standard.  However, this is (indirectly) the subject
of core issue
<a href="http://wiki.edg.com/pub/Wg21summer2020/CoreWorkingGroup/cwg_closed.html#1008">#1008</a>,
an extension request that was discussed recently by EWG and there may well be a
forthcoming proposal for <code>alignof</code> to accept expressions, much like
<code>sizeof</code>, in which case the <code>typename</code> keyword would become
necessary to disambiguate the two cases.
</p>

<h4><a id="3.1.D">3.1.13 Preserve <code>typename</code> within <code>decltype</code> Expressions</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
void func() {
   using x = decltype(<ins>typename</ins> T::type{}); 
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Any syntax that expects an expression continues to require the
<code>typename</code> keyword, as this is the very reason it exists.  Note that
this usage of <code>decltype</code> is essentially an overly complicated way of
spelling the type already clearly identified within the parentheses.
</p>


<h4><a id="3.1.E">3.1.14 Preserve <code>typename</code> for <code>noexcept</code> Expressions</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
void func() {
   auto x = noexcept(<ins>typename</ins> T::type{}); 
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Any syntax that expects an expression continues to require the
<code>typename</code> keyword, as this is the very reason it exists.
</p>


<h4><a id="3.1.F">3.1.15 Preserve <code>typename</code> for <code>sizeof</code> Expressions</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
void func() {
   auto x = sizeof(<ins>typename</ins> T::type &amp;&amp;);
   auto y = sizeof(<ins>typename</ins> T::type {});
   auto z = sizeof <ins>typename</ins> T::type {} ;
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Any syntax that expects or admits an expression continues to require the
<code>typename</code> keyword, as this is the very reason it exists.  The
form of <code>sizeof</code> taking a type name in parentheses must be
disambiguated from <code>sizeof</code> a plain parenthetical expression.
</p>


<h4><a id="3.1.G">3.1.16 Preserve <code>typename</code> for <code>throw</code> Expressions</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
void chuck() {
   throw <ins>typename</ins> T::type{}; 
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Any syntax that expects an expression continues to require the
<code>typename</code> keyword, as this is the very reason it exists.
</p>


<h4><a id="3.1.H">3.1.17 Preserve <code>typename</code> for <code>typeid</code> Expressions</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
#include &lt;typeinfo&gt;

template &lt;class T&gt;
void func() {
   auto x = typeid(<ins>typename</ins> T::type *);
   auto y = typeid(<ins>typename</ins> T::type{});
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
Any syntax that expects or admits an expression continues to require the
<code>typename</code> keyword, as this is the very reason it exists.
</p>


<h4><a id="3.1.I">3.1.18 Preserve <code>typename</code> for Cast Expressions</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
void func() {
   auto a = static_cast&lt;T&gt;(<ins>typename</ins> T::type{});
   auto b = const_cast&lt;T const &amp;&gt;(<ins>typename</ins> T::type{});
   auto c = dynamic_cast&lt;T&gt;(<ins>typename</ins> T::type{});
   auto d = reinterpret_cast&lt;T&gt;(<ins>typename</ins> T::type{});
   auto e = (void)<ins>typename</ins> T::type{};
   auto f = (<ins>typename</ins> T::type *)nullptr;
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
The argument to a cast is necessarily an expression, and so continues to
require the <code>typename</code> keyword, as this is the very reason it exists.
However, see <a href="#3.2.8">3.2.8</a> below regarding the angle-bracket
portion of this syntax.
</p>


<h4><a id="3.1.J">3.1.19 Preserve <code>typename</code> in Exception Specifications</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.  Note that this construction is particularly
obscure, relying on contextual conversion from objects of the dependent type to
<code>bool</code>.
</p>

<blockquote class="invented_example">
<pre>
struct Boolish {
   constexpr explicit operator bool() { return true; }
};

template &lt;class T&gt;
struct Indirect {
   using type = Boolish;
};

template &lt;class T&gt;
void func() noexcept(<ins>typename</ins> Indirect&lt;T&gt;::type{});
</pre>
</blockquote>

<p>
<b>Rationale:</b>
The content of an exception specification is a predicate expression, and so
continues to require the <code>typename</code> keyword.
</p>



<h3><a id="3.2">3.2 Patterns that Remove <code>typename</code></a></h3>
<p>
Next, we will examine the places where the language has sufficient context to
make the use of <code>typename</code> optional, with a relevant example in each
case.  Ideally examples will quote from the standard library, otherwise fresh
examples are created where the syntax pattern is not yet used within the
library clauses of the standard, to preserve the knowledge in case it becomes
relevant to wording future proposals.
</p>


<h4><a id="3.2.1">3.2.1 Remove <code>typename</code> from Alias Definitions</a></h4>
<p>
Relevant examples from the standard library:
</p>

<blockquote class="standard_example">
<h4>20.15.2 Header <code>&lt;type_traits&gt;</code> synopsis [meta.type.synop]</h4>
<pre>
namespace std {
template&lt;class T&gt;
  using remove_const_t = <del>typename</del> remove_const&lt;T&gt;::type;
}
</pre>
</blockquote>


<blockquote class="standard_example">
<h4>21.3.2 Class template <code>basic_string</code> [basic.string]</h4>
<pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;,
           class Allocator = allocator&lt;charT&gt;&gt;
  class basic_string {
  public:
    // types
    using traits_type        = traits;
    using value_type         = charT;
    using allocator_type     = Allocator;
    using size_type          = <del>typename</del> allocator_traits&lt;Allocator&gt;::size_type;
    using difference_type    = <del>typename</del> allocator_traits&lt;Allocator&gt;::difference_type;
    using pointer            = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
    using const_pointer      = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
    using reference          = value_type&amp;;
    using const_reference    = const value_type&amp;;

    // ...
  };
}
</pre>
</blockquote>

<blockquote class="standard_example">
<h4>22.3.8.1 Overview [deque.overview]</h4>
<pre>
namespace std {
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt;
    class deque {
    public:
      <i>// types</i>
      using value_type             = T;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
      using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;

      <i>// ...</i>
    };
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
When defining a type alias, or alias template, with either <code>using</code>
or <code>typedef</code>, the parser is already primed to expect a type, so
<code>typename</code> can be safely omitted.  This would be by far the most
common application of the remove redundant <code>typename</code>s from the
library principle.
</p>
<p>
Note that early drafts of this paper were hesitant to recommend striking
<code>typename</code> in these cases while
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0945r0">P0945R0</a>
was still in flight, generalizing the notion of aliases through <code>using</code>.
That proposal was rejected, and now that C++20 is finalized, it could not
return without being a breaking change, so the recommendation to remove
<code>typename</code> in these cases stands, and is likely the most widely
encountered case for a change.
</p>


<h4><a id="3.2.2">3.2.2 Remove <code>typename</code> from Default Template Arguments</a></h4>
<p>
Relevant example from the standard library:
</p>

<blockquote class="standard_example">
<h4>27.2 Header <code>&lt;chrono&gt;</code> synopsis [time.syn]</h4>
<pre>
namespace std {
  namespace chrono {
    <i>// 27.5, class template duration</i>
    template&lt;class Rep, class Period = ratio&lt;1&gt;&gt; class duration;

    <i>// 27.6, class template time_point</i>
    template&lt;class Clock, class Duration = <del>typename</del> Clock::duration&gt; class time_point;
  }
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
When declaring a template-head with default template parameters, the right-hand
side of the <code>=</code> is known to require a type (for a type parameter) so
there is no ambiguity to discriminate, and the <code>typename</code> keyword
becomes optional.
</p>


<h4><a id="3.2.3">3.2.3 Remove <code>typename</code> from Variable Template declarations</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template &lt;class T&gt;
struct Indirect {
   using type = T;
};

template &lt;class T&gt;
<del>typename</del> Indirect&lt;T&gt;::type default_value = <ins>typename</ins> Indirect&lt;T&gt;::type{};

template &lt;class T&gt;
<del>typename</del> Indirect&lt;T&gt;::type another_value{ <ins>typename</ins> Indirect&lt;T&gt;::type{} };
</pre>
</blockquote>

<p>
<b>Rationale:</b>
This case is confusingly similar to the non-redundancy highlighted for variable
template <i>definitions</i> where the <code>typename</code> remains essential when
providing the value to initialize with.  However, the <code>typename</code> on the
declaration itself is now optional, as illustrated in the example above.
</p>



<h4><a id="3.2.4">3.2.4 Remove <code>typename</code> from Function Return Types</a></h4>
<p>
Relevant examples from the standard library:
</p>

<blockquote class="standard_example">
<h4>21.3.1 Header <code>&lt;string&gt;</code> synopsis [string.syn]</h4>
<pre>
namespace std {

  <i>// ...</i>

  <i>// 21.3.3.5, erasure</i>
  template&lt;class charT, class traits, class Allocator, class U&gt;
    constexpr <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type
      erase(basic_string&lt;charT, traits, Allocator&gt;&amp; c, const U&amp; value);
  template&lt;class charT, class traits, class Allocator, class Predicate&gt;
    constexpr <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type
      erase_if(basic_string&lt;charT, traits, Allocator&gt;&amp; c, Predicate pred);

  <i>// basic_string typedef names</i>
  <i>// ...</i>
}
</pre>
</blockquote>

<p>
There is no example in the standard library of a dependent trailing return type
using <code>typename</code>, so we adapt the previous example for illustration purposes
below:
</p>

<blockquote class="invented_example">
<pre>
template&lt;class charT, class traits, class Allocator, class U&gt;
  constexpr auto erase(basic_string&lt;charT, traits, Allocator&gt;&amp; c, const U&amp; value)
              -&gt; <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type;
template&lt;class charT, class traits, class Allocator, class Predicate&gt;
  constexpr auto erase_if(basic_string&lt;charT, traits, Allocator&gt;&amp; c, Predicate pred);
              -&gt; <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type;
</pre>
</blockquote>


<p>
<b>Rationale:</b>
The grammar is unambiguous that the return type of a function is indeed a type,
so the <code>typename</code> keyword is optional in this context.
</p>


<h4><a id="3.2.5">3.2.5 Remove <code>typename</code> from Friend Function Declarations</a></h4>
<p>
There is no example in the standard library, so we provide our own example to
illustrate the use case below.
</p>

<blockquote class="invented_example">
<pre>
template&lt;class T&gt;
struct host {
   friend void func(<del>typename</del> T::type) {}

   template&lt;class U&gt;
   friend void func(<del>typename</del> U::type) {}
};
</pre>
</blockquote>

<p>
<b>Rationale:</b>
The grammar inside a class definition does not suffer from the vexing parse
issues of global/namespace scope, even for friend functions, so
<code>typename</code> can be safely omitted from any friend function parameters.
</p>

<p>
Note that default function arguments remain constrained to use the
<code>typename</code> keyword in all scenarios.
</p>


<h4><a id="3.2.6">3.2.6 Remove <code>typename</code> from Member Function Declarations</a></h4>
<p>
Relevant example from the standard library:
</p>

<blockquote class="standard_example">
<h4>23.5.2.1 Class template <code>back_insert_iterator</code> [back.insert.iterator]</h4>
<pre>
namespace std {
  template&lt;class Container&gt;
  class back_insert_iterator {
  <i>// ...</i>

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = ptrdiff_t;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    constexpr back_insert_iterator() noexcept = default;
    constexpr explicit back_insert_iterator(Container&amp; x);
    constexpr back_insert_iterator&amp; operator=(const <del>typename</del> Container::value_type&amp; value);
    constexpr back_insert_iterator&amp; operator=(<del>typename</del> Container::value_type&amp;&amp; value);

    <i>// ...</i>
  };
}
</pre>
</blockquote>

<p>
<b>Rationale:</b>
The grammar inside a class definition does not suffer from the vexing parse
issues of global/namespace scope, so <code>typename</code> can be safely omitted
from any member function parameters.  Similarly, for a member function to be
defined outside the class definition, it must be redeclared with a qualified
name, which again avoids ambiguous parses, making <code>typename</code> optional.
</p>

<p>
Note that default function arguments remain constrained to use the
<code>typename</code> keyword in all scenarios.
</p>


<h4><a id="3.2.7">3.2.7 Remove <code>typename</code> from Data Member Declarations</a></h4>
<p>
Relevant example from the standard library:
</p>

<blockquote class="standard_example">
<h4>22.2.4.1 Overview [container.node.overview]</h4>
<pre>
template&lt;<i>unspecified</i>&gt;
class <i>node-handle</i> {
  <i>// ...</i>

private:
  using container_node_type = <i>unspecified</i>;
  using ator_traits = allocator_traits&lt;allocator_type&gt;;

  <del>typename</del> ator_traits::rebind_traits&lt;container_node_type&gt;::pointer ptr_;
  optional&lt;allocator_type&gt; alloc_;

  <i>// ...</i>
};
</pre>
</blockquote>

<p>
<b>Rationale:</b>
The grammar inside a class definition does not suffer from the vexing parse
issues of global/namespace scope, so <code>typename</code> can be safely omitted
from any data member declarations.
</p>


<h4><a id="3.2.8">3.2.8 Remove <code>typename</code> from C++ Cast Types</a></h4>
<p>
Relevant example from the standard library:
</p>

<blockquote class="standard_example">
<h4>20.11.3.9 Casts [util.smartptr.shared.cast]</h4>
<ol>
<pre>
template&lt;class T, class U&gt;
  shared_ptr&lt;T&gt; static_pointer_cast(const shared_ptr&lt;U&gt;&amp; r) noexcept;
template&lt;class T, class U&gt;
  shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt;&amp;&amp; r) noexcept;
</pre>
<li>
<i>Mandates:</i> The expression <code>static_cast&lt;T*&gt;((U*)nullptr)</code>
shall be well-formed.
</li>
<li>
<i>Returns:</i>
<blockquote><pre>
  shared_ptr&lt;T&gt;(<i>R</i>, static_cast&lt;<del>typename</del> shared_ptr&lt;T&gt;::element_type*&gt;(r.get()))
</pre></blockquote>
where <code><i>R</i></code> is <code>r</code> for the first overload, and <code>std::move(r)</code> for the second.
</li>
<li>
[ <i>Note:</i> The seemingly equivalent expression
<code>shared_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code> will eventually
result in undefined behavior, attempting to delete the same object twice.
&mdash; <i>end note</i> ]
</li>
</ol>
</blockquote>

<p>
<b>Rationale:</b>
For each of the four C++ type-casts, the content of the angle brackets
specifying what to cast to is unambiguously a type, so the <code>typename</code>
keyword is optional.  This does not apply to C-style casts, as the grammar
around parentheses is more nuanced.
</p>


<h4><a id="3.2.9">3.2.9 Remove <code>typename</code> from New Expressions</a></h4>
<p>
Relevant example from the standard library:
</p>

<blockquote class="standard_example">
<h4>25.11.3 <code>uninitialized_value_construct</code> [uninitialized.construct.value]</h4>
<ol>
<pre>
template &lt;class NoThrowForwardIterator&gt;
  void uninitialized_value_construct(NoThrowForwardIterator first, NoThrowForwardIterator last);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
for (; first != last; ++first)
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type();
</pre></blockquote>
</li>
</ol>
</blockquote>

<p>
<b>Rationale:</b>
It is clear that for a <code>new</code> expression to create an object, you must
name the type of the object to be created, so there is no ambiguity in the
grammar at this point, and the <code>typename</code> can be safely omitted.
</p>



<h2><a id="4.0">4 Impact on the Standard</a></h2>
<p>
The net effect will be a cleaner standard with less syntactic noise distracting
from reading a variety of declarations.  In some cases, this will also lead to
less line wrapping, further promoting clarity.
</p>

<p>
There is no risk to the language in adopting the feature, as it is purely
editorial in effect.  However, there may be a perceived risk in applying such
an edit entirely under the purview of editorial oversight, in the case of
accidental overreach removing a necessary <code>typename</code>.
</p>

<p>
One subtle consequence is that it might no longer be as easy to copy/paste
library declarations out of the standard directly into a standard library
implementation, unless the vendor is willing to assume a C++20 baseline for
their support.  For vendors wishing to maintain ongoing support for customers
relying on older dialects of the language, they would have to enter the
redundant <code>typename</code>s themselves.
</p>



<h2><a id="5.0">5 Tentative Wording (Informative)</a></h2>
<p>
The following are a representative set of changes from applying the editorial
guidelines above; they are not intended to be complete for review purposes
(although a best faith effort hopes they are, outside Annex D!) but to give a
fair impression of the kind and scale of changes that are proposed.  It is
expected that the editors would take this as guidance for bringing the working
draft into a good state, rather than perform a line-by-line review by the whole
LWG.  Note that unlike the sequence of mandating papers for C++20, there are no
issues with rewording requiring a more detailed review - the only changes are
striking redundant use of a single keyword, not replacing it with anything
else.
</p>
<p>
The editorial conventions for the following wording are:
</p>
<ul>
<li>
<code><ins>typename</ins></code> : non-redundant <code>typename</code> that must be retained
</li>
<li>
<code><del>typename</del></code> : redundant <code>typename</code> that should be excised
</li>
<li>
<code><b>typename</b></code> : grammatical use of <code>typename</code> other than to disambiguate dependent names
</li>
</ul>
<p>
Where a <code><ins>typename</ins></code> is retained in a declaration in a header
synopsis, the normative specification is not duplicated unless there are
additional interactions in that specification wording itself.
</p>

<blockquote class="std">
<h4>17.11.1 Header <code>&lt;compare&gt;</code> synopsis [compare.syn]</h4>
<ol>
<li>
The header <code>&lt;compare&gt;</code> specifies types, objects, and functions for
use primarily in connection with the three-way comparison operator (7.6.8).
</li>
</ol>
<blockquote><pre>
namespace std {
  <i>// 17.11.2, comparison category types</i>
  class partial_ordering;
  class weak_ordering;
  class strong_ordering;

  <i>// named comparison functions</i>
  constexpr bool is_eq  (partial_ordering cmp) noexcept { return cmp == 0; }
  constexpr bool is_neq (partial_ordering cmp) noexcept { return cmp != 0; }
  constexpr bool is_lt  (partial_ordering cmp) noexcept { return cmp &lt;  0; }
  constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp &lt;= 0; }
  constexpr bool is_gt  (partial_ordering cmp) noexcept { return cmp &gt;  0; }
  constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp &gt;= 0; }

  <i>// 17.11.3, common comparison category type</i>
  template&lt;class... Ts&gt;
    struct common_comparison_category {
      using type = see below;
    };
  template&lt;class... Ts&gt;
    using common_comparison_category_t = <del>typename</del> common_comparison_category&lt;Ts...&gt;::type;

  <i>// 17.11.4, concept three_way_comparable</i>
  template&lt;class T, class Cat = partial_ordering&gt;
    concept three_way_comparable = <i>see below</i>;
  template&lt;class T, class U, class Cat = partial_ordering&gt;
    concept three_way_comparable_with = <i>see below</i>;

  <i>// 17.11.5, result of three-way comparison</i>
  template&lt;class T, class U = T&gt; struct compare_three_way_result;

  template&lt;class T, class U = T&gt;
    using compare_three_way_result_t = <del>typename</del> compare_three_way_result&lt;T, U&gt;::type;

  <i>// 20.14.7.7, class compare_three_way</i>
  struct compare_three_way;

  <i>// 17.11.6, comparison algorithms</i>
  inline namespace unspecified {
    inline constexpr <i>unspecified</i> strong_order  = <i>unspecified</i>;
    inline constexpr <i>unspecified</i> weak_order    = <i>unspecified</i>;
    inline constexpr <i>unspecified</i> partial_order = <i>unspecified</i>;
    inline constexpr <i>unspecified</i> compare_strong_order_fallback  = <i>unspecified</i>;
    inline constexpr <i>unspecified</i> compare_weak_order_fallback    = <i>unspecified</i>;
    inline constexpr <i>unspecified</i> compare_partial_order_fallback = <i>unspecified</i>;
  }
}
</pre></blockquote>



<h4>17.12.2.1 Class template <code>coroutine_traits</code> [coroutine.traits.primary]</h4>
<ol>
<li>
The header <code>&lt;coroutine&gt;</code> defines the primary template
<code>coroutine_traits</code> such that if <code>ArgTypes</code> is a parameter pack of
types and if the <i>qualified-id</i> <code>R::promise_type</code> is valid and
denotes a type (13.10.2), then <code>coroutine_traits&lt;R,ArgTypes...&gt;</code>
has the following publicly accessible member:
<pre>
    using promise_type = <del>typename</del> R::promise_type;
</pre>
Otherwise, <code>coroutine_traits&lt;R,ArgTypes...&gt;</code> has no members.
</li>
</ol>


<h4>20.5.2 Header <code>&lt;tuple&gt;</code> synopsis [tuple.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;          // see 17.11.1

namespace std {
  <i>// ...</i>

  <i>// 20.5.6, tuple helper classes</i>
  template&lt;class T&gt; struct tuple_size;               <i>// not defined</i>
  template&lt;class T&gt; struct tuple_size&lt;const T&gt;;

  template&lt;class... Types&gt; struct tuple_size&lt;tuple&lt;Types...&gt;&gt;;

  template&lt;size_t I, class T&gt; struct tuple_element; <i>// not defined</i>
  template&lt;size_t I, class T&gt; struct tuple_element&lt;I, const T&gt;;

  template&lt;size_t I, class... Types&gt;
    struct tuple_element&lt;I, tuple&lt;Types...&gt;&gt;;
  template&lt;size_t I, class T&gt;
    using tuple_element_t = <del>typename</del> tuple_element&lt;I, T&gt;::type;

  <i>// ...</i>
}
</pre></blockquote>


<h4>20.7.2 Header <code>&lt;variant&gt;</code> synopsis [variant.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;          // see 17.11.1

namespace std {
  <i>// 20.7.3, class template</i> variant
  template&lt;class... Types&gt;
    class variant;

  <i>// 20.7.4, variant helper classes</i>
  template&lt;class T&gt; struct variant_size;                        <i>// not defined</i>
  template&lt;class T&gt; struct variant_size&lt;const T&gt;;
  template&lt;class T&gt;
    inline constexpr size_t variant_size_v = variant_size&lt;T&gt;::value;

  template&lt;class... Types&gt;
    struct variant_size&lt;variant&lt;Types...&gt;&gt;;

  template&lt;size_t I, class T&gt; struct variant_alternative;       <i>// not defined</i>
  template&lt;size_t I, class T&gt; struct variant_alternative&lt;I, const T&gt;;
  template&lt;size_t I, class T&gt;
    using variant_alternative_t = <del>typename</del> variant_alternative&lt;I, T&gt;::type;

  template&lt;size_t I, class... Types&gt;
    struct variant_alternative&lt;I, variant&lt;Types...&gt;&gt;;

  inline constexpr size_t variant_npos = -1;

  <i>// ...</i>
}
</pre></blockquote>


<h4>20.9.2 Class template <code>bitset</code> [template.bitset]</h4>
<blockquote><pre>
namespace std {
  template&lt;size_t N&gt; class bitset {
  public:
    <i>// elided declarations ...</i>

    <i>// 20.9.2.1, constructors</i>
    constexpr bitset() noexcept;
    constexpr bitset(unsigned long long val) noexcept;
    template&lt;class charT, class traits, class Allocator&gt;
      explicit bitset(
        const basic_string&lt;charT, traits, Allocator&gt;&amp; str,
        <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type pos = 0,
        <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type n
          = basic_string&lt;charT, traits, Allocator&gt;::npos,
        charT zero = charT('0'),
        charT one = charT('1'));
    template &lt;class charT&gt;
      explicit bitset(
        const charT* str,
        <del>typename</del> basic_string&lt;charT&gt;::size_type n = basic_string&lt;charT&gt;::npos,
        charT zero = charT('0'),
        charT one = charT('1'));

    <i>// more elided declarations ...</i>
  };
}
</pre></blockquote>


<h4>20.9.2.1 Constructors [bitset.cons]</h4>
<blockquote><pre>
template&lt;class charT, class traits, class Allocator&gt;
  explicit bitset(
    const basic_string&lt;charT, traits, Allocator&gt;&amp; str,
    <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type pos = 0,
    <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type n
      = basic_string&lt;charT, traits, Allocator&gt;::npos,
    charT zero = charT('0'),
    charT one = charT('1'));
</pre></blockquote>
<ol start="3">
<li>
<i>Effects:</i> Determines the effective length ...</li>
</ol>


<blockquote><pre>
template &lt;class charT&gt;
  explicit bitset(
    const charT* str,
    <del>typename</del> basic_string&lt;charT&gt;::size_type n = basic_string&lt;charT&gt;::npos,
    charT zero = charT('0'),
    charT one = charT('1'));
</pre></blockquote>

<ol start="8">
<li>
<i>Effects:</i> As if by:
<blockquote><pre>
bitset(n == basic_string&lt;charT&gt;::npos
          ? basic_string&lt;charT&gt;(str)
          : basic_string&lt;charT&gt;(str, n),
       0, n, zero, one)
</pre></blockquote>
</li>
</ol>


<h4>20.10.2 Header <code>&lt;memory&gt;</code> synopsis [memory.syn]</h4>
<blockquote><pre>
namespace std {
<i>// ...</i>

// 20.11.1, class template unique_ptr
<i>// ...</i>

template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator==(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator&lt;(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator&gt;(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator&lt;=(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator&gt;=(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  requires three_way_comparable_with&lt;<ins>typename</ins> unique_ptr&lt;T1, D1&gt;::pointer,
                                     <ins>typename</ins> unique_ptr&lt;T2, D2&gt;::pointer&gt;
  compare_three_way_result_t&lt;<ins>typename</ins> unique_ptr&lt;T1, D1&gt;::pointer,
                             <ins>typename</ins> unique_ptr&lt;T2, D2&gt;::pointer&gt;
    operator&lt;=&gt;(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);

template&lt;class T, class D&gt;
  bool operator==(const unique_ptr&lt;T, D&gt;&amp; x, nullptr_t) noexcept;
template&lt;class T, class D&gt;
  bool operator&lt;(const unique_ptr&lt;T, D&gt;&amp; x, nullptr_t);
template&lt;class T, class D&gt;
  bool operator&lt;(nullptr_t, const unique_ptr&lt;T, D&gt;&amp; y);
template&lt;class T, class D&gt;
  bool operator&gt;(const unique_ptr&lt;T, D&gt;&amp; x, nullptr_t);
template&lt;class T, class D&gt;
  bool operator&gt;(nullptr_t, const unique_ptr&lt;T, D&gt;&amp; y);
template&lt;class T, class D&gt;
  bool operator&lt;=(const unique_ptr&lt;T, D&gt;&amp; x, nullptr_t);
template&lt;class T, class D&gt;
  bool operator&lt;=(nullptr_t, const unique_ptr&lt;T, D&gt;&amp; y);
template&lt;class T, class D&gt;
  bool operator&gt;=(const unique_ptr&lt;T, D&gt;&amp; x, nullptr_t);
template&lt;class T, class D&gt;
  bool operator&gt;=(nullptr_t, const unique_ptr&lt;T, D&gt;&amp; y);
template&lt;class T, class D&gt;
  requires three_way_comparable_with&lt;<ins>typename</ins> unique_ptr&lt;T, D&gt;::pointer, nullptr_t&gt;
  compare_three_way_result_t&lt;<ins>typename</ins> unique_ptr&lt;T, D&gt;::pointer, nullptr_t&gt;
    operator&lt;=&gt;(const unique_ptr&lt;T, D&gt;&amp; x, nullptr_t);

<i>// ...</i>
}
</pre></blockquote>


<h4>20.10.9 Allocator traits [allocator.traits]</h4>
<ol>
<li>
The class template <code>allocator_traits</code> supplies ...
</li>
</ol>
<blockquote><pre>
namespace std {
  template&lt;class Alloc&gt; struct allocator_traits {
    using allocator_type     = Alloc;

    using value_type         = <del>typename</del> Alloc::value_type;

    using pointer            = <i>see below</i>
    using const_pointer      = <i>see below</i>
    using void_pointer       = <i>see below</i>
    using const_void_pointer = <i>see below</i>

    using difference_type    = <i>see below</i>
    using size_type          = <i>see below</i>

    <i>// ...</i>
</pre></blockquote>


<h4>20.11.1.5 Specialized algorithms [unique.ptr.special]</h4>
<blockquote><pre>
template &lt;class T1, class D1, class T2, class D2&gt;
  bool operator&lt;(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);
</pre></blockquote>
<ol start="4">
<li>
Let <code>CT</code> denote<pre>
common_type_t&lt;<ins>typename</ins> unique_ptr&lt;T1, D1&gt;::pointer,
              <ins>typename</ins> unique_ptr&lt;T2, D2&gt;::pointer&gt;</pre>
</li>
<li>
<i>Mandates:</i>
  <ol>
  <li>&mdash; <code>unique_ptr&lt;T1, D1&gt;::pointer</code> is implicitly convertible to <code>CT</code> and</li>
  <li>&mdash; <code>unique_ptr&lt;T2, D2&gt;::pointer</code> is implicitly convertible to <code>CT</code>.</li>
  </ol>
</li>
</ol>
<blockquote class="note">
Note the existing documentation convention to frequently omit <code>typename</code>
in normative text that names a type in descriptive text.
</blockquote>


<h4>20.11.3.9 Casts [util.smartptr.shared.cast]</h4>
<ol>
<pre>
templatecl&lt;ass T, class U&gt;
  shared_ptr&lt;T&gt; static_pointer_cast(const shared_ptr&lt;U&gt;&amp; r) noexcept;
templatecl&lt;ass T, class U&gt;
  shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt;&amp;&amp; r) noexcept;
</pre>
<li>
<i>Mandates:</i> The expression <code>static_cast&lt;T*&gt;((U*)nullptr)</code>
shall be well-formed.
</li>
<li>
<i>Returns:</i>
<blockquote><pre>
  shared_ptr&lt;T&gt;(<i>R</i>, static_cast&lt;<del>typename</del> shared_ptr&lt;T&gt;::element_type*&gt;(r.get()))
</pre></blockquote>
where <code><i>R</i></code> is <code>r</code> for the first overload, and <code>std::move(r)</code> for the second.
</li>
<li>
[ <i>Note:</i> The seemingly equivalent expression
<code>shared_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code> will eventually
result in undefined behavior, attempting to delete the same object twice.
&mdash; <i>end note</i> ]
</li>

<pre>
template &lt;class T, class U&gt;
  shared_ptr&lt;T&gt; dynamic_pointer_cast(const shared_ptr&lt;U&gt;&amp; r) noexcept;
template &lt;class T, class U&gt;
  shared_ptr&lt;T&gt; dynamic_pointer_cast(shared_ptr&lt;U&gt;&amp;&amp; r) noexcept;
</pre>
<li>
<i>Mandates:</i> The expression <code>dynamic_cast&lt;T*&gt;((U*)nullptr)</code>
is  well-formed.  The expression
<code>dynamic_cast&lt;<del>typename</del> shared_ptr&lt;T&gt;::element_type*&gt;(r.get())</code>
is well formed.
</li>
<li>
<i>Preconditions:</i> The expression
<code>dynamic_cast&lt;<del>typename</del> shared_ptr&lt;T&gt;::element_type*&gt;(r.get())</code>
has well-defined behavior.
</li>
<li>
<i>Returns:</i>
  <ol>
  <li>
  When
  <code>dynamic_cast&lt;<del>typename</del> shared_ptr&lt;T&gt;::element_type*&gt;(r.get())</code>
  returns a non-null value <code>p</code>, <code>shared_ptr&lt;T&gt;(<i>R</i>, p)</code>,
  where <code><i>R</i></code> is <code>r</code> for the first overload, and <code>std::move(r)</code>
  for the second.
  </li>
  <li>Otherwise, <code>shared_ptr&lt;T&gt;()</code>.</li>
  </ol>
</li>

<li>
[ <i>Note:</i> The seemingly equivalent expression
<code>shared_ptr&lt;T&gt;(dynamic_cast&lt;T*&gt;(r.get()))</code> will eventually
result in undefined behavior, attempting to delete the same object twice.
&mdash; <i>end note</i> ]
</li>

<pre>
template &lt;class T, class U&gt;
  shared_ptr&lt;T&gt; const_pointer_cast(const shared_ptr&lt;U&gt;&amp; r) noexcept;
template &lt;class T, class U&gt;
  shared_ptr&lt;T&gt; const_pointer_cast(shared_ptr&lt;U&gt;&amp;&amp; r) noexcept;
</pre>
<li>
<i>Mandates:</i> The expression <code>const_cast&lt;T*&gt;((U*)nullptr)</code>
shall be well-formed.
</li>
<li>
<i>Returns:</i>
<blockquote><pre>
  shared_ptr&lt;T&gt;(<i>R</i>, const_cast&lt;<del>typename</del> shared_ptr&lt;T&gt;::element_type*&gt;(r.get()))
</pre></blockquote>
where <code><i>R</i></code> is <code>r</code> for the first overload, and <code>std::move(r)</code> for the second.
</li>
<li>
[ <i>Note:</i> The seemingly equivalent expression
<code>shared_ptr&lt;T&gt;(const_cast&lt;T*&gt;(r.get()))</code> will eventually
result in undefined behavior, attempting to delete the same object twice.
&mdash; <i>end note</i> ]
</li>

<pre>
template &lt;class T, class U&gt;
  shared_ptr&lt;T&gt; reinterpret_pointer_cast(const shared_ptr&lt;U&gt;&amp; r) noexcept;
template &lt;class T, class U&gt;
  shared_ptr&lt;T&gt; reinterpret_pointer_cast(shared_ptr&lt;U&gt;&amp;&amp; r) noexcept;
</pre>
<li>
<i>Mandates:</i> The expression <code>reinterpret_cast&lt;T*&gt;((U*)nullptr)</code>
shall be well-formed.
</li>
<li>
<i>Returns:</i>
<blockquote><pre>
  shared_ptr&lt;T&gt;(<i>R</i>, reinterpret_cast&lt;<del>typename</del> shared_ptr&lt;T&gt;::element_type*&gt;(r.get()))
</pre></blockquote>
where <code><i>R</i></code> is <code>r</code> for the first overload, and <code>std::move(r)</code> for the second.
</li>
<li>
[ <i>Note:</i> The seemingly equivalent expression
<code>shared_ptr&lt;T&gt;(reinterpret_cast&lt;T*&gt;(r.get()))</code> will
eventually result in undefined behavior, attempting to delete the same object
twice. &mdash; <i>end note</i> ]
</li>
</ol>


<h4>20.11.7 Smart pointer hash support [util.smartptr.hash]</h4>
<ol>
<blockquote><pre>
template&lt;class T, class D&gt; struct hash&lt;unique_ptr&lt;T, D&gt;&gt;;
</pre></blockquote>
<li>
Letting <code>UP</code> be <code>unique_ptr&lt;T,D&gt;</code>, the specialization
<code>hash&lt;UP&gt;</code> is enabled (20.14.18) if and only if
<code>hash&lt;<ins>typename</ins> UP::pointer&gt;</code> is enabled.  When enabled,
for an object <code>p</code> of type <code>UP</code>, <code>hash&lt;UP&gt;()(p)</code>
evaluates to the same value as
<code>hash&lt;<ins>typename</ins> UP::pointer&gt;()(p.get())</code>. The member
functions are not guaranteed to be <code>noexcept</code>.
</li>

<blockquote><pre>
template&lt;class T&gt; struct hash&lt;shared_ptr&lt;T&gt;&gt;;
</pre></blockquote>
<li>
For an object <code>p</code> of type <code>shared_ptr&lt;T&gt;</code>,
<code>hash&lt;shared_ptr&lt;T&gt;&gt;()(p)</code> evaluates to the same value as
<code>hash&lt;<ins>typename</ins> shared_ptr&lt;T&gt;::element_type*&gt;()(p.get())</code>.
</li>
</ol>


<h4>20.13.1 Header <code>&lt;scoped_allocator&gt;</code> synopsis [allocator.adaptor.syn]</h4>
<blockquote><pre>
namespace std {
<i>// class template scoped allocator adaptor</i>
template&lt;class OuterAlloc, class... InnerAlloc&gt;
  class scoped_allocator_adaptor;

<i>// 20.13.5, scoped allocator operators</i>
template&lt;class OuterA1, class OuterA2, class... InnerAllocs&gt;
  bool operator==(const scoped_allocator_adaptor&lt;OuterA1, InnerAllocs...&gt;&amp; a,
                  const scoped_allocator_adaptor&lt;OuterA2, InnerAllocs...&gt;&amp; b) noexcept;
}
</pre></blockquote>
<ol>
<li>
The class template <code>scoped_allocator_adaptor</code> is ...
</li>
</ol>
<blockquote><pre>
namespace std {
  template&lt;class OuterAlloc, class... InnerAlloc&gt;
    class scoped_allocator_adaptor : public OuterAlloc {
    private:
      using OuterTraits = allocator_traits&lt;OuterAlloc&gt;;  <i>// exposition only</i>
      scoped_allocator_adaptor&lt;InnerAllocs...&gt; inner;    <i>// exposition only</i>

    public:
      using outer_allocator_type = OuterAlloc;
      using inner_allocator_type = <i>see below</i>;

      using value_type           = <del>typename</del> OuterTraits::value_type;
      using size_type            = <del>typename</del> OuterTraits::size_type;
      using difference_type      = <del>typename</del> OuterTraits::difference_type;
      using pointer              = <del>typename</del> OuterTraits::pointer;
      using const_pointer        = <del>typename</del> OuterTraits::const_pointer;
      using void_pointer         = <del>typename</del> OuterTraits::void_pointer;
      using const_void_pointer   = <del>typename</del> OuterTraits::const_void_pointer;

      <i>// ...</i>
  };
}
</pre></blockquote>


<h4>23.14.1 Header <code>&lt;functional&gt;</code> synopsis [functional.syn]</h4>
<blockquote><pre>
namespace std {
<i>// ...</i>

<i>// 20.14.17, searchers</i>
template&lt;class ForwardIterator, class BinaryPredicate = equal_to&lt;&gt;&gt;
  class default_searcher;
template&lt;class RandomAccessIterator,
         class Hash = hash&lt;<ins>typename</ins> iterator_traits&lt;RandomAccessIterator&gt;::value_type&gt;,
         class BinaryPredicate = equal_to&lt;&gt;&gt;
  class boyer_moore_searcher;
template&lt;class RandomAccessIterator,
         class Hash = hash&lt;<ins>typename</ins> iterator_traits&lt;RandomAccessIterator&gt;::value_type&gt;,
         class BinaryPredicate = equal_to&lt;&gt;&gt;
  class boyer_moore_horspool_searcher;

<i>// ...</i>
}
</pre></blockquote>


<h4>20.14.17.2 Class template <code>boyer_moore_searcher</code> [func.search.bm]</h4>
<blockquote><pre>
template&lt;class RandomAccessIterator1,
         class Hash = hash&lt;<ins>typename</ins> iterator_traits&lt;RandomAccessIterator1&gt;::value_type&gt;,
         class BinaryPredicate = equal_to&lt;&gt;&gt;
  class boyer_moore_searcher {
  <i>// ...</i>
};
</pre></blockquote>


<h4>20.14.17.3 Class template <code>boyer_moore_horspool_searcher</code> [func.search.bmh]</h4>
<blockquote><pre>
template&lt;class RandomAccessIterator1,
         class Hash = hash&lt;<ins>typename</ins> iterator_traits&lt;RandomAccessIterator1&gt;::value_type&gt;,
         class BinaryPredicate = equal_to&lt;&gt;&gt;
  class boyer_moore_horspool_searcher {
  <i>// ...</i>
};
</pre></blockquote>


<h4>20.15.2 Header <code>&lt;type_traits&gt;</code> synopsis [meta.type.synop]</h4>
<blockquote><pre>
namespace std {
<i>// 20.15.3, helper class</i>
<i>// ...</i>

<i>// 20.15.7.1, const-volatile modifications</i>
template&lt;class T&gt; struct remove_const;
template&lt;class T&gt; struct remove_volatile;
template&lt;class T&gt; struct remove_cv;
template&lt;class T&gt; struct add_const;
template&lt;class T&gt; struct add_volatile;
template&lt;class T&gt; struct add_cv;

template&lt;class T&gt;
  using remove_const_t    = <del>typename</del> remove_const&lt;T&gt;::type;
template&lt;class T&gt;
  using remove_volatile_t = <del>typename</del> remove_volatile&lt;T&gt;::type;
template&lt;class T&gt;
  using remove_cv_t       = <del>typename</del> remove_cv&lt;T&gt;::type;
template&lt;class T&gt;
  using add_const_t       = <del>typename</del> add_const&lt;T&gt;::type;
template&lt;class T&gt;
  using add_volatile_t    = <del>typename</del> add_volatile&lt;T&gt;::type;
template&lt;class T&gt;
  using add_cv_t          = <del>typename</del> add_cv&lt;T&gt;::type;

<i>// 20.15.7.2, reference modifications</i>
template&lt;class T&gt; struct remove_reference;
template&lt;class T&gt; struct add_lvalue_reference;
template&lt;class T&gt; struct add_rvalue_reference;

template&lt;class T&gt;
  using remove_reference_t     = <del>typename</del> remove_reference&lt;T&gt;::type;
template&lt;class T&gt;
  using add_lvalue_reference_t = <del>typename</del> add_lvalue_reference&lt;T&gt;::type;
template&lt;class T&gt;
  using add_rvalue_reference_t = <del>typename</del> add_rvalue_reference&lt;T&gt;::type;

<i>// 20.15.7.3, sign modifications</i>
template&lt;class T&gt; struct make_signed;
template&lt;class T&gt; struct make_unsigned;

template&lt;class T&gt;
  using make_signed_t   = <del>typename</del> make_signed&lt;T&gt;::type;
template&lt;class T&gt;
  using make_unsigned_t = <del>typename</del> make_unsigned&lt;T&gt;::type;

<i>// 20.15.7.4, array modifications</i>
 template&lt;class T&gt; struct remove_extent;
template&lt;class T&gt; struct remove_all_extents;

template&lt;class T&gt;
  using remove_extent_t      = <del>typename</del> remove_extent&lt;T&gt;::type;
template&lt;class T&gt;
  using remove_all_extents_t = <del>typename</del> remove_all_extents&lt;T&gt;::type;

<i>// 20.15.7.5, pointer modifications</i>
 template&lt;class T&gt; struct remove_pointer;
 template&lt;class T&gt; struct add_pointer;

template&lt;class T&gt;
  using remove_pointer_t = <del>typename</del> remove_pointer&lt;T&gt;::type;
template&lt;class T&gt;
  using add_pointer_t    = <del>typename</del> add_pointer&lt;T&gt;::type;

<i>// 20.15.7.6, other transformations</i>
template&lt;class T&gt; struct type_identity;
template&lt;size_t Len, size_t Align = <i>default-alignment</i>&gt; <i>// see 20.15.7.6</i>
  struct aligned_storage;
template&lt;size_t Len, class... Types&gt; struct aligned_union;
template&lt;class T&gt; struct remove_cvref;
template&lt;class T&gt; struct decay;
template&lt;bool, class T = void&gt; struct enable_if;
template&lt;bool, class T, class F&gt; struct conditional;
template&lt;class... T&gt; struct common_type;
template&lt;class T, class U, template&lt;class&gt; class TQual, template&lt;class&gt; class UQual&gt;
  struct basic_common_reference { };
template&lt;class... T&gt; struct common_reference;
template&lt;class T&gt; struct underlying_type;
template&lt;class Fn, class... ArgTypes&gt; struct invoke_result;
template&lt;class T&gt; struct unwrap_reference;
template&lt;class T&gt; struct unwrap_ref_decay;

template&lt;class T&gt;
  using type_identity_t    = <del>typename</del> type_identity&lt;T&gt;::type;
template&lt;size_t Len, size_t Align = <i>default-alignment</i>&gt; // see 20.15.7.6
  using aligned_storage_t = <del>typename</del> aligned_storage&lt;Len, Align&gt;::type;
template&lt;size_t Len, class... Types&gt;
  using aligned_union_t = <del>typename</del> aligned_union&lt;Len, Types...&gt;::type;
template&lt;class T&gt;
  using remove_cvref_t = <del>typename</del> remove_cvref&lt;T&gt;::type;
template&lt;class T&gt;
   using decay_t   = <del>typename</del> decay&lt;T&gt;::type;
template&lt;bool b, class T = void&gt;
  using enable_if_t        = <del>typename</del> enable_if&lt;b, T&gt;::type;
template&lt;bool b, class T, class F&gt;
  using conditional_t      = <del>typename</del> conditional&lt;b, T, F&gt;::type;
template&lt;class... T&gt;
  using common_type_t      = <del>typename</del> common_type&lt;T...&gt;::type;
template&lt;class... T&gt;
  using common_reference_t = <del>typename</del> common_reference&lt;T...&gt;::type;
template&lt;class T&gt;
  using underlying_type_t  = <del>typename</del> underlying_type&lt;T&gt;::type;
template&lt;class Fn, class... ArgTypes&gt;
  using invoke_result_t    = <del>typename</del> invoke_result&lt;Fn, ArgTypes...&gt;::type;
template&lt;class T&gt;
  using unwrap_reference_t = <del>typename</del> unwrap_reference&lt;T&gt;::type;
template&lt;class T&gt;
  using unwrap_ref_decay_t = <del>typename</del> unwrap_ref_decay&lt;T&gt;::type;
template&lt;class...&gt;
  using void_t             = void;

<i>// 20.15.8, logical operator traits</i>
<i>// ...</i>

}
</pre></blockquote>


<h4>20.20.5.3 Class template <code>basic_format_parse_context</code> [format.parse.ctx]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT&gt;
  class basic_format_parse_context {
  public:
    using char_type = charT;
    using const_iterator = <del>typename</del> basic_string_view&lt;charT&gt;::const_iterator;
    using iterator = const_iterator;

    <i>// ...</i>
  };
}
</pre></blockquote>


<h4>20.20.6.1 Class template <code>basic_format_arg</code> [format.arg]</h4>
<blockquote><pre>
namespace std {
  template&lt;class Context&gt;
  class basic_format_arg {
  public:
    class handle;

  private:
    using char_type = <del>typename</del> Context::char_type;

    <i>// ...</i>
  };
}
</pre></blockquote>

<ol start="4">
<pre>
template&lt;class T&gt; explicit basic_format_arg(const T&amp; v) noexcept;
</pre>
<li>
<i>Constraints:</i> The template specialization
<pre><del>typename</del> Context::template formatter_type&lt;T&gt;</pre>
meets the Formatter requirements (20.20.5.1). The extent to which an
implementation determines that the specialization meets the Formatter
requirements is unspecified, except that as a minimum the expression
<pre>
  <ins>typename</ins> Context::template formatter_type&lt;T&gt;()
    .format(declval&lt;const T&amp;&gt;(), declval&lt;Context&amp;&gt;())
</pre>
shall be well-formed when treated as an unevaluated operand.
</li>
</ol>

<ol start="17">
<pre>
template&lt;class T&gt; explicit handle(const T&amp; val) noexcept;
</pre>
<li>
<i>Effects:</i> Initializes <code>ptr_</code> with <code>addressof(val)</code> and <code>format_</code> with
<pre>
[](basic_format_parse_context&lt;char_type&gt;&amp; parse_ctx,
   Context&amp; format_ctx, const void* ptr) {
  <ins>typename</ins> Context::template formatter_type&lt;T&gt; f;
  parse_ctx.advance_to(f.parse(parse_ctx));
  format_ctx.advance_to(f.format(*static_cast&lt;const T*&gt;(ptr), format_ctx));
}
</pre>
</li>
</ol>


<h4>20.20.6.2 Class template <code><i>format-arg-store</i></code> [format.arg.store]</h4>
<ol start="2">
<pre>
template&lt;class Context = format_context, class... Args&gt;
<i>format-arg-store</i>&lt;Context, Args...&gt; make_format_args(const Args&amp;... args);
</pre>
<li>
<i>Preconditions:</i> : The type
<code><del>typename</del> Context::template formatter_type&lt;T<sub><i>i</i></sub>&gt;</code>
meets the <i>Formatter</i> requirements (20.20.5.1) for each
T<code><sub><i>i</i></sub></code> in
<code>Args</code>.
</li>
<li>
<i>Returns:</i> <code>{basic_format_arg&lt;Context&gt;(args)...}</code>.
</li>
</ol>


<h4>21.3.1 Header <code>&lt;string&gt;</code> synopsis [string.syn]</h4>
<blockquote><pre>
namespace std {

  <i>// ...</i>

  <i>// 21.3.3.5, erasure</i>
  template&lt;class charT, class traits, class Allocator, class U&gt;
    constexpr <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type
      erase(basic_string&lt;charT, traits, Allocator&gt;&amp; c, const U&amp; value);
  template&lt;class charT, class traits, class Allocator, class Predicate&gt;
    constexpr <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type
      erase_if(basic_string&lt;charT, traits, Allocator&gt;&amp; c, Predicate pred);

  <i>// basic_string typedef names</i>
  <i>// ...</i>
}
</pre></blockquote>


<h4>21.3.2 Class template <code>basic_string</code> [basic.string]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;,
           class Allocator = allocator&lt;charT&gt;&gt;
  class basic_string {
  public:
    <i>// types</i>
    using traits_type            = traits;
    using value_type             = charT;
    using allocator_type         = Allocator;
    using size_type              = <del>typename</del> allocator_traits&lt;Allocator&gt;::size_type;
    using difference_type        = <del>typename</del> allocator_traits&lt;Allocator&gt;::difference_type;
    using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
    using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
    using reference              = value_type&amp;;
    using const_reference        = const value_type&amp;;

    using iterator               = <i>implementation-defined</i>; // see 22.2
    using const_iterator         = <i>implementation-defined</i>	; // see 22.2
    using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
    using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;
    static const size_type npos  = -1;

    <i>// 21.3.2.2, construct/copy/destroy</i>
    <i>// ...</i>
  };


  template&lt;class InputIterator,
           class Allocator = allocator&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type&gt;&gt;
    basic_string(InputIterator, InputIterator, Allocator = Allocator())
      -&gt; basic_string&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type,
                      char_traits&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type&gt;,
                      Allocator&gt;;
  template&lt;class charT,
           class traits,
           class Allocator = allocator&lt;charT&gt;&gt;
    explicit basic_string(basic_string_view&lt;charT, traits&gt;, const Allocator&amp; = Allocator())
      -&gt; basic_string&lt;charT, traits, Allocator&gt;;

  template&lt;class charT,
           class traits,
           class Allocator = allocator&lt;charT&gt;&gt;
    basic_string(basic_string_view&lt;charT, traits&gt;,
                 <ins>typename</ins> <i>see below</i>::size_type, <ins>typename</ins> <i>see below</i>::size_type,
                 const Allocator&amp; = Allocator())
      -&gt; basic_string&lt;charT, traits, Allocator&gt;;
}
</pre></blockquote>


<h4>21.3.3.5 Erasure [string.erasure]</h4>
<ol>
<pre>
template&lt;class charT, class traits, class Allocator, class U&gt;
  constexpr <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type
    erase(basic_string&lt;charT, traits, Allocator&gt;&amp; c, const U&amp; value);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<pre>
   auto it = remove(c.begin(), c.end(), value);
   auto r = distance(it, c.end());
   c.erase(it, c.end());
   return r;
</pre>
</li>
<pre>
template&lt;class charT, class traits, class Allocator, class Predicate&gt;
  constexpr <del>typename</del> basic_string&lt;charT, traits, Allocator&gt;::size_type
    erase_if(basic_string&lt;charT, traits, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<pre>
       auto it = remove_if(c.begin(), c.end(), pred);
       auto r = distance(it, c.end());
       c.erase(it, c.end());
       return r;
</pre>
</li>
</ol>


<h4>22.2.4.1 Overview [container.node.overview]</h4>
<blockquote><pre>
template&lt;<i>unspecified</i>&gt;
class <i>node-handle</i> {
  <i>// ...</i>

private:
  using container_node_type = <i>unspecified</i>;
  using ator_traits = allocator_traits&lt;allocator_type&gt;;

  <del>typename</del> ator_traits::rebind_traits&lt;container_node_type&gt;::pointer ptr_;
  optional&lt;allocator_type&gt; alloc_;

  <i>// ...</i>
};
</pre></blockquote>


<h4>22.3.1 In general [sequences.general]</h4>
<ol>
<li>
The headers <code>&lt;array&gt;</code> (22.3.2), <code>&lt;deque&gt;</code> (22.3.3),
<code>&lt;forward_list&gt;</code> (22.3.4), <code>&lt;list&gt;</code> (22.3.5), and
<code>&lt;vector&gt;</code> (22.3.6) define class templates that meet the
requirements for sequence containers.
</li>
<li>
The following exposition-only alias template may appear in deduction guides for sequence containers:
<pre>
  template&lt;class InputIterator&gt;
    using <i>iter-value-type</i> = <del>typename</del> iterator_traits&lt;InputIterator&gt;::value_type;  <i>// exposition only</i>
</pre>
</li>
</ol>


<h4>22.3.3 Header <code>&lt;deque&gt;</code> synopsis [deque.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;            <i>// see 17.11.1</i>
#include &lt;initializer_list&gt;   <i>// see 17.10.1</i>
namespace std {
  <i>// 22.3.8, class template deque</i>
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt; class deque;

  template&lt;class T, class Allocator&gt;
    bool operator==(const deque&lt;T, Allocator&gt;&amp; x, const deque&lt;T, Allocator&gt;&amp; y);
  template&lt;class T, class Allocator&gt;
    <i>synth-three-way-result</i>&lt;T&gt; operator&lt;=&gt;(const deque&lt;T, Allocator&gt;&amp; x,
                                          const deque&lt;T, Allocator&gt;&amp; y);

  template&lt;class T, class Allocator&gt;
    void swap(deque&lt;T, Allocator&gt;&amp; x, deque&lt;T, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class T, class Allocator, class U&gt;
    <del>typename</del> deque&lt;T, Allocator&gt;::size_type
      erase(deque&lt;T, Allocator&gt;&amp; c, const U&amp; value);
  template&lt;class T, class Allocator, class Predicate&gt;
    <del>typename</del> deque&lt;T, Allocator&gt;::size_type
      erase_if(deque&lt;T, Allocator&gt;&amp; c, Predicate pred);

  namespace pmr {
    template&lt;class T&gt;
      using deque = std::deque&lt;T, polymorphic_allocator&lt;T&gt;&gt;;
  }
}
</pre></blockquote>


<h4>22.3.4 Header <code>&lt;forward_list&gt;</code> synopsis [forward.list.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;            <i>// see 17.11.1</i>
#include &lt;initializer_list&gt;   <i>// see 17.10.1</i>
namespace std {
  <i>// 22.3.9, class template forward_list</i>
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt; class forward_list;

  template&lt;class T, class Allocator&gt;
    bool operator==(const forward_list&lt;T, Allocator&gt;&amp; x, const forward_list&lt;T, Allocator&gt;&amp; y);
  template&lt;class T, class Allocator&gt;
    <i>synth-three-way-result</i>&lt;T&gt; operator&lt;=&gt;(const forward_list&lt;T, Allocator&gt;&amp; x,
                                          const forward_list&lt;T, Allocator&gt;&amp; y);

  template&lt;class T, class Allocator&gt;
    void swap(forward_list&lt;T, Allocator&gt;&amp; x, forward_list&lt;T, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class T, class Allocator, class U&gt;
    <del>typename</del> forward_list&lt;T, Allocator&gt;::size_type
      erase(forward_list&lt;T, Allocator&gt;&amp; c, const U&amp; value);
  template&lt;class T, class Allocator, class Predicate&gt;
    <del>typename</del> forward_list&lt;T, Allocator&gt;::size_type
      erase_if(forward_list&lt;T, Allocator&gt;&amp; c, Predicate pred);

  namespace pmr {
    template&lt;class T&gt;
      using forward_list = std::forward_list&lt;T, polymorphic_allocator&lt;T&gt;&gt;;
  }
}
</pre></blockquote>


<h4>22.3.5 Header <code>&lt;list&gt;</code> synopsis [list.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;            <i>// see 17.11.1</i>
#include &lt;initializer_list&gt;   <i>// see 17.10.1</i>
namespace std {
  <i>// 22.3.10, class template list</i>
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt; class list;

  template&lt;class T, class Allocator&gt;
    bool operator==(const list&lt;T, Allocator&gt;&amp; x, const list&lt;T, Allocator&gt;&amp; y);
  template&lt;class T, class Allocator&gt;
    <i>synth-three-way-result</i>&lt;T&gt; operator&lt;=&gt;(const list&lt;T, Allocator&gt;&amp; x,
                                          const list&lt;T, Allocator&gt;&amp; y);

  template&lt;class T, class Allocator&gt;
    void swap(list&lt;T, Allocator&gt;&amp; x, list&lt;T, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class T, class Allocator, class U&gt;
    <del>typename</del> list&lt;T, Allocator&gt;::size_type
      erase(list&lt;T, Allocator&gt;&amp; c, const U&amp; value);
  template&lt;class T, class Allocator, class Predicate&gt;
    <del>typename</del> list&lt;T, Allocator&gt;::size_type
      erase_if(list&lt;T, Allocator&gt;&amp; c, Predicate pred);

  namespace pmr {
    template&lt;class T&gt;
      using list = std::list&lt;T, polymorphic_allocator&lt;T&gt;&gt;;
  }
}
</pre></blockquote>


<h4>22.3.6 Header <code>&lt;vector&gt;</code> synopsis [vector.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;            <i>// see 17.11.1</i>
#include &lt;initializer_list&gt;   <i>// see 17.10.1</i>
namespace std {
  <i>// 22.3.11, class template vector</i>
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt; class vector;

  template&lt;class T, class Allocator&gt;
    bool operator==(const vector&lt;T, Allocator&gt;&amp; x, const vector&lt;T, Allocator&gt;&amp; y);
  template&lt;class T, class Allocator&gt;
    <i>synth-three-way-result</i>&lt;T&gt; operator&lt;=&gt;(const vector&lt;T, Allocator&gt;&amp; x,
                                          const vector&lt;T, Allocator&gt;&amp; y);

  template&lt;class T, class Allocator&gt;
    void swap(vector&lt;T, Allocator&gt;&amp; x, vector&lt;T, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class T, class Allocator, class U&gt;
    <del>typename</del> vector&lt;T, Allocator&gt;::size_type
      erase(vector&lt;T, Allocator&gt;&amp; c, const U&amp; value);
  template&lt;class T, class Allocator, class Predicate&gt;
    <del>typename</del> vector&lt;T, Allocator&gt;::size_type
      erase_if(vector&lt;T, Allocator&gt;&amp; c, Predicate pred);

  <i>// 22.3.12, class vector&lt;bool&gt;</i>
  template&lt;class Allocator&gt; class vector&lt;bool, Allocator&gt;;

  <i>// hash support</i>
  template&lt;class T&gt; struct hash;
  template&lt;class Allocator&gt; struct hash&lt;vector&lt;bool, Allocator&gt;&gt;;

  namespace pmr {
    template&lt;class T&gt;
      using vector = std::vector&lt;T, polymorphic_allocator&lt;T&gt;&gt;;
  }
}
</pre></blockquote>


<h4>22.3.8.1 Overview [deque.overview]</h4>
<ol start="2">
<li>
A <code>deque</code> meets all of the requirements of a container, ...
</li>
<pre>
namespace std {
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt;
    class deque {
    public:
      <i>// types</i>
      using value_type             = T;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
      using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;

      <i>// ...</i>
    };
}
</pre>
</ol>

<h4>22.3.8.5 Erasure [deque.erasure]</h4>
<ol>
<pre>
template&lt;class T, class Allocator, class U&gt;
  <del>typename</del> deque&lt;T, Allocator&gt;::size_type
    erase(deque&lt;T, Allocator&gt;&amp; c, const U&amp; value);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<pre>
   auto it = remove(c.begin(), c.end(), value);
   auto r = distance(it, c.end());
   c.erase(it, c.end());
   return r;
</pre>
</li>
<pre>
template&lt;class T, class Allocator, class Predicate&gt;
  <del>typename</del> deque&lt;T, Allocator&gt;::size_type
    erase_if(deque&lt;T, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<pre>
   auto it = remove_if(c.begin(), c.end(), pred);
   auto r = distance(it, c.end());
   c.erase(it, c.end());
   return r;
</pre>
</li>
</ol>


<h4>22.3.9.1 Overview [forwardlist.overview]</h4>
<ol start="2">
<li>
A <code>forward_list</code> meets all of the requirements of a container, ...
</li>
<pre>
namespace std {
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt;
    class forward_list {
    public:
      <i>// types</i>
      using value_type             = T;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>

      <i>// ...</i>
    };
}
</pre>
</ol>

<h4>22.3.9.7 Erasure [forward.list.erasure]</h4>
<ol>
<pre>
template&lt;class T, class Allocator, class U&gt;
  <del>typename</del> forward_list&lt;T, Allocator&gt;::size_type
    erase(forward_list&lt;T, Allocator&gt;&amp; c, const U&amp; value);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<code>
return erase_if(c, [&amp;](auto&amp; elem) { return elem == value; });
</code>
</li>
<pre>
template&lt;class T, class Allocator, class Predicate&gt;
  <del>typename</del> forward_list&lt;T, Allocator&gt;::size_type
    erase_if(forward_list&lt;T, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to: <code>return c.remove_if(pred);</code>
</li>
</ol>


<h4>22.3.10.1 Overview [list.overview]</h4>
<ol start="2">
<li>
A <code>list</code> meets all of the requirements of a container, ...
</li>
<pre>
namespace std {
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt;
    class list {
    public:
      <i>// types</i>
      using value_type             = T;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
      using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;

      <i>// ...</i>
    };
}
</pre>
</ol>

<h4>22.3.10.6 Erasure [list.erasure]</h4>
<ol>
<pre>
template&lt;class T, class Allocator, class U&gt;
  <del>typename</del> list&lt;T, Allocator&gt;::size_type
    erase(list&lt;T, Allocator&gt;&amp; c, const U&amp; value);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<code>
return erase_if(c, [&amp;](auto&amp; elem) { return elem == value; });
</code>
</li>
<pre>
template&lt;class T, class Allocator, class Predicate&gt;
  <del>typename</del> list&lt;T, Allocator&gt;::size_type
    erase_if(list&lt;T, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to: <code>return c.remove_if(pred);</code>
</li>
</ol>


<h4>22.3.11.1 Overview [vector.overview]</h4>
<ol start="2">
<li>
	A <code>vector</code> meets all of the requirements of a container, ...
</li>
<pre>
namespace std {
  template&lt;class T, class Allocator = allocator&lt;T&gt;&gt;
    class vector {
    public:
      <i>// types</i>
      using value_type             = T;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
      using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;

      <i>// ...</i>
    };
}
</pre>
</ol>

<h4>22.3.11.6 Erasure [vector.erasure]</h4>
<ol>
<pre>
template&lt;class T, class Allocator, class U&gt;
  <del>typename</del> vector&lt;T, Allocator&gt;::size_type
    erase(vector&lt;T, Allocator&gt;&amp; c, const U&amp; value);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<pre>
   auto it = remove(c.begin(), c.end(), value);
   auto r = distance(it, c.end());
   c.erase(it, c.end());
   return r;
</pre>
</li>
<pre>
template&lt;class T, class Allocator, class Predicate&gt;
  <del>typename</del> vector&lt;T, Allocator&gt;::size_type
    erase_if(vector&lt;T, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<pre>
   auto it = remove_if(c.begin(), c.end(), pred);
   auto r = distance(it, c.end());
   c.erase(it, c.end());
   return r;
</pre>
</li>
</ol>


<h4>22.4.1 In general [associative.general]</h4>
<ol start="2">
<li>
The following exposition-only alias templates may appear in deduction guides for associative containers:
<pre>
  template&lt;class InputIterator&gt;
    using <i>iter-value-type</i> =
      <del>typename</del> iterator_traits&lt;InputIterator&gt;::value_type;                <i>// exposition only</i>
  template&lt;class InputIterator&gt;
    using <i>iter-key-type</i> = remove_const_t&lt;
      <ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type::first_type&gt;;   <i>// exposition only</i>
  template&lt;class InputIterator&gt;
    using <i>iter-mapped-type</i> =
      <del>typename</del> iterator_traits&lt;InputIterator&gt;::value_type::second_type;   <i>// exposition only</i>
  template&lt;class InputIterator&gt;
    using <i>iter-to-alloc-type</i> = pair&lt;
      add_const_t&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type::first_type&gt;,
      <ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type::second_type&gt;;  <i>// exposition only</i>
</pre>
</li>
</ol>


<h4>22.4.2 Header <code>&lt;map&gt;</code> synopsis [associative.map.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;            <i>// see 17.11.1</i>
#include &lt;initializer_list&gt;   <i>// see 17.10.1</i>

namespace std {
  <i>// 22.4.4, class template map</i>
  template&lt;class Key, class T, class Compare = less&lt;Key&gt;,
           class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    class map;

  template&lt;class Key, class T, class Compare, class Allocator&gt;
    bool operator==(const map&lt;Key, T, Compare, Allocator&gt;&amp; x,
                    const map&lt;Key, T, Compare, Allocator&gt;&amp; y);
  template&lt;class Key, class T, class Compare, class Allocator&gt;
    <i>synth-three-way-result</i>&lt;T&gt; operator&lt;=&gt;(const map&lt;Key, T, Compare, Allocator&gt;&amp; x,
                                          const map&lt;Key, T, Compare, Allocator&gt;&amp; y);

  template&lt;class Key, class T, class Compare, class Allocator&gt;
    void swap(map&lt;Key, T, Compare, Allocator&gt;&amp; x,
              map&lt;Key, T, Compare, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class Key, class T, class Compare, class Allocator, class Predicate&gt;
    <del>typename</del> map&lt;Key, T, Compare, Allocator&gt;::size_type
      erase_if(map&lt;Key, T, Compare, Allocator&gt;&amp; c, Predicate pred);

  <i>// 22.4.5, class template multimap</i>
  template&lt;class Key, class T, class Compare = less&lt;Key&gt;,
           class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    class multimap;

  template&lt;class Key, class T, class Compare, class Allocator&gt;
    bool operator==(const multimap&lt;Key, T, Compare, Allocator&gt;&amp; x,
                    const multimap&lt;Key, T, Compare, Allocator&gt;&amp; y);
  template&lt;class Key, class T, class Compare, class Allocator&gt;
    <i>synth-three-way-result</i>&lt;T&gt; operator&lt;=&gt;(const multimap&lt;Key, T, Compare, Allocator&gt;&amp; x,
                                          const multimap&lt;Key, T, Compare, Allocator&gt;&amp; y);

  template&lt;class Key, class T, class Compare, class Allocator&gt;
    void swap(multimap&lt;Key, T, Compare, Allocator&gt;&amp; x,
              multimap&lt;Key, T, Compare, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class Key, class T, class Compare, class Allocator, class Predicate&gt;
    <del>typename</del> multimap&lt;Key, T, Compare, Allocator&gt;::size_type
      erase_if(multimap&lt;Key, T, Compare, Allocator&gt;&amp; c, Predicate pred);

  namespace pmr {
    template&lt;class Key, class T, class Compare = less&lt;Key&gt;&gt;
      using map = std::map&lt;Key, T, Compare, polymorphic_allocator&lt;T&gt;&gt;;

    template&lt;class Key, class T, class Compare = less&lt;Key&gt;&gt;
      using multimap = std::multimap&lt;Key, T, Compare, polymorphic_allocator&lt;T&gt;&gt;;
  }
}
</pre></blockquote>


<h4>22.4.3 Header <code>&lt;set&gt;</code> synopsis [associative.set.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;            <i>// see 17.11.1</i>
#include &lt;initializer_list&gt;   <i>// see 17.10.1</i>

namespace std {
  <i>// 22.4.6, class template set</i>
  template&lt;class Key, class Compare = less&lt;Key&gt;, class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;
    class set;

  template&lt;class Key, class Compare, class Allocator&gt;
    bool operator==(const set&lt;Key, Compare, Allocator&gt;&amp; x,
                    const set&lt;Key, Compare, Allocator&gt;&amp; y);
  template&lt;class Key, class Compare, class Allocator&gt;
    <i>synth-three-way-result</i>&lt;T&gt; operator&lt;=&gt;(const set&lt;Key, Compare, Allocator&gt;&amp; x,
                                          const set&lt;Key, Compare, Allocator&gt;&amp; y);

  template&lt;class Key, class Compare, class Allocator&gt;
    void swap(set&lt;Key, Compare, Allocator&gt;&amp; x,
              set&lt;Key, Compare, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class Key, class Compare, class Allocator, class Predicate&gt;
    <del>typename</del> set&lt;Key, Compare, Allocator&gt;::size_type
      erase_if(set&lt;Key, Compare, Allocator&gt;&amp; c, Predicate pred);

  <i>// 22.4.7, class template multiset</i>
  template&lt;class Key, class Compare = less&lt;Key&gt;, class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;
    class multiset;

  template&lt;class Key, class Compare, class Allocator&gt;
    bool operator==(const multiset&lt;Key, Compare, Allocator&gt;&amp; x,
                    const multiset&lt;Key, Compare, Allocator&gt;&amp; y);
  template&lt;class Key, class Compare, class Allocator&gt;
    <i>synth-three-way-result</i>&lt;T&gt; operator&lt;=&gt;(const multiset&lt;Key, Compare, Allocator&gt;&amp; x,
                                          const multiset&lt;Key, Compare, Allocator&gt;&amp; y);

  template&lt;class Key, class Compare, class Allocator&gt;
    void swap(multiset&lt;Key, Compare, Allocator&gt;&amp; x,
              multiset&lt;Key, Compare, Allocator&gt;&amp; y)
      noexcept(noexcept(x.swap(y)));

  template&lt;class Key, class Compare, class Allocator, class Predicate&gt;
    <del>typename</del> multiset&lt;Key, Compare, Allocator&gt;::size_type
      erase_if(multiset&lt;Key, Compare, Allocator&gt;&amp; c, Predicate pred);

  namespace pmr {
    template&lt;class Key, class Compare = less&lt;Key&gt;&gt;
      using set = std::set&lt;Key, Compare, polymorphic_allocator&lt;T&gt;&gt;;

    template&lt;class Key, class Compare = less&lt;Key&gt;&gt;
      using multiset = std::multiset&lt;Key, Compare, polymorphic_allocator&lt;T&gt;&gt;;
  }
}
</pre></blockquote>


<h4>22.4.4.1 Overview [map.overview]</h4>
<ol start="2">
<li>
A <code>map</code> meets all of the requirements of a container, ...
</li>
<pre>
namespace std {
  template&lt;class Key, class T, class Compare = less&lt;Key&gt;,
           class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    class map {
    public:
      <i>// types</i>
      using key_type               = Key;
      using mapped_type            = T;
      using value_type             = Key;
      using key_compare            = pair&lt;const Key, T&gt;;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
      using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;
      using node_type              = <i>unspecified</i>;
      using insert_return_type     = <i>insert-return-type</i>&lt;iterator, node_type&gt;;

      <i>// ...</i>
    };
}
</pre>
</ol>


<h4>22.4.4.5 Erasure [map.erasure]</h4>
<ol>
<pre>
template&lt;class Key, class T, class Compare, class Allocator, class Predicate&gt;
  <del>typename</del> map&lt;Key, T, Compare, Allocator&gt;::size_type
    erase_if(map&lt;Key, T, Compare, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
auto original_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
     ++i;
  } 
}
return original_size - c.size();
</pre></blockquote>
</li>
</ol>


<h4>22.4.5.1 Overview [multimap.overview]</h4>
<ol start="2">
<li>
A <code>multimap</code> meets all of the requirements of a container, ...
</li>
<pre>
namespace std {
  template&lt;class Key, class T, class Compare = less&lt;Key&gt;,
           class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    class multimap {
    public:
      <i>// types</i>
      using key_type               = Key;
      using mapped_type            = T;
      using value_type             = Key;
      using key_compare            = pair&lt;const Key, T&gt;;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
      using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;
      using node_type              = <i>unspecified</i>;

      <i>// ...</i>
    };
}
</pre>
</ol>


<h4>22.4.5.4 Erasure [multimap.erasure]</h4>
<ol>
<pre>
template&lt;class Key, class T, class Compare, class Allocator, class Predicate&gt;
  <del>typename</del> multimap&lt;Key, T, Compare, Allocator&gt;::size_type
    erase_if(multimap&lt;Key, T, Compare, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
auto original_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
     ++i;
  } 
}
return original_size - c.size();
</pre></blockquote>
</li>
</ol>


<h4>22.4.6.1 Overview [set.overview]</h4>
<ol start="2">
<li>
A <code>set</code> meets all of the requirements of a container, ...
</li>
<pre>
namespace std {
  template&lt;class Key, class Compare = less&lt;Key&gt;, class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;
    class set {
    public:
      <i>// types</i>
      using key_type               = Key;
      using key_compare            = Compare;
      using value_type             = Key;
      using value_compare          = Compare;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
      using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;
      using node_type              = <i>unspecified</i>;
      using insert_return_type     = <i>insert-return-type</i>&lt;iterator, node_type&gt;;

      <i>// ...</i>
    };
}
</pre>
</ol>


<h4>22.4.6.3 Erasure [set.erasure]</h4>
<ol>
<pre>
template&lt;class Key, class Compare, class Allocator, class Predicate&gt;
  <del>typename</del> set&lt;Key, Compare, Allocator&gt;::size_type
    erase_if(set&lt;Key, Compare, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
auto original_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
     ++i;
  } 
}
return original_size - c.size();
</pre></blockquote>
</li>
</ol>


<h4>22.4.6.1 Overview [multiset.overview]</h4>
<ol start="2">
<li>
A <code>multiset</code> meets all of the requirements of a container, ...
</li>
<pre>
namespace std {
  template&lt;class Key, class Compare = less&lt;Key&gt;, class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;
    class multiset {
    public:
      <i>// types</i>
      using key_type               = Key;
      using key_compare            = Compare;
      using value_type             = Key;
      using value_compare          = Compare;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>
      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using reverse_iterator       = std::reverse_iterator&lt;iterator&gt;;
      using const_reverse_iterator = std::reverse_iterator&lt;const_iterator&gt;;
      using node_type              = <i>unspecified</i>;

      <i>// ...</i>
    };
}
</pre>
</ol>


<h4>22.4.7.3 Erasure [multiset.erasure]</h4>
<ol>
<pre>
template&lt;class Key, class Compare, class Allocator, class Predicate&gt;
  <del>typename</del> multiset&lt;Key, Compare, Allocator&gt;::size_type
    erase_if(multiset&lt;Key, Compare, Allocator&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
auto original_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
     ++i;
  } 
}
return original_size - c.size();
</pre></blockquote>
</li>
</ol>


<h4>22.5.2 Header <code>&lt;unordered_map&gt;</code> synopsis [unord.map.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;            <i>// see 17.11.1</i>
#include &lt;initializer_list&gt;   <i>// see 17.10.1</i>

namespace std {
  <i>// ...</i>

  template&lt;class K, class T, class H, class P, class A, class Predicate&gt;
    <del>typename</del> unordered_map&lt;K, T, H, P, A&gt;::size_type
      erase_if(unordered_map&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);
  template&lt;class K, class T, class H, class P, class A, class Predicate&gt;
    <del>typename</del> unordered_multimap&lt;K, T, H, P, A&gt;::size_type
      erase_if(unordered_multimap&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);

  <i>// ...</i>
}
</pre></blockquote>


<h4>22.5.3 Header <code>&lt;unordered_set&gt;</code> synopsis [unord.set.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;            <i>// see 17.11.1</i>
#include &lt;initializer_list&gt;   <i>// see 17.10.1</i>

namespace std {
  <i>// ...</i>

  template&lt;class K, class H, class P, class A, class Predicate&gt;
    <del>typename</del> unordered_set&lt;K, H, P, A&gt;::size_type
      erase_if(unordered_set&lt;K, H, P, A&gt;&amp; c, Predicate pred);
  template&lt;class K, class H, class P, class A, class Predicate&gt;
    <del>typename</del> unordered_multiset&lt;K, H, P, A&gt;::size_type
      erase_if(unordered_multiset&lt;K, H, P, A&gt;&amp; c, Predicate pred);

  <i>// ...</i>
}
</pre></blockquote>


<h4>22.5.4.1 Overview [unord.map.overview]</h4>
<ol start="3">
<li>
Subclause 22.5.4 only describes operations on <code>unordered_map</code> that are
not described in one of the requirement tables, or for which there is
additional semantic information.
<pre>
namespace std {
  template&lt;class Key,
           class T,
           class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;,
           class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
  class unordered_map {
    public:
      <i>// types</i>
      using key_type               = Key;
      using mapped_type            = T;
      using value_type             = pair&lt;const Key, T&gt;;;
      using hasher                 = Hash;
      using key_equal              = Pred;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>

      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using local_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_local_iterator   = <i>implementation-defined</i>; <i>// see 22.2</i>
      using node_type              = <i>unspecified</i>;
      using insert_return_type     = <i>insert-return-type</i>&lt;iterator, node_type&gt;;

      <i>// ...</i>
  };

  template&lt;class InputIterator,
           class Hash = hash&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;,
           class Pred = equal_to&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;,
           class Allocator = allocator&lt;<i>iter-to-alloc-type</i>&lt;InputIterator&gt;&gt;&gt;
    unordered_map(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type = <i>see below</i>,
                  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -&gt; unordered_map&lt;<i>iter-key-type</i>&lt;InputIterator&gt;, <i>iter-mapped-type</i>&lt;InputIterator&gt;, Hash, Pred,
                       Allocator&gt;;

  template&lt;class Key, class T, class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;, class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    unordered_map(initializer_list&lt;pair&lt;const Key, T&gt;&gt;,
                  <ins>typename</ins> <i>see below</i>::size_type = <i>see below</i>, Hash = Hash(),
                  Pred = Pred(), Allocator = Allocator())
      -&gt; unordered_map&lt;Key, T, Hash, Pred, Allocator&gt;;

  template&lt;class InputIterator, class Allocator&gt;
    unordered_map(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type, Allocator)
      -&gt; unordered_map&lt;<i>iter-key-type</i>&lt;InputIterator&gt;, <i>iter-mapped-type</i>&lt;InputIterator&gt;,
                       hash&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;,
                       equal_to&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;, Allocator&gt;;

  template&lt;class InputIterator, class Allocator&gt;
    unordered_map(InputIterator, InputIterator, Allocator)
      -&gt; unordered_map&lt;<i>iter-key-type</i>&lt;InputIterator&gt;, <i>iter-mapped-type</i>&lt;InputIterator&gt;,
                       hash&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;,
                       equal_to&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;, Allocator&gt;;

  template&lt;class InputIterator, class Hash, class Allocator&gt;
    unordered_map(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type, Hash, Allocator)
      -&gt; unordered_map&lt;<i>iter-key-type</i>&lt;InputIterator&gt;, <i>iter-mapped-type</i>&lt;InputIterator&gt;, Hash,
                       equal_to&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;, Allocator&gt;;

  template&lt;class Key, class T, class Allocator&gt;
    unordered_map(initializer_list&lt;pair&lt;const Key, T&gt;&gt;, <ins>typename</ins> <i>see below</i>::size_type,
                  Allocator)
      -&gt; unordered_map&lt;Key, T, hash&lt;Key&gt;, equal_to&lt;Key&gt;, Allocator&gt;;

  template&lt;class Key, class T, class Allocator&gt;
    unordered_map(initializer_list&lt;pair&lt;const Key, T&gt;&gt;, Allocator)
      -&gt; unordered_map&lt;Key, T, hash&lt;Key&gt;, equal_to&lt;Key&gt;, Allocator&gt;;

  template&lt;class Key, class T, class Hash, class Allocator&gt;
    unordered_map(initializer_list&lt;pair&lt;const Key, T&gt;&gt;, <ins>typename</ins> <i>see below</i>::size_type, Hash,
                  Allocator)
      -&gt; unordered_map&lt;Key, T, Hash, equal_to&lt;Key&gt;, Allocator&gt;;

    <i>// ...</i>
}
</pre>
</li>
</ol>


<h4>22.5.4.5 Erasure [unord.map.erasure]</h4>
<ol>
<pre>
template&lt;class K, class T, class H, class P, class A, class Predicate&gt;
  <del>typename</del> unordered_map&lt;K, T, H, P, A&gt;::size_type
    erase_if(unordered_map&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
auto original_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
     ++i;
  } 
}
return original_size - c.size();
</pre></blockquote>
</li>
</ol>


<h4>22.5.5.1 Overview [unord.multimap.overview]</h4>
<ol start="3">
<li>
Subclause 22.5.5 only describes operations on <code>unordered_multimap</code> that
are not described in one of the requirement tables, or for which there is
additional semantic information.
<pre>
namespace std {
  template&lt;class Key,
           class T,
           class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;,
           class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
  class unordered_multimap {
    public:
      <i>// types</i>
      using key_type               = Key;
      using mapped_type            = T;
      using value_type             = pair&lt;const Key, T&gt;;;
      using hasher                 = Hash;
      using key_equal              = Pred;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>

      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using local_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_local_iterator   = <i>implementation-defined</i>; <i>// see 22.2</i>
      using node_type              = <i>unspecified</i>;

      <i>// ...</i>
  };

  template&lt;class InputIterator,
           class Hash = hash&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;,
           class Pred = equal_to&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;,
           class Allocator = allocator&lt;<i>iter-to-alloc-type</i>&lt;InputIterator&gt;&gt;&gt;
    unordered_multimap(InputIterator, InputIterator,
                       <ins>typename</ins> <i>see below</i>::size_type = <i>see below</i>,
                       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -&gt; unordered_multimap&lt;<i>iter-key-type</i>&lt;InputIterator&gt;, <i>iter-mapped-type</i>&lt;InputIterator&gt;, Hash, Pred,
                            Allocator&gt;;

  template&lt;class Key, class T, class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;, class Allocator = allocator&lt;pair&lt;const Key, T&gt;&gt;&gt;
    unordered_multimap(initializer_list&lt;pair&lt;const Key, T&gt;&gt;,
                       <ins>typename</ins> <i>see below</i>::size_type = <i>see below</i>,
                       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -&gt; unordered_multimap&lt;Key, T, Hash, Pred, Allocator&gt;;

  template&lt;class InputIterator, class Allocator&gt;
    unordered_multimap(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type, Allocator)
      -&gt; unordered_multimap&lt;<i>iter-key-type</i>&lt;InputIterator&gt;, <i>iter-mapped-type</i>&lt;InputIterator&gt;,
                            hash&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;,
                            equal_to&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;, Allocator&gt;;

  template&lt;class InputIterator, class Allocator&gt;
    unordered_multimap(InputIterator, InputIterator, Allocator)
      -&gt; unordered_multimap&lt;<i>iter-key-type</i>&lt;InputIterator&gt;, <i>iter-mapped-type</i>&lt;InputIterator&gt;,
                            hash&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;,
                            equal_to&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;, Allocator&gt;;

  template&lt;class InputIterator, class Hash, class Allocator&gt;
    unordered_multimap(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type, Hash,
                       Allocator)
      -&gt; unordered_multimap&lt;<i>iter-key-type</i>&lt;InputIterator&gt;, <i>iter-mapped-type</i>&lt;InputIterator&gt;, Hash,
                            equal_to&lt;<i>iter-key-type</i>&lt;InputIterator&gt;&gt;, Allocator&gt;;

  template&lt;class Key, class T, class Allocator&gt;
    unordered_multimap(initializer_list&lt;pair&lt;const Key, T&gt;&gt;, <ins>typename</ins> <i>see below</i>::size_type,
                       Allocator)
      -&gt; unordered_multimap&lt;Key, T, hash&lt;Key&gt;, equal_to&lt;Key&gt;, Allocator&gt;;

  template&lt;class Key, class T, class Allocator&gt;
    unordered_multimap(initializer_list&lt;pair&lt;const Key, T&gt;&gt;, Allocator)
      -&gt; unordered_multimap&lt;Key, T, hash&lt;Key&gt;, equal_to&lt;Key&gt;, Allocator&gt;;

  template&lt;class Key, class T, class Hash, class Allocator&gt;
    unordered_multimap(initializer_list&lt;pair&lt;const Key, T&gt;&gt;, <ins>typename</ins> <i>see below</i>::size_type,
                       Hash, Allocator)
      -&gt; unordered_multimap&lt;Key, T, Hash, equal_to&lt;Key&gt;, Allocator&gt;;

    <i>// ...</i>
}
</pre>
</li>
</ol>


<h4>22.5.5.4 Erasure [unord.multimap.erasure]</h4>
<ol>
<pre>
template&lt;class K, class T, class H, class P, class A, class Predicate&gt;
  <del>typename</del> unordered_multimap&lt;K, T, H, P, A&gt;::size_type
    erase_if(unordered_multimap&lt;K, T, H, P, A&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
auto original_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
     ++i;
  } 
}
return original_size - c.size();
</pre></blockquote>
</li>
</ol>


<h4>22.5.6.1 Overview [unord.set.overview]</h4>
<ol start="3">
<li>
Subclause 22.5.6 only describes operations on <code>unordered_set</code> that are
not described in one of the requirement tables, or for which there is
additional semantic information.
<pre>
namespace std {
  template&lt;class Key,
           class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;,
           class Allocator = allocator&lt;Key&gt;&gt;
  class unordered_set {
    public:
      <i>// types</i>
      using key_type               = Key;
      using value_type             = Key;
      using hasher                 = Hash;
      using key_equal              = Pred;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>

      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using local_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_local_iterator   = <i>implementation-defined</i>; <i>// see 22.2</i>
      using node_type              = <i>unspecified</i>;
      using insert_return_type     = <i>insert-return-type</i>&lt;iterator, node_type&gt;;

      <i>// ...</i>
  };

  template&lt;class InputIterator,
           class Hash = hash&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
           class Pred = equal_to&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
           class Allocator = allocator&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;&gt;
    unordered_set(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type = <i>see below</i>,
                  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -&gt; unordered_set&lt;<i>iter-value-type</i>&lt;InputIterator&gt;, Hash, Pred, Allocator&gt;;

  template&lt;class T, class Hash = hash&lt;T&gt;,
           class Pred = equal_to&lt;T&gt;, class Allocator = allocator&lt;T&gt;&gt;
    unordered_set(initializer_list&lt;T&gt;, <ins>typename</ins> <i>see below</i>::size_type = <i>see below</i>,
                  Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -&gt; unordered_set&lt;T, Hash, Pred, Allocator&gt;;

  template&lt;class InputIterator, class Allocator&gt;
    unordered_set(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type, Allocator)
      -&gt; unordered_set&lt;<i>iter-value-type</i>&lt;InputIterator&gt;,
                       hash&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
                       equal_to&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
                       Allocator&gt;;

  template&lt;class InputIterator, class Hash, class Allocator&gt;
    unordered_set(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type,
                  Hash, Allocator)
      -&gt; unordered_set&lt;<i>iter-value-type</i>&lt;InputIterator&gt;, Hash,
                       equal_to&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
                       Allocator&gt;;

  template&lt;class T, class Allocator&gt;
    unordered_set(initializer_list&lt;T&gt;, <ins>typename</ins> <i>see below</i>::size_type, Allocator)
      -&gt; unordered_set&lt;T, hash&lt;T&gt;, equal_to&lt;T&gt;, Allocator&gt;;

  template&lt;class T, class Hash, class Allocator&gt;
    unordered_set(initializer_list&lt;T&gt;, <ins>typename</ins> <i>see below</i>::size_type, Hash, Allocator)
      -&gt; unordered_set&lt;T, Hash, equal_to&lt;T&gt;, Allocator&gt;;

    <i>// ...</i>
}
</pre>
</li>
</ol>


<h4>22.5.6.3 Erasure [unord.set.erasure]</h4>
<ol>
<pre>
template&lt;class K, class H, class P, class A, class Predicate&gt;
  <del>typename</del> unordered_set&lt;K, H, P, A&gt;::size_type
    erase_if(unordered_set&lt;K, H, P, A&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
auto original_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
     ++i;
  } 
}
return original_size - c.size();
</pre></blockquote>
</li>
</ol>


<h4>22.5.7.1 Overview [unord.multiset.overview]</h4>
<ol start="3">
<li>
Subclause 22.5.7 only describes operations on <code>unordered_multiset</code> that
are not described in one of the requirement tables, or for which there is
additional semantic information.
<pre>
namespace std {
  template&lt;class Key,
           class Hash = hash&lt;Key&gt;,
           class Pred = equal_to&lt;Key&gt;,
           class Allocator = allocator&lt;Key&gt;&gt;
  class unordered_multiset {
    public:
      <i>// types</i>
      using key_type               = Key;
      using value_type             = Key;
      using hasher                 = Hash;
      using key_equal              = Pred;
      using allocator_type         = Allocator;
      using pointer                = <del>typename</del> allocator_traits&lt;Allocator&gt;::pointer;
      using const_pointer          = <del>typename</del> allocator_traits&lt;Allocator&gt;::const_pointer;
      using reference              = value_type&amp;;
      using const_reference        = const value_type&amp;;
      using size_type              = <i>implementation-defined</i>; <i>// see 22.2</i>
      using difference_type        = <i>implementation-defined</i>; <i>// see 22.2</i>

      using iterator               = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using local_iterator         = <i>implementation-defined</i>; <i>// see 22.2</i>
      using const_local_iterator   = <i>implementation-defined</i>; <i>// see 22.2</i>
      using node_type              = <i>unspecified</i>;

      <i>// ...</i>

  };

  template&lt;class InputIterator,
           class Hash = hash&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
           class Pred = equal_to&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
           class Allocator = allocator&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;&gt;
    unordered_multiset(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type = <i>see below</i>,
                       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -&gt; unordered_multiset&lt;<i>iter-value-type</i>&lt;InputIterator&gt;,
                            Hash, Pred, Allocator&gt;;

  template&lt;class T, class Hash = hash&lt;T&gt;,
           class Pred = equal_to&lt;T&gt;, class Allocator = allocator&lt;T&gt;&gt;
    unordered_multiset(initializer_list&lt;T&gt;, <ins>typename</ins> <i>see below</i>::size_type = <i>see below</i>,
                       Hash = Hash(), Pred = Pred(), Allocator = Allocator())
      -&gt; unordered_multiset&lt;T, Hash, Pred, Allocator&gt;;

  template&lt;class InputIterator, class Allocator&gt;
    unordered_multiset(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type, Allocator)
      -&gt; unordered_multiset&lt;<i>iter-value-type</i>&lt;InputIterator&gt;,
                            hash&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
                            equal_to&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
                            Allocator&gt;;

  template&lt;class InputIterator, class Hash, class Allocator&gt;
    unordered_multiset(InputIterator, InputIterator, <ins>typename</ins> <i>see below</i>::size_type,
                       Hash, Allocator)
      -&gt; unordered_multiset&lt;<i>iter-value-type</i>&lt;InputIterator&gt;, Hash,
                            equal_to&lt;<i>iter-value-type</i>&lt;InputIterator&gt;&gt;,
                            Allocator&gt;;

  template&lt;class T, class Allocator&gt;
    unordered_multiset(initializer_list&lt;T&gt;, <ins>typename</ins> <i>see below</i>::size_type, Allocator)
      -&gt; unordered_multiset&lt;T, hash&lt;T&gt;, equal_to&lt;T&gt;, Allocator&gt;;

  template&lt;class T, class Hash, class Allocator&gt;
    unordered_multiset(initializer_list&lt;T&gt;, <ins>typename</ins> <i>see below</i>::size_type, Hash, Allocator)
      -&gt; unordered_multiset&lt;T, Hash, equal_to&lt;T&gt;, Allocator&gt;;

    <i>// ...</i>
}
</pre>
</li>
</ol>


<h4>22.5.7.3 Erasure [unord.multiset.erasure]</h4>
<ol>
<pre>
template&lt;class K, class H, class P, class A, class Predicate&gt;
  <del>typename</del> unordered_multiset&lt;K, H, P, A&gt;::size_type
    erase_if(unordered_multiset&lt;K, H, P, A&gt;&amp; c, Predicate pred);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
auto original_size = c.size();
for (auto i = c.begin(), last = c.end(); i != last; ) {
  if (pred(*i)) {
    i = c.erase(i);
  } else {
     ++i;
  } 
}
return original_size - c.size();
</pre></blockquote>
</li>
</ol>


<h4>22.6.2 Header <code>&lt;queue&gt;</code> synopsis [queue.syn]</h4>

<blockquote><pre>
#include &lt;initializer_list&gt;

namespace std {
  <i>// ...</i>

  template&lt;class T, class Container = vector&lt;T&gt;,
           class Compare = less&lt;<ins>typename</ins> Container::value_type&gt;&gt;
    class priority_queue;

    <i>// ...</i>
}
</pre></blockquote>


<h4>22.6.4.1 Definition [queue.defn]</h4>
<ol>
<li>
Any sequence container supporting operations <code>front()</code>, <code>back()</code>, <code>push_back()</code> and
<code>pop_front()</code> can be used to instantiate <code>queue</code>. In particular, <code>list</code> (26.3.10) and
<code>deque</code> (26.3.8) can be used.
</li>
</ol>

<blockquote><pre>
namespace std {
  template&lt;class T, class Container = deque&lt;T&gt;&gt;
  class queue {
   public:
     using value_type      = <del>typename</del> Container::value_type;
     using reference       = <del>typename</del> typename Container::reference;
     using const_reference = <del>typename</del> typename Container::const_reference;
     using size_type       = <del>typename</del> typename Container::size_type;
     using container_type  = Container;
     
  protected:
    Container c;

    <i>// ...</i>
  };

  template&lt;class Container&gt;
    queue(Container) -&gt; queue&lt;<ins>typename</ins> Container::value_type, Container&gt;;

  template&lt;class Container, class Allocator&gt;
    queue(Container, Allocator) -&gt; queue&lt;<ins>typename</ins> Container::value_type, Container&gt;;

  <i>// ...</i>
}
</pre></blockquote>


<h4>22.6.5.1 Overview [priqueue.overview]</h4>
<ol>
<li>
Any sequence container with random access iterator and ...
</li>
</ol>

<blockquote><pre>
namespace std {
  template&lt;class T, class Container = vector&lt;T&gt;,
           class Compare = less&lt;<ins>typename</ins> Container::value_type&gt;&gt;
   class priority_queue {
   public:
     using value_type      = <del>typename</del> Container::value_type;
     using reference       = <del>typename</del> typename Container::reference;
     using const_reference = <del>typename</del> typename Container::const_reference;
     using size_type       = <del>typename</del> typename Container::size_type;
     using container_type  = Container;
     using value_compare   = Compare;
     
  protected:
    Container c;
    Compare comp;

    <i>// ...</i>
  };

  template&lt;class Compare, class Container&gt;
    priority_queue(Compare, Container)
      -&gt; priority_queue&lt;<ins>typename</ins> Container::value_type, Container, Compare&gt;;

  template&lt;class InputIterator,
           class Compare = less&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type&gt;,
           class Container = vector&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type&gt;&gt;
    priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container())
      -&gt; priority_queue&lt;<ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type, Container, Compare&gt;;

  template&lt;class Compare, class Container, class Allocator&gt;
    priority_queue(Compare, Container, Allocator)
      -&gt; priority_queue&lt;<ins>typename</ins> Container::value_type, Container, Compare&gt;;

  <i>// ...</i>
}
</pre></blockquote>


<h4>22.6.6.1 Definition [stack.defn]</h4>
<blockquote><pre>
namespace std {
  template&lt;class T, class Container = deque&lt;T&gt;&gt;
    class stack {
   public:
     using value_type      = <del>typename</del> Container::value_type;
     using reference       = <del>typename</del> typename Container::reference;
     using const_reference = <del>typename</del> typename Container::const_reference;
     using size_type       = <del>typename</del> typename Container::size_type;
     using container_type  = Container;
     
  protected:
    Container c;

    <i>// ...</i>
  };

  template&lt;class Container&gt;
    stack(Container) -&gt; stack&lt;<ins>typename</ins> Container::value_type, Container&gt;;

  template&lt;class Container, class Allocator&gt;
    stack(Container, Allocator) -&gt; stack&lt;<ins>typename</ins> Container::value_type, Container&gt;;

  <i>// ...</i>
}
</pre></blockquote>


<h4>23.2 Header <code>&lt;iterator&gt;</code> synopsis [iterator.synopsis]</h4>
<blockquote><pre>
#include &lt;compare&gt;
#include &lt;concepts&gt;

namespace std {
  <i>// ...</i>

  <i>// 23.4.2, iterator operations</i>
  template&lt;class InputIterator, class Distance&gt;
    constexpr void
      advance(InputIterator&amp; i, Distance n);
  template&lt;class InputIterator&gt;
    constexpr <del>typename</del> iterator_traits&lt;InputIterator&gt;::difference_type
      distance(InputIterator first, InputIterator last);
  template&lt;class InputIterator&gt;
    constexpr InputIterator
      next(InputIterator x,
           <ins>typename</ins> iterator_traits&lt;InputIterator&gt;::difference_type n = 1);
  template&lt;class BidirectionalIterator&gt;
    constexpr BidirectionalIterator
      prev(BidirectionalIterator x,
           <ins>typename</ins> iterator_traits&lt;BidirectionalIterator&gt;::difference_type n = 1);

  <i>// ...</i>

  <i>// 23.5, predefined iterators and sentinels</i>

  <i>// ...</i>

  template&lt;class Iterator1, class Iterator2&gt;
    constexpr auto operator-(
    const reverse_iterator&lt;Iterator1&gt;&amp; x,
    const reverse_iterator&lt;Iterator2&gt;&amp; y) -&gt; decltype(x.base() - y.base());
  template&lt;class Iterator&gt;
    constexpr reverse_iterator&lt;Iterator&gt; operator+(
      <ins>typename</ins> reverse_iterator&lt;Iterator&gt;::difference_type n, const reverse_iterator&lt;Iterator&gt;&amp; x);

  template&lt;class Iterator&gt;
    constexpr reverse_iterator&lt;Iterator&gt; make_reverse_iterator(Iterator i);

  <i>// ...</i>

  template&lt;class Iterator1, class Iterator2&gt;
    constexpr auto operator-(
    const move_iterator&lt;Iterator1&gt;&amp; x,
    const move_iterator&lt;Iterator2&gt;&amp; y) -&gt; decltype(x.base() - y.base());
  template&lt;class Iterator&gt;
    constexpr move_iterator&lt;Iterator&gt; operator+(
      <ins>typename</ins> move_iterator&lt;Iterator&gt;::difference_type n, const move_iterator&lt;Iterator&gt;&amp; x);

  template&lt;class Iterator&gt;
    constexpr move_iterator&lt;Iterator&gt; make_move_iterator(Iterator i);

  <i>...</i>

}
</pre></blockquote>


<h4>23.3.2.1 Incrementable traits [incrementable.traits]</h4>
<ol>
<li>
To implement algorithms only in terms of incrementable types, it is often
necessary to determine the difference type that corresponds to a particular
incrementable type. Accordingly, it is required that if <code>WI</code> is the name
of a type that models the <code>weakly_incrementable</code> concept (23.3.4.4), the
type
<pre>
    iter_difference_t&lt;WI&gt;
</pre>
be defined as the incrementable type's difference type.
</li>
<pre>
namespace std {
  template&lt;class&gt; struct incrementable_traits { };

  template&lt;class T&gt;
    requires is_object_v&lt;T&gt;
  struct incrementable_traits&lt;T*&gt; {
    using difference_type = ptrdiff_t;
  };

  template&lt;class I&gt;
  struct incrementable_traits&lt;const I&gt;
    : incrementable_traits&lt;I&gt; { };

  template&lt;class T&gt;
    requires requires { <b>typename</b> T::difference_type; }
  struct incrementable_traits&lt;T&gt; {
    using difference_type = <del>typename</del> T::difference_type;
  };

  template&lt;class T&gt;
    requires (!requires { <b>typename</b> T::difference_type; } &amp;&amp;
              requires(const T&amp; a, const T&amp; b) { { a - b } -&gt; integral; })
  struct incrementable_traits&lt;T&gt; {
    using difference_type = make_signed_t&lt;decltype(declval&lt;T&gt;() - declval&lt;T&gt;())&gt;;
  };

  template&lt;class T&gt;
    using iter_difference_t = <i>see below</i>;
}
</pre>
</ol>


<h4>23.3.2.3 Iterator traits [iterator.traits]</h4>

<ol start="2">
<li>
The definitions in this subclause make use of the following exposition-only
concepts:
<blockquote><pre>
template&lt;class I&gt;
concept <i>cpp17-iterator</i> =
  copyable&lt;I&gt; &amp;&amp; requires(I i) {
    {   *i } -&gt; <i>can-reference</i>;
    {  ++i } -&gt; same_as&lt;I&amp;&gt;;
    { *i++ } -&gt; <i>can-reference</i>;
  };

template&lt;class I&gt;
  concept <i>cpp17-input-iterator</i> =
    <i>cpp17-iterator</i>&lt;I&gt; &amp;&amp; equality_comparable&lt;I&gt; &amp;&amp; requires(I i) {
      <b>typename</b> incrementable_traits&lt;I&gt;::difference_type;
      <b>typename</b> indirectly_readable_traits&lt;I&gt;::value_type;
      <b>typename</b> common_reference_t&lt;iter_reference_t&lt;I&gt;&amp;&amp;,
                                  <ins>typename</ins> indirectly_readable_traits&lt;I&gt;::value_type&amp;&gt;;
      <b>typename</b> common_reference_t&lt;decltype(*i++)&amp;&amp;,
                                  <ins>typename</ins> indirectly_readable_traits&lt;I&gt;::value_type&amp;&gt;;
         requires signed_integral&lt;<ins>typename</ins> incrementable_traits&lt;I&gt;::difference_type&gt;;
  };

template&lt;class I&gt;
  concept <i>cpp17-forward-iterator</i> =
    <i>cpp17-input-iterator</i>&lt;I&gt; &amp;&amp; constructible_from&lt;I&gt; &amp;&amp;
    is_lvalue_reference_v&lt;iter_reference_t&lt;I&gt;&gt; &amp;&amp;
    same_as&lt;remove_cvref_t&lt;iter_reference_t&lt;I&gt;&gt;,
            <ins>typename</ins> indirectly_readable_traits&lt;I&gt;::value_type&gt; &amp;&amp;
    requires(I i) {
      {  i++ } -&gt; convertible_to&lt;const I&amp;&gt;;
      { *i++ } -&gt; same_as&lt;iter_reference_t&lt;I&gt;&gt;;
    };

template&lt;class I&gt;
  concept <i>cpp17-bidirectional-iterator</i> =
    <i>cpp17-forward-iterator</i>&lt;I&gt; &amp;&amp; requires(I i) {
      {  --i } -&gt; same_as&lt;I&amp;&gt;;
      {  i-- } -&gt; convertible_to&lt;const I&amp;&gt;;
      { *i-- } -&gt; same_as&lt;iter_reference_t&lt;I&gt;&gt;;
  };

template&lt;class I&gt;
  concept <i>cpp17-random-access-iterator</i> =
    <i>cpp17-bidirectional-iterator</i>&lt;I&gt; &amp;&amp; totally_ordered&lt;I&gt; &amp;&amp;
    requires(I i, <ins>typename</ins> incrementable_traits&lt;I&gt;::difference_type n) {
      { i += n } -&gt; same_as&lt;I&amp;&gt;;
      { i -= n } -&gt; same_as&lt;I&amp;&gt;;
      { i +  n } -&gt; same_as&lt;I&gt;;
      { n +  i } -&gt; same_as&lt;I&gt;;
      { i -  n } -&gt; same_as&lt;I&gt;;
      { i -  i } -&gt; same_as&lt;decltype(n)&gt;;
      {  i[n]  } -&gt; convertible_to&lt;iter_reference_t&lt;I&gt;&gt;;
  };
</pre></blockquote>
</li>
<li>
The members of a specialization <code>iterator_traits&lt;I&gt;</code> generated
from the <code>iterator_traits</code> primary template are computed as follows:
  <ol>
  <li>
&mdash; If <code>I</code> has valid (13.10.2) member types
<code>difference_type</code>, <code>value_type</code>, <code>reference</code>, and
<code>iterator_category</code>, then <code>iterator_traits&lt;I&gt;</code> has the
following publicly accessible members:
  <blockquote><pre>
using iterator_category = <del>typename</del> I::iterator_category;
using value_type        = <del>typename</del> I::value_type;
using difference_type   = <del>typename</del> I::difference_type;
using pointer           = <i>see below</i>;
using reference         = <del>typename</del> I::reference;
  </pre></blockquote>
If the qualified-id <code>I::pointer</code> is valid and denotes a type, then
<code>iterator_traits&lt;I&gt;::pointer</code> names that type; otherwise, it names
<code>void</code>.
  </li>
  <li>
&mdash; Otherwise, if <code>I</code> satisfies the exposition-only concept
<i>cpp17-input-iterator</i>, <code>iterator_traits&lt;I&gt;</code> has the
following publicly accessible members:
  <blockquote><pre>
using iterator_category = <i>see below</i>;
using value_type        = <del>typename</del> indirectly_readable_traits&lt;I&gt;::value_type;
using difference_type   = <del>typename</del> incrementable_traits&lt;I&gt;::difference_type;
using pointer           = <i>see below</i>;
using reference         = <i>see below</i>;
  </pre></blockquote>
  </li>
  </ol>
</li>
</ol>

<ol start="6">
<li>
[ <i>Example:</i> To implement a generic <code>reverse</code> function, a C++
program can do the following:
<pre>
template&lt;class BI&gt;
void reverse(BI first, BI last) {
  <ins>typename</ins> iterator_traits&lt;BI&gt;::difference_type n = distance(first, last);
  --n;
  while(n &gt; 0) {
    <ins>typename</ins> iterator_traits&lt;BI&gt;::value_type tmp = *first;
    *first++ = *--last;
    *last = tmp;
    n -= 2;
  }
}
</pre>
&mdash; <i>end example</i> ]
</li>
</ol>


<h4>23.4.1 Standard iterator tags [std.iterator.tags]</h4>
<ol start="3">
<li>
[ <i>Example:</i> If <code>evolve()</code> is well-defined for bidirectional iterators,
but can be implemented more efficiently for random access iterators, then the
implementation is as follows:
<pre>
template&lt;class BidirectionalIterator&gt;
inline void
evolve(BidirectionalIterator first, BidirectionalIterator last) {
  evolve(first, last,
    <ins>typename</ins> iterator_traits&lt;BidirectionalIterator&gt;::iterator_category());
}

template&lt;class BidirectionalIterator&gt;
void evolve(BidirectionalIterator first, BidirectionalIterator last,
  bidirectional_iterator_tag) {
  <i>// more generic, but less efficient algorithm</i>
}

template&lt;class RandomAccessIterator&gt;
void evolve(RandomAccessIterator first, RandomAccessIterator last,
  random_access_iterator_tag) {
  <i>// more efficient, but less generic algorithm</i>
}
</pre>
&mdash; <i>end example</i> ]
</li>
</ol>


<h4>23.4.2 Iterator operations [iterator.operations]</h4>
<ol start="4">
<pre>
template&lt;class InputIterator&gt;
  constexpr <del>typename</del> iterator_traits&lt;InputIterator&gt;::difference_type
    distance(InputIterator first, InputIterator last);
</pre>
<li>
<i>Preconditions:</i> <code>last</code> is reachable from <code>first</code>, or
<code>InputIterator</code> meets the <i>Cpp17RandomAccessIterator</i> requirements
and <code>first</code> is reachable from <code>last</code>.
</li>
<li>
<i>Effects:</i> If <code>InputIterator</code> meets the
<i>Cpp17RandomAccessIterator</i> requirements, returns <code>(last - first)</code>;
otherwise, returns the number of increments needed to get from <code>first</code>
to <code>last</code>.
</li>

<pre>
template&lt;class InputIterator&gt;
  constexpr InputIterator next(InputIterator x,
    <ins>typename</ins> iterator_traits&lt;InputIterator&gt;::difference_type n = 1);
</pre>
<li>
<i>Effects:</i> Equivalent to: <code>advance(x, n); return x;</code>
</li>

<pre>
template&lt;class BidirectionalIterator&gt;
  constexpr BidirectionalIterator prev(BidirectionalIterator x,
    <ins>typename</ins> iterator_traits&lt;BidirectionalIterator&gt;::difference_type n = 1);
</pre>
<li>
<i>Effects:</i> Equivalent to: <code>advance(x, -n); return x;</code>
</li>
</ol>


<h4>23.5.1.1 Class template <code>reverse_iterator</code> [reverse.iterator]</h4>
<blockquote><pre>
namespace std {
  template&lt;class Iterator&gt;
  class reverse_iterator {
  public:
    using iterator_type     = Iterator;
    using iterator_concept  = <i>see below</i>;
    using iterator_category = <i>see below</i>;
    using value_type        = iter_value_t&lt;Iterator&gt;;
    using difference_type   = iter_difference_t&lt;Iterator&gt;;
    using pointer           = <del>typename</del> iterator_traits&lt;Iterator&gt;::pointer;
    using reference         = iter_reference_t&lt;Iterator&gt;;

      <i>// ...</i>
  };
}
</pre></blockquote>


<h4>23.5.2.1 Class template <code>back_insert_iterator</code> [back.insert.iterator]</h4>
<blockquote><pre>
namespace std {
  template&lt;class Container&gt;
  class back_insert_iterator {
  protected:
    Container* container = nullptr;

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = ptrdiff_t;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    constexpr back_insert_iterator() noexcept = default;
    constexpr explicit back_insert_iterator(Container&amp; x);
    constexpr back_insert_iterator&amp; operator=(const <del>typename</del> Container::value_type&amp; value);
    constexpr back_insert_iterator&amp; operator=(<del>typename</del> Container::value_type&amp;&amp; value);

    constexpr back_insert_iterator&amp; operator*();
    constexpr back_insert_iterator&amp; operator++();
    constexpr back_insert_iterator  operator++(int);
  };

  template&lt;class Container&gt;
    back_insert_iterator&lt;Container&gt; back_inserter(Container&amp; x);
}
</pre></blockquote>


<h4>23.5.2.1.1 Operations [back.insert.iter.ops]</h4>
<ol start="2">
<pre>
back_insert_iterator&amp; operator=(const <del>typename</del> Container::value_type&amp; value);
</pre>
<li>
<i>Effects:</i> As if by: <code>container-&gt;push_back(value);</code>
</li>
<li>
<i>Returns:</i> <code>*this</code>.
</li>

<pre>
back_insert_iterator&amp; operator=(<del>typename</del> Container::value_type&amp;&amp; value);
</pre>
<li>
<i>Effects:</i> As if by: <code>container-&gt;push_back(std::move(value));</code>
</li>
<li>
<i>Returns:</i> <code>*this</code>.
</li>
</ol>


<h4>23.5.2.2 Class template <code>front_insert_iterator</code> [front.insert.iterator]</h4>
<blockquote><pre>
namespace std {
  template&lt;class Container&gt;
  class front_insert_iterator {
  protected:
    Container* container = nullptr;

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = ptrdiff_t;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    constexpr front_insert_iterator() noexcept = default;
    constexpr explicit front_insert_iterator(Container&amp; x);
    constexpr front_insert_iterator&amp; operator=(const <del>typename</del> Container::value_type&amp; value);
    constexpr front_insert_iterator&amp; operator=(<del>typename</del> Container::value_type&amp;&amp; value);

    constexpr front_insert_iterator&amp; operator*();
    constexpr front_insert_iterator&amp; operator++();
    constexpr front_insert_iterator  operator++(int);
  };
}
</pre></blockquote>


<h4>23.5.2.2.1 Operations [front.insert.iter.ops]</h4>
<ol start="2">
<pre>
front_insert_iterator&amp; operator=(const <del>typename</del> Container::value_type&amp; value);
</pre>
<li>
<i>Effects:</i> As if by: <code>container-&gt;push_front(value);</code>
</li>
<li>
<i>Returns:</i> <code>*this</code>.
</li>

<pre>
front_insert_iterator&amp; operator=(<del>typename</del> Container::value_type&amp;&amp; value);
</pre>
<li>
<i>Effects:</i> As if by: <code>container-&gt;push_front(std::move(value));</code>
</li>
<li>
<i>Returns:</i> <code>*this</code>.
</li>
</ol>


<h4>23.5.2.3 Class template <code>insert_iterator</code> [insert.iterator]</h4>
<blockquote><pre>
namespace std {
  template&lt;class Container&gt;
  class insert_iterator {
  protected:
      Container* container = nullptr;
      ranges::iterator_t&lt;Container&gt; iter = ranges::iterator_t&lt;Container&gt;();

  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = ptrdiff_t;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    insert_iterator() = default;
    constexpr insert_iterator(Container&amp; x, ranges::iterator_t&lt;Container&gt; i);
    constexpr insert_iterator&amp; operator=(const <del>typename</del> Container::value_type&amp; value);
    constexpr insert_iterator&amp; operator=(<del>typename</del> Container::value_type&amp;&amp; value);

    constexpr insert_iterator&amp; operator*();
    constexpr insert_iterator&amp; operator++();
    constexpr insert_iterator&amp; operator++(int);
  };
}
</pre></blockquote>


<h4>23.5.2.3.1 Operations [insert.iter.ops]</h4>
<ol>
<pre>
insert_iterator(Container&amp; x, ranges::iterator_t&lt;Container&gt; i);
</pre>
<li>
<i>Effects:</i> Initializes <code>container</code> with <code>addressof(x)</code> and
<code>iter</code> with <code>i</code>.
</li>

<pre>
constexpr insert_iterator&amp; operator=(const <del>typename</del> Container::value_type&amp; value);
</pre>
<li>
<i>Effects:</i> As if by:
<pre>
iter = container-&gt;insert(iter, value);
++iter;
</pre>
</li>
<li>
<i>Returns:</i> <code>*this</code>.
</li>

<pre>
constexpr insert_iterator&amp; operator=(<del>typename</del> Container::value_type&amp;&amp; value);
</pre>
<li>
<i>Effects:</i> As if by:
<pre>
iter = container-&gt;insert(iter, std::move(value));
++iter;
</pre>
</li>
<li>
<i>Returns:</i> <code>*this</code>.
</li>
</ol>


<h4>24.7.11.5 Class template <code>split_view::<i>inner-iterator</i></code> [range.split.inner]</h4>
<blockquote><pre>
namespace std::ranges {
  template&lt;input_range V, forward_range Pattern&gt;
    requires view&lt;V&gt; &amp;&amp; view&lt;Pattern&gt; &amp;&amp;
             indirectly_comparable&lt;iterator_t&lt;V&gt;, iterator_t&lt;Pattern&gt;, ranges::equal_to&gt; &amp;&amp;
	     (forward_range&lt;V&gt; || <i>tiny-range</i>&lt;Pattern&gt;)
  template&lt;bool Const&gt;
  struct split_view&lt;V, Pattern&gt;::<i>inner-iterator</i> {
  private:
    using Base = conditional_t&lt;Const, const V, V&gt;;      <i>// exposition only</i>
    <i>outer-iterator</i>&lt;Const&gt; <i>i_</i> = <i>outer-iterator</i>&lt;Const&gt;(); <i>// exposition only</i>
    bool <i>incremented_</i> = false;                          <i>// exposition only</i>

  public:
    using iterator_concept  = <del>typename</del> <i>outer-iterator</i>&lt;Const&gt;::iterator_concept;
    using iterator_category = <i>see below</i>;
    using value_type        = range_value_t&lt;<i>Base</i>&gt;;
    using difference_type   = range_difference_t&lt;<i>Base</i>&gt;;

    <i>// ...</i>
  };

  <i>// ...</i>
}
</pre></blockquote>


<h4>24.7.15.3 Class template <code>elements_view::<i>iterator</i></code> [range.elements.iterator]</h4>
<blockquote><pre>
namespace std::ranges {
  template&lt;input_range V, size_t N&gt;
    requires view&lt;V&gt; &amp;&amp; <i>has-tuple-element</i>&lt;range_value_t&lt;V&gt;, N&gt; &amp;&amp;
             <i>has-tuple-element</i>&lt;remove_reference_t&lt;range_reference_t&lt;V&gt;&gt;, N&gt;
  template&lt;bool Const&gt;
  class elements_view&lt;V, N&gt;::<i>iterator</i> {                <i>// exposition only</i>
    using <i>Base</i> = conditional_t&lt;Const, const V, V&gt;;     <i>// exposition only</i>

    iterator_t&lt;<i>Base</i>&gt; <i>current_</i> = iterator_t&lt;<i>Base</i>&gt;();

  public:
    using iterator_category = <del>typename</del> iterator_traits&lt;iterator_t&lt;<i>Base</i>&gt;&gt;::iterator_category;
    using value_type = remove_cvref_t&lt;tuple_element_t&lt;N, range_value_t&lt;<i>Base</i>&gt;&gt;&gt;;
    using difference_type = range_difference_t&lt;<i>Base</i>&gt;;

    <i>// ...</i>
  };
}
</pre></blockquote>



<h4>25.4 Header <code>&lt;algorithm&gt;</code> synopsis [algorithm.syn]</h4>
<blockquote><pre>
#include &lt;initializer_list&gt;

namespace std {
  <i>// ...</i>

  <i>// 25.6.9, count</i>
  template&lt;class InputIterator, class T&gt;
    constexpr <del>typename</del> iterator_traits&lt;InputIterator&gt;::difference_type
      count(InputIterator first, InputIterator last, const T&amp; value);
  template&lt;class ExecutionPolicy, class ForwardIterator, class T&gt;
    <del>typename</del> iterator_traits&lt;ForwardIterator&gt;::difference_type
      count(ExecutionPolicy&amp;&amp; exec, <i>// see 25.3.5</i>
            ForwardIterator first, ForwardIterator last, const T&amp; value);
  template&lt;class InputIterator, class Predicate&gt;
    constexpr <del>typename</del> iterator_traits&lt;InputIterator&gt;::difference_type
      count_if(InputIterator first, InputIterator last, Predicate pred);
  template&lt;class ExecutionPolicy, class ForwardIterator, class Predicate&gt;
    <del>typename</del> iterator_traits&lt;ForwardIterator&gt;::difference_type
      count_if(ExecutionPolicy&amp;&amp; exec, <i>// see 25.3.5</i>
               ForwardIterator first, ForwardIterator last, Predicate pred);

  <i>// ...</i>

  <i>// 25.7.14, shift</i>
  template&lt;class ForwardIterator&gt;
    constexpr ForwardIterator
      shift_left(ForwardIterator first, ForwardIterator last,
                 <ins>typename</ins> iterator_traits&lt;ForwardIterator&gt;::difference_type n);
  template&lt;class ExecutionPolicy, class ForwardIterator&gt;
    ForwardIterator
      shift_left(ExecutionPolicy&amp;&amp; exec, <i>// see 25.3.5</i>
                 ForwardIterator first, ForwardIterator last,
                 <ins>typename</ins> iterator_traits&lt;ForwardIterator&gt;::difference_type n);
  template&lt;class ForwardIterator&gt;
    constexpr ForwardIterator
      shift_right(ForwardIterator first, ForwardIterator last,
                  <ins>typename</ins> iterator_traits&lt;ForwardIterator&gt;::difference_type n);
  template&lt;class ExecutionPolicy, class ForwardIterator&gt;
    ForwardIterator
      shift_right(ExecutionPolicy&amp;&amp; exec, <i>// see 25.3.5</i>
                  ForwardIterator first, ForwardIterator last,
                  <ins>typename</ins> iterator_traits&lt;ForwardIterator&gt;::difference_type n);

  <i>// ...</i>

}
</pre></blockquote>


<h4>25.6.9 Count [alg.count]</h4>
<ol>
<pre>
template&lt;class InputIterator, class T&gt;
  constexpr <del>typename</del> iterator_traits&lt;InputIterator&gt;::difference_type
    count(InputIterator first, InputIterator last, const T&amp; value);
template&lt;class ExecutionPolicy, class ForwardIterator, class T&gt;
  <del>typename</del> iterator_traits&lt;ForwardIterator&gt;::difference_type
    count(ExecutionPolicy&amp;&amp; exec,
          ForwardIterator first, ForwardIterator last, const T&amp; value);

template&lt;class InputIterator, class Predicate&gt;
  constexpr <del>typename</del> iterator_traits&lt;InputIterator&gt;::difference_type
    count_if(InputIterator first, InputIterator last, Predicate pred);
template&lt;class ExecutionPolicy, class ForwardIterator, class Predicate&gt;
  <del>typename</del> iterator_traits&lt;ForwardIterator&gt;::difference_type
    count_if(ExecutionPolicy&amp;&amp; exec,
             ForwardIterator first, ForwardIterator last, Predicate pred);
</pre>
<li>
<i>Effects:</i> Returns the number of iterators <code>i</code> in the range
<code>[first, last)</code> for which the following corresponding conditions hold:
<code>*i == value</code>, <code>pred(*i) != false</code>.
</li>
<li>
<i>Complexity:</i> Exactly <code>last - first</code> applications of the
corresponding predicate.
</li>
</ol>



<h4>25.9 Header <code>&lt;numeric&gt;</code> synopsis [numeric.ops.overview]</h4>
<blockquote><pre>
namespace std {
  <i>// ...</i>

  // 25.10.3, reduce
  template&lt;class InputIterator&gt;
    <del>typename</del> iterator_traits&lt;InputIterator&gt;::value_type
      reduce(InputIterator first, InputIterator last);
  template&lt;class InputIterator, class T&gt;
    T reduce(InputIterator first, InputIterator last, T init);
  template&lt;class InputIterator, class T, class BinaryOperation&gt;
    T reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
  template&lt;class ExecutionPolicy, class ForwardIterator&gt;
    <del>typename</del> iterator_traits&lt;ForwardIterator&gt;::value_type
      reduce(ExecutionPolicy&amp;&amp; exec, // see 28.4.5 ForwardIterator first, ForwardIterator last);
  template&lt;class ExecutionPolicy, class ForwardIterator, class T&gt;
    T reduce(ExecutionPolicy&amp;&amp; exec, // see 28.4.5
             ForwardIterator first, ForwardIterator last, T init);
  template&lt;class ExecutionPolicy, class ForwardIterator, class T, class BinaryOperation&gt;
    T reduce(ExecutionPolicy&amp;&amp; exec, // see 28.4.5
             ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op);

  <i>// ...</i>
}
</pre></blockquote>


<h4>25.10.3 Reduce [reduce]</h4>
<ol>
<pre>
template&lt;class InputIterator&gt;
  <del>typename</del> iterator_traits&lt;InputIterator&gt;::value_type
    reduce(InputIterator first, InputIterator last);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<pre>
return reduce(first, last,
              <ins>typename</ins> iterator_traits&lt;InputIterator&gt;::value_type{});
</pre>
</li>

<pre>
template&lt;class ExecutionPolicy, class ForwardIterator&gt;
  <del>typename</del> iterator_traits&lt;ForwardIterator&gt;::value_type
    reduce(ExecutionPolicy&amp;&amp; exec,
           ForwardIterator first, ForwardIterator last);
</pre>
<li>
<i>Effects:</i>  Equivalent to:
<pre>
return reduce(std::forward&lt;ExecutionPolicy&gt;(exec), first, last,
              <ins>typename</ins> iterator_traits&lt;ForwardIterator&gt;::value_type{});
</pre>
</li>
</ol>


<h4>25.11.2 <code>uninitialized_default_construct</code> [uninitialized.construct.default]</h4>
<ol>
<pre>
template &lt;class NoThrowForwardIterator&gt;
  void uninitialized_default_construct(NoThrowForwardIterator first, NoThrowForwardIterator last);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
for (; first != last; ++first)
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type;
</pre></blockquote>
</li>
</ol>

<ol start="3">
<pre>
template &lt;class NoThrowForwardIterator, class Size&gt;
  NoThrowForwardIterator uninitialized_default_construct_n(NoThrowForwardIterator first, Size n);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
for (; n &gt; 0; (void)++first, --n)
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type;
return first;
</pre></blockquote>
</li>
</ol>


<h4>25.11.3 <code>uninitialized_value_construct</code> [uninitialized.construct.value]</h4>
<ol>
<pre>
template &lt;class NoThrowForwardIterator&gt;
  void uninitialized_value_construct(NoThrowForwardIterator first, NoThrowForwardIterator last);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
for (; first != last; ++first)
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type();
</pre></blockquote>
</li>
</ol>

<ol start="3">
<pre>
template &lt;class NoThrowForwardIterator, class Size&gt;
  NoThrowForwardIterator uninitialized_value_construct_n(NoThrowForwardIterator first, Size n);
</pre>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
for (; n &gt; 0; (void)++first, --n)
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type();
return first;
</pre></blockquote>
</li>
</ol>


<h4>25.11.4 <code>uninitialized_copy</code> [uninitialized.copy]</h4>
<ol>
<pre>
template &lt;class InputIterator, class NoThrowForwardIterator&gt;
  NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last,
                                            NoThrowForwardIterator result);
</pre>
<li>
<i>Preconditions:</i> <code>result + [0, (last - first))</code> does not overlap
with <code>[first, last)</code>.
</li>
<li>
<i>Effects:</i> As if by:
<blockquote><pre>
for (; first != last; ++result, (void) ++first)
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(*first);
</pre></blockquote>
</li>
<li>
<i>Returns:</i> <code>result</code>.
</li>
</ol>

<ol start="6">
<pre>
template &lt;class InputIterator, class Size, class NoThrowForwardIterator&gt;
  NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, NoThrowForwardIterator result);
</pre>
<li>
<i>Preconditions:</i> <code>result + [0, n)</code> does not overlap with
<code>first + [0, n)</code>.
</li>
<li>
<i>Effects:</i> As if by:
<blockquote><pre>
for ( ; n &gt; 0; ++result, (void) ++first, --n) {
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(*first);
}
</pre></blockquote>
</li>
<li>
<i>Returns:</i> <code>result</code>.
</li>
</ol>


<h4>25.11.5 <code>uninitialized_move</code> [uninitialized.move]</h4>
<ol>
<pre>
template &lt;class InputIterator, class ForwardIterator&gt;
  NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last,
                                            NoThrowForwardIterator result);
</pre>
<li>
<i>Preconditions:</i> <code>result + [0, (last - first))</code> does not overlap
with <code>[first, last)</code>.
</li>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
for (; first != last; (void)++result, ++first)
  ::new (<i>voidify</i>(*first))
      <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(std::move(*first));
return result;
</pre></blockquote>
</li>
</ol>

<ol start="6">
<pre>
template &lt;class InputIterator, class Size, class NoThrowForwardIterator&gt;
  pair&lt;InputIterator, NoThrowForwardIterator&gt;
    uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result);
</pre>
<li>
<i>Preconditions:</i> <code>result + [0, n)</code> does not overlap with
<code>first + [0, n)</code>.
</li>
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
for (; n &gt; 0; ++result, (void) ++first, --n)
  ::new (<i>voidify</i>(*first))
     <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(std::move(*first));
return {first,result};
</pre></blockquote>
</li>
</ol>


<h4>23.11.6 <code>uninitialized_fill</code> [uninitialized.fill]</h4>
<ol>
<pre>
template &lt;class NoThrowForwardIterator, class T&gt;
  void uninitialized_fill(ForwardIterator first, NoThrowForwardIterator last, const T&amp; x);
</pre>
<li>
<i>Effects:</i> As if by:
<blockquote><pre>
for (; first != last; ++first)
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(x);
</pre></blockquote>
</li>
</ol>

<ol start="3">
<pre>
template &lt;class NoThrowForwardIterator, class Size, class T&gt;
  ForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T&amp; x);
</pre>
<li>
<i>Effects:</i> As if by:
<blockquote><pre>
for (; n--; ++first)
  ::new (<i>voidify</i>(*first))
    <del>typename</del> iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(x);
return first;
</pre></blockquote>
</li>
</ol>


<h4>26.6.4.2 Class template <code>discard_block_engine</code> [rand.adapt.disc]</h4>
<ol start="3">
<li>
The generation algorithm yields the value returned by the last invocation of
<code>e()</code> while advancing <code>e</code>'s state as described above.
</li>
<pre>
template&lt;class Engine, size_t p, size_t r&gt;
  class discard_block_engine {
  public:
    <i>// types</i>
    using result_type = <del>typename</del> Engine::result_type;

    <i>// ...</i>
};
</pre>
</ol>


<h4>26.6.4.4 Class template <code>shuffle_order_engine</code> [rand.adapt.shuf]</h4>
<ol start="3">
<li>
The generation algorithm yields the last value of <code>Y</code> produced while
advancing <code>e</code>'s state as described above.
</li>
<pre>
template&lt;class Engine, size_t k&gt;
  class shuffle_order_engine {
  public:
    <i>// types</i>
    using result_type = <del>typename</del> Engine::result_type;

    <i>// ...</i>
};
</pre>
</ol>


<h4>26.7.1 Header <code>&lt;valarray&gt;</code> synopsis [valarray.syn]</h4>
<blockquote><pre>
#include &lt;initializer_list&gt;
namespace std {
  template&lt;class T&gt; class valarray;        <i>// An array of type T</i>
  class slice;                             <i>// a BLAS-like slice out of an array</i>
  template&lt;class T&gt; class slice_array;
  class gslice;                            <i>// a generalized slice out of an array</i>
  template&lt;class T&gt; class gslice_array;
  template&lt;class T&gt; class mask_array;      <i>// a masked array</i>
  template&lt;class T&gt; class indirect_array;  <i>// an indirected array</i>

  template&lt;class T&gt; void swap(valarray&lt;T&gt;&amp;, valarray&lt;T&gt;&amp;) noexcept;

  template&lt;class T&gt; valarray&lt;T&gt; operator* (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator* (const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator* (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; operator/ (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator/ (const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator/ (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; operator% (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator% (const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator% (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; operator+ (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator+ (const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator+ (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; operator- (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator- (const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator- (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,

  template&lt;class T&gt; valarray&lt;T&gt; operator^ (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator^ (const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator^ (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; operator&amp; (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator&amp; (const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator&amp; (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; operator| (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator| (const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator| (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; operator&lt;&lt;(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator&lt;&lt;(const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator&lt;&lt;(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; operator&gt;&gt;(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator&gt;&gt;(const valarray&lt;T&gt;&amp;,
                                           const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; operator&gt;&gt;(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                           const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;bool&gt; operator&amp;&amp;(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&amp;&amp;(const valarray&lt;T&gt;&amp;,
                                              const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&amp;&amp;(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                              const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;bool&gt; operator||(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator||(const valarray&lt;T&gt;&amp;,
                                              const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator||(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                              const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;bool&gt; operator==(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator==(const valarray&lt;T&gt;&amp;,
                                              const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator==(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                              const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator!=(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator!=(const valarray&lt;T&gt;&amp;,
                                              const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator!=(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                              const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;bool&gt; operator&lt; (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&lt; (const valarray&lt;T&gt;&amp;,
                                              const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&lt; (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                              const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&gt; (const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&gt; (const valarray&lt;T&gt;&amp;,
                                              const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&gt; (const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                              const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&lt;=(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;bool&gt; operator&lt;=(const valarray&lt;T&gt;&amp;,
                                              const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&lt;=(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                              const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&gt;=(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&gt;=(const valarray&lt;T&gt;&amp;,
                                              const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;bool&gt; operator&gt;=(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                              const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; abs  (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; acos (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; asin (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; atan (const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; atan2(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; atan2(const valarray&lt;T&gt;&amp;,
                                      const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; atan2(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;,
                                      const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; cos  (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; cosh (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; exp  (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; log  (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; log10(const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; pow(const valarray&lt;T&gt;&amp;, const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; pow(const valarray&lt;T&gt;&amp;, const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; pow(const <ins>typename</ins> valarray&lt;T&gt;::value_type&amp;, const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; valarray&lt;T&gt; sin  (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; sinh (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; sqrt (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; tan  (const valarray&lt;T&gt;&amp;);
  template&lt;class T&gt; valarray&lt;T&gt; tanh (const valarray&lt;T&gt;&amp;);

  template&lt;class T&gt; <i>unspecified1</i> begin(valarray&lt;T&gt;&amp; v);
  template&lt;class T&gt; <i>unspecified2</i> begin(const valarray&lt;T&gt;&amp; v);
  template&lt;class T&gt; <i>unspecified1</i> end(valarray&lt;T&gt;&amp; v);
  template&lt;class T&gt; <i>unspecified2</i> end(const valarray&lt;T&gt;&amp; v);
}
</pre></blockquote>


<h4>27.2 Header <code>&lt;chrono&gt;</code> synopsis [time.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt; <i>// see 17.11.1</i>
namespace std {
  namespace chrono {
    <i>// 27.5, class template duration</i>
    template&lt;class Rep, class Period = ratio&lt;1&gt;&gt; class duration;

    <i>// 27.6, class template time_point</i>
    template&lt;class Clock, class Duration = <del>typename</del> Clock::duration&gt; class time_point;
  }

  <i>// ...</i>
}
</pre></blockquote>


<h4>27.5 Class template duration [time.duration]</h4>
<pre>
namespace std::chrono {
  template&lt;class Rep, class Period = ratio&lt;1&gt;&gt;
    class duration {
    public:
      using rep    = Rep;
      using period = <del>typename</del> Period::type;

      <i>// ...</i>
    };
}
</pre>


<h4>27.5.6 Comparisons [time.duration.comparisons]</h4>
<ol start="7">
<pre>
template&lt;class Rep1, class Period1, class Rep2, class Period2&gt;
    requires three_way_comparable&lt;<ins>typename</ins> CT::rep&gt;
  constexpr auto operator&lt;=&gt;(const duration&lt;Rep1, Period1&gt;&amp; lhs,
                             const duration&lt;Rep2, Period2&gt;&amp; rhs);
</pre>
<li>
<i>Returns:</i> <code>CT(lhs).count() &lt;=&gt; CT(rhs).count()</code>.
</li>
</ol>


<h4>27.5.7 Conversions [time.duration.cast]</h4>
<ol>
<pre>
template&lt;class ToDuration, class Rep, class Period&gt;
  constexpr ToDuration duration_cast(const duration&lt;Rep, Period&gt;&amp; d);
</pre>
<li>
<i>Constraints:</i> <code>ToDuration</code> is a specialization of <code>duration</code>.
</li>
<li>
<i>Returns:</i> Let <code>CF</code> be
<code>ratio_divide&lt;Period, <ins>typename</ins> ToDuration::period&gt;</code>,
and <code>CR</code> be
<code>common_type&lt;<ins>typename</ins> ToDuration::rep, Rep, intmax_t&gt;::type</code>.
  <ol>
  <li>
&mdash; If <code>CF::num == 1</code> and <code>CF::den == 1</code>, returns
<pre>
   ToDuration(static_cast&lt;<del>typename</del> ToDuration::rep&gt;(d.count()))
</pre>
  </li>
  <li>
&mdash; otherwise, if <code>CF::num != 1</code> and <code>CF::den == 1</code>, returns
<pre>
   ToDuration(static_cast&lt;<del>typename</del> ToDuration::rep&gt;(
     static_cast&lt;CR&gt;(d.count()) * static_cast&lt;CR&gt;(CF::num)))
</pre>
  </li>
  <li>
&mdash; otherwise, if <code>CF::num == 1</code> and <code>CF::den != 1</code>, returns
<pre>
   ToDuration(static_cast&lt;<del>typename</del> ToDuration::rep&gt;(
     static_cast&lt;CR&gt;(d.count()) / static_cast&lt;CR&gt;(CF::den)))
</pre>
  </li>
  <li>
&mdash; otherwise, returns
<pre>
   ToDuration(static_cast&lt;<del>typename</del> ToDuration::rep&gt;(
     static_cast&lt;CR&gt;(d.count()) * static_cast&lt;CR&gt;(CF::num) / static_cast&lt;CR&gt;(CF::den)))
</pre>
  </li>
  </ol>
</li>
</ol>

<ol start="8">
<pre>
template&lt;class ToDuration, class Rep, class Period&gt;
  constexpr ToDuration round(const duration&lt;Rep, Period&gt;&amp; d);
</pre>
<li>
<i>Constraints:</i> <code>ToDuration</code> is a specialization of
<code>duration</code>, and <code>treat_as_floating_point_v&lt;<ins>typename</ins>
ToDuration::rep&gt;</code> is <code>false</code>.
</li>
<li>
<i>Returns:</i> The value of <code>ToDuration</code> that is closest to <code>d</code>.
If there are two closest values, then return the value <code>t</code> for which
<code>t % 2 == 0</code>.
</li>
</ol>


<h4>27.6 Class template time_point [time.point]</h4>
<blockquote><pre>
namespace std::chrono {
  template&lt;class Clock, class Duration = <del>typename</del> Clock::duration&gt;
    class time_point {
    public:
      using clock    = Clock;
      using duration = Duration;
      using rep      = <del>typename</del> duration::rep;
      using period   = <del>typename</del> duration::period;

      <i>// ...</i>
    };
}
</pre></blockquote>


<h4>27.6.7 Conversions [time.point.cast]</h4>
<pre>
template&lt;class ToDuration, class Clock, class Duration&gt;
  constexpr time_point&lt;Clock, ToDuration&gt; round(const time_point&lt;Clock, Duration&gt;&amp; tp);
</pre>
<ol start="7">
<li>
<i>Constraints:</i> <code>ToDuration</code> is a specialization of
<code>duration</code>, and <code>treat_as_floating_point_v&lt;<ins>typename</ins>
ToDuration::rep&gt;</code> is <code>false</code>.
</li>
</ol>


<h4>27.7.1.3 Non-member functions [time.clock.system.nonmembers]</h4>
<pre>
template&lt;class charT, class traits, class Duration&gt;
  basic_ostream&lt;charT, traits&gt;&amp;
    operator&lt;&lt;(basic_ostream&lt;charT, traits&gt;&amp; os, const sys_time&lt;Duration&gt;&amp; tp);
</pre>
<ol>
<li>
<i>Constraints:</i> <code>treat_as_floating_point_v&lt;<ins>typename</ins>
Duration::rep&gt;</code> is <code>false</code>, and <code>Duration{1} &lt; days{1}</code>
is <code>true</code>.
</li>
</ol>


<h4>27.12 Formatting [time.format]</h4>
<pre>
template&lt;class Duration, class TimeZonePtr, class charT&gt;
struct formatter&lt;chrono::zoned_time&lt;Duration, TimeZonePtr&gt;, charT&gt;
    : formatter&lt;chrono::<i>local-time-format-t</i>&lt;Duration&gt;, charT&gt; {
    template&lt;class FormatContext&gt;
      <del>typename</del> FormatContext::iterator
        format(const chrono::zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp, FormatContext&amp; ctx);
};
template&lt;class FormatContext&gt;
  <del>typename</del> FormatContext::iterator
    format(const chrono::zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp, FormatContext&amp; ctx);
</pre>
<ol start="16">
<li>
<i>Effects:</i> Equivalent to:
<blockquote><pre>
sys_info info = tp.get_info();
return formatter&lt;chrono::<i>local-time-format-t</i>&lt;Duration&gt;, charT&gt;::
         format({tp.get_local_time(), &amp;info.abbrev, &amp;info.offset}, ctx);
</pre></blockquote>
</li>
</ol>


<h4>28.3.1 <code>Class locale</code> [locale]</h4>
<ol start="3">
<li>
[ <i>Example:</i> An iostream <code>operator&lt;&lt;</code> might be implemented as:<sup>257</sup>
<blockquote><pre>
template&lt;class charT, class traits&gt;
basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt; (basic_ostream&lt;charT, traits&gt;&amp; s, Date d) {
  <ins>typename</ins> basic_ostream&lt;charT, traits&gt;::sentry cerberos(s);
  if (cerberos) {
    tm tmbuf; d.extract(tmbuf);
    bool failed =
      use_facet&lt;time_put&lt;charT, ostreambuf_iterator&lt;charT, traits&gt;&gt;&gt;(
        s.getloc()).put(s, s, s.fill(), &amp;tmbuf, 'x').failed();
    if (failed)
      s.setstate(s.badbit);     <i>// might throw</i>
  }
  return s;
}
</pre></blockquote>
&mdash; <i>end example</i> ]
</li>
</ol>


<h4>28.4.1.2 Class template ctype_byname [locale.ctype.byname]</h4>
<blockquote><pre>
namespace std {
  emplate&lt;class charT&gt;
    class ctype_byname : public ctype&lt;charT&gt; {
    public:
      using mask = <del>typename</del> ctype&lt;charT&gt;::mask;
      explicit ctype_byname(const char*, size_t refs = 0);
      explicit ctype_byname(const string&amp;, size_t refs = 0);

    protected:
      ~ctype_byname();

    };
}
</pre></blockquote>


<h4>29.5.5.1 Overview [ios.overview]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_ios : public ios_base {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;

      <i>// 29.5.5.4, flags functions ...</i>
    };
}
</pre></blockquote>


<h4>29.6.3 Class template <code>basic_streambuf</code> [streambuf]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_streambuf {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;

      virtual ~basic_streambuf();

      <i>// 29.6.3.2.1, locales ...</i>
    };
}
</pre></blockquote>


<h4>29.7.4.1 Class template <code>basic_istream</code> [istream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_istream : virtual public basic_ios&lt;charT, traits&gt; {
    public:
      <i>// types (inherited from basic_ios (29.5.5))</i>
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;

      <i>// 29.7.4.1.1, constructor/destructor ...</i>
    };
}
</pre></blockquote>


<h4>29.7.4.6 Class template <code>basic_iostream</code> [iostream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_iostream
      : public basic_istream&lt;charT, traits&gt;,
        public basic_ostream&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;;

      <i>// 29.7.4.6.1, constructor ...</i>
    };
}
</pre></blockquote>


<h4>29.7.5.1 Class template <code>basic_ostream</code> [ostream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_ostream : virtual public basic_ios&lt;charT, traits&gt; {
    public:
      <i>// types (inherited from basic_ios (29.5.5))</i>
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;;

      <i>// 29.7.5.1.1, constructor/destructor ...</i>
    };
}
</pre></blockquote>



<h4>29.8.2 Class template <code>basic_stringbuf</code> [stringbuf]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_stringbuf : public basic_streambuf&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;

      <i>// 29.8.2.1, constructors/destructor</i>
    };
}
</pre></blockquote>


<h4>29.8.3 Class template <code>basic_istringstream</code> [istringstream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_istringstream : public basic_istream&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;

      <i>// 29.8.3.1, constructors ...</i>
    };
}
</pre></blockquote>


<h4>29.8.4 Class template <code>basic_ostringstream</code> [ostringstream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_ostringstream : public basic_ostream&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;;

      <i>// 29.8.4.1, constructors ...</i>
    };
}
</pre></blockquote>


<h4>29.8.5 Class template <code>basic_stringstream</code> [stringstream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_stringstream : public basic_iostream&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;;

      <i>// 29.8.5.1, constructors ...</i>
    };
}
</pre></blockquote>


<h4>29.9.2 Class template <code>basic_filebuf</code> [filebuf]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_filebuf : public basic_streambuf&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;

      <i>// 29.9.2.1, constructors/destructor</i>
    };
}
</pre></blockquote>
<ol start="5">
<li>
In order to support file I/O and multibyte/wide character conversion,
conversions are performed using members of a facet, referred to as
<code>a_codecvt</code> in following subclauses, obtained as if by
<pre>
const codecvt&lt;charT, char, <ins>typename</ins> traits::state_type&gt;&amp; a_codecvt =
  use_facet&lt;codecvt&lt;charT, char, <ins>typename</ins> traits::state_type&gt;&gt;(getloc());
</pre>
</li>
</ol>


<h4>29.9.3 Class template <code>basic_ifstream</code> [ifstream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_ifstream : public basic_istream&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;

      <i>// 29.9.3.1, constructors ...</i>
    };
}
</pre></blockquote>


<h4>29.9.4 Class template <code>basic_ofstream</code> [ofstream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_ofstream : public basic_ostream&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;;

      <i>// 29.9.4.1, constructors ...</i>
    };
}
</pre></blockquote>


<h4>29.9.5 Class template <code>basic_fstream</code> [fstream]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;&gt;
    class basic_fstream : public basic_iostream&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;;

      <i>// 29.9.5.1, constructors ...</i>
    };
}
</pre></blockquote>


<h4>29.10.2.1 Overview [syncstream.syncbuf.overview]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;, class Allocator = allocator&lt;charT&gt;&gt;
    class basic_syncbuf : public basic_streambuf&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;
      using allocator_type = Allocator;

      using streambuf_type = basic_streambuf&lt;charT, traits&gt;;

      <i>// 29.10.2.2, construction and destruction...</i>
    };
}
</pre></blockquote>


<h4>29.10.3.1 Overview [syncstream.osyncstream.overview]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = char_traits&lt;charT&gt;, class Allocator = allocator&gt;charT&gt;&gt;
    class basic_osyncstream : public basic_ostream&lt;charT, traits&gt; {
    public:
      using char_type      = charT;
      using int_type       = <del>typename</del> traits::int_type;
      using pos_type       = <del>typename</del> traits::pos_type;
      using off_type       = <del>typename</del> traits::off_type;
      using traits_type    = traits;;

      using allocator_type = Allocator;
      using streambuf_type = basic_streambuf&lt;charT, traits&gt;;
      using syncbuf_type   = basic_syncbuf&lt;charT, traits, Allocator&gt;;

      <i>// 29.10.3.2, construction and destruction ...</i>
    };
}
</pre></blockquote>


<h4>30.4 Header <code>&lt;regex&gt;</code> synopsis [re.syn]</h4>
<blockquote><pre>
#include &lt;compare&gt;          <i>// see 17.11.1</i>
#include &lt;initializer_list&gt; <i>// see 17.10.1</i>

namespace std {
  // 30.5, regex constants
  namespace regex_constants {
    using syntax_option_type = T1;
    using match_flag_type = T2;
    using error_type = T3;
  }

  // 30.6, class regex_error
  class regex_error;

  // 30.7, class template regex_traits
  template&lt;class charT&gt; struct regex_traits;

  // 30.8, class template basic_regex
  template&lt;class charT, class traits = regex_traits&lt;charT&gt;&gt;
    class basic_regex;

  using regex  = basic_regex&lt;char&gt;;
  using wregex = basic_regex&lt;wchar_t&gt;;

  // 30.8.5, basic_regex swap
  template&lt;class charT, class traits&gt;
    void swap(basic_regex&lt;charT, traits&gt;&amp; e1, basic_regex&lt;charT, traits&gt;&amp; e2);

  // 30.9, class template sub_match
  template&lt;class BidirectionalIterator&gt;
    class sub_match;

  using csub_match  = sub_match&lt;const char*&gt;;
  using wcsub_match = sub_match&lt;const wchar_t*&gt;;
  using ssub_match  = sub_match&lt;string::const_iterator&gt;;
  using wssub_match = sub_match&lt;wstring::const_iterator&gt;;

  // 30.9.2, sub_match non-member operators
  template&lt;class BiIter&gt;
    bool operator==(const sub_match&lt;BiIter&gt;&amp; lhs, const sub_match&lt;BiIter&gt;&amp; rhs);
  template&lt;class BiIter&gt;
    auto operator&lt;=&gt;(const sub_match&lt;BiIter&gt;&amp; lhs, const sub_match&lt;BiIter&gt;&amp; rhs);
  template&lt;class BiIter, class ST, class SA&gt;
    bool operator==(
      const sub_match&lt;BiIter&gt;&amp; lhs,
      const basic_string&lt;<ins>typename</ins> iterator_traits&lt;BiIter&gt;::value_type, ST, SA&gt;&amp; rhs);
  template&lt;class BiIter, class ST, class SA&gt;
    auto operator&lt;=&gt;(
      const sub_match&lt;BiIter&gt;&amp; lhs,
      const basic_string&lt;<ins>typename</ins> iterator_traits&lt;BiIter&gt;::value_type, ST, SA&gt;&amp; rhs);
  template&lt;class BiIter&gt;
    bool operator==(const sub_match&lt;BiIter&gt;&amp; lhs,
                    const <ins>typename</ins> iterator_traits&lt;BiIter&gt;::value_type* rhs);
  template&lt;class BiIter&gt;
    auto operator&lt;=&gt;(const sub_match&lt;BiIter&gt;&amp; lhs,
                     const <ins>typename</ins> iterator_traits&lt;BiIter&gt;::value_type* rhs);
  template&lt;class BiIter&gt;
    bool operator==(const sub_match&lt;BiIter&gt;&amp; lhs,
                    const <ins>typename</ins> iterator_traits&lt;BiIter&gt;::value_type&amp; rhs);
  template&lt;class BiIter&gt;
    auto operator&lt;=&gt;(const sub_match&lt;BiIter&gt;&amp; lhs,
                     const <ins>typename</ins> iterator_traits&lt;BiIter&gt;::value_type&amp; rhs);
  template&lt;class charT, class ST, class BiIter&gt;
    basic_ostream&lt;charT, ST&gt;&amp;
      operator&lt;&lt;(basic_ostream&lt;charT, ST&gt;&amp; os, const sub_match&lt;BiIter&gt;&amp; m);

  // 30.10, class template match_results
  template&lt;class BidirectionalIterator,
           class Allocator = allocator&lt;sub_match&lt;BidirectionalIterator&gt;&gt;&gt;
    class match_results;

  using cmatch  = match_results&lt;const char*&gt;;
  using wcmatch = match_results&lt;const wchar_t*&gt;;
  using smatch  = match_results&lt;string::const_iterator&gt;;
  using wsmatch = match_results&lt;wstring::const_iterator&gt;;

  // match_results comparisons
  template&lt;class BidirectionalIterator, class Allocator&gt;
    bool operator==(const match_results&lt;BidirectionalIterator, Allocator&gt;&amp; m1,
                    const match_results&lt;BidirectionalIterator, Allocator&gt;&amp; m2);

  // 30.10.7, match_results swap
  template&lt;class BidirectionalIterator, class Allocator&gt;
    void swap(match_results&lt;BidirectionalIterator, Allocator&gt;&amp; m1,
              match_results&lt;BidirectionalIterator, Allocator&gt;&amp; m2);

  // 30.11.2, function template regex_match
  template&lt;class BidirectionalIterator, class Allocator, class charT, class traits&gt;
    bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
                     match_results&lt;BidirectionalIterator, Allocator&gt;&amp; m,
                     const basic_regex&lt;charT, traits&gt;&amp; e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class BidirectionalIterator, class charT, class traits&gt;
    bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
                     const basic_regex&lt;charT, traits&gt;&amp; e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class charT, class Allocator, class traits&gt;
    bool regex_match(const charT* str, match_results&lt;const charT*, Allocator&gt;&amp; m,
                     const basic_regex&lt;charT, traits&gt;&amp; e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class ST, class SA, class Allocator, class charT, class traits&gt;
    bool regex_match(const basic_string&lt;charT, ST, SA&gt;&amp; s,
                     match_results&lt;<ins>typename</ins> basic_string&lt;charT, ST, SA&gt;::const_iterator,
                                   Allocator&gt;&amp; m,
                     const basic_regex&lt;charT, traits&gt;&amp; e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class ST, class SA, class Allocator, class charT, class traits&gt;
    bool regex_match(const basic_string&lt;charT, ST, SA&gt;&amp;&amp;,
                     match_results&lt;<ins>typename</ins> basic_string&lt;charT, ST, SA&gt;::const_iterator,
                                   Allocator&gt;&amp;,
                     const basic_regex&lt;charT, traits&gt;&amp;,
                     regex_constants::match_flag_type = regex_constants::match_default) = delete;
  template&lt;class charT, class traits&gt;
    bool regex_match(const charT* str,
                     const basic_regex&lt;charT, traits&gt;&amp; e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class ST, class SA, class charT, class traits&gt;
    bool regex_match(const basic_string&lt;charT, ST, SA&gt;&amp; s,
                     const basic_regex&lt;charT, traits&gt;&amp; e,
                     regex_constants::match_flag_type flags = regex_constants::match_default);

  // 30.11.3, function template regex_search
  template&lt;class BidirectionalIterator, class Allocator, class charT, class traits&gt;
    bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                      match_results&lt;BidirectionalIterator, Allocator&gt;&amp; m,
                      const basic_regex&lt;charT, traits&gt;&amp; e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class BidirectionalIterator, class charT, class traits&gt;
    bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                      const basic_regex&lt;charT, traits&gt;&amp; e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class charT, class Allocator, class traits&gt;
    bool regex_search(const charT* str,
                      match_results&lt;const charT*, Allocator&gt;&amp; m,
                      const basic_regex&lt;charT, traits&gt;&amp; e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class charT, class traits&gt;
    bool regex_search(const charT* str,
                      const basic_regex&lt;charT, traits&gt;&amp; e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);

  template&lt;class ST, class SA, class charT, class traits&gt;
    bool regex_search(const basic_string&lt;charT, ST, SA&gt;&amp; s,
                      const basic_regex&lt;charT, traits&gt;&amp; e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class ST, class SA, class Allocator, class charT, class traits&gt;
    bool regex_search(const basic_string&lt;charT, ST, SA&gt;&amp; s,
                      match_results&lt;<ins>typename</ins> basic_string&lt;charT, ST, SA&gt;::const_iterator,
                                    Allocator&gt;&amp; m,
                      const basic_regex&lt;charT, traits&gt;&amp; e,
                      regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class ST, class SA, class Allocator, class charT, class traits&gt;
    bool regex_search(const basic_string&lt;charT, ST, SA&gt;&amp;&amp;,
                      match_results&lt;<ins>typename</ins> basic_string&lt;charT, ST, SA&gt;::const_iterator,
                                    Allocator&gt;&amp;,
                      const basic_regex&lt;charT, traits&gt;&amp;,
                      regex_constants::match_flag_type
                        = regex_constants::match_default) = delete;

  // 30.11.4, function template regex_replace
  template&lt;class OutputIterator, class BidirectionalIterator,
           class traits, class charT, class ST, class SA&gt;
    OutputIterator
      regex_replace(OutputIterator out,
                    BidirectionalIterator first, BidirectionalIterator last,
                    const basic_regex&lt;charT, traits&gt;&amp; e,
                    const basic_string&lt;charT, ST, SA&gt;&amp; fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class OutputIterator, class BidirectionalIterator, class traits, class charT&gt;
    OutputIterator
      regex_replace(OutputIterator out,
                    BidirectionalIterator first, BidirectionalIterator last,
                    const basic_regex&lt;charT, traits&gt;&amp; e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class traits, class charT, class ST, class SA, class FST, class FSA&gt;
    basic_string&lt;charT, ST, SA&gt;
      regex_replace(const basic_string&lt;charT, ST, SA&gt;&amp; s,
                    const basic_regex&lt;charT, traits&gt;&amp; e,
                    const basic_string&lt;charT, FST, FSA&gt;&amp; fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class traits, class charT, class ST, class SA&gt;
    basic_string&lt;charT, ST, SA&gt;
      regex_replace(const basic_string&lt;charT, ST, SA&gt;&amp; s,
                    const basic_regex&lt;charT, traits&gt;&amp; e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class traits, class charT, class ST, class SA&gt;
    basic_string&lt;charT&gt;
      regex_replace(const charT* s,
                    const basic_regex&lt;charT, traits&gt;&amp; e,
                    const basic_string&lt;charT, ST, SA&gt;&amp; fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);
  template&lt;class traits, class charT&gt;
    basic_string&lt;charT&gt;
      regex_replace(const charT* s,
                    const basic_regex&lt;charT, traits&gt;&amp; e,
                    const charT* fmt,
                    regex_constants::match_flag_type flags = regex_constants::match_default);

  // 30.12.1, class template regex_iterator
  template&lt;class BidirectionalIterator,
           class charT = <del>typename</del> iterator_traits&lt;BidirectionalIterator&gt;::value_type,
           class traits = regex_traits&lt;charT&gt;&gt;
    class regex_iterator;

  using cregex_iterator  = regex_iterator&lt;const char*&gt;;
  using wcregex_iterator = regex_iterator&lt;const wchar_t*&gt;;
  using sregex_iterator  = regex_iterator&lt;string::const_iterator&gt;;
  using wsregex_iterator = regex_iterator&lt;wstring::const_iterator&gt;;

  // 30.12.2, class template regex_token_iterator
  template&lt;class BidirectionalIterator,
           class charT = <del>typename</del> iterator_traits&lt;BidirectionalIterator&gt;::value_type,
           class traits = regex_traits&lt;charT&gt;&gt;
    class regex_token_iterator;

    using cregex_token_iterator  = regex_token_iterator&lt;const char*&gt;;
    using wcregex_token_iterator = regex_token_iterator&lt;const wchar_t*&gt;;
    using sregex_token_iterator  = regex_token_iterator&lt;string::const_iterator&gt;;
    using wsregex_token_iterator = regex_token_iterator&lt;wstring::const_iterator&gt;;

    namespace pmr {
      template&lt;class BidirectionalIterator&gt;
        using match_results =
          std::match_results&lt;BidirectionalIterator,
                             polymorphic_allocator&lt;sub_match&lt;BidirectionalIterator&gt;&gt;&gt;;

      using cmatch  = match_results&lt;const char*&gt;;
      using wcmatch = match_results&lt;const wchar_t*&gt;;
      using smatch  = match_results&lt;string::const_iterator&gt;;
      using wsmatch = match_results&lt;wstring::const_iterator&gt;;
  }
}
</pre></blockquote>


<h4>30.8 Class template <code>basic_regex</code> [re.regex]</h4>
<blockquote><pre>
namespace std {
  template&lt;class charT, class traits = regex_traits&lt;charT&gt;&gt;
    class basic_regex {
    public:
      <i>// types</i>
      using value_type  =          charT;
      using traits_type =          traits;
      using string_type = <del>typename</del> traits::string_type;
      using flag_type   =          regex_constants::syntax_option_type;
      using locale_type = <del>typename</del> traits::locale_type;

      <i>// 30.5.1, constants ...</i>

    };

  template&lt;class ForwardIterator&gt;
    basic_regex(ForwardIterator, ForwardIterator,
                  regex_constants::syntax_option_type = regex_constants::ECMAScript)
		  -&gt; basic_regex&lt;<ins>typename</ins> iterator_traits&lt;ForwardIterator&gt;::value_type&gt;;
}
</pre></blockquote>


<H4>30.9 Class template sub_match [re.submatch]</H4>
<ol>
<li>
Class template <code>sub_match</code> denotes the sequence of characters matched by
a particular marked sub-expression
</li>
<pre>
namespace std {
  template&lt;class BidirectionalIterator&gt;
    class sub_match : public pair&lt;BidirectionalIterator, BidirectionalIterator&gt; {
    public:
      using value_type      =
	      <del>typename</del> iterator_traits&lt;BidirectionalIterator&gt;::value_type;
      using difference_type =
              <del>typename</del> iterator_traits&lt;BidirectionalIterator&gt;::difference_type;
      using iterator        = BidirectionalIterator;
      using string_type     = basic_string&lt;value_type&gt;;

      bool matched;

      constexpr sub_match();

      difference_type length() const;
      operator string_type() const;
      string_type str() const;

      int compare(const sub_match&amp; s) const;
      int compare(const string_type&amp; s) const;
      int compare(const value_type* s) const;
}; }
</pre>
</ol>


<h4>30.10 Class template <code>match_results</code> [re.results]</h4>
<blockquote><pre>
namespace std {
  template&lt;class BidirectionalIterator,
           class Allocator = allocator&lt;sub_match&lt;BidirectionalIterator&gt;&gt;&gt;
    class match_results {
    public:
      using value_type      = sub_match&lt;BidirectionalIterator&gt;;
      using const_reference = const value_type&amp;;
      using reference       = value_type&amp;;
      using const_iterator  = <i>implementation-defined</i>;
      using iterator        = const_iterator;
      using difference_type =
	<del>typename</del> iterator_traits&lt;BidirectionalIterator&gt;::difference_type;
      using size_type       = <del>typename</del> allocator_traits&lt;Allocator&gt;::size_type;
      using allocator_type  = Allocator;
      using char_type       =
        <del>typename</del> iterator_traits&lt;BidirectionalIterator&gt;::value_type;
      using string_type     = basic_string&lt;char_type&gt;;

      <i>// ...</i>
  };
}
</pre></blockquote>


<h4>30.12.1 Class template <code>regex_iterator</code> [re.regiter]</h4>
<ol>
<li>
The class template <code>regex_iterator</code> is an iterator adaptor.
It represents ...
</li>
<pre>
namespace std {
  template&lt;class BidirectionalIterator,
           class charT = <del>typename</del> iterator_traits&lt;BidirectionalIterator&gt;::value_type,
           class traits = regex_traits&lt;charT&gt;&gt;
    class regex_iterator {
      <i>// ...</i>
    };
}
</pre>
</ol>


<h4>30.12.2 Class template <code>regex_token_iterator</code> [re.tokiter]</h4>
<ol start="6">
<li>
It is impossible to store things into <code>regex_token_iterators</code>.
Two end-of-sequence iterators ...
</li>
<pre>
namespace std {
  template&lt;class BidirectionalIterator,
           class charT = <del>typename</del> iterator_traits&lt;BidirectionalIterator&gt;::value_type,
           class traits = regex_traits&lt;charT&gt;&gt;
    class regex_token_iterators {
      <i>// ...</i>
    };
}
</pre>
</ol>


<h4>31.2 Header <code>&lt;atomic&gt;</code> synopsis [atomics.syn]</h4>
<blockquote><pre>
namespace std {
  <i>// ...</i>

  // 31.9, non-member functions
  template&lt;class T&gt;
    bool atomic_is_lock_free(const volatile atomic&lt;T&gt;*) noexcept;
  template&lt;class T&gt;
    bool atomic_is_lock_free(const atomic&lt;T&gt;*) noexcept;

  template&lt;class T&gt;
    void atomic_store(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    void atomic_store(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    void atomic_store_explicit(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                               memory_order) noexcept;
  template&lt;class T&gt;
    void atomic_store_explicit(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                               memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_load(const volatile atomic&lt;T&gt;*) noexcept;
  template&lt;class T&gt;
    T atomic_load(const atomic&lt;T&gt;*) noexcept;
  template&lt;class T&gt;
    T atomic_load_explicit(const volatile atomic&lt;T&gt;*, memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_load_explicit(const atomic&lt;T&gt;*, memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_exchange(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    T atomic_exchange(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    T atomic_exchange_explicit(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                               memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_exchange_explicit(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                               memory_order) noexcept;
  template&lt;class T&gt;
    bool atomic_compare_exchange_weak(volatile atomic&lt;T&gt;*,
                                      <ins>typename</ins> atomic&lt;T&gt;::value_type*,
                                      <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    bool atomic_compare_exchange_weak(atomic&lt;T&gt;*,
                                      <ins>typename</ins> atomic&lt;T&gt;::value_type*,
                                      <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    bool atomic_compare_exchange_strong(volatile atomic&lt;T&gt;*,
                                        <ins>typename</ins> atomic&lt;T&gt;::value_type*,
                                        <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    bool atomic_compare_exchange_strong(atomic&lt;T&gt;*,
                                        <ins>typename</ins> atomic&lt;T&gt;::value_type*,
                                        <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    bool atomic_compare_exchange_weak_explicit(volatile atomic&lt;T&gt;*,
                                               <ins>typename</ins> atomic&lt;T&gt;::value_type*,
                                               <ins>typename</ins> atomic&lt;T&gt;::value_type,
                                               memory_order, memory_order) noexcept;
  template&lt;class T&gt;
    bool atomic_compare_exchange_weak_explicit(atomic&lt;T&gt;*,
                                               <ins>typename</ins> atomic&lt;T&gt;::value_type*,
                                               <ins>typename</ins> atomic&lt;T&gt;::value_type,
                                               memory_order, memory_order) noexcept;
  template&lt;class T&gt;
    bool atomic_compare_exchange_strong_explicit(volatile atomic&lt;T&gt;*,
                                                 <ins>typename</ins> atomic&lt;T&gt;::value_type*,
                                                 <ins>typename</ins> atomic&lt;T&gt;::value_type,
                                                 memory_order, memory_order) noexcept;
  template&lt;class T&gt;
    bool atomic_compare_exchange_strong_explicit(atomic&lt;T&gt;*,
                                                 <ins>typename</ins> atomic&lt;T&gt;::value_type*,
                                                 <ins>typename</ins> atomic&lt;T&gt;::value_type,
                                                 memory_order, memory_order) noexcept;

  template&lt;class T&gt;
    T atomic_fetch_add(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::difference_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_add(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::difference_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_add_explicit(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::difference_type,
                                memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_add_explicit(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::difference_type,
                                memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_sub(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::difference_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_sub(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::difference_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_sub_explicit(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::difference_type,
                                memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_sub_explicit(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::difference_type,
                                memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_and(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_and(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_and_explicit(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                                memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_and_explicit(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                                memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_or(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_or(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_or_explicit(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                               memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_or_explicit(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                               memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_xor(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_xor(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_xor_explicit(volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                                memory_order) noexcept;
  template&lt;class T&gt;
    T atomic_fetch_xor_explicit(atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                                memory_order) noexcept;
  template&lt;class T&gt;
    void atomic_wait(const volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type);
  template&lt;class T&gt;
    void atomic_wait(const atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type);
  template&lt;class T&gt;
    void atomic_wait_explicit(const volatile atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                              memory_order);
  template&lt;class T&gt;
    void atomic_wait_explicit(const atomic&lt;T&gt;*, <ins>typename</ins> atomic&lt;T&gt;::value_type,
                              memory_order);
  template&lt;class T&gt;
    void atomic_notify_one(volatile atomic&lt;T&gt;*);
  template&lt;class T&gt;
    void atomic_notify_one(atomic&lt;T&gt;*);
  template&lt;class T&gt;
    void atomic_notify_all(volatile atomic&lt;T&gt;*);
  template&lt;class T&gt;
    void atomic_notify_all(atomic&lt;T&gt;*);

  // 31.3, type aliases ...

}
</pre></blockquote>

</blockquote>


<h2><a id="6.0">6 Acknowledgements</a></h2>
<p>
Thanks to Richard Smith and Daveed Vandevoorde for review of early versions of
this paper that caught several technical errors.  Thanks to Jens Maurer for
suggesting to list each pattern in section 3, that really improved the clarity
of the paper.  Thanks to Dietmar Kühl and Daryl Haresign for a final review of
the paper that again, greatly improved its clarity.
</p>


<h2><a id="7.0">7 References</a></h2>
<ul>
  <li>
<a href=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4861>N4861</a>
C++ Standard Working Draft (at inception of C++23),
Richard Smith
  </li>
  <li>
<a href="http://wiki.edg.com/pub/Wg21summer2020/CoreWorkingGroup/cwg_closed.html#1008">Core #1008</a>
Querying the alignment of an object
  </li>
  <li>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3">P0634R3</a>
Down with <code>typename</code>!,
Nina Ranns, Daveed Vandevoorde
  </li>
  <li>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0945r0">P0945R0</a>
Generalizing alias declarations,
Richard Smith
  </li>
</ul>


</body>
</html>
